diff --git a/AUTHORS b/AUTHORS index 7f9c785..9e5f74a 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -117,6 +117,7 @@ Andrew Tulloch <andrew@tullo.ch> Andriy Rysin <arysin@gmail.com> Anish Patankar <anish.p@samsung.com> +Ankit Kiran <sahuankit453@gmail.com> Ankit Kumar <ankit2.kumar@samsung.com> Ankur Verma <ankur1.verma@samsung.com> Anna Henningsen <anna@addaleax.net> @@ -679,6 +680,7 @@ Justin Ribeiro <justin@justinribeiro.com> Jüri Valdmann <juri.valdmann@qt.io> Juyoung Kim <chattank05@gmail.com> +Jing Peiyang <jingpeiyang@eswincomputing.com> Kai Jiang <jiangkai@gmail.com> Kai Köhne <kai.koehne@qt.io> Kai Uwe Broulik <kde@privat.broulik.de> @@ -1289,7 +1291,6 @@ Tom Callaway <tcallawa@redhat.com> Tom Harwood <tfh@skip.org> Tomas Popela <tomas.popela@gmail.com> -Tony Shen <legendmastertony@gmail.com> Torsten Kurbad <google@tk-webart.de> Toshihito Kikuchi <leamovret@gmail.com> Toshiaki Tanaka <zokutyou2@gmail.com> @@ -1475,6 +1476,7 @@ Cosium <*@cosium.com> Dell Technologies Inc. <*@dell.corp-partner.google.com> Ding (Beijing) Intelligent Technology Co. Ltd <*@dingdao.com> +Dropbox, Inc. <*@dropbox.com> Duck Duck Go, Inc. <*@duckduckgo.com> Endless Mobile, Inc. <*@endlessm.com> EngFlow, Inc. <*@engflow.com>
diff --git a/BUILD.gn b/BUILD.gn index 83afe3b3..48647e6 100644 --- a/BUILD.gn +++ b/BUILD.gn
@@ -1125,6 +1125,7 @@ args = [ "--product=chrome", "--no-show-results", + "--zero-tests-executed-ok", ] data_deps = [ "//chrome:chrome", @@ -1134,7 +1135,10 @@ } script_test("wpt_tests_isolate_content_shell") { script = "//third_party/blink/tools/run_wpt_tests.py" - args = [ "--no-show-results" ] + args = [ + "--no-show-results", + "--zero-tests-executed-ok", + ] data_deps = [ ":blink_web_tests_support_data", "//third_party/blink/tools:wpt_tests_isolate",
diff --git a/DEPS b/DEPS index fdd3c5d..491c2538 100644 --- a/DEPS +++ b/DEPS
@@ -278,7 +278,7 @@ # reclient CIPD package 'reclient_package': 'infra/rbe/client/', # reclient CIPD package version - 'reclient_version': 're_client_version:0.105.0.d6a0caf-gomaip', + 'reclient_version': 're_client_version:0.107.1.0b39c4c-gomaip', # Fetch siso CIPD package 'checkout_siso': False, @@ -300,23 +300,23 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'src_internal_revision': 'e689c5782dfc3ac5762403991b2d66e86b09d53f', + 'src_internal_revision': 'acc428e1264990c35d14607b1a5984cc8a4d3a7d', # 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': '4895a62e55c43b7d1c4518d19867827435a3c169', + 'skia_revision': '7777ee2bf7ef53e743c2aca75ad988ab74aecd38', # 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': 'e6731e8554a7a253532af4cd30cf7e4c5fd73a52', + 'v8_revision': '2662ff95341e023ac32fbc012ffce2a8b74c5af6', # 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': '53b2db67433bb123497658461bae4e09998bb7ef', + 'angle_revision': '0ea8e55a6f0667c2bb189d95987833231cdb22b2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. - 'swiftshader_revision': 'f549d5e6c6635ec8b75fb544a6bdc9f48bfb1dd3', + 'swiftshader_revision': 'ae667fe96db9b7f76edea242015d61f293c7210e', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling PDFium # and whatever else without interference from each other. @@ -331,7 +331,7 @@ # 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. - 'fuchsia_version': 'version:12.20230601.1.1', + 'fuchsia_version': 'version:12.20230601.2.1', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling google-toolbox-for-mac # and whatever else without interference from each other. @@ -375,7 +375,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': 'dfd78540ae99b3f753f8e250abd5e9be240b0053', + 'catapult_revision': 'ecf1f9c5b78d2d519a160545eea66692983d2543', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -391,7 +391,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': 'edba8844016204d290ecb38dfb6897e49f851afc', + 'devtools_frontend_revision': 'ca51bbf258c6a314b6435849135b0e020ac35041', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -431,7 +431,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': '4a21f2436f2c3a4dc041926312c572eec17a4665', + 'dawn_revision': '6d385e414cc076878d86bc335e5d5296fa98dee2', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -475,7 +475,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. - 'libcxxabi_revision': 'b2e8ad2755f15556a2e93b500db665c25409b95e', + 'libcxxabi_revision': '899caea3814eeb45c689fc206052968943fd5cb8', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -812,12 +812,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - '2fe0d34bc406af1e6c127c48c7bb9da2c7816698', + 'b03093da2bde7c1e6bfee17f5f20b290c9543faf', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + 'a54773400bdcdfc6bd9628ebe90a3188e74fd0d6', + 'url': Var('chromium_git') + '/website.git' + '@' + '109669807a0bdcd2c7cd195966b41aa181939cb1', }, 'src/ios/third_party/earl_grey2/src': { @@ -911,7 +911,7 @@ 'packages': [ { 'package': 'chromium/rts/model/linux-amd64', - 'version': '-Udx-GFRArzehZO7k15mF25l706PBMQx1oBBATwR7T4C', + 'version': 'lruYpxnOzy-mE1oc1CXKng8vsAkZVzh_igLwUpkQTrwC', }, ], 'dep_type': 'cipd', @@ -922,7 +922,7 @@ 'packages': [ { 'package': 'chromium/rts/model/mac-amd64', - 'version': 'wfxRWlK6F4wH3SGPPBoi0KVRqWDxafcafS2hYFjF56kC', + 'version': 'zjhLYLQi1z72lepqNR0Gi01ReauE0zARedH0uVZ0mTIC', }, ], 'dep_type': 'cipd', @@ -933,7 +933,7 @@ 'packages': [ { 'package': 'chromium/rts/model/windows-amd64', - 'version': 'ti5hS9obwfYzYotz-wQPYyXHFcIYht46V6NGFePgZUoC', + 'version': 'wHG5HB0sNxrS6DqWU4ZTnKr6jgYe1blIkaDgybPoPP0C', }, ], 'dep_type': 'cipd', @@ -1001,7 +1001,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'yy7NOUTgTyjACkyQjFHtZUyiPftLIKaZxhnICD0hU7AC', + 'version': 'OHveK-sQfZYVc9OYLG-gzd5LUi8BLlUn70JqB7cZEqIC', }, ], 'condition': 'checkout_android', @@ -1009,7 +1009,7 @@ }, 'src/third_party/androidx_javascriptengine/src': { - 'url': Var('chromium_git') + '/aosp/platform/frameworks/support/javascriptengine/javascriptengine/src.git' + '@' + '5afa1411d4818e3598a03fb7a3aaf43eecfd00fb', + 'url': Var('chromium_git') + '/aosp/platform/frameworks/support/javascriptengine/javascriptengine/src.git' + '@' + '1a958ab76811aa736c2a9434a9c2622fcb0ab71c', 'condition': 'checkout_android', }, @@ -1153,7 +1153,7 @@ Var('boringssl_git') + '/boringssl.git' + '@' + Var('boringssl_revision'), 'src/third_party/breakpad/breakpad': - Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '02fe1eef8e4753cfa686db52fc375e17f5d23c84', + Var('chromium_git') + '/breakpad/breakpad.git' + '@' + '8988364bcddd9b194b0bf931c10bc125987330ed', 'src/third_party/byte_buddy': { 'packages': [ @@ -1207,7 +1207,7 @@ # Tools used when building Chrome for Chrome OS. This affects both the Simple # Chrome workflow, as well as the chromeos-chrome ebuild. 'src/third_party/chromite': { - 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '222f3d3c7015cc5019deb87c1fe702e1bdcf3791', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + '58c2b7340e8016076e1e4653811957d0aa760940', 'condition': 'checkout_chromeos', }, @@ -1242,13 +1242,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'e49349becf69ddf68e5e8c7329836e125b4367aa', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '9e0ff22bfb3137e9c6b44304671a78c3e3d1e1d9', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + 'e25bc2ece543ccf2d728dd6c83f4ff52269d3ae9', + 'url': Var('chrome_git') + '/devtools/devtools-internal.git' + '@' + '95bd968fa3d42996225f25a8dbc9be254ad15251', 'condition': 'checkout_src_internal', }, @@ -1408,7 +1408,7 @@ Var('chromium_git') + '/chromium/deps/hunspell_dictionaries.git' + '@' + '41cdffd71c9948f63c7ad36e1fb0ff519aa7a37e', 'src/third_party/icu': - Var('chromium_git') + '/chromium/deps/icu.git' + '@' + '709d56e26482982f7390e49f98ef7a91101f137e', + Var('chromium_git') + '/chromium/deps/icu.git' + '@' + 'a2961dc659b4ae847a9c6120718cc2517ee57d9e', 'src/third_party/icu4j': { 'packages': [ @@ -1441,7 +1441,7 @@ 'packages': [ { 'package': 'chromium/third_party/jdk', - 'version': '2Of9Pe_OdO4xoAATuiLDiMVNebKTNO3WrwJGqil4RosC', + 'version': '-1zDGMOzS_Qsja50TakJCSqN9C9TYppQrsny4HATSQwC', # version:2@jdk-20.0.1+9.13e718d227 }, ], # Needed on Linux for use on chromium_presubmit (for checkstyle). @@ -1704,7 +1704,7 @@ Var('chromium_git') + '/external/github.com/cisco/openh264' + '@' + '09a4f3ec842a8932341b195c5b01e141c8a16eb7', 'src/third_party/openscreen/src': - Var('chromium_git') + '/openscreen' + '@' + 'c0ee33b4e062214d014825cef2117df405e48c94', + Var('chromium_git') + '/openscreen' + '@' + 'ff6c5c90428d0c747d9bac2350aef3edb4e5f26c', 'src/third_party/openxr/src': { 'url': Var('chromium_git') + '/external/github.com/KhronosGroup/OpenXR-SDK' + '@' + '58a00cf85c39ad5ec4dc43a769624e420c06179a', @@ -1715,7 +1715,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + '53002b30d2f05f6c267012ce2abf3c5fbd4e9e35', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '922cf5c76a1ef4eb6fd120d86af5fe54389913f2', 'src/third_party/perl': { 'url': Var('chromium_git') + '/chromium/deps/perl.git' + '@' + '6f3e5028eb65d0b4c5fdd792106ac4c84eee1eb3', @@ -1749,7 +1749,7 @@ }, 'src/third_party/re2/src': - Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '03da4fc0857c285e3a26782f6bc8931c4c950df4', + Var('chromium_git') + '/external/github.com/google/re2.git' + '@' + '7c5e396af825562ec8321fdbf2f1cf276b26e3ae', 'src/third_party/r8': { 'packages': [ @@ -1860,7 +1860,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@cb2dba2037f71d304fb96c18ebee0fb519f034c9', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@fc830f4fbc41418e206e699beb6aaf77ad51d01a', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'ebe84bec02c041d28f902da0214bf442743fc907', @@ -1897,10 +1897,10 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + 'b934957d2423492a9a8682f48517f07607503f3f', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '847437002f76105fa25a511619ef07dc1971318d', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '480edec387e8cd5bf5934680050c59a3f7a01438', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '513ab0cb2c000b5613c6660259a31a7de48ef9d2', + Var('webrtc_git') + '/src.git' + '@' + '063b45bed7636d2b038d8f6f0913441a00bc5474', # Wuffs' canonical repository is at github.com/google/wuffs, but we use # Skia's mirror of Wuffs, the same as in upstream Skia's DEPS file. @@ -1994,6 +1994,11 @@ 'condition': 'checkout_src_internal', }, + 'src/internal': { + 'url': Var('chrome_git') + '/chrome/src-internal.git' + '@' + Var('src_internal_revision'), + 'condition': 'checkout_src_internal', + }, + 'src/ash/ambient/resources': { 'packages': [ { @@ -2020,7 +2025,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/help_app/app', - 'version': 'eyw4WDSkZaHJrDTff98UJTmLG9cgf0LM-PgDMMa0jrsC', + 'version': 'kI-tZEeE3OpUX1ybIxjU2UULBhtXYdOn9ygpYmLWfSQC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -2031,7 +2036,7 @@ 'packages': [ { 'package': 'chromeos_internal/apps/media_app/app', - 'version': 'Sx1WXJws6Du7GQA8CKx_llcuoUkaxXjfFAmDhs58Ka4C', + 'version': 'S9AmQsKMIfUGkvos6g4Xiss569nzW2Io4eAjUFLOrvcC', }, ], 'condition': 'checkout_chromeos and checkout_src_internal', @@ -3996,7 +4001,7 @@ 'src/chrome/app/theme/default_200_percent/google_chrome': { 'url': Var('chrome_git') + '/chrome/theme/default_200_percent/google_chrome.git' + '@' + - 'db0cce3e7bfc7489c7213295d56e1c7611f9c43f', + '1d0c7e07b914acb41d288af6af24e4393dad4977', 'condition': 'checkout_src_internal', }, @@ -4189,7 +4194,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'f1fd47a005b7fd749021632ab2ce3bc276adc4de', + 'bc3ffc419b6469704f3493c3b572c2ff5f3fb1d5', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index d2ce0244..cf1cdd0 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py
@@ -15,9 +15,6 @@ PRESUBMIT_VERSION = '2.0.0' -# This line is 'magic' in that git-cl looks for it to decide whether to -# use Python3 instead of Python2 when running the code in this file. -USE_PYTHON3 = True _EXCLUDED_PATHS = ( # Generated file @@ -5452,21 +5449,12 @@ if not input_api.os_path.exists(test_file): continue - use_python3 = False - with open(f.LocalPath(), encoding='utf-8') as fp: - use_python3 = any( - line.startswith('USE_PYTHON3 = True') - for line in fp.readlines()) - results.extend( input_api.canned_checks.RunUnitTestsInDirectory( input_api, output_api, full_path, - files_to_check=[r'^PRESUBMIT_test\.py$'], - run_on_python2=not use_python3, - run_on_python3=use_python3, - skip_shebang_check=True)) + files_to_check=[r'^PRESUBMIT_test\.py$'])) return results
diff --git a/android_webview/PRESUBMIT.py b/android_webview/PRESUBMIT.py index 8074704..4d82b5a 100644 --- a/android_webview/PRESUBMIT.py +++ b/android_webview/PRESUBMIT.py
@@ -6,9 +6,6 @@ Gates against using Context#bindService API before upload. """ -USE_PYTHON3 = True - - def CheckChangeOnCommit(input_api, output_api): results = [] results.extend(_CheckNoContextBindServiceAdded(input_api, output_api))
diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index dd35756b..45f1826 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc
@@ -57,7 +57,6 @@ #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool/thread_pool_instance.h" #include "build/build_config.h" -#include "components/cdm/browser/cdm_message_filter_android.h" #include "components/crash/content/browser/crash_handler_host_linux.h" #include "components/embedder_support/origin_trials/origin_trials_settings_storage.h" #include "components/embedder_support/switches.h" @@ -301,8 +300,6 @@ host->GetID(), url::kContentScheme); host->AddFilter(new AwContentsMessageFilter(host->GetID())); - // WebView always allows persisting data. - host->AddFilter(new cdm::CdmMessageFilterAndroid(true, false)); } bool AwContentBrowserClient::IsExplicitNavigation(
diff --git a/android_webview/common/BUILD.gn b/android_webview/common/BUILD.gn index b3febb8..46e4744 100644 --- a/android_webview/common/BUILD.gn +++ b/android_webview/common/BUILD.gn
@@ -51,6 +51,7 @@ "//ipc", "//mojo/public/cpp/bindings", "//skia", + "//third_party/widevine/cdm:buildflags", "//ui/base", "//ui/gfx/geometry", "//ui/gfx/ipc/geometry",
diff --git a/android_webview/common/DEPS b/android_webview/common/DEPS index 493b8767..f11fb6e 100644 --- a/android_webview/common/DEPS +++ b/android_webview/common/DEPS
@@ -7,4 +7,5 @@ "+components/gwp_asan/common/crash_key_name.h" "+components/printing/common", "+media/base/android", + "+third_party/widevine/cdm/buildflags.h", ]
diff --git a/android_webview/common/aw_content_client.cc b/android_webview/common/aw_content_client.cc index ca98d1b..23980a7 100644 --- a/android_webview/common/aw_content_client.cc +++ b/android_webview/common/aw_content_client.cc
@@ -14,14 +14,17 @@ #include "base/functional/bind.h" #include "base/no_destructor.h" #include "base/task/sequenced_task_runner.h" +#include "components/cdm/common/android_cdm_registration.h" #include "components/embedder_support/origin_trials/origin_trial_policy_impl.h" #include "components/services/heap_profiling/public/cpp/profiling_client.h" #include "components/version_info/version_info.h" +#include "content/public/common/cdm_info.h" #include "content/public/common/content_switches.h" #include "gpu/config/gpu_info.h" #include "gpu/config/gpu_util.h" #include "mojo/public/cpp/bindings/binder_map.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "third_party/widevine/cdm/buildflags.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" @@ -68,6 +71,18 @@ gpu::SetKeysForCrashLogging(gpu_info); } +void AwContentClient::AddContentDecryptionModules( + std::vector<content::CdmInfo>* cdms, + std::vector<media::CdmHostFilePath>* cdm_host_file_paths) { +#if BUILDFLAG(ENABLE_WIDEVINE) + // Register Widevine. + cdm::AddAndroidWidevineCdm(cdms); +#endif + + // Register any other CDMs supported by the device. + cdm::AddOtherAndroidCdms(cdms); +} + bool AwContentClient::UsingSynchronousCompositing() { return true; }
diff --git a/android_webview/common/aw_content_client.h b/android_webview/common/aw_content_client.h index 60f0347..70c1f19b 100644 --- a/android_webview/common/aw_content_client.h +++ b/android_webview/common/aw_content_client.h
@@ -34,6 +34,9 @@ base::RefCountedMemory* GetDataResourceBytes(int resource_id) override; std::string GetDataResourceString(int resource_id) override; void SetGpuInfo(const gpu::GPUInfo& gpu_info) override; + void AddContentDecryptionModules( + std::vector<content::CdmInfo>* cdms, + std::vector<media::CdmHostFilePath>* cdm_host_file_paths) override; bool UsingSynchronousCompositing() override; media::MediaDrmBridgeClient* GetMediaDrmBridgeClient() override; void ExposeInterfacesToBrowser(
diff --git a/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java b/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java index d3b53266..1ac72a3 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java +++ b/android_webview/java/src/org/chromium/android_webview/AwActionModeCallback.java
@@ -77,7 +77,7 @@ int groupId = item.getGroupId(); - if (groupId == R.id.select_action_menu_text_processing_menus) { + if (groupId == R.id.select_action_menu_text_processing_items) { processText(item.getIntent()); // The ActionMode is not dismissed to match the behavior with // TextView in Android M.
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 81f0e37e..96b32cf 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java
@@ -78,8 +78,8 @@ import org.chromium.base.task.AsyncTask; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; -import org.chromium.components.autofill.AutofillActionModeCallback; import org.chromium.components.autofill.AutofillProvider; +import org.chromium.components.autofill.AutofillSelectionMenuItemProvider; import org.chromium.components.content_capture.OnscreenContentProvider; import org.chromium.components.embedder_support.util.WebResourceResponseInfo; import org.chromium.components.navigation_interception.InterceptNavigationDelegate; @@ -1172,8 +1172,8 @@ mAutofillProvider.setWebContents(mWebContents); } SelectionPopupController.fromWebContents(mWebContents) - .setNonSelectionActionModeCallback( - new AutofillActionModeCallback(mContext, mAutofillProvider)); + .setNonSelectionAdditionalMenuItemProvider( + new AutofillSelectionMenuItemProvider(mContext, mAutofillProvider)); AwContentsJni.get().initializeAndroidAutofill(mNativeAwContents); }
diff --git a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java index e19ba38..e898572 100644 --- a/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java +++ b/android_webview/java/src/org/chromium/android_webview/common/ProductionSupportedFlagList.java
@@ -252,7 +252,6 @@ + "thread."), Flag.baseFeature(BaseFeatures.OPTIMIZE_DATA_URLS, "Optimizes parsing and loading of data: URLs."), - Flag.baseFeature(BlinkFeatures.EVENT_PATH, "Enables the deprecated Event.path API."), Flag.baseFeature(BlinkFeatures.PREFETCH_FONT_LOOKUP_TABLES, "If enabled, font lookup tables will be prefetched on renderer startup."), Flag.baseFeature(BlinkFeatures.PRECOMPILE_INLINE_SCRIPTS,
diff --git a/android_webview/java/src/org/chromium/android_webview/variations/FastVariationsSeedSafeModeAction.java b/android_webview/java/src/org/chromium/android_webview/variations/FastVariationsSeedSafeModeAction.java index c7707682..7dee106 100644 --- a/android_webview/java/src/org/chromium/android_webview/variations/FastVariationsSeedSafeModeAction.java +++ b/android_webview/java/src/org/chromium/android_webview/variations/FastVariationsSeedSafeModeAction.java
@@ -28,6 +28,8 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; +import java.util.Locale; +import java.util.concurrent.TimeUnit; /** * A {@link SafeModeAction} to ensure the variations seed is distributed on an app's first run. @@ -75,8 +77,12 @@ sHasRun = true; long currDateTime = new Date().getTime(); SeedParser parser = new SeedParser(); - long stampTime = sSeedFile.lastModified(); + long ageInMillis = currDateTime - stampTime; + + if (sSeedFile.exists() && ageInMillis > 0) { + logSeedFileAge(ageInMillis); + } // If we see that the local seed file has not exceeded the // maximum seed age of 15 minutes, parse the local seed instead // of requesting a new one from the ContentProvider @@ -95,6 +101,16 @@ } } + private void logSeedFileAge(long ageInMillis) { + int seconds = (int) (ageInMillis / 1000) % 60; + int minutes = (int) (ageInMillis / TimeUnit.MINUTES.toMillis(1)) % 60; + int hrs = (int) (ageInMillis / TimeUnit.HOURS.toMillis(1)); + + String formattedAge = + String.format(Locale.US, "%02d:%02d:%02d (hh:mm:ss)", hrs, minutes, seconds); + Log.i(TAG, "Seed file age - " + formattedAge); + } + /** * This class queries {@link SafeModeVariationsSeedContentProvider} for the * latest variations seed. @@ -211,6 +227,7 @@ String filePath = sSeedFile.getPath(); try (FileOutputStream out = new FileOutputStream(filePath, false)) { out.write(mProtoAsByteArray); + out.flush(); return true; } catch (IOException e) { Log.e(TAG, "Failed writing seed file: " + e.getMessage());
diff --git a/android_webview/javatests/DEPS b/android_webview/javatests/DEPS index e0b64d0..8de32b9 100644 --- a/android_webview/javatests/DEPS +++ b/android_webview/javatests/DEPS
@@ -20,4 +20,6 @@ "+services/device/public/java", "+media/base/android", + + "+ui/accessibility", ]
diff --git a/android_webview/javatests/PRESUBMIT.py b/android_webview/javatests/PRESUBMIT.py index cbe783e..f8e89155 100644 --- a/android_webview/javatests/PRESUBMIT.py +++ b/android_webview/javatests/PRESUBMIT.py
@@ -6,9 +6,6 @@ Runs various style checks before upload. """ -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): results = [] results.extend(_CheckAwJUnitTestRunner(input_api, output_api))
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java index b5e7ab1..2f44d2d 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsGarbageCollectionTest.java
@@ -39,6 +39,7 @@ import org.chromium.content_public.browser.WebContentsAccessibility; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.content_public.common.ContentUrlConstants; +import org.chromium.ui.accessibility.AccessibilityState; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; @@ -160,12 +161,12 @@ mActivityTestRule.loadUrlAsync( containerView.getAwContents(), ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL); TestThreadUtils.runOnUiThreadBlocking(() -> { - WebContentsAccessibility webContentsA11y = - WebContentsAccessibility.fromWebContents(containerView.getWebContents()); // Enable a11y for testing. - webContentsA11y.setAccessibilityEnabledForTesting(); + AccessibilityState.setIsAnyAccessibilityServiceEnabledForTesting(true); // Initialize native object. containerView.getAccessibilityNodeProvider(); + WebContentsAccessibility webContentsA11y = + WebContentsAccessibility.fromWebContents(containerView.getWebContents()); Assert.assertTrue(webContentsA11y.isNativeInitialized()); });
diff --git a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java index 6e32e05..b39c4dd 100644 --- a/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java +++ b/android_webview/nonembedded/java/src/org/chromium/android_webview/services/AwVariationsSeedFetcher.java
@@ -366,7 +366,6 @@ final VariationsSeedFetcher.SeedFetchParameters params = VariationsSeedFetcher.SeedFetchParameters.Builder.newBuilder() .setPlatform(VariationsSeedFetcher.VariationsPlatform.ANDROID_WEBVIEW) - .setRestrictMode(null) .setMilestone(milestone) .setChannel(getChannelStr()) .setIsFastFetchMode(fastMode)
diff --git a/android_webview/renderer/BUILD.gn b/android_webview/renderer/BUILD.gn index e1c83486..745ad89 100644 --- a/android_webview/renderer/BUILD.gn +++ b/android_webview/renderer/BUILD.gn
@@ -10,8 +10,6 @@ "aw_content_renderer_client.h", "aw_content_settings_client.cc", "aw_content_settings_client.h", - "aw_key_systems.cc", - "aw_key_systems.h", "aw_print_render_frame_helper_delegate.cc", "aw_print_render_frame_helper_delegate.h", "aw_render_frame_ext.cc",
diff --git a/android_webview/renderer/aw_content_renderer_client.cc b/android_webview/renderer/aw_content_renderer_client.cc index 0238ea4..9540fd12 100644 --- a/android_webview/renderer/aw_content_renderer_client.cc +++ b/android_webview/renderer/aw_content_renderer_client.cc
@@ -11,7 +11,6 @@ #include "android_webview/common/mojom/frame.mojom.h" #include "android_webview/common/url_constants.h" #include "android_webview/renderer/aw_content_settings_client.h" -#include "android_webview/renderer/aw_key_systems.h" #include "android_webview/renderer/aw_print_render_frame_helper_delegate.h" #include "android_webview/renderer/aw_render_frame_ext.h" #include "android_webview/renderer/aw_render_view_ext.h" @@ -24,6 +23,7 @@ #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" #include "components/android_system_error_page/error_page_populator.h" +#include "components/cdm/renderer/key_system_support_update.h" #include "components/js_injection/renderer/js_communication.h" #include "components/network_hints/renderer/web_prescient_networking_impl.h" #include "components/page_load_metrics/renderer/metrics_render_frame_observer.h" @@ -214,9 +214,8 @@ void AwContentRendererClient::GetSupportedKeySystems( media::GetSupportedKeySystemsCB cb) { - media::KeySystemInfos key_systems; - AwAddKeySystems(&key_systems); - std::move(cb).Run(std::move(key_systems)); + // WebView always allows persisting data. + cdm::GetSupportedKeySystemsUpdates(/*can_persist_data=*/true, std::move(cb)); } std::unique_ptr<blink::WebSocketHandshakeThrottleProvider>
diff --git a/android_webview/renderer/aw_key_systems.cc b/android_webview/renderer/aw_key_systems.cc deleted file mode 100644 index d1ec362..0000000 --- a/android_webview/renderer/aw_key_systems.cc +++ /dev/null
@@ -1,17 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "android_webview/renderer/aw_key_systems.h" -#include "components/cdm/renderer/android_key_systems.h" - -namespace android_webview { - -void AwAddKeySystems(media::KeySystemInfos* key_systems_infos) { -#if BUILDFLAG(ENABLE_WIDEVINE) - cdm::AddAndroidWidevine(key_systems_infos); -#endif // BUILDFLAG(ENABLE_WIDEVINE) - cdm::AddAndroidPlatformKeySystems(key_systems_infos); -} - -} // namespace android_webview
diff --git a/android_webview/renderer/aw_key_systems.h b/android_webview/renderer/aw_key_systems.h deleted file mode 100644 index 60324025..0000000 --- a/android_webview/renderer/aw_key_systems.h +++ /dev/null
@@ -1,16 +0,0 @@ -// Copyright 2013 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ANDROID_WEBVIEW_RENDERER_AW_KEY_SYSTEMS_H_ -#define ANDROID_WEBVIEW_RENDERER_AW_KEY_SYSTEMS_H_ - -#include "media/base/key_system_info.h" - -namespace android_webview { - -void AwAddKeySystems(media::KeySystemInfos* key_system_infos); - -} // namespace android_webview - -#endif // ANDROID_WEBVIEW_RENDERER_AW_KEY_SYSTEMS_H_
diff --git a/android_webview/support_library/PRESUBMIT.py b/android_webview/support_library/PRESUBMIT.py index 6337e0c..741a987 100644 --- a/android_webview/support_library/PRESUBMIT.py +++ b/android_webview/support_library/PRESUBMIT.py
@@ -6,9 +6,6 @@ Runs various style checks before upload. """ -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): results = [] results.extend(_CheckAnnotatedInvocationHandlers(input_api, output_api))
diff --git a/android_webview/test/BUILD.gn b/android_webview/test/BUILD.gn index eb189b8..6a4bf04 100644 --- a/android_webview/test/BUILD.gn +++ b/android_webview/test/BUILD.gn
@@ -82,6 +82,7 @@ args = [ "--product", "android_webview", + "--zero-tests-executed-ok", "--webview-provider", "@WrappedPath(apks/SystemWebView.apk)", "--browser-apk", @@ -314,6 +315,7 @@ "//third_party/junit", "//third_party/metrics_proto:metrics_proto_java", "//third_party/mockito:mockito_java", + "//ui/accessibility:ax_base_java", "//ui/android:ui_java", "//ui/android:ui_java_test_support", "//url:gurl_java",
diff --git a/android_webview/tools/PRESUBMIT.py b/android_webview/tools/PRESUBMIT.py index ffcc0126..5c0fb82 100644 --- a/android_webview/tools/PRESUBMIT.py +++ b/android_webview/tools/PRESUBMIT.py
@@ -4,17 +4,13 @@ """Presubmit for android_webview/tools.""" -USE_PYTHON3 = True - - def _GetPythonUnitTests(input_api, output_api): return input_api.canned_checks.GetUnitTestsRecursively( input_api, output_api, input_api.PresubmitLocalPath(), files_to_check=['.*_test\\.py$'], - files_to_skip=[], - run_on_python2=False) + files_to_skip=[]) def CommonChecks(input_api, output_api):
diff --git a/android_webview/tools/system_webview_shell/test/data/webexposed/PRESUBMIT.py b/android_webview/tools/system_webview_shell/test/data/webexposed/PRESUBMIT.py index 3d127029..3749fa4 100644 --- a/android_webview/tools/system_webview_shell/test/data/webexposed/PRESUBMIT.py +++ b/android_webview/tools/system_webview_shell/test/data/webexposed/PRESUBMIT.py
@@ -3,9 +3,6 @@ # found in the LICENSE file. import sys -USE_PYTHON3 = True - - def _SetupImportPath(input_api): webview_data_dir = input_api.PresubmitLocalPath() if webview_data_dir not in sys.path:
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 4a21e4a..f683fe6 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -973,6 +973,8 @@ "scoped_animation_disabler.h", "screen_util.cc", "screen_util.h", + "sensor_info/sensor_types.cc", + "sensor_info/sensor_types.h", "session/fullscreen_controller.cc", "session/fullscreen_controller.h", "session/fullscreen_notification_bubble.cc",
diff --git a/ash/accelerators/accelerator_tracker.cc b/ash/accelerators/accelerator_tracker.cc index 230a3cf..ac0a424 100644 --- a/ash/accelerators/accelerator_tracker.cc +++ b/ash/accelerators/accelerator_tracker.cc
@@ -4,6 +4,8 @@ #include "ash/accelerators/accelerator_tracker.h" +#include <string> + #include "base/metrics/user_metrics.h" #include "ui/events/event.h" @@ -25,7 +27,7 @@ event->key_code(), event->flags()); const auto it = accelerator_tracker_map_.find(trackerData); if (it != accelerator_tracker_map_.end()) { - base::RecordAction(base::UserMetricsAction(it->second.data())); + base::RecordComputedAction(std::string(it->second)); } }
diff --git a/ash/accelerators/accelerator_tracker_unittest.cc b/ash/accelerators/accelerator_tracker_unittest.cc index 31ef39bb..c193a79 100644 --- a/ash/accelerators/accelerator_tracker_unittest.cc +++ b/ash/accelerators/accelerator_tracker_unittest.cc
@@ -41,43 +41,43 @@ base::UserActionTester user_action_tester; // The metric is not recorded before the event is fired. - EXPECT_EQ(0, user_action_tester.GetActionCount(intended_user_action.data())); + EXPECT_EQ(0, user_action_tester.GetActionCount(intended_user_action)); // The metric is recorded after the event is fired. ui::KeyEvent key_event(ui::ET_KEY_PRESSED, intended_key_code, intended_modifier); accelerator_tracker.OnKeyEvent(&key_event); - EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action.data())); + EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action)); // Fire a similar key event won't trigger this metric. // An event with same key code and modifier, but different key states. ui::KeyEvent key_event1(ui::ET_KEY_RELEASED, intended_key_code, intended_modifier); accelerator_tracker.OnKeyEvent(&key_event1); - EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action.data())); + EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action)); // An event with same key code and key state, but superset of modifiers. ui::KeyEvent key_event2(ui::ET_KEY_PRESSED, intended_key_code, intended_modifier | ui::EF_ALT_DOWN); accelerator_tracker.OnKeyEvent(&key_event2); - EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action.data())); + EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action)); // An event with same key code and key state, but subset of modifiers. ui::KeyEvent key_event3(ui::ET_KEY_PRESSED, intended_key_code, ui::EF_CONTROL_DOWN); accelerator_tracker.OnKeyEvent(&key_event3); - EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action.data())); + EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action)); // An event with same key code and key state, but different modifiers. ui::KeyEvent key_event4(ui::ET_KEY_PRESSED, intended_key_code, ui::EF_ALT_DOWN); accelerator_tracker.OnKeyEvent(&key_event4); - EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action.data())); + EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action)); // An event with same key state and modifiers, but different key codes. ui::KeyEvent key_event5(ui::ET_KEY_PRESSED, ui::VKEY_B, intended_modifier); accelerator_tracker.OnKeyEvent(&key_event5); - EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action.data())); + EXPECT_EQ(1, user_action_tester.GetActionCount(intended_user_action)); } } // namespace ash
diff --git a/ash/ambient/ambient_ui_settings.cc b/ash/ambient/ambient_ui_settings.cc index 54dab4b..709d011 100644 --- a/ash/ambient/ambient_ui_settings.cc +++ b/ash/ambient/ambient_ui_settings.cc
@@ -104,7 +104,7 @@ } std::string AmbientUiSettings::ToString() const { - std::string output(ash::ToString(theme_).data()); + std::string output(ash::ToString(theme_)); if (theme_ == AmbientTheme::kVideo) { CHECK(video_); base::StrAppend(&output, {".", ash::ToString(*video_)});
diff --git a/ash/ambient/metrics/ambient_metrics.cc b/ash/ambient/metrics/ambient_metrics.cc index ea78179..478e3c5 100644 --- a/ash/ambient/metrics/ambient_metrics.cc +++ b/ash/ambient/metrics/ambient_metrics.cc
@@ -69,10 +69,10 @@ return histogram; } -void RecordEngagementTime(base::StringPiece histogram_name, +void RecordEngagementTime(const std::string& histogram_name, base::TimeDelta engagement_time) { base::UmaHistogramCustomTimes( - histogram_name.data(), + histogram_name, /*sample=*/engagement_time, // There is no value in bucketing engagement times that are on the order // of milliseconds. A 1 second minimum is imposed here but not in the
diff --git a/ash/ambient/model/ambient_animation_attribution_provider.cc b/ash/ambient/model/ambient_animation_attribution_provider.cc index 6a4e49a..9881df1 100644 --- a/ash/ambient/model/ambient_animation_attribution_provider.cc +++ b/ash/ambient/model/ambient_animation_attribution_provider.cc
@@ -31,8 +31,8 @@ // 2 -> "CrOS_AttributionNode2" // ... std::string BuildAttributionNodeName(int idx) { - return base::StringPrintf("%s_Attribution_Text%d", - kLottieCustomizableIdPrefix.data(), idx); + return base::StrCat({kLottieCustomizableIdPrefix, "_Attribution_Text", + base::NumberToString(idx)}); } // Not all text nodes in the animation are necessarily ones that should hold
diff --git a/ash/ambient/test/ambient_test_util.cc b/ash/ambient/test/ambient_test_util.cc index 38a489d..c503ba00 100644 --- a/ash/ambient/test/ambient_test_util.cc +++ b/ash/ambient/test/ambient_test_util.cc
@@ -23,9 +23,8 @@ std::string GenerateLottieDynamicAssetIdForTesting(base::StringPiece position, int idx) { CHECK(!position.empty()); - return base::StringPrintf("%s_Photo_Position%s_%d", - kLottieCustomizableIdPrefix.data(), position.data(), - idx); + return base::StrCat({kLottieCustomizableIdPrefix, "_Photo_Position", position, + "_", base::NumberToString(idx)}); } AmbientPhotoConfig GenerateAnimationConfigWithNAssets(int num_assets) {
diff --git a/ash/ambient/ui/ambient_info_view.cc b/ash/ambient/ui/ambient_info_view.cc index 33fec11..fde8e58 100644 --- a/ash/ambient/ui/ambient_info_view.cc +++ b/ash/ambient/ui/ambient_info_view.cc
@@ -31,11 +31,16 @@ constexpr int kDetailsFontSizeDip = 13; constexpr int kTimeFontSizeDip = 64; +// Returns the fontlist used for the details label text. +gfx::FontList GetDetailsLabelFontList() { + return ambient::util::GetDefaultFontlist().DeriveWithSizeDelta( + kDetailsFontSizeDip - kDefaultFontSizeDip); +} + views::Label* AddLabel(views::View* parent) { auto* label = parent->AddChildView(std::make_unique<views::Label>()); label->SetAutoColorReadabilityEnabled(false); - label->SetFontList(ambient::util::GetDefaultFontlist().DeriveWithSizeDelta( - kDetailsFontSizeDip - kDefaultFontSizeDip)); + label->SetFontList(GetDetailsLabelFontList()); label->SetPaintToLayer(); label->layer()->SetFillsBoundsOpaquely(false); @@ -111,6 +116,17 @@ related_details_label_ = AddLabel(this); } +// To make the distance from the time/weather to the bottom same as to the left, +// an extra padding of the time font descent and the height of the details label +// is needed. If the details label info is not empty, need to consider line +// height distance too. +int AmbientInfoView::GetAdjustedLeftPaddingToMatchBottom() { + auto details_label_font_list = GetDetailsLabelFontList(); + int adjusted_left_padding = details_label_font_list.GetHeight() + + glanceable_info_view_->GetTimeFontDescent(); + return adjusted_left_padding; +} + BEGIN_METADATA(AmbientInfoView, views::View) END_METADATA
diff --git a/ash/ambient/ui/ambient_info_view.h b/ash/ambient/ui/ambient_info_view.h index e8d98701..8501a9a 100644 --- a/ash/ambient/ui/ambient_info_view.h +++ b/ash/ambient/ui/ambient_info_view.h
@@ -45,6 +45,8 @@ void SetTextTransform(const gfx::Transform& transform); + int GetAdjustedLeftPaddingToMatchBottom(); + private: void InitLayout();
diff --git a/ash/ambient/ui/ambient_slideshow_peripheral_ui.cc b/ash/ambient/ui/ambient_slideshow_peripheral_ui.cc index ce4429a..b5532f23 100644 --- a/ash/ambient/ui/ambient_slideshow_peripheral_ui.cc +++ b/ash/ambient/ui/ambient_slideshow_peripheral_ui.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/ambient/ui/ambient_shield_view.h" +#include "ash/ambient/ui/ambient_slideshow_peripheral_ui.h" #include "ash/ambient/ui/ambient_view_delegate.h" #include "ash/ambient/ui/ambient_view_ids.h" #include "ash/ambient/ui/jitter_calculator.h" @@ -17,9 +18,11 @@ #include "base/logging.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/compositor/layer.h" +#include "ui/views/border.h" #include "ui/views/layout/box_layout.h" #include "ui/views/layout/fill_layout.h" #include "ui/views/layout/flex_layout_types.h" +#include "ui/views/view.h" namespace ash { @@ -105,6 +108,11 @@ } } +void AmbientSlideshowPeripheralUi::UpdateLeftPaddingToMatchBottom() { + ambient_info_view_->SetBorder(views::CreateEmptyBorder(gfx::Insets::TLBR( + 0, ambient_info_view_->GetAdjustedLeftPaddingToMatchBottom(), 0, 0))); +} + void AmbientSlideshowPeripheralUi::UpdateImageDetails( const std::u16string& details, const std::u16string& related_details) {
diff --git a/ash/ambient/ui/ambient_slideshow_peripheral_ui.h b/ash/ambient/ui/ambient_slideshow_peripheral_ui.h index 6922426..9cb40c8 100644 --- a/ash/ambient/ui/ambient_slideshow_peripheral_ui.h +++ b/ash/ambient/ui/ambient_slideshow_peripheral_ui.h
@@ -39,6 +39,8 @@ // the desired frequency to prevent screen burn. void UpdateGlanceableInfoPosition(); + void UpdateLeftPaddingToMatchBottom(); + void UpdateImageDetails(const std::u16string& details, const std::u16string& related_details);
diff --git a/ash/ambient/ui/ambient_video_view.cc b/ash/ambient/ui/ambient_video_view.cc index df275384..c46ba95 100644 --- a/ash/ambient/ui/ambient_video_view.cc +++ b/ash/ambient/ui/ambient_video_view.cc
@@ -65,6 +65,10 @@ ash_web_view_->Navigate(ambient_video_url); AddChildView(peripheral_ui_.get()); + peripheral_ui_->UpdateLeftPaddingToMatchBottom(); + // Update details label to empty string as details info is not shown for + // ambient video. + peripheral_ui_->UpdateImageDetails(u"", u""); peripheral_ui_jitter_timer_.Start( FROM_HERE, kPeripheralUiJitterPeriod, peripheral_ui_.get(), &AmbientSlideshowPeripheralUi::UpdateGlanceableInfoPosition);
diff --git a/ash/ambient/ui/glanceable_info_view.cc b/ash/ambient/ui/glanceable_info_view.cc index 3fdc8af..f35a64c 100644 --- a/ash/ambient/ui/glanceable_info_view.cc +++ b/ash/ambient/ui/glanceable_info_view.cc
@@ -190,6 +190,10 @@ 0, 0, GetFontDescent(time_font_list) - GetTemperatureFontDescent(), 0))); } +int GlanceableInfoView::GetTimeFontDescent() { + return GetFontDescent(GetTimeFontList(time_font_size_dip_)); +} + BEGIN_METADATA(GlanceableInfoView, views::View) END_METADATA
diff --git a/ash/ambient/ui/glanceable_info_view.h b/ash/ambient/ui/glanceable_info_view.h index 3e7ffe1..eba749f 100644 --- a/ash/ambient/ui/glanceable_info_view.h +++ b/ash/ambient/ui/glanceable_info_view.h
@@ -53,6 +53,8 @@ void Show(); + int GetTimeFontDescent(); + private: void InitLayout();
diff --git a/ash/ash_prefs.cc b/ash/ash_prefs.cc index b94b6c5..7dc701ee 100644 --- a/ash/ash_prefs.cc +++ b/ash/ash_prefs.cc
@@ -54,6 +54,7 @@ #include "ash/system/palette/palette_welcome_bubble.h" #include "ash/system/pcie_peripheral/pcie_peripheral_notification_controller.h" #include "ash/system/power/power_prefs.h" +#include "ash/system/power/power_sounds_controller.h" #include "ash/system/privacy_hub/privacy_hub_controller.h" #include "ash/system/session/logout_button_tray.h" #include "ash/system/session/logout_confirmation_controller.h" @@ -124,6 +125,7 @@ PaletteTray::RegisterProfilePrefs(registry); PaletteWelcomeBubble::RegisterProfilePrefs(registry); PciePeripheralNotificationController::RegisterProfilePrefs(registry); + PowerSoundsController::RegisterPrefs(registry); PrivacyHubController::RegisterProfilePrefs(registry); PrivacyScreenController::RegisterProfilePrefs(registry); ProjectorControllerImpl::RegisterProfilePrefs(registry);
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 41f9b22..857f14b 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2980,6 +2980,10 @@ Noise cancellation </message> + <message name="IDS_ASH_STATUS_TRAY_AUDIO_NBS_MESSAGE" desc="label used to warn that NBS is in use"> + Your Chromebook or Bluetooth device is using an older version of Bluetooth. Use another input source for better audio quality. + </message> + <!-- Status tray Live Caption strings. --> <message name="IDS_ASH_STATUS_TRAY_LIVE_CAPTION" desc="The label used in the accessibility menu of the system tray to toggle on/off Live Caption feature."> Live Caption @@ -5973,7 +5977,7 @@ </message> <!-- Firmware Update App --> - <message name="IDS_ASH_FIRMWARE_UPDATE_APP_TITLE" translateable="false" desc="The title of the firmware update system web app. Firmware update lets users update all their peripheral firmwares in one place."> + <message name="IDS_ASH_FIRMWARE_UPDATE_APP_TITLE" desc="The title of the firmware update system web app. Firmware update lets users update all their peripheral firmwares in one place."> Firmware Updates </message>
diff --git a/ash/ash_strings_grd/IDS_ASH_FIRMWARE_UPDATE_APP_TITLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_FIRMWARE_UPDATE_APP_TITLE.png.sha1 new file mode 100644 index 0000000..9a8691e --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_FIRMWARE_UPDATE_APP_TITLE.png.sha1
@@ -0,0 +1 @@ +2b8ef11b14cd0dc96a173bc581ef6830dce98830 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_AUDIO_NBS_MESSAGE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_AUDIO_NBS_MESSAGE.png.sha1 new file mode 100644 index 0000000..cd97df2 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_AUDIO_NBS_MESSAGE.png.sha1
@@ -0,0 +1 @@ +651c8ee7e24962330cf11cfc8acb70be4a2b917f \ No newline at end of file
diff --git a/ash/capture_mode/capture_mode_game_dashboard_unittests.cc b/ash/capture_mode/capture_mode_game_dashboard_unittests.cc index 33945a2..be44476 100644 --- a/ash/capture_mode/capture_mode_game_dashboard_unittests.cc +++ b/ash/capture_mode/capture_mode_game_dashboard_unittests.cc
@@ -597,6 +597,47 @@ } } +TEST_P(GameDashboardCaptureModeHistogramTest, + GameDashboardEndRecordingReasonHistogram) { + constexpr char kHistogramNameBase[] = "EndRecordingReason"; + + CaptureModeTestApi test_api; + + const std::string histogram_name = BuildHistogramName( + kHistogramNameBase, test_api.GetBehavior(BehaviorType::kDefault), + /*append_ui_mode_suffix=*/true); + + // Testing the game dashboard stop recording button enum. + histogram_tester_.ExpectBucketCount( + histogram_name, + /*sample=*/EndRecordingReason::kGameDashboardStopRecordingButton, + /*expected_count=*/0); + StartGameCaptureModeSession(); + StartVideoRecordingImmediately(); + CaptureModeController::Get()->EndVideoRecording( + EndRecordingReason::kGameDashboardStopRecordingButton); + WaitForCaptureFileToBeSaved(); + histogram_tester_.ExpectBucketCount( + histogram_name, + /*sample=*/EndRecordingReason::kGameDashboardStopRecordingButton, + /*expected_count=*/1); + + // Testing the game toolbar stop recording button enum. + histogram_tester_.ExpectBucketCount( + histogram_name, + /*sample=*/EndRecordingReason::kGameToolbarStopRecordingButton, + /*expected_count=*/0); + StartGameCaptureModeSession(); + StartVideoRecordingImmediately(); + CaptureModeController::Get()->EndVideoRecording( + EndRecordingReason::kGameToolbarStopRecordingButton); + WaitForCaptureFileToBeSaved(); + histogram_tester_.ExpectBucketCount( + histogram_name, + /*sample=*/EndRecordingReason::kGameToolbarStopRecordingButton, + /*expected_count=*/1); +} + INSTANTIATE_TEST_SUITE_P(All, GameDashboardCaptureModeHistogramTest, ::testing::Bool());
diff --git a/ash/capture_mode/capture_mode_metrics.h b/ash/capture_mode/capture_mode_metrics.h index d24861b..8f6408e 100644 --- a/ash/capture_mode/capture_mode_metrics.h +++ b/ash/capture_mode/capture_mode_metrics.h
@@ -40,7 +40,9 @@ kLowDriveFsQuota, kVideoEncoderReconfigurationFailure, kKeyboardShortcut, - kMaxValue = kKeyboardShortcut, + kGameDashboardStopRecordingButton, + kGameToolbarStopRecordingButton, + kMaxValue = kGameToolbarStopRecordingButton, }; // Enumeration of capture bar buttons that can be pressed while in capture mode.
diff --git a/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.cc b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.cc index 8c5f4bf..466c7c4 100644 --- a/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.cc +++ b/ash/components/arc/compat_mode/arc_splash_screen_dialog_view.cc
@@ -10,18 +10,21 @@ #include "ash/components/arc/compat_mode/style/arc_color_provider.h" #include "ash/components/arc/vector_icons/vector_icons.h" #include "ash/frame/non_client_frame_view_ash.h" +#include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" #include "base/auto_reset.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/notreached.h" #include "base/scoped_multi_source_observation.h" #include "base/task/sequenced_task_runner.h" +#include "chromeos/constants/chromeos_features.h" #include "chromeos/ui/frame/default_frame_header.h" #include "components/strings/grit/components_strings.h" #include "components/vector_icons/vector_icons.h" #include "ui/aura/client/aura_constants.h" #include "ui/aura/window.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/base/resource/resource_bundle.h" #include "ui/color/color_id.h" #include "ui/color/color_provider.h" #include "ui/gfx/canvas.h" @@ -172,10 +175,15 @@ /*adjust_height_for_width=*/true)); constexpr gfx::Size kLogoImageSize(152, 126); + auto image = + chromeos::features::IsJellyEnabled() + ? ui::ResourceBundle::GetSharedInstance().GetThemedLottieImageNamed( + IDR_ARC_COMPAT_MODE_SPLASH_SCREEN_IMAGE) + : ui::ImageModel::FromVectorIcon(kCompatModeSplashscreenIcon, + background_color_id_, + kLogoImageSize.width()); AddChildView(views::Builder<views::ImageView>() // Logo - .SetImage(ui::ImageModel::FromVectorIcon( - kCompatModeSplashscreenIcon, background_color_id_, - kLogoImageSize.width())) + .SetImage(image) .Build()); AddChildView(views::Builder<views::Label>() // Header .SetText(l10n_util::GetStringUTF16(
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index dd74f0af..d3ca7fd4 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -53,12 +53,6 @@ "AllowAmbientEQ", base::FEATURE_DISABLED_BY_DEFAULT); -// Allows DevTools to open from the context menu and shortcut keys in Ash if -// Lacros is the only browser. -BASE_FEATURE(kAllowDevtoolsInSystemUI, - "kAllowDevtoolsInSystemUI", - base::FEATURE_DISABLED_BY_DEFAULT); - // Allows network connections which use EAP methods that validate the // server certificate to use the default server CA certificate without // verifying the servers identity. @@ -171,6 +165,11 @@ "AssistantNativeIcons", base::FEATURE_ENABLED_BY_DEFAULT); +// Enables warning in the quick settings when NBS device is in use. +BASE_FEATURE(kAudioHFPNbsWarning, + "AudioHFPNbsWarning", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables Peripheral volume change by hardware reported steps BASE_FEATURE(kAudioPeripheralVolumeGranularity, "AudioPeripheralVolumeGranularity", @@ -226,6 +225,10 @@ "AutocorrectByDefault", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kAutocorrectUseReplaceSurroundingText, + "AutocorrectUseReplaceSurroundingText", + base::FEATURE_DISABLED_BY_DEFAULT); + // If enabled, the autozoom nudge shown prefs will be reset at the start of // each new user session. BASE_FEATURE(kAutozoomNudgeSessionReset, @@ -1823,6 +1826,11 @@ "PrinterSettingsRevamp", base::FEATURE_DISABLED_BY_DEFAULT); +// Enables showing discovered printers in the Print Preview dialog. +BASE_FEATURE(kPrintPreviewDiscoveredPrinters, + "PrintPreviewDiscoveredPrinters", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables showing printer status on the OS Printer Settings UI. BASE_FEATURE(kPrinterSettingsPrinterStatus, "PrinterSettingsPrinterStatus", @@ -1925,7 +1933,7 @@ base::FEATURE_ENABLED_BY_DEFAULT); // Enable or disable quick settings revamped view (go/qsrevamp). -BASE_FEATURE(kQsRevamp, "QsRevamp", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kQsRevamp, "QsRevamp", base::FEATURE_DISABLED_BY_DEFAULT); // Controls whether the Projector Viewer supports the user experience for // secondary account. @@ -1986,6 +1994,9 @@ BASE_FEATURE(kRgbKeyboard, "RgbKeyboard", base::FEATURE_ENABLED_BY_DEFAULT); +// Enables ChromeOS scalable IPH. +BASE_FEATURE(kScalableIph, "ScalableIph", base::FEATURE_DISABLED_BY_DEFAULT); + // If enabled, the jelly colors will be used in the scanning app. Requires // jelly-colors flag to also be enabled. BASE_FEATURE(kScanningAppJelly, @@ -2166,11 +2177,6 @@ constexpr base::FeatureParam<bool> kAutomaticallyLockGroup{ &kSnapGroup, "AutomaticLockGroup", true}; -// Controls whether the speak-on-mute detection feature is enabled or not. -BASE_FEATURE(kSpeakOnMuteEnabled, - "SpeakOnMuteEnabled", - base::FEATURE_DISABLED_BY_DEFAULT); - // Enables battery indicator for styluses in the palette tray BASE_FEATURE(kStylusBatteryStatus, "StylusBatteryStatus", @@ -2479,6 +2485,11 @@ "InputDeviceSettingsSplit", base::FEATURE_ENABLED_BY_DEFAULT); +// Enables peripheral customization to be split per device. +BASE_FEATURE(kPeripheralCustomization, + "PeripheralCustomization", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables or disables whether to store UMA logs per-user and whether metrics // consent is per-user. BASE_FEATURE(kPerUserMetrics, @@ -2524,6 +2535,10 @@ return base::FeatureList::IsEnabled(kSystemSounds); } +bool IsAudioHFPNbsWarningEnabled() { + return base::FeatureList::IsEnabled(kAudioHFPNbsWarning); +} + bool IsAutocompleteExtendedSuggestionsEnabled() { return base::FeatureList::IsEnabled(kAutocompleteExtendedSuggestions); } @@ -2712,6 +2727,10 @@ return base::FeatureList::IsEnabled(kInputDeviceSettingsSplit); } +bool IsPeripheralCustomizationEnabled() { + return base::FeatureList::IsEnabled(kPeripheralCustomization); +} + bool IsDisplayAlignmentAssistanceEnabled() { return base::FeatureList::IsEnabled(kDisplayAlignAssist); } @@ -3344,6 +3363,10 @@ return base::FeatureList::IsEnabled(kPrinterSettingsRevamp); } +bool IsPrintPreviewDiscoveredPrintersEnabled() { + return base::FeatureList::IsEnabled(kPrintPreviewDiscoveredPrinters); +} + bool IsPrivacyIndicatorsEnabled() { // Privacy indicators should not be enabled when video conference is enabled. return base::FeatureList::IsEnabled(kPrivacyIndicators) && @@ -3449,6 +3472,10 @@ kEnableSamlNotificationOnPasswordChangeSuccess); } +bool IsScalableIphEnabled() { + return base::FeatureList::IsEnabled(kScalableIph); +} + bool IsSeparateNetworkIconsEnabled() { return base::FeatureList::IsEnabled(kSeparateNetworkIcons); } @@ -3507,10 +3534,6 @@ return base::FeatureList::IsEnabled(kSnapGroup); } -bool IsSpeakOnMuteEnabled() { - return base::FeatureList::IsEnabled(kSpeakOnMuteEnabled); -} - bool IsSystemTrayShadowEnabled() { return base::FeatureList::IsEnabled(kSystemTrayShadow); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 20a68a8..ae8242a 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -20,7 +20,6 @@ BASE_DECLARE_FEATURE(kAdaptiveChargingForTesting); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAdjustSplitViewForVK); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAllowAmbientEQ); -COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAllowDevtoolsInSystemUI); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAllowEapDefaultCasWithoutSubjectVerification); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAllowRepeatedUpdates); @@ -53,6 +52,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAssistMultiWord); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAssistMultiWordExpanded); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAssistantNativeIcons); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAudioHFPNbsWarning); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAudioPeripheralVolumeGranularity); COMPONENT_EXPORT(ASH_CONSTANTS) @@ -68,6 +68,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutocorrectToggle); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutocorrectByDefault); COMPONENT_EXPORT(ASH_CONSTANTS) +BASE_DECLARE_FEATURE(kAutocorrectUseReplaceSurroundingText); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAutozoomNudgeSessionReset); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kAvatarsCloudMigration); COMPONENT_EXPORT(ASH_CONSTANTS) @@ -160,6 +162,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kInputDeviceSettingsSplit); COMPONENT_EXPORT(ASH_CONSTANTS) +BASE_DECLARE_FEATURE(kPeripheralCustomization); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kDiacriticsOnPhysicalKeyboardLongpress); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kDiacriticsOnPhysicalKeyboardLongpressDefaultOn); @@ -529,6 +533,8 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPrinterSettingsRevamp); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPrintManagementJelly); COMPONENT_EXPORT(ASH_CONSTANTS) +BASE_DECLARE_FEATURE(kPrintPreviewDiscoveredPrinters); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPrintManagementSetupAssistance); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kPrivacyIndicators); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kProductivityLauncher); @@ -577,6 +583,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kRenderArcNotificationsByChrome); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSameAppWindowCycle); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScalableIph); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScanningAppJelly); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScreenSaverDuration); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kScreenSaverPreview); @@ -623,7 +630,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) extern const base::FeatureParam<bool> kAutomaticallyLockGroup; COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSnoopingProtection); -COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kSpeakOnMuteEnabled); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kStylusBatteryStatus); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kStartAssistantAudioDecoderOnDemand); @@ -727,6 +733,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAudioPeripheralVolumeGranularityEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAutoNightLightEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsAudioHFPNbsWarningEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBackgroundBlurEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsBluetoothQualityReportEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsCalendarJellyEnabled(); @@ -748,6 +755,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsDeskButtonEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsDeskTemplateSyncEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsInputDeviceSettingsSplitEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPeripheralCustomizationEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsDnsOverHttpsWithIdentifiersReuseOldPolicyEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsDnsOverHttpsWithIdentifiersEnabled(); @@ -911,6 +919,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPrivacyIndicatorsEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPrinterSettingsPrinterStatusEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPrinterSettingsRevampEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsPrintPreviewDiscoveredPrintersEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProductivityLauncherEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProductivityLauncherImageSearchEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsProjectorEnabled(); @@ -946,6 +955,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSameAppWindowCycleEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSamlNotificationOnPasswordChangeSuccessEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsScalableIphEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsScreenSaverDurationEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsScreenSaverPreviewEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSeparateNetworkIconsEnabled(); @@ -966,7 +976,6 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSmdsDbusMigrationEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSnoopingProtectionEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSnapGroupEnabled(); -COMPONENT_EXPORT(ASH_CONSTANTS) bool IsSpeakOnMuteEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsStartAssistantAudioDecoderOnDemandEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsImeTrayHideVoiceButtonEnabled();
diff --git a/ash/constants/ash_pref_names.cc b/ash/constants/ash_pref_names.cc index bf3e46d4..ce632f74 100644 --- a/ash/constants/ash_pref_names.cc +++ b/ash/constants/ash_pref_names.cc
@@ -47,6 +47,9 @@ const char kManagedCellularIccidSmdpPair[] = "cros_esim.managed_iccid_smdp_pair"; +// A boolean pref for whether playing charging sounds is enabled. +const char kChargingSoundsEnabled[] = "ash.charging_sounds.enabled"; + // A dictionary pref to hold the mute setting for all the currently known // audio devices. const char kAudioDevicesMute[] = "settings.audio.devices.mute";
diff --git a/ash/constants/ash_pref_names.h b/ash/constants/ash_pref_names.h index f410b32..997cdea 100644 --- a/ash/constants/ash_pref_names.h +++ b/ash/constants/ash_pref_names.h
@@ -28,6 +28,7 @@ extern const char kEmojiSuggestionEnabled[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kEmojiSuggestionEnterpriseAllowed[]; +COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kChargingSoundsEnabled[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kAudioDevicesMute[]; COMPONENT_EXPORT(ASH_CONSTANTS) extern const char kAudioDevicesGainPercent[];
diff --git a/ash/public/cpp/input_device_settings_controller.h b/ash/public/cpp/input_device_settings_controller.h index cb6d897..123dc90d 100644 --- a/ash/public/cpp/input_device_settings_controller.h +++ b/ash/public/cpp/input_device_settings_controller.h
@@ -82,6 +82,9 @@ // settings. virtual const mojom::MousePolicies& GetMousePolicies() = 0; + // Restore the keyboard modifier remappings to its default mappings for + // keyboard of `id`. + virtual void RestoreDefaultKeyboardModifierRemappings(DeviceId id) = 0; // Configure the settings for keyboard of `id` with the provided // `settings`. virtual void SetKeyboardSettings(DeviceId id,
diff --git a/ash/public/cpp/resources/ash_public_unscaled_resources.grd b/ash/public/cpp/resources/ash_public_unscaled_resources.grd index 4a90b08..970f6ee 100644 --- a/ash/public/cpp/resources/ash_public_unscaled_resources.grd +++ b/ash/public/cpp/resources/ash_public_unscaled_resources.grd
@@ -38,8 +38,8 @@ <structure type="lottie" name="IDR_PHONE_HUB_ONBOARDING_IMAGE" file="unscaled_resources/phone_hub_onboarding_image.json" compress="gzip" /> <structure type="lottie" name="IDR_PHONE_HUB_CONNECTING_IMAGE" file="unscaled_resources/phone_hub_connecting_image.json" compress="gzip" /> <structure type="lottie" name="IDR_PHONE_HUB_ERROR_STATE_IMAGE" file="unscaled_resources/phone_hub_error_state_image.json" compress="gzip" /> - <structure type="lottie" name="IDR_SHARESHEET_EMPTY_STATE_IMAGE" file="unscaled_resources/sharesheet_empty_state_image.json" compress="gzip" /> <structure type="lottie" name="IDR_HOLDING_SPACE_RECENT_FILES_PLACEHOLDER_IMAGE" file="unscaled_resources/holding_space_recent_files_placeholder_image.json" compress="gzip" /> + <structure type="lottie" name="IDR_ARC_COMPAT_MODE_SPLASH_SCREEN_IMAGE" file="unscaled_resources/arc_compat_mode_splash_screen_image.json" compress="gzip" /> </structures> </release> </grit>
diff --git a/ash/public/cpp/resources/unscaled_resources/arc_compat_mode_splash_screen_image.json b/ash/public/cpp/resources/unscaled_resources/arc_compat_mode_splash_screen_image.json new file mode 100644 index 0000000..5123e9a4 --- /dev/null +++ b/ash/public/cpp/resources/unscaled_resources/arc_compat_mode_splash_screen_image.json
@@ -0,0 +1 @@ +{"layers":[{"ddd":0,"ty":4,"ind":0,"sr":1,"ip":0,"op":60,"st":0,"ks":{"a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[133.33333333333331,133.33333333333331],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}},"ao":0,"bm":0,"shapes":[{"nm":"surface1","ty":"gr","it":[{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0,2.550781999999998],[2.546875,0],[0,-2.546875],[-2.5507810000000006,0]],"o":[[2.546875,0],[0,-2.546875],[-2.5507810000000006,0],[0,2.550781999999998],[0,0]],"v":[[33.578125,61.558594],[38.191406,56.941406],[33.578125,52.328125],[28.960938,56.941406],[33.578125,61.558594]]},"a":0}},{"nm":"cros.sys.illo.secondary","ty":"fl","o":{"k":100,"a":0},"c":{"k":[0.8862745098039215,0.8823529411764706,0.9254901960784314,1],"a":0}},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0.34375,0.6640629999999987],[-4.074218999999999,2.9726560000000006],[-3.40625,-3.5351560000000006],[0.59375,-0.43359399999999937]],"o":[[-0.59375,0.4335930000000019],[-2.3242189999999994,-4.324218000000002],[4.074218999999999,-2.96875],[0.5234379999999987,0.53125],[0,0]],"v":[[88.4375,39.949219],[86.648438,39.539062],[89.574219,26.773438],[102.625,27.890625],[102.464844,29.71875]]},"a":0}},{"nm":"cros.sys.illo.color3","ty":"fl","o":{"k":100,"a":0},"c":{"k":[0.9333333333333333,0.596078431372549,0.1607843137254902,1],"a":0}},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[-1.4648439999999994,0.3320319999999981],[0,0],[-0.023437999999998738,0.003906999999998106],[-0.007812000000001262,0.003906000000000631],[0,0],[-0.5429689999999994,0.06640600000000063],[-0.953125,-0.2773430000000019],[1.34375,-3.9023439999999994],[3.3593759999999975,0.6445310000000006],[0.17187400000000252,0.05859399999999937],[0,0],[0.7460939999999994,0.625],[0.33593700000000126,0.42968700000000126],[0,0],[1.535156999999998,0.03906299999999874],[0,0],[0,0],[0,0],[0.15234399999999937,0.03906299999999874],[-0.734375,2.644531999999998],[-2.609375,-0.765625],[-0.12890600000000063,-0.05468799999999874],[-0.06640600000000063,-0.023437000000001262],[-0.019531999999998106,-0.011718999999999369]],"o":[[1.3046879999999987,0.7968740000000025],[0,0],[0.02734399999999937,-0.003906000000000631],[0.011718999999999369,-0.003906000000000631],[0,0],[0.5,-0.1875],[0.9140629999999987,-0.12109399999999937],[3.8671879999999987,1.128906999999998],[-1.1210939999999994,3.2734370000000013],[-0.1875,-0.035156999999998106],[0,0],[-0.9882810000000006,-0.26953100000000063],[-0.41015600000000063,-0.3593759999999975],[0,0],[-1.0742189999999994,-1.113281999999998],[0,0],[-0.03515600000000063,0.007812999999998738],[0,0],[-0.15625,-0.02734399999999937],[-2.671875,-0.6914060000000006],[0.7226560000000006,-2.6289060000000006],[0.12890600000000063,0.03906299999999874],[0.0664069999999981,0.023437000000001262],[0,0],[0,0]],"v":[[95.375,51.210938],[99.683594,51.910156],[99.683594,51.925781],[99.761719,51.914062],[99.789062,51.90625],[101.472656,51.476562],[103.050781,51.085938],[105.863281,51.300781],[110.574219,60.546875],[102.726562,65.136719],[102.179688,65.003906],[102.175781,64.988281],[99.558594,63.617188],[98.429688,62.421875],[97.214844,61.152344],[93.132812,59.347656],[91.160156,59.300781],[90.304688,59.246094],[90.289062,59.25],[89.832031,59.144531],[86.296875,52.941406],[92.339844,49.535156],[92.726562,49.679688],[92.921875,49.753906],[93.683594,50.175781]]},"a":0}},{"nm":"cros.sys.illo.color5","ty":"fl","o":{"k":100,"a":0},"c":{"k":[0.7764705882352941,0.6274509803921569,0.7490196078431373,1],"a":0}},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0,-2.0703120000000013],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[2.0703129999999987,0]],"o":[[-2.0703120000000013,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,-2.0703120000000013],[0,0]],"v":[[19.382812,15],[15.632812,18.75],[15.632812,71.710938],[10.5,71.710938],[10.5,77.25],[104.652344,77.25],[104.652344,71.710938],[99.519531,71.710938],[99.519531,18.75],[95.769531,15]]},"a":0}},{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0,0],[0,0],[0,0]],"o":[[0,0],[0,0],[0,0],[0,0]],"v":[[20.132812,70.382812],[20.132812,19.5],[95.019531,19.5],[95.019531,70.382812]]},"a":0}},{"nm":"cros.sys.illo.color1.1","ty":"fl","o":{"k":100,"a":0},"c":{"k":[0.7058823529411765,0.7725490196078432,1,1],"a":0},"r":2},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0,0],[-1.363281999999998,-2.5195310000000006],[2.9609379999999987,-1.6015620000000013]],"o":[[0,0],[2.6484370000000013,-0.6992189999999994],[1.6015620000000013,2.957031999999998],[0,0]],"v":[[64.210938,54.441406],[64.210938,40.832031],[71.085938,43.820312],[68.632812,52.050781]]},"a":0}},{"nm":"cros.sys.illo.color4","ty":"fl","o":{"k":100,"a":0},"c":{"k":[1,0.32941176470588235,0.28627450980392155,1],"a":0},"r":2},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0,0],[-1.5976560000000006,-2.9570310000000006],[2.9570310000000006,-1.6015620000000013],[0,0],[1.6015620000000013,2.9570310000000006],[-2.9296879999999987,1.5859379999999987]],"o":[[0,0],[2.9570310000000006,-1.597656999999998],[1.6015620000000013,2.957031999999998],[0,0],[-2.9570310000000006,1.5976560000000006],[-1.5976560000000006,-2.9609379999999987],[0,0]],"v":[[48.917969,48.90625],[62.863281,41.367188],[71.089844,43.820312],[68.636719,52.050781],[54.695312,59.589844],[46.464844,57.136719],[48.917969,48.90625]]},"a":0}},{"nm":"cros.sys.illo.secondary","ty":"fl","o":{"k":100,"a":0},"c":{"k":[0.8862745098039215,0.8823529411764706,0.9254901960784314,1],"a":0}},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0,0],[0.59375,-0.6054689999999994],[0,0],[-0.828125,-0.21875],[0,0],[0.2304680000000019,0.8203129999999987]],"o":[[0,0],[-0.23046899999999937,-0.8242189999999994],[0,0],[-0.59375,0.6054689999999994],[0,0],[0.8242189999999994,0.21484399999999937],[0,0]],"v":[[41.933594,41.800781],[37.792969,26.84375],[35.941406,26.359375],[25.058594,37.425781],[25.574219,39.269531],[40.597656,43.160156],[41.933594,41.800781]]},"a":0}},{"nm":"cros.sys.illo.secondary","ty":"fl","o":{"k":100,"a":0},"c":{"k":[0.8862745098039215,0.8823529411764706,0.9254901960784314,1],"a":0}},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"gr","it":[{"ty":"sh","d":1,"ks":{"k":{"c":true,"i":[[0,0],[0,0],[0,-1.1041669999999968],[0,0],[-1.1041659999999922,0],[0,0],[0,1.109375],[0,0],[1.104167000000004,0]],"o":[[0,0],[-1.1041659999999922,0],[0,0],[0,1.109375],[0,0],[1.104167000000004,0],[0,0],[0,-1.1041669999999968],[0,0]],"v":[[117.84375,30.385417],[88.614583,30.385417],[86.614583,32.385417],[86.614583,87.458333],[88.614583,89.458333],[117.84375,89.458333],[119.84375,87.458333],[119.84375,32.385417],[117.84375,30.385417]]},"a":0}},{"nm":"cros.sys.illo.color1","ty":"st","lc":2,"lj":2,"ml":10,"o":{"k":100,"a":0},"w":{"k":1.90881,"a":0},"c":{"k":[0.24705882352941178,0.35294117647058826,0.6627450980392157,1],"a":0}},{"nm":"cros.sys.illo.color1","ty":"fl","o":{"k":100,"a":0},"c":{"k":[0.24705882352941178,0.35294117647058826,0.6627450980392157,1],"a":0}},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[75,75],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]},{"ty":"tr","a":{"k":[0,0],"a":0},"p":{"k":[0,0],"a":0},"s":{"k":[100,100],"a":0},"r":{"k":0,"a":0},"o":{"k":100,"a":0},"sk":{"k":0,"a":0},"sa":{"k":0,"a":0}}]}]}],"v":"5.5.2","fr":60,"ip":0,"op":60,"w":152,"h":126,"ddd":0,"assets":[]} \ No newline at end of file
diff --git a/ash/public/cpp/resources/unscaled_resources/sharesheet_empty_state_image.json b/ash/public/cpp/resources/unscaled_resources/sharesheet_empty_state_image.json deleted file mode 100644 index eb04f24..0000000 --- a/ash/public/cpp/resources/unscaled_resources/sharesheet_empty_state_image.json +++ /dev/null
@@ -1 +0,0 @@ -{"v":"5.8.1","fr":30,"ip":0,"op":1,"w":200,"h":160,"nm":"Empty Sharesheet","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Empty Sharesheet/Sharesheet illo Lottie Ready Outlines","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[100,80,0],"ix":2,"l":2},"a":{"a":0,"k":[83.5,66,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.845,0.664],[-1.865,-0.692]],"o":[[-1.857,-0.738],[1.8,0.758]],"v":[[-4.002,8.294],[-2.916,5.49]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-2.101,0.846],[-0.457,0.263],[2.886,-3.399],[0,0],[-2.021,-2.425],[-0.123,-0.776],[1.04,-0.863],[0.476,-0.222],[0.341,-0.138],[0.584,-1.508]],"o":[[0.8,-2.068],[0.657,-0.253],[3.592,-2.155],[0,0],[1.937,-2.405],[0.541,0.615],[0.264,1.298],[-0.439,0.389],[-0.469,0.208],[-1.578,0.604],[0,0]],"v":[[-3.118,3.127],[0.597,-0.766],[2.268,-1.541],[-1.949,-5.077],[-3.388,-6.472],[4.454,-6.533],[5.449,-4.447],[4.165,-0.604],[2.794,0.313],[1.577,0.832],[-1.199,3.87]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541176470588,0.705882352941,0.972549079446,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[131.715,14.308],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":4,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.155,0.296],[0,0],[-0.941,-0.705],[0,0],[-0.305,0.214],[0,0],[-0.365,0.143],[0,0]],"o":[[0,0],[-1.095,0.428],[0,0],[0.352,-0.123],[0,0],[-0.314,-0.235],[0,0],[-0.078,-0.326]],"v":[[2.457,-2.847],[-1.512,-1.296],[-1.866,1.301],[0.198,2.847],[1.189,2.34],[-1.266,0.501],[-1.148,-0.365],[2.807,-1.91]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[102.604,10.502],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 2","np":2,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.493,0.112],[4.098,-7.463],[3.258,-2.108],[-0.829,0.533],[-1.731,3.755],[-2.851,2.928],[-1.984,-9.198],[-0.405,0.089],[0.089,0.405]],"o":[[-10.013,-0.268],[-1.615,3.526],[-0.816,0.531],[3.47,-2.248],[2.02,-3.654],[4.638,-5.16],[0.088,0.405],[0.404,-0.088],[-0.737,-3.368]],"v":[[-19.216,-4.759],[-38.491,11.228],[-45.943,19.861],[-45.127,21.12],[-37.165,11.929],[-30.107,1.487],[-12.967,2.751],[-12.074,3.323],[-11.502,2.43]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[-5.043,-1.799],[0,0],[-0.685,2.127],[2.128,0.686]],"o":[[-5.14,-1.484],[0,0],[2.128,0.686],[0.686,-2.128],[0,0]],"v":[[32.924,-20.169],[30.44,-12.463],[40.979,-9.066],[46.073,-11.676],[43.463,-16.771]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[59.294,22.621],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 3","np":4,"cix":2,"bm":0,"ix":3,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.111,-0.762],[0,0],[0.606,0.462],[0,0],[-1.445,0.574]],"o":[[0.715,-0.284],[0,0],[-0.111,0.755],[0,0],[-1.237,-0.943],[0,0]],"v":[[3.126,-4.945],[4.485,-3.87],[3.319,4.116],[1.723,4.767],[-3.359,0.893],[-2.885,-2.557]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.984313785329,0.737254901961,0.01568627451,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color3","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[105.007,11.481],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 4","np":2,"cix":2,"bm":0,"ix":4,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.563,0.841],[0.344,0.23],[0.23,-0.345],[0.678,-0.454],[-0.818,0.543]],"o":[[0.23,-0.344],[-0.344,-0.231],[-0.454,0.677],[-0.812,0.548],[0.841,-0.563]],"v":[[1.772,-0.7],[1.566,-1.74],[0.526,-1.534],[-1.19,0.182],[-0.355,1.428]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[59.894,17.09],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 5","np":2,"cix":2,"bm":0,"ix":5,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.153,-1.066],[0.407,0.08],[-0.08,0.406],[0.161,0.803]],"o":[[0.52,0.976],[-0.081,0.406],[-0.406,-0.08],[0.165,-0.803],[0,0]],"v":[[0.423,-2.022],[0.609,1.352],[-0.273,1.942],[-0.863,1.061],[-0.872,-1.434]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[62.21,12.258],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 6","np":2,"cix":2,"bm":0,"ix":6,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.006,0.457],[0,0],[-0.457,-1.006],[0,0],[1.006,-0.457],[0,0],[0.457,1.006],[0,0]],"o":[[0,0],[1.006,-0.456],[0,0],[0.457,1.006],[0,0],[-1.006,0.457],[0,0],[-0.457,-1.006]],"v":[[-6.032,-3.775],[1.126,-7.027],[3.774,-6.033],[7.026,1.126],[6.032,3.773],[-1.126,7.025],[-3.774,6.031],[-7.026,-1.127]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.945098099054,0.952941236309,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_SecondaryColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[63.982,16.138],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 7","np":2,"cix":2,"bm":0,"ix":7,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.716,0.145],[4.716,-0.145]],"o":[[4.718,0.146],[-4.718,-0.146]],"v":[[0,-3.569],[0,3.569]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.933333393172,0.372549019608,0.980392216701,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color5","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.947,5.651],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 8","np":2,"cix":2,"bm":0,"ix":8,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.647,-1.097],[0,0],[1.646,1.097],[0,0]],"o":[[0,0],[1.606,1.15],[0,0],[-1.607,-1.15]],"v":[[-1.094,-2.584],[2.805,0.109],[1.095,2.584],[-2.804,-0.109]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.917647118662,0.262745098039,0.207843152214,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color4","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[4.661,43.898],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 9","np":2,"cix":2,"bm":0,"ix":9,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.134,1.122],[-0.722,0.074],[-0.25,-1.005],[0.761,-0.057]],"o":[[0.25,-1.006],[0.723,0.074],[0.133,1.122],[-0.76,-0.056]],"v":[[-2.094,6.846],[0,6.375],[2.095,6.846],[0,7.875]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.344,-0.23],[0.71,-0.541],[0.231,0.344],[-0.344,0.231],[-0.453,0.678]],"o":[[1.154,0.894],[-0.345,0.23],[-0.23,-0.345],[0.678,-0.454],[0.231,-0.344]],"v":[[6.207,3.408],[4.286,6.576],[3.245,6.37],[3.451,5.329],[5.166,3.614]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.344,0.231],[-0.231,-0.344],[-0.678,-0.454],[0.23,-0.345],[0.541,0.71]],"o":[[0.344,-0.23],[0.453,0.678],[0.344,0.231],[-0.894,1.154],[-0.23,-0.345]],"v":[[-6.206,3.408],[-5.165,3.614],[-3.45,5.329],[-3.244,6.37],[-6.412,4.449]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[-1.122,-0.134],[-0.075,-0.722],[1.005,-0.25],[0.057,0.76]],"o":[[1.005,0.25],[-0.074,0.723],[-1.123,0.133],[0.056,-0.761]],"v":[[-6.683,-1.932],[-6.211,0.163],[-6.683,2.258],[-7.711,0.163]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[-1.005,0.25],[-0.057,-0.76],[1.122,0.134],[0.074,0.723]],"o":[[1.122,-0.133],[-0.056,0.761],[-1.006,-0.25],[0.074,-0.722]],"v":[[6.684,-1.932],[7.712,0.163],[6.684,2.258],[6.212,0.163]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[-0.23,0.344],[-0.541,-0.71],[0.344,-0.231],[0.231,0.344],[0.678,0.453]],"o":[[0.894,-1.154],[0.23,0.344],[-0.344,0.23],[-0.453,-0.678],[-0.344,-0.231]],"v":[[3.245,-6.044],[6.413,-4.122],[6.207,-3.081],[5.166,-3.288],[3.451,-5.003]],"c":true},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":6,"ty":"sh","ix":7,"ks":{"a":0,"k":{"i":[[-0.231,-0.344],[0.344,-0.231],[0.453,-0.678],[0.344,0.23],[-0.71,0.541]],"o":[[0.23,0.344],[-0.678,0.453],[-0.231,0.344],[-1.154,-0.894],[0.344,-0.23]],"v":[[-3.244,-6.044],[-3.45,-5.003],[-5.165,-3.288],[-6.206,-3.081],[-4.285,-6.249]],"c":true},"ix":2},"nm":"Path 7","mn":"ADBE Vector Shape - Group","hd":false},{"ind":7,"ty":"sh","ix":8,"ks":{"a":0,"k":{"i":[[-0.962,0.194],[0.186,-1.448],[0.406,0.08],[0.779,-0.157]],"o":[[0.879,-0.12],[-0.081,0.406],[-0.779,-0.157],[-0.962,0.186]],"v":[[-1.504,-7.402],[2.095,-6.521],[1.214,-5.931],[-1.213,-5.931]],"c":true},"ix":2},"nm":"Path 8","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[55.254,11.943],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 10","np":10,"cix":2,"bm":0,"ix":10,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.031,1.122],[-0.736,0.077],[-0.163,-1.063],[0.755,-0.067]],"o":[[0.164,-1.063],[0.736,0.077],[0.03,1.123],[-0.756,-0.067]],"v":[[-2.149,13.961],[0,13.342],[2.149,13.961],[0,14.862]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[-0.198,-0.37],[0.37,-0.199],[0.947,-0.286],[0.122,0.402],[-0.401,0.121],[-0.77,0.412]],"o":[[0.199,0.37],[-0.856,0.459],[-0.402,0.122],[-0.121,-0.401],[0.85,-0.258],[0.37,-0.198]],"v":[[7.365,12.069],[7.054,13.098],[4.344,14.221],[3.396,13.714],[3.903,12.767],[6.337,11.758]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.198,0.37],[-0.37,-0.198],[-0.849,-0.258],[0.122,-0.401],[0.401,0.122],[0.857,0.459]],"o":[[0.199,-0.37],[0.77,0.412],[0.402,0.121],[-0.121,0.402],[-0.947,-0.286],[-0.37,-0.199]],"v":[[-7.366,12.069],[-6.337,11.758],[-3.904,12.767],[-3.397,13.714],[-4.344,14.221],[-7.055,13.098]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[-0.325,-0.267],[0.267,-0.325],[0.757,-0.622],[0.266,0.325],[-0.325,0.266],[-0.559,0.68]],"o":[[0.324,0.266],[-0.622,0.756],[-0.325,0.267],[-0.266,-0.324],[0.68,-0.559],[0.266,-0.325]],"v":[[11.461,8.323],[11.565,9.393],[9.492,11.466],[8.422,11.361],[8.527,10.292],[10.391,8.428]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[-0.324,0.266],[-0.266,-0.325],[-0.68,-0.559],[0.266,-0.324],[0.324,0.267],[0.621,0.756]],"o":[[0.325,-0.267],[0.559,0.68],[0.324,0.266],[-0.267,0.325],[-0.757,-0.622],[-0.267,-0.325]],"v":[[-11.461,8.323],[-10.391,8.428],[-8.527,10.292],[-8.422,11.361],[-9.492,11.466],[-11.565,9.393]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[-0.401,0.122],[-0.122,-0.402],[-0.412,-0.77],[0.37,-0.198],[0.198,0.37],[0.287,0.947]],"o":[[0.402,-0.122],[0.257,0.85],[0.198,0.37],[-0.37,0.198],[-0.459,-0.857],[-0.121,-0.402]],"v":[[-13.814,3.297],[-12.866,3.804],[-11.857,6.238],[-12.168,7.266],[-13.197,6.955],[-14.321,4.245]],"c":true},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ind":6,"ty":"sh","ix":7,"ks":{"a":0,"k":{"i":[[-0.402,-0.122],[0.122,-0.402],[0.459,-0.857],[0.37,0.198],[-0.198,0.37],[-0.258,0.85]],"o":[[0.401,0.122],[-0.286,0.947],[-0.198,0.37],[-0.37,-0.198],[0.412,-0.77],[0.122,-0.402]],"v":[[13.814,3.297],[14.32,4.245],[13.197,6.955],[12.168,7.266],[11.857,6.238],[12.866,3.804]],"c":true},"ix":2},"nm":"Path 7","mn":"ADBE Vector Shape - Group","hd":false},{"ind":7,"ty":"sh","ix":8,"ks":{"a":0,"k":{"i":[[-1.063,0.163],[-0.067,-0.755],[1.123,0.031],[0.077,0.736]],"o":[[1.123,-0.031],[-0.067,0.755],[-1.063,-0.164],[0.077,-0.736]],"v":[[14.06,-2.248],[14.961,-0.099],[14.06,2.05],[13.441,-0.099]],"c":true},"ix":2},"nm":"Path 8","mn":"ADBE Vector Shape - Group","hd":false},{"ind":8,"ty":"sh","ix":9,"ks":{"a":0,"k":{"i":[[-1.123,-0.031],[-0.077,-0.737],[1.062,-0.163],[0.067,0.755]],"o":[[1.062,0.163],[-0.077,0.736],[-1.123,0.031],[0.067,-0.755]],"v":[[-14.06,-2.248],[-13.441,-0.099],[-14.06,2.05],[-14.961,-0.099]],"c":true},"ix":2},"nm":"Path 9","mn":"ADBE Vector Shape - Group","hd":false},{"ind":9,"ty":"sh","ix":10,"ks":{"a":0,"k":{"i":[[-0.37,-0.198],[0.198,-0.37],[0.257,-0.849],[0.402,0.122],[-0.121,0.401],[-0.459,0.857]],"o":[[0.37,0.198],[-0.412,0.769],[-0.122,0.402],[-0.401,-0.121],[0.287,-0.947],[0.198,-0.37]],"v":[[-12.168,-7.465],[-11.857,-6.436],[-12.866,-4.003],[-13.814,-3.496],[-14.321,-4.443],[-13.197,-7.154]],"c":true},"ix":2},"nm":"Path 10","mn":"ADBE Vector Shape - Group","hd":false},{"ind":10,"ty":"sh","ix":11,"ks":{"a":0,"k":{"i":[[-0.37,0.198],[-0.198,-0.37],[-0.286,-0.947],[0.401,-0.121],[0.122,0.402],[0.412,0.769]],"o":[[0.37,-0.198],[0.459,0.857],[0.122,0.401],[-0.402,0.122],[-0.258,-0.849],[-0.198,-0.37]],"v":[[12.168,-7.465],[13.197,-7.154],[14.32,-4.443],[13.814,-3.496],[12.866,-4.003],[11.857,-6.436]],"c":true},"ix":2},"nm":"Path 11","mn":"ADBE Vector Shape - Group","hd":false},{"ind":11,"ty":"sh","ix":12,"ks":{"a":0,"k":{"i":[[-0.267,-0.324],[0.324,-0.267],[0.559,-0.681],[0.325,0.266],[-0.267,0.324],[-0.757,0.622]],"o":[[0.266,0.324],[-0.68,0.559],[-0.266,0.324],[-0.324,-0.267],[0.621,-0.757],[0.324,-0.266]],"v":[[-8.422,-11.56],[-8.527,-10.49],[-10.391,-8.626],[-11.461,-8.521],[-11.565,-9.591],[-9.492,-11.665]],"c":true},"ix":2},"nm":"Path 12","mn":"ADBE Vector Shape - Group","hd":false},{"ind":12,"ty":"sh","ix":13,"ks":{"a":0,"k":{"i":[[-0.266,0.324],[-0.325,-0.266],[-0.622,-0.757],[0.324,-0.267],[0.266,0.324],[0.68,0.559]],"o":[[0.266,-0.324],[0.757,0.622],[0.267,0.324],[-0.325,0.266],[-0.559,-0.681],[-0.325,-0.267]],"v":[[8.422,-11.56],[9.492,-11.665],[11.565,-9.591],[11.461,-8.521],[10.391,-8.626],[8.527,-10.49]],"c":true},"ix":2},"nm":"Path 13","mn":"ADBE Vector Shape - Group","hd":false},{"ind":13,"ty":"sh","ix":14,"ks":{"a":0,"k":{"i":[[-0.121,-0.401],[0.402,-0.122],[0.77,-0.412],[0.199,0.37],[-0.37,0.198],[-0.947,0.287]],"o":[[0.122,0.402],[-0.849,0.257],[-0.37,0.198],[-0.198,-0.37],[0.857,-0.459],[0.401,-0.122]],"v":[[-3.397,-13.913],[-3.904,-12.965],[-6.337,-11.956],[-7.366,-12.267],[-7.055,-13.296],[-4.344,-14.42]],"c":true},"ix":2},"nm":"Path 14","mn":"ADBE Vector Shape - Group","hd":false},{"ind":14,"ty":"sh","ix":15,"ks":{"a":0,"k":{"i":[[-0.121,0.402],[-0.402,-0.122],[-0.856,-0.459],[0.199,-0.37],[0.37,0.198],[0.85,0.257]],"o":[[0.122,-0.401],[0.947,0.287],[0.37,0.198],[-0.198,0.37],[-0.77,-0.412],[-0.401,-0.122]],"v":[[3.396,-13.913],[4.344,-14.42],[7.054,-13.296],[7.365,-12.267],[6.337,-11.956],[3.903,-12.965]],"c":true},"ix":2},"nm":"Path 15","mn":"ADBE Vector Shape - Group","hd":false},{"ind":15,"ty":"sh","ix":16,"ks":{"a":0,"k":{"i":[[-0.99,0.101],[-0.963,-0.094],[0.04,-0.418],[0.418,0.041],[0.866,-0.085]],"o":[[0.962,-0.094],[0.418,0.041],[-0.041,0.417],[-0.866,-0.085],[-0.989,0.092]],"v":[[-1.466,-14.99],[1.466,-14.99],[2.149,-14.159],[1.319,-13.477],[-1.319,-13.477]],"c":true},"ix":2},"nm":"Path 16","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.945098099054,0.952941236309,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_SecondaryColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[131.083,15.334],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 11","np":18,"cix":2,"bm":0,"ix":11,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[1.714,0.669],[0.106,0.051],[0.168,-1.37],[0.54,0.207],[-2.425,-1.599],[0.261,0.165],[-0.017,-1.757],[-0.846,-1.252],[1.626,-0.456],[-0.168,-1.067],[-0.433,-0.335],[-1.179,-1.722],[-2.286,-4.779],[-2.993,-0.928],[0.936,0.295],[0.584,1.517],[3.435,4.53],[1.75,1.379],[0.026,0.166],[-0.599,-0.718],[-0.935,-1.77],[0.199,0.795],[3.456,3.603],[-0.584,-0.409],[-1.672,-1.619],[-0.756,-2.316],[0.075,0.942],[0.024,0.072],[4.051,3.472],[-0.424,-0.187],[-1.877,-1.897],[-0.662,-2.712],[-0.403,0.099],[0.098,0.403],[2.275,2.071],[1.325,0.827],[-0.18,0.29],[-0.591,-0.182],[-2.193,-4.468],[-0.242,-3.749],[-1.69,-1.698],[0,0],[0.702,0.793],[0.269,0.464],[0.072,2.192],[0,0],[1.448,3.264],[0,0]],"o":[[-0.228,-0.089],[-1.186,-0.699],[-0.519,-0.251],[-2.449,-0.741],[-0.257,-0.171],[-1.419,-0.904],[0.061,1.571],[-1.339,-0.894],[-1.041,0.328],[0.086,0.542],[1.639,1.292],[3.194,4.264],[0.825,2.092],[0.936,0.286],[-2.81,-0.875],[-2.234,-4.826],[-1.262,-1.836],[-0.135,-0.102],[0.44,-3.233],[1.397,1.621],[0.412,0.707],[-0.885,-5.08],[-0.566,-0.692],[1.968,1.243],[2.217,2.027],[0.143,0.941],[-0.002,-0.073],[-1.154,-5.506],[-0.527,-0.509],[2.49,0.959],[2.069,1.873],[0.098,0.402],[0.402,-0.098],[-0.729,-2.989],[-1.107,-1.115],[-0.271,-0.314],[0.437,-0.568],[1.851,0.742],[1.437,3.392],[0.092,2.783],[0,0],[0.629,0.844],[-0.298,-0.321],[-0.902,-1.45],[0,0],[-0.215,-3.598],[0,0],[-2.493,-5.078]],"v":[[0.803,-17.475],[0.296,-17.683],[-2.718,-16.241],[-4.308,-16.928],[-6.29,-13.157],[-7.066,-13.661],[-10.669,-11.82],[-7.851,-7.971],[-12.358,-9.332],[-13.926,-6.794],[-13.118,-5.429],[-8.865,-0.881],[-4.747,13.575],[1.121,18.096],[1.566,16.664],[-3.366,12.986],[-7.648,-1.759],[-12.192,-6.609],[-12.444,-7.027],[-5.111,-3.613],[-2.493,1.777],[-1.124,1.219],[-9.019,-11.442],[-7.846,-12.379],[-2.371,-8.074],[1.3,-1.611],[2.791,-1.779],[2.752,-1.998],[-5.769,-14.69],[-4.802,-15.511],[1.824,-11.178],[6.015,-4.142],[6.921,-3.592],[7.472,-4.498],[2.862,-12.262],[-0.8,-15.183],[-1.187,-16.18],[0.323,-16.046],[8.469,-9.191],[10.039,2.681],[12.214,9.606],[12.215,9.607],[13.392,8.669],[12.57,7.629],[11.481,1.401],[11.481,1.395],[9.817,-9.848],[9.816,-9.851]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[75.273,71.155],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 12","np":2,"cix":2,"bm":0,"ix":12,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,-2.8],[-1.197,-2.572],[-2.143,-1.072],[0,0],[1.961,7.488],[1,0.5],[-1.201,-1.102],[1.08,0.398],[0.319,-0.089],[-0.867,-0.718],[0,-2.537],[2.52,1.591],[-1.256,-1.309],[-1.515,-2.091],[2.365,1.149],[-1.333,-1.05],[-1.221,-1.78]],"o":[[0.056,2.836],[1.002,2.432],[0,0],[-1.901,-5.403],[-2.7,-5.5],[-1.525,-0.756],[-0.982,-0.6],[-0.316,-0.102],[-0.904,0.251],[1.786,1.588],[-1.849,-2.587],[-1.316,-0.774],[1.814,1.837],[-1.946,-1.769],[-1.516,-0.81],[1.695,1.336],[2.2,2.9]],"v":[[-5.197,5.407],[-3.298,13.607],[2.625,17.349],[13.23,8.819],[10.003,-9.093],[0.803,-16.593],[-0.598,-14.393],[-3.697,-15.893],[-4.949,-15.893],[-5.398,-13.793],[-0.098,-7.393],[-7.066,-12.838],[-8.798,-10.593],[-3.798,-3.793],[-10.298,-8.193],[-11.898,-5.693],[-7.497,-0.993]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[74.496,70.728],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 13","np":3,"cix":2,"bm":0,"ix":13,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.613,1.715],[-1.863,3.383],[0.1,0.4],[-0.5,1.4],[-0.741,-0.077],[-0.5,-0.8],[-1.2,-3.1]],"o":[[-1.173,-1.394],[-1.104,-3.701],[0.2,-0.4],[-0.1,-0.4],[0.134,-0.732],[1,0.1],[1.7,2.5],[0,0]],"v":[[-0.51,12.189],[-3.21,7.489],[-2.01,-3.712],[-2.71,-6.411],[-3.01,-10.911],[-1.41,-12.111],[0.691,-10.312],[4.314,0.483]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":2,"lj":2,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[57.025,76.346],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 14","np":2,"cix":2,"bm":0,"ix":14,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-2.806,5.137],[0.1,0.4],[-2.7,-0.233],[-0.5,-0.8],[-1.135,-3.517]],"o":[[-3.771,-4.482],[0.2,-0.4],[-0.321,-1.284],[1,0.1],[1.7,2.5],[0,0]],"v":[[-0.17,12.266],[-1.67,-3.633],[-2.37,-6.334],[-1.07,-12.034],[1.03,-10.234],[4.476,-0.117]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[56.686,76.268],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 15","np":3,"cix":2,"bm":0,"ix":15,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,7.152],[-7.152,0],[17.173,-0.68]],"o":[[0,-7.152],[17.178,0.682],[-7.152,0]],"v":[[-14.314,-2.359],[-1.364,-15.309],[-1.364,10.592]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[7.98,0],[0,-7.98],[-0.758,19.162]],"o":[[-7.981,0],[0.761,19.167],[0,-7.98]],"v":[[-1.364,-16.809],[-15.814,-2.359],[13.086,-2.359]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[35.08,69.993],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 16","np":4,"cix":2,"bm":0,"ix":16,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-3.041,1.38],[0.895,-0.409],[0.573,-3.79],[-0.158,0.97]],"o":[[0.887,-0.412],[-3.491,1.584],[-0.147,0.967],[0.499,-3.303]],"v":[[3.258,-3.418],[2.628,-4.78],[-3.997,3.984],[-2.516,4.219]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[26.173,61.733],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 17","np":2,"cix":2,"bm":0,"ix":17,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-10.107,0],[0,10.107],[0.96,-24.268]],"o":[[10.107,0],[-0.964,-24.274],[0,10.107]],"v":[[0,21.287],[18.3,2.987],[-18.3,2.987]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[33.716,64.648],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 18","np":4,"cix":2,"bm":0,"ix":18,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0.532,-1.599],[0,0],[-0.051,1.924]],"o":[[-0.048,1.775],[0,0],[0.579,-1.738],[0,0]],"v":[[4.766,5.884],[3.877,10.963],[5.3,11.437],[6.265,5.924]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[0.195,-7.293],[0,0],[6.797,3.056]],"o":[[6.265,2.817],[0,0],[0.213,-7.918],[0,0]],"v":[[-5.586,-10.6],[4.766,5.884],[6.265,5.924],[-4.97,-11.968]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[0,0],[-0.313,0.929]],"o":[[-0.306,0.933],[0,0]],"v":[[3.877,10.963],[5.3,11.437]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[0,0],[-0.892,-0.406]],"o":[[-0.897,-0.398],[0,0]],"v":[[-4.97,-11.968],[-5.586,-10.6]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[55.743,61.272],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 19","np":6,"cix":2,"bm":0,"ix":19,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[3.701,-0.71],[0,0]],"o":[[0,0],[3.815,0.297],[0,0],[0,0]],"v":[[-38.825,-17.909],[34.824,-16.391],[35.124,-9.991],[-33.676,17.909]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[71.992,67.326],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 20","np":3,"cix":2,"bm":0,"ix":20,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.85,0.004],[-0.85,-0.004]],"o":[[-0.85,0.004],[0.85,-0.004]],"v":[[0,-0.65],[0,0.651]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0.072,2.835],[-0.071,-2.835]],"o":[[0.072,-2.836],[-0.072,2.835]],"v":[[-2.15,0.001],[2.15,0.001]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.716,81.734],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 21","np":4,"cix":2,"bm":0,"ix":21,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.004,0.85],[-0.004,-0.85]],"o":[[0.004,-0.85],[-0.004,0.85]],"v":[[-0.65,0],[0.65,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[2.835,0.072],[-2.835,-0.072]],"o":[[-2.836,0.072],[2.836,-0.072]],"v":[[0,-2.15],[0,2.15]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[113.916,72.235],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 22","np":4,"cix":2,"bm":0,"ix":22,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.004,0.85],[-0.004,-0.85]],"o":[[0.004,-0.85],[-0.004,0.85]],"v":[[-6.077,13.829],[-4.778,13.829]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[0,0],[1.732,0.045],[0,0],[-1.143,0.078],[-0.662,1.342]],"o":[[-1.26,1.01],[0,0],[0.24,1.12],[1.471,-0.016],[0,0]],"v":[[-2.773,-15.579],[-7.405,-14.023],[-7.004,-12.77],[-4.549,-10.921],[-1.649,-13.07]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ind":2,"ty":"sh","ix":3,"ks":{"a":0,"k":{"i":[[-0.261,2.878],[0,0],[-5.102,0.068]],"o":[[0,0],[-3.765,3.34],[2.946,0]],"v":[[-1.601,-20.654],[-11.048,-25.333],[-7.228,-15.521]],"c":true},"ix":2},"nm":"Path 3","mn":"ADBE Vector Shape - Group","hd":false},{"ind":3,"ty":"sh","ix":4,"ks":{"a":0,"k":{"i":[[5.827,-4.661],[-2.646,1.621],[-1.528,1.458],[0,0],[0,0],[2.904,2.915],[0,0],[0.897,1.226]],"o":[[2.854,-1.217],[1.78,-1.136],[0,0],[0,0],[3.049,-2.766],[0,0],[-1.045,-1.114],[-1.172,10.731]],"v":[[13.513,41.456],[21.774,37.193],[26.748,33.292],[26.949,33.092],[26.956,33.085],[27.229,22.247],[27.225,22.243],[24.311,18.729]],"c":true},"ix":2},"nm":"Path 4","mn":"ADBE Vector Shape - Group","hd":false},{"ind":4,"ty":"sh","ix":5,"ks":{"a":0,"k":{"i":[[0,0],[0.002,-0.01],[0,0]],"o":[[-0.003,0.009],[0,0],[0,0]],"v":[[12.654,42.113],[12.646,42.143],[12.566,42.178]],"c":true},"ix":2},"nm":"Path 5","mn":"ADBE Vector Shape - Group","hd":false},{"ind":5,"ty":"sh","ix":6,"ks":{"a":0,"k":{"i":[[0.595,-1.425],[1.064,-0.919],[1.302,-0.503],[1.361,-0.019],[0.647,-0.269],[2.092,-2.442],[0,0],[1.227,-17.019],[0,0],[0,0],[-1.413,-1.486],[0.308,-2.651],[-2.11,-5.719],[0,0],[0.983,-0.005],[0,0],[7.212,0.185],[10.55,21.566],[-0.273,0.22],[0,0],[-0.267,-0.288],[0,0],[0,0],[-0.16,-0.967],[0.105,-0.081],[0,0],[0,0],[-2.453,0.004],[0.014,-1.195],[0,0],[0.794,-0.585],[0,0],[0.258,0.279],[0,0],[0,0],[-12.303,-0.255],[0,0],[-5.943,4.66],[9.594,10.802],[8.446,1.722],[1.852,0.013],[0.427,1.788],[0,0],[-8.915,-0.945],[0.307,0.337],[0.526,1.419],[-0.068,1.44],[-4.732,1.206],[-0.414,0.373],[-1.302,0.503],[-1.354,-0.076],[-1.388,-0.702],[-0.994,-1.08],[-0.527,-1.419],[0.068,-1.44]],"o":[[-0.673,1.382],[-0.998,0.894],[-1.325,0.494],[-0.537,0],[2.143,2.391],[0,0],[16.716,3.231],[0,0],[0,0],[1.157,1.672],[1.853,1.922],[4.482,4.177],[0,0],[0.977,0.004],[0,0],[-5.478,2.478],[-13.326,-0.278],[-0.154,-0.314],[0,0],[0.307,-0.246],[0,0],[0,0],[-0.15,-0.969],[0.006,0.164],[0,0],[0,0],[-2.315,-0.703],[1.196,-0.001],[0,0],[0.789,-0.573],[0,0],[-0.306,0.225],[0,0],[0,0],[10.446,21.137],[0,0],[9.616,0.248],[10.113,-6.734],[-3.855,-4.697],[-0.818,1.625],[-1.836,0.095],[0,0],[-8.519,-2.484],[-0.162,-0.508],[-0.947,-1.077],[-0.491,-1.437],[-0.207,-2.872],[0.728,-0.207],[0.998,-0.894],[1.326,-0.494],[1.424,0.09],[1.406,0.71],[0.947,1.078],[0.491,1.436],[-0.115,1.462]],"v":[[11.572,-31.171],[7.272,-28.971],[4.673,-24.87],[0.072,-26.271],[-1.738,-25.752],[-1.637,-16.713],[-0.253,-13.62],[24.52,16.381],[24.52,16.383],[24.517,16.428],[28.317,21.215],[30.79,28.542],[39.999,43.38],[46.272,43.38],[46.272,44.88],[7.887,44.88],[-11.346,48.079],[-47.102,14.958],[-46.898,14.044],[-25.498,-3.156],[-24.479,-3.081],[-15.562,6.514],[-15.669,5.848],[-14.187,5.611],[-13.799,8.411],[-6.532,16.23],[-6.059,15.885],[-5.428,11.68],[-3.278,13.854],[7.03,6.324],[7.914,7.536],[-6.186,17.835],[-7.177,17.74],[-25.102,-1.549],[-45.49,14.838],[-11.312,46.579],[-11.309,46.579],[12.397,40.426],[18.018,-2.482],[-0.432,-12.148],[-4.507,-9.421],[-8.451,-12.37],[-9.055,-14.257],[-6.266,-28.257],[-6.928,-29.571],[-11.028,-32.171],[-9.528,-36.771],[-8.176,-42.89],[-6.327,-43.671],[-3.728,-47.771],[0.872,-46.271],[5.673,-47.37],[7.872,-43.071],[11.972,-40.471],[10.472,-35.87]],"c":true},"ix":2},"nm":"Path 6","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"mm","mm":1,"nm":"Merge Paths 1","mn":"ADBE Vector Filter - Merge","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[119.443,77.705],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 23","np":8,"cix":2,"bm":0,"ix":23,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-0.822,-0.669],[0.919,-0.003],[-0.56,1.289],[-0.357,-0.21],[-0.478,0.05]],"o":[[0.914,1.085],[-0.871,0.068],[0.21,-0.358],[0.414,0.243],[0.838,0.075]],"v":[[2.047,-0.704],[0.094,1.305],[-2.4,-0.223],[-1.374,-0.49],[-0.001,-0.193]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[110.369,58.379],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 24","np":2,"cix":2,"bm":0,"ix":24,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[1.1,-16],[19.4,0.5],[10.533,21.533],[0,0],[0,0],[0,0]],"o":[[17.1,3.5],[-1.7,24],[-12.867,-0.267],[0,0],[0,0],[0,0],[0,0]],"v":[[10.55,-30.35],[34.55,-1.15],[-0.55,29.85],[-35.65,-2.85],[-14.25,-20.05],[4.15,-0.25],[18.25,-10.55]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[108.666,95.185],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 25","np":2,"cix":2,"bm":0,"ix":25,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[5.526,-0.081],[-7.478,-1.613],[0,0],[-1.49,0.086],[-0.8,1.9]],"o":[[3.777,-3.939],[-7.729,0.16],[0,0],[0.335,1.455],[1.7,0],[0,0]],"v":[[4.82,2.046],[0.124,-8.702],[-1.118,3.977],[-0.376,6.298],[2.824,8.697],[6.524,5.798]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[112.091,58.838],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 26","np":3,"cix":2,"bm":0,"ix":26,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[-1.6,-16.994],[0,0],[0,0],[-13.2,8.267]],"o":[[-17.598,-0.307],[0,0],[0,0],[15.4,24.667],[0,0]],"v":[[28.5,-32.48],[2.1,-0.58],[-11.6,-13.38],[-28.5,-0.08],[14.4,24.52]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"st","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1.5,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[82.816,97.315],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 27","np":4,"cix":2,"bm":0,"ix":27,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-11.514,-12.28],[3.346,-3.038],[1.897,-1.21],[3.044,-1.272],[9.161,13.453],[0,0],[-8.267,-1.002]],"o":[[3.189,3.203],[-1.593,1.592],[-2.814,1.724],[-5.213,2.085],[-9.162,-13.454],[5.26,-2.339],[8.267,1.002]],"v":[[22.74,6.37],[22.439,18.27],[17.139,22.47],[8.339,26.97],[-16.767,14.623],[-25.32,-25.321],[-5.658,-28.053]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[124.476,93.065],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 28","np":2,"cix":2,"bm":0,"ix":28,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[0,0],[-11.915,5.391],[-3.306,-7.965],[0,-4.499]],"o":[[0,0],[0,0],[0.192,-13.119],[7.856,3.554],[1.725,4.156],[0,0]],"v":[[20.1,47.079],[-20.1,47.079],[-20.1,-16.421],[-0.002,-47.079],[17.487,-29.032],[20.1,-15.921]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.541176470588,0.705882352941,0.972549079446,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[143.316,74.755],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 29","np":2,"cix":2,"bm":0,"ix":29,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-18.187,-0.354],[0.209,-18.622],[0,0],[0,0],[0,0]],"o":[[18.624,-0.263],[0,0],[0,0],[0,0],[-0.087,-18.191]],"v":[[-0.111,-48.423],[34.189,-14.223],[34.189,48.777],[-34.311,48.777],[-34.311,-14.723]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[129.227,73.058],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 30","np":2,"cix":2,"bm":0,"ix":30,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0.034,7.025],[0.003,-0.985],[-1.694,-2.622],[-3.394,-1.646],[0.884,0.435]],"o":[[-0.001,-0.975],[0,3.687],[1.692,2.619],[0.881,0.42],[-6.316,-3.102]],"v":[[-4.331,-7.595],[-5.831,-7.595],[-3.339,1.833],[4.292,8.16],[4.947,6.81]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[53.496,88.15],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 31","np":2,"cix":2,"bm":0,"ix":31,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[3.608,-0.792],[0.164,-2.378],[0.259,-1.558],[0.339,-0.781],[-0.38,-0.165],[-0.165,0.38],[0.195,2.645],[-0.238,1.81],[-0.231,-2.009],[0.182,-2.455],[-0.748,-3.683],[-1.305,0.791],[0.236,0.34],[0.151,0.911],[-0.046,3.211],[0.256,2.536]],"o":[[-0.588,-3.193],[-2.949,0.981],[0.133,1.574],[-0.16,0.836],[-0.165,0.38],[0.38,0.165],[1.08,-2.454],[0.006,-2.022],[1.748,-2.007],[0.245,2.45],[-0.058,3.237],[0.179,0.894],[0.34,-0.236],[-0.527,-0.76],[-0.722,-3.511],[0.187,-2.541],[0,0]],"v":[[3.228,-4.725],[-1.84,-14.03],[-2.763,-6.365],[-2.952,-1.647],[-3.702,0.786],[-3.312,1.773],[-2.327,1.383],[-1.266,-6.465],[-1.809,-12.272],[1.742,-4.523],[1.837,2.848],[2.048,10.721],[4.365,14.031],[4.553,12.988],[3.523,10.449],[3.335,2.922],[3.23,-4.708]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.258823529412,0.521568627451,0.956862804936,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[64.43,71.45],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 32","np":2,"cix":2,"bm":0,"ix":32,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-8.403,-5.035],[-3.751,3.462],[0.219,2.222],[-0.591,3.032],[-0.015,-1.683]],"o":[[4.148,-2.872],[-0.972,-2.011],[0.007,-3.088],[-3.494,1.254],[0,3.943]],"v":[[-1.597,10.499],[10,1.482],[8.2,-4.918],[8.759,-10.5],[-9.951,-2.775]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.823529471603,0.89019613827,0.988235353956,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_Color1Shade2","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[58.416,84.352],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 33","np":2,"cix":2,"bm":0,"ix":33,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-8.403,-5.035],[-3.751,3.462],[0.219,2.222],[-0.591,3.032],[-0.015,-1.683]],"o":[[4.148,-2.872],[-0.972,-2.011],[0.007,-3.088],[-3.494,1.254],[0,3.943]],"v":[[-1.597,10.499],[10,1.482],[8.2,-4.918],[8.759,-10.5],[-9.951,-2.775]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"CrOS_BaseColor","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[58.416,84.352],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 34","np":2,"cix":2,"bm":0,"ix":34,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":1,"st":0,"bm":0}],"markers":[]} \ No newline at end of file
diff --git a/ash/public/cpp/test/mock_input_device_settings_controller.h b/ash/public/cpp/test/mock_input_device_settings_controller.h index a8b7d63..01b38ef8 100644 --- a/ash/public/cpp/test/mock_input_device_settings_controller.h +++ b/ash/public/cpp/test/mock_input_device_settings_controller.h
@@ -62,6 +62,10 @@ (DeviceId id, mojom::KeyboardSettingsPtr settings), (override)); MOCK_METHOD(void, + RestoreDefaultKeyboardModifierRemappings, + (DeviceId id), + (override)); + MOCK_METHOD(void, SetTouchpadSettings, (DeviceId id, mojom::TouchpadSettingsPtr settings), (override));
diff --git a/ash/sensor_info/sensor_types.cc b/ash/sensor_info/sensor_types.cc new file mode 100644 index 0000000..d7f8481 --- /dev/null +++ b/ash/sensor_info/sensor_types.cc
@@ -0,0 +1,61 @@ +// 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 "ash/sensor_info/sensor_types.h" + +#include "base/check_op.h" +#include "base/numerics/math_constants.h" + +namespace ash { + +SensorReading::SensorReading() = default; + +SensorReading::SensorReading(float x) : x(x) { + y = std::numeric_limits<float>::quiet_NaN(); + z = std::numeric_limits<float>::quiet_NaN(); +} + +SensorReading::SensorReading(float x, float y, float z) : x(x), y(y), z(z) {} + +SensorReading::~SensorReading() = default; + +// ----------------------------------------------------------------------------- +// SensorUpdate: + +SensorUpdate::SensorUpdate() = default; + +SensorUpdate::SensorUpdate(const SensorUpdate& update) = default; + +SensorUpdate& SensorUpdate::operator=(const SensorUpdate& update) = default; + +SensorUpdate::~SensorUpdate() = default; + +std::vector<float> SensorUpdate::GetReadingAsVector(SensorType source) const { + const absl::optional<SensorReading>& reading = data_[source]; + if (source == SensorType::LID_ANGLE) { + return reading.has_value() ? std::vector<float>{reading->x} + : std::vector<float>{0.0}; + } + return reading.has_value() + ? std::vector<float>{reading->x, reading->y, reading->z} + : std::vector<float>{0.0, 0.0, 0.0}; +} + +void SensorUpdate::Set(SensorType source, float x, float y, float z) { + CHECK_NE(source, SensorType::LID_ANGLE); + data_[source] = SensorReading(x, y, z); +} + +void SensorUpdate::Set(SensorType source, float x) { + DCHECK_EQ(source, SensorType::LID_ANGLE); + data_[source] = SensorReading(x); +} + +void SensorUpdate::Reset() { + for (auto& i : data_) { + i = absl::nullopt; + } +} + +} // namespace ash
diff --git a/ash/sensor_info/sensor_types.h b/ash/sensor_info/sensor_types.h new file mode 100644 index 0000000..303c39b --- /dev/null +++ b/ash/sensor_info/sensor_types.h
@@ -0,0 +1,89 @@ +// 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 ASH_SENSOR_INFO_SENSOR_TYPES_H_ +#define ASH_SENSOR_INFO_SENSOR_TYPES_H_ + +#include <vector> + +#include "ash/ash_export.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace ash { + +// Location of sensor. There are three types of sensors: gyroscope, +// accelerometer, lid_angle. +enum class SensorLocation { + kLid, + kBase, + kOther, +}; + +// Sensor types. +enum SensorType { + LID_ANGLE, + ACCELEROMETER_BASE, + ACCELEROMETER_LID, + GYROSCOPE_BASE, + GYROSCOPE_LID, + SENSOR_SOURCE_COUNT, +}; + +// Stores one sensor's reading info. +struct ASH_EXPORT SensorReading { + SensorReading(); + // We use SensorReading(x) for lid_angle sensor, and SensorReading(x, y, z) + // for gyroscope and accelerometer. + explicit SensorReading(float x); + SensorReading(float x, float y, float z); + ~SensorReading(); + + // The readings from this sensor. + float x; + float y; + float z; +}; + +// Stores all present sensors' reading info. +class ASH_EXPORT SensorUpdate { + public: + SensorUpdate(); + SensorUpdate(const SensorUpdate& update); + SensorUpdate& operator=(const SensorUpdate& update); + ~SensorUpdate(); + + // Returns true if `source` has a valid value in this update. + bool has(SensorType source) const { return data_[source].has_value(); } + // Returns the last known value for |source|. + const absl::optional<SensorReading>& get(SensorType source) const { + return data_[source]; + } + + // Returns the last known value for `source` as a vector. + std::vector<float> GetReadingAsVector(SensorType source) const; + // We use Set(x) for lid_angle sensor, and Set(x, y, z) for gyroscope and + // accelerometer. + void Set(SensorType source, float x); + void Set(SensorType source, float x, float y, float z); + // Clear content in data_. + void Reset(); + + protected: + absl::optional<SensorReading> data_[SensorType::SENSOR_SOURCE_COUNT]; +}; + +// Class for all potential observer. +class ASH_EXPORT Observer { + public: + // SensorProvider will gather updates from AccelGyroSamplesObserver. Then + // SensorProvider will call OnSensorUpdated to notify Observer. + virtual void OnSensorUpdated(const SensorUpdate& update) = 0; + + protected: + virtual ~Observer() = default; +}; + +} // namespace ash + +#endif // ASH_SENSOR_INFO_SENSOR_TYPES_H_
diff --git a/ash/style/ash_color_mixer.cc b/ash/style/ash_color_mixer.cc index 92b8f79..4899de2 100644 --- a/ash/style/ash_color_mixer.cc +++ b/ash/style/ash_color_mixer.cc
@@ -508,6 +508,67 @@ mixer[kColorAshTileSmallCircle] = dark_mode ? ui::ColorTransform(cros_tokens::kCrosSysHighlightShape) : ui::SetAlpha(gfx::kGoogleBlue600, 31); // 12% opacity + + // Remap illo tokens to GM2 equivilants so GM3 assets will render reasonably + // if the jelly flag is flipped off for launch. + mixer[cros_tokens::kCrosSysIlloColor1] = {cros_tokens::kIllustrationColor1}; + mixer[cros_tokens::kCrosSysIlloColor11] = { + cros_tokens::kIllustrationColor1Shade1}; + mixer[cros_tokens::kCrosSysIlloColor12] = { + cros_tokens::kIllustrationColor1Shade2}; + mixer[cros_tokens::kCrosSysIlloColor2] = {cros_tokens::kIllustrationColor2}; + mixer[cros_tokens::kCrosSysIlloColor3] = {cros_tokens::kIllustrationColor3}; + mixer[cros_tokens::kCrosSysIlloColor4] = {cros_tokens::kIllustrationColor4}; + mixer[cros_tokens::kCrosSysIlloColor5] = {cros_tokens::kIllustrationColor5}; + mixer[cros_tokens::kCrosSysIlloColor6] = {cros_tokens::kIllustrationColor6}; + mixer[cros_tokens::kCrosSysIlloBase] = {cros_tokens::kIllustrationBaseColor}; + mixer[cros_tokens::kCrosSysIlloSecondary] = { + cros_tokens::kIllustrationSecondaryColor}; + // Card colors are new in GM3 and have no equivalent GM2 token. As such as map + // them to hex codes directly as specified in go/cros-tokens. + mixer[cros_tokens::kCrosSysIlloCardColor1] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0x42, 0x4d, 0x63)) + : SkColorSetRGB(0xff, 0xca, 0xd1); + mixer[cros_tokens::kCrosSysIlloCardOnColor1] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0xf6, 0xae, 0xa9)) + : SkColorSetRGB(0xa5, 0x0e, 0x0e); + mixer[cros_tokens::kCrosSysIlloCardColor2] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0x62, 0x5a, 0x47)) + : SkColorSetRGB(0xfb, 0xe0, 0x97); + mixer[cros_tokens::kCrosSysIlloCardOnColor2] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0xfd, 0xe2, 0x93)) + : SkColorSetRGB(0x9b, 0x61, 0x00); + mixer[cros_tokens::kCrosSysIlloCardColor3] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0x4d, 0x63, 0x52)) + : SkColorSetRGB(0xc6, 0xeb, 0xcb); + mixer[cros_tokens::kCrosSysIlloCardOnColor3] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0xa8, 0xda, 0xb5)) + : SkColorSetRGB(0x0d, 0x65, 0x2d); + mixer[cros_tokens::kCrosSysIlloCardColor4] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0x42, 0x4d, 0x63)) + : SkColorSetRGB(0xd0, 0xe1, 0xfa); + mixer[cros_tokens::kCrosSysIlloCardOnColor4] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0xae, 0xcb, 0xfa)) + : SkColorSetRGB(0x18, 0x5a, 0xbc); + mixer[cros_tokens::kCrosSysIlloCardColor5] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0x51, 0x40, 0x64)) + : SkColorSetRGB(0xf6, 0xe9, 0xf8); + mixer[cros_tokens::kCrosSysIlloCardOnColor5] = + dark_mode ? ui::ColorTransform(SkColorSetRGB(0xd7, 0xae, 0xfb)) + : SkColorSetRGB(0x75, 0x09, 0x9b); + // Some GM2 assets are "elevated" meaning they have slightly different + // colors to improve contrast on their elevated surfaces in dark mode. To + // handle this we create "elevated" sys tokens that are the same as their + // unelevated counterparts when the jelly flag is on but resolve to higher + // contrast GM2 colors when jelly is off and dark mode is on. + mixer[cros_tokens::kCrosSysIlloElevatedColor11] = { + cros_tokens::kIllustrationElevationColor1Shade1}; + mixer[cros_tokens::kCrosSysIlloElevatedColor12] = { + cros_tokens::kIllustrationElevationColor1Shade2}; + mixer[cros_tokens::kCrosSysIlloElevatedBase] = { + cros_tokens::kIllustrationElevationBaseColor}; + mixer[cros_tokens::kCrosSysIlloElevatedSecondary] = { + cros_tokens::kIllustrationElevationSecondaryColor}; } } // namespace
diff --git a/ash/system/audio/audio_detailed_view.cc b/ash/system/audio/audio_detailed_view.cc index aea9a86..40aaf51 100644 --- a/ash/system/audio/audio_detailed_view.cc +++ b/ash/system/audio/audio_detailed_view.cc
@@ -14,6 +14,7 @@ #include "ash/shell.h" #include "ash/strings/grit/ash_strings.h" #include "ash/style/ash_color_id.h" +#include "ash/style/ash_color_provider.h" #include "ash/style/rounded_container.h" #include "ash/style/typography.h" #include "ash/system/audio/mic_gain_slider_controller.h" @@ -49,6 +50,7 @@ #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/vector_icon_types.h" #include "ui/views/accessibility/view_accessibility.h" +#include "ui/views/background.h" #include "ui/views/border.h" #include "ui/views/controls/button/toggle_button.h" #include "ui/views/controls/focus_ring.h" @@ -66,6 +68,7 @@ const int kLabelFontSizeDelta = 1; const int kToggleButtonRowViewSpacing = 18; +const int kNbsWarningMinHeight = 80; constexpr auto kLiveCaptionContainerMargins = gfx::Insets::TLBR(0, 0, 8, 0); constexpr auto kToggleButtonRowLabelPadding = gfx::Insets::TLBR(16, 0, 15, 0); constexpr auto kToggleButtonRowViewPadding = gfx::Insets::TLBR(0, 56, 8, 0); @@ -615,9 +618,11 @@ scroll_content()->RemoveAllChildViews(); device_map_.clear(); + const bool is_qs_revamp = features::IsQsRevampEnabled(); + // Uses the `RoundedContainer` for QsRevamp. views::View* container = scroll_content(); - if (features::IsQsRevampEnabled()) { + if (is_qs_revamp) { container = scroll_content()->AddChildView(std::make_unique<RoundedContainer>()); } @@ -625,7 +630,7 @@ // Adds the live caption toggle. AccessibilityControllerImpl* controller = Shell::Get()->accessibility_controller(); - if (features::IsQsRevampEnabled()) { + if (is_qs_revamp) { CreateLiveCaptionView(); } else if (controller->IsLiveCaptionSettingVisibleInTray()) { live_caption_view_ = AddScrollListCheckableItem( @@ -649,7 +654,7 @@ container, gfx::kNoneIcon, GetAudioDeviceName(device), device.active); device_map_[device_name_container] = device; - if (features::IsQsRevampEnabled()) { + if (is_qs_revamp) { // Sets this flag to false to make the assigned color id effective. // Otherwise it will use `color_utils::BlendForMinContrast()` to improve // label readability over the background. @@ -662,7 +667,7 @@ } if (has_output_devices) { - if (features::IsQsRevampEnabled()) { + if (is_qs_revamp) { last_output_device->SetProperty(views::kMarginsKey, kQsSubsectionMargins); } else { container->AddChildView(TrayPopupUtils::CreateListSubHeaderSeparator()); @@ -683,7 +688,7 @@ container, gfx::kNoneIcon, GetAudioDeviceName(device), device.active); device_map_[device_name_container] = device; - if (features::IsQsRevampEnabled()) { + if (is_qs_revamp) { // Sets this flag to false to make the assigned color id effective. device_name_container->text_label()->SetAutoColorReadabilityEnabled( /*enabled=*/false); @@ -694,7 +699,7 @@ // Adds the input noise cancellation toggle. if (audio_handler->GetPrimaryActiveInputNode() == device.id && audio_handler->IsNoiseCancellationSupportedForDevice(device.id)) { - if (features::IsQsRevampEnabled()) { + if (is_qs_revamp) { noise_cancellation_view_ = container->AddChildView( AudioDetailedView::CreateQsNoiseCancellationToggleRow(device)); @@ -716,6 +721,42 @@ scroll_content()->AddChildView(mic_gain_controller_->CreateMicGainSlider( device.id, device.IsInternalMic())); } + + // Adds a warning message if NBS is selected. + if (features::IsAudioHFPNbsWarningEnabled()) { + if (audio_handler->GetPrimaryActiveInputNode() == device.id && + device.type == AudioDeviceType::kBluetoothNbMic) { + std::unique_ptr<TriView> nbs_warning_view( + TrayPopupUtils::CreateDefaultRowView( + /*use_wide_layout=*/is_qs_revamp)); + nbs_warning_view->SetMinHeight(kNbsWarningMinHeight); + nbs_warning_view->SetContainerVisible(TriView::Container::END, false); + + std::unique_ptr<views::ImageView> image_view = + base::WrapUnique(TrayPopupUtils::CreateMainImageView( + /*use_wide_layout=*/is_qs_revamp)); + image_view->SetImage(ui::ImageModel::FromVectorIcon( + vector_icons::kNotificationWarningIcon, kColorAshIconColorWarning, + kMenuIconSize)); + image_view->SetBackground( + views::CreateSolidBackground(SK_ColorTRANSPARENT)); + nbs_warning_view->AddView(TriView::Container::START, + std::move(image_view)); + + std::unique_ptr<views::Label> label = + base::WrapUnique(TrayPopupUtils::CreateDefaultLabel()); + label->SetText( + l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_AUDIO_NBS_MESSAGE)); + label->SetMultiLine(/*multi_line=*/true); + label->SetBackground(views::CreateSolidBackground(SK_ColorTRANSPARENT)); + label->SetEnabledColorId(kColorAshTextColorWarning); + TrayPopupUtils::SetLabelFontList( + label.get(), TrayPopupUtils::FontStyle::kDetailedViewLabel); + nbs_warning_view->AddView(TriView::Container::CENTER, std::move(label)); + + container->AddChildView(std::move(nbs_warning_view)); + } + } } container->SizeToPreferredSize();
diff --git a/ash/system/geolocation/geolocation_controller_unittest.cc b/ash/system/geolocation/geolocation_controller_unittest.cc index dfe6223..24e22cc 100644 --- a/ash/system/geolocation/geolocation_controller_unittest.cc +++ b/ash/system/geolocation/geolocation_controller_unittest.cc
@@ -62,7 +62,7 @@ base::Time ToUTCTime(base::StringPiece utc_time_str) { base::Time time; - CHECK(base::Time::FromUTCString(utc_time_str.data(), &time)) + CHECK(base::Time::FromUTCString(std::string(utc_time_str).c_str(), &time)) << "Invalid UTC time string specified: " << utc_time_str; return time; }
diff --git a/ash/system/input_device_settings/input_device_settings_controller_impl.cc b/ash/system/input_device_settings/input_device_settings_controller_impl.cc index 0b0f970..a1c5b09 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_impl.cc +++ b/ash/system/input_device_settings/input_device_settings_controller_impl.cc
@@ -280,19 +280,27 @@ return; } - // If the flag is disabled, clear the new touchpad setting from all settings - // dictionaries. + // If the flag is disabled, clear the new touchpad and keyboard settings from + // all settings dictionaries. if (!features::IsAltClickAndSixPackCustomizationEnabled() && pref_service) { - base::Value::Dict updated_dict; - for (auto [key, dict] : - pref_service->GetDict(prefs::kTouchpadDeviceSettingsDictPref) - .Clone()) { - auto existing_settings = dict.GetDict().Clone(); - existing_settings.Remove(prefs::kTouchpadSettingSimulateRightClick); - updated_dict.Set(key, std::move(existing_settings)); + base::Value::Dict updated_touchpad_dict = + pref_service->GetDict(prefs::kTouchpadDeviceSettingsDictPref).Clone(); + for (auto [key, dict] : updated_touchpad_dict) { + CHECK(dict.is_dict()); + dict.GetDict().Remove(prefs::kTouchpadSettingSimulateRightClick); + } + + base::Value::Dict updated_keyboard_dict = + pref_service->GetDict(prefs::kKeyboardDeviceSettingsDictPref).Clone(); + + for (auto [key, dict] : updated_keyboard_dict) { + CHECK(dict.is_dict()); + dict.GetDict().Remove(prefs::kKeyboardSettingSixPackKeyRemappings); } pref_service->SetDict(prefs::kTouchpadDeviceSettingsDictPref, - std::move(updated_dict)); + std::move(updated_touchpad_dict)); + pref_service->SetDict(prefs::kKeyboardDeviceSettingsDictPref, + std::move(updated_keyboard_dict)); } active_pref_service_ = pref_service; active_account_id_ = Shell::Get()->session_controller()->GetActiveAccountId();
diff --git a/ash/system/input_device_settings/input_device_settings_controller_impl.h b/ash/system/input_device_settings/input_device_settings_controller_impl.h index 5207b9a..91667d19 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_impl.h +++ b/ash/system/input_device_settings/input_device_settings_controller_impl.h
@@ -85,7 +85,7 @@ std::vector<ui::InputDevice> pointing_sticks_to_add, std::vector<DeviceId> pointing_stick_ids_to_remove); bool GetGeneralizedTopRowAreFKeys(); - void RestoreDefaultKeyboardModifierRemappings(DeviceId id); + void RestoreDefaultKeyboardModifierRemappings(DeviceId id) override; // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
diff --git a/ash/system/input_device_settings/input_device_settings_controller_unittest.cc b/ash/system/input_device_settings/input_device_settings_controller_unittest.cc index efa3b98c..b82162e0 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_unittest.cc +++ b/ash/system/input_device_settings/input_device_settings_controller_unittest.cc
@@ -301,6 +301,9 @@ /*provide_pref_service=*/false); session_controller->SetUserPrefService(account_id_2, std::move(user_2_prefs)); + session_controller->AddUserSession(kUserEmail3, + user_manager::USER_TYPE_REGULAR, + /*provide_pref_service=*/false); session_controller->SwitchActiveUser(account_id_1); session_controller->SetSessionState(session_manager::SessionState::ACTIVE); @@ -323,6 +326,13 @@ task_runner_.reset(); } + void SetActiveUser(const AccountId& account_id) { + TestSessionControllerClient* session_controller = + GetSessionControllerClient(); + session_controller->SwitchActiveUser(account_id); + session_controller->SetSessionState(session_manager::SessionState::ACTIVE); + } + protected: std::unique_ptr<InputDeviceSettingsControllerImpl> controller_; std::unique_ptr<FakeDeviceManager> fake_keyboard_manager_; @@ -412,7 +422,8 @@ prefs::kTouchpadDeviceSettingsDictPref)); } -TEST_F(InputDeviceSettingsControllerTest, DeletesPrefsWhenAltFlagDisabled) { +TEST_F(InputDeviceSettingsControllerTest, + DeletesSimulateRightClickPrefsWhenAltFlagDisabled) { base::test::ScopedFeatureList feature_list; feature_list.InitAndDisableFeature( features::kAltClickAndSixPackCustomization); @@ -420,22 +431,17 @@ RegisterUserProfilePrefs(user_prefs->registry(), /*for_test=*/true); base::Value::Dict test_pref_value; - base::Value::Dict test_pref_dict; - test_pref_dict.Set( + base::Value::Dict six_pack_remappings_dict; + six_pack_remappings_dict.Set( prefs::kTouchpadSettingSimulateRightClick, static_cast<int>(ui::mojom::SimulateRightClickModifier::kAlt)); - test_pref_value.Set("key", std::move(test_pref_dict)); + test_pref_value.Set("key", std::move(six_pack_remappings_dict)); user_prefs->SetDict(prefs::kTouchpadDeviceSettingsDictPref, test_pref_value.Clone()); - TestSessionControllerClient* session_controller = - GetSessionControllerClient(); - session_controller->AddUserSession(kUserEmail3, - user_manager::USER_TYPE_REGULAR, - /*provide_pref_service=*/false); - session_controller->SetUserPrefService(account_id_3, std::move(user_prefs)); + GetSessionControllerClient()->SetUserPrefService(account_id_3, + std::move(user_prefs)); - session_controller->SwitchActiveUser(account_id_3); - session_controller->SetSessionState(session_manager::SessionState::ACTIVE); + SetActiveUser(account_id_3); PrefService* active_pref_service = Shell::Get()->session_controller()->GetActivePrefService(); base::Value::Dict devices_dict = @@ -446,6 +452,41 @@ } TEST_F(InputDeviceSettingsControllerTest, + DeletesSixPackKeyPrefsWhenAltFlagDisabled) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndDisableFeature( + features::kAltClickAndSixPackCustomization); + auto user_prefs = std::make_unique<TestingPrefServiceSimple>(); + RegisterUserProfilePrefs(user_prefs->registry(), /*for_test=*/true); + + base::Value::Dict test_pref_value; + base::Value::Dict six_pack_remappings_dict; + base::Value::Dict settings_dict; + + six_pack_remappings_dict.Set( + prefs::kSixPackKeyPageUp, + static_cast<int>(ui::mojom::SimulateRightClickModifier::kAlt)); + + settings_dict.Set(prefs::kKeyboardSettingSixPackKeyRemappings, + std::move(six_pack_remappings_dict)); + + test_pref_value.Set("key", std::move(settings_dict)); + user_prefs->SetDict(prefs::kKeyboardDeviceSettingsDictPref, + test_pref_value.Clone()); + GetSessionControllerClient()->SetUserPrefService(account_id_3, + std::move(user_prefs)); + + SetActiveUser(account_id_3); + PrefService* active_pref_service = + Shell::Get()->session_controller()->GetActivePrefService(); + base::Value::Dict devices_dict = + active_pref_service->GetDict(prefs::kKeyboardDeviceSettingsDictPref) + .Clone(); + base::Value::Dict* existing_settings_dict = devices_dict.FindDict("key"); + EXPECT_EQ(base::Value::Dict(), *existing_settings_dict); +} + +TEST_F(InputDeviceSettingsControllerTest, InitializeSettingsWhenUserSessionChanges) { ui::DeviceDataManagerTestApi().SetKeyboardDevices({kSampleKeyboardUsb}); EXPECT_EQ(observer_->num_keyboards_connected(), 1u);
diff --git a/ash/system/message_center/arc_notification_manager_delegate_impl.cc b/ash/system/message_center/arc_notification_manager_delegate_impl.cc index 3c41f26..d770373 100644 --- a/ash/system/message_center/arc_notification_manager_delegate_impl.cc +++ b/ash/system/message_center/arc_notification_manager_delegate_impl.cc
@@ -4,11 +4,13 @@ #include "ash/system/message_center/arc_notification_manager_delegate_impl.h" +#include "ash/constants/ash_features.h" #include "ash/login_status.h" #include "ash/root_window_controller.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/system/message_center/message_center_controller.h" +#include "ash/system/notification_center/notification_center_tray.h" #include "ash/system/status_area_widget.h" #include "ash/system/unified/unified_system_tray.h" @@ -28,10 +30,18 @@ } void ArcNotificationManagerDelegateImpl::ShowMessageCenter() { + if (!ash::features::IsQsRevampEnabled()) { + Shell::Get() + ->GetPrimaryRootWindowController() + ->GetStatusAreaWidget() + ->unified_system_tray() + ->ShowBubble(); + return; + } Shell::Get() ->GetPrimaryRootWindowController() ->GetStatusAreaWidget() - ->unified_system_tray() + ->notification_center_tray() ->ShowBubble(); } @@ -39,8 +49,14 @@ // Close the message center on all the displays. for (auto* root_window_controller : RootWindowController::root_window_controllers()) { + if (!ash::features::IsQsRevampEnabled()) { + root_window_controller->GetStatusAreaWidget() + ->unified_system_tray() + ->CloseBubble(); + continue; + } root_window_controller->GetStatusAreaWidget() - ->unified_system_tray() + ->notification_center_tray() ->CloseBubble(); } }
diff --git a/ash/system/power/power_sounds_controller.cc b/ash/system/power/power_sounds_controller.cc index eb8abb06..01909da9 100644 --- a/ash/system/power/power_sounds_controller.cc +++ b/ash/system/power/power_sounds_controller.cc
@@ -4,12 +4,15 @@ #include "ash/system/power/power_sounds_controller.h" +#include "ash/constants/ash_pref_names.h" #include "ash/shell.h" #include "ash/system/power/power_status.h" #include "base/check.h" #include "base/metrics/histogram_functions.h" #include "chromeos/ash/components/audio/sounds.h" #include "chromeos/dbus/power/power_manager_client.h" +#include "components/prefs/pref_registry_simple.h" +#include "components/prefs/pref_service.h" #include "ui/message_center/message_center.h" namespace ash { @@ -34,6 +37,15 @@ : Sound::kChargeLowBattery; } +PrefService* GetActivePrefService() { + return Shell::Get()->session_controller()->GetActivePrefService(); +} + +bool GetChargingSoundsEnabled() { + PrefService* prefs = GetActivePrefService(); + return prefs && prefs->GetBoolean(prefs::kChargingSoundsEnabled); +} + } // namespace // static @@ -66,6 +78,11 @@ chromeos::PowerManagerClient::Get()->RemoveObserver(this); } +void PowerSoundsController::RegisterPrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(prefs::kChargingSoundsEnabled, + /*default_value=*/false); +} + void PowerSoundsController::OnPowerStatusChanged() { const PowerStatus& status = *PowerStatus::Get(); @@ -119,6 +136,12 @@ void PowerSoundsController::MaybePlaySoundsForCharging( bool old_line_power_connected) { + // Don't play the charging sound if the toggle button is disabled by user in + // the Settings UI. + if (!GetChargingSoundsEnabled()) { + return; + } + // Returns when it isn't a plug in event. bool is_plugging_in = !old_line_power_connected && is_line_power_connected_; if (!is_plugging_in)
diff --git a/ash/system/power/power_sounds_controller.h b/ash/system/power/power_sounds_controller.h index ff49c9c4..e70e5c4 100644 --- a/ash/system/power/power_sounds_controller.h +++ b/ash/system/power/power_sounds_controller.h
@@ -8,6 +8,8 @@ #include "ash/system/power/power_status.h" #include "chromeos/dbus/power/power_manager_client.h" +class PrefRegistrySimple; + namespace ash { // Controller class to manage power/battery sounds. @@ -23,6 +25,8 @@ PowerSoundsController& operator=(const PowerSoundsController&) = delete; ~PowerSoundsController() override; + static void RegisterPrefs(PrefRegistrySimple* registry); + // PowerStatus::Observer: void OnPowerStatusChanged() override;
diff --git a/ash/system/power/power_sounds_controller_unittest.cc b/ash/system/power/power_sounds_controller_unittest.cc index 9c885285..9c6feec 100644 --- a/ash/system/power/power_sounds_controller_unittest.cc +++ b/ash/system/power/power_sounds_controller_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include "ash/constants/ash_features.h" +#include "ash/constants/ash_pref_names.h" #include "ash/shell.h" #include "ash/system/system_notification_controller.h" #include "ash/system/test_system_sounds_delegate.h" @@ -99,6 +100,11 @@ } void SetInitialPowerStatus() { + // The charging sounds toggle button is disabled as default, to test our + // charging sounds features, we will initialize it as enabled. + Shell::Get()->session_controller()->GetActivePrefService()->SetBoolean( + prefs::kChargingSoundsEnabled, true); + // The default status for power is connected with a charger and the battery // level is 1%. We set the initial power status for each unit test to // disconnected with a charger and 5% battery level. @@ -236,4 +242,18 @@ EXPECT_TRUE(VerifySounds({Sound::kChargeLowBattery})); } +// Tests that when the user disables the toggle button for charging sounds, when +// plugging in a charger, the device won't play any charging sound. +TEST_F(PowerSoundsControllerTest, NoChargingSoundPlayedIfToggleButtonDisabled) { + PrefService* pref = + Shell::Get()->session_controller()->GetActivePrefService(); + + pref->SetBoolean(prefs::kChargingSoundsEnabled, false); + ASSERT_FALSE(pref->GetBoolean(prefs::kChargingSoundsEnabled)); + + // Charge the device after disabling the button, and no sounds will be played. + SetPowerStatus(5, /*line_power_connected=*/true); + EXPECT_TRUE(GetSystemSoundsDelegate()->empty()); +} + } // namespace ash \ No newline at end of file
diff --git a/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller.cc b/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller.cc index 71a9fc02..2cf259b2 100644 --- a/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller.cc +++ b/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller.cc
@@ -6,6 +6,7 @@ #include <memory> +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/session/session_observer.h" #include "ash/session/session_controller_impl.h" @@ -25,7 +26,7 @@ CrasAudioHandler::Get()->SetSpeakOnMuteDetection(/*som_on=*/false); // Only observes `SessionController` if the feature is enabled. - if (!features::IsSpeakOnMuteEnabled()) { + if (!features::IsVideoConferenceEnabled()) { return; } SessionControllerImpl* session_controller =
diff --git a/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller_unittest.cc b/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller_unittest.cc index a80a0e4..90fe3628 100644 --- a/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller_unittest.cc +++ b/ash/system/privacy_hub/speak_on_mute_detection_privacy_switch_controller_unittest.cc
@@ -6,9 +6,12 @@ #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" +#include "ash/constants/ash_switches.h" #include "ash/shell.h" #include "ash/system/privacy_hub/privacy_hub_controller.h" +#include "ash/system/video_conference/fake_video_conference_tray_controller.h" #include "ash/test/ash_test_base.h" +#include "base/command_line.h" #include "base/test/scoped_feature_list.h" #include "chromeos/ash/components/dbus/audio/fake_cras_audio_client.h" @@ -18,9 +21,13 @@ public: PrivacyHubSpeakOnMuteControllerTest() : AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) { + // We need the privacy hub feature flag to have the controller constructed, + // and the video conference feature flag together with the camera effects + // switch to enable video conference. scoped_feature_list_.InitWithFeatures( - {ash::features::kCrosPrivacyHub, ash::features::kSpeakOnMuteEnabled}, - {}); + {ash::features::kCrosPrivacyHub, ash::features::kVideoConference}, {}); + base::CommandLine::ForCurrentProcess()->AppendSwitch( + switches::kCameraEffectsSupportedByHardware); } ~PrivacyHubSpeakOnMuteControllerTest() override = default; @@ -52,6 +59,11 @@ private: raw_ptr<SpeakOnMuteDetectionPrivacySwitchController> speak_on_mute_controller_; + // Instantiates a fake controller (the real one is created in + // ChromeBrowserMainExtraPartsAsh::PreProfileInit() which is not called in + // ash unit tests). + FakeVideoConferenceTrayController fake_video_conference_tray_controller_; + base::test::ScopedFeatureList scoped_feature_list_; };
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index 73a057d..c995eed 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -954,6 +954,8 @@ DCHECK(Shell::Get()->session_controller()->IsActiveUserSessionStarted()); DVLOG(1) << __func__ << " params=" << params; if (!CanSetUserWallpaper(params.account_id)) { + wallpaper_metrics_manager_->LogWallpaperResult( + WallpaperType::kOnline, SetWallpaperResult::kPermissionDenied); std::move(callback).Run(/*success=*/false); return; } @@ -2070,7 +2072,7 @@ const base::FilePath& file_path) { bool file_exists = !file_path.empty(); if (!file_exists) { - std::move(callback).Run(false); + std::move(callback).Run(/*success=*/false); return; } @@ -2086,7 +2088,7 @@ const OnlineWallpaperParams& params, const base::flat_map<std::string, base::FilePath>& url_to_file_path_map) { if (url_to_file_path_map.empty()) { - std::move(callback).Run(false); + std::move(callback).Run(/*success=*/false); return; } @@ -2117,7 +2119,7 @@ } // Report that setting the wallpaper failed. - std::move(callback).Run(false); + std::move(callback).Run(/*success=*/false); // Daily wallpaper should schedule retry. if (type == WallpaperType::kDaily) @@ -2130,11 +2132,17 @@ SetWallpaperCallback callback, const gfx::ImageSkia& image) { bool success = !image.isNull(); - if (callback) + if (callback) { std::move(callback).Run(success); + } if (!success) { + wallpaper_metrics_manager_->LogWallpaperResult( + WallpaperType::kOnline, SetWallpaperResult::kDecodingError); LOG(ERROR) << "Failed to decode online wallpaper."; return; + } else { + wallpaper_metrics_manager_->LogWallpaperResult( + WallpaperType::kOnline, SetWallpaperResult::kSuccess); } if (save_file) { @@ -2904,7 +2912,7 @@ SetWallpaperCallback callback, bool success) { if (success) { - std::move(callback).Run(true); + std::move(callback).Run(/*success=*/true); return; } @@ -2980,6 +2988,8 @@ gfx::ImageSkia variant_to_use = online_wallpaper_variant_to_use_; online_wallpaper_variant_to_use_ = gfx::ImageSkia(); if (!success) { + wallpaper_metrics_manager_->LogWallpaperResult( + WallpaperType::kOnline, SetWallpaperResult::kNetworkError); std::move(callback).Run(success); return; }
diff --git a/ash/wallpaper/wallpaper_metrics_manager.cc b/ash/wallpaper/wallpaper_metrics_manager.cc index a842e1da..70d939b56 100644 --- a/ash/wallpaper/wallpaper_metrics_manager.cc +++ b/ash/wallpaper/wallpaper_metrics_manager.cc
@@ -5,6 +5,7 @@ #include "ash/wallpaper/wallpaper_metrics_manager.h" #include "ash/public/cpp/wallpaper/online_wallpaper_params.h" +#include "ash/public/cpp/wallpaper/wallpaper_types.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" #include "ash/shell_delegate.h" @@ -12,9 +13,26 @@ #include "base/logging.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" +#include "base/notreached.h" namespace ash { +namespace { + +// NOTE: These strings are persisted to metric logs. +std::string ToResultHistogram(WallpaperType type) { + switch (type) { + case WallpaperType::kOnline: + return "Ash.Wallpaper.Online.Result"; + default: + // TODO(b/285387348): Implement other WallpaperType. + NOTIMPLEMENTED_LOG_ONCE(); + return ""; + } +} + +} // namespace + WallpaperMetricsManager::WallpaperMetricsManager() { wallpaper_controller_observation_.Observe(WallpaperController::Get()); } @@ -52,4 +70,9 @@ base::UmaHistogramBoolean("Ash.Wallpaper.IsSetToTimeOfDayAfterOobe", success); } +void WallpaperMetricsManager::LogWallpaperResult(WallpaperType type, + SetWallpaperResult result) { + UMA_HISTOGRAM_ENUMERATION(ToResultHistogram(type), result); +} + } // namespace ash
diff --git a/ash/wallpaper/wallpaper_metrics_manager.h b/ash/wallpaper/wallpaper_metrics_manager.h index 7230c6af..e775dfb 100644 --- a/ash/wallpaper/wallpaper_metrics_manager.h +++ b/ash/wallpaper/wallpaper_metrics_manager.h
@@ -9,10 +9,21 @@ #include "ash/public/cpp/wallpaper/online_wallpaper_params.h" #include "ash/public/cpp/wallpaper/wallpaper_controller.h" #include "ash/public/cpp/wallpaper/wallpaper_controller_observer.h" +#include "ash/public/cpp/wallpaper/wallpaper_types.h" #include "base/scoped_observation.h" namespace ash { +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +enum class SetWallpaperResult { + kSuccess = 0, + kPermissionDenied, + kNetworkError, + kDecodingError, + kMaxValue = kDecodingError, +}; + // The implementation of WallpaperControllerObserver that saves metrics. class ASH_EXPORT WallpaperMetricsManager : public WallpaperControllerObserver { public: @@ -29,6 +40,7 @@ void OnWallpaperPreviewStarted() override; void LogSettingTimeOfDayWallpaperAfterOobe(bool success); + void LogWallpaperResult(WallpaperType type, SetWallpaperResult reason); private: base::ScopedObservation<WallpaperController, WallpaperControllerObserver>
diff --git a/ash/webui/diagnostics_ui/resources/diagnostics_app.ts b/ash/webui/diagnostics_ui/resources/diagnostics_app.ts index 81f302db..666f3e4 100644 --- a/ash/webui/diagnostics_ui/resources/diagnostics_app.ts +++ b/ash/webui/diagnostics_ui/resources/diagnostics_app.ts
@@ -185,6 +185,7 @@ ]; if (this.isInputEnabled) { + pages.push(this.createInputSelector()); const devices: ConnectedDevices = await this.inputDataProvider.getConnectedDevices(); // Check the existing value of |numKeyboards| if |GetConnectedDevices| @@ -194,8 +195,8 @@ const isTouchPadOrTouchScreenEnabled = loadTimeData.getBoolean('isTouchpadEnabled') || loadTimeData.getBoolean('isTouchscreenEnabled'); - if (this.numKeyboards > 0 || isTouchPadOrTouchScreenEnabled) { - pages.push(this.createInputSelector()); + if (this.numKeyboards === 0 && !isTouchPadOrTouchScreenEnabled) { + pages.pop(); } }
diff --git a/ash/webui/personalization_app/search/search.mojom b/ash/webui/personalization_app/search/search.mojom index f046a0fc..69bcb81 100644 --- a/ash/webui/personalization_app/search/search.mojom +++ b/ash/webui/personalization_app/search/search.mojom
@@ -12,6 +12,7 @@ enum SearchConceptId { kPersonalization = 0, kChangeWallpaper = 100, + kTimeOfDayWallpaper = 101, kChangeDeviceAccountImage = 200, kAmbientMode = 300, kAmbientModeChooseSource = 301, @@ -19,6 +20,7 @@ kAmbientModeGooglePhotos = 303, kAmbientModeArtGallery = 304, kAmbientModeTurnOn = 305, + kAmbientModeTimeOfDay = 306, kDarkMode = 400, kDarkModeSchedule = 401, kDarkModeTurnOff = 402,
diff --git a/ash/webui/personalization_app/search/search_handler.cc b/ash/webui/personalization_app/search/search_handler.cc index ed370e13..67803cc 100644 --- a/ash/webui/personalization_app/search/search_handler.cc +++ b/ash/webui/personalization_app/search/search_handler.cc
@@ -122,7 +122,7 @@ search_results.push_back(mojom::SearchResult::New( /*id=*/search_concept->id, - /*text=*/l10n_util::GetStringUTF16(matching_content_id), + /*text=*/SearchTagRegistry::MessageIdToString(matching_content_id), /*relative_url=*/search_concept->relative_url, /*relevance_score=*/local_result.score)); }
diff --git a/ash/webui/personalization_app/search/search_handler_unittest.cc b/ash/webui/personalization_app/search/search_handler_unittest.cc index 4b52804..dd977a8 100644 --- a/ash/webui/personalization_app/search/search_handler_unittest.cc +++ b/ash/webui/personalization_app/search/search_handler_unittest.cc
@@ -4,11 +4,13 @@ #include "ash/webui/personalization_app/search/search_handler.h" +#include <array> #include <memory> #include <string> #include <utility> #include <vector> +#include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" #include "ash/public/cpp/ambient/ambient_prefs.h" #include "ash/public/cpp/personalization_app/enterprise_policy_delegate.h" @@ -20,9 +22,12 @@ #include "ash/webui/personalization_app/search/search_concept.h" #include "ash/webui/personalization_app/search/search_tag_registry.h" #include "base/functional/callback.h" +#include "base/ranges/algorithm.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" +#include "base/types/cxx23_to_underlying.h" #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h" #include "chromeos/ash/components/local_search_service/public/mojom/index.mojom-test-utils.h" #include "chromeos/ash/components/test/ash_test_suite.h" @@ -40,6 +45,22 @@ inline constexpr int kMaxNumResults = 3; +constexpr std::array<int, 6> kTimeOfDayWallpaperMessageIds = { + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT1, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT2, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT3, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT4, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT5, +}; + +constexpr std::array<int, 4> kAmbientModeTimeOfDayMessageIds = { + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT1, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT2, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT3, +}; + bool HasSearchResult(const std::vector<mojom::SearchResultPtr>& search_results, const std::u16string& text) { for (const auto& result : search_results) { @@ -52,9 +73,7 @@ std::string SearchConceptIdToString( mojom::SearchConceptId search_result_concept) { - return base::NumberToString( - static_cast<std::underlying_type_t<mojom::SearchConceptId>>( - search_result_concept)); + return base::NumberToString(base::to_underlying(search_result_concept)); } class TestSearchResultsObserver : public mojom::SearchResultsObserver { @@ -163,6 +182,11 @@ test_pref_service_->registry()->RegisterBooleanPref( ::ash::prefs::kDarkModeEnabled, false); + InitSearchHandler(); + } + + void InitSearchHandler() { + search_handler_remote_.reset(); search_handler_ = std::make_unique<SearchHandler>( *local_search_service_proxy_, test_pref_service_.get(), std::make_unique<TestEnterprisePolicyDelegate>()); @@ -194,7 +218,7 @@ return search_handler_->search_tag_registry_.get(); } - TestEnterprisePolicyDelegate* test_search_delegate() { + TestEnterprisePolicyDelegate* test_enterprise_policy_delegate() { return static_cast<TestEnterprisePolicyDelegate*>( search_tag_registry()->enterprise_policy_delegate_.get()); } @@ -209,7 +233,7 @@ std::vector<mojom::SearchResultPtr> RunSearch(int message_id) { std::vector<mojom::SearchResultPtr> search_results; - std::u16string query = l10n_util::GetStringUTF16(message_id); + std::u16string query = SearchTagRegistry::MessageIdToString(message_id); // Search results match better if one character is subtracted. query.pop_back(); mojom::SearchHandlerAsyncWaiter(search_handler_remote()->get()) @@ -316,7 +340,7 @@ TestSearchResultsObserver test_observer; search_handler_remote()->get()->AddObserver(test_observer.GetRemote()); - test_search_delegate()->SetIsUserImageEnterpriseManaged(true); + test_enterprise_policy_delegate()->SetIsUserImageEnterpriseManaged(true); test_observer.WaitForSearchResultsChanged(); @@ -332,7 +356,7 @@ TestSearchResultsObserver test_observer; search_handler_remote()->get()->AddObserver(test_observer.GetRemote()); - test_search_delegate()->SetIsWallpaperImageEnterpriseManaged(true); + test_enterprise_policy_delegate()->SetIsWallpaperImageEnterpriseManaged(true); test_observer.WaitForSearchResultsChanged(); @@ -463,4 +487,137 @@ EXPECT_EQ(0.5, results.at(1)->relevance_score); } +TEST_F(PersonalizationAppSearchHandlerTest, NoTimeOfDayWallpaperResults) { + for (const auto message_id : kTimeOfDayWallpaperMessageIds) { + std::vector<mojom::SearchResultPtr> time_of_day_search_results = + RunSearch(message_id); + + auto time_of_day_result = base::ranges::find_if( + time_of_day_search_results, [](const auto& result) { + return result->search_concept_id == + mojom::SearchConceptId::kTimeOfDayWallpaper; + }); + + EXPECT_EQ(time_of_day_search_results.end(), time_of_day_result); + } +} + +TEST_F(PersonalizationAppSearchHandlerTest, NoAmbientModeTimeOfDayResults) { + for (const auto message_id : kAmbientModeTimeOfDayMessageIds) { + std::vector<mojom::SearchResultPtr> time_of_day_search_results = + RunSearch(message_id); + + auto time_of_day_result = base::ranges::find_if( + time_of_day_search_results, [](const auto& result) { + return result->search_concept_id == + mojom::SearchConceptId::kAmbientModeTimeOfDay; + }); + + EXPECT_EQ(time_of_day_search_results.end(), time_of_day_result); + } +} + +class PersonalizationAppSearchHandlerTimeOfDayTest + : public PersonalizationAppSearchHandlerTest { + public: + PersonalizationAppSearchHandlerTimeOfDayTest() { + scoped_feature_list_.InitWithFeatures( + {::ash::features::kTimeOfDayWallpaper, + ::ash::features::kTimeOfDayScreenSaver}, + {}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(PersonalizationAppSearchHandlerTimeOfDayTest, TimeOfDayWallpaperSearch) { + for (const auto message_id : kTimeOfDayWallpaperMessageIds) { + std::vector<mojom::SearchResultPtr> time_of_day_search_results = + RunSearch(message_id); + + auto time_of_day_result = base::ranges::find_if( + time_of_day_search_results, [](const auto& result) { + return result->search_concept_id == + mojom::SearchConceptId::kTimeOfDayWallpaper; + }); + + EXPECT_NE(time_of_day_search_results.end(), time_of_day_result); + EXPECT_EQ("wallpaper/collection?id=_time_of_day_chromebook_collection", + time_of_day_result->get()->relative_url); + } +} + +TEST_F(PersonalizationAppSearchHandlerTimeOfDayTest, + AmbientModeTimeOfDaySearch) { + for (const auto message_id : kAmbientModeTimeOfDayMessageIds) { + std::vector<mojom::SearchResultPtr> time_of_day_search_results = + RunSearch(message_id); + + auto time_of_day_result = base::ranges::find_if( + time_of_day_search_results, [](const auto& result) { + return result->search_concept_id == + mojom::SearchConceptId::kAmbientModeTimeOfDay; + }); + + EXPECT_NE(time_of_day_search_results.end(), time_of_day_result); + EXPECT_EQ(kAmbientSubpageRelativeUrl, + time_of_day_result->get()->relative_url); + } +} + +TEST_F(PersonalizationAppSearchHandlerTimeOfDayTest, + TimeOfDayWallpaperSearchPolicyControlled) { + test_enterprise_policy_delegate()->SetIsWallpaperImageEnterpriseManaged(true); + + for (const auto message_id : kTimeOfDayWallpaperMessageIds) { + std::vector<mojom::SearchResultPtr> time_of_day_search_results = + RunSearch(message_id); + + auto time_of_day_result = base::ranges::find_if( + time_of_day_search_results, [](const auto& result) { + return result->search_concept_id == + mojom::SearchConceptId::kTimeOfDayWallpaper; + }); + + EXPECT_EQ(time_of_day_search_results.end(), time_of_day_result); + } +} + +TEST_F(PersonalizationAppSearchHandlerTimeOfDayTest, + TimeOfDayScreenSaverDisallowed) { + // Search tag registry does not live update when ambient mode allowed is set + // to false. This cannot happen during a session for a given account, so no + // need for an observer method. Log in as a non-eligible account and clear and + // recreate the search handler to receive updates. + SimulateUserLogin("asdf@example.com"); + ClearSearchTagRegistry(); + InitSearchHandler(); + { + // Search another message id that should be present to confirm that search + // is still working. + std::vector<mojom::SearchResultPtr> other_search_results = + RunSearch(IDS_PERSONALIZATION_APP_SEARCH_RESULT_CHANGE_WALLPAPER); + auto desired_result = + base::ranges::find_if(other_search_results, [](const auto& result) { + return result->search_concept_id == + mojom::SearchConceptId::kChangeWallpaper; + }); + ASSERT_NE(other_search_results.end(), desired_result); + } + + for (const auto message_id : kAmbientModeTimeOfDayMessageIds) { + std::vector<mojom::SearchResultPtr> time_of_day_search_results = + RunSearch(message_id); + + auto time_of_day_result = base::ranges::find_if( + time_of_day_search_results, [](const auto& result) { + return result->search_concept_id == + mojom::SearchConceptId::kAmbientModeTimeOfDay; + }); + + EXPECT_EQ(time_of_day_search_results.end(), time_of_day_result); + } +} + } // namespace ash::personalization_app
diff --git a/ash/webui/personalization_app/search/search_tag_registry.cc b/ash/webui/personalization_app/search/search_tag_registry.cc index 42d335d..fdd1dd1b 100644 --- a/ash/webui/personalization_app/search/search_tag_registry.cc +++ b/ash/webui/personalization_app/search/search_tag_registry.cc
@@ -6,15 +6,18 @@ #include <iterator> #include <map> +#include <string> #include <vector> #include "ash/constants/ash_features.h" #include "ash/constants/ash_pref_names.h" +#include "ash/public/cpp/ambient/ambient_backend_controller.h" #include "ash/public/cpp/ambient/ambient_client.h" #include "ash/public/cpp/ambient/ambient_prefs.h" #include "ash/public/cpp/personalization_app/enterprise_policy_delegate.h" #include "ash/rgb_keyboard/rgb_keyboard_manager.h" #include "ash/shell.h" +#include "ash/wallpaper/wallpaper_constants.h" #include "ash/webui/personalization_app/personalization_app_url_constants.h" #include "ash/webui/personalization_app/search/search.mojom-shared.h" #include "ash/webui/personalization_app/search/search.mojom.h" @@ -22,7 +25,10 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/no_destructor.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/utf_string_conversions.h" +#include "base/types/cxx23_to_underlying.h" #include "chromeos/ash/components/local_search_service/public/cpp/local_search_service_proxy.h" #include "chromeos/ash/components/local_search_service/shared_structs.h" #include "chromeos/strings/grit/chromeos_strings.h" @@ -39,9 +45,7 @@ } std::string SearchConceptToId(const SearchConcept& search_concept) { - return base::NumberToString( - static_cast<std::underlying_type_t<mojom::SearchConceptId>>( - search_concept.id)); + return base::NumberToString(base::to_underlying(search_concept.id)); } std::vector<int> GetMessageIds(const SearchConcept& search_concept) { @@ -62,8 +66,9 @@ std::vector<local_search_service::Content> content_vector; for (auto message_id : GetMessageIds(search_concept)) { - content_vector.emplace_back(base::NumberToString(message_id), - l10n_util::GetStringUTF16(message_id)); + content_vector.emplace_back( + base::NumberToString(message_id), + SearchTagRegistry::MessageIdToString(message_id)); } return content_vector; @@ -97,9 +102,34 @@ return *search_concept; } +const SearchConcept& GetTimeOfDayWallpaperSearchConcept() { + DCHECK(::ash::features::IsTimeOfDayWallpaperEnabled()); + static const base::NoDestructor<const SearchConcept> search_concept({ + .id = mojom::SearchConceptId::kTimeOfDayWallpaper, + .message_id = IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER, + .alternate_message_ids = + { + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT1, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT2, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT3, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT4, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT5, + }, + .relative_url = + base::StrCat({kWallpaperSubpageRelativeUrl, "/collection?id=", + wallpaper_constants::kTimeOfDayWallpaperCollectionId}), + }); + return *search_concept; +} + SearchTagRegistry::SearchConceptUpdates GetWallpaperEnterpriseUpdates( bool is_enterprise_managed) { - return {{&GetWallpaperSearchConcept(), !is_enterprise_managed}}; + SearchTagRegistry::SearchConceptUpdates updates{ + {&GetWallpaperSearchConcept(), !is_enterprise_managed}}; + if (::ash::features::IsTimeOfDayWallpaperEnabled()) { + updates[&GetTimeOfDayWallpaperSearchConcept()] = !is_enterprise_managed; + } + return updates; } const SearchConcept& GetUserImageSearchConcept() { @@ -135,6 +165,23 @@ return *search_concept; } +const SearchConcept& GetAmbientTimeOfDaySearchConcept() { + DCHECK(::ash::features::IsTimeOfDayScreenSaverEnabled()); + static const base::NoDestructor<const SearchConcept> search_concept({ + .id = mojom::SearchConceptId::kAmbientModeTimeOfDay, + .message_id = + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY, + .alternate_message_ids = + { + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT1, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT2, + IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT3, + }, + .relative_url = kAmbientSubpageRelativeUrl, + }); + return *search_concept; +} + const std::vector<const SearchConcept>& GetAmbientOnSearchConcepts() { static const base::NoDestructor<std::vector<const SearchConcept>> tags({ { @@ -317,6 +364,20 @@ } // namespace +// static +std::u16string SearchTagRegistry::MessageIdToString(int message_id) { + switch (message_id) { + case IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY: + case IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER: + return l10n_util::GetStringFUTF16( + message_id, + base::UTF8ToUTF16( + AmbientBackendController::Get()->GetTimeOfDayProductName())); + default: + return l10n_util::GetStringUTF16(message_id); + } +} + SearchTagRegistry::SearchTagRegistry( local_search_service::LocalSearchServiceProxy& local_search_service_proxy, PrefService* pref_service, @@ -337,6 +398,7 @@ updates.merge(GetUserImageEnterpriseUpdates( enterprise_policy_delegate_->IsUserImageEnterpriseManaged())); + updates.merge(GetWallpaperEnterpriseUpdates( enterprise_policy_delegate_->IsWallpaperEnterpriseManaged())); @@ -357,6 +419,9 @@ if (IsAmbientModeAllowed()) { updates[&GetAmbientSearchConcept()] = true; + if (::ash::features::IsTimeOfDayScreenSaverEnabled()) { + updates[&GetAmbientTimeOfDaySearchConcept()] = true; + } updates.merge(GetAmbientPrefChangedUpdates( pref_service_->GetBoolean(::ash::ambient::prefs::kAmbientModeEnabled))); } @@ -444,6 +509,7 @@ } void SearchTagRegistry::OnAmbientPrefChanged() { + DCHECK(IsAmbientModeAllowed()); bool ambient_on = pref_service_->GetBoolean(::ash::ambient::prefs::kAmbientModeEnabled); UpdateSearchConcepts(GetAmbientPrefChangedUpdates(ambient_on));
diff --git a/ash/webui/personalization_app/search/search_tag_registry.h b/ash/webui/personalization_app/search/search_tag_registry.h index 7329f99..f6f9721 100644 --- a/ash/webui/personalization_app/search/search_tag_registry.h +++ b/ash/webui/personalization_app/search/search_tag_registry.h
@@ -41,6 +41,8 @@ using SearchConceptUpdates = std::map<const SearchConcept*, bool>; + static std::u16string MessageIdToString(int message_id); + SearchTagRegistry( local_search_service::LocalSearchServiceProxy& local_search_service_proxy, PrefService* pref_service,
diff --git a/base/BUILD.gn b/base/BUILD.gn index b4ae946..df2bd3f 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -2165,16 +2165,6 @@ "base_paths_mac.h", "base_paths_mac.mm", "critical_closure_internal_ios.mm", - "ios/block_types.h", - "ios/device_util.h", - "ios/device_util.mm", - "ios/ios_util.h", - "ios/ios_util.mm", - "ios/ns_error_util.h", - "ios/ns_error_util.mm", - "ios/ns_range.h", - "ios/scoped_critical_action.h", - "ios/scoped_critical_action.mm", "native_library_ios.mm", "power_monitor/power_monitor_device_source_ios.mm", "process/process_metrics_ios.cc", @@ -2188,7 +2178,6 @@ "files/file_path_watcher_kqueue.cc", "files/file_path_watcher_kqueue.h", "files/file_path_watcher_mac.cc", - "ios/sim_header_shims.h", "mac/mach_port_rendezvous.cc", "mac/mach_port_rendezvous.h", "process/kill_mac.cc", @@ -2212,6 +2201,9 @@ ] } + public_deps += [ "//base/ios" ] + allow_circular_includes_from += [ "//base/ios" ] + if (is_cronet_build) { sources += [ "message_loop/message_pump_io_ios.cc", @@ -2740,6 +2732,10 @@ if (is_mac) { frameworks = [ "CoreFoundation.framework" ] } + + if (is_ios) { + deps += [ "//base/ios" ] + } } test("base_perftests") {
diff --git a/base/PRESUBMIT.py b/base/PRESUBMIT.py index 13c17065..8ee2005 100644 --- a/base/PRESUBMIT.py +++ b/base/PRESUBMIT.py
@@ -8,10 +8,6 @@ for more details on the presubmit API built into depot_tools. """ - -USE_PYTHON3 = True - - def CheckChangeLintsClean(input_api, output_api): """Makes sure that the code is cpplint clean.""" # lint_filters=[] stops the OFF_BY_DEFAULT_LINT_FILTERS from being disabled,
diff --git a/base/allocator/partition_allocator/page_allocator_constants.h b/base/allocator/partition_allocator/page_allocator_constants.h index 37a88fc3..05c99c4 100644 --- a/base/allocator/partition_allocator/page_allocator_constants.h +++ b/base/allocator/partition_allocator/page_allocator_constants.h
@@ -77,7 +77,7 @@ // compiled for 64kB are likely to work on 4kB systems, 64kB is a good choice // here. return 16; // 64kB -#elif defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_LOONG64) +#elif defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_LOONGARCH64) return 14; // 16kB #elif BUILDFLAG(IS_APPLE) && defined(ARCH_CPU_64_BITS) return static_cast<size_t>(vm_page_shift);
diff --git a/base/allocator/partition_allocator/partition_alloc_config.h b/base/allocator/partition_allocator/partition_alloc_config.h index 2931396..7b69265 100644 --- a/base/allocator/partition_allocator/partition_alloc_config.h +++ b/base/allocator/partition_allocator/partition_alloc_config.h
@@ -158,6 +158,18 @@ static_assert(sizeof(void*) == 8); #endif +// If memory tagging is enabled with BRP previous slot, the MTE tag and BRP ref +// count will cause a race (crbug.com/1445816). To prevent this, the +// ref_count_size is increased to the MTE granule size and the ref count is not +// tagged. +#if PA_CONFIG(HAS_MEMORY_TAGGING) && \ + BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) && \ + BUILDFLAG(PUT_REF_COUNT_IN_PREVIOUS_SLOT) +#define PA_CONFIG_INCREASE_REF_COUNT_SIZE_FOR_MTE() 1 +#else +#define PA_CONFIG_INCREASE_REF_COUNT_SIZE_FOR_MTE() 0 +#endif + // Specifies whether allocation extras need to be added. #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SUPPORT) #define PA_CONFIG_EXTRAS_REQUIRED() 1
diff --git a/base/allocator/partition_allocator/partition_alloc_constants.h b/base/allocator/partition_allocator/partition_alloc_constants.h index 4e1f28df6..7d2060e1 100644 --- a/base/allocator/partition_allocator/partition_alloc_constants.h +++ b/base/allocator/partition_allocator/partition_alloc_constants.h
@@ -81,7 +81,7 @@ // other constant values, we pack _all_ `PartitionRoot::Alloc` sizes perfectly // up against the end of a system page. -#if defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_LOONG64) +#if defined(_MIPS_ARCH_LOONGSON) || defined(ARCH_CPU_LOONGARCH64) PA_ALWAYS_INLINE PAGE_ALLOCATOR_CONSTANTS_DECLARE_CONSTEXPR size_t PartitionPageShift() { return 16; // 64 KiB
diff --git a/base/allocator/partition_allocator/partition_alloc_unittest.cc b/base/allocator/partition_allocator/partition_alloc_unittest.cc index 7e916990..16365ca 100644 --- a/base/allocator/partition_allocator/partition_alloc_unittest.cc +++ b/base/allocator/partition_allocator/partition_alloc_unittest.cc
@@ -254,14 +254,25 @@ }; const std::vector<PartitionAllocTestParam> GetPartitionAllocTestParams() { - std::vector<size_t> ref_count_sizes = {0, 8, 16}; - // sizeof(PartitionRefCount) == 8 under some configurations, so we can't force - // the size down to 4. + std::vector<size_t> ref_count_sizes = {16}; + + bool only_supports_16b_ref_count = false; +#if PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE) + only_supports_16b_ref_count = + partition_alloc::internal::base::CPU::GetInstanceNoAllocation().has_mte(); +#endif + + if (!only_supports_16b_ref_count) { + ref_count_sizes.push_back(0); + ref_count_sizes.push_back(8); + // sizeof(PartitionRefCount) == 8 under some configurations, so we can't + // force the size down to 4. #if !PA_CONFIG(REF_COUNT_STORE_REQUESTED_SIZE) && \ !PA_CONFIG(REF_COUNT_CHECK_COOKIE) && \ !BUILDFLAG(ENABLE_DANGLING_RAW_PTR_CHECKS) - ref_count_sizes.push_back(4); + ref_count_sizes.push_back(4); #endif + } std::vector<PartitionAllocTestParam> params; for (size_t ref_count_size : ref_count_sizes) {
diff --git a/base/allocator/partition_allocator/partition_bucket.cc b/base/allocator/partition_allocator/partition_bucket.cc index 8a97bb0d..bcb3e0f 100644 --- a/base/allocator/partition_allocator/partition_bucket.cc +++ b/base/allocator/partition_allocator/partition_bucket.cc
@@ -581,6 +581,20 @@ return static_cast<uint8_t>(best_pages); } +#if PA_CONFIG(HAS_MEMORY_TAGGING) +// Returns size that should be tagged. Avoiding the previous slot ref count if +// it exists to avoid a race (crbug.com/1445816). +template <bool thread_safe> +PA_ALWAYS_INLINE size_t TagSizeForSlot(PartitionRoot<thread_safe>* root, + size_t slot_size) { +#if PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE) + return slot_size - root->flags.ref_count_size; +#else + return slot_size; +#endif +} +#endif // PA_CONFIG(HAS_MEMORY_TAGGING) + } // namespace uint8_t ComputeSystemPagesPerSlotSpan(size_t slot_size, @@ -979,7 +993,7 @@ root->IsMemoryTaggingEnabled() && slot_size <= kMaxMemoryTaggingSize; if (PA_LIKELY(use_tagging)) { // Ensure the MTE-tag of the memory pointed by |return_slot| is unguessable. - TagMemoryRangeRandomly(return_slot, slot_size); + TagMemoryRangeRandomly(return_slot, TagSizeForSlot(root, slot_size)); } #endif // PA_CONFIG(HAS_MEMORY_TAGGING) // Add all slots that fit within so far committed pages to the free list. @@ -993,7 +1007,8 @@ // Ensure the MTE-tag of the memory pointed by other provisioned slot is // unguessable. They will be returned to the app as is, and the MTE-tag // will only change upon calling Free(). - next_slot_ptr = TagMemoryRangeRandomly(next_slot, slot_size); + next_slot_ptr = + TagMemoryRangeRandomly(next_slot, TagSizeForSlot(root, slot_size)); } else { // No MTE-tagging for larger slots, just cast. next_slot_ptr = reinterpret_cast<void*>(next_slot);
diff --git a/base/allocator/partition_allocator/partition_ref_count.h b/base/allocator/partition_allocator/partition_ref_count.h index 8cdc0c5..6a58431 100644 --- a/base/allocator/partition_allocator/partition_ref_count.h +++ b/base/allocator/partition_allocator/partition_ref_count.h
@@ -419,14 +419,8 @@ #if BUILDFLAG(PA_DCHECK_IS_ON) || BUILDFLAG(ENABLE_BACKUP_REF_PTR_SLOW_CHECKS) PA_CHECK(refcount_address % alignof(PartitionRefCount) == 0); #endif - // Have to MTE-tag, because the address is untagged, but lies within a slot - // area, which is protected by MTE. - // - // There could be a race condition though if the previous slot is - // freed/retagged concurrently, so ideally the ref count should occupy its - // own MTE granule. - // TODO(crbug.com/1445816): improve this. - return static_cast<PartitionRefCount*>(TagAddr(refcount_address)); + // No need to tag because the ref count is not protected by MTE. + return reinterpret_cast<PartitionRefCount*>(refcount_address); } else { // No need to tag, as the metadata region isn't protected by MTE. PartitionRefCount* bitmap_base = reinterpret_cast<PartitionRefCount*>(
diff --git a/base/allocator/partition_allocator/partition_root.cc b/base/allocator/partition_allocator/partition_root.cc index c12a33b..27389db1 100644 --- a/base/allocator/partition_allocator/partition_root.cc +++ b/base/allocator/partition_allocator/partition_root.cc
@@ -968,6 +968,13 @@ if (!ref_count_size) { ref_count_size = internal::kPartitionRefCountSizeAdjustment; } +#if PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE) + if (IsMemoryTaggingEnabled()) { + ref_count_size = internal::base::bits::AlignUp( + ref_count_size, internal::kMemTagGranuleSize); + } + flags.ref_count_size = ref_count_size; +#endif // PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE) PA_CHECK(internal::kPartitionRefCountSizeAdjustment <= ref_count_size); flags.extras_size += ref_count_size; flags.extras_offset += internal::kPartitionRefCountOffsetAdjustment;
diff --git a/base/allocator/partition_allocator/partition_root.h b/base/allocator/partition_allocator/partition_root.h index a0e23e1..52e023e 100644 --- a/base/allocator/partition_allocator/partition_root.h +++ b/base/allocator/partition_allocator/partition_root.h
@@ -258,7 +258,10 @@ bool use_configurable_pool; #if PA_CONFIG(HAS_MEMORY_TAGGING) bool memory_tagging_enabled_ = false; -#endif +#if PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE) + size_t ref_count_size; +#endif // PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE) +#endif // PA_CONFIG(HAS_MEMORY_TAGGING) #if BUILDFLAG(ENABLE_THREAD_ISOLATION) ThreadIsolationOption thread_isolation; #endif @@ -1218,8 +1221,12 @@ // slot_span is untagged at this point, so we have to recover its tag // again to increment and provide use-after-free mitigations. uintptr_t slot_start_to_object_delta = object_addr - slot_start; + size_t tag_size = slot_size; +#if PA_CONFIG(INCREASE_REF_COUNT_SIZE_FOR_MTE) + tag_size -= root->flags.ref_count_size; +#endif void* retagged_slot_start = internal::TagMemoryRangeIncrement( - internal::TagAddr(slot_start), slot_size); + internal::TagAddr(slot_start), tag_size); // Incrementing the MTE-tag in the memory range invalidates the |object|'s // tag, so it must be retagged. object = reinterpret_cast<void*>(
diff --git a/base/allocator/partition_allocator/pointers/raw_ptr.h b/base/allocator/partition_allocator/pointers/raw_ptr.h index 6ad9c9c..c356da1 100644 --- a/base/allocator/partition_allocator/pointers/raw_ptr.h +++ b/base/allocator/partition_allocator/pointers/raw_ptr.h
@@ -1188,6 +1188,13 @@ // This is not meant to be added manually. You can ignore this flag. constexpr auto ExperimentalAsh = base::RawPtrTraits::kExperimentalAsh; +// This flag is used to tag a subset of dangling pointers. Similarly to +// DanglingUntriaged, those pointers are known to be dangling. However, we also +// detected that those raw_ptr's were never released (either by calling +// raw_ptr's destructor or by resetting its value), which can ultimately put +// pressure on the BRP quarantine. +constexpr auto LeakedDanglingUntriaged = base::RawPtrTraits::kMayDangle; + namespace std { // Override so set/map lookups do not create extra raw_ptr. This also allows
diff --git a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java index 2f0a58483..5d5815f 100644 --- a/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java +++ b/base/android/java/src/org/chromium/base/library_loader/LibraryLoader.java
@@ -580,9 +580,13 @@ * * @deprecated: please avoid using in new code: * https://crsrc.org/c/base/android/jni_generator/README.md#testing-for-readiness-use-get + * + * TODO(crbug.com/1406012): adding back {@link VisibleForTesting} after crbug.com/1442347 is + * fixed. This method is exposed in order to unblock the test failures because of isInitialized + * loading .so file before native flags are ready. Ideally, it should be fixed by migrating + * the feature flag to CachedFlag. */ @Deprecated - @VisibleForTesting public boolean isLoaded() { return mLoadState == LoadState.LOADED && (!sEnableStateForTesting || mLoadStateForTesting == LoadState.LOADED);
diff --git a/base/android/jni_generator/PRESUBMIT.py b/base/android/jni_generator/PRESUBMIT.py index c6b1312..9e09180 100644 --- a/base/android/jni_generator/PRESUBMIT.py +++ b/base/android/jni_generator/PRESUBMIT.py
@@ -8,9 +8,6 @@ details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): base_android_jni_generator_dir = input_api.PresubmitLocalPath() @@ -24,7 +21,6 @@ input_api.canned_checks.GetUnitTests( input_api, output_api, - run_on_python2=False, unit_tests=[ input_api.os_path.join(base_android_jni_generator_dir, 'jni_generator_tests.py')
diff --git a/base/debug/asan_service_unittest.cc b/base/debug/asan_service_unittest.cc index 0571e065..d3a7b094 100644 --- a/base/debug/asan_service_unittest.cc +++ b/base/debug/asan_service_unittest.cc
@@ -11,6 +11,7 @@ #include <sstream> #include "base/debug/asan_invalid_access.h" +#include "base/memory/raw_ref.h" #include "base/run_loop.h" #include "base/strings/string_piece.h" #include "base/test/bind.h" @@ -103,19 +104,19 @@ AsanTaskTraceTest() {} void Run() { - task_runner_.PostTask( + task_runner_->PostTask( FROM_HERE, BindOnce(&AsanTaskTraceTest::PostingTask, Unretained(this))); task_environment_.RunUntilIdle(); } private: void PostingTask() { - task_runner_.PostTask(FROM_HERE, BindOnce(&AsanHeapUseAfterFree)); + task_runner_->PostTask(FROM_HERE, BindOnce(&AsanHeapUseAfterFree)); } test::TaskEnvironment task_environment_; - SingleThreadTaskRunner& task_runner_ = - *task_environment_.GetMainThreadTaskRunner(); + const raw_ref<SingleThreadTaskRunner> task_runner_{ + *task_environment_.GetMainThreadTaskRunner()}; }; TEST_F(AsanServiceTest, MAYBE_TaskTraceCallback) {
diff --git a/base/ios/BUILD.gn b/base/ios/BUILD.gn index 8aac4634..1a16242 100644 --- a/base/ios/BUILD.gn +++ b/base/ios/BUILD.gn
@@ -2,15 +2,37 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/features.gni") +import("//build/config/ios/config.gni") + source_set("ios") { sources = [ + "block_types.h", "crb_protocol_observers.h", "crb_protocol_observers.mm", + "device_util.h", + "device_util.mm", + "ios_util.h", + "ios_util.mm", + "ns_error_util.h", + "ns_error_util.mm", + "ns_range.h", + "scoped_critical_action.h", + "scoped_critical_action.mm", ] + if (use_blink) { + sources += [ "sim_header_shims.h" ] + } + frameworks = [ "Foundation.framework" ] - deps = [ "//base" ] - configs += [ "//build/config/compiler:enable_arc" ] + + deps = [ + "//base:base_static", + "//base/numerics:base_numerics", + "//build:blink_buildflags", + "//third_party/abseil-cpp:absl", + ] }
diff --git a/base/ios/device_util.mm b/base/ios/device_util.mm index 4aa6219..1126e497 100644 --- a/base/ios/device_util.mm +++ b/base/ios/device_util.mm
@@ -22,6 +22,10 @@ #include "base/strings/stringprintf.h" #include "base/strings/sys_string_conversions.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { // Client ID key in the user preferences. @@ -54,8 +58,7 @@ } // namespace -namespace ios { -namespace device_util { +namespace ios::device_util { std::string GetPlatform() { #if TARGET_OS_SIMULATOR @@ -185,5 +188,4 @@ return base::SysCFStringRefToUTF8(device_id); } -} // namespace device_util -} // namespace ios +} // namespace ios::device_util
diff --git a/base/ios/ios_util.mm b/base/ios/ios_util.mm index 45336e24..74025d51 100644 --- a/base/ios/ios_util.mm +++ b/base/ios/ios_util.mm
@@ -12,14 +12,17 @@ #include "base/mac/foundation_util.h" #include "base/system/sys_info.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { std::string* g_icudtl_path_override = nullptr; } // namespace -namespace base { -namespace ios { +namespace base::ios { bool IsRunningOnIOS12OrLater() { static const bool is_running_on_or_later = IsRunningOnOrLater(12, 0, 0); @@ -105,5 +108,4 @@ return is_dynamic_island_model; } -} // namespace ios -} // namespace base +} // namespace base::ios
diff --git a/base/ios/ns_error_util.mm b/base/ios/ns_error_util.mm index cf0e1f1..40fc381 100644 --- a/base/ios/ns_error_util.mm +++ b/base/ios/ns_error_util.mm
@@ -7,15 +7,17 @@ #import <Foundation/Foundation.h> #include "base/check.h" -#include "base/mac/scoped_nsobject.h" -namespace base { -namespace ios { +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace base::ios { namespace { // Iterates through |error|'s underlying errors and returns them in an array. -NSArray* GetFullErrorChainForError(NSError* error) { - NSMutableArray* error_chain = [NSMutableArray array]; +NSArray<NSError*>* GetFullErrorChainForError(NSError* error) { + NSMutableArray<NSError*>* error_chain = [NSMutableArray array]; NSError* current_error = error; while (current_error) { DCHECK([current_error isKindOfClass:[NSError class]]); @@ -28,20 +30,19 @@ NSError* GetFinalUnderlyingErrorFromError(NSError* error) { DCHECK(error); - return [GetFullErrorChainForError(error) lastObject]; + return GetFullErrorChainForError(error).lastObject; } NSError* ErrorWithAppendedUnderlyingError(NSError* original_error, NSError* underlying_error) { DCHECK(original_error); DCHECK(underlying_error); - NSArray* error_chain = GetFullErrorChainForError(original_error); + NSArray<NSError*>* error_chain = GetFullErrorChainForError(original_error); NSError* current_error = underlying_error; for (size_t idx = error_chain.count; idx > 0; --idx) { NSError* error = error_chain[idx - 1]; - scoped_nsobject<NSMutableDictionary> user_info( - [error.userInfo mutableCopy]); - [user_info setObject:current_error forKey:NSUnderlyingErrorKey]; + NSMutableDictionary* user_info = [error.userInfo mutableCopy]; + user_info[NSUnderlyingErrorKey] = current_error; current_error = [NSError errorWithDomain:error.domain code:error.code userInfo:user_info]; @@ -49,5 +50,4 @@ return current_error; } -} // namespace ios -} // namespace base +} // namespace base::ios
diff --git a/base/ios/scoped_critical_action.mm b/base/ios/scoped_critical_action.mm index 6266a2a..c62b638 100644 --- a/base/ios/scoped_critical_action.mm +++ b/base/ios/scoped_critical_action.mm
@@ -5,10 +5,10 @@ #include "base/ios/scoped_critical_action.h" #import <UIKit/UIKit.h> +#include <float.h> #include <atomic> -#include <float.h> #include "base/ios/ios_util.h" #include "base/logging.h" #include "base/memory/ref_counted.h" @@ -19,8 +19,11 @@ #include "base/strings/sys_string_conversions.h" #include "base/synchronization/lock.h" -namespace base { -namespace ios { +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +namespace base::ios { namespace { constexpr base::TimeDelta kMaxTaskReuseDelay = base::Seconds(3); @@ -62,7 +65,7 @@ // static void ScopedCriticalAction::Core::StartBackgroundTask(scoped_refptr<Core> core, StringPiece task_name) { - UIApplication* application = [UIApplication sharedApplication]; + UIApplication* application = UIApplication.sharedApplication; if (!application) { return; } @@ -208,5 +211,4 @@ } } -} // namespace ios -} // namespace base +} // namespace base::ios
diff --git a/base/process/launch_posix.cc b/base/process/launch_posix.cc index 1c55917..b249686 100644 --- a/base/process/launch_posix.cc +++ b/base/process/launch_posix.cc
@@ -713,9 +713,9 @@ // specifying a new stack, so we use setjmp/longjmp to emulate // fork-like behavior. alignas(16) char stack_buf[PTHREAD_STACK_MIN]; -#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ - defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_S390_FAMILY) || \ - defined(ARCH_CPU_PPC64_FAMILY) || defined(ARCH_CPU_LOONG_FAMILY) || \ +#if defined(ARCH_CPU_X86_FAMILY) || defined(ARCH_CPU_ARM_FAMILY) || \ + defined(ARCH_CPU_MIPS_FAMILY) || defined(ARCH_CPU_S390_FAMILY) || \ + defined(ARCH_CPU_PPC64_FAMILY) || defined(ARCH_CPU_LOONGARCH_FAMILY) || \ defined(ARCH_CPU_RISCV_FAMILY) // The stack grows downward. void* stack = stack_buf + sizeof(stack_buf);
diff --git a/base/profiler/stack_copier_signal.cc b/base/profiler/stack_copier_signal.cc index 963bc9a..236ec179 100644 --- a/base/profiler/stack_copier_signal.cc +++ b/base/profiler/stack_copier_signal.cc
@@ -4,6 +4,7 @@ #include "base/profiler/stack_copier_signal.h" +#include <errno.h> #include <linux/futex.h> #include <signal.h> #include <sys/ucontext.h> @@ -30,30 +31,49 @@ // handlers cannot allocate memory or use pthread api. class AsyncSafeWaitableEvent { public: - AsyncSafeWaitableEvent() { futex_.store(0, std::memory_order_release); } - ~AsyncSafeWaitableEvent() {} + AsyncSafeWaitableEvent() { + futex_.store(kNotSignaled, std::memory_order_release); + } + ~AsyncSafeWaitableEvent() = default; + AsyncSafeWaitableEvent(const AsyncSafeWaitableEvent&) = delete; + AsyncSafeWaitableEvent& operator=(const AsyncSafeWaitableEvent&) = delete; bool Wait() { // futex() can wake up spuriously if this memory address was previously used - // for a pthread mutex. So, also check the condition. + // for a pthread mutex or we get a signal. So, also check the condition. while (true) { long res = syscall(SYS_futex, futex_int_ptr(), FUTEX_WAIT | FUTEX_PRIVATE_FLAG, - 0, nullptr, nullptr, 0); - if (futex_.load(std::memory_order_acquire) != 0) + kNotSignaled, nullptr, nullptr, 0); + int futex_errno = errno; + if (futex_.load(std::memory_order_acquire) != kNotSignaled) { return true; - if (res != 0) - return false; + } + if (res != 0) { + // EINTR indicates the wait was interrupted by a signal; retry the wait. + // EAGAIN happens if this thread sees the FUTEX_WAKE before it sees the + // atomic_int store in Signal. This can't happen in an unoptimized + // single total modification order threading model; however, since we + // using release-acquire semantics on the atomic_int, it might be. (The + // futex docs aren't clear what memory/threading model they are using.) + if (futex_errno != EINTR && futex_errno != EAGAIN) { + return false; + } + } } } void Signal() { - futex_.store(1, std::memory_order_release); + futex_.store(kSignaled, std::memory_order_release); syscall(SYS_futex, futex_int_ptr(), FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1, nullptr, nullptr, 0); } private: + // The possible values in the futex / atomic_int. + static constexpr int kNotSignaled = 0; + static constexpr int kSignaled = 1; + // Provides a pointer to the atomic's storage. std::atomic_int has standard // layout so its address can be used for the pointer as long as it only // contains the int. @@ -63,7 +83,7 @@ return reinterpret_cast<int*>(&futex_); } - std::atomic_int futex_{0}; + std::atomic_int futex_{static_cast<int>(kNotSignaled)}; }; // Scoped signal event that calls Signal on the AsyncSafeWaitableEvent at
diff --git a/base/test/metrics/user_action_tester.cc b/base/test/metrics/user_action_tester.cc index 5b5e9847..283c503 100644 --- a/base/test/metrics/user_action_tester.cc +++ b/base/test/metrics/user_action_tester.cc
@@ -22,12 +22,12 @@ base::RemoveActionCallback(action_callback_); } -int UserActionTester::GetActionCount(const std::string& user_action) const { +int UserActionTester::GetActionCount(base::StringPiece user_action) const { return times_map_.count(user_action); } std::vector<TimeTicks> UserActionTester::GetActionTimes( - const std::string& user_action) const { + base::StringPiece user_action) const { std::vector<TimeTicks> result; auto range = times_map_.equal_range(user_action); for (auto it = range.first; it != range.second; it++) {
diff --git a/base/test/metrics/user_action_tester.h b/base/test/metrics/user_action_tester.h index d8a9e2d..134ad50b 100644 --- a/base/test/metrics/user_action_tester.h +++ b/base/test/metrics/user_action_tester.h
@@ -11,6 +11,7 @@ #include "base/memory/scoped_refptr.h" #include "base/metrics/user_metrics.h" +#include "base/strings/string_piece.h" #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" @@ -31,17 +32,17 @@ ~UserActionTester(); // Returns the number of times the given |user_action| occurred. - int GetActionCount(const std::string& user_action) const; + int GetActionCount(base::StringPiece user_action) const; // Returns the time values at which the given |user_action| has occurred. // The order of returned values is unspecified. - std::vector<TimeTicks> GetActionTimes(const std::string& user_action) const; + std::vector<TimeTicks> GetActionTimes(base::StringPiece user_action) const; // Resets all user action counts to 0. void ResetCounts(); private: - typedef std::multimap<std::string, TimeTicks> UserActionTimesMap; + typedef std::multimap<std::string, TimeTicks, std::less<>> UserActionTimesMap; // The callback that is notified when a user actions occurs. void OnUserAction(const std::string& user_action, TimeTicks action_time);
diff --git a/build/PRESUBMIT.py b/build/PRESUBMIT.py index c6cc1ccd..a74917b 100644 --- a/build/PRESUBMIT.py +++ b/build/PRESUBMIT.py
@@ -52,6 +52,4 @@ input_api, output_api, input_api.PresubmitLocalPath(), - files_to_check=[r'.+_(?:unit)?test\.py$'], - run_on_python2=False, - run_on_python3=True)) + files_to_check=[r'.+_(?:unit)?test\.py$']))
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py index 08f6ec5..7bf9ee80 100644 --- a/build/android/PRESUBMIT.py +++ b/build/android/PRESUBMIT.py
@@ -81,7 +81,7 @@ # Disabled due to http://crbug.com/410936 #output.extend(input_api.canned_checks.RunUnitTestsInDirectory( - #input_api, output_api, J('buildbot', 'tests', skip_shebang_check=True))) + #input_api, output_api, J('buildbot', 'tests'))) pylib_test_env = dict(input_api.environ) pylib_test_env.update({ @@ -120,10 +120,7 @@ J('gyp', 'util', 'md5_check_test.py'), J('gyp', 'util', 'resource_utils_test.py'), ], - env=pylib_test_env, - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + env=pylib_test_env)) return input_api.RunTests(tests)
diff --git a/build/build_config.h b/build/build_config.h index d9f768b..24847036 100644 --- a/build/build_config.h +++ b/build/build_config.h
@@ -336,18 +336,13 @@ #define ARCH_CPU_BIG_ENDIAN 1 #endif #elif defined(__loongarch__) -// Phase out _LOONG with _LOONGARCH, since the latter is more intuitive. -// TODO(loongarch): Remove XXX_LOONG definition after it's all cleaned up. #define ARCH_CPU_LOONGARCH_FAMILY 1 -#define ARCH_CPU_LOONG_FAMILY 1 #define ARCH_CPU_LITTLE_ENDIAN 1 #if __loongarch_grlen == 64 #define ARCH_CPU_LOONGARCH64 1 -#define ARCH_CPU_LOONG64 1 #define ARCH_CPU_64_BITS 1 #else #define ARCH_CPU_LOONGARCH32 1 -#define ARCH_CPU_LOONG32 1 #define ARCH_CPU_32_BITS 1 #endif #elif defined(__riscv) && (__riscv_xlen == 64)
diff --git a/build/chromeos/PRESUBMIT.py b/build/chromeos/PRESUBMIT.py index 61ba20b..2455a05 100644 --- a/build/chromeos/PRESUBMIT.py +++ b/build/chromeos/PRESUBMIT.py
@@ -19,12 +19,7 @@ results += input_api.canned_checks.RunPylint( input_api, output_api, pylintrc='pylintrc', version='2.6') tests = input_api.canned_checks.GetUnitTestsInDirectory( - input_api, - output_api, - '.', [r'^.+_test\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + input_api, output_api, '.', [r'^.+_test\.py$']) results += input_api.RunTests(tests) return results
diff --git a/build/config/c++/c++.gni b/build/config/c++/c++.gni index 25ece4c..282c421e 100644 --- a/build/config/c++/c++.gni +++ b/build/config/c++/c++.gni
@@ -53,13 +53,6 @@ libcxx_is_shared = use_custom_libcxx && is_component_build } -# TODO(https://crbug.com/1385662): This is temporarily guarded to make it easier -# to roll out this change. Once the various projects (ANGLE, v8, et cetera) -# rolling in Chrome's //build have updated, remove this entirely. -if (!defined(enable_safe_libcxx)) { - enable_safe_libcxx = true -} - # libc++abi needs to be exported from executables to be picked up by shared # libraries on certain instrumented builds. export_libcxxabi_from_executables =
diff --git a/build/config/riscv.gni b/build/config/riscv.gni index b9597a0..5f93266 100644 --- a/build/config/riscv.gni +++ b/build/config/riscv.gni
@@ -4,7 +4,8 @@ import("//build/config/v8_target_cpu.gni") -if (current_cpu == "riscv64" || v8_current_cpu == "riscv64") { +if (current_cpu == "riscv64" || v8_current_cpu == "riscv64" || + current_cpu == "riscv32" || v8_current_cpu == "riscv32") { declare_args() { # RISCV Vector extension compilation flag. riscv_use_rvv = false
diff --git a/build/config/rust.gni b/build/config/rust.gni index aa8dba95..b4b2f25 100644 --- a/build/config/rust.gni +++ b/build/config/rust.gni
@@ -86,7 +86,7 @@ enable_rust_json = enable_all_rust_features # Support for chrome://crash-rust to check crash dump collection works. - enable_rust_crash = is_linux || is_android || enable_all_rust_features + enable_rust_crash = enable_all_rust_features # Support for Rust mojo bindings. enable_rust_mojo = enable_all_rust_features
diff --git a/build/config/siso/remote_exec_wrapper.star b/build/config/siso/remote_exec_wrapper.star index dcd5169..b93749e4 100644 --- a/build/config/siso/remote_exec_wrapper.star +++ b/build/config/siso/remote_exec_wrapper.star
@@ -42,6 +42,11 @@ "use_remote_exec_wrapper": True, }, { + "name": "clang/asm", + "action": "(.*_)?asm", + "use_remote_exec_wrapper": True, + }, + { "name": "action_remote", "command_prefix": "python3 ../../build/util/action_remote.py", "use_remote_exec_wrapper": True,
diff --git a/build/config/siso/rewrapper_to_reproxy.star b/build/config/siso/rewrapper_to_reproxy.star index 18d98d16..de19d8ec 100644 --- a/build/config/siso/rewrapper_to_reproxy.star +++ b/build/config/siso/rewrapper_to_reproxy.star
@@ -4,30 +4,52 @@ # found in the LICENSE file. """Siso configuration for rewriting remote exec wrapper calls into reproxy config.""" +load("@builtin//encoding.star", "json") load("@builtin//lib/gn.star", "gn") load("@builtin//struct.star", "module") load("./config.star", "config") __filegroups = {} -def __remove_rewrapper(ctx, cmd): +def __rewrite_rewrapper(ctx, cmd): # Slice from the first non-arg passed to rewrapper. # (Whilst rewrapper usage is `rewrapper [-flags] -- command ...` we don't pass -- to rewrapper.) non_flag_start = -1 + cfg_file = None for i, arg in enumerate(cmd.args): if i == 0: continue - if not arg.startswith('-'): + # NOTE: Only handle -cfg= as that's we call rewrapper in our .gn files. + if arg.startswith("-cfg="): + cfg_file = ctx.fs.canonpath(arg.removeprefix("-cfg=")) + continue + if not arg.startswith("-"): non_flag_start = i break if non_flag_start < 1: - fail("couldn't find first non-arg passed to rewrapper") + fail("couldn't find first non-arg passed to rewrapper for %s" % str(cmd.args)) + + if not cfg_file: + fail("cfg file expected but none found") + + # TODO(b/273407069): Read rewrapper args other than labels. + labels = dict() + if not ctx.fs.exists(cfg_file): + fail("cmd specifies rewrapper cfg %s but not found, is download_remoteexec_cfg set in gclient custom_vars?" % cfg_file) + for line in str(ctx.fs.read(cfg_file)).splitlines(): + if line.startswith("labels="): + for label in line.removeprefix("labels=").split(","): + label_parts = label.split("=") + if len(label_parts) != 2: + fail("invalid label %s" % label) + labels[label_parts[0]] = label_parts[1] ctx.actions.fix( args = cmd.args[non_flag_start:], + reproxy_config = json.encode({"labels": labels}) ) __handlers = { - "remove_rewrapper": __remove_rewrapper, + "rewrite_rewrapper": __rewrite_rewrapper, } def __enabled(ctx): @@ -38,44 +60,31 @@ return False def __step_config(ctx, step_config): - labels = dict() - - # TODO(b/273407069): Choose the right cfg rather than hardcoding buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_linux.cfg. - # TODO(b/273407069): Read cfg values other than labels. - if not ctx.fs.exists("buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_linux.cfg"): - fail("rewrapper_to_reproxy enabled but buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_linux.cfg not found, is download_remoteexec_cfg set in gclient custom_vars?") - for line in str(ctx.fs.read("buildtools/reclient_cfgs/chromium-browser-clang/rewrapper_linux.cfg")).splitlines(): - if line.startswith("labels="): - for label in line.removeprefix("labels=").split(","): - label_parts = label.split("=") - if len(label_parts) != 2: - fail("invalid label %s" % label) - labels[label_parts[0]] = label_parts[1] - step_config["rules"].extend([ { "name": "clang/cxx", "action": "(.*_)?cxx", - "handler": "remove_rewrapper", - "reproxy_config": {"labels": labels}, + "handler": "rewrite_rewrapper", }, { "name": "clang/cc", "action": "(.*_)?cc", - "handler": "remove_rewrapper", - "reproxy_config": {"labels": labels}, + "handler": "rewrite_rewrapper", }, { "name": "clang/objcxx", "action": "(.*_)?objcxx", - "handler": "remove_rewrapper", - "reproxy_config": {"labels": labels}, + "handler": "rewrite_rewrapper", }, { "name": "clang/objc", "action": "(.*_)?objc", - "handler": "remove_rewrapper", - "reproxy_config": {"labels": labels}, + "handler": "rewrite_rewrapper", + }, + { + "name": "clang/asm", + "action": "(.*_)?asm", + "handler": "rewrite_rewrapper", }, ]) return step_config
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn index c51ad03..83be929 100644 --- a/build/config/win/BUILD.gn +++ b/build/config/win/BUILD.gn
@@ -420,6 +420,7 @@ "/DELAYLOAD:setupapi.dll", "/DELAYLOAD:shell32.dll", "/DELAYLOAD:shlwapi.dll", + "/DELAYLOAD:uiautomationcore.dll", "/DELAYLOAD:urlmon.dll", "/DELAYLOAD:user32.dll", "/DELAYLOAD:usp10.dll",
diff --git a/build/fuchsia/PRESUBMIT.py b/build/fuchsia/PRESUBMIT.py index 1c0222a1..41949b9 100644 --- a/build/fuchsia/PRESUBMIT.py +++ b/build/fuchsia/PRESUBMIT.py
@@ -31,10 +31,7 @@ tests.extend( input_api.canned_checks.GetUnitTests(input_api, output_api, - unit_tests=unit_tests, - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + unit_tests=unit_tests)) return input_api.RunTests(tests)
diff --git a/build/fuchsia/test/common.py b/build/fuchsia/test/common.py index 0f8af33..65b5e80 100644 --- a/build/fuchsia/test/common.py +++ b/build/fuchsia/test/common.py
@@ -28,10 +28,6 @@ SDK_TOOLS_DIR = os.path.join(SDK_ROOT, 'tools', get_host_arch()) _FFX_TOOL = os.path.join(SDK_TOOLS_DIR, 'ffx') -# This global variable is used to set the environment variable -# |FFX_ISOLATE_DIR| when running ffx commands in E2E testing scripts. -_FFX_ISOLATE_DIR = None - class TargetState(enum.Enum): """State of a target.""" @@ -128,10 +124,10 @@ def set_ffx_isolate_dir(isolate_dir: str) -> None: - """Overwrites |_FFX_ISOLATE_DIR|.""" + """Overwrites the global environment so the following ffx calls will have + the isolate dir being carried.""" - global _FFX_ISOLATE_DIR # pylint: disable=global-statement - _FFX_ISOLATE_DIR = isolate_dir + os.environ['FFX_ISOLATE_DIR'] = isolate_dir def get_host_tool_path(tool): @@ -352,11 +348,8 @@ for config in configs: ffx_cmd.extend(('--config', config)) ffx_cmd.extend(cmd) - env = os.environ - if _FFX_ISOLATE_DIR: - env['FFX_ISOLATE_DIR'] = _FFX_ISOLATE_DIR - return subprocess.Popen(ffx_cmd, encoding=encoding, env=env, **kwargs) + return subprocess.Popen(ffx_cmd, encoding=encoding, **kwargs) def read_package_paths(out_dir: str, pkg_name: str) -> List[str]:
diff --git a/build/ios/PRESUBMIT.py b/build/ios/PRESUBMIT.py index f737a7e..a83d1a43 100644 --- a/build/ios/PRESUBMIT.py +++ b/build/ios/PRESUBMIT.py
@@ -11,9 +11,4 @@ def CheckUnitTests(input_api, output_api): # Runs all unit tests under the build/ios folder. return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=TEST_PATTERNS, - run_on_python2=False, - skip_shebang_check=True) + input_api, output_api, '.', files_to_check=TEST_PATTERNS)
diff --git a/build/lacros/PRESUBMIT.py b/build/lacros/PRESUBMIT.py index 13d3423..f8b13b8 100644 --- a/build/lacros/PRESUBMIT.py +++ b/build/lacros/PRESUBMIT.py
@@ -10,12 +10,7 @@ if input_api.is_windows: return [] tests = input_api.canned_checks.GetUnitTestsInDirectory( - input_api, - output_api, - '.', [r'^.+_test\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + input_api, output_api, '.', [r'^.+_test\.py$']) return input_api.RunTests(tests)
diff --git a/build/skia_gold_common/PRESUBMIT.py b/build/skia_gold_common/PRESUBMIT.py index 14ea488..2a57eae0 100644 --- a/build/skia_gold_common/PRESUBMIT.py +++ b/build/skia_gold_common/PRESUBMIT.py
@@ -28,9 +28,7 @@ input_api, output_api, input_api.PresubmitLocalPath(), [r'^.+_unittest\.py$'], - env=_GetSkiaGoldEnv(input_api), - run_on_python2=False, - skip_shebang_check=True) + env=_GetSkiaGoldEnv(input_api)) def CheckPylint(input_api, output_api):
diff --git a/build/util/PRESUBMIT.py b/build/util/PRESUBMIT.py index bac696bb..22376c3 100644 --- a/build/util/PRESUBMIT.py +++ b/build/util/PRESUBMIT.py
@@ -39,10 +39,7 @@ output_api, input_api.PresubmitLocalPath(), files_to_check=['.*_test\\.py$'], - files_to_skip=files_to_skip, - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + files_to_skip=files_to_skip) def CommonChecks(input_api, output_api):
diff --git a/build/util/lib/common/PRESUBMIT.py b/build/util/lib/common/PRESUBMIT.py index 5c92f3ce..28d0cf38 100644 --- a/build/util/lib/common/PRESUBMIT.py +++ b/build/util/lib/common/PRESUBMIT.py
@@ -7,12 +7,7 @@ def _RunTests(input_api, output_api): return (input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=[r'.+_test.py$'], - run_on_python2=False, - skip_shebang_check=True)) + input_api, output_api, '.', files_to_check=[r'.+_test.py$'])) def CheckChangeOnUpload(input_api, output_api):
diff --git a/buildtools/checkdeps/PRESUBMIT.py b/buildtools/checkdeps/PRESUBMIT.py index 9e011a1..c8255a5 100644 --- a/buildtools/checkdeps/PRESUBMIT.py +++ b/buildtools/checkdeps/PRESUBMIT.py
@@ -5,16 +5,11 @@ """Presubmit script for checkdeps tool. """ -USE_PYTHON3 = True - - def CheckChange(input_api, output_api): return input_api.canned_checks.RunUnitTests( input_api, output_api, [input_api.os_path.join(input_api.PresubmitLocalPath(), - 'checkdeps_test.py')], - # `run_on_python3` defaults to `True`. - run_on_python2=not USE_PYTHON3) + 'checkdeps_test.py')]) # Mandatory entrypoint.
diff --git a/cc/PRESUBMIT.py b/cc/PRESUBMIT.py index 0a87842..d064d9c78 100644 --- a/cc/PRESUBMIT.py +++ b/cc/PRESUBMIT.py
@@ -12,7 +12,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True CC_SOURCE_FILES=(r'^cc[\\/].*\.(cc|h)$',) def _CheckChangeLintsClean(input_api, output_api):
diff --git a/cc/raster/bitmap_raster_buffer_provider.cc b/cc/raster/bitmap_raster_buffer_provider.cc index cc53c03..5f1c57d5 100644 --- a/cc/raster/bitmap_raster_buffer_provider.cc +++ b/cc/raster/bitmap_raster_buffer_provider.cc
@@ -8,25 +8,59 @@ #include <stdint.h> #include <algorithm> +#include <limits> #include <utility> +#include "base/logging.h" #include "base/memory/raw_ptr.h" +#include "base/memory/read_only_shared_memory_region.h" #include "base/memory/shared_memory_mapping.h" +#include "base/process/memory.h" #include "base/trace_event/process_memory_dump.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/traced_value.h" -#include "cc/raster/raster_source.h" #include "cc/trees/layer_tree_frame_sink.h" #include "components/viz/common/resources/bitmap_allocation.h" -#include "components/viz/common/resources/platform_color.h" +#include "components/viz/common/resources/shared_image_format.h" +#include "gpu/command_buffer/common/shared_image_usage.h" +#include "ui/gfx/buffer_format_util.h" +#include "ui/gfx/color_space.h" +#include "ui/gfx/geometry/size.h" namespace cc { namespace { +base::UnsafeSharedMemoryRegion AllocateSharedMemory( + const gfx::Size& size, + viz::SharedImageFormat format) { + DCHECK(format.IsBitmapFormatSupported()) + << "(format = " << format.ToString() << ")"; + + size_t bytes = 0; + if (!viz::ResourceSizes::MaybeSizeInBytes(size, format.resource_format(), + &bytes)) { + DLOG(ERROR) << "AllocateMappedBitmap with size that overflows"; + size_t alloc_size = std::numeric_limits<int>::max(); + base::TerminateBecauseOutOfMemory(alloc_size); + } + + auto shared_memory = base::UnsafeSharedMemoryRegion::Create(bytes); + if (!shared_memory.IsValid()) { + DLOG(ERROR) << "Browser failed to allocate shared memory"; + base::TerminateBecauseOutOfMemory(bytes); + } + return shared_memory; +} + class BitmapSoftwareBacking : public ResourcePool::SoftwareBacking { public: ~BitmapSoftwareBacking() override { - frame_sink->DidDeleteSharedBitmap(shared_bitmap_id); + if (frame_sink->shared_image_interface()) { + frame_sink->shared_image_interface()->DestroySharedImage( + gpu::SyncToken(), shared_bitmap_id); + } else { + frame_sink->DidDeleteSharedBitmap(shared_bitmap_id); + } } void OnMemoryDump( @@ -40,6 +74,8 @@ raw_ptr<LayerTreeFrameSink> frame_sink; base::WritableSharedMemoryMapping mapping; + + base::UnsafeSharedMemoryRegion unsafe_region; }; class BitmapRasterBufferImpl : public RasterBuffer { @@ -117,13 +153,36 @@ if (!resource.software_backing()) { auto backing = std::make_unique<BitmapSoftwareBacking>(); backing->frame_sink = frame_sink_; - backing->shared_bitmap_id = viz::SharedBitmap::GenerateId(); - base::MappedReadOnlyRegion shm = - viz::bitmap_allocation::AllocateSharedBitmap( - size, viz::SinglePlaneFormat::kRGBA_8888); - backing->mapping = std::move(shm.mapping); - frame_sink_->DidAllocateSharedBitmap(std::move(shm.region), - backing->shared_bitmap_id); + + if (frame_sink_->shared_image_interface()) { + constexpr char kDebugLabel[] = "BitmapRasterBufferProvider"; + backing->unsafe_region = + AllocateSharedMemory(size, viz::SinglePlaneFormat::kRGBA_8888); + backing->mapping = backing->unsafe_region.Map(); + + gfx::GpuMemoryBufferHandle handle; + handle.type = gfx::SHARED_MEMORY_BUFFER; + handle.offset = 0; + handle.stride = static_cast<int32_t>(gfx::RowSizeForBufferFormat( + size.width(), gfx::BufferFormat::RGBA_8888, 0)); + handle.region = backing->unsafe_region.Duplicate(); + + backing->shared_bitmap_id = + frame_sink_->shared_image_interface()->CreateSharedImage( + viz::SinglePlaneFormat::kRGBA_8888, size, color_space, + kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, + gpu::SHARED_IMAGE_USAGE_CPU_WRITE, kDebugLabel, + std::move(handle)); + + } else { + backing->shared_bitmap_id = viz::SharedBitmap::GenerateId(); + base::MappedReadOnlyRegion shm = + viz::bitmap_allocation::AllocateSharedBitmap( + size, viz::SinglePlaneFormat::kRGBA_8888); + backing->mapping = std::move(shm.mapping); + frame_sink_->DidAllocateSharedBitmap(std::move(shm.region), + backing->shared_bitmap_id); + } resource.set_software_backing(std::move(backing)); }
diff --git a/chrome/VERSION b/chrome/VERSION index 3fff85c..b819ad15 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=116 MINOR=0 -BUILD=5807 +BUILD=5808 PATCH=0
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index f4958ca6..6fb60a9 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn
@@ -247,6 +247,7 @@ deps = [ ":app_hooks_java", "//chrome/browser/accessibility/hierarchysnapshotter/android:delegate_public_impl_java", + "//chrome/browser/auxiliary_search:delegate_public_impl_java", "//chrome/browser/feed/android:hooks_public_impl_java", "//chrome/browser/feedback/android:delegate_public_impl_java", "//chrome/browser/lens:delegate_public_impl_java", @@ -305,6 +306,7 @@ "//chrome/browser/android/lifecycle:java", "//chrome/browser/android/messages:java", "//chrome/browser/autofill/android:java", + "//chrome/browser/auxiliary_search:java", "//chrome/browser/back_press/android:java", "//chrome/browser/banners/android:java", "//chrome/browser/battery/android:java", @@ -940,6 +942,7 @@ "//chrome/browser/omaha/android:java", "//chrome/browser/optimization_guide/android:java", "//chrome/browser/partnercustomizations:java", + "//chrome/browser/partnercustomizations:junit", "//chrome/browser/password_edit_dialog/android:junit", "//chrome/browser/password_entry_edit/android/internal:junit", "//chrome/browser/password_manager/android:java", @@ -2985,6 +2988,7 @@ args = [ "--product", "chrome_android", + "--zero-tests-executed-ok", "--browser-apk", "@WrappedPath(apks/ChromePublic.apk)", "-v",
diff --git a/chrome/android/chrome_java_resources.gni b/chrome/android/chrome_java_resources.gni index e9297e4..fe922e4 100644 --- a/chrome/android/chrome_java_resources.gni +++ b/chrome/android/chrome_java_resources.gni
@@ -431,7 +431,6 @@ "java/res/drawable/long_screenshot.xml", "java/res/drawable/material_tooltip_background.xml", "java/res/drawable/outline_chevron_right_24dp.xml", - "java/res/drawable/pill_background.xml", "java/res/drawable/price_tracking_disabled.xml", "java/res/drawable/price_tracking_enabled_filled.xml", "java/res/drawable/price_tracking_enabled_outline.xml", @@ -529,7 +528,6 @@ "java/res/layout/find_in_page.xml", "java/res/layout/find_toolbar.xml", "java/res/layout/fre_tos_privacy_disclaimer.xml", - "java/res/layout/fullscreen_notification.xml", "java/res/layout/history_clear_browsing_data_header.xml", "java/res/layout/history_item_view.xml", "java/res/layout/history_main.xml",
diff --git a/chrome/android/chrome_java_sources.gni b/chrome/android/chrome_java_sources.gni index b1a39f8..1881f3af 100644 --- a/chrome/android/chrome_java_sources.gni +++ b/chrome/android/chrome_java_sources.gni
@@ -10,7 +10,6 @@ "java/src/org/chromium/chrome/browser/AppHooksModule.java", "java/src/org/chromium/chrome/browser/AppIndexingUtil.java", "java/src/org/chromium/chrome/browser/ApplicationLifetime.java", - "java/src/org/chromium/chrome/browser/BackPressHelper.java", "java/src/org/chromium/chrome/browser/BackupSigninProcessor.java", "java/src/org/chromium/chrome/browser/BrowserRestartActivity.java", "java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java", @@ -200,10 +199,10 @@ "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUiState.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUndoController.java", "java/src/org/chromium/chrome/browser/bookmarks/BookmarkUtils.java", - "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectView.java", - "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewBinder.java", - "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinator.java", - "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewProperties.java", + "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRow.java", + "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinator.java", + "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowProperties.java", + "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowViewBinder.java", "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderView.java", "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandler.java", "java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRow.java",
diff --git a/chrome/android/chrome_junit_test_java_sources.gni b/chrome/android/chrome_junit_test_java_sources.gni index 277a5d1..714271a 100644 --- a/chrome/android/chrome_junit_test_java_sources.gni +++ b/chrome/android/chrome_junit_test_java_sources.gni
@@ -7,7 +7,6 @@ "java/src/org/chromium/chrome/browser/segmentation_platform/SignalAccumulatorTest.java", "java/src/org/chromium/chrome/browser/tab/TabFaviconTest.java", "junit/src/org/chromium/chrome/browser/AppIndexingUtilTest.java", - "junit/src/org/chromium/chrome/browser/BackPressHelperUnitTest.java", "junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java", "junit/src/org/chromium/chrome/browser/ChromeActivityUnitTest.java", "junit/src/org/chromium/chrome/browser/ChromeBackgroundServiceTest.java", @@ -56,7 +55,7 @@ "junit/src/org/chromium/chrome/browser/bookmarks/BookmarkTextInputLayoutTest.java", "junit/src/org/chromium/chrome/browser/bookmarks/BookmarkToolbarMediatorTest.java", "junit/src/org/chromium/chrome/browser/bookmarks/BookmarkUiPrefsTest.java", - "junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinatorTest.java", + "junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinatorTest.java", "junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkQueryHandlerTest.java", "junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowTest.java", "junit/src/org/chromium/chrome/browser/bookmarks/LegacyBookmarkQueryHandlerTest.java", @@ -337,5 +336,7 @@ "junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredential.java", "junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredentialManager.java", "junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredentialOption.java", + "junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPasswordCredential.java", + "junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPublicKeyCredential.java", "junit/src/org/chromium/chrome/browser/webauth/Fido2CredentialRequestRobolectricTest.java", ]
diff --git a/chrome/android/chrome_test_java_sources.gni b/chrome/android/chrome_test_java_sources.gni index edb8f4c..b302f68 100644 --- a/chrome/android/chrome_test_java_sources.gni +++ b/chrome/android/chrome_test_java_sources.gni
@@ -85,7 +85,7 @@ "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSaveFlowTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchBoxRowRenderTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/BookmarkSearchBoxRowTest.java", - "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewRenderTest.java", + "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowRenderTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderViewRenderTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkRowRenderTest.java", "javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkSaveFlowRenderTest.java",
diff --git a/chrome/android/expectations/lint-baseline.xml b/chrome/android/expectations/lint-baseline.xml index 651074c..4df8f95d 100644 --- a/chrome/android/expectations/lint-baseline.xml +++ b/chrome/android/expectations/lint-baseline.xml
@@ -91,28 +91,6 @@ <issue id="NewApi" - message="Call requires API level 26 (current min is 24): `shouldQueryAutofillSuggestion`" - errorLine1=" if (mAutofillMenuItemTitle != 0 && mAutofillProvider.shouldQueryAutofillSuggestion()) {" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java" - line="43" - column="62"/> - </issue> - - <issue - id="NewApi" - message="Call requires API level 26 (current min is 24): `queryAutofillSuggestion`" - errorLine1=" mAutofillProvider.queryAutofillSuggestion();" - errorLine2=" ~~~~~~~~~~~~~~~~~~~~~~~"> - <location - file="../../components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java" - line="55" - column="31"/> - </issue> - - <issue - id="NewApi" message="Call requires API level 26 (current min is 24): `deleteLegacyChannels`" errorLine1=" mChannelsInitializer.deleteLegacyChannels();" errorLine2=" ~~~~~~~~~~~~~~~~~~~~">
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java index 7c9ce6c..ecd4e34 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogCoordinator.java
@@ -13,7 +13,6 @@ import androidx.annotation.Nullable; import org.chromium.base.TraceEvent; -import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.chrome.browser.compositor.layouts.content.TabContentManager; @@ -206,9 +205,8 @@ @Override public @BackPressResult int handleBackPress() { - mMediator.hideDialog(true); - RecordUserAction.record("TabGridDialog.Exit"); - return isVisible() ? BackPressResult.FAILURE : BackPressResult.SUCCESS; + final boolean handled = mMediator.handleBackPress(); + return handled ? BackPressResult.SUCCESS : BackPressResult.FAILURE; } @Override
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java index ebbb5fd..2ac3fb8 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogMediator.java
@@ -342,6 +342,21 @@ } } + /** + * @return a boolean indicating if the result of handling the backpress was successful. + */ + public boolean handleBackPress() { + if (mTabSelectionEditorControllerSupplier != null + && mTabSelectionEditorControllerSupplier.hasValue() + && mTabSelectionEditorControllerSupplier.get().isVisible()) { + mTabSelectionEditorControllerSupplier.get().hide(); + return !mTabSelectionEditorControllerSupplier.get().isVisible(); + } + hideDialog(true); + RecordUserAction.record("TabGridDialog.Exit"); + return !isVisible(); + } + // @TabGridDialogView.VisibilityListener @Override public void finishedHidingDialogView() {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java index b1d25432..520d716 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediator.java
@@ -565,7 +565,9 @@ // undo, identify the related TabIds and determine newIndex based on if any of // the related ids are present in model. newIndex = getIndexForTabWithRelatedTabs(tab); - model.updateTabListModelIdForGroup(tab, newIndex); + if (newIndex != Tab.INVALID_TAB_ID) { + model.updateTabListModelIdForGroup(tab, newIndex); + } } mLastSelectedTabListModelIndex = oldIndex;
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java index cd5e3f3..28f8f436 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabGridDialogTest.java
@@ -426,23 +426,27 @@ // Open dialog and open selection editor. openDialogFromTabSwitcherAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); // Click navigation button should close selection editor but not tab grid dialog. mSelectionEditorRobot.actionRobot.clickToolbarNavigationButton(); mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden(); assertTrue(isDialogShowing(cta)); - // Back press should close both the dialog and selection editor. - openSelectionEditorV2AndVerify(cta, 2); + // Back press should close both theselectioneditor. + openSelectionEditorAndVerify(cta, 2); Espresso.pressBack(); mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden(); + assertTrue(isDialogShowing(cta)); + + // Back press again to exit. + Espresso.pressBack(); waitForDialogHidingAnimationInTabSwitcher(cta); verifyTabSwitcherCardCount(cta, 1); // Clicking ScrimView should close both the dialog and selection editor. openDialogFromTabSwitcherAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); clickScrimToExitDialog(cta); mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden(); waitForDialogHidingAnimationInTabSwitcher(cta); @@ -452,7 +456,7 @@ @Test @MediumTest // clang-format off - public void testDialogToolbarSelectionEditorV2() throws ExecutionException { + public void testDialogToolbarSelectionEditor() throws ExecutionException { // clang-format on final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2); @@ -470,23 +474,21 @@ .inRoot(withDecorView(not(cta.getWindow().getDecorView()))) .check(doesNotExist()); Espresso.pressBack(); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); // Click navigation button should close selection editor but not tab grid dialog. mSelectionEditorRobot.actionRobot.clickToolbarNavigationButton(); mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden(); assertTrue(isDialogShowing(cta)); - // Back press should close both the dialog and selection editor. - openSelectionEditorV2AndVerify(cta, 2); + // Back press should close only the selection editor. + openSelectionEditorAndVerify(cta, 2); Espresso.pressBack(); mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden(); - waitForDialogHidingAnimationInTabSwitcher(cta); - verifyTabSwitcherCardCount(cta, 1); + assertTrue(isDialogShowing(cta)); // Clicking ScrimView should close both the dialog and selection editor. - openDialogFromTabSwitcherAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); clickScrimToExitDialog(cta); mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsHidden(); waitForDialogHidingAnimationInTabSwitcher(cta); @@ -495,7 +497,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_LongPressTabAndVerifyNoSelectionOccurs() + public void testDialogSelectionEditor_LongPressTabAndVerifyNoSelectionOccurs() throws ExecutionException { TabUiFeatureUtilities.setTabSelectionEditorLongPressEntryEnabledForTesting(true); final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); @@ -522,7 +524,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_PostLongPressClickNoSelectionEditor() + public void testDialogSelectionEditor_PostLongPressClickNoSelectionEditor() throws ExecutionException { TabUiFeatureUtilities.setTabSelectionEditorLongPressEntryEnabledForTesting(true); final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); @@ -542,7 +544,7 @@ mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsVisible(); Espresso.pressBack(); - openDialogFromTabSwitcherAndVerify(cta, 2, null); + assertTrue(isDialogShowing(cta)); clickFirstTabInDialog(cta); waitForDialogHidingAnimation(cta); @@ -559,7 +561,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_BookmarkSingleTabView() throws ExecutionException { + public void testDialogSelectionEditor_BookmarkSingleTabView() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); SnackbarManager snackbarManager = cta.getSnackbarManager(); createTabs(cta, false, 2); @@ -573,7 +575,7 @@ // Open the selection editor. openDialogFromTabSwitcherAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); // Bookmark one tab and verify edit snackbar. mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) @@ -596,7 +598,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_BookmarkTabsView() throws ExecutionException { + public void testDialogSelectionEditor_BookmarkTabsView() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); SnackbarManager snackbarManager = cta.getSnackbarManager(); createTabs(cta, false, 2); @@ -610,7 +612,7 @@ // Open the selection editor. openDialogFromTabSwitcherAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); // Bookmark two tabs and verify edit snackbar. mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) @@ -634,7 +636,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_ShareActionView() throws ExecutionException { + public void testDialogSelectionEditor_ShareActionView() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2); @@ -651,7 +653,7 @@ // Open dialog and verify dialog is showing correct content. openDialogFromTabSwitcherAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); // Share tabs mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(1) @@ -672,7 +674,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_ShareActionTabs() throws ExecutionException { + public void testDialogSelectionEditor_ShareActionTabs() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); final String httpsCanonicalUrl = @@ -701,7 +703,7 @@ // Open dialog and verify dialog is showing correct content. openDialogFromTabSwitcherAndVerify(cta, 3, null); - openSelectionEditorV2AndVerify(cta, 3); + openSelectionEditorAndVerify(cta, 3); TabSelectionEditorShareAction.setIntentCallbackForTesting((result -> { assertEquals(Intent.ACTION_SEND, result.getAction()); @@ -719,8 +721,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_ShareActionAllFilterableTabs() - throws ExecutionException { + public void testDialogSelectionEditor_ShareActionAllFilterableTabs() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 2); @@ -733,7 +734,7 @@ // Open dialog and verify dialog is showing correct content. openDialogFromTabSwitcherAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) .clickItemAtAdapterPosition(1) @@ -745,7 +746,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_UndoClose() throws ExecutionException { + public void testDialogSelectionEditor_UndoClose() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 4); enterTabSwitcher(cta); @@ -757,7 +758,7 @@ // Open the selection editor. openDialogFromTabSwitcherAndVerify(cta, 4, null); - openSelectionEditorV2AndVerify(cta, 4); + openSelectionEditorAndVerify(cta, 4); // Close two tabs and undo. mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) @@ -776,7 +777,7 @@ @Test @MediumTest - public void testDialogSelectionEditorV2_UndoCloseAll() throws ExecutionException { + public void testDialogSelectionEditor_UndoCloseAll() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 4); enterTabSwitcher(cta); @@ -788,7 +789,7 @@ // Open the selection editor. openDialogFromTabSwitcherAndVerify(cta, 4, null); - openSelectionEditorV2AndVerify(cta, 4); + openSelectionEditorAndVerify(cta, 4); // Close two tabs and undo. mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) @@ -857,7 +858,7 @@ checkPosition(cta, true, true); // Verify the size and position of TabSelectionEditor in portrait mode. - openSelectionEditorV2AndVerify(cta, 3); + openSelectionEditorAndVerify(cta, 3); checkPosition(cta, false, true); // Verify the size and position of TabSelectionEditor in landscape mode. @@ -883,7 +884,7 @@ rootView.setLayoutParams(params); }); checkPosition(cta, true, true); - openSelectionEditorV2AndVerify(cta, 3); + openSelectionEditorAndVerify(cta, 3); checkPosition(cta, false, true); TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -1023,7 +1024,7 @@ @Test @MediumTest @Features.EnableFeatures({ChromeFeatureList.TAB_GROUPS_CONTINUATION_ANDROID}) - public void testTabGroupNaming_afterMergeWithSelectionEditorV2() throws ExecutionException { + public void testTabGroupNaming_afterMergeWithSelectionEditor() throws ExecutionException { final ChromeTabbedActivity cta = mActivityTestRule.getActivity(); createTabs(cta, false, 4); enterTabSwitcher(cta); @@ -1044,7 +1045,7 @@ waitForDialogHidingAnimation(cta); verifyFirstCardTitle(CUSTOMIZED_TITLE1); openDialogFromTabSwitcherAndVerify(cta, 4, CUSTOMIZED_TITLE1); - openSelectionEditorV2AndVerify(cta, 4); + openSelectionEditorAndVerify(cta, 4); // Ungroup tab. mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(1) @@ -1059,7 +1060,7 @@ verifyFirstCardTitle(CUSTOMIZED_TITLE1); verifyTabSwitcherCardCount(cta, 3); - enterTabSelectionEditorV2(cta); + enterTabSelectionEditor(cta); mSelectionEditorRobot.resultRobot.verifyTabSelectionEditorIsVisible(); mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) .clickItemAtAdapterPosition(1) @@ -1305,7 +1306,7 @@ @Test @MediumTest @DisableIf.Device(type = UiDisableIf.TABLET) - public void testStripDialog_TabSelectionEditorV2CloseAll_NoCustomHomepage() throws Exception { + public void testStripDialog_TabSelectionEditorCloseAll_NoCustomHomepage() throws Exception { ChromeTabbedActivity cta = mActivityTestRule.getActivity(); // Create a tab group with 2 tabs. createTabs(cta, false, 2); @@ -1329,7 +1330,7 @@ // Test opening dialog from strip and from tab switcher. openDialogFromStripAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); // Close two tabs. mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) @@ -1344,7 +1345,7 @@ @Test @MediumTest @DisableIf.Device(type = UiDisableIf.TABLET) - public void testStripDialog_TabSelectionEditorV2CloseAll_CustomHomepage() throws Exception { + public void testStripDialog_TabSelectionEditorCloseAll_CustomHomepage() throws Exception { GURL url = new GURL(mActivityTestRule.getEmbeddedTestServerRule().getServer().getURL( "/chrome/test/data/android/google.html")); when(mHomepagePolicyManager.isHomepageLocationPolicyEnabled()).thenReturn(true); @@ -1374,7 +1375,7 @@ // Test opening dialog from strip and from tab switcher. openDialogFromStripAndVerify(cta, 2, null); - openSelectionEditorV2AndVerify(cta, 2); + openSelectionEditorAndVerify(cta, 2); // Close two tabs. mSelectionEditorRobot.actionRobot.clickItemAtAdapterPosition(0) @@ -1693,7 +1694,7 @@ }); } - private void openSelectionEditorV2AndVerify(ChromeTabbedActivity cta, int count) { + private void openSelectionEditorAndVerify(ChromeTabbedActivity cta, int count) { // Open tab selection editor by selecting the select tabs item in tab grid dialog menu. onView(withId(R.id.toolbar_menu_button)).perform(click()); onView(withText(cta.getString(R.string.menu_select_tabs))) @@ -1883,7 +1884,7 @@ }); } - private void enterTabSelectionEditorV2(ChromeTabbedActivity cta) { + private void enterTabSelectionEditor(ChromeTabbedActivity cta) { MenuUtils.invokeCustomMenuActionSync( InstrumentationRegistry.getInstrumentation(), cta, R.id.menu_select_tabs); }
diff --git a/chrome/android/java/res/drawable/pill_background.xml b/chrome/android/java/res/drawable/pill_background.xml deleted file mode 100644 index a74f85c..0000000 --- a/chrome/android/java/res/drawable/pill_background.xml +++ /dev/null
@@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -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. ---> - -<shape xmlns:android="http://schemas.android.com/apk/res/android" - android:dither="true" - android:shape="rectangle"> - <corners android:radius="40dp" /> - <solid android:color="@color/default_bg_color_dark"/> - <size - android:width="60dp" - android:height="20dp" /> -</shape>
diff --git a/chrome/android/java/res/layout/fullscreen_notification.xml b/chrome/android/java/res/layout/fullscreen_notification.xml deleted file mode 100644 index 1ead803..0000000 --- a/chrome/android/java/res/layout/fullscreen_notification.xml +++ /dev/null
@@ -1,29 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- -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. ---> - -<FrameLayout - xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/fullscreen_notification" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:gravity="center" - android:paddingBottom="24dp"> - <TextView - android:id="@+id/text" - android:layout_height="wrap_content" - android:layout_width="wrap_content" - android:maxWidth="@dimen/fullscreen_notification_max_width" - android:layout_gravity="bottom|center_horizontal" - android:background="@drawable/pill_background" - android:textAppearance="@style/TextAppearance.Toast" - android:paddingStart="20dp" - android:paddingEnd="20dp" - android:paddingTop="8dp" - android:paddingBottom="8dp" - android:textAlignment="center" - android:text="@string/immersive_fullscreen_api_notification"/> -</FrameLayout>
diff --git a/chrome/android/java/res/layout/improved_bookmark_folder_select_layout.xml b/chrome/android/java/res/layout/improved_bookmark_folder_select_layout.xml index a89d3e03..15b5e60d 100644 --- a/chrome/android/java/res/layout/improved_bookmark_folder_select_layout.xml +++ b/chrome/android/java/res/layout/improved_bookmark_folder_select_layout.xml
@@ -5,7 +5,7 @@ found in the LICENSE file. --> -<org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectView +<org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectRow xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" @@ -62,4 +62,4 @@ android:importantForAccessibility="no" android:focusable="false" /> </androidx.constraintlayout.widget.ConstraintLayout> -</org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectView> +</org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectRow>
diff --git a/chrome/android/java/res/values/dimens.xml b/chrome/android/java/res/values/dimens.xml index 622b94b8..86627e6 100644 --- a/chrome/android/java/res/values/dimens.xml +++ b/chrome/android/java/res/values/dimens.xml
@@ -129,13 +129,9 @@ <!-- ModalDialogView dimensions --> <dimen name="tab_modal_scrim_vertical_margin">16dp</dimen> - <!-- Full Screen Dimensions --> - <dimen name="fullscreen_toast_elevation">@dimen/custom_tabs_elevation</dimen> - <!-- Should match toolbar_height_no_shadow --> <dimen name="control_container_height">56dp</dimen> <dimen name="custom_tabs_control_container_height">56dp</dimen> - <dimen name="fullscreen_notification_max_width">320dp</dimen> <!-- The combined height of the tab strip and toolbar. --> <dimen name="tab_strip_and_toolbar_height">56dp</dimen>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java index e0fad91..5f5ebbe7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActionModeHandler.java
@@ -144,7 +144,7 @@ Set<String> launchers = getPackageNames(PackageManagerUtils.queryAllLaunchersInfo()); for (int i = 0; i < menu.size(); i++) { MenuItem item = menu.getItem(i); - if (item.getGroupId() != R.id.select_action_menu_text_processing_menus + if (item.getGroupId() != R.id.select_action_menu_text_processing_items || item.getIntent() == null || item.getIntent().getComponent() == null) { continue; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 41c876f..6096e8f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -448,6 +448,7 @@ () -> findViewById(android.R.id.content), this::getIntent, this::shouldIgnoreIntent, this::isTablet, this::shouldShowOverviewPageOnStart, this::isInstantStartEnabled, + mTabModelProfileSupplier, new IncognitoRestoreAppLaunchDrawBlockerFactory(this::getSavedInstanceState, getTabModelSelectorSupplier())); // clang-format on
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java index befc98c..154b205 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/ChromeActivity.java
@@ -775,7 +775,9 @@ protected void onInitialLayoutInflationComplete() { mInflateInitialLayoutEndMs = SystemClock.elapsedRealtime(); - mRootUiCoordinator.getStatusBarColorController().updateStatusBarColor(); + if (mRootUiCoordinator.getStatusBarColorController() != null) { + mRootUiCoordinator.getStatusBarColorController().updateStatusBarColor(); + } ViewGroup rootView = (ViewGroup) getWindow().getDecorView().getRootView(); mCompositorViewHolderSupplier.set( @@ -819,7 +821,9 @@ mTabModelSelectorSupplier.set(tabModelSelector); mActivityTabProvider.setTabModelSelector(tabModelSelector); - mRootUiCoordinator.getStatusBarColorController().setTabModelSelector(tabModelSelector); + if (mRootUiCoordinator.getStatusBarColorController() != null) { + mRootUiCoordinator.getStatusBarColorController().setTabModelSelector(tabModelSelector); + } Pair<? extends TabCreator, ? extends TabCreator> tabCreators = createTabCreators(); mTabCreatorManagerSupplier.set( @@ -1021,8 +1025,13 @@ Tab tab = getActivityTab(); TabModelSelector tabModelSelector = mTabModelOrchestrator.getTabModelSelector(); - if (tabModelSelector != null && !tabModelSelector.isReparentingInProgress() - && tab != null) { + // If tab reparenting is in progress and the activity Tab isn't being reparented, e.g. + // because it's an NTP, skip hiding the Tab since it will be destroyed when the Activity is + // destroyed prior to recreation. + if (tab != null + && ((tabModelSelector != null && !tabModelSelector.isReparentingInProgress()) + || AsyncTabParamsManagerSingleton.getInstance().hasParamsForTabId( + tab.getId()))) { tab.hide(TabHidingType.ACTIVITY_HIDDEN); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java index 3d08f34..f1c6459 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkActivity.java
@@ -9,10 +9,11 @@ import android.text.TextUtils; import org.chromium.base.IntentUtils; -import org.chromium.chrome.browser.BackPressHelper; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.SnackbarActivity; +import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.back_press.BackPressManager; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.bookmarks.BookmarkManagerCoordinator; import org.chromium.chrome.browser.bookmarks.BookmarkPage; import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs; @@ -47,10 +48,11 @@ mBookmarkManagerCoordinator.updateForUrl(url); setContentView(mBookmarkManagerCoordinator.getView()); if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create(this, getOnBackPressedDispatcher(), mBookmarkManagerCoordinator); + BackPressHelper.create(this, getOnBackPressedDispatcher(), mBookmarkManagerCoordinator, + SecondaryActivity.BOOKMARK); } else { - BackPressHelper.create( - this, getOnBackPressedDispatcher(), mBookmarkManagerCoordinator::onBackPressed); + BackPressHelper.create(this, getOnBackPressedDispatcher(), + mBookmarkManagerCoordinator::onBackPressed, SecondaryActivity.BOOKMARK); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkEditActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkEditActivity.java index 8160865..19ff7baf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkEditActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/bookmarks/BookmarkEditActivity.java
@@ -25,8 +25,8 @@ import org.chromium.chrome.browser.bookmarks.BookmarkTextInputLayout; import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref; import org.chromium.chrome.browser.bookmarks.BookmarkUtils; -import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectView; -import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectViewCoordinator; +import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectRow; +import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkFolderSelectRowCoordinator; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.components.bookmarks.BookmarkId; import org.chromium.components.bookmarks.BookmarkItem; @@ -49,7 +49,7 @@ private static final String TAG = "BookmarkEdit"; - private ImprovedBookmarkFolderSelectViewCoordinator mFolderSelectCoordinator; + private ImprovedBookmarkFolderSelectRowCoordinator mFolderSelectCoordinator; private BookmarkModel mModel; private BookmarkId mBookmarkId; @@ -131,8 +131,8 @@ Resources res = this.getResources(); Profile profile = Profile.getLastUsedRegularProfile(); - mFolderSelectCoordinator = new ImprovedBookmarkFolderSelectViewCoordinator(this, - (ImprovedBookmarkFolderSelectView) findViewById(R.id.improved_folder_row), + mFolderSelectCoordinator = new ImprovedBookmarkFolderSelectRowCoordinator(this, + (ImprovedBookmarkFolderSelectRow) findViewById(R.id.improved_folder_row), new BookmarkImageFetcher(this, mModel, ImageFetcherFactory.createImageFetcher( ImageFetcherConfig.DISK_CACHE_ONLY, profile.getProfileKey()),
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java index e5a5ded..5b653f1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/download/home/DownloadActivity.java
@@ -7,9 +7,10 @@ import android.app.Activity; import android.os.Bundle; -import org.chromium.chrome.browser.BackPressHelper; import org.chromium.chrome.browser.SnackbarActivity; +import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.back_press.BackPressManager; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.download.DownloadUtils; import org.chromium.chrome.browser.download.home.DownloadManagerCoordinator; import org.chromium.chrome.browser.download.home.DownloadManagerUiConfig; @@ -26,7 +27,6 @@ import org.chromium.ui.permissions.AndroidPermissionDelegate; import java.lang.ref.WeakReference; - /** * Activity for managing downloads handled through Chrome. */ @@ -81,10 +81,10 @@ mDownloadCoordinator.addObserver(mUiObserver); if (BackPressManager.isSecondaryActivityEnabled()) { BackPressHelper.create(this, getOnBackPressedDispatcher(), - mDownloadCoordinator.getBackPressHandlers()); + mDownloadCoordinator.getBackPressHandlers(), SecondaryActivity.DOWNLOAD); } else { - BackPressHelper.create( - this, getOnBackPressedDispatcher(), mDownloadCoordinator::onBackPressed); + BackPressHelper.create(this, getOnBackPressedDispatcher(), + mDownloadCoordinator::onBackPressed, SecondaryActivity.DOWNLOAD); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectView.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRow.java similarity index 93% rename from chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectView.java rename to chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRow.java index 4863768f..db8dc08 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectView.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRow.java
@@ -23,14 +23,14 @@ * 1. Launch an activity to select a new folder. * 2. Within that activity select a folder or subfolder. */ -public class ImprovedBookmarkFolderSelectView extends FrameLayout { +public class ImprovedBookmarkFolderSelectRow extends FrameLayout { private View mRowView; private ImprovedBookmarkFolderView mFolderView; private TextView mTitleView; private View mEndIconView; /** Constructor for inflating from XML. */ - public ImprovedBookmarkFolderSelectView(Context context, AttributeSet attrs) { + public ImprovedBookmarkFolderSelectRow(Context context, AttributeSet attrs) { super(context, attrs); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinator.java similarity index 71% rename from chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinator.java rename to chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinator.java index cccb316..2f8a2b7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinator.java
@@ -22,7 +22,7 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor; /** Business logic for the improved bookmark folder select view. */ -public class ImprovedBookmarkFolderSelectViewCoordinator { +public class ImprovedBookmarkFolderSelectRowCoordinator { private final Context mContext; private final View mView; private final PropertyModel mModel; @@ -38,51 +38,51 @@ * @param bookmarkId The folder to show the row for. * @param bookmarkModel The bookmark model used to query bookmark properties. */ - public ImprovedBookmarkFolderSelectViewCoordinator(Context context, - ImprovedBookmarkFolderSelectView view, BookmarkImageFetcher bookmarkImageFetcher, + public ImprovedBookmarkFolderSelectRowCoordinator(Context context, + ImprovedBookmarkFolderSelectRow view, BookmarkImageFetcher bookmarkImageFetcher, BookmarkId bookmarkId, BookmarkModel bookmarkModel) { mContext = context; mView = view; - mModel = new PropertyModel(ImprovedBookmarkFolderSelectViewProperties.ALL_KEYS); + mModel = new PropertyModel(ImprovedBookmarkFolderSelectRowProperties.ALL_KEYS); PropertyModelChangeProcessor.create( - mModel, mView, ImprovedBookmarkFolderSelectViewBinder::bind); + mModel, mView, ImprovedBookmarkFolderSelectRowViewBinder::bind); mBookmarkImageFetcher = bookmarkImageFetcher; mBookmarkId = bookmarkId; mBookmarkModel = bookmarkModel; mBookmarkItem = mBookmarkModel.getBookmarkById(mBookmarkId); int type = mBookmarkId.getType(); - mModel.set(ImprovedBookmarkFolderSelectViewProperties.START_ICON_DRAWABLE, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.START_ICON_DRAWABLE, BookmarkUtils.getFolderIcon(mContext, type, BookmarkRowDisplayPref.VISUAL)); if (type == BookmarkType.READING_LIST) { - mModel.set(ImprovedBookmarkFolderSelectViewProperties.START_AREA_BACKGROUND_COLOR, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.START_AREA_BACKGROUND_COLOR, SemanticColorUtils.getColorPrimaryContainer(mContext)); - mModel.set(ImprovedBookmarkFolderSelectViewProperties.START_ICON_TINT, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.START_ICON_TINT, ColorStateList.valueOf( SemanticColorUtils.getDefaultIconColorAccent1(mContext))); } else { - mModel.set(ImprovedBookmarkFolderSelectViewProperties.START_AREA_BACKGROUND_COLOR, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.START_AREA_BACKGROUND_COLOR, ChromeColors.getSurfaceColor(mContext, R.dimen.default_elevation_1)); - mModel.set(ImprovedBookmarkFolderSelectViewProperties.START_ICON_TINT, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.START_ICON_TINT, AppCompatResources.getColorStateList( mContext, R.color.default_icon_color_secondary_tint_list)); } - mModel.set(ImprovedBookmarkFolderSelectViewProperties.TITLE, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.TITLE, mBookmarkModel.getBookmarkTitle(mBookmarkId)); - mModel.set(ImprovedBookmarkFolderSelectViewProperties.FOLDER_CHILD_COUNT, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.FOLDER_CHILD_COUNT, mBookmarkModel.getChildCount(mBookmarkId)); - mModel.set(ImprovedBookmarkFolderSelectViewProperties.END_ICON_VISIBLE, true); - mModel.set(ImprovedBookmarkFolderSelectViewProperties.ROW_CLICK_LISTENER, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.END_ICON_VISIBLE, true); + mModel.set(ImprovedBookmarkFolderSelectRowProperties.ROW_CLICK_LISTENER, (v) -> { // TODO(crbug.com/1448933): Implement new move activity. }); - mModel.set(ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES, new Pair<>(null, null)); if (BookmarkUtils.shouldShowImagesForFolder(mBookmarkModel, mBookmarkId)) { mBookmarkImageFetcher.fetchFirstTwoImagesForFolder(mBookmarkItem, (imagePair) -> { - mModel.set(ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES, + mModel.set(ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES, imagePair); }); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewProperties.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowProperties.java similarity index 96% rename from chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewProperties.java rename to chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowProperties.java index 95d3d61..e2791d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewProperties.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowProperties.java
@@ -15,7 +15,7 @@ import org.chromium.ui.modelutil.PropertyModel.WritableObjectPropertyKey; /** Responsible for hosting properties of the improved bookmark folder select view. */ -public class ImprovedBookmarkFolderSelectViewProperties { +public class ImprovedBookmarkFolderSelectRowProperties { public static final WritableObjectPropertyKey<String> TITLE = new WritableObjectPropertyKey<>(); // Sets the background color for the start image, both for the image and folder view. public static final WritableIntPropertyKey START_AREA_BACKGROUND_COLOR =
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowViewBinder.java new file mode 100644 index 0000000..c33ab32d --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowViewBinder.java
@@ -0,0 +1,44 @@ +// 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. + +package org.chromium.chrome.browser.bookmarks; + +import android.graphics.drawable.Drawable; +import android.util.Pair; +import android.view.View; + +import org.chromium.ui.modelutil.PropertyKey; +import org.chromium.ui.modelutil.PropertyModel; + +/** Binds model properties to view methods for ImprovedBookmarkFolderSelectRow. */ +public class ImprovedBookmarkFolderSelectRowViewBinder { + public static void bind(PropertyModel model, View view, PropertyKey key) { + ImprovedBookmarkFolderSelectRow row = (ImprovedBookmarkFolderSelectRow) view; + if (key == ImprovedBookmarkFolderSelectRowProperties.TITLE) { + row.setTitle(model.get(ImprovedBookmarkFolderSelectRowProperties.TITLE)); + } else if (key == ImprovedBookmarkFolderSelectRowProperties.START_AREA_BACKGROUND_COLOR) { + row.setStartAreaBackgroundColor(model.get( + ImprovedBookmarkFolderSelectRowProperties.START_AREA_BACKGROUND_COLOR)); + } else if (key == ImprovedBookmarkFolderSelectRowProperties.START_ICON_DRAWABLE) { + row.setStartIconDrawable( + model.get(ImprovedBookmarkFolderSelectRowProperties.START_ICON_DRAWABLE)); + } else if (key == ImprovedBookmarkFolderSelectRowProperties.START_ICON_TINT) { + row.setStartIconTint( + model.get(ImprovedBookmarkFolderSelectRowProperties.START_ICON_TINT)); + } else if (key == ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES) { + Pair<Drawable, Drawable> drawables = model.get( + ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES); + row.setStartImageDrawables(drawables.first, drawables.second); + } else if (key == ImprovedBookmarkFolderSelectRowProperties.FOLDER_CHILD_COUNT) { + row.setChildCount( + model.get(ImprovedBookmarkFolderSelectRowProperties.FOLDER_CHILD_COUNT)); + } else if (key == ImprovedBookmarkFolderSelectRowProperties.END_ICON_VISIBLE) { + row.setEndIconVisible( + model.get(ImprovedBookmarkFolderSelectRowProperties.END_ICON_VISIBLE)); + } else if (key == ImprovedBookmarkFolderSelectRowProperties.ROW_CLICK_LISTENER) { + row.setRowClickListener( + model.get(ImprovedBookmarkFolderSelectRowProperties.ROW_CLICK_LISTENER)); + } + } +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewBinder.java b/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewBinder.java deleted file mode 100644 index 5a668bcc..0000000 --- a/chrome/android/java/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewBinder.java +++ /dev/null
@@ -1,44 +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. - -package org.chromium.chrome.browser.bookmarks; - -import android.graphics.drawable.Drawable; -import android.util.Pair; -import android.view.View; - -import org.chromium.ui.modelutil.PropertyKey; -import org.chromium.ui.modelutil.PropertyModel; - -/** Binds model properties to view methods for ImprovedBookmarkFolderSelectRow. */ -public class ImprovedBookmarkFolderSelectViewBinder { - public static void bind(PropertyModel model, View view, PropertyKey key) { - ImprovedBookmarkFolderSelectView row = (ImprovedBookmarkFolderSelectView) view; - if (key == ImprovedBookmarkFolderSelectViewProperties.TITLE) { - row.setTitle(model.get(ImprovedBookmarkFolderSelectViewProperties.TITLE)); - } else if (key == ImprovedBookmarkFolderSelectViewProperties.START_AREA_BACKGROUND_COLOR) { - row.setStartAreaBackgroundColor(model.get( - ImprovedBookmarkFolderSelectViewProperties.START_AREA_BACKGROUND_COLOR)); - } else if (key == ImprovedBookmarkFolderSelectViewProperties.START_ICON_DRAWABLE) { - row.setStartIconDrawable( - model.get(ImprovedBookmarkFolderSelectViewProperties.START_ICON_DRAWABLE)); - } else if (key == ImprovedBookmarkFolderSelectViewProperties.START_ICON_TINT) { - row.setStartIconTint( - model.get(ImprovedBookmarkFolderSelectViewProperties.START_ICON_TINT)); - } else if (key == ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES) { - Pair<Drawable, Drawable> drawables = model.get( - ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES); - row.setStartImageDrawables(drawables.first, drawables.second); - } else if (key == ImprovedBookmarkFolderSelectViewProperties.FOLDER_CHILD_COUNT) { - row.setChildCount( - model.get(ImprovedBookmarkFolderSelectViewProperties.FOLDER_CHILD_COUNT)); - } else if (key == ImprovedBookmarkFolderSelectViewProperties.END_ICON_VISIBLE) { - row.setEndIconVisible( - model.get(ImprovedBookmarkFolderSelectViewProperties.END_ICON_VISIBLE)); - } else if (key == ImprovedBookmarkFolderSelectViewProperties.ROW_CLICK_LISTENER) { - row.setRowClickListener( - model.get(ImprovedBookmarkFolderSelectViewProperties.ROW_CLICK_LISTENER)); - } - } -}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java index 8a599fd..934c951 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStacker.java
@@ -11,9 +11,7 @@ */ public class ScrollingStripStacker extends StripStacker { @Override - public void setTabOffsets(int selectedIndex, StripLayoutTab[] indexOrderedTabs, - float tabStackWidth, int maxTabsToStack, float tabOverlapWidth, float stripLeftMargin, - float stripRightMargin, float stripWidth, boolean inReorderMode, boolean tabClosing, + public void setTabOffsets(StripLayoutTab[] indexOrderedTabs, boolean tabClosing, boolean tabCreating, float cachedTabWidth) { for (int i = 0; i < indexOrderedTabs.length; i++) { StripLayoutTab tab = indexOrderedTabs[i]; @@ -30,8 +28,7 @@ } @Override - public void performOcclusionPass( - int selectedIndex, StripLayoutTab[] indexOrderedTabs, float stripWidth) { + public void performOcclusionPass(StripLayoutTab[] indexOrderedTabs, float stripWidth) { for (int i = 0; i < indexOrderedTabs.length; i++) { StripLayoutTab tab = indexOrderedTabs[i]; tab.setVisible((tab.getDrawX() + tab.getWidth()) >= 0 && tab.getDrawX() <= stripWidth);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index 7748683..d380198 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -94,7 +94,6 @@ // Behavior Constants private static final float EPSILON = 0.001f; - private static final int MAX_TABS_TO_STACK = 4; private static final float REORDER_OVERLAP_SWITCH_PERCENTAGE = 0.53f; private static final float DROP_INTO_GROUP_MAX_OFFSET = 36.f; @@ -103,9 +102,9 @@ private static final int SPINNER_UPDATE_DELAY_MS = 66; // Degrees per millisecond. private static final float SPINNER_DPMS = 0.33f; - private static final int EXPAND_DURATION_MS = 250; - private static final int EXPAND_DURATION_MS_MEDIUM = 350; - private static final int EXPAND_DURATION_MS_LONG = 450; + private static final int SCROLL_DURATION_MS = 250; + private static final int SCROLL_DURATION_MS_MEDIUM = 350; + private static final int SCROLL_DURATION_MS_LONG = 450; private static final int ANIM_FOLIO_DETACH_MS = 75; private static final int ANIM_TAB_CREATED_MS = 150; private static final int ANIM_TAB_CLOSED_MS = 150; @@ -123,7 +122,6 @@ static final long DROP_INTO_GROUP_MS = 300L; // Visibility Constants - private static final float TAB_STACK_WIDTH_DP = 4.f; private static final float TAB_OVERLAP_WIDTH_DP = 24.f; private static final float TAB_OVERLAP_WIDTH_LARGE_DP = 28.f; private static final float TAB_WIDTH_MEDIUM = 156.f; @@ -534,22 +532,6 @@ } /** - * Allows changing the visual behavior of the tabs in this stack, as specified by - * {@code stacker}. - * @param stacker The {@link StripStacker} that should specify how the tabs should be - * presented. - */ - public void setTabStacker(StripStacker stacker) { - if (stacker != mStripStacker) mUpdateHost.requestUpdate(); - mStripStacker = stacker; - - // Push Stacker properties to tabs. - for (int i = 0; i < mStripTabs.length; i++) { - pushStackerPropertiesToTab(mStripTabs[i]); - } - } - - /** * @param margin The distance between the last tab and the edge of the screen. */ public void setEndMargin(float margin, boolean isMsbVisible) { @@ -859,27 +841,21 @@ } // 4. Figure out which tab needs to be visible. - StripLayoutTab fastExpandTab = findTabById(prevId); - int selIndex = mModel.index(); + StripLayoutTab tabToMakeVisible; if (!selected && selIndex >= 0 && selIndex < mStripTabs.length) { // Prioritize focusing on selected tab over newly created unselected tabs. - fastExpandTab = mStripTabs[selIndex]; + tabToMakeVisible = mStripTabs[selIndex]; } else { - fastExpandTab = tab; + tabToMakeVisible = tab; } - boolean allowLeftExpand = true; - boolean canExpandSelectedTab = true; - // 5. Scroll the stack so that the fast expand tab is visible. Skip if tab was restored. + // 5. Scroll the stack so that the desired tab visible. Skip if tab was restored. boolean skipAutoScroll = closureCancelled || onStartup; - if (fastExpandTab != null && !skipAutoScroll) { - float delta = calculateOffsetToMakeTabVisible( - fastExpandTab, canExpandSelectedTab, allowLeftExpand, true, selected); - - // If new tab button is visible, go directly to the new scroll offset rather than - // animating. Animating the scroll causes the new tab button to disappear for a frame. + if (tabToMakeVisible != null && !skipAutoScroll) { + float delta = calculateOffsetToMakeTabVisible(tabToMakeVisible, selected); boolean shouldAnimate = !mAnimationsDisabledForTesting; + setScrollForScrollingTabStacker(delta, shouldAnimate, time); } @@ -1249,8 +1225,8 @@ // 1. If we're currently in reorder mode, don't allow the user to fling. if (mInReorderMode) return; - // 2. If we're fast expanding or scrolling, figure out the destination of the scroll so we - // can apply it to the end of this fling. + // 2. If we're fast scrolling, figure out the destination of the scroll so we can apply it + // to the end of this fling. int scrollDeltaRemaining = 0; if (!mScroller.isFinished()) { scrollDeltaRemaining = mScroller.getFinalX() - Math.round(mScrollOffset); @@ -1705,8 +1681,7 @@ // The close button is visible by default. If it should be hidden on tab creation, do not // animate the fade-out. See (https://crbug.com/1342654). boolean shouldShowCloseButton = mCachedTabWidth >= TAB_WIDTH_MEDIUM; - tab.setCanShowCloseButton( - mStripStacker.canShowCloseButton() && shouldShowCloseButton, false); + tab.setCanShowCloseButton(shouldShowCloseButton, false); // TODO(dtrainor): Push more properties as they are added (title text slide, etc?) } @@ -1792,12 +1767,11 @@ computeTabInitialPositions(); // 3. Calculate the tab stacking and ensure that tabs are sized correctly. - mStripStacker.setTabOffsets(mModel.index(), mStripTabs, TAB_STACK_WIDTH_DP, - MAX_TABS_TO_STACK, mTabOverlapWidth, mLeftMargin, mRightMargin, mWidth, - mInReorderMode, mMultiStepTabCloseAnimRunning, mTabCreating, mCachedTabWidth); + mStripStacker.setTabOffsets( + mStripTabs, mMultiStepTabCloseAnimRunning, mTabCreating, mCachedTabWidth); // 4. Calculate which tabs are visible. - mStripStacker.performOcclusionPass(mModel.index(), mStripTabs, mWidth); + mStripStacker.performOcclusionPass(mStripTabs, mWidth); // 5. Create render list. createRenderList(); @@ -1919,14 +1893,10 @@ } /** - * This method calculates the scroll offset to make a tab visible when using the cascading or - * scrolling strip stacker. This method assumes that the {@param tab} is either currently - * selected or was newly created. {@param tab} isn't necessarily the selected tab as it could - * have been created in the background. + * This method calculates the scroll offset to make a tab visible. This method assumes that the + * {@param tab} is either currently selected or was newly created. {@param tab} isn't + * necessarily the selected tab as it could have been created in the background. * Note: - * 1. {@param canExpandSelectedTab}, {@param canExpandLeft} and {@param canExpandRight} is - * currently only relevant to the cascading strip stacker. - * 2. For scrollingStripStacker, * i) If {@param tab} isn't {@param selected}, and the currently selected tab is already fully * visible, the tab strip does not scroll. If the currently selected tab isn't already fully * visible, a minimum offset is scrolled to make it visible. @@ -1934,55 +1904,46 @@ * the selected tab or if the selected tab is towards the end of strip. * * @param tab The tab to make visible. - * @param canExpandSelectedTab Whether the selected tab is already unstacked. - * @param canExpandLeft Whether the cascading tab strip can be expanded to the left of the tab. - * @param canExpandRight Whether the cascading tab strip can be expanded to the right of the - * tab. * @param selected Whether the tab to make visible will be focused. * @return scroll offset to make the tab visible. */ - private float calculateOffsetToMakeTabVisible(StripLayoutTab tab, boolean canExpandSelectedTab, - boolean canExpandLeft, boolean canExpandRight, boolean selected) { + private float calculateOffsetToMakeTabVisible(StripLayoutTab tab, boolean selected) { if (tab == null) return 0.f; + // 1. Calculate the optimal minimum and maximum scroll offsets to show the tab. final int selIndex = mModel.index(); final int index = TabModelUtils.getTabIndexById(mModel, tab.getId()); - - // 1. The selected tab is always visible. Early out unless we want to unstack it. - if (selIndex == index && !canExpandSelectedTab) { - return 0.f; - } - - float stripWidth = getScrollableWidth(); + final float stripWidth = getScrollableWidth(); final float tabWidth = mCachedTabWidth - mTabOverlapWidth; - - // TODO(dtrainor): Handle maximum number of tabs that can be visibly stacked in these - // optimal positions. - - // 2. Calculate the optimal minimum and maximum scroll offsets to show the tab. float optimalLeft = -index * tabWidth; float optimalRight = stripWidth - (index + 1) * tabWidth; - // 3. Account for the selected tab always being visible. Need to buffer by one extra - // tab width depending on if the tab is to the left or right of the selected tab. + // 2. If the newly created tab will not be selected, prioritize keeping the currently + // selected tab visible. If it already is, there's no need to scroll. + // TODO(https://crbug.com/1448717): This is counterintuitive to the naming of the method, so + // planning to move this "prioritize selected tab" logic to wherever this method is + // actually called. StripLayoutTab currentlyFocusedTab = null; if (selIndex >= 0 && selIndex < mStripTabs.length) { currentlyFocusedTab = mStripTabs[selIndex]; } + if (currentlyFocusedTab != null && isSelectedTabCompletelyVisible(currentlyFocusedTab) && !selected) { - // We want to prioritize keeping the currently selected tab in visible area if newly - // created tab is not selected. If selected tab is already visible, no need to scroll. return 0.f; - } else { - if (index < selIndex) { // Tab is to the left of the selected tab - optimalRight -= tabWidth; - } else if (index > selIndex) { // Tab is to the right of the selected tab - optimalLeft += tabWidth; - } } - // 4. Return the proper deltaX that has to be applied to the current scroll to see the + // 3. Need to buffer by one extra tab width depending on if the tab is to the left or right + // of the selected tab. + if (index < selIndex) { + // Tab is to the left of the selected tab + optimalRight -= tabWidth; + } else if (index > selIndex) { + // Tab is to the right of the selected tab + optimalLeft += tabWidth; + } + + // 3. Return the proper deltaX that has to be applied to the current scroll to see the // tab. // Distance to make tab visible on the left edge and the right edge. float offsetToOptimalLeft = optimalLeft - mScrollOffset; @@ -2883,24 +2844,24 @@ if (shouldAnimate && !mAnimationsDisabledForTesting) { mScroller.startScroll( - Math.round(mScrollOffset), 0, (int) delta, 0, time, getExpandDuration()); + Math.round(mScrollOffset), 0, (int) delta, 0, time, getScrollDuration()); } else { mScrollOffset = mScrollOffset + delta; } } /** - * Scales the expand/scroll duration based on the scroll offset. + * Scales the scroll duration based on the scroll offset. * @return the duration in ms. */ - private int getExpandDuration() { + private int getScrollDuration() { float scrollDistance = Math.abs(mScrollOffset); if (scrollDistance <= SCROLL_DISTANCE_SHORT) { - return EXPAND_DURATION_MS; + return SCROLL_DURATION_MS; } else if (scrollDistance <= SCROLL_DISTANCE_MEDIUM) { - return EXPAND_DURATION_MS_MEDIUM; + return SCROLL_DURATION_MS_MEDIUM; } else { - return EXPAND_DURATION_MS_LONG; + return SCROLL_DURATION_MS_LONG; } } @@ -2914,7 +2875,7 @@ StripLayoutTab selectedLayoutTab = findTabById(selectedTab.getId()); if (selectedLayoutTab == null || isSelectedTabCompletelyVisible(selectedLayoutTab)) return; - float delta = calculateOffsetToMakeTabVisible(selectedLayoutTab, true, true, true, true); + float delta = calculateOffsetToMakeTabVisible(selectedLayoutTab, true); setScrollForScrollingTabStacker(delta, animate, time); } @@ -2979,8 +2940,8 @@ } @VisibleForTesting - int getExpandDurationForTesting() { - return getExpandDuration(); + int getScrollDurationForTesting() { + return getScrollDuration(); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java index 35d7bf88..4d6bf611 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -180,7 +180,8 @@ private static final int CLOSE_BUTTON_PADDING_DP = 7; private static final int CLOSE_BUTTON_WIDTH_DP = 48; - // Tab strip content y offset + // Strip Tab Offset Constants + private static final float TOP_MARGIN_DP = 2.f; private static final float FOLIO_CONTENT_OFFSET_Y = 8.f; private static final float DETACHED_CONTENT_OFFSET_Y = 10.f; @@ -625,9 +626,9 @@ */ public float getContentOffsetY() { if (TabManagementFieldTrial.isTabStripDetachedEnabled()) { - return DETACHED_CONTENT_OFFSET_Y; + return DETACHED_CONTENT_OFFSET_Y - (TOP_MARGIN_DP / 2); } else if (TabManagementFieldTrial.isTabStripFolioEnabled()) { - return FOLIO_CONTENT_OFFSET_Y; + return FOLIO_CONTENT_OFFSET_Y - (TOP_MARGIN_DP / 2); } else { // If TSR is disabled, contentOffsetY will not be used. Default to 0. return 0.f; @@ -670,6 +671,13 @@ } /** + * @return How far to offset the top of the tab container from the top of the tab strip. + */ + public float getTopMargin() { + return ChromeFeatureList.sTabStripRedesign.isEnabled() ? TOP_MARGIN_DP : 0; + } + + /** * @param visiblePercentage How much of the tab is visible (not overlapped by other tabs). */ public void setVisiblePercentage(float visiblePercentage) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStacker.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStacker.java index 929a1ff..c0b0d4b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStacker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStacker.java
@@ -15,15 +15,6 @@ */ public abstract class StripStacker { /** - * @return Whether or not the close button can be shown. Note that even if it can be shown, - * it might not be due to how much of the tab is actually visible to preserve proper hit - * target sizes. - */ - public boolean canShowCloseButton() { - return true; - } - - /** * This gives the implementing class a chance to determine how the tabs should be ordered * visually. The positioning logic is the same regardless, this just has to do with visual * stacking. @@ -53,22 +44,12 @@ /** * Computes and sets the draw X, draw Y, visibility and content offset for each tab. * - * @param selectedIndex The selected index of the tabs. * @param indexOrderedTabs A list of tabs ordered by index. - * @param tabStackWidth The width of a tab when it's stacked behind another tab. - * @param maxTabsToStack The maximum number of tabs to stack. - * @param tabOverlapWidth The amount tabs overlap. - * @param stripLeftMargin The left margin of the tab strip. - * @param stripRightMargin The right margin of the tab strip. - * @param stripWidth The width of the tab strip. - * @param inReorderMode Whether the strip is in reorder mode. * @param tabClosing Whether a tab is being closed. * @param tabCreating Whether a tab is being created. * @param cachedTabWidth Whether The ideal tab width. */ - public abstract void setTabOffsets(int selectedIndex, StripLayoutTab[] indexOrderedTabs, - float tabStackWidth, int maxTabsToStack, float tabOverlapWidth, float stripLeftMargin, - float stripRightMargin, float stripWidth, boolean inReorderMode, boolean tabClosing, + public abstract void setTabOffsets(StripLayoutTab[] indexOrderedTabs, boolean tabClosing, boolean tabCreating, float cachedTabWidth); /** @@ -88,7 +69,7 @@ float touchTargetOffset, float cachedTabWidth, boolean animate) { return LocalizationUtils.isLayoutRtl() ? computeNewTabButtonOffsetRtl(indexOrderedTabs, stripLeftMargin, stripRightMargin, - stripWidth, buttonWidth, touchTargetOffset, cachedTabWidth, animate) + stripWidth, buttonWidth, touchTargetOffset, animate) : computeNewTabButtonOffsetLtr(indexOrderedTabs, tabOverlapWidth, stripLeftMargin, stripRightMargin, stripWidth, touchTargetOffset, cachedTabWidth, animate); } @@ -128,8 +109,7 @@ private float computeNewTabButtonOffsetRtl(StripLayoutTab[] indexOrderedTabs, float stripLeftMargin, float stripRightMargin, float stripWidth, - float newTabButtonWidth, float touchTargetOffset, float cachedTabWidth, - boolean animate) { + float newTabButtonWidth, float touchTargetOffset, boolean animate) { float leftEdge = stripWidth - stripRightMargin; for (StripLayoutTab tab : indexOrderedTabs) { @@ -150,10 +130,8 @@ /** * Performs an occlusion pass, setting the visibility on tabs. This is relegated to this * interface because the implementing class knows the proper visual order to optimize this pass. - * @param selectedIndex The selected index of the tabs. * @param indexOrderedTabs A list of tabs ordered by index. * @param stripWidth The width of the tab strip. */ - public abstract void performOcclusionPass(int selectedIndex, StripLayoutTab[] indexOrderedTabs, - float stripWidth); -} \ No newline at end of file + public abstract void performOcclusionPass(StripLayoutTab[] indexOrderedTabs, float stripWidth); +}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java index bf2eb39..7195eeff 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
@@ -153,6 +153,8 @@ StripLayoutTab[] stripTabs, int selectedTabId) { final int tabsCount = stripTabs != null ? stripTabs.length : 0; + // TODO(https://crbug.com/1450380): Cleanup params, as some don't change and others are now + // unused. for (int i = 0; i < tabsCount; i++) { final StripLayoutTab st = stripTabs[i]; boolean isSelected = st.getId() == selectedTabId; @@ -165,10 +167,11 @@ st.getDrawX() * mDpToPx, st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx, st.getHeight() * mDpToPx, st.getContentOffsetX() * mDpToPx, st.getContentOffsetY() * mDpToPx, st.getDividerOffsetX() * mDpToPx, - st.getBottomMargin() * mDpToPx, st.getCloseButtonPadding() * mDpToPx, - st.getCloseButton().getOpacity(), st.isStartDividerVisible(), - st.isEndDividerVisible(), st.isLoading(), st.getLoadingSpinnerRotation(), - st.getBrightness(), st.getContainerOpacity(), layerTitleCache, resourceManager); + st.getBottomMargin() * mDpToPx, st.getTopMargin() * mDpToPx, + st.getCloseButtonPadding() * mDpToPx, st.getCloseButton().getOpacity(), + st.isStartDividerVisible(), st.isEndDividerVisible(), st.isLoading(), + st.getLoadingSpinnerRotation(), st.getBrightness(), st.getContainerOpacity(), + layerTitleCache, resourceManager); } } @@ -209,7 +212,7 @@ int handleOutlineResourceId, int closeTint, int dividerTint, int handleTint, int handleOutlineTint, boolean foreground, boolean closePressed, float toolbarWidth, float x, float y, float width, float height, float contentOffsetX, - float contentOffsetY, float dividerOffsetX, float bottomOffsetY, + float contentOffsetY, float dividerOffsetX, float bottomMargin, float topMargin, float closeButtonPadding, float closeButtonAlpha, boolean isStartDividerVisible, boolean isEndDividerVisible, boolean isLoading, float spinnerRotation, float brightness, float opacity, LayerTitleCache layerTitleCache,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java index 379f836..3db0cb9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/CustomTabActivity.java
@@ -134,7 +134,9 @@ FontPreloader.getInstance().onPostInflationStartupCustomTabActivity(); - mRootUiCoordinator.getStatusBarColorController().updateStatusBarColor(); + if (mRootUiCoordinator.getStatusBarColorController() != null) { + mRootUiCoordinator.getStatusBarColorController().updateStatusBarColor(); + } // Properly attach tab's InfoBarContainer to the view hierarchy if the tab is already // attached to a ChromeActivity, as the main tab might have been initialized prior to
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java index 966bf8d..b0c239ef 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/dependency_injection/ChromeActivityCommonsModule.java
@@ -16,6 +16,7 @@ import android.os.Bundle; import android.view.View; +import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import org.chromium.base.supplier.ObservableSupplier; @@ -74,6 +75,7 @@ private final TabCreatorManager mTabCreatorManager; private final Supplier<TabCreator> mTabCreatorSupplier; private final Supplier<Boolean> mIsPromotableToTabSupplier; + @Nullable private final StatusBarColorController mStatusBarColorController; private final ScreenOrientationProvider mScreenOrientationProvider; private final Supplier<NotificationManagerProxy> mNotificationManagerProxySupplier;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivity.java index b38ad3b..b97fee5c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/device_lock/DeviceLockActivity.java
@@ -13,6 +13,7 @@ import android.widget.FrameLayout; import androidx.annotation.CallSuper; +import androidx.annotation.VisibleForTesting; import org.chromium.chrome.browser.SynchronousInitializationActivity; import org.chromium.chrome.browser.ui.device_lock.DeviceLockCoordinator; @@ -36,15 +37,30 @@ private FrameLayout mFrameLayout; private WindowAndroid mWindowAndroid; + private IntentRequestTracker mIntentRequestTracker; private DeviceLockCoordinator mDeviceLockCoordinator; @Override + public void onActivityResult(int requestCode, int resultCode, Intent data) { + if (mIntentRequestTracker != null) { + mIntentRequestTracker.onActivityResult(requestCode, resultCode, data); + } + super.onActivityResult(requestCode, resultCode, data); + } + + @VisibleForTesting + void setIntentRequestTrackerForTesting(IntentRequestTracker intentRequestTracker) { + mIntentRequestTracker = intentRequestTracker; + } + + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mFrameLayout = new FrameLayout(this); setContentView(mFrameLayout); mWindowAndroid = new ActivityWindowAndroid(this, /* listenToActivityState= */ true, IntentRequestTracker.createFromActivity(this)); + mIntentRequestTracker = mWindowAndroid.getIntentRequestTracker(); Bundle fragmentArgs = getIntent().getBundleExtra(ARGUMENT_FRAGMENT_ARGS); Account selectedAccount = AccountUtils.createAccountFromName(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java index f37831e..f2e72b2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivity.java
@@ -23,6 +23,7 @@ import org.chromium.base.Promise; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.fonts.FontPreloader; import org.chromium.chrome.browser.metrics.UmaUtils; @@ -398,6 +399,11 @@ return BackPressResult.SUCCESS; } + @Override + public int getSecondaryActivity() { + return SecondaryActivity.FIRST_RUN; + } + // FirstRunPageDelegate: @Override public Bundle getProperties() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java index db91b90..dba5e82e 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/FirstRunActivityBase.java
@@ -21,8 +21,9 @@ import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.OneshotSupplier; import org.chromium.base.supplier.OneshotSupplierImpl; -import org.chromium.chrome.browser.BackPressHelper; +import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.back_press.BackPressManager; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.customtabs.CustomTabsConnection; import org.chromium.chrome.browser.init.AsyncInitializationActivity; import org.chromium.chrome.browser.metrics.SimpleStartupForegroundSessionDetector; @@ -109,12 +110,13 @@ protected void onPreCreate() { super.onPreCreate(); if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create(this, getOnBackPressedDispatcher(), this); + BackPressHelper.create( + this, getOnBackPressedDispatcher(), this, getSecondaryActivity()); } else { BackPressHelper.create(this, getOnBackPressedDispatcher(), () -> { handleBackPress(); return true; - }); + }, getSecondaryActivity()); } } @@ -169,6 +171,8 @@ @Override public abstract @BackPressResult int handleBackPress(); + public abstract @SecondaryActivity int getSecondaryActivity(); + protected void flushPersistentData() { if (mNativeInitialized) { ProfileManagerUtils.flushPersistentDataForAllProfiles();
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java index ca2f5fa..fe5e7336 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/firstrun/LightweightFirstRunActivity.java
@@ -22,6 +22,7 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.enterprise.util.EnterpriseInfo; import org.chromium.ui.base.LocalizationUtils; @@ -220,6 +221,11 @@ return BackPressResult.SUCCESS; } + @Override + public int getSecondaryActivity() { + return SecondaryActivity.LIGHTWEIGHT_FIRST_RUN; + } + private void abortFirstRunExperience() { finish(); notifyCustomTabCallbackFirstRunIfNecessary(getIntent(), false);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java index 38343c3..3ac6d47b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandler.java
@@ -35,8 +35,6 @@ import org.chromium.cc.input.BrowserControlsState; import org.chromium.chrome.browser.ActivityTabProvider; import org.chromium.chrome.browser.ActivityTabProvider.ActivityTabTabObserver; -import org.chromium.chrome.browser.flags.ChromeFeatureList; -import org.chromium.chrome.browser.fullscreen.FullscreenToast.CustomViewToast; import org.chromium.chrome.browser.multiwindow.MultiWindowUtils; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAttributeKeys; @@ -46,7 +44,6 @@ import org.chromium.chrome.browser.tab.TabUtils; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelSelectorTabObserver; -import org.chromium.components.browser_ui.util.DimensionCompat; import org.chromium.components.embedder_support.view.ContentView; import org.chromium.content_public.browser.GestureListenerManager; import org.chromium.content_public.browser.NavigationHandle; @@ -107,6 +104,8 @@ @Nullable private Tab mTab; + private boolean mNotifyOnNextExit; + // Current ContentView. Updates when active tab is switched or WebContents is swapped // in the current Tab. private ContentView mContentView; @@ -298,13 +297,7 @@ @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) private FullscreenToast getToast() { if (mToast == null) { - if (ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_WIDGET_FULLSCREEN_TOAST)) { - mToast = new FullscreenToast.AndroidToast( - mActivity, this::getPersistentFullscreenMode); - } else { - mToast = new FullscreenToast.CustomViewToast(mActivity, mHandler, - () -> mTab, () -> mContentViewInFullscreen, () -> mTabInFullscreen); - } + mToast = new FullscreenToast.AndroidToast(mActivity, this::getPersistentFullscreenMode); } return mToast; } @@ -343,7 +336,8 @@ setEnterFullscreenRunnable(tab, null); boolean wasInPersistentFullscreenMode = getPersistentFullscreenMode(); exitPersistentFullscreenMode(); - if (wasInPersistentFullscreenMode) { + if (wasInPersistentFullscreenMode || mNotifyOnNextExit) { + mNotifyOnNextExit = false; for (FullscreenManager.Observer observer : mObservers) { observer.onExitFullscreen(tab); } @@ -395,6 +389,7 @@ private void enterPersistentFullscreenMode(FullscreenOptions options) { if (!shouldSkipEnterFullscreenRequest(options)) { mPersistentModeSupplier.set(true); + mNotifyOnNextExit = true; if (mAreControlsHidden.get()) { // The browser controls are currently hidden. enterFullscreen(mTab, options); @@ -743,18 +738,6 @@ return getToast().isVisible(); } - int getToastBottomMarginForTesting() { - return ((CustomViewToast) getToast()).getToastBottomMarginForTesting(); - } - - void setVersionCompatForTesting(DimensionCompat compat) { - ((CustomViewToast) getToast()).setDimensionCompatForTesting(compat); - } - - void triggerWindowLayoutChangeForTesting() { - ((CustomViewToast) getToast()).triggerWindowLayoutForTesting(); - } - private static void setSystemUiVisibility(View contentView, int systemUiVisibility) { if (!BuildInfo.getInstance().isAutomotive) { contentView.setSystemUiVisibility(systemUiVisibility);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenToast.java b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenToast.java index 8a88d26..b75f318 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenToast.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/fullscreen/FullscreenToast.java
@@ -5,21 +5,10 @@ package org.chromium.chrome.browser.fullscreen; import android.app.Activity; -import android.graphics.Rect; -import android.os.Handler; import android.view.Gravity; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.view.ViewPropertyAnimator; -import android.view.ViewTreeObserver.OnGlobalLayoutListener; -import android.widget.TextView; import org.chromium.base.BuildInfo; -import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; -import org.chromium.chrome.browser.tab.Tab; -import org.chromium.components.browser_ui.util.DimensionCompat; import org.chromium.ui.widget.Toast; import org.chromium.ui.widget.Toast.ToastPriority; @@ -114,310 +103,4 @@ } } } - - // Custom view-based fullscreen toast. - class CustomViewToast implements FullscreenToast { - // Fade in/out animation duration for fullscreen notification toast. - private static final int TOAST_FADE_MS = 500; - - // Time that the notification toast remains on-screen before starting to fade out. - private static final int TOAST_SHOW_DURATION_MS = 5000; - - private final Activity mActivity; - private final Handler mHandler; - private final Supplier<Tab> mTab; - private final Supplier<Tab> mTabInFullscreen; - private final Supplier<View> mContentViewInFullscreen; - - // Runnable that will complete the current toast and fade it out. - private final Runnable mFadeOutNotificationToastRunnable; - - // Toast at the top of the screen that is shown when user enters fullscreen for the - // first time. - // - // This is whether we believe that we need to show the user a notification toast. It's - // false if we're not in full screen, or if we are in full screen but have already shown the - // toast for enough time for the user to read it. The toast might or might not actually be - // on-screen right now; we remove it in some cases like when we lose window focus. However, - // as long as we'll be in full screen, we still keep the toast pending until we successfully - // show it. - private boolean mIsNotificationToastPending; - - // Sometimes, the toast must be removed temporarily, such as when we lose focus or if we - // transition to picture-in-picture. In those cases, the toast is removed from the view - // hierarchy, and these fields are cleared. The toast will be re-created from scratch when - // it's appropriate to show it again. `mIsNotificationToastPending` won't be reset in those - // cases, though, since we'll still want to show the toast when it's possible to do so. - // - // If `mNotificationToast` exists, then it's attached to the view hierarchy, though it might - // be animating to or from alpha=0. Any time the toast exists, we also have an animation - // for it, to allow us to fade it in, and eventually back out. The animation is not cleared - // when it completes; it's only cleared when we also detach the toast and clear - // `mNotificationToast`. - // - // Importantly, it's possible that `mNotificationToast` is not null while no toast is - // pending. This can happen when the toast has been on-screen long enough, and is fading - // out. - private View mNotificationToast; - private ViewPropertyAnimator mToastFadeAnimation; - - private DimensionCompat mDimensionCompat; - private int mNavbarHeight; - - // Monitors the window layout change while the fullscreen toast is on. - private OnGlobalLayoutListener mWindowLayoutListener = new OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - if (mContentViewInFullscreen.get() == null || mNotificationToast == null) return; - Rect bounds = new Rect(); - mContentViewInFullscreen.get().getWindowVisibleDisplayFrame(bounds); - var lp = (ViewGroup.MarginLayoutParams) mNotificationToast.getLayoutParams(); - int bottomMargin = mContentViewInFullscreen.get().getHeight() - bounds.height(); - // If positioned at the bottom of the display, shift it up to avoid overlapping - // with the bottom nav bar when it appears by user gestures. - if (bottomMargin == 0) bottomMargin = mNavbarHeight; - lp.setMargins(0, 0, 0, bottomMargin); - mNotificationToast.requestLayout(); - } - }; - - CustomViewToast(Activity activity, Handler handler, Supplier<Tab> tab, - Supplier<View> contentViewInFullscreen, Supplier<Tab> tabInFullscreen) { - mActivity = activity; - mHandler = handler; - mTab = tab; - mContentViewInFullscreen = contentViewInFullscreen; - mTabInFullscreen = tabInFullscreen; - mFadeOutNotificationToastRunnable = this::fadeOutNotificationToast; - mDimensionCompat = DimensionCompat.create(mActivity, () -> {}); - } - - @Override - public void onEnterFullscreen() { - // Cache the navigation bar height before entering fullscreen mode in which - // the dimension is zero. - mNavbarHeight = mDimensionCompat.getNavbarHeight(); - mActivity.getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener( - mWindowLayoutListener); - } - - @Override - public void onFullscreenLayout() { - beginNotificationToast(); - } - - @Override - public void onExitPersistentFullscreen() { - cancelNotificationToast(); - } - - @Override - public void onExitFullscreen() { - cancelNotificationToast(); - } - - /** - * Whether we show a toast message when entering fullscreen. - */ - private boolean shouldShowToast() { - // If there's no notification toast pending, such as when we're not in full screen or - // after we've already displayed it for longe enough, then we don't need to show the - // toast now. - if (!mIsNotificationToastPending) return false; - - if (mTabInFullscreen.get() == null) return false; - - if (mTab.get() == null) return false; - - final ViewGroup parent = mTab.get().getContentView(); - if (parent == null) return false; - - // The window must have the focus, so that it is not obscured while the notification is - // showing. This also covers the case of picture in picture video, but any case of an - // unfocused window should prevent the toast. - if (!parent.hasWindowFocus()) return false; - - return true; - } - - /** - * Create and show the fullscreen notification toast, if it's not already visible and if it - * should be visible. It's okay to call this when it should not be; we'll do nothing. This - * will fade the toast in if needed. It will also schedule a timer to fade it back out, if - * it's not hidden or cancelled before then. - */ - private void createAndShowNotificationToast() { - // If it's already visible, then that's fine. That includes if it's currently fading - // out; that's part of it. - if (mNotificationToast != null) return; - - // If the toast should not be visible, then do nothing. - if (!shouldShowToast()) return; - - assert mTab.get() != null && mTab.get().getContentView() != null; - - // Create a new toast and fade it in, or re-use one we've created before. - mNotificationToast = mActivity.getWindow().findViewById(R.id.fullscreen_notification); - boolean addView = false; - if (mNotificationToast == null) { - mNotificationToast = LayoutInflater.from(mActivity).inflate( - R.layout.fullscreen_notification, null); - addView = true; - } - if (BuildInfo.getInstance().isAutomotive) { - TextView toastTextView = mNotificationToast.findViewById(R.id.text); - if (toastTextView != null) { - toastTextView.setText( - R.string.immersive_fullscreen_api_notification_automotive); - } - } - mNotificationToast.setAlpha(0); - mToastFadeAnimation = mNotificationToast.animate(); - if (addView) { - mActivity.addContentView(mNotificationToast, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - // Ensure the toast is visible on bottom sheet CCT which is elevated for shadow - // effect. Does no harm on other embedders. - mNotificationToast.setElevation(mActivity.getResources().getDimensionPixelSize( - R.dimen.fullscreen_toast_elevation)); - } else { - mNotificationToast.setVisibility(View.VISIBLE); - } - - mToastFadeAnimation.alpha(1).setDuration(TOAST_FADE_MS).start(); - mHandler.postDelayed(mFadeOutNotificationToastRunnable, TOAST_SHOW_DURATION_MS); - } - - /** - * Pause the notification toast, which hides it and stops all the timers. It's okay if - * there is not currently a toast; we don't change any state in that case. This will - * abruptly hide the toast, rather than fade it out. This does not change - * `mIsNotificationToastPending`; the toast hasn't been shown long enough. - */ - private void hideImmediatelyNotificationToast() { - if (mNotificationToast == null) return; - - // Stop the fade-out timer. - mHandler.removeCallbacks(mFadeOutNotificationToastRunnable); - - // Remove it immediately, without fading out. - assert mToastFadeAnimation != null; - mToastFadeAnimation.cancel(); - mToastFadeAnimation = null; - - mActivity.getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener( - mWindowLayoutListener); - - // We can't actually remove it, so this will do. - mNotificationToast.setVisibility(View.GONE); - mNotificationToast = null; - } - - /** - * Begin a new instance of the notification toast. If the toast should not be shown right - * now, we'll start showing it when we can. - */ - private void beginNotificationToast() { - // It would be nice if we could determine that we're not starting a new toast while a - // previous one is fading out. We can't ask the animation for its current target value. - // We could almost check that there's not a notification pending and also that there's - // no current toast. When a notification is pending, the previous toast hasn't - // completed yet, so nobody should be starting a new one. When `mNotificationToast` is - // not null, but pending is false, then the fade-out animation has started but not - // completed. Only when they're both false is it in the steady-state of "no - // notification" that would let us start a new one. - // - // The problem with that is that there are cases when we double-enter fullscreen. In - // particular, changing the visibility of the navigation bar and/or status bar can cause - // us to think that we're entering fullscreen without an intervening exit. In this - // case, the right thing to do is to continue with the toast from the previous full - // screen, if it's still on-screen. If it's fading out now, just let it continue to - // fade out. The user has already seen it for the full duration, and we've not actually - // exited fullscreen. - if (mNotificationToast != null) { - // Don't reset the pending flag here -- either it's on the screen or fading out, and - // either way is correct. We have not actually exited fullscreen, so we shouldn't - // re-display the notification. - return; - } - - mIsNotificationToastPending = true; - createAndShowNotificationToast(); - } - - /** - * Cancel a toast immediately, without fading out. For example, if we leave fullscreen, - * then the toast isn't needed anymore. - */ - private void cancelNotificationToast() { - hideImmediatelyNotificationToast(); - // Don't restart it either. - mIsNotificationToastPending = false; - } - - /** - * Called when the notification toast should not be shown any more, because it's been - * on-screen long enough for the user to read it. To re-show it, one must call - * `beginNotificationToast()` again. Show / hide of the toast will no-op until then. - */ - private void fadeOutNotificationToast() { - if (mNotificationToast == null) return; - - // Clear this first, so that we know that the toast timer has expired already. - mIsNotificationToastPending = false; - - // Cancel any timer that will start the fade-out animation, in case it's running. It - // might not be, especially if we're called by it. - mHandler.removeCallbacks(mFadeOutNotificationToastRunnable); - - // Start the fade-out animation. - assert mToastFadeAnimation != null; - mToastFadeAnimation.cancel(); - mToastFadeAnimation.alpha(0) - .setDuration(TOAST_FADE_MS) - .withEndAction(this::hideImmediatelyNotificationToast) - .start(); - } - - @Override - public void onWindowFocusChanged(boolean hasWindowFocus) { - // Try to show / hide the toast, if we need to. Note that these won't do anything if - // the toast should not be visible, such as if we re-gain the window focus after having - // completed the most recently started notification toast. - // - // Also note that this handles picture-in-picture. We definitely do not want the toast - // to be visible then; it's not relevant and also takes up almost all of the window. We - // could also do this on ActivityStateChanged => PAUSED if - // Activity.isInPictureInPictureMode(), but it doesn't seem to be needed. - if (hasWindowFocus) { - createAndShowNotificationToast(); - } else { - // While we don't have the focus, hide any ongoing notification. - hideImmediatelyNotificationToast(); - } - } - - @Override - public boolean isVisible() { - return mNotificationToast != null; - } - - boolean isVisibleForTesting() { - return mNotificationToast != null; - } - - int getToastBottomMarginForTesting() { - var lp = (ViewGroup.MarginLayoutParams) mNotificationToast.getLayoutParams(); - return lp.bottomMargin; - } - - void setDimensionCompatForTesting(DimensionCompat compat) { - mDimensionCompat = compat; - } - - void triggerWindowLayoutForTesting() { - mWindowLayoutListener.onGlobalLayout(); - } - } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java index 80a93e64..88e1ab83 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryActivity.java
@@ -9,10 +9,11 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.IntentUtils; -import org.chromium.chrome.browser.BackPressHelper; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.SnackbarActivity; +import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.back_press.BackPressManager; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.history_clusters.HistoryClustersConstants; import org.chromium.chrome.browser.profiles.Profile; @@ -37,10 +38,11 @@ new BrowsingHistoryBridge(Profile.getLastUsedRegularProfile())); setContentView(mHistoryManager.getView()); if (BackPressManager.isSecondaryActivityEnabled()) { - BackPressHelper.create(this, getOnBackPressedDispatcher(), mHistoryManager); - } else { BackPressHelper.create( - this, getOnBackPressedDispatcher(), mHistoryManager::onBackPressed); + this, getOnBackPressedDispatcher(), mHistoryManager, SecondaryActivity.HISTORY); + } else { + BackPressHelper.create(this, getOnBackPressedDispatcher(), + mHistoryManager::onBackPressed, SecondaryActivity.HISTORY); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java index 2fb16d3..16838413 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/history/HistoryManager.java
@@ -690,7 +690,6 @@ } else if (isHistoryClustersUIShowing()) { return mHistoryClustersCoordinator.onBackPressed(); } - return mSelectableListLayout.onBackPressed(); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java index 9cad003..7783471 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/SettingsActivity.java
@@ -34,12 +34,13 @@ import org.chromium.base.IntentUtils; import org.chromium.chrome.R; import org.chromium.chrome.browser.ApplicationLifetime; -import org.chromium.chrome.browser.BackPressHelper; import org.chromium.chrome.browser.ChromeBaseAppCompatActivity; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.LaunchIntentDispatcher; import org.chromium.chrome.browser.accessibility.settings.ChromeAccessibilitySettingsDelegate; +import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.back_press.BackPressManager; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.browsing_data.ClearBrowsingDataFragmentBasic; import org.chromium.chrome.browser.feedback.FragmentHelpAndFeedbackLauncher; import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl; @@ -398,12 +399,14 @@ if (BackPressManager.isSecondaryActivityEnabled()) { if (activeFragment instanceof BackPressHandler) { BackPressHelper.create(activeFragment.getViewLifecycleOwner(), - getOnBackPressedDispatcher(), (BackPressHandler) activeFragment); + getOnBackPressedDispatcher(), (BackPressHandler) activeFragment, + SecondaryActivity.SETTINGS); } } else if (activeFragment instanceof BackPressHelper.ObsoleteBackPressedHandler) { BackPressHelper.create(activeFragment.getViewLifecycleOwner(), getOnBackPressedDispatcher(), - (BackPressHelper.ObsoleteBackPressedHandler) activeFragment); + (BackPressHelper.ObsoleteBackPressedHandler) activeFragment, + SecondaryActivity.SETTINGS); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java index 3b229431f..72bf1047 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/sync/settings/ManageSyncSettings.java
@@ -35,9 +35,9 @@ import org.chromium.base.task.TaskTraits; import org.chromium.chrome.R; import org.chromium.chrome.browser.AppHooks; -import org.chromium.chrome.browser.BackPressHelper; import org.chromium.chrome.browser.SyncFirstSetupCompleteSource; import org.chromium.chrome.browser.autofill.PersonalDataManager; +import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.feedback.FragmentHelpAndFeedbackLauncher; import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher; import org.chromium.chrome.browser.profiles.Profile;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java index 6f7f986f9..37adb15 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedRootUiCoordinator.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.tabbed_mode; +import android.graphics.Color; import android.os.Bundle; import android.view.ViewGroup; @@ -627,12 +628,16 @@ new ScrimCoordinator.SystemUiScrimDelegate() { @Override public void setScrimColor(int scrimColor) { - mStatusBarColorController.setScrimColor(scrimColor); + if (mStatusBarColorController != null) { + mStatusBarColorController.setScrimColor(scrimColor); + } } @Override public void setStatusBarScrimFraction(float scrimFraction) { - mStatusBarColorController.setStatusBarScrimFraction(scrimFraction); + if (mStatusBarColorController != null) { + mStatusBarColorController.setStatusBarScrimFraction(scrimFraction); + } } @Override @@ -838,7 +843,9 @@ mStatusIndicatorCoordinator = new StatusIndicatorCoordinator(mActivity, mCompositorViewHolderSupplier.get().getResourceManager(), browserControlsSizer, mTabObscuringHandlerSupplier.get(), - mStatusBarColorController::getStatusBarColorWithoutStatusIndicator, + mStatusBarColorController == null + ? (() -> Color.BLACK) + : mStatusBarColorController::getStatusBarColorWithoutStatusIndicator, mCanAnimateBrowserControls, layoutManager::requestUpdate); layoutManager.addSceneOverlay(mStatusIndicatorCoordinator.getSceneLayer()); mStatusIndicatorObserver = new StatusIndicatorCoordinator.StatusIndicatorObserver() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java index af0a204..b79a8d7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtil.java
@@ -13,6 +13,7 @@ import android.text.TextUtils; import android.text.format.DateUtils; +import androidx.annotation.IntDef; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -56,6 +57,7 @@ import org.chromium.chrome.browser.tabmodel.TabPersistentStore.ActiveTabState; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.ui.fold_transitions.FoldTransitionController; +import org.chromium.chrome.browser.ui.native_page.NativePage; import org.chromium.chrome.browser.util.BrowserUiUtils; import org.chromium.chrome.browser.util.BrowserUiUtils.HostSurface; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; @@ -74,6 +76,9 @@ import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.PageTransition; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + /** * This is a utility class for managing features related to returning to Chrome after haven't used * Chrome for a while. @@ -81,6 +86,29 @@ public final class ReturnToChromeUtil { private static final String TAG = "TabSwitcherOnReturn"; + /** + * The reasons of failing to show the home surface UI on a NTP. + * + * These values are persisted to logs. Entries should not be renumbered and numeric values + * should never be reused. See tools/metrics/histograms/enums.xml. + */ + @IntDef({FailToShowHomeSurfaceReason.FAIL_TO_CREATE_NTP_TAB, + FailToShowHomeSurfaceReason.FAIL_TO_FIND_NTP_TAB, + FailToShowHomeSurfaceReason.NOT_A_NATIVE_PAGE, + FailToShowHomeSurfaceReason.NOT_A_NTP_NATIVE_PAGE, + FailToShowHomeSurfaceReason.NATIVE_PAGE_IS_FROZEN, + FailToShowHomeSurfaceReason.NUM_ENTRIES}) + @Retention(RetentionPolicy.SOURCE) + @interface FailToShowHomeSurfaceReason { + int FAIL_TO_CREATE_NTP_TAB = 0; + int FAIL_TO_FIND_NTP_TAB = 1; + int NOT_A_NATIVE_PAGE = 2; + + int NOT_A_NTP_NATIVE_PAGE = 3; + int NATIVE_PAGE_IS_FROZEN = 4; + int NUM_ENTRIES = 5; + } + @VisibleForTesting public static final String LAST_VISITED_TAB_IS_SRP_WHEN_OVERVIEW_IS_SHOWN_AT_LAUNCH_UMA = "Startup.Android.LastVisitedTabIsSRPWhenOverviewShownAtLaunch"; @@ -93,6 +121,8 @@ public static final String HOME_SURFACE_SHOWN_AT_STARTUP_UMA = "NewTabPage.AsHomeSurface.ShownAtStartup"; public static final String HOME_SURFACE_SHOWN_UMA = "NewTabPage.AsHomeSurface"; + public static final String FAIL_TO_SHOW_HOME_SURFACE_UI_UMA = + "NewTabPage.FailToShowHomeSurfaceUI"; private static final String START_SEGMENTATION_PLATFORM_KEY = "chrome_start_android"; private static final String START_V2_SEGMENTATION_PLATFORM_KEY = "chrome_start_android_v2"; @@ -577,6 +607,13 @@ // Creates a new Tab if doesn't find an existing to reuse. Tab ntpTab = tabCreator.createNewTab( new LoadUrlParams(UrlConstants.NTP_URL), TabLaunchType.FROM_STARTUP, null); + boolean isNtpUrl = UrlUtilities.isNTPUrl(ntpTab.getUrl()); + assert isNtpUrl : "The URL of the newly created NTP doesn't match NTP URL!"; + if (!isNtpUrl) { + recordFailToShowHomeSurfaceReasonUma( + FailToShowHomeSurfaceReason.FAIL_TO_CREATE_NTP_TAB); + return null; + } // In cold startup, we only have the URL of the last active Tab. if (lastActiveTab == null) { @@ -587,11 +624,25 @@ TabModelObserver observer = new TabModelObserver() { @Override public void willAddTab(Tab tab, int type) { - assert TextUtils.equals(lastActiveTabUrl, tab.getUrl().getSpec()) - : "The URL of first Tab restored doesn't match the URL of the last active Tab read from the Tab state metadata file!"; + boolean isTabExpected = + TextUtils.equals(lastActiveTabUrl, tab.getUrl().getSpec()); + assert isTabExpected + : "The URL of first Tab restored doesn't match the URL of the last active " + + "Tab read from the Tab state metadata file! Existing Tab count = %d" + + tabModelSelector.getModel(false).getCount() + + "."; + if (!isTabExpected) { + return; + } showHomeSurfaceUiOnNtp(ntpTab, tab, homeSurfaceTracker); tabModelSelector.getModel(false).removeObserver(this); } + + @Override + public void restoreCompleted() { + // This would be no-op if the observer has been removed in willAddTab(). + tabModelSelector.getModel(false).removeObserver(this); + } }; tabModelSelector.getModel(false).addObserver(observer); } else { @@ -634,6 +685,14 @@ if (indexOfFirstNtp != TabModel.INVALID_TAB_INDEX) { Tab ntpTab = currentTabModel.getTabAt(indexOfFirstNtp); assert indexOfFirstNtp != index; + boolean isNtpUrl = UrlUtilities.isNTPUrl(ntpTab.getUrl()); + assert isNtpUrl + : "The URL of the first NTP found onResume doesn't match a NTP URL!"; + if (!isNtpUrl) { + recordFailToShowHomeSurfaceReasonUma( + FailToShowHomeSurfaceReason.FAIL_TO_FIND_NTP_TAB); + return; + } // Sets the found NTP as home surface. TabModelUtils.setIndex(currentTabModel, indexOfFirstNtp, false); @@ -798,10 +857,36 @@ /** * Shows the home surface UI on the given Ntp on tablets. */ - private static void showHomeSurfaceUiOnNtp( + static void showHomeSurfaceUiOnNtp( Tab ntpTab, Tab lastActiveTab, HomeSurfaceTracker homeSurfaceTracker) { - assert ntpTab.isNativePage(); + NativePage nativePage = ntpTab.getNativePage(); + if (nativePage == null) { + recordFailToShowHomeSurfaceReasonUma(FailToShowHomeSurfaceReason.NOT_A_NATIVE_PAGE); + return; + } + + // It is possible to get null after casting ntpTab.getNativePage() to NewTabPage, early + // exit here. See https://crbug.com/1449900. + if (!(nativePage instanceof NewTabPage)) { + recordFailToShowHomeSurfaceReasonUma(FailToShowHomeSurfaceReason.NOT_A_NTP_NATIVE_PAGE); + if (nativePage.isFrozen()) { + recordFailToShowHomeSurfaceReasonUma( + FailToShowHomeSurfaceReason.NATIVE_PAGE_IS_FROZEN); + } + return; + } + + // This cast is now guaranteed to succeed to a non-null value. + NewTabPage newTabPage = (NewTabPage) nativePage; homeSurfaceTracker.updateHomeSurfaceAndTrackingTabs(ntpTab, lastActiveTab); - ((NewTabPage) ntpTab.getNativePage()).showHomeSurfaceUi(lastActiveTab); + newTabPage.showHomeSurfaceUi(lastActiveTab); + } + + // TODO(https://crbug.com/1450578): Removes this histogram once we understand the root cause of + // the crash. + private static void recordFailToShowHomeSurfaceReasonUma( + @FailToShowHomeSurfaceReason int reason) { + RecordHistogram.recordEnumeratedHistogram( + FAIL_TO_SHOW_HOME_SURFACE_UI_UMA, reason, FailToShowHomeSurfaceReason.NUM_ENTRIES); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java index 99a3328..d487b44 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/toolbar/ToolbarManager.java
@@ -250,6 +250,7 @@ private MenuButtonCoordinator mMenuButtonCoordinator; private MenuButtonCoordinator mOverviewModeMenuButtonCoordinator; private HomepageManager.HomepageStateListener mHomepageStateListener; + @Nullable private StatusBarColorController mStatusBarColorController; private final ActivityLifecycleDispatcher mActivityLifecycleDispatcher; private final BottomSheetController mBottomSheetController; @@ -444,7 +445,8 @@ OneshotSupplier<Boolean> promoShownOneshotSupplier, WindowAndroid windowAndroid, Supplier<Boolean> isInOverviewModeSupplier, Supplier<ModalDialogManager> modalDialogManagerSupplier, - StatusBarColorController statusBarColorController, AppMenuDelegate appMenuDelegate, + @Nullable StatusBarColorController statusBarColorController, + AppMenuDelegate appMenuDelegate, ActivityLifecycleDispatcher activityLifecycleDispatcher, @NonNull Supplier<Tab> startSurfaceParentTabSupplier, @NonNull BottomSheetController bottomSheetController,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlocker.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlocker.java index b2f943c..1b23af0 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlocker.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlocker.java
@@ -14,6 +14,8 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.OneShotCallback; import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.IntentHandler; import org.chromium.chrome.browser.homepage.HomepageManager; @@ -75,6 +77,7 @@ private final Supplier<Boolean> mIsTabletSupplier; private final Supplier<Boolean> mShouldShowOverviewPageOnStartSupplier; private final Supplier<Boolean> mIsInstantStartEnabledSupplier; + private final ObservableSupplier<Profile> mProfileSupplier; /** * An app draw blocker that takes care of blocking the draw when we are restoring tabs with @@ -112,6 +115,7 @@ @NonNull Supplier<Boolean> isTabletSupplier, @NonNull Supplier<Boolean> shouldShowTabSwitcherOnStartSupplier, @NonNull Supplier<Boolean> isInstantStartEnabledSupplier, + @NonNull ObservableSupplier<Profile> profileSupplier, @NonNull IncognitoRestoreAppLaunchDrawBlockerFactory incognitoRestoreAppLaunchDrawBlockerFactory) { mActivityLifecycleDispatcher = activityLifecycleDispatcher; @@ -142,6 +146,7 @@ mIsTabletSupplier = isTabletSupplier; mShouldShowOverviewPageOnStartSupplier = shouldShowTabSwitcherOnStartSupplier; mIsInstantStartEnabledSupplier = isInstantStartEnabledSupplier; + mProfileSupplier = profileSupplier; mIncognitoRestoreAppLaunchDrawBlocker = incognitoRestoreAppLaunchDrawBlockerFactory.create( intentSupplier, shouldIgnoreIntentSupplier, activityLifecycleDispatcher, this::onIncognitoRestoreUnblockConditionsFired); @@ -192,8 +197,10 @@ } private void writeSearchEngineHadLogoPref() { + Profile profile = mProfileSupplier.get(); + if (profile == null) return; boolean searchEngineHasLogo = - TemplateUrlServiceFactory.getForProfile(Profile.getLastUsedRegularProfile()) + TemplateUrlServiceFactory.getForProfile(profile.getOriginalProfile()) .doesDefaultSearchEngineHaveLogo(); SharedPreferencesManager.getInstance().writeBoolean( ChromePreferenceKeys.APP_LAUNCH_SEARCH_ENGINE_HAD_LOGO, searchEngineHasLogo); @@ -292,13 +299,22 @@ */ private void recordBlockDrawForInitialTabHistograms( boolean isTabRegularNtp, boolean isOverviewShownWithoutInstantStart) { + if (!mProfileSupplier.hasValue()) { + new OneShotCallback<>(mProfileSupplier, (profile) -> { + recordBlockDrawForInitialTabHistograms( + isTabRegularNtp, isOverviewShownWithoutInstantStart); + }); + return; + } + long durationDrawBlocked = SystemClock.elapsedRealtime() - mTimeStartedBlockingDrawForInitialTab; boolean singleUrlBarNtp = false; if (!isOverviewShownWithoutInstantStart) { boolean searchEngineHasLogo = - TemplateUrlServiceFactory.getForProfile(Profile.getLastUsedRegularProfile()) + TemplateUrlServiceFactory + .getForProfile(mProfileSupplier.get().getOriginalProfile()) .doesDefaultSearchEngineHaveLogo(); boolean singleUrlBarMode = NewTabPage.isInSingleUrlBarMode(mIsTabletSupplier.get(), searchEngineHasLogo);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java index 4c05fb7..c7053a39 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/RootUiCoordinator.java
@@ -7,6 +7,7 @@ import android.app.Fragment; import android.content.ComponentName; import android.content.Intent; +import android.graphics.Color; import android.graphics.Rect; import android.net.Uri; import android.os.Build; @@ -25,6 +26,7 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.content.res.AppCompatResources; +import org.chromium.base.BuildInfo; import org.chromium.base.Callback; import org.chromium.base.CallbackController; import org.chromium.base.TraceEvent; @@ -292,7 +294,8 @@ protected final Supplier<TabCreatorManager> mTabCreatorManagerSupplier; protected final FullscreenManager mFullscreenManager; protected final Supplier<CompositorViewHolder> mCompositorViewHolderSupplier; - protected final StatusBarColorController mStatusBarColorController; + @Nullable + protected StatusBarColorController mStatusBarColorController; protected final Supplier<SnackbarManager> mSnackbarManagerSupplier; protected final @ActivityType int mActivityType; protected final Supplier<Boolean> mIsInOverviewModeSupplier; @@ -482,10 +485,14 @@ DeviceFormFactor.isNonMultiDisplayContextOnTablet(activity), shouldAllowThemingInNightMode(), shouldAllowBrightThemeColors()); - mStatusBarColorController = new StatusBarColorController(mActivity.getWindow(), - DeviceFormFactor.isNonMultiDisplayContextOnTablet(/* Context */ mActivity), - mActivity, mStatusBarColorProvider, mLayoutManagerSupplier, - mActivityLifecycleDispatcher, mActivityTabProvider, mTopUiThemeColorProvider); + if (BuildInfo.getInstance().isAutomotive) { + StatusBarColorController.setStatusBarColor(mActivity.getWindow(), Color.BLACK); + } else { + mStatusBarColorController = new StatusBarColorController(mActivity.getWindow(), + DeviceFormFactor.isNonMultiDisplayContextOnTablet(/* Context */ mActivity), + mActivity, mStatusBarColorProvider, mLayoutManagerSupplier, + mActivityLifecycleDispatcher, mActivityTabProvider, mTopUiThemeColorProvider); + } mEphemeralTabCoordinatorSupplier = ephemeralTabCoordinatorSupplier; mPageZoomCoordinator = new PageZoomCoordinator(new PageZoomCoordinatorDelegate() { @@ -509,6 +516,7 @@ return mToolbarManager; } + @Nullable public StatusBarColorController getStatusBarColorController() { return mStatusBarColorController; } @@ -1270,7 +1278,9 @@ } protected void setStatusBarScrimFraction(float scrimFraction) { - mStatusBarColorController.setStatusBarScrimFraction(scrimFraction); + if (mStatusBarColorController != null) { + mStatusBarColorController.setStatusBarScrimFraction(scrimFraction); + } } protected void setLayoutStateProvider(LayoutStateProvider layoutStateProvider) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java index b5a595c..f1dae0a4 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ui/system/StatusBarColorController.java
@@ -13,6 +13,7 @@ import androidx.annotation.Nullable; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.BuildInfo; import org.chromium.base.CallbackController; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.chrome.R; @@ -425,6 +426,13 @@ * @param color The color that the status bar should be set to. */ public static void setStatusBarColor(Window window, @ColorInt int color) { + // The status bar should always be black in automotive devices to match the black back + // button toolbar. + if (BuildInfo.getInstance().isAutomotive) { + ApiCompatibilityUtils.setStatusBarColor(window, Color.BLACK); + ApiCompatibilityUtils.setStatusBarIconColor(window.getDecorView().getRootView(), false); + return; + } if (UiUtils.isSystemUiThemingDisabled()) return; final View root = window.getDecorView().getRootView();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderRowRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderRowRenderTest.java new file mode 100644 index 0000000..62e4c2b --- /dev/null +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderRowRenderTest.java
@@ -0,0 +1,233 @@ +// 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. + +package org.chromium.chrome.browser.bookmarks; + +import android.content.res.ColorStateList; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.drawable.BitmapDrawable; +import android.util.Pair; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.LinearLayout; + +import androidx.appcompat.content.res.AppCompatResources; +import androidx.test.filters.MediumTest; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TestRule; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import org.chromium.base.test.BaseActivityTestRule; +import org.chromium.base.test.params.ParameterAnnotations; +import org.chromium.base.test.params.ParameterAnnotations.UseRunnerDelegate; +import org.chromium.base.test.params.ParameterSet; +import org.chromium.base.test.params.ParameterizedRunner; +import org.chromium.base.test.util.Batch; +import org.chromium.base.test.util.CommandLineFlags; +import org.chromium.base.test.util.Feature; +import org.chromium.chrome.R; +import org.chromium.chrome.browser.bookmarks.BookmarkUiPrefs.BookmarkRowDisplayPref; +import org.chromium.chrome.browser.bookmarks.ImprovedBookmarkRowProperties.StartImageVisibility; +import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.test.ChromeJUnit4RunnerDelegate; +import org.chromium.chrome.test.util.ChromeRenderTestRule; +import org.chromium.chrome.test.util.browser.Features; +import org.chromium.components.bookmarks.BookmarkType; +import org.chromium.components.browser_ui.styles.ChromeColors; +import org.chromium.components.browser_ui.styles.SemanticColorUtils; +import org.chromium.components.payments.CurrencyFormatter; +import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.modelutil.PropertyModel; +import org.chromium.ui.modelutil.PropertyModelChangeProcessor; +import org.chromium.ui.test.util.BlankUiTestActivity; +import org.chromium.ui.test.util.DisableAnimationsTestRule; +import org.chromium.ui.test.util.NightModeTestUtils; +import org.chromium.ui.test.util.NightModeTestUtils.NightModeParams; + +import java.io.IOException; +import java.util.List; + +/** + * Render tests for the improved bookmark row. + */ +@RunWith(ParameterizedRunner.class) +@UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) +@CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@Batch(Batch.PER_CLASS) +public class ImprovedBookmarkFolderRowRenderTest { + @ParameterAnnotations.ClassParameter + private static List<ParameterSet> sClassParams = new NightModeParams().getParameters(); + + @Rule + public final DisableAnimationsTestRule mDisableAnimationsRule = new DisableAnimationsTestRule(); + + @Rule + public MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Rule + public BaseActivityTestRule<BlankUiTestActivity> mActivityTestRule = + new BaseActivityTestRule<>(BlankUiTestActivity.class); + + @Rule + public ChromeRenderTestRule mRenderTestRule = + ChromeRenderTestRule.Builder.withPublicCorpus() + .setBugComponent(ChromeRenderTestRule.Component.UI_BROWSER_BOOKMARKS) + .build(); + + @Rule + public TestRule mProcessor = new Features.JUnitProcessor(); + + @Mock + CurrencyFormatter mFormatter; + + private ImprovedBookmarkRow mView; + private PropertyModel mModel; + private Bitmap mPrimaryBitmap; + private Bitmap mSecondaryBitmap; + private BitmapDrawable mPrimaryDrawable; + private BitmapDrawable mSecondaryDrawable; + private LinearLayout mContentView; + + public ImprovedBookmarkFolderRowRenderTest(boolean nightModeEnabled) { + // Sets a fake background color to make the screenshots easier to compare with bare eyes. + NightModeTestUtils.setUpNightModeForBlankUiTestActivity(nightModeEnabled); + mRenderTestRule.setNightModeEnabled(nightModeEnabled); + } + + @Before + public void setUp() throws Exception { + mActivityTestRule.launchActivity(null); + mActivityTestRule.getActivity().setTheme(R.style.Theme_BrowserUI_DayNight); + + mPrimaryBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); + mPrimaryBitmap.eraseColor(Color.GREEN); + mPrimaryDrawable = + new BitmapDrawable(mActivityTestRule.getActivity().getResources(), mPrimaryBitmap); + + mSecondaryBitmap = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888); + mSecondaryBitmap.eraseColor(Color.RED); + mSecondaryDrawable = new BitmapDrawable( + mActivityTestRule.getActivity().getResources(), mSecondaryBitmap); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + mContentView = new LinearLayout(mActivityTestRule.getActivity()); + mContentView.setBackgroundColor(Color.WHITE); + + FrameLayout.LayoutParams params = new FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + mActivityTestRule.getActivity().setContentView(mContentView, params); + + mView = ImprovedBookmarkRow.buildView(mActivityTestRule.getActivity(), /*visual=*/true); + mContentView.addView(mView); + + mModel = new PropertyModel(ImprovedBookmarkRowProperties.ALL_KEYS); + PropertyModelChangeProcessor.create(mModel, mView, ImprovedBookmarkRowViewBinder::bind); + mModel.set(ImprovedBookmarkRowProperties.FOLDER_CHILD_COUNT, 5); + }); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testNoImage() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_VISIBILITY, + StartImageVisibility.FOLDER_DRAWABLE); + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_FOLDER_DRAWABLES, + new Pair<>(null, null)); + mModel.set(ImprovedBookmarkRowProperties.START_ICON_DRAWABLE, + BookmarkUtils.getFolderIcon(mActivityTestRule.getActivity(), + BookmarkType.NORMAL, BookmarkRowDisplayPref.VISUAL)); + mModel.set(ImprovedBookmarkRowProperties.START_AREA_BACKGROUND_COLOR, + ChromeColors.getSurfaceColor( + mActivityTestRule.getActivity(), R.dimen.default_elevation_1)); + mModel.set(ImprovedBookmarkRowProperties.START_ICON_TINT, + AppCompatResources.getColorStateList(mActivityTestRule.getActivity(), + R.color.default_icon_color_secondary_tint_list)); + }); + mRenderTestRule.render(mContentView, "no_image"); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testNoImage_readingList() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_VISIBILITY, + StartImageVisibility.FOLDER_DRAWABLE); + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_FOLDER_DRAWABLES, + new Pair<>(null, null)); + mModel.set(ImprovedBookmarkRowProperties.START_ICON_DRAWABLE, + BookmarkUtils.getFolderIcon(mActivityTestRule.getActivity(), + BookmarkType.READING_LIST, BookmarkRowDisplayPref.VISUAL)); + mModel.set(ImprovedBookmarkRowProperties.START_AREA_BACKGROUND_COLOR, + SemanticColorUtils.getColorPrimaryContainer(mActivityTestRule.getActivity())); + mModel.set(ImprovedBookmarkRowProperties.START_ICON_TINT, + ColorStateList.valueOf(SemanticColorUtils.getDefaultIconColorAccent1( + mActivityTestRule.getActivity()))); + }); + mRenderTestRule.render(mContentView, "no_image_reading_list"); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testOneImage() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_VISIBILITY, + StartImageVisibility.FOLDER_DRAWABLE); + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_FOLDER_DRAWABLES, + new Pair<>(mPrimaryDrawable, null)); + }); + mRenderTestRule.render(mContentView, "one_image"); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testTwoImages() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_VISIBILITY, + StartImageVisibility.FOLDER_DRAWABLE); + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_FOLDER_DRAWABLES, + new Pair<>(mPrimaryDrawable, mSecondaryDrawable)); + }); + mRenderTestRule.render(mContentView, "two_images"); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testTwoImages_99Children() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_VISIBILITY, + StartImageVisibility.FOLDER_DRAWABLE); + mModel.set(ImprovedBookmarkRowProperties.FOLDER_CHILD_COUNT, 99); + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_FOLDER_DRAWABLES, + new Pair<>(mPrimaryDrawable, mSecondaryDrawable)); + }); + mRenderTestRule.render(mContentView, "two_images_99_children"); + } + + @Test + @MediumTest + @Feature({"RenderTest"}) + public void testTwoImages_999Children() throws IOException { + TestThreadUtils.runOnUiThreadBlocking(() -> { + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_VISIBILITY, + StartImageVisibility.FOLDER_DRAWABLE); + mModel.set(ImprovedBookmarkRowProperties.FOLDER_CHILD_COUNT, 999); + mModel.set(ImprovedBookmarkRowProperties.START_IMAGE_FOLDER_DRAWABLES, + new Pair<>(mPrimaryDrawable, mSecondaryDrawable)); + }); + mRenderTestRule.render(mContentView, "two_images_999_children"); + } +}
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowRenderTest.java similarity index 90% rename from chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewRenderTest.java rename to chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowRenderTest.java index 35d8a73d..f9d0aa2 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowRenderTest.java
@@ -53,11 +53,11 @@ import java.util.Arrays; import java.util.List; -/** Render tests for the {@link ImprovedBookmarkFolderSelectView}. */ +/** Render tests for the {@link ImprovedBookmarkFolderSelectRow}. */ @RunWith(ParameterizedRunner.class) @ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) @Batch(Batch.PER_CLASS) -public class ImprovedBookmarkFolderSelectViewRenderTest { +public class ImprovedBookmarkFolderSelectRowRenderTest { private static final String TITLE = "Test title"; private static final String READING_LIST_TITLE = "Reading list"; private static final int CHILD_COUNT = 5; @@ -99,9 +99,9 @@ private Drawable mDrawable; private LinearLayout mContentView; - private ImprovedBookmarkFolderSelectView mView; + private ImprovedBookmarkFolderSelectRow mView; - public ImprovedBookmarkFolderSelectViewRenderTest(boolean nightModeEnabled) { + public ImprovedBookmarkFolderSelectRowRenderTest(boolean nightModeEnabled) { // Sets a fake background color to make the screenshots easier to compare with bare eyes. NightModeTestUtils.setUpNightModeForBlankUiTestActivity(nightModeEnabled); mRenderTestRule.setNightModeEnabled(nightModeEnabled); @@ -149,7 +149,7 @@ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); mActivityTestRule.getActivity().setContentView(mContentView, params); - mView = (ImprovedBookmarkFolderSelectView) LayoutInflater + mView = (ImprovedBookmarkFolderSelectRow) LayoutInflater .from(mActivityTestRule.getActivity()) .inflate(R.layout.improved_bookmark_folder_select_layout, null); mContentView.addView(mView); @@ -161,8 +161,8 @@ @Feature({"RenderTest"}) public void testNormal() throws IOException { TestThreadUtils.runOnUiThreadBlocking(() -> { - ImprovedBookmarkFolderSelectViewCoordinator coordinator = - new ImprovedBookmarkFolderSelectViewCoordinator(mActivityTestRule.getActivity(), + ImprovedBookmarkFolderSelectRowCoordinator coordinator = + new ImprovedBookmarkFolderSelectRowCoordinator(mActivityTestRule.getActivity(), mView, mBookmarkImageFetcher, mFolderId, mBookmarkModel); }); mRenderTestRule.render(mContentView, "normal"); @@ -176,8 +176,8 @@ .when(mBookmarkModel) .getTopLevelFolderIds(anyBoolean(), anyBoolean()); TestThreadUtils.runOnUiThreadBlocking(() -> { - ImprovedBookmarkFolderSelectViewCoordinator coordinator = - new ImprovedBookmarkFolderSelectViewCoordinator(mActivityTestRule.getActivity(), + ImprovedBookmarkFolderSelectRowCoordinator coordinator = + new ImprovedBookmarkFolderSelectRowCoordinator(mActivityTestRule.getActivity(), mView, mBookmarkImageFetcher, mFolderId, mBookmarkModel); }); mRenderTestRule.render(mContentView, "top_level_folder"); @@ -191,8 +191,8 @@ .when(mBookmarkModel) .getTopLevelFolderIds(anyBoolean(), anyBoolean()); TestThreadUtils.runOnUiThreadBlocking(() -> { - ImprovedBookmarkFolderSelectViewCoordinator coordinator = - new ImprovedBookmarkFolderSelectViewCoordinator(mActivityTestRule.getActivity(), + ImprovedBookmarkFolderSelectRowCoordinator coordinator = + new ImprovedBookmarkFolderSelectRowCoordinator(mActivityTestRule.getActivity(), mView, mBookmarkImageFetcher, mReadingListFolderId, mBookmarkModel); }); mRenderTestRule.render(mContentView, "reading_list");
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityTest.java index 1d218518..c1657c6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/device_lock/DeviceLockActivityTest.java
@@ -9,9 +9,11 @@ import static androidx.test.espresso.matcher.ViewMatchers.withText; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import android.app.Activity; import android.content.Intent; +import android.os.Bundle; import androidx.test.core.app.ActivityScenario; import androidx.test.filters.MediumTest; @@ -26,6 +28,9 @@ import org.chromium.base.test.util.DoNotBatch; import org.chromium.chrome.R; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; +import org.chromium.ui.base.IntentRequestTracker; + +import java.lang.ref.WeakReference; /** * Tests for the {@link DeviceLockActivity}. @@ -69,6 +74,20 @@ ApplicationTestUtils.waitForActivityState(mDeviceLockActivity, Stage.DESTROYED); } + @Test + @MediumTest + public void testOnActivityResult_passesActivityResultToWindowAndroid() { + launchActivity(); + MockIntentRequestTracker mockIntentRequestTracker = new MockIntentRequestTracker(); + mDeviceLockActivity.setIntentRequestTrackerForTesting(mockIntentRequestTracker); + + int testRequestCode = 1; + Intent data = new Intent(); + mDeviceLockActivity.onActivityResult(testRequestCode, Activity.RESULT_OK, data); + + assertTrue(mockIntentRequestTracker.mOnActivityResultCalled); + } + public void launchActivity() { Intent intent = DeviceLockActivity.createIntent( ContextUtils.getApplicationContext(), true, "testSelectedAccount"); @@ -77,4 +96,27 @@ mActivityScenario.onActivity(activity -> mDeviceLockActivity = activity); ApplicationTestUtils.waitForActivityState(mDeviceLockActivity, Stage.RESUMED); } + + private class MockIntentRequestTracker implements IntentRequestTracker { + boolean mOnActivityResultCalled; + + MockIntentRequestTracker() {} + + @Override + public boolean onActivityResult(int requestCode, int resultCode, Intent data) { + mOnActivityResultCalled = true; + return true; + } + + @Override + public WeakReference<Activity> getActivity() { + return null; + } + + @Override + public void saveInstanceState(Bundle bundle) {} + + @Override + public void restoreInstanceState(Bundle bundle) {} + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/FullscreenVideoPictureInPictureControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/FullscreenVideoPictureInPictureControllerTest.java index 967749d..8321304 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/FullscreenVideoPictureInPictureControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/media/ui/FullscreenVideoPictureInPictureControllerTest.java
@@ -104,6 +104,13 @@ public void testEnterPip() throws Throwable { enterFullscreen(); triggerAutoPiPAndWait(); + + // Exit Picture in Picture. + AsyncInitializationActivity.interceptMoveTaskToBackForTesting(); + TestThreadUtils.runOnUiThreadBlocking( + () -> InstrumentationRegistry.getInstrumentation().callActivityOnStop(mActivity)); + CriteriaHelper.pollUiThread( + AsyncInitializationActivity::wasMoveTaskToBackInterceptedForTesting); } /** Tests that PiP is left when we navigate the main page. */ @@ -278,4 +285,29 @@ mNavigationOccurred = true; } } + + /** Tests that we exit PiP whe device is locked. */ + @Test + @MediumTest + @MinAndroidSdkLevel(Build.VERSION_CODES.O) + public void testExitPipWhenDeviceLocked() throws Throwable { + AsyncInitializationActivity.interceptMoveTaskToBackForTesting(); + enterFullscreen(); + triggerAutoPiPAndWait(); + + // Ensure that we entered Picture in Picture. + Assert.assertTrue( + TestThreadUtils.runOnUiThreadBlocking(mActivity::isInPictureInPictureMode)); + + // Call activity OnStop. This simulates user locking the device. + TestThreadUtils.runOnUiThreadBlocking( + () -> InstrumentationRegistry.getInstrumentation().callActivityOnStop(mActivity)); + + CriteriaHelper.pollUiThread( + AsyncInitializationActivity::wasMoveTaskToBackInterceptedForTesting); + // This logic would run if we hadn't intercepted moveTaskToBack (which is how PiP gets + // exited), we run it now for completion and proceed to ensure we exited Picture in Picture. + mActivity.onPictureInPictureModeChanged(false, mActivity.getResources().getConfiguration()); + CriteriaHelper.pollUiThread(() -> !mActivity.getLastPictureInPictureModeForTesting()); + } }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxActionsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxActionsTest.java index 7cfe410..a35980c8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxActionsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxActionsTest.java
@@ -165,14 +165,15 @@ } private AutocompleteMatch createDummyHistoryClustersAction(String name) { - return createDummySuggestion(List.of(new HistoryClustersAction(0, "hint", name))); + return createDummySuggestion( + List.of(new HistoryClustersAction(0, "hint", "accessibility", name))); } private AutocompleteMatch createDummyActionInSuggest(ActionInfo.ActionType... types) { var actions = new ArrayList<OmniboxAction>(); for (var type : types) { - actions.add(new OmniboxActionInSuggest( - type.getNumber(), "hint", type.getNumber(), "https://www.google.com")); + actions.add(new OmniboxActionInSuggest(type.getNumber(), "hint", "accessibility", + type.getNumber(), "https://www.google.com")); } return createDummySuggestion(actions);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java index fee9951..d37b2e6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsRenderTest.java
@@ -109,7 +109,7 @@ private AutocompleteMatch createDummyPedalSuggestion(String name, @OmniboxPedalId int id) { return AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.SEARCH_SUGGEST) .setDisplayText(name) - .setActions(List.of(new OmniboxPedal(0, "hint", id))) + .setActions(List.of(new OmniboxPedal(0, "hint", "accessibility", id))) .build(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java index 06def94..ffb0e04 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxPedalsTest.java
@@ -257,7 +257,7 @@ private AutocompleteMatch createDummyPedalSuggestion(String name, @OmniboxPedalId int id) { return AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.SEARCH_SUGGEST) .setDisplayText(name) - .setActions(List.of(new OmniboxPedal(0, "hint", id))) + .setActions(List.of(new OmniboxPedal(0, "hint", "accessibility", id))) .build(); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentManifestDownloaderTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentManifestDownloaderTest.java index 31d5299..1f624d3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentManifestDownloaderTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentManifestDownloaderTest.java
@@ -151,8 +151,9 @@ CriteriaHelper.pollInstrumentationThread(() -> mDownloadComplete); Assert.assertTrue("Web app manifest should not have been downloaded.", mDownloadFailure); - Assert.assertEquals( - "Unable to download payment manifest \"" + url.getSpec() + "\".", mErrorMessage); + Assert.assertEquals("Unable to download payment manifest \"" + url.getSpec() + + "\". HTTP 404 Not Found.", + mErrorMessage); } @Test @@ -183,8 +184,9 @@ Assert.assertTrue( "Payment method manifest should have not have been downloaded.", mDownloadFailure); - Assert.assertEquals( - "Unable to download payment manifest \"" + url.getSpec() + "\".", mErrorMessage); + Assert.assertEquals("Unable to download payment manifest \"" + url.getSpec() + + "\". HTTP 404 Not Found.", + mErrorMessage); } @Test
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java index 49dbc176..0a7a21e 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ui/system/StatusBarColorControllerTest.java
@@ -5,12 +5,14 @@ package org.chromium.chrome.browser.ui.system; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; import android.app.Activity; import android.graphics.Color; import androidx.annotation.ColorInt; import androidx.test.filters.LargeTest; +import androidx.test.filters.SmallTest; import org.hamcrest.Matchers; import org.junit.Assert; @@ -48,6 +50,7 @@ import org.chromium.chrome.test.util.browser.ThemeTestUtils; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.test.util.DeviceRestriction; import org.chromium.ui.test.util.DisableAnimationsTestRule; import org.chromium.ui.test.util.UiRestriction; import org.chromium.ui.util.ColorUtils; @@ -360,6 +363,25 @@ activity.getWindow().getStatusBarColor()); } + /** + * Test status bar is always black in Automotive devices. + */ + @Test + @SmallTest + @Feature({"StatusBar, Automotive Toolbar"}) + @Restriction(DeviceRestriction.RESTRICTION_TYPE_AUTO) + public void testStatusBarBlackInAutomotive() { + final ChromeActivity activity = sActivityTestRule.getActivity(); + final StatusBarColorController statusBarColorController = + sActivityTestRule.getActivity() + .getRootUiCoordinatorForTesting() + .getStatusBarColorController(); + + assertNull(statusBarColorController); + assertEquals("Status bar should always be black in automotive devices.", Color.BLACK, + activity.getWindow().getStatusBarColor()); + } + private int getScrimmedColor(@ColorInt int color, float fraction) { final float scrimColorAlpha = (mScrimColor >>> 24) / 255f; final int scrimColorOpaque = mScrimColor | 0xFF000000;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java index 15efd3f..2d25065 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeActionModeHandlerUnitTest.java
@@ -226,7 +226,7 @@ } private void addMenuItem(Menu menu, int order, String packageName) { - menu.add(R.id.select_action_menu_text_processing_menus, Menu.NONE, order, "title") + menu.add(R.id.select_action_menu_text_processing_items, Menu.NONE, order, "title") .setIntent(new Intent() .setAction(Intent.ACTION_PROCESS_TEXT) .setType("text/plain")
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinatorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinatorTest.java similarity index 78% rename from chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinatorTest.java rename to chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinatorTest.java index 71f7cb6..353e23be 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectViewCoordinatorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/bookmarks/ImprovedBookmarkFolderSelectRowCoordinatorTest.java
@@ -44,11 +44,11 @@ import java.util.Arrays; -/** Unit tests for {@link ImprovedBookmarkFolderSelectViewCoordinator}. */ +/** Unit tests for {@link ImprovedBookmarkFolderSelectRowCoordinator}. */ @Batch(Batch.UNIT_TESTS) @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class ImprovedBookmarkFolderSelectViewCoordinatorTest { +public class ImprovedBookmarkFolderSelectRowCoordinatorTest { private static final String TITLE = "Test title"; private static final String READING_LIST_TITLE = "Reading list"; private static final int CHILD_COUNT = 5; @@ -73,7 +73,7 @@ false, 0, false); @Mock - private ImprovedBookmarkFolderSelectView mView; + private ImprovedBookmarkFolderSelectRow mView; @Mock private BookmarkImageFetcher mBookmarkImageFetcher; @Mock @@ -107,21 +107,21 @@ @Test public void testConstructor_withImages() { - ImprovedBookmarkFolderSelectViewCoordinator coordinator = - new ImprovedBookmarkFolderSelectViewCoordinator( + ImprovedBookmarkFolderSelectRowCoordinator coordinator = + new ImprovedBookmarkFolderSelectRowCoordinator( mActivity, mView, mBookmarkImageFetcher, mFolderId, mBookmarkModel); PropertyModel model = coordinator.getModel(); - assertEquals(TITLE, model.get(ImprovedBookmarkFolderSelectViewProperties.TITLE)); + assertEquals(TITLE, model.get(ImprovedBookmarkFolderSelectRowProperties.TITLE)); assertEquals(CHILD_COUNT, - model.get(ImprovedBookmarkFolderSelectViewProperties.FOLDER_CHILD_COUNT)); + model.get(ImprovedBookmarkFolderSelectRowProperties.FOLDER_CHILD_COUNT)); assertNotNull( - model.get(ImprovedBookmarkFolderSelectViewProperties.START_AREA_BACKGROUND_COLOR)); - assertNotNull(model.get(ImprovedBookmarkFolderSelectViewProperties.START_ICON_DRAWABLE)); - assertNotNull(model.get(ImprovedBookmarkFolderSelectViewProperties.START_ICON_TINT)); - assertTrue(model.get(ImprovedBookmarkFolderSelectViewProperties.END_ICON_VISIBLE)); + model.get(ImprovedBookmarkFolderSelectRowProperties.START_AREA_BACKGROUND_COLOR)); + assertNotNull(model.get(ImprovedBookmarkFolderSelectRowProperties.START_ICON_DRAWABLE)); + assertNotNull(model.get(ImprovedBookmarkFolderSelectRowProperties.START_ICON_TINT)); + assertTrue(model.get(ImprovedBookmarkFolderSelectRowProperties.END_ICON_VISIBLE)); assertEquals(new Pair<>(mDrawable, mDrawable), - model.get(ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES)); + model.get(ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES)); verify(mView).setTitle(TITLE); verify(mView).setStartAreaBackgroundColor(anyInt()); @@ -141,12 +141,12 @@ -> callback.onResult(new Pair<>(null, null))) .when(mBookmarkImageFetcher) .fetchFirstTwoImagesForFolder(any(), any()); - ImprovedBookmarkFolderSelectViewCoordinator coordinator = - new ImprovedBookmarkFolderSelectViewCoordinator( + ImprovedBookmarkFolderSelectRowCoordinator coordinator = + new ImprovedBookmarkFolderSelectRowCoordinator( mActivity, mView, mBookmarkImageFetcher, mFolderId, mBookmarkModel); PropertyModel model = coordinator.getModel(); assertEquals(new Pair<>(null, null), - model.get(ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES)); + model.get(ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES)); } @Test @@ -154,12 +154,12 @@ doReturn(Arrays.asList(mFolderId)) .when(mBookmarkModel) .getTopLevelFolderIds(anyBoolean(), anyBoolean()); - ImprovedBookmarkFolderSelectViewCoordinator coordinator = - new ImprovedBookmarkFolderSelectViewCoordinator( + ImprovedBookmarkFolderSelectRowCoordinator coordinator = + new ImprovedBookmarkFolderSelectRowCoordinator( mActivity, mView, mBookmarkImageFetcher, mFolderId, mBookmarkModel); PropertyModel model = coordinator.getModel(); assertEquals(new Pair<>(null, null), - model.get(ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES)); + model.get(ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES)); } @Test @@ -167,16 +167,16 @@ doReturn(Arrays.asList(mReadingListFolderId)) .when(mBookmarkModel) .getTopLevelFolderIds(anyBoolean(), anyBoolean()); - ImprovedBookmarkFolderSelectViewCoordinator coordinator = - new ImprovedBookmarkFolderSelectViewCoordinator(mActivity, mView, + ImprovedBookmarkFolderSelectRowCoordinator coordinator = + new ImprovedBookmarkFolderSelectRowCoordinator(mActivity, mView, mBookmarkImageFetcher, mReadingListFolderId, mBookmarkModel); PropertyModel model = coordinator.getModel(); assertEquals( - READING_LIST_TITLE, model.get(ImprovedBookmarkFolderSelectViewProperties.TITLE)); + READING_LIST_TITLE, model.get(ImprovedBookmarkFolderSelectRowProperties.TITLE)); assertEquals(READING_LIST_CHILD_COUNT, - model.get(ImprovedBookmarkFolderSelectViewProperties.FOLDER_CHILD_COUNT)); + model.get(ImprovedBookmarkFolderSelectRowProperties.FOLDER_CHILD_COUNT)); assertEquals(new Pair<>(null, null), - model.get(ImprovedBookmarkFolderSelectViewProperties.START_IMAGE_FOLDER_DRAWABLES)); + model.get(ImprovedBookmarkFolderSelectRowProperties.START_IMAGE_FOLDER_DRAWABLES)); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java index ec849db..7941c75 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/ScrollingStripStackerUnitTest.java
@@ -59,7 +59,7 @@ @Test public void testSetTabOffsets_tabNotClosing() { - mTarget.setTabOffsets(2, mInput, 0, 0, 0, 0, 0, 0, false, false, false, CACHED_TAB_WIDTH); + mTarget.setTabOffsets(mInput, false, false, CACHED_TAB_WIDTH); float expected_x = 0; for (StripLayoutTab tab : mInput) { @@ -74,8 +74,7 @@ @Test public void testSetTabOffsets_tabClosing() { - mTarget.setTabOffsets( - 2, mInput, 0, 0, 0, 0, 0, STRIP_WIDTH, false, true, false, CACHED_TAB_WIDTH); + mTarget.setTabOffsets(mInput, true, false, CACHED_TAB_WIDTH); for (StripLayoutTab tab : mInput) { verify(tab).setDrawY(TAB_OFFSET_Y); @@ -88,8 +87,7 @@ @Test public void testSetTabOffsets_tabCreating() { - mTarget.setTabOffsets( - 2, mInput, 0, 0, 0, 0, 0, STRIP_WIDTH, false, false, true, CACHED_TAB_WIDTH); + mTarget.setTabOffsets(mInput, false, true, CACHED_TAB_WIDTH); float expected_x = 0; for (StripLayoutTab tab : mInput) { @@ -107,7 +105,7 @@ @Test public void testPerformOcclusionPass() { - mTarget.performOcclusionPass(2, mInput, 2 * TAB_WIDTH); + mTarget.performOcclusionPass(mInput, 2 * TAB_WIDTH); for (StripLayoutTab tab : mInput) { if (tab == mTab1 || tab == mTab5) {
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java index 0dcc51b..fe92a489 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -1036,8 +1036,8 @@ // Act: Set scroll offset greater than -960. mStripLayoutHelper.testSetScrollOffset(-800); - // Assert: Expand duration is 250. - assertEquals(mStripLayoutHelper.getExpandDurationForTesting(), 250); + // Assert: Scroll duration is 250. + assertEquals(mStripLayoutHelper.getScrollDurationForTesting(), 250); } @Test @@ -1047,8 +1047,8 @@ // Act: Set scroll offset between -960 and -1920. mStripLayoutHelper.testSetScrollOffset(-1000); - // Assert: Expand duration is 350. - assertEquals(mStripLayoutHelper.getExpandDurationForTesting(), 350); + // Assert: Scroll duration is 350. + assertEquals(mStripLayoutHelper.getScrollDurationForTesting(), 350); } @Test @@ -1058,8 +1058,8 @@ // Act: Set scroll offset less than -1920 mStripLayoutHelper.testSetScrollOffset(-2000); - // Assert: Expand duration is 450. - assertEquals(mStripLayoutHelper.getExpandDurationForTesting(), 450); + // Assert: Scroll duration is 450. + assertEquals(mStripLayoutHelper.getScrollDurationForTesting(), 450); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java index 08487fa..80c51d8d 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripStackerUnitTest.java
@@ -99,14 +99,10 @@ class DummyStacker extends StripStacker { @Override - public void setTabOffsets(int selectedIndex, StripLayoutTab[] indexOrderedTabs, - float tabStackWidth, int maxTabsToStack, float tabOverlapWidth, - float stripLeftMargin, float stripRightMargin, float stripWidth, - boolean inReorderMode, boolean tabClosing, boolean tabCreating, - float cachedTabWidth) {} + public void setTabOffsets(StripLayoutTab[] indexOrderedTabs, boolean tabClosing, + boolean tabCreating, float cachedTabWidth) {} @Override - public void performOcclusionPass( - int selectedIndex, StripLayoutTab[] indexOrderedTabs, float stripWidth) {} + public void performOcclusionPass(StripLayoutTab[] indexOrderedTabs, float stripWidth) {} } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java index 642fd2ac..8024112 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayerTest.java
@@ -174,6 +174,7 @@ mStripLayoutTab.getContentOffsetY() * mDpToPx, mStripLayoutTab.getDividerOffsetX() * mDpToPx, mStripLayoutTab.getBottomMargin() * mDpToPx, + mStripLayoutTab.getTopMargin() * mDpToPx, mStripLayoutTab.getCloseButtonPadding() * mDpToPx, mStripLayoutTab.getCloseButton().getOpacity(), mStripLayoutTab.isStartDividerVisible(),
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java index 969ed423..28544f8 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/fullscreen/FullscreenHtmlApiHandlerUnitTest.java
@@ -6,15 +6,12 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.app.Activity; -import android.graphics.Rect; import android.view.View.OnLayoutChangeListener; import org.junit.Assert; @@ -35,14 +32,11 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.cc.input.BrowserControlsState; import org.chromium.chrome.browser.ActivityTabProvider; -import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabAttributes; import org.chromium.chrome.browser.tab.TabBrowserControlsConstraintsHelper; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.test.util.browser.Features; -import org.chromium.chrome.test.util.browser.Features.DisableFeatures; -import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.components.browser_ui.util.DimensionCompat; import org.chromium.components.embedder_support.view.ContentView; import org.chromium.content_public.browser.WebContents; @@ -51,7 +45,6 @@ * Unit tests for {@link FullscreenHtmlApiHandler}. */ @RunWith(BaseRobolectricTestRunner.class) -@EnableFeatures({ChromeFeatureList.ANDROID_WIDGET_FULLSCREEN_TOAST}) public class FullscreenHtmlApiHandlerUnitTest { private static final int DEVICE_WIDTH = 900; private static final int DEVICE_HEIGHT = 1600; @@ -212,6 +205,41 @@ } @Test + public void testFullscreenObserverCalledOncePerSessionWhenWebContentsNotNull() { + doReturn(mWebContents).when(mTab).getWebContents(); + doReturn(mContentView).when(mTab).getContentView(); + doReturn(true).when(mTab).isUserInteractable(); + doReturn(true).when(mTab).isHidden(); + doReturn(true).when(mContentView).hasWindowFocus(); + mAreControlsHidden.set(true); + + mFullscreenHtmlApiHandler.setTabForTesting(mTab); + FullscreenManager.Observer observer = Mockito.mock(FullscreenManager.Observer.class); + mFullscreenHtmlApiHandler.addObserver(observer); + FullscreenOptions fullscreenOptions = new FullscreenOptions(false, false); + + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); + verify(observer, times(1)).onEnterFullscreen(mTab, fullscreenOptions); + + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + verify(observer, times(1)).onExitFullscreen(mTab); + + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); + verify(observer, times(2)).onEnterFullscreen(mTab, fullscreenOptions); + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + verify(observer, times(2)).onExitFullscreen(mTab); + + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); + verify(observer, times(3)).onEnterFullscreen(mTab, fullscreenOptions); + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + verify(observer, times(3)).onExitFullscreen(mTab); + } + + @Test public void testNoObserverWhenCanceledBeforeBeingInteractable() { // avoid calling GestureListenerManager/SelectionPopupController doReturn(null).when(mTab).getWebContents(); @@ -258,18 +286,7 @@ } @Test - @EnableFeatures({ChromeFeatureList.ANDROID_WIDGET_FULLSCREEN_TOAST}) - public void testToastIsShownInFullscreenButNotPictureInPicture_AndroidWidgetToast() { - testToastIsShownInFullscreenButNotPictureInPicture(); - } - - @Test - @DisableFeatures({ChromeFeatureList.ANDROID_WIDGET_FULLSCREEN_TOAST}) - public void testToastIsShownInFullscreenButNotPictureInPicture_CustomViewToast() { - testToastIsShownInFullscreenButNotPictureInPicture(); - } - - private void testToastIsShownInFullscreenButNotPictureInPicture() { + public void testToastIsShownInFullscreenButNotPictureInPicture() { doReturn(mWebContents).when(mTab).getWebContents(); doReturn(mContentView).when(mTab).getContentView(); doReturn(true).when(mTab).isUserInteractable(); @@ -321,18 +338,7 @@ } @Test - @EnableFeatures({ChromeFeatureList.ANDROID_WIDGET_FULLSCREEN_TOAST}) - public void testToastIsShownAtLayoutChangeWithRotation_AndroidWidgetToast() { - testToastIsShownAtLayoutChangeWithRotation(); - } - - @Test - @DisableFeatures({ChromeFeatureList.ANDROID_WIDGET_FULLSCREEN_TOAST}) - public void testToastIsShownAtLayoutChangeWithRotation_CustomViewToast() { - testToastIsShownAtLayoutChangeWithRotation(); - } - - private void testToastIsShownAtLayoutChangeWithRotation() { + public void testToastIsShownAtLayoutChangeWithRotation() { doReturn(mWebContents).when(mTab).getWebContents(); doReturn(mContentView).when(mTab).getContentView(); doReturn(true).when(mTab).isUserInteractable(); @@ -359,46 +365,59 @@ } @Test - @DisableFeatures({ChromeFeatureList.ANDROID_WIDGET_FULLSCREEN_TOAST}) - public void testToastRepositionsUponWindowLayoutChange() { + public void testFullscreenObserverNotifiedWhenActivityStopped() { + mFullscreenHtmlApiHandler = + new FullscreenHtmlApiHandler(mActivity, mAreControlsHidden, true) { + @Override + public void destroySelectActionMode(Tab tab) {} + }; + doReturn(mWebContents).when(mTab).getWebContents(); doReturn(mContentView).when(mTab).getContentView(); doReturn(true).when(mTab).isUserInteractable(); doReturn(true).when(mTab).isHidden(); doReturn(true).when(mContentView).hasWindowFocus(); - doReturn(SYSTEM_UI_HEIGHT).when(mDimensionCompat).getNavbarHeight(); - final int contentHeight = DEVICE_HEIGHT - SYSTEM_UI_HEIGHT; - doReturn(contentHeight).when(mContentView).getHeight(); - final Rect windowBounds = new Rect(0, 0, 800, contentHeight); - doAnswer(invocation -> { - Rect paramRect = invocation.getArgument(0); - paramRect.set(windowBounds); - return null; - }) - .when(mContentView) - .getWindowVisibleDisplayFrame(any(Rect.class)); mAreControlsHidden.set(true); + mFullscreenHtmlApiHandler.setTabForTesting(mTab); - mFullscreenHtmlApiHandler.setVersionCompatForTesting(mDimensionCompat); + FullscreenManager.Observer observer = Mockito.mock(FullscreenManager.Observer.class); + mFullscreenHtmlApiHandler.addObserver(observer); FullscreenOptions fullscreenOptions = new FullscreenOptions(false, false); + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); - var arg = ArgumentCaptor.forClass(OnLayoutChangeListener.class); - verify(mContentView).addOnLayoutChangeListener(arg.capture()); - arg.getValue().onLayoutChange(mContentView, 0, 0, DEVICE_WIDTH, DEVICE_HEIGHT, 0, 0, 0, 0); - mFullscreenHtmlApiHandler.triggerWindowLayoutChangeForTesting(); - assertEquals(SYSTEM_UI_HEIGHT, mFullscreenHtmlApiHandler.getToastBottomMarginForTesting()); + verify(observer, times(1)).onEnterFullscreen(mTab, fullscreenOptions); - // Verify that the toast has a bigger margin that puts it up above the OSK. - final int oskHeight = 800; - final int windowHeightWithOsk = contentHeight - oskHeight; - windowBounds.bottom = windowHeightWithOsk; - mFullscreenHtmlApiHandler.triggerWindowLayoutChangeForTesting(); - assertEquals(oskHeight, mFullscreenHtmlApiHandler.getToastBottomMarginForTesting()); + mFullscreenHtmlApiHandler.onActivityStateChange(mActivity, ActivityState.STOPPED); + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + verify(observer, times(1)).onExitFullscreen(mTab); + } - // Verify that the toast returns to the original position when the OSK is gone. - windowBounds.bottom = contentHeight; - mFullscreenHtmlApiHandler.triggerWindowLayoutChangeForTesting(); - assertEquals(SYSTEM_UI_HEIGHT, mFullscreenHtmlApiHandler.getToastBottomMarginForTesting()); + @Test + public void testFullscreenObserverCalledOnceWhenExitPersistentFullscreenModeCalled() { + doReturn(mWebContents).when(mTab).getWebContents(); + doReturn(mContentView).when(mTab).getContentView(); + doReturn(true).when(mTab).isUserInteractable(); + doReturn(true).when(mTab).isHidden(); + doReturn(true).when(mContentView).hasWindowFocus(); + mAreControlsHidden.set(true); + + mFullscreenHtmlApiHandler.setTabForTesting(mTab); + + FullscreenManager.Observer observer = Mockito.mock(FullscreenManager.Observer.class); + mFullscreenHtmlApiHandler.addObserver(observer); + FullscreenOptions fullscreenOptions = new FullscreenOptions(false, false); + + // Enter full screen. + mFullscreenHtmlApiHandler.onEnterFullscreen(mTab, fullscreenOptions); + verify(observer, times(1)).onEnterFullscreen(mTab, fullscreenOptions); + + // Call exitPersistentFullscreenMode followed by onExitFullscreen. Observers should be + // notified once. + mFullscreenHtmlApiHandler.exitPersistentFullscreenMode(); + mFullscreenHtmlApiHandler.exitPersistentFullscreenMode(); + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + mFullscreenHtmlApiHandler.onExitFullscreen(mTab); + verify(observer, times(1)).onExitFullscreen(mTab); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java b/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java index 0315ab4..bcaf5b5c 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/history/HistoryUITest.java
@@ -52,10 +52,12 @@ import org.chromium.base.Promise; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.R; -import org.chromium.chrome.browser.BackPressHelper; import org.chromium.chrome.browser.IntentHandler; +import org.chromium.chrome.browser.back_press.BackPressHelper; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.history_clusters.HistoryClustersBridge; import org.chromium.chrome.browser.history_clusters.HistoryClustersCoordinator; @@ -203,10 +205,11 @@ // Some individual tests may override to enable this feature which is disabled by // the class by default. if (ChromeFeatureList.isEnabled(ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY)) { - BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mHistoryManager); + BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mHistoryManager, + SecondaryActivity.HISTORY); } else { - BackPressHelper.create( - mLifecycleOwner, mOnBackPressedDispatcher, mHistoryManager::onBackPressed); + BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, + mHistoryManager::onBackPressed, SecondaryActivity.HISTORY); } } @@ -478,6 +481,7 @@ @Test @SmallTest + @DisableFeatures({ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY}) public void testSearchViewDismissedByBackPress() { final HistoryManagerToolbar toolbar = mHistoryManager.getToolbarForTests(); View toolbarShadow = mHistoryManager.getSelectableListLayout().getToolbarShadowForTests(); @@ -494,17 +498,23 @@ Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility()); // Press back press to unselect item and the search view is showing again. + var backPressRecorder = HistogramWatcher.newSingleRecordWatcher( + "Android.BackPress.SecondaryActivity", SecondaryActivity.HISTORY); Assert.assertTrue(mHistoryManager.getHandleBackPressChangedSupplier().get()); TestThreadUtils.runOnUiThreadBlocking(mOnBackPressedDispatcher::onBackPressed); Assert.assertFalse(mHistoryManager.getSelectionDelegateForTests().isSelectionEnabled()); Assert.assertEquals(View.GONE, toolbarShadow.getVisibility()); Assert.assertEquals(View.VISIBLE, toolbarSearchView.getVisibility()); + backPressRecorder.assertExpected(); // Press back to close the search view. + var backPressRecorder2 = HistogramWatcher.newSingleRecordWatcher( + "Android.BackPress.SecondaryActivity", SecondaryActivity.HISTORY); Assert.assertTrue(mHistoryManager.getHandleBackPressChangedSupplier().get()); TestThreadUtils.runOnUiThreadBlocking(mOnBackPressedDispatcher::onBackPressed); Assert.assertEquals(View.GONE, toolbarShadow.getVisibility()); Assert.assertEquals(View.GONE, toolbarSearchView.getVisibility()); + backPressRecorder2.assertExpected(); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateExtractorTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateExtractorTest.java index 328d4d9..2135adf6 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateExtractorTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/TabStateExtractorTest.java
@@ -49,10 +49,10 @@ @Mock private WebContents mWebContentsMock; @Mock - private ByteBuffer mByteBufferMock; - @Mock private Origin mMockOrigin; + private ByteBuffer mByteBuffer = ByteBuffer.allocate(1); + @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -66,7 +66,7 @@ public void testGetWebContentsState_notPending() { doReturn(null).when(mTabMock).getPendingLoadParams(); doReturn(mWebContentsMock).when(mTabMock).getWebContents(); - doReturn(mByteBufferMock) + doReturn(mByteBuffer) .when(mWebContentsBridgeJni) .getContentsStateAsByteBuffer(eq(mWebContentsMock)); @@ -74,7 +74,7 @@ assertNotNull(result); assertEquals(WebContentsState.CONTENTS_STATE_CURRENT_VERSION, result.version()); - assertEquals(mByteBufferMock, result.buffer()); + assertEquals(mByteBuffer, result.buffer()); } @Test @@ -85,7 +85,7 @@ loadUrlParams.setInitiatorOrigin(mMockOrigin); doReturn(loadUrlParams).when(mTabMock).getPendingLoadParams(); doReturn(true).when(mTabMock).isIncognito(); - doReturn(mByteBufferMock) + doReturn(mByteBuffer) .when(mWebContentsBridgeJni) .createSingleNavigationStateAsByteBuffer( eq(URL), eq(REFERRER_URL), eq(REFERRER_POLICY), eq(mMockOrigin), eq(true)); @@ -94,6 +94,6 @@ assertNotNull(result); assertEquals(WebContentsState.CONTENTS_STATE_CURRENT_VERSION, result.version()); - assertEquals(mByteBufferMock, result.buffer()); + assertEquals(mByteBuffer, result.buffer()); } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java index ca9a76b5..c54ba53 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tasks/ReturnToChromeUtilUnitTest.java
@@ -12,6 +12,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import static org.chromium.chrome.browser.tasks.ReturnToChromeUtil.FAIL_TO_SHOW_HOME_SURFACE_UI_UMA; import static org.chromium.chrome.browser.tasks.ReturnToChromeUtil.HOME_SURFACE_SHOWN_AT_STARTUP_UMA; import static org.chromium.chrome.browser.tasks.ReturnToChromeUtil.HOME_SURFACE_SHOWN_UMA; import static org.chromium.chrome.browser.ui.fold_transitions.FoldTransitionController.RESUME_HOME_SURFACE_ON_MODE_CHANGE; @@ -65,10 +66,12 @@ import org.chromium.chrome.browser.tabmodel.TabModelObserver; import org.chromium.chrome.browser.tabmodel.TabModelSelector; import org.chromium.chrome.browser.tabmodel.TabModelUtils; +import org.chromium.chrome.browser.tasks.ReturnToChromeUtil.FailToShowHomeSurfaceReason; import org.chromium.chrome.browser.tasks.ReturnToChromeUtilUnitTest.ShadowHomepageManager; import org.chromium.chrome.browser.tasks.ReturnToChromeUtilUnitTest.ShadowHomepagePolicyManager; import org.chromium.chrome.browser.tasks.ReturnToChromeUtilUnitTest.ShadowSysUtils; import org.chromium.chrome.browser.ui.fold_transitions.FoldTransitionController; +import org.chromium.chrome.browser.ui.native_page.FrozenNativePage; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.features.start_surface.StartSurfaceConfiguration; import org.chromium.chrome.test.util.browser.Features; @@ -163,6 +166,7 @@ doReturn(JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_URL)) .when(mUrlFormatterJniMock) .fixupUrl(UrlConstants.NTP_NON_NATIVE_URL); + doReturn(JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_NATIVE_URL)).when(mNtpTab).getUrl(); ChromeFeatureList.sStartSurfaceAndroid.setForTesting(true); @@ -636,7 +640,6 @@ doReturn(JUnitTestGURLs.getGURL(JUnitTestGURLs.URL_1)).when(mTab1).getUrl(); doReturn(mTab1).when(mCurrentTabModel).getTabAt(0); - doReturn(JUnitTestGURLs.getGURL(JUnitTestGURLs.NTP_NATIVE_URL)).when(mNtpTab).getUrl(); doReturn(true).when(mNtpTab).isNativePage(); doReturn(mNewTabPage).when(mNtpTab).getNativePage(); doReturn(mNtpTab).when(mCurrentTabModel).getTabAt(1); @@ -828,6 +831,7 @@ mTabCreater, mHomeSurfaceTracker, mTabModelSelector, JUnitTestGURLs.URL_1, null); verify(mCurrentTabModel).addObserver(mTabModelObserverCaptor.capture()); + // Verifies if the added Tab matches the tracking URL, call showHomeSurfaceUi(). mTabModelObserverCaptor.getValue().willAddTab(mTab1, TabLaunchType.FROM_RESTORE); verify(mNewTabPage).showHomeSurfaceUi(eq(mTab1)); verify(mHomeSurfaceTracker).updateHomeSurfaceAndTrackingTabs(eq(mNtpTab), eq(mTab1)); @@ -867,6 +871,30 @@ mSaveInstanceState)); } + @Test + @SmallTest + public void testLogFailToShowHomeSurfaceUI() { + HistogramWatcher histogram = HistogramWatcher.newBuilder() + .expectIntRecords(FAIL_TO_SHOW_HOME_SURFACE_UI_UMA, + FailToShowHomeSurfaceReason.NOT_A_NATIVE_PAGE) + .build(); + doReturn(null).when(mNtpTab).getNativePage(); + ReturnToChromeUtil.showHomeSurfaceUiOnNtp(mNtpTab, mTab1, mHomeSurfaceTracker); + histogram.assertExpected(); + + FrozenNativePage frozenNativePage = Mockito.mock(FrozenNativePage.class); + doReturn(true).when(frozenNativePage).isFrozen(); + doReturn(frozenNativePage).when(mNtpTab).getNativePage(); + histogram = HistogramWatcher.newBuilder() + .expectIntRecords(FAIL_TO_SHOW_HOME_SURFACE_UI_UMA, + FailToShowHomeSurfaceReason.NOT_A_NTP_NATIVE_PAGE) + .expectIntRecords(FAIL_TO_SHOW_HOME_SURFACE_UI_UMA, + FailToShowHomeSurfaceReason.NATIVE_PAGE_IS_FROZEN) + .build(); + ReturnToChromeUtil.showHomeSurfaceUiOnNtp(mNtpTab, mTab1, mHomeSurfaceTracker); + histogram.assertExpected(); + } + private Intent createMainIntentFromLauncher() { Intent intent = new Intent(); intent.setAction(Intent.ACTION_MAIN);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlockerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlockerUnitTest.java index db9dbe7..67733f6 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlockerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/ui/AppLaunchDrawBlockerUnitTest.java
@@ -47,6 +47,7 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.metrics.UmaRecorderHolder; +import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.Supplier; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; @@ -102,6 +103,9 @@ private Supplier<Boolean> mShouldShowTabSwitcherOnStartSupplier; @Mock private Supplier<Boolean> mIsInstantStartEnabledSupplier; + + private ObservableSupplierImpl<Profile> mProfileSupplier = new ObservableSupplierImpl<>(); + @Mock private IncognitoRestoreAppLaunchDrawBlockerFactory mIncognitoRestoreAppLaunchDrawBlockerFactoryMock; @@ -125,7 +129,10 @@ when(mView.getViewTreeObserver()).thenReturn(mViewTreeObserver); mJniMocker.mock(TemplateUrlServiceFactoryJni.TEST_HOOKS, mTemplateUrlServiceFactory); TemplateUrlServiceFactory.setInstanceForTesting(mTemplateUrlService); - Profile.setLastUsedProfileForTesting(mProfile); + + when(mProfile.getOriginalProfile()).thenReturn(mProfile); + mProfileSupplier.set(mProfile); + when(mShouldIgnoreIntentSupplier.get()).thenReturn(false); when(mIsTabletSupplier.get()).thenReturn(false); when(mShouldShowTabSwitcherOnStartSupplier.get()).thenReturn(false); @@ -136,7 +143,7 @@ mAppLaunchDrawBlocker = new AppLaunchDrawBlocker(mActivityLifecycleDispatcher, mViewSupplier, mIntentSupplier, mShouldIgnoreIntentSupplier, mIsTabletSupplier, mShouldShowTabSwitcherOnStartSupplier, mIsInstantStartEnabledSupplier, - mIncognitoRestoreAppLaunchDrawBlockerFactoryMock); + mProfileSupplier, mIncognitoRestoreAppLaunchDrawBlockerFactoryMock); validateConstructorAndCaptureObservers(); UmaRecorderHolder.resetForTesting(); SystemClock.setCurrentTimeMillis(INITIAL_TIME); @@ -145,7 +152,6 @@ @After public void tearDown() { TemplateUrlServiceFactory.setInstanceForTesting(null); - Profile.setLastUsedProfileForTesting(null); } @Test
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredManGetResponse.java b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredManGetResponse.java index 3cc4793..d35d690f 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredManGetResponse.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredManGetResponse.java
@@ -8,7 +8,13 @@ * Fake implementation of the Android Credential Manager GetCredentialResponse object. */ public final class FakeAndroidCredManGetResponse { + private final FakeAndroidCredential mCredential; + + public FakeAndroidCredManGetResponse(FakeAndroidCredential credential) { + mCredential = credential; + } + public FakeAndroidCredential getCredential() { - return new FakeAndroidCredential(); + return mCredential; } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredential.java b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredential.java index c356bb5..4f612e97 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredential.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredential.java
@@ -7,12 +7,10 @@ import android.os.Bundle; /** - * Fake implementation of the Android Credential Manager Credential object. + * Interface of the Android Credential Manager Credential object. */ -public final class FakeAndroidCredential { - public Bundle getData() { - Bundle data = new Bundle(); - data.putString("androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON", "json"); - return data; - } +interface FakeAndroidCredential { + Bundle getData(); + + String getType(); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredentialManager.java b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredentialManager.java index 4cee4021..e6bce63 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredentialManager.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidCredentialManager.java
@@ -17,8 +17,11 @@ FakeAndroidCredManCreateRequest mCreateRequest; FakeAndroidCredManGetRequest mGetRequest; FakeAndroidCredManException mErrorResponse; + FakeAndroidCredential mCredential; - public FakeAndroidCredentialManager() {} + public FakeAndroidCredentialManager() { + mCredential = new FakeAndroidPublicKeyCredential(); + } /** * Fake implementation of CredentialManager.createCredential(). @@ -47,7 +50,7 @@ callback.onError(mErrorResponse); return; } - callback.onResult(new FakeAndroidCredManGetResponse()); + callback.onResult(new FakeAndroidCredManGetResponse(mCredential)); } /** @@ -86,4 +89,8 @@ public void setErrorResponse(FakeAndroidCredManException error) { mErrorResponse = error; } + + public void setCredManGetResponseCredential(FakeAndroidCredential credential) { + mCredential = credential; + } }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPasswordCredential.java b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPasswordCredential.java new file mode 100644 index 0000000..7add4333 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPasswordCredential.java
@@ -0,0 +1,22 @@ +// 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. + +package org.chromium.chrome.browser.webauth; + +import android.os.Bundle; + +/** + * Fake implementation of the Android Credential Manager Password object. + */ +public final class FakeAndroidPasswordCredential implements FakeAndroidCredential { + @Override + public Bundle getData() { + return new Bundle(); + } + + @Override + public String getType() { + return "android.credentials.TYPE_PASSWORD_CREDENTIAL"; + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPublicKeyCredential.java b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPublicKeyCredential.java new file mode 100644 index 0000000..ddd0496 --- /dev/null +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/FakeAndroidPublicKeyCredential.java
@@ -0,0 +1,24 @@ +// 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. + +package org.chromium.chrome.browser.webauth; + +import android.os.Bundle; + +/** + * Fake implementation of the Android Credential Manager Passkey object. + */ +public final class FakeAndroidPublicKeyCredential implements FakeAndroidCredential { + @Override + public Bundle getData() { + Bundle data = new Bundle(); + data.putString("androidx.credentials.BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON", "json"); + return data; + } + + @Override + public String getType() { + return "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"; + } +}
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/Fido2CredentialRequestRobolectricTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/Fido2CredentialRequestRobolectricTest.java index 2871ffd..b2edaf39 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/webauth/Fido2CredentialRequestRobolectricTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/webauth/Fido2CredentialRequestRobolectricTest.java
@@ -21,6 +21,7 @@ import org.mockito.Mockito; import org.mockito.MockitoAnnotations; +import org.chromium.base.Callback; import org.chromium.base.FeatureList; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.JniMocker; @@ -41,26 +42,28 @@ import org.chromium.url.GURL; import org.chromium.url.Origin; +import java.util.List; + @RunWith(BaseRobolectricTestRunner.class) public class Fido2CredentialRequestRobolectricTest { private static class MockBrowserBridge extends WebAuthnBrowserBridge { private int mOnCredManConditionalRequestPendingCallCount; private int mCleanupRequestCallCount; private int mOnCredManClosedCallCount; - private Runnable mCredManGetAssertionRunnable; + private Callback<Boolean> mCredManGetAssertionCallback; void reset() { mOnCredManConditionalRequestPendingCallCount = 0; mCleanupRequestCallCount = 0; mOnCredManClosedCallCount = 0; - mCredManGetAssertionRunnable = null; + mCredManGetAssertionCallback = null; } @Override public void onCredManConditionalRequestPending( - RenderFrameHost frameHost, boolean hasResults, Runnable fullAssertion) { + RenderFrameHost frameHost, boolean hasResults, Callback<Boolean> fullAssertion) { mOnCredManConditionalRequestPendingCallCount += 1; - mCredManGetAssertionRunnable = fullAssertion; + mCredManGetAssertionCallback = fullAssertion; } @Override @@ -81,9 +84,10 @@ return mCleanupRequestCallCount; } - Runnable getCredManGetAssertionRunnable() { - return mCredManGetAssertionRunnable; + Callback<Boolean> getCredManGetAssertionCallback() { + return mCredManGetAssertionCallback; } + int getOnCredManClosedCallCount() { return mOnCredManClosedCallCount; } @@ -236,6 +240,7 @@ Assert.assertNotNull(credManRequest); Assert.assertEquals( credManRequest.getOrigin(), Fido2CredentialRequest.convertOriginToString(mOrigin)); + Assert.assertEquals(credManRequest.getCredentialOptions().size(), 1); FakeAndroidCredentialOption option = credManRequest.getCredentialOptions().get(0); Assert.assertNotNull(option); Assert.assertEquals(option.getType(), "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"); @@ -361,10 +366,43 @@ mCredentialManager.setErrorResponse(new FakeAndroidCredManException( "android.credentials.GetCredentialException.TYPE_USER_CANCELED", "Message")); - mMockBrowserBridge.getCredManGetAssertionRunnable().run(); + mMockBrowserBridge.getCredManGetAssertionCallback().onResult(true); Assert.assertEquals(mCallback.getStatus(), null); Assert.assertEquals(mMockBrowserBridge.getCleanupRequestCallCount(), 0); Assert.assertEquals(mMockBrowserBridge.getOnCredManClosedCallCount(), 1); } + + @Test + @SmallTest + public void testConditionalGetAssertion_credManEnabledWithPasswords_canHavePasswordResponse() { + // Calls to `context.getMainExecutor()` require API level 28 or higher. + Assume.assumeTrue(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P); + mRequestOptions.isConditional = true; + + mRequest.handleGetAssertionRequest(mRequestOptions, mFrameHost, mOrigin, /*payment=*/null, + (responseStatus, response) + -> mCallback.onSignResponse(responseStatus, response), + errorStatus -> mCallback.onError(errorStatus)); + + FakeAndroidCredManGetRequest credManRequest = mCredentialManager.getGetRequest(); + Assert.assertNotNull(credManRequest); + Assert.assertEquals(credManRequest.getCredentialOptions().size(), 1); + + mCredentialManager.setCredManGetResponseCredential(new FakeAndroidPasswordCredential()); + mMockBrowserBridge.getCredManGetAssertionCallback().onResult(true); + + credManRequest = mCredentialManager.getGetRequest(); + Assert.assertNotNull(credManRequest); + Assert.assertEquals(credManRequest.getCredentialOptions().size(), 2); + List<FakeAndroidCredentialOption> credentialOptions = credManRequest.getCredentialOptions(); + Assert.assertEquals(credentialOptions.get(0).getType(), + "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"); + Assert.assertEquals( + credentialOptions.get(1).getType(), "android.credentials.TYPE_PASSWORD_CREDENTIAL"); + + Assert.assertEquals(mMockBrowserBridge.getOnCredManClosedCallCount(), 1); + // A password is selected, the callback will not be signed. + Assert.assertEquals(mCallback.getStatus(), null); + } }
diff --git a/chrome/app/chromeos_strings.grdp b/chrome/app/chromeos_strings.grdp index 41a0475..6a8778e 100644 --- a/chrome/app/chromeos_strings.grdp +++ b/chrome/app/chromeos_strings.grdp
@@ -6091,9 +6091,6 @@ <message name="IDS_BOREALIS_DISALLOWED_ADMIN" desc="Message shown to the user when Steam on Chromebook is blocked by their admin"> Please contact your administrator </message> - <message name="IDS_BOREALIS_DISALLOWED_CHANNEL" desc="Message shown to the user when they try to install Steam on Chromebook on stable channel before it's available"> - Steam is coming to Chromebook soon. Check for updates to see if Steam is available. - </message> <message name="IDS_BOREALIS_DISALLOWED_FLAG" desc="Message shown to the user when Steam on Chromebook doesn't have the correct chrome://flags setting enabled"> #borealis-enabled must be enabled in chrome://flags </message> @@ -6703,29 +6700,43 @@ <!-- CHOOBE Screen --> <!-- TODO(b/258503542): Remove translateable tags when strings are finalized. --> <message name="IDS_OOBE_CHOOBE_TITLE" desc="Title of the CHOOBE screen." translateable="false"> - Select features you want to set up next + Choose more features to set up </message> <message name="IDS_OOBE_CHOOBE_DESCRIPTION" desc="Subitle of the CHOOBE screen." translateable="false"> - Or you can click Done for now and find them later in system Settings + You can also find these options in Settings after you finish setting up your Chromebook </message> <message name="IDS_OOBE_CHOOBE_SKIP_BUTTON" desc="Skip button for the CHOOBE screen" translateable="false"> - Remind me later + Skip </message> <!-- CHOOBE Tiles --> <!-- TODO(b/258503542): Remove translateable tags when strings are finalized. --> <message name="IDS_OOBE_CHOOBE_THEME_SELECTION_TILE_TITLE" desc="Title of the theme selection tile in the CHOOBE screen." translateable="false"> - Select dark/light theme + Select light or dark theme </message> <message name="IDS_OOBE_CHOOBE_TOUCHPAD_SCROLL_TILE_TITLE" desc="Title of the touchpad scroll tile in the CHOOBE screen." translateable="false"> Change touchpad scrolling direction </message> <message name="IDS_OOBE_CHOOBE_DISPLAY_SIZE_TILE_TITLE" desc="Title of the display size tile in the CHOOBE screen." translateable="false"> - Display size + Change display and text size </message> <message name="IDS_OOBE_CHOOBE_RETURN_BUTTON" desc="Label for the return button shown in the last optional screen selected by the user if there still exists more features thaat the user can select." translateable="false"> Save and see more </message> + <message name="IDS_OOBE_CHOOBE_TOUCHPAD_SCROLL_SUBTITLE_ENABLED" desc="Subtitle of the touchpad scroll tile in the CHOOBE screen if reverse scroll enabled." translateable="false"> + Reverse scrolling enabled + </message> + <message name="IDS_OOBE_CHOOBE_TOUCHPAD_SCROLL_SUBTITLE_DISABLED" desc="Subtitle of the touchpad scroll tile in the CHOOBE screen if reverse scroll disabled." translateable="false"> + Reverse scrolling disabled + </message> + + <!-- CHOOBE Tiles Accessibility --> + <message name="IDS_OOBE_CHOOBE_TILE_SYNCED" desc="message will be announced by the chromevox if the tile is synced and contain the sync icons." translateable="false"> + Setting synced from your previous device. + </message> + <message name="IDS_OOBE_CHOOBE_TILE_VISITED" desc="message will be announced by the chromevox if the tile is visited." translateable="false"> + Visited + </message> <!-- Strings for the office fallback dialog --> <message name="IDS_OFFICE_FALLBACK_CANCEL" desc="Label for the button that cancels office fallback."> @@ -6759,6 +6770,26 @@ Try enabling Google Drive in Settings. </message> + <!-- Office setup and move dialogs --> + <message name="IDS_CONNECT_TO_ONEDRIVE_TITLE" desc="Title for a dialog which allows the user to connect Files app and Microsoft OneDrive storage."> + Connect to Microsoft OneDrive + </message> + <message name="IDS_CONNECT_TO_ONEDRIVE_BODY_TEXT" desc="Explanation text for a dialog which allows the user to connect Files app and Microsoft OneDrive storage."> + Connect OneDrive to the Files app to manage your stored documents from your Chromebook. You'll need to sign in with your Microsoft account. + </message> + <message name="IDS_CANT_CONNECT_ONEDRIVE" desc="Error message text displayed when the user has tried to connect to OneDrive storage, but failed for any reason."> + Can't connect to OneDrive. Try again. + </message> + <message name="IDS_CONNECT_ONEDRIVE" desc="Text for a button which triggers a UI flow to connect the user to OneDrive storage."> + Connect to OneDrive + </message> + <message name="IDS_ONEDRIVE_CONNECTED_TITLE" desc="Text for a button which triggers a UI flow to connect the user to OneDrive storage."> + Microsoft OneDrive connected + </message> + <message name="IDS_ONEDRIVE_CONNECTED_BODY_TEXT" desc="Text for a button which triggers a UI flow to connect the user to OneDrive storage."> + OneDrive will now appear in the Files app + </message> + <!-- security curtain --> <message name="IDS_SECURITY_CURTAIN_TITLE" desc="Title text displayed to inform the user a remote admin has taken control of the ChromeOs device."> Your administrator is controlling your device
diff --git a/chrome/app/chromeos_strings_grdp/IDS_BOREALIS_DISALLOWED_CHANNEL.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_BOREALIS_DISALLOWED_CHANNEL.png.sha1 deleted file mode 100644 index 261435a..0000000 --- a/chrome/app/chromeos_strings_grdp/IDS_BOREALIS_DISALLOWED_CHANNEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -2273e4936805bebf9dbd28d59406d1a19a0772b0 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CANT_CONNECT_ONEDRIVE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CANT_CONNECT_ONEDRIVE.png.sha1 new file mode 100644 index 0000000..3ff338e --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CANT_CONNECT_ONEDRIVE.png.sha1
@@ -0,0 +1 @@ +ec297311816661b139be93b4ce733fea8c14d5a3 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONNECT_ONEDRIVE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONNECT_ONEDRIVE.png.sha1 new file mode 100644 index 0000000..c9091275 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONNECT_ONEDRIVE.png.sha1
@@ -0,0 +1 @@ +1143125e22241c3817a5acc195da4c20fb32bd15 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONNECT_TO_ONEDRIVE_BODY_TEXT.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONNECT_TO_ONEDRIVE_BODY_TEXT.png.sha1 new file mode 100644 index 0000000..c9091275 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONNECT_TO_ONEDRIVE_BODY_TEXT.png.sha1
@@ -0,0 +1 @@ +1143125e22241c3817a5acc195da4c20fb32bd15 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_CONNECT_TO_ONEDRIVE_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_CONNECT_TO_ONEDRIVE_TITLE.png.sha1 new file mode 100644 index 0000000..c9091275 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_CONNECT_TO_ONEDRIVE_TITLE.png.sha1
@@ -0,0 +1 @@ +1143125e22241c3817a5acc195da4c20fb32bd15 \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ONEDRIVE_CONNECTED_BODY_TEXT.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ONEDRIVE_CONNECTED_BODY_TEXT.png.sha1 new file mode 100644 index 0000000..ea686765 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ONEDRIVE_CONNECTED_BODY_TEXT.png.sha1
@@ -0,0 +1 @@ +0abbcc289a3d89cae121de0389c5816bbe04e1ed \ No newline at end of file
diff --git a/chrome/app/chromeos_strings_grdp/IDS_ONEDRIVE_CONNECTED_TITLE.png.sha1 b/chrome/app/chromeos_strings_grdp/IDS_ONEDRIVE_CONNECTED_TITLE.png.sha1 new file mode 100644 index 0000000..ea686765 --- /dev/null +++ b/chrome/app/chromeos_strings_grdp/IDS_ONEDRIVE_CONNECTED_TITLE.png.sha1
@@ -0,0 +1 @@ +0abbcc289a3d89cae121de0389c5816bbe04e1ed \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index df23793..c8e444f 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -2647,7 +2647,11 @@ </message> <message name="IDS_DOWNLOAD_BUBBLE_PROMO" desc="Text for the in-product-help bubble shown for the download bubble."> - Manage files as they download, and open them when they’re done + Manage files as they download, and open them when they're done + </message> + <message name="IDS_DOWNLOAD_BUBBLE_PROMO_SCREENREADER" + desc="Text read by the screenreader when the in-product-help bubble is shown for the download bubble."> + Downloads are now in the toolbar </message> <message name="IDS_DOWNLOAD_BUBBLE_PROMO_TITLE" desc="Title for the in-product-help bubble shown for the download bubble.">
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO.png.sha1 index 1ed1a08e0..53ba8d27 100644 --- a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO.png.sha1
@@ -1 +1 @@ -e5a44dca8f367ded27bae3496678fdcd48d5322b \ No newline at end of file +a28e0cdffee4f434b599a495d945a23fa43e4a21 \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO_SCREENREADER.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO_SCREENREADER.png.sha1 new file mode 100644 index 0000000..73b2a93 --- /dev/null +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO_SCREENREADER.png.sha1
@@ -0,0 +1 @@ +907098ec4499a7b116faa1cc35d960e44e6ba40b \ No newline at end of file
diff --git a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO_TITLE.png.sha1 b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO_TITLE.png.sha1 index 1ed1a08e0..53ba8d27 100644 --- a/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO_TITLE.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_DOWNLOAD_BUBBLE_PROMO_TITLE.png.sha1
@@ -1 +1 @@ -e5a44dca8f367ded27bae3496678fdcd48d5322b \ No newline at end of file +a28e0cdffee4f434b599a495d945a23fa43e4a21 \ No newline at end of file
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index f37a7cf..bc7b5db 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -158,6 +158,9 @@ <message name="IDS_OS_SETTINGS_TAG_AUDIO_SETTINGS_ALT4" desc="Text for search result item which, when clicked, navigates the user to Audio settings. Alternative phrase for: 'Audio'."> Microphone </message> + <message name="IDS_OS_SETTINGS_TAG_CHARGING_SOUNDS" desc="Text for search result item which, when clicked, navigates the user to settings to toggle whether the device plays charging sounds."> + Charging sounds + </message> <message name="IDS_OS_SETTINGS_TAG_AUTO_CONNECT_NETWORK" desc="Text for search result item which, when clicked, navigates the user to settings to toggle whether the device auto-connects to a network. Alternate phrase for: 'Auto connect to network'"> Automatically connect to network </message>
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_CHARGING_SOUNDS.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_CHARGING_SOUNDS.png.sha1 new file mode 100644 index 0000000..074145a --- /dev/null +++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_CHARGING_SOUNDS.png.sha1
@@ -0,0 +1 @@ +9cf85f3599c488a855a131a72517a6d27e2b7594 \ No newline at end of file
diff --git a/chrome/app/os_settings_strings.grdp b/chrome/app/os_settings_strings.grdp index 25a901d..503ad8c 100644 --- a/chrome/app/os_settings_strings.grdp +++ b/chrome/app/os_settings_strings.grdp
@@ -2863,6 +2863,9 @@ <message name="IDS_SETTINGS_AUDIO_OUTPUT_MUTE_BUTTON_ARIA_LABEL_MUTED" desc="In Device Settings, the aria label for the output mute button muted."> Volume is off. Turn on volume. </message> + <message name="IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_CHARGING_SOUNDS_LABEL" desc="Label for checkbox which enables charging sounds."> + Charging sounds + </message> <!-- Device pointer page (OS settings) --> <message name="IDS_SETTINGS_MOUSE_TITLE" desc="In Device Settings, the title of the mouse settings subpage.">
diff --git a/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_CHARGING_SOUNDS_LABEL.png.sha1 b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_CHARGING_SOUNDS_LABEL.png.sha1 new file mode 100644 index 0000000..f9233b2b --- /dev/null +++ b/chrome/app/os_settings_strings_grdp/IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_CHARGING_SOUNDS_LABEL.png.sha1
@@ -0,0 +1 @@ +d1f762c59853a48c0cbc91c051ff36781ce09a79 \ No newline at end of file
diff --git a/chrome/app/settings_strings.grdp b/chrome/app/settings_strings.grdp index bf3b9bf..c857088 100644 --- a/chrome/app/settings_strings.grdp +++ b/chrome/app/settings_strings.grdp
@@ -3995,6 +3995,12 @@ <message name="IDS_SETTINGS_STORAGE_ACCESS_BLOCKED" translateable="false" desc="It explains that an embedded site is blocked from accessing its unpartitioned cookies that it would normally only have access to in a first-party context (i.e. when loaded directly in a browser tab) "> Don't allow embedded sites to access info they've saved about you </message> + <message name="IDS_SETTINGS_STORAGE_ACCESS_ALLOWED_EXCEPTIONS" translateable="false" desc="It explains that an embedded site is allowed to access its unpartitioned cookies that it would normally only have access to in a first-party context (i.e. when loaded directly in a browser tab) "> + Allowed to access info they've about you while embeded in another site + </message> + <message name="IDS_SETTINGS_STORAGE_ACCESS_BLOCKED_EXCEPTIONS" translateable="false" desc="It explains that an embedded site is blocked from accessing its unpartitioned cookies that it would normally only have access to in a first-party context (i.e. when loaded directly in a browser tab) "> + Not allowed to access info they've about you while embeded in another site + </message> <message name="IDS_SETTINGS_NO_BLUETOOTH_DEVICES_FOUND" desc="Explanation for not showing Bluetooth devices in site settings."> No Bluetooth devices found
diff --git a/chrome/app/sharesheet_strings.grdp b/chrome/app/sharesheet_strings.grdp index 5722853f..de012edd 100644 --- a/chrome/app/sharesheet_strings.grdp +++ b/chrome/app/sharesheet_strings.grdp
@@ -14,12 +14,6 @@ <message name="IDS_SHARESHEET_FEWER_APPS_LABEL" desc="The label for the button at the bottom of the sharesheet which clicks into the default sharesheet."> Fewer apps </message> - <message name="IDS_SHARESHEET_ZERO_STATE_PRIMARY_LABEL" desc="The label shown to inform users that the sharesheet is empty."> - No apps available for this content - </message> - <message name="IDS_SHARESHEET_ZERO_STATE_SECONDARY_LABEL" desc="The label informing users where to download apps."> - Visit the Play Store to find more apps - </message> <message name="IDS_SHARESHEET_FILES_LABEL" desc="The label for the enumeration of the number of files a user is trying to share."> {COUNT, plural, =1 {{COUNT} file}
diff --git a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_ZERO_STATE_PRIMARY_LABEL.png.sha1 b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_ZERO_STATE_PRIMARY_LABEL.png.sha1 deleted file mode 100644 index f28077bc..0000000 --- a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_ZERO_STATE_PRIMARY_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -1d9f3c86bd03e8f20ea6c17e78f2f453ea57ce5d \ No newline at end of file
diff --git a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_ZERO_STATE_SECONDARY_LABEL.png.sha1 b/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_ZERO_STATE_SECONDARY_LABEL.png.sha1 deleted file mode 100644 index f28077bc..0000000 --- a/chrome/app/sharesheet_strings_grdp/IDS_SHARESHEET_ZERO_STATE_SECONDARY_LABEL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -1d9f3c86bd03e8f20ea6c17e78f2f453ea57ce5d \ No newline at end of file
diff --git a/chrome/app/theme/theme_resources.grd b/chrome/app/theme/theme_resources.grd index cbc877b..0aec5267 100644 --- a/chrome/app/theme/theme_resources.grd +++ b/chrome/app/theme/theme_resources.grd
@@ -358,6 +358,7 @@ <structure type="chrome_scaled_image" name="IDR_WEBSTORE_ICON_24" file="google_chrome/webstore_icon_24.png" /> <structure type="chrome_scaled_image" name="IDR_WEBSTORE_ICON_32" file="google_chrome/webstore_icon_32.png" /> <structure type="chrome_scaled_image" name="IDR_TRANSLATE_TAB_WORDMARK" file="google_chrome/translate_tab_wordmark.png" /> + <structure type="chrome_scaled_image" name="IDR_TAILORED_SECURITY_UNCONSENTED_NOTIFICATION" file="google_chrome/safer_with_google_blue_shield.png" /> </if> </if> <if expr="not is_android">
diff --git a/chrome/app/vector_icons/BUILD.gn b/chrome/app/vector_icons/BUILD.gn index 959a70f..1bd9d3b1 100644 --- a/chrome/app/vector_icons/BUILD.gn +++ b/chrome/app/vector_icons/BUILD.gn
@@ -293,6 +293,7 @@ sources += [ "autocorrect_undo.icon", "full_restore_notification.icon", + "game_controls_add.icon", "game_controls_delete.icon", "game_controls_done.icon", "game_controls_dpad_keyboard.icon",
diff --git a/chrome/app/vector_icons/game_controls_add.icon b/chrome/app/vector_icons/game_controls_add.icon new file mode 100644 index 0000000..faf01e2 --- /dev/null +++ b/chrome/app/vector_icons/game_controls_add.icon
@@ -0,0 +1,19 @@ +// 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. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 11, 4, +H_LINE_TO, 9, +R_V_LINE_TO, 5, +H_LINE_TO, 4, +R_V_LINE_TO, 2, +R_H_LINE_TO, 5, +R_V_LINE_TO, 5, +R_H_LINE_TO, 2, +R_V_LINE_TO, -5, +R_H_LINE_TO, 5, +V_LINE_TO, 9, +R_H_LINE_TO, -5, +V_LINE_TO, 4, +CLOSE
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 355c190..ca02eec 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -297,6 +297,8 @@ "command_updater_impl.h", "commerce/shopping_service_factory.cc", "commerce/shopping_service_factory.h", + "companion/visual_search/visual_search_suggestions_service_factory.cc", + "companion/visual_search/visual_search_suggestions_service_factory.h", "complex_tasks/task_tab_helper.cc", "complex_tasks/task_tab_helper.h", "component_updater/chrome_client_side_phishing_component_installer.cc", @@ -2283,10 +2285,7 @@ "//components/segmentation_platform/internal/proto", "//components/segmentation_platform/public", "//components/send_tab_to_self", - "//components/services/app_service/public/cpp:crosapi_utils", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:protocol_handling", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//components/services/heap_profiling", "//components/services/language_detection/public/cpp", "//components/services/language_detection/public/mojom", @@ -3059,6 +3058,8 @@ "password_manager/android/auto_signin_first_run_dialog_android.h", "password_manager/android/auto_signin_prompt_controller.cc", "password_manager/android/auto_signin_prompt_controller.h", + "password_manager/android/cred_man_controller.cc", + "password_manager/android/cred_man_controller.h", "password_manager/android/credential_android.cc", "password_manager/android/credential_android.h", "password_manager/android/credential_leak_controller_android.cc", @@ -4434,16 +4435,7 @@ "//components/live_caption:live_translate", "//components/memory_pressure", "//components/omnibox/browser:mojo_bindings", - "//components/services/app_service/public/cpp:app_file_handling", - "//components/services/app_service/public/cpp:app_share_target", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_loader", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:preferred_apps", - "//components/services/app_service/public/cpp:protocol_handling", - "//components/services/app_service/public/cpp:run_on_os_login", + "//components/services/app_service", "//components/shared_highlighting/core/common", "//components/soda", "//components/soda:constants", @@ -6199,7 +6191,6 @@ "//chrome/browser/enterprise/connectors/device_trust/key_management/core", "//chrome/browser/enterprise/connectors/device_trust/key_management/core/persistence", "//chrome/services/system_signals/public/cpp/browser", - "//components/power_metrics", ] public_deps += [ "//chrome/browser/enterprise/connectors/analysis:sdk_manager" ] @@ -6579,6 +6570,7 @@ if (is_win || is_mac || is_linux || is_chromeos) { deps += [ + "//components/power_metrics", "//components/user_notes:features", "//components/user_notes/browser", "//components/user_notes/interfaces",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 55c39b2..6885910 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -1314,7 +1314,6 @@ const FeatureEntry::FeatureParam kJourneysOmniboxHistoryClusterProviderVariationsAggressive[] = { {"omnibox_history_cluster_provider_score", "1100"}, - {"omnibox_history_cluster_provider_shortcuts", "true"}, {"omnibox_history_cluster_provider_navigation_intent_score_threshold", "1400"}, {"omnibox_history_cluster_provider_on_navigation_intents", "false"}, @@ -1322,19 +1321,10 @@ const FeatureEntry::FeatureParam kJourneysOmniboxHistoryClusterProviderVariationsModerate[] = { {"omnibox_history_cluster_provider_score", "900"}, - {"omnibox_history_cluster_provider_shortcuts", "true"}, {"omnibox_history_cluster_provider_navigation_intent_score_threshold", "1300"}, {"omnibox_history_cluster_provider_on_navigation_intents", "false"}, }; -const FeatureEntry::FeatureParam - kJourneysOmniboxHistoryClusterProviderVariationsConservative[] = { - {"omnibox_history_cluster_provider_score", "700"}, - {"omnibox_history_cluster_provider_shortcuts", "false"}, - {"omnibox_history_cluster_provider_navigation_intent_score_threshold", - "1100"}, - {"omnibox_history_cluster_provider_on_navigation_intents", "false"}, -}; const FeatureEntry::FeatureVariation kJourneysOmniboxHistoryClusterProviderVariations[] = { {"Aggressive - score 1100, shortcut boosting, nav-intent filtering " @@ -1346,22 +1336,6 @@ kJourneysOmniboxHistoryClusterProviderVariationsModerate, std::size(kJourneysOmniboxHistoryClusterProviderVariationsModerate), nullptr}, - {"Conservative - score 700, nav-intent filtering 1100", - kJourneysOmniboxHistoryClusterProviderVariationsConservative, - std::size( - kJourneysOmniboxHistoryClusterProviderVariationsConservative), - nullptr}, -}; - -const FeatureEntry::FeatureParam kJourneysHideVisitsVariationsMenuItem[] = { - {"hide_visits_icon", "false"}}; -const FeatureEntry::FeatureParam kJourneysHideVisitsVariationsIcon[] = { - {"hide_visits_icon", "true"}}; -const FeatureEntry::FeatureVariation kJourneysHideVisitsVariations[] = { - {"Menu item", kJourneysHideVisitsVariationsMenuItem, - std::size(kJourneysHideVisitsVariationsMenuItem), nullptr}, - {"Thumbs-down Icon", kJourneysHideVisitsVariationsIcon, - std::size(kJourneysHideVisitsVariationsIcon), nullptr}, }; const FeatureEntry::FeatureVariation @@ -4031,6 +4005,9 @@ {"audio-hfp-mic-sr", flag_descriptions::kAudioHFPMicSRName, flag_descriptions::kAudioHFPMicSRDescription, kOsCrOS, PLATFORM_FEATURE_NAME_TYPE("CrOSLateBootAudioHFPMicSR")}, + {"audio-hfp-nbs-warning", flag_descriptions::kAudioHFPNbsWarningName, + flag_descriptions::kAudioHFPNbsWarningDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kAudioHFPNbsWarning)}, {"audio-hfp-offload", flag_descriptions::kAudioHFPOffloadName, flag_descriptions::kAudioHFPOffloadDescription, kOsCrOS, PLATFORM_FEATURE_NAME_TYPE("CrOSLateBootAudioHFPOffload")}, @@ -4106,9 +4083,6 @@ flag_descriptions::kBluetoothFlossCoredumpDescription, kOsCrOS, FEATURE_VALUE_TYPE( chromeos::bluetooth::features::kBluetoothFlossCoredump)}, - {"speak-on-mute-detection", flag_descriptions::kSpeakOnMuteName, - flag_descriptions::kSpeakOnMuteDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kSpeakOnMuteEnabled)}, {kBluetoothUseFlossInternalName, flag_descriptions::kBluetoothUseFlossName, flag_descriptions::kBluetoothUseFlossDescription, kOsCrOS, FEATURE_VALUE_TYPE(floss::features::kFlossEnabled)}, @@ -5290,6 +5264,11 @@ flag_descriptions::kAutocorrectByDefaultName, flag_descriptions::kAutocorrectByDefaultDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kAutocorrectByDefault)}, + {"enable-cros-autocorrect-use-replace-surrounding-text", + flag_descriptions::kAutocorrectUseReplaceSurroundingTextName, + flag_descriptions::kAutocorrectUseReplaceSurroundingTextDescription, + kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kAutocorrectUseReplaceSurroundingText)}, {"enable-cros-avatars-cloud-migration", flag_descriptions::kAvatarsCloudMigrationName, flag_descriptions::kAvatarsCloudMigrationDescription, kOsCrOS, @@ -5566,11 +5545,6 @@ autofill::features::kAutofillVirtualCardsOnTouchToFillAndroid)}, #if BUILDFLAG(IS_ANDROID) - {"enable-autofill-manual-fallback", - flag_descriptions::kAutofillManualFallbackAndroidName, - flag_descriptions::kAutofillManualFallbackAndroidDescription, kOsAndroid, - FEATURE_VALUE_TYPE(autofill::features::kAutofillManualFallbackAndroid)}, - {"enable-autofill-touch-to-fill-for-credit-cards", flag_descriptions::kAutofillTouchToFillForCreditCardsAndroidName, flag_descriptions::kAutofillTouchToFillForCreditCardsAndroidDescription, @@ -5725,6 +5699,10 @@ flag_descriptions::kPrintManagementSetupAssistanceName, flag_descriptions::kPrintManagementSetupAssistanceDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kPrintManagementSetupAssistance)}, + {"print-preview-discovered-printers", + flag_descriptions::kPrintPreviewDiscoveredPrintersName, + flag_descriptions::kPrintPreviewDiscoveredPrintersDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kPrintPreviewDiscoveredPrinters)}, {"printer-settings-printer-status", flag_descriptions::kPrinterSettingsPrinterStatusName, flag_descriptions::kPrinterSettingsPrinterStatusDescription, kOsCrOS, @@ -5900,10 +5878,6 @@ omnibox::kRichAutocompletion, kOmniboxRichAutocompletionPromisingVariations, "OmniboxBundledExperimentV1")}, - {"omnibox-disable-cgi-param-matching", - flag_descriptions::kOmniboxDisableCGIParamMatchingName, - flag_descriptions::kOmniboxDisableCGIParamMatchingDescription, kOsDesktop, - FEATURE_VALUE_TYPE(omnibox::kDisableCGIParamMatching)}, {"omnibox-site-search-starter-pack", flag_descriptions::kOmniboxSiteSearchStarterPackName, flag_descriptions::kOmniboxSiteSearchStarterPackDescription, kOsDesktop, @@ -6218,12 +6192,6 @@ FEATURE_VALUE_TYPE( history_clusters::internal::kJourneysIncludeSyncedVisits)}, - {"history-journeys-hide-visits", flag_descriptions::kJourneysHideVisitsName, - flag_descriptions::kJourneysHideVisitsDescription, kOsDesktop, - FEATURE_WITH_PARAMS_VALUE_TYPE(history_clusters::internal::kHideVisits, - kJourneysHideVisitsVariations, - "JourneysHide")}, - {"history-journeys-zero-state-filtering", flag_descriptions::kJourneysZeroStateFilteringName, flag_descriptions::kJourneysZeroStateFilteringDescription, @@ -6306,9 +6274,6 @@ {"handwriting-library-dlc", flag_descriptions::kHandwritingLibraryDlcName, flag_descriptions::kHandwritingLibraryDlcDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kHandwritingLibraryDlc)}, - {"language-packs-in-oobe", flag_descriptions::kLanguagePacksInOobeName, - flag_descriptions::kLanguagePacksInOobeDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kLanguagePacksInOobe)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) {"block-insecure-private-network-requests", @@ -7425,6 +7390,11 @@ flag_descriptions::kEnableInputDeviceSettingsSplitDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kInputDeviceSettingsSplit)}, + {"enable-peripheral-customization", + flag_descriptions::kEnablePeripheralCustomizationName, + flag_descriptions::kEnablePeripheralCustomizationDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kPeripheralCustomization)}, + {"enable-rgb-keyboard", flag_descriptions::kEnableRgbKeyboardName, flag_descriptions::kEnableRgbKeyboardDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kRgbKeyboard)}, @@ -7601,16 +7571,16 @@ {"use-toast-manager", flag_descriptions::kUseToastManagerName, flag_descriptions::kUseToastManagerDescription, kOsAndroid, FEATURE_VALUE_TYPE(::features::kUseToastManager)}, - {"android-widget-fullscreen-toast", - flag_descriptions::kAndroidWidgetFullscreenToastName, - flag_descriptions::kAndroidWidgetFullscreenToastDescription, kOsAndroid, - FEATURE_VALUE_TYPE(chrome::android::kAndroidWidgetFullscreenToast)}, #endif // BUILDFLAG(IS_ANDROID) #if BUILDFLAG(IS_CHROMEOS_ASH) {"contextual-nudges", flag_descriptions::kContextualNudgesName, flag_descriptions::kContextualNudgesDescription, kOsCrOS, FEATURE_VALUE_TYPE(ash::features::kContextualNudges)}, + + {"scalable-iph", flag_descriptions::kScalableIphName, + flag_descriptions::kScalableIphDescription, kOsCrOS, + FEATURE_VALUE_TYPE(ash::features::kScalableIph)}, #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(IS_CHROMEOS_ASH) @@ -7863,14 +7833,6 @@ FEATURE_VALUE_TYPE(paint_preview::kPaintPreviewDemo)}, #endif // BUILDFLAG(ENABLE_PAINT_PREVIEW) && BUILDFLAG(IS_ANDROID) -#if BUILDFLAG(IS_ANDROID) - {"recover-from-never-save-android", - flag_descriptions::kRecoverFromNeverSaveAndroidName, - flag_descriptions::kRecoverFromNeverSaveAndroidDescription, kOsAndroid, - FEATURE_VALUE_TYPE( - password_manager::features::kRecoverFromNeverSaveAndroid)}, -#endif // BUILDFLAG(IS_ANDROID) - {"fullscreen-popup-windows", flag_descriptions::kFullscreenPopupWindowsName, flag_descriptions::kFullscreenPopupWindowsDescription, kOsDesktop | kOsAndroid, @@ -8810,7 +8772,8 @@ {"csc-vss", flag_descriptions::kCscVssName, flag_descriptions::kCscVssDescription, kOsDesktop, - FEATURE_VALUE_TYPE(visual_search::features::kVisualSearchSuggestions)}, + FEATURE_VALUE_TYPE( + companion::visual_search::features::kVisualSearchSuggestions)}, {"enable-lens-region-search-static-page", flag_descriptions::kLensRegionSearchStaticPageName, @@ -10414,10 +10377,6 @@ FEATURE_VALUE_TYPE(policy::features::kEnablePolicyTestPage)}, #if BUILDFLAG(IS_CHROMEOS_ASH) - {"allow-devtools-in-system-ui", - flag_descriptions::kAllowDevtoolsInSystemUIName, - flag_descriptions::kAllowDevtoolsInSystemUIDescription, kOsCrOS, - FEATURE_VALUE_TYPE(ash::features::kAllowDevtoolsInSystemUI)}, {"cros-web-app-shortcut-ui-update", flag_descriptions::kCrosWebAppShortcutUiUpdateName, flag_descriptions::kCrosWebAppShortcutUiUpdateDescription, kOsCrOS,
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.cc b/chrome/browser/android/compositor/layer/tab_handle_layer.cc index b9bf486d..997b90f 100644 --- a/chrome/browser/android/compositor/layer/tab_handle_layer.cc +++ b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
@@ -45,7 +45,8 @@ float content_offset_x, float content_offset_y, float divider_offset_x, - float bottom_offset_y, + float bottom_margin, + float top_margin, float close_button_padding, float close_button_alpha, bool is_start_divider_visible, @@ -78,6 +79,7 @@ } } + y += top_margin; float original_x = x; float original_y = y; if (foreground_) { @@ -106,9 +108,11 @@ y = y - (margin_height - height); height = margin_height; } - gfx::Size tab_bounds(width, height - bottom_offset_y); + height -= top_margin; + gfx::Size tab_bounds(width, height - bottom_margin); layer_->SetPosition(gfx::PointF(x, y)); + DecorationTitle* title_layer = nullptr; // Only pull if tab id is valid. if (layer_title_cache_ && id != -1) { @@ -170,15 +174,7 @@ close_width = 0.f; } - int divider_y; - float divider_y_offset_mid = - (tab_handle_resource->padding().y() + height) / 2 - - start_divider_->bounds().height() / 2; - if (is_tab_strip_redesign_enabled) { - divider_y = content_offset_y; - } else { - divider_y = divider_y_offset_mid; - } + int divider_y = content_offset_y; if (!is_start_divider_visible) { start_divider_->SetIsDrawable(false); @@ -204,8 +200,9 @@ if (title_layer) { int title_y; - float title_y_offset_mid = tab_handle_resource->padding().y() / 2 + - height / 2 - title_layer->size().height() / 2; + float title_y_offset_mid = (tab_handle_resource->padding().y() + height - + title_layer->size().height()) / + 2; if (is_tab_strip_redesign_enabled) { // 8dp top padding for folio and 10 dp for detached at default text size. title_y = std::min(content_offset_y, title_y_offset_mid); @@ -235,9 +232,9 @@ } else { close_button_->SetIsDrawable(true); int close_y; - float close_y_offset_mid = - (tab_handle_resource->padding().y() + height) / 2 - - close_button_->bounds().height() / 2; + float close_y_offset_mid = (tab_handle_resource->padding().y() + height - + close_button_->bounds().height()) / + 2; if (is_tab_strip_redesign_enabled) { // Close button image is larger than divider image, so close button will // appear slightly lower even the close_y are set in the same value as @@ -254,8 +251,8 @@ int close_x = is_rtl ? padding_left - close_button_padding : width - padding_right - close_width; if (foreground_) { - close_y += original_y; close_x += original_x; + close_y += original_y; } close_button_->SetPosition(gfx::PointF(close_x, close_y));
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.h b/chrome/browser/android/compositor/layer/tab_handle_layer.h index cf1d541..73ae2d8 100644 --- a/chrome/browser/android/compositor/layer/tab_handle_layer.h +++ b/chrome/browser/android/compositor/layer/tab_handle_layer.h
@@ -46,7 +46,8 @@ float content_offset_x, float content_offset_y, float divider_offset_x, - float bottom_offset_y, + float bottom_margin, + float top_margin, float close_button_padding, float close_button_alpha, bool is_start_divider_visible,
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc index d075161..5aae6590 100644 --- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc +++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -376,7 +376,8 @@ jfloat content_offset_x, jfloat content_offset_y, jfloat divider_offset_x, - jfloat bottom_offset_y, + jfloat bottom_margin, + jfloat top_margin, jfloat close_button_padding, jfloat close_button_alpha, jboolean is_start_divider_visible, @@ -407,7 +408,7 @@ id, close_button_resource, divider_resource, tab_handle_resource, tab_handle_outline_resource, foreground, close_pressed, toolbar_width, x, y, width, height, content_offset_x, content_offset_y, divider_offset_x, - bottom_offset_y, close_button_padding, close_button_alpha, + bottom_margin, top_margin, close_button_padding, close_button_alpha, is_start_divider_visible, is_end_divider_visible, is_loading, spinner_rotation, brightness, opacity, is_tab_strip_redesign_enabled_); }
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h index c83bafe..3001a2d 100644 --- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h +++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
@@ -139,7 +139,8 @@ jfloat content_offset_x, jfloat content_offset_y, jfloat divider_offset_x, - jfloat bottom_offset_y, + jfloat bottom_margin, + jfloat top_margin, jfloat close_button_padding, jfloat close_button_alpha, jboolean is_start_divider_visible,
diff --git a/chrome/browser/android/vr/gvr_scheduler_delegate.cc b/chrome/browser/android/vr/gvr_scheduler_delegate.cc index 2c8a2a91..88fac2a 100644 --- a/chrome/browser/android/vr/gvr_scheduler_delegate.cc +++ b/chrome/browser/android/vr/gvr_scheduler_delegate.cc
@@ -276,10 +276,12 @@ weak_ptr_factory_.GetWeakPtr()))) { return; } - if (mailbox_bridge_) - mailbox_bridge_->ResizeSurface(size.width(), size.height()); - else + if (!mailbox_bridge_) { CreateSurfaceBridge(graphics_->webxr_surface_texture()); + } else if (graphics_->webxr_surface_texture()) { + // Need to resize only if we have surface. + mailbox_bridge_->ResizeSurface(size.width(), size.height()); + } } void GvrSchedulerDelegate::OnGpuProcessConnectionReady() {
diff --git a/chrome/browser/app_controller_mac_browsertest.mm b/chrome/browser/app_controller_mac_browsertest.mm index aa7e536..fbeeef6 100644 --- a/chrome/browser/app_controller_mac_browsertest.mm +++ b/chrome/browser/app_controller_mac_browsertest.mm
@@ -1206,6 +1206,15 @@ EXPECT_TRUE(incognito_browser->profile()->IsIncognitoProfile()); EXPECT_EQ(BrowserList::GetInstance()->size(), 1u); EXPECT_EQ(incognito_browser, chrome::GetLastActiveBrowser()); + // Assure that `windowDidBecomeMain` is called even if this browser process + // lost focus because of other browser processes in other shards taking + // focus. It prevents flakiness. + // See: https://crbug.com/1450491 + [[NSNotificationCenter defaultCenter] + postNotificationName:NSWindowDidBecomeMainNotification + object:incognito_browser->window() + ->GetNativeWindow() + .GetNativeNSWindow()]; // Simulate click on "New Window". ui_test_utils::BrowserChangeObserver browser_added_observer(
diff --git a/chrome/browser/apps/app_service/BUILD.gn b/chrome/browser/apps/app_service/BUILD.gn index 58ab3be..5123a1b 100644 --- a/chrome/browser/apps/app_service/BUILD.gn +++ b/chrome/browser/apps/app_service/BUILD.gn
@@ -70,13 +70,7 @@ "//components/crx_file", "//components/favicon/core", "//components/keyed_service/content", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_loader", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:preferred_apps", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//extensions/browser", "//extensions/common", ] @@ -251,9 +245,6 @@ "//components/image_fetcher/core", "//components/metrics/structured:structured_events", "//components/resources:components_resources", - "//components/services/app_service/public/cpp:crosapi_utils", - "//components/services/app_service/public/cpp:instance_update", - "//components/services/app_service/public/cpp:macros", "//components/ukm", "//components/webapps/browser", "//services/metrics/public/cpp:ukm_builders", @@ -289,8 +280,6 @@ "app_service_proxy_desktop.cc", "app_service_proxy_desktop.h", ] - - deps += [ "//components/services/app_service/public/cpp:run_on_os_login" ] } if (!is_chromeos_lacros) { @@ -306,8 +295,6 @@ "publishers/extension_apps_base.cc", "publishers/extension_apps_base.h", ] - - deps += [ "//components/services/app_service/public/cpp:preferred_app" ] } } @@ -367,17 +354,7 @@ "//chrome/test:test_support", "//components/account_id", "//components/app_constants", - - # TODO: Depend on "//components/services/app_service" once - # crrev.com/c/4570160 lands. - "//components/services/app_service/public/cpp:app_file_handling", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_loader", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:preferred_app", - "//components/services/app_service/public/cpp:preferred_apps", + "//components/services/app_service", "//components/services/app_service/public/cpp:test_support", "//components/user_manager", "//content/test:test_support", @@ -469,9 +446,7 @@ deps = [ "//build:chromeos_buildflags", "//chrome/test:test_support", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:run_on_os_login", + "//components/services/app_service", "//skia", ]
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app.cc b/chrome/browser/apps/app_service/promise_apps/promise_app.cc index 7c03d17..ae14f52c 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app.cc +++ b/chrome/browser/apps/app_service/promise_apps/promise_app.cc
@@ -20,6 +20,12 @@ PromiseAppIcon::PromiseAppIcon() = default; PromiseAppIcon::~PromiseAppIcon() = default; +bool PromiseApp::operator==(const PromiseApp& rhs) const { + return this->package_id == rhs.package_id && this->name == rhs.name && + this->progress == rhs.progress && this->status == rhs.status && + this->should_show == rhs.should_show; +} + PromiseAppPtr PromiseApp::Clone() const { auto promise_app = std::make_unique<PromiseApp>(package_id); if (name.has_value()) {
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app.h b/chrome/browser/apps/app_service/promise_apps/promise_app.h index a2b171a..11cffc4 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app.h +++ b/chrome/browser/apps/app_service/promise_apps/promise_app.h
@@ -30,6 +30,8 @@ explicit PromiseApp(const apps::PackageId& package_id); ~PromiseApp(); + bool operator==(const PromiseApp&) const; + PackageId package_id; absl::optional<std::string> name;
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc index 54bf23a..4f310c1 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc +++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.cc
@@ -10,36 +10,14 @@ namespace apps { -PromiseAppRegistryCache::Observer::Observer(PromiseAppRegistryCache* cache) { - Observer::Observe(cache); -} - -PromiseAppRegistryCache::Observer::Observer() = default; - -PromiseAppRegistryCache::Observer::~Observer() { - if (cache_) { - cache_->RemoveObserver(this); - } -} - -void PromiseAppRegistryCache::Observer::Observe( - PromiseAppRegistryCache* cache) { - if (cache == cache_) { - // Early exit to avoid infinite loops if we're in the middle of a callback. - return; - } - if (cache_) { - cache_->RemoveObserver(this); - } - cache_ = cache; - if (cache_) { - cache_->AddObserver(this); - } -} - PromiseAppRegistryCache::PromiseAppRegistryCache() = default; -PromiseAppRegistryCache::~PromiseAppRegistryCache() = default; +PromiseAppRegistryCache::~PromiseAppRegistryCache() { + for (auto& obs : observers_) { + obs.OnPromiseAppRegistryCacheWillBeDestroyed(this); + } + CHECK(observers_.empty()); +} void PromiseAppRegistryCache::AddObserver(Observer* observer) { DCHECK(observer);
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h index 4c9a1071..d3477a35 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h +++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h
@@ -25,37 +25,18 @@ public: class Observer : public base::CheckedObserver { public: - Observer(const Observer&) = delete; - Observer& operator=(const Observer&) = delete; - - // The apps::PromiseAppUpdate argument shouldn't be accessed after - // OnPromiseAppUpdate returns. + // Triggered when a new promise app is registered or an existing promise app + // is updated in the observed Promise App Registry Cache. `Update` contains + // information on which promise app has been updated and what changes have + // been made. virtual void OnPromiseAppUpdate(const PromiseAppUpdate& update) {} // Called when the PromiseAppRegistryCache object (the thing that this // observer observes) will be destroyed. In response, the observer, |this|, // should call "cache->RemoveObserver(this)", whether directly or indirectly - // (e.g. via base::ScopedObservation::Remove or via Observe(nullptr)). + // (e.g. via base::ScopedObservation::Reset) virtual void OnPromiseAppRegistryCacheWillBeDestroyed( PromiseAppRegistryCache* cache) = 0; - - protected: - // Use this constructor when the observer |this| is tied to a single - // PromiseAppRegistryCache for its entire lifetime, or until the observee - // (the PromiseAppRegistryCache) is destroyed, whichever comes first. - explicit Observer(PromiseAppRegistryCache* cache); - - // Use this constructor when the observer |this| wants to observe a - // PromiseAppRegistryCache for part of its lifetime. It can then call - // Observe() to start and stop observing. - Observer(); - - ~Observer() override; - - void Observe(PromiseAppRegistryCache* cache); - - private: - raw_ptr<PromiseAppRegistryCache> cache_ = nullptr; }; PromiseAppRegistryCache();
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc index 0d84b15e..4ed6a37d 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc +++ b/chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache_unittest.cc
@@ -4,11 +4,10 @@ #include "chrome/browser/apps/app_service/promise_apps/promise_app_registry_cache.h" -#include <sstream> - +#include "base/scoped_observation.h" #include "chrome/browser/apps/app_service/package_id.h" #include "chrome/browser/apps/app_service/promise_apps/promise_app.h" -#include "components/services/app_service/public/cpp/app_types.h" +#include "chrome/browser/apps/app_service/promise_apps/promise_app_update.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -89,4 +88,86 @@ EXPECT_EQ(promise_app_list[1]->package_id, package_id_2); } +class PromiseAppRegistryCacheObserverTest : public testing::Test, + PromiseAppRegistryCache::Observer { + public: + void SetUp() override { + cache_ = std::make_unique<PromiseAppRegistryCache>(); + } + + // apps::PromiseAppRegistryCache::Observer: + void OnPromiseAppUpdate(const PromiseAppUpdate& update) override { + EXPECT_EQ(update, *expected_update_); + on_promise_app_updated_called_ = true; + } + + void OnPromiseAppRegistryCacheWillBeDestroyed( + apps::PromiseAppRegistryCache* cache) override { + obs_.Reset(); + } + + void ExpectPromiseAppUpdate(std::unique_ptr<PromiseAppUpdate> update) { + expected_update_ = std::move(update); + if (!obs_.IsObserving()) { + obs_.Observe(cache()); + } + on_promise_app_updated_called_ = false; + } + + bool CheckOnPromiseAppUpdatedCalled() { + return on_promise_app_updated_called_; + } + + PromiseAppRegistryCache* cache() { return cache_.get(); } + + private: + base::ScopedObservation<PromiseAppRegistryCache, + PromiseAppRegistryCache::Observer> + obs_{this}; + std::unique_ptr<PromiseAppUpdate> expected_update_; + std::unique_ptr<PromiseAppRegistryCache> cache_; + bool on_promise_app_updated_called_; +}; + +TEST_F(PromiseAppRegistryCacheObserverTest, OnPromiseAppUpdate_NewPromiseApp) { + auto promise_app = std::make_unique<PromiseApp>(kTestPackageId); + promise_app->name = "Test"; + promise_app->progress = 0; + promise_app->status = PromiseStatus::kPending; + promise_app->should_show = false; + + ASSERT_FALSE(cache()->HasPromiseApp(kTestPackageId)); + + // Check that we get the appropriate update when registering a new promise + // app. + ExpectPromiseAppUpdate( + std::make_unique<PromiseAppUpdate>(nullptr, promise_app.get())); + cache()->OnPromiseApp(std::move(promise_app)); + EXPECT_TRUE(CheckOnPromiseAppUpdatedCalled()); +} + +TEST_F(PromiseAppRegistryCacheObserverTest, + OnPromiseAppUpdate_ModifyPromiseApp) { + auto promise_app_pending = std::make_unique<PromiseApp>(kTestPackageId); + promise_app_pending->status = PromiseStatus::kPending; + promise_app_pending->should_show = false; + ExpectPromiseAppUpdate( + std::make_unique<PromiseAppUpdate>(nullptr, promise_app_pending.get())); + cache()->OnPromiseApp(promise_app_pending->Clone()); + EXPECT_TRUE(CheckOnPromiseAppUpdatedCalled()); + + // Check that we get the appropriate update when going from pending to + // installing. + auto promise_app_installing = std::make_unique<PromiseApp>(kTestPackageId); + promise_app_installing->name = "Test"; + promise_app_installing->progress = 0.4; + promise_app_installing->status = PromiseStatus::kInstalling; + promise_app_installing->should_show = true; + ExpectPromiseAppUpdate(std::make_unique<PromiseAppUpdate>( + promise_app_pending.get(), promise_app_installing.get())); + EXPECT_FALSE(CheckOnPromiseAppUpdatedCalled()); + cache()->OnPromiseApp(std::move(promise_app_installing)); + EXPECT_TRUE(CheckOnPromiseAppUpdatedCalled()); +} + } // namespace apps
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc index 31fbe01..6ac0eb85 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc +++ b/chrome/browser/apps/app_service/promise_apps/promise_app_service_unittest.cc
@@ -4,6 +4,7 @@ #include "chrome/browser/apps/app_service/promise_apps/promise_app_service.h" +#include "base/scoped_observation.h" #include "chrome/browser/apps/app_service/package_id.h" #include "chrome/browser/apps/app_service/promise_apps/promise_app.h" #include "chrome/browser/apps/app_service/promise_apps/promise_app_almanac_connector.h" @@ -47,11 +48,8 @@ std::make_unique<image_fetcher::FakeImageDecoder>(), profile_->GetURLLoaderFactory()); service_->SetImageFetcherForTesting(std::move(image_fetcher)); - Observe(cache()); } - ~PromiseAppServiceTest() override { Observe(nullptr); } - network::TestURLLoaderFactory* url_loader_factory() { return url_loader_factory_.get(); } @@ -64,9 +62,18 @@ PromiseAppService* service() { return service_.get(); } - void WaitForPromiseAppUpdates(int num_updates) { + void ExpectNumUpdates(int num_updates) { expected_num_updates_ = num_updates; current_num_updates_ = 0; + if (!obs_.IsObserving()) { + obs_.Observe(cache()); + } + } + + void WaitForPromiseAppUpdates() { + if (expected_num_updates_ == current_num_updates_) { + return; + } wait_run_loop_ = std::make_unique<base::RunLoop>(); wait_run_loop_->Run(); } @@ -81,7 +88,9 @@ } void OnPromiseAppRegistryCacheWillBeDestroyed( - apps::PromiseAppRegistryCache* cache) override {} + apps::PromiseAppRegistryCache* cache) override { + obs_.Reset(); + } private: content::BrowserTaskEnvironment task_environment_; @@ -89,6 +98,9 @@ std::unique_ptr<PromiseAppService> service_; std::unique_ptr<Profile> profile_; std::unique_ptr<network::TestURLLoaderFactory> url_loader_factory_; + base::ScopedObservation<PromiseAppRegistryCache, + PromiseAppRegistryCache::Observer> + obs_{this}; scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_; ash::system::ScopedFakeStatisticsProvider fake_statistics_provider_; @@ -108,6 +120,8 @@ response.mutable_icons(0)->set_mime_type("image/png"); response.mutable_icons(0)->set_is_masking_allowed(true); + // Wait for the registry cache update that follows the Almanac API response. + ExpectNumUpdates(/*num_updates=*/2); url_loader_factory()->AddResponse( PromiseAppAlmanacConnector::GetServerUrl().spec(), response.SerializeAsString()); @@ -115,8 +129,7 @@ // Add promise app to cache and trigger Almanac API call. service()->OnPromiseApp(std::make_unique<PromiseApp>(kTestPackageId)); - // Wait for the registry cache update that follows the Almanac API response. - WaitForPromiseAppUpdates(/*num_updates=*/1); + WaitForPromiseAppUpdates(); const PromiseApp* promise_app_result = cache()->GetPromiseAppForTesting(kTestPackageId); @@ -157,11 +170,12 @@ EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId)); // Add promise app to cache and trigger Almanac API and image fetcher calls. + ExpectNumUpdates(/*num_updates=*/3); service()->OnPromiseApp(std::make_unique<PromiseApp>(kTestPackageId)); // Wait for the separate registry cache updates that follow the Almanac API // response and image fetcher completion. - WaitForPromiseAppUpdates(/*num_updates=*/2); + WaitForPromiseAppUpdates(); // Verify that there are 2 icons now saved in cache. EXPECT_TRUE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId)); @@ -200,10 +214,10 @@ EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId)); // Add promise app to cache and trigger Almanac API call. + ExpectNumUpdates(/*num_updates=*/2); service()->OnPromiseApp(std::make_unique<PromiseApp>(kTestPackageId)); - // Wait for the registry cache update that follows the Almanac API response. - WaitForPromiseAppUpdates(/*num_updates=*/1); + WaitForPromiseAppUpdates(); // Icon cache should still be empty. EXPECT_FALSE(icon_cache()->DoesPackageIdHaveIcons(kTestPackageId));
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc index 380300a9..804a6d4 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc +++ b/chrome/browser/apps/app_service/promise_apps/promise_app_update.cc
@@ -21,6 +21,25 @@ } } +bool PromiseAppUpdate::operator==(const PromiseAppUpdate& rhs) const { + bool states_are_same = false; + bool deltas_are_same = false; + if (!this->state_ && !rhs.state_) { + states_are_same = true; + } + if (this->state_ && rhs.state_) { + states_are_same = *(this->state_) == *(rhs.state_); + } + + if (!this->delta_ && !rhs.delta_) { + deltas_are_same = true; + } + if (this->delta_ && rhs.delta_) { + deltas_are_same = *(this->delta_) == *(rhs.delta_); + } + return states_are_same && deltas_are_same; +} + void PromiseAppUpdate::Merge(PromiseApp* state, const PromiseApp* delta) { DCHECK(state); if (!delta) {
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_update.h b/chrome/browser/apps/app_service/promise_apps/promise_app_update.h index ce33131..ec58d69 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app_update.h +++ b/chrome/browser/apps/app_service/promise_apps/promise_app_update.h
@@ -22,6 +22,8 @@ PromiseAppUpdate(const PromiseAppUpdate&) = delete; PromiseAppUpdate& operator=(const PromiseAppUpdate&) = delete; + bool operator==(const PromiseAppUpdate&) const; + const PackageId& PackageId() const; // Indicates the app name for the package. If app name is not known or still
diff --git a/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc b/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc index f64f87c..764bc32 100644 --- a/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc +++ b/chrome/browser/apps/app_service/promise_apps/promise_app_update_unittest.cc
@@ -97,4 +97,64 @@ EXPECT_EQ(u.ShouldShowChanged(), true); } +TEST_F(PromiseAppUpdateTest, Equal) { + auto state_1 = std::make_unique<PromiseApp>(package_id); + state_1->status = PromiseStatus::kPending; + state_1->should_show = false; + + auto state_2 = std::make_unique<PromiseApp>(package_id); + state_2->name = "Name"; + state_2->progress = 0.9; + state_2->status = PromiseStatus::kInstalling; + state_2->should_show = true; + + auto delta_1 = std::make_unique<PromiseApp>(package_id); + state_1->status = PromiseStatus::kInstalling; + state_1->should_show = true; + + auto delta_2 = std::make_unique<PromiseApp>(package_id); + delta_2->progress = 0.9; + state_2->status = PromiseStatus::kInstalling; + + // Test nullptr handling. + EXPECT_EQ(PromiseAppUpdate(nullptr, delta_1.get()), + PromiseAppUpdate(nullptr, delta_1.get())); + EXPECT_EQ(PromiseAppUpdate(state_1.get(), nullptr), + PromiseAppUpdate(state_1.get(), nullptr)); + EXPECT_NE(PromiseAppUpdate(nullptr, delta_1.get()), + PromiseAppUpdate(state_1.get(), nullptr)); + EXPECT_NE(PromiseAppUpdate(state_1.get(), nullptr), + PromiseAppUpdate(nullptr, delta_1.get())); + EXPECT_NE(PromiseAppUpdate(nullptr, delta_1.get()), + PromiseAppUpdate(state_1.get(), delta_1.get())); + EXPECT_NE(PromiseAppUpdate(state_1.get(), nullptr), + PromiseAppUpdate(state_1.get(), delta_1.get())); + EXPECT_NE(PromiseAppUpdate(state_1.get(), delta_1.get()), + PromiseAppUpdate(nullptr, delta_1.get())); + EXPECT_NE(PromiseAppUpdate(state_1.get(), delta_1.get()), + PromiseAppUpdate(state_1.get(), nullptr)); + + // Test equal. + EXPECT_EQ(PromiseAppUpdate(state_1.get(), delta_1.get()), + PromiseAppUpdate(state_1.get(), delta_1.get())); + EXPECT_EQ(PromiseAppUpdate(state_1.get(), delta_2.get()), + PromiseAppUpdate(state_1.get(), delta_2.get())); + EXPECT_EQ(PromiseAppUpdate(state_2.get(), delta_1.get()), + PromiseAppUpdate(state_2.get(), delta_1.get())); + EXPECT_EQ(PromiseAppUpdate(state_2.get(), delta_2.get()), + PromiseAppUpdate(state_2.get(), delta_2.get())); + + // Test deep equal. + EXPECT_EQ(PromiseAppUpdate(state_1.get(), delta_1.get()), + PromiseAppUpdate(state_1->Clone().get(), delta_1->Clone().get())); + + // Test not equal. + EXPECT_NE(PromiseAppUpdate(state_1.get(), delta_1.get()), + PromiseAppUpdate(state_2.get(), delta_1.get())); + EXPECT_NE(PromiseAppUpdate(state_1.get(), delta_1.get()), + PromiseAppUpdate(state_2.get(), delta_2.get())); + EXPECT_NE(PromiseAppUpdate(state_1.get(), delta_1.get()), + PromiseAppUpdate(state_1.get(), delta_2.get())); +} + } // namespace apps
diff --git a/chrome/browser/apps/app_shim/app_shim_listener_browsertest_mac.mm b/chrome/browser/apps/app_shim/app_shim_listener_browsertest_mac.mm index c87e889..50fc3e92 100644 --- a/chrome/browser/apps/app_shim/app_shim_listener_browsertest_mac.mm +++ b/chrome/browser/apps/app_shim/app_shim_listener_browsertest_mac.mm
@@ -108,9 +108,9 @@ // lifetime here. const IpczAPI& ipcz = mojo::core::GetIpczAPIForMojo(); IpczHandle node; - IpczResult result = ipcz.CreateNode( - &mojo::core::GetIpczDriverForMojo(), IPCZ_INVALID_DRIVER_HANDLE, - IPCZ_CREATE_NODE_AS_BROKER, nullptr, &node); + IpczResult result = + ipcz.CreateNode(&mojo::core::GetIpczDriverForMojo(), + IPCZ_CREATE_NODE_AS_BROKER, nullptr, &node); CHECK_EQ(IPCZ_RESULT_OK, result); secondary_ipcz_broker_.reset(mojo::Handle{node});
diff --git a/chrome/browser/ash/BUILD.gn b/chrome/browser/ash/BUILD.gn index 9e1c533..df01251 100644 --- a/chrome/browser/ash/BUILD.gn +++ b/chrome/browser/ash/BUILD.gn
@@ -393,6 +393,8 @@ "arc/input_overlay/touch_id_manager.h", "arc/input_overlay/touch_injector.cc", "arc/input_overlay/touch_injector.h", + "arc/input_overlay/touch_injector_observer.cc", + "arc/input_overlay/touch_injector_observer.h", "arc/input_overlay/ui/action_label.cc", "arc/input_overlay/ui/action_label.h", "arc/input_overlay/ui/action_view.cc", @@ -1824,6 +1826,10 @@ "login/screens/parental_handoff_screen.h", "login/screens/pin_setup_screen.cc", "login/screens/pin_setup_screen.h", + + # Template used by the `tools/oobe/generate_screen_template.py` script. + "login/screens/placeholder_screen.cc", + "login/screens/placeholder_screen.h", "login/screens/quick_start_screen.cc", "login/screens/quick_start_screen.h", "login/screens/recommend_apps/fake_recommend_apps_fetcher.cc", @@ -3609,11 +3615,7 @@ "//components/reporting/proto:record_proto", "//components/reporting/resources:resource_manager", "//components/reporting/storage_selector", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:instance_update", - "//components/services/app_service/public/cpp:intents", + "//components/services/app_service", "//components/services/unzip/public/cpp", "//components/session_manager:base", "//components/session_manager/core", @@ -6080,14 +6082,8 @@ "//components/reporting/util:test_callbacks_support", "//components/safe_browsing/core/common:safe_browsing_prefs", "//components/search_engines", - "//components/services/app_service/public/cpp:app_file_handling", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_loader", + "//components/services/app_service", "//components/services/app_service/public/cpp:icon_loader_test_support", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:instance_update", - "//components/services/app_service/public/cpp:intents", "//components/services/app_service/public/cpp:test_support", "//components/services/app_service/public/protos", "//components/services/filesystem/public/mojom",
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc index 8a73e845..d12af64 100644 --- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.cc
@@ -553,6 +553,16 @@ return input_mapping_view_->children().size(); } +void DisplayOverlayController::AddTouchInjectorObserver( + TouchInjectorObserver* observer) { + touch_injector_->AddObserver(observer); +} + +void DisplayOverlayController::RemoveTouchInjectorObserver( + TouchInjectorObserver* observer) { + touch_injector_->RemoveObserver(observer); +} + void DisplayOverlayController::OnMouseEvent(ui::MouseEvent* event) { if ((display_mode_ == DisplayMode::kView && !nudge_view_) || event->type() != ui::ET_MOUSE_PRESSED) {
diff --git a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h index 18641533..ea17beeb 100644 --- a/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h +++ b/chrome/browser/ash/arc/input_overlay/display_overlay_controller.h
@@ -33,6 +33,7 @@ class MessageView; class NudgeView; class TouchInjector; +class TouchInjectorObserver; // DisplayOverlayController manages the input mapping view, view and edit mode, // menu, and educational dialog. It also handles the visibility of the @@ -82,6 +83,10 @@ // For menu entry hover state: void SetMenuEntryHoverState(bool curr_hover_state); + // Add UIs to observer touch injector change. + void AddTouchInjectorObserver(TouchInjectorObserver* observer); + void RemoveTouchInjectorObserver(TouchInjectorObserver* observer); + // ui::EventHandler: void OnMouseEvent(ui::MouseEvent* event) override; void OnTouchEvent(ui::TouchEvent* event) override;
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.cc b/chrome/browser/ash/arc/input_overlay/touch_injector.cc index bec7d8fa..7218172 100644 --- a/chrome/browser/ash/arc/input_overlay/touch_injector.cc +++ b/chrome/browser/ash/arc/input_overlay/touch_injector.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/ash/arc/input_overlay/arc_input_overlay_uma.h" #include "chrome/browser/ash/arc/input_overlay/constants.h" #include "chrome/browser/ash/arc/input_overlay/touch_id_manager.h" +#include "chrome/browser/ash/arc/input_overlay/touch_injector_observer.h" #include "chrome/browser/ash/arc/input_overlay/util.h" #include "ui/aura/window.h" #include "ui/display/display.h" @@ -884,6 +885,14 @@ } } +void TouchInjector::AddObserver(TouchInjectorObserver* observer) { + observers_.AddObserver(observer); +} + +void TouchInjector::RemoveObserver(TouchInjectorObserver* observer) { + observers_.RemoveObserver(observer); +} + std::unique_ptr<Action> TouchInjector::CreateRawAction(ActionType action_type) { std::unique_ptr<Action> action; switch (action_type) { @@ -962,6 +971,31 @@ added_default_actions.clear(); } +void TouchInjector::NotifyActionAdded(const Action& action) { + for (auto& observer : observers_) { + observer.OnActionAdded(action); + } +} + +void TouchInjector::NotifyActionRemoved(const Action& action) { + for (auto& observer : observers_) { + observer.OnActionRemoved(action); + } +} + +void TouchInjector::NotifyActionTypeChanged(const Action& action, + const Action& new_action) { + for (auto& observer : observers_) { + observer.OnActionTypeChanged(action, new_action); + } +} + +void TouchInjector::NotifyActionUpdated(const Action& action) { + for (auto& observer : observers_) { + observer.OnActionUpdated(action); + } +} + int TouchInjector::GetNextActionID() { return next_action_id_++; }
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector.h b/chrome/browser/ash/arc/input_overlay/touch_injector.h index d45feff2..51f25be 100644 --- a/chrome/browser/ash/arc/input_overlay/touch_injector.h +++ b/chrome/browser/ash/arc/input_overlay/touch_injector.h
@@ -11,6 +11,7 @@ #include "ash/constants/ash_features.h" #include "base/functional/callback.h" #include "base/memory/raw_ptr.h" +#include "base/observer_list.h" #include "base/scoped_observation.h" #include "base/values.h" #include "chrome/browser/ash/arc/input_overlay/display_overlay_controller.h" @@ -30,6 +31,7 @@ class Action; class ArcInputOverlayManagerTest; +class TouchInjectorObserver; // If the following touch move sent immediately, the touch move event is not // processed correctly by apps. This is a delayed time to send touch move @@ -117,6 +119,9 @@ // Remove action view for |action|. void RemoveActionView(Action* action); + void AddObserver(TouchInjectorObserver* observer); + void RemoveObserver(TouchInjectorObserver* observer); + // UMA stats. void RecordMenuStateOnLaunch(); @@ -250,6 +255,12 @@ void RemoveDefaultActionsAndViews( std::vector<Action*>& added_default_actions); + // For observers. + void NotifyActionAdded(const Action& action); + void NotifyActionRemoved(const Action& action); + void NotifyActionTypeChanged(const Action& action, const Action& new_action); + void NotifyActionUpdated(const Action& action); + // For test. int GetRewrittenTouchIdForTesting(ui::PointerId original_id); gfx::PointF GetRewrittenRootLocationForTesting(ui::PointerId original_id); @@ -308,6 +319,8 @@ std::vector<Action*> pending_add_default_actions_; std::vector<Action*> pending_delete_default_actions_; + base::ReentrantObserverList<TouchInjectorObserver> observers_; + // Callback when saving proto file. OnSaveProtoFileCallback save_file_callback_;
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector_observer.cc b/chrome/browser/ash/arc/input_overlay/touch_injector_observer.cc new file mode 100644 index 0000000..8019435 --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/touch_injector_observer.cc
@@ -0,0 +1,13 @@ +// 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 "chrome/browser/ash/arc/input_overlay/touch_injector_observer.h" + +namespace arc::input_overlay { + +TouchInjectorObserver::TouchInjectorObserver() = default; + +TouchInjectorObserver::~TouchInjectorObserver() = default; + +} // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/touch_injector_observer.h b/chrome/browser/ash/arc/input_overlay/touch_injector_observer.h new file mode 100644 index 0000000..d608cb3e --- /dev/null +++ b/chrome/browser/ash/arc/input_overlay/touch_injector_observer.h
@@ -0,0 +1,34 @@ +// 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 CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_TOUCH_INJECTOR_OBSERVER_H_ +#define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_TOUCH_INJECTOR_OBSERVER_H_ + +#include "base/observer_list_types.h" + +namespace arc::input_overlay { + +class Action; + +// Observer for UIs to update the content when the touch injector updates, adds, +// removes actions and changes action types. +class TouchInjectorObserver : public base::CheckedObserver { + public: + TouchInjectorObserver(); + + virtual void OnActionAdded(const Action& action) {} + virtual void OnActionRemoved(const Action& action) {} + // Once action type is changed, the original action is removed and + // |new_action| with new type is added. + virtual void OnActionTypeChanged(const Action& action, + const Action& new_action) {} + virtual void OnActionUpdated(const Action& action) {} + + protected: + ~TouchInjectorObserver() override; +}; + +} // namespace arc::input_overlay + +#endif // CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_TOUCH_INJECTOR_OBSERVER_H_
diff --git a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc index e24f8b3..1d0738f 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.cc
@@ -100,9 +100,13 @@ ButtonOptionsMenu::ButtonOptionsMenu(DisplayOverlayController* controller, Action* action) - : display_overlay_controller_(controller), action_(action) {} + : TouchInjectorObserver(), controller_(controller), action_(action) { + controller_->AddTouchInjectorObserver(this); +} -ButtonOptionsMenu::~ButtonOptionsMenu() = default; +ButtonOptionsMenu::~ButtonOptionsMenu() { + controller_->RemoveTouchInjectorObserver(this); +} void ButtonOptionsMenu::Init() { SetUseDefaultFillLayout(true); @@ -302,8 +306,7 @@ auto position = action_->GetUICenterPosition(); auto x = position.x(); auto y = position.y(); - auto parent_size = - display_overlay_controller_->GetOverlayWidgetContentsView()->size(); + auto parent_size = controller_->GetOverlayWidgetContentsView()->size(); // Set the menu at the middle if there is not enough margin on the right // or left side. @@ -322,12 +325,12 @@ void ButtonOptionsMenu::OnTrashButtonPressed() { // TODO(b/270969760): Implement close menu functionality. - display_overlay_controller_->RemoveButtonOptionsMenu(); + controller_->RemoveButtonOptionsMenu(); } void ButtonOptionsMenu::OnDoneButtonPressed() { // TODO(b/270969760): Implement save menu functionality. - display_overlay_controller_->RemoveButtonOptionsMenu(); + controller_->RemoveButtonOptionsMenu(); } void ButtonOptionsMenu::OnTapButtonPressed() { @@ -364,4 +367,17 @@ return gfx::Size(kMenuWidth, GetHeightForWidth(kMenuWidth)); } +void ButtonOptionsMenu::OnActionRemoved(const Action& action) { + NOTIMPLEMENTED(); +} + +void ButtonOptionsMenu::OnActionTypeChanged(const Action& action, + const Action& new_action) { + NOTIMPLEMENTED(); +} + +void ButtonOptionsMenu::OnActionUpdated(const Action& action) { + NOTIMPLEMENTED(); +} + } // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h index 1e6db663..d52423da 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h +++ b/chrome/browser/ash/arc/input_overlay/ui/button_options_menu.h
@@ -9,6 +9,7 @@ #include "ash/style/rounded_container.h" #include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" +#include "chrome/browser/ash/arc/input_overlay/touch_injector_observer.h" #include "ui/color/color_id.h" #include "ui/events/event.h" #include "ui/views/view.h" @@ -37,14 +38,12 @@ // ||"Button label" > | // ||"Unassigned" | // +----------------------------------+ -class ButtonOptionsMenu : public views::View { +class ButtonOptionsMenu : public views::View, public TouchInjectorObserver { public: - static ButtonOptionsMenu* Show( - DisplayOverlayController* display_overlay_controller, - Action* action); + static ButtonOptionsMenu* Show(DisplayOverlayController* controller, + Action* action); - ButtonOptionsMenu(DisplayOverlayController* display_overlay_controller, - Action* action); + ButtonOptionsMenu(DisplayOverlayController* controller, Action* action); ButtonOptionsMenu(const ButtonOptionsMenu&) = delete; ButtonOptionsMenu& operator=(const ButtonOptionsMenu&) = delete; ~ButtonOptionsMenu() override; @@ -75,8 +74,14 @@ void OnPaintBackground(gfx::Canvas* canvas) override; gfx::Size CalculatePreferredSize() const override; + // TouchInjectorObserver: + void OnActionRemoved(const Action& action) override; + void OnActionTypeChanged(const Action& action, + const Action& new_action) override; + void OnActionUpdated(const Action& action) override; + // DisplayOverlayController owns this class, no need to deallocate. - const raw_ptr<DisplayOverlayController> display_overlay_controller_ = nullptr; + const raw_ptr<DisplayOverlayController> controller_ = nullptr; const raw_ptr<Action> action_ = nullptr; };
diff --git a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc index 7aab699..16aabd9 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc +++ b/chrome/browser/ash/arc/input_overlay/ui/editing_list.cc
@@ -46,8 +46,13 @@ } EditingList::EditingList(DisplayOverlayController* controller) - : controller_(controller) {} -EditingList::~EditingList() = default; + : TouchInjectorObserver(), controller_(controller) { + controller_->AddTouchInjectorObserver(this); +} + +EditingList::~EditingList() { + controller_->RemoveTouchInjectorObserver(this); +} void EditingList::Init() { SetUseDefaultFillLayout(true); @@ -99,7 +104,7 @@ header_container->AddChildView(std::make_unique<ash::IconButton>( base::BindRepeating(&EditingList::OnAddButtonPressed, base::Unretained(this)), - ash::IconButton::Type::kMedium, &kAddIcon, + ash::IconButton::Type::kMedium, &kGameControlsAddIcon, // TODO(b/279117180): Update a11y string. IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)); header_container->AddChildView(ash::bubble_utils::CreateLabel( @@ -109,7 +114,7 @@ header_container->AddChildView(std::make_unique<ash::IconButton>( base::BindRepeating(&EditingList::OnDoneButtonPressed, base::Unretained(this)), - ash::IconButton::Type::kMedium, &ash::kCheckIcon, + ash::IconButton::Type::kMedium, &kGameControlsDoneIcon, // TODO(b/279117180): Update a11y string. IDS_APP_LIST_FOLDER_NAME_PLACEHOLDER)); } @@ -184,4 +189,20 @@ return gfx::Size(kMainContainerWidth, GetHeightForWidth(kMainContainerWidth)); } +void EditingList::OnActionAdded(const Action& action) { + NOTIMPLEMENTED(); +} +void EditingList::OnActionRemoved(const Action& action) { + NOTIMPLEMENTED(); +} + +void EditingList::OnActionTypeChanged(const Action& action, + const Action& new_action) { + NOTIMPLEMENTED(); +} + +void EditingList::OnActionUpdated(const Action& action) { + NOTIMPLEMENTED(); +} + } // namespace arc::input_overlay
diff --git a/chrome/browser/ash/arc/input_overlay/ui/editing_list.h b/chrome/browser/ash/arc/input_overlay/ui/editing_list.h index 233b00ea..d657e49 100644 --- a/chrome/browser/ash/arc/input_overlay/ui/editing_list.h +++ b/chrome/browser/ash/arc/input_overlay/ui/editing_list.h
@@ -6,6 +6,7 @@ #define CHROME_BROWSER_ASH_ARC_INPUT_OVERLAY_UI_EDITING_LIST_H_ #include "base/memory/raw_ptr.h" +#include "chrome/browser/ash/arc/input_overlay/touch_injector_observer.h" #include "ui/views/view.h" namespace arc::input_overlay { @@ -22,7 +23,7 @@ // | |___________________________| | // |_________________________________| // -class EditingList : public views::View { +class EditingList : public views::View, public TouchInjectorObserver { public: static EditingList* Show(DisplayOverlayController* controller); @@ -47,6 +48,13 @@ // views::View: gfx::Size CalculatePreferredSize() const override; + // TouchInjectorObserver: + void OnActionAdded(const Action& action) override; + void OnActionRemoved(const Action& action) override; + void OnActionTypeChanged(const Action& action, + const Action& new_action) override; + void OnActionUpdated(const Action& action) override; + raw_ptr<DisplayOverlayController> controller_; };
diff --git a/chrome/browser/ash/borealis/borealis_features.cc b/chrome/browser/ash/borealis/borealis_features.cc index 37f97081d..fc1d46db 100644 --- a/chrome/browser/ash/borealis/borealis_features.cc +++ b/chrome/browser/ash/borealis/borealis_features.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/ash/settings/cros_settings.h" #include "chrome/browser/policy/profile_policy_connector.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/channel_info.h" #include "chrome/common/chrome_features.h" #include "chromeos/ash/components/install_attributes/install_attributes.h" #include "chromeos/ash/components/settings/cros_settings_names.h" @@ -152,11 +151,6 @@ return AllowStatus::kUserPrefBlocked; } - version_info::Channel c = chrome::GetChannel(); - if (c == version_info::Channel::STABLE) { - return AllowStatus::kBlockedOnStable; - } - if (!base::FeatureList::IsEnabled(ash::features::kBorealisPermitted)) { return AllowStatus::kBlockedByFlag; } @@ -230,9 +224,6 @@ "disabled)"; case AllowStatus::kUserPrefBlocked: return os << "Your admin has blocked borealis (for your account)"; - case AllowStatus::kBlockedOnStable: - return os << "Your ChromeOS channel must be set to Beta or Dev to run " - "Borealis"; case AllowStatus::kBlockedByFlag: return os << "Borealis is still being worked on. You must set the " "#borealis-enabled feature flag.";
diff --git a/chrome/browser/ash/borealis/borealis_features.h b/chrome/browser/ash/borealis/borealis_features.h index 0ab2786..5e24ac0 100644 --- a/chrome/browser/ash/borealis/borealis_features.h +++ b/chrome/browser/ash/borealis/borealis_features.h
@@ -35,7 +35,6 @@ kBlockedOnChildAccount, kVmPolicyBlocked, kUserPrefBlocked, - kBlockedOnStable, kBlockedByFlag, kUnsupportedModel, kHardwareChecksFailed,
diff --git a/chrome/browser/ash/crosapi/browser_util.cc b/chrome/browser/ash/crosapi/browser_util.cc index 60227266..9e99e0e 100644 --- a/chrome/browser/ash/crosapi/browser_util.cc +++ b/chrome/browser/ash/crosapi/browser_util.cc
@@ -1150,9 +1150,4 @@ ash::features::kEnforceAshExtensionKeeplist); } -bool IsAshDevToolEnabled() { - return IsAshWebBrowserEnabled() || - base::FeatureList::IsEnabled(ash::features::kAllowDevtoolsInSystemUI); -} - } // namespace crosapi::browser_util
diff --git a/chrome/browser/ash/crosapi/browser_util.h b/chrome/browser/ash/crosapi/browser_util.h index ae37524d..3df021e 100644 --- a/chrome/browser/ash/crosapi/browser_util.h +++ b/chrome/browser/ash/crosapi/browser_util.h
@@ -528,9 +528,6 @@ // Returns true if ash 1st party extension keep list should be enforced. bool ShouldEnforceAshExtensionKeepList(); -// Indicates whether user can open DevTools in Ash. -bool IsAshDevToolEnabled(); - } // namespace crosapi::browser_util #endif // CHROME_BROWSER_ASH_CROSAPI_BROWSER_UTIL_H_
diff --git a/chrome/browser/ash/extensions/file_manager/private_api_misc.cc b/chrome/browser/ash/extensions/file_manager/private_api_misc.cc index 210583b4..36925a7 100644 --- a/chrome/browser/ash/extensions/file_manager/private_api_misc.cc +++ b/chrome/browser/ash/extensions/file_manager/private_api_misc.cc
@@ -35,6 +35,7 @@ #include "chrome/browser/ash/drive/drive_integration_service.h" #include "chrome/browser/ash/drive/file_system_util.h" #include "chrome/browser/ash/extensions/file_manager/private_api_util.h" +#include "chrome/browser/ash/file_manager/file_tasks.h" #include "chrome/browser/ash/file_manager/fileapi_util.h" #include "chrome/browser/ash/file_manager/path_util.h" #include "chrome/browser/ash/file_manager/url_util.h" @@ -59,8 +60,10 @@ #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_helper.h" #include "chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h" +#include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/chrome_pages.h" #include "chrome/browser/ui/settings_window_manager_chromeos.h" +#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h" #include "chrome/browser/ui/webui/settings/chromeos/constants/routes_util.h" #include "chrome/common/extensions/api/file_manager_private_internal.h" #include "chrome/common/extensions/api/manifest_types.h" @@ -494,6 +497,24 @@ const absl::optional<Params> params = Params::Create(args()); EXTENSION_FUNCTION_VALIDATE(params); + Profile* profile = Profile::FromBrowserContext(browser_context()); + + if (ash::cloud_upload::IsEligibleAndEnabledUploadOfficeToCloud(profile) && + params->provider_id == + file_manager::file_tasks::GetODFSExtensionId(profile)) { + // Get Files App window, if it exists. + Browser* browser = + FindSystemWebAppBrowser(profile, ash::SystemWebAppType::FILE_MANAGER); + gfx::NativeWindow modal_parent = + browser ? browser->window()->GetNativeWindow() : nullptr; + + // This will call into service->RequestMount() if necessary. This is 'fire + // and forget' as Files app doesn't do anything if this succeeds or fails. + bool started = ash::cloud_upload::ShowConnectOneDriveDialog(modal_parent); + return RespondNow(started ? NoArguments() + : Error("Failed to request a new mount.")); + } + using ash::file_system_provider::ProviderId; using ash::file_system_provider::Service; Service* const service = Service::Get(browser_context());
diff --git a/chrome/browser/ash/file_manager/external_filesystem_apitest.cc b/chrome/browser/ash/file_manager/external_filesystem_apitest.cc index 0bbb8ec..0ce1de5 100644 --- a/chrome/browser/ash/file_manager/external_filesystem_apitest.cc +++ b/chrome/browser/ash/file_manager/external_filesystem_apitest.cc
@@ -140,9 +140,10 @@ base::StringPiece mtime_string, base::StringPiece atime_string) { base::Time mtime, atime; - auto result = base::Time::FromString(mtime_string.data(), &mtime) && - base::Time::FromString(atime_string.data(), &atime) && - base::TouchFile(path, atime, mtime); + auto result = + base::Time::FromString(std::string(mtime_string).c_str(), &mtime) && + base::Time::FromString(std::string(atime_string).c_str(), &atime) && + base::TouchFile(path, atime, mtime); return result; }
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc index 872f24d..0c16e8f 100644 --- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc +++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -573,7 +573,7 @@ // Maps |value| to base::Time. Returns true on success. static bool MapStringToTime(base::StringPiece value, base::Time* time) { - return base::Time::FromString(value.data(), time); + return base::Time::FromString(std::string(value).c_str(), time); } }; };
diff --git a/chrome/browser/ash/input_method/autocorrect_manager.cc b/chrome/browser/ash/input_method/autocorrect_manager.cc index 0f96fe10..68e02e0 100644 --- a/chrome/browser/ash/input_method/autocorrect_manager.cc +++ b/chrome/browser/ash/input_method/autocorrect_manager.cc
@@ -1045,12 +1045,18 @@ surrounding_text.selection_range.start() - autocorrect_range.start(); const uint32_t after = autocorrect_range.end() - surrounding_text.selection_range.end(); - input_context->DeleteSurroundingText(before, after); - // Replace with the original text. - input_context->CommitText( - pending_autocorrect_->original_text, - ui::TextInputClient::InsertTextCursorBehavior::kMoveCursorAfterText); + if (base::FeatureList::IsEnabled( + features::kAutocorrectUseReplaceSurroundingText)) { + input_context->ReplaceSurroundingText( + before, after, pending_autocorrect_->original_text); + } else { + input_context->DeleteSurroundingText(before, after); + // Replace with the original text. + input_context->CommitText( + pending_autocorrect_->original_text, + ui::TextInputClient::InsertTextCursorBehavior::kMoveCursorAfterText); + } } MeasureAndLogAssistiveAutocorrectQualityBreakdown(
diff --git a/chrome/browser/ash/input_method/input_method_engine_browsertests.cc b/chrome/browser/ash/input_method/input_method_engine_browsertests.cc index a72f80cc..4a875b5 100644 --- a/chrome/browser/ash/input_method/input_method_engine_browsertests.cc +++ b/chrome/browser/ash/input_method/input_method_engine_browsertests.cc
@@ -1199,7 +1199,7 @@ ASSERT_TRUE( content::ExecJs(browser()->tab_strip_model()->GetActiveWebContents(), - password_field_change_to_text_script.data())); + password_field_change_to_text_script)); ASSERT_TRUE(focus_listener.WaitUntilSatisfied()); ASSERT_TRUE(focus_listener.was_satisfied());
diff --git a/chrome/browser/ash/login/chrome_restart_request.cc b/chrome/browser/ash/login/chrome_restart_request.cc index ec2fa57..6d45f0e 100644 --- a/chrome/browser/ash/login/chrome_restart_request.cc +++ b/chrome/browser/ash/login/chrome_restart_request.cc
@@ -112,7 +112,6 @@ ::switches::kDisableGpuCompositing, ::switches::kDisableGpuRasterization, ::switches::kDisableMojoBroker, - ::switches::kDisablePepper3DImageChromium, ::switches::kDisableTouchDragDrop, ::switches::kDisableVideoCaptureUseGpuMemoryBuffer, ::switches::kDisableYUVImageDecoding,
diff --git a/chrome/browser/ash/login/screens/display_size_screen.cc b/chrome/browser/ash/login/screens/display_size_screen.cc index adf26a3..e47eb37 100644 --- a/chrome/browser/ash/login/screens/display_size_screen.cc +++ b/chrome/browser/ash/login/screens/display_size_screen.cc
@@ -220,13 +220,29 @@ BaseScreen::OnUserAction(args); } +std::string DisplaySizeScreen::RetrieveChoobeSubtitle() { + int percentage = + std::round(ProfileManager::GetActiveUserProfile()->GetPrefs()->GetDouble( + prefs::kOobeDisplaySizeFactorDeferred) * + 100); + + return base::NumberToString(percentage) + "%"; +} + ScreenSummary DisplaySizeScreen::GetScreenSummary() { ScreenSummary summary; summary.screen_id = DisplaySizeScreenView::kScreenId; - summary.icon_id = "oobe-32:display"; + summary.icon_id = "oobe-40:display-size-choobe"; summary.title_id = "choobeDisplaySizeTitle"; summary.is_revisitable = true; summary.is_synced = false; + + if (WizardController::default_controller() + ->choobe_flow_controller() + ->IsScreenCompleted(DisplaySizeScreenView::kScreenId)) { + summary.subtitle_resource = RetrieveChoobeSubtitle(); + } + return summary; }
diff --git a/chrome/browser/ash/login/screens/display_size_screen.h b/chrome/browser/ash/login/screens/display_size_screen.h index 300a5986..3eae332 100644 --- a/chrome/browser/ash/login/screens/display_size_screen.h +++ b/chrome/browser/ash/login/screens/display_size_screen.h
@@ -47,6 +47,7 @@ void HideImpl() override; void OnUserAction(const base::Value::List& args) override; ScreenSummary GetScreenSummary() override; + std::string RetrieveChoobeSubtitle(); base::WeakPtr<DisplaySizeScreenView> view_; ScreenExitCallback exit_callback_;
diff --git a/chrome/browser/ash/login/screens/placeholder_screen.cc b/chrome/browser/ash/login/screens/placeholder_screen.cc new file mode 100644 index 0000000..ccbc7b99 --- /dev/null +++ b/chrome/browser/ash/login/screens/placeholder_screen.cc
@@ -0,0 +1,67 @@ +// 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 "chrome/browser/ash/login/screens/placeholder_screen.h" + +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "chrome/browser/ash/login/oobe_screen.h" +#include "chrome/browser/ash/login/screens/base_screen.h" +#include "chrome/browser/ash/login/wizard_context.h" +#include "chrome/browser/ui/webui/ash/login/placeholder_screen_handler.h" + +namespace ash { +namespace { + +constexpr char kUserActionBackButtonClicked[] = "back"; +constexpr char kUserActionNextButtonClicked[] = "next"; + +} // namespace + +// static +std::string PlaceholderScreen::GetResultString(Result result) { + switch (result) { + case Result::kNext: + return "Next"; + case Result::kBack: + return "Back"; + case Result::kNotApplicable: + return BaseScreen::kNotApplicable; + } +} + +PlaceholderScreen::PlaceholderScreen(base::WeakPtr<PlaceholderScreenView> view, + const ScreenExitCallback& exit_callback) + : BaseScreen(PlaceholderScreenView::kScreenId, OobeScreenPriority::DEFAULT), + view_(std::move(view)), + exit_callback_(exit_callback) {} + +PlaceholderScreen::~PlaceholderScreen() = default; + +bool PlaceholderScreen::MaybeSkip(WizardContext& context) { + return false; +} + +void PlaceholderScreen::ShowImpl() { + if (!view_) { + return; + } + + view_->Show(); +} + +void PlaceholderScreen::HideImpl() {} + +void PlaceholderScreen::OnUserAction(const base::Value::List& args) { + const std::string& action_id = args[0].GetString(); + if (action_id == kUserActionNextButtonClicked) { + exit_callback_.Run(Result::kNext); + } else if (action_id == kUserActionBackButtonClicked) { + exit_callback_.Run(Result::kBack); + } else { + BaseScreen::OnUserAction(args); + } +} + +} // namespace ash
diff --git a/chrome/browser/ash/login/screens/placeholder_screen.h b/chrome/browser/ash/login/screens/placeholder_screen.h new file mode 100644 index 0000000..6b5af2fd --- /dev/null +++ b/chrome/browser/ash/login/screens/placeholder_screen.h
@@ -0,0 +1,52 @@ +// 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 CHROME_BROWSER_ASH_LOGIN_SCREENS_PLACEHOLDER_SCREEN_H_ +#define CHROME_BROWSER_ASH_LOGIN_SCREENS_PLACEHOLDER_SCREEN_H_ + +#include <memory> +#include <string> + +#include "base/functional/callback.h" +#include "base/memory/weak_ptr.h" +#include "base/values.h" +#include "chrome/browser/ash/login/screens/base_screen.h" +#include "chrome/browser/ash/login/wizard_context.h" + +namespace ash { + +class PlaceholderScreenView; + +class PlaceholderScreen : public BaseScreen { + public: + using TView = PlaceholderScreenView; + + enum class Result { kNext = 0, kBack, kNotApplicable }; + + using ScreenExitCallback = base::RepeatingCallback<void(Result result)>; + + PlaceholderScreen(base::WeakPtr<PlaceholderScreenView> view, + const ScreenExitCallback& exit_callback); + + PlaceholderScreen(const PlaceholderScreen&) = delete; + PlaceholderScreen& operator=(const PlaceholderScreen&) = delete; + + ~PlaceholderScreen() override; + + static std::string GetResultString(Result result); + + private: + // BaseScreen: + bool MaybeSkip(WizardContext& context) override; + void ShowImpl() override; + void HideImpl() override; + void OnUserAction(const base::Value::List& args) override; + + base::WeakPtr<PlaceholderScreenView> view_; + ScreenExitCallback exit_callback_; +}; + +} // namespace ash + +#endif // CHROME_BROWSER_ASH_LOGIN_SCREENS_PLACEHOLDER_SCREEN_H_
diff --git a/chrome/browser/ash/login/screens/theme_selection_screen.cc b/chrome/browser/ash/login/screens/theme_selection_screen.cc index 44a4187..dcc0232 100644 --- a/chrome/browser/ash/login/screens/theme_selection_screen.cc +++ b/chrome/browser/ash/login/screens/theme_selection_screen.cc
@@ -93,6 +93,19 @@ ThemeSelectionScreen::~ThemeSelectionScreen() = default; +std::string ThemeSelectionScreen::RetrieveChoobeSubtitle() { + Profile* profile = ProfileManager::GetActiveUserProfile(); + ThemeSelectionScreen::SelectedTheme theme = GetSelectedTheme(profile); + switch (theme) { + case ThemeSelectionScreen::SelectedTheme::kAuto: + return "autoThemeLabel"; + case ThemeSelectionScreen::SelectedTheme::kDark: + return "darkThemeLabel"; + case ThemeSelectionScreen::SelectedTheme::kLight: + return "lightThemeLabel"; + } +} + bool ThemeSelectionScreen::ShouldBeSkipped(const WizardContext& context) const { if (context.skip_post_login_screens_for_tests) return true; @@ -180,10 +193,17 @@ ScreenSummary ThemeSelectionScreen::GetScreenSummary() { ScreenSummary summary; summary.screen_id = ThemeSelectionScreenView::kScreenId; - summary.icon_id = "oobe-32:stars"; + summary.icon_id = "oobe-40:theme-choobe"; summary.title_id = "choobeThemeSelectionTitle"; summary.is_revisitable = true; summary.is_synced = false; + + if (WizardController::default_controller() + ->choobe_flow_controller() + ->IsScreenCompleted(ThemeSelectionScreenView::kScreenId)) { + summary.subtitle_resource = RetrieveChoobeSubtitle(); + } + return summary; }
diff --git a/chrome/browser/ash/login/screens/theme_selection_screen.h b/chrome/browser/ash/login/screens/theme_selection_screen.h index 4844bcb..0e58783 100644 --- a/chrome/browser/ash/login/screens/theme_selection_screen.h +++ b/chrome/browser/ash/login/screens/theme_selection_screen.h
@@ -10,6 +10,7 @@ #include "base/functional/callback.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/ash/login/screens/base_screen.h" +#include "chrome/browser/profiles/profile_manager.h" namespace ash { @@ -64,6 +65,7 @@ void HideImpl() override; void OnUserAction(const base::Value::List& args) override; ScreenSummary GetScreenSummary() override; + std::string RetrieveChoobeSubtitle(); base::WeakPtr<ThemeSelectionScreenView> view_; ScreenExitCallback exit_callback_;
diff --git a/chrome/browser/ash/login/screens/touchpad_scroll_screen.cc b/chrome/browser/ash/login/screens/touchpad_scroll_screen.cc index 70cc06b..43f373b 100644 --- a/chrome/browser/ash/login/screens/touchpad_scroll_screen.cc +++ b/chrome/browser/ash/login/screens/touchpad_scroll_screen.cc
@@ -155,16 +155,30 @@ BaseScreen::OnUserAction(args); } +std::string TouchpadScrollScreen::RetrieveChoobeSubtitle() { + if (GetNaturalScrollPrefValue()) { + return "choobeTouchpadScrollSubtitleEnabled"; + } + return "choobeTouchpadScrollSubtitleDisabled"; +} + ScreenSummary TouchpadScrollScreen::GetScreenSummary() { ScreenSummary summary; summary.screen_id = TouchpadScrollScreenView::kScreenId; - summary.icon_id = "oobe-32:scroll-direction"; + summary.icon_id = "oobe-40:scroll-choobe"; summary.title_id = "choobeTouchpadScrollTitle"; - summary.is_revisitable = false; + summary.is_revisitable = true; summary.is_synced = !ProfileManager::GetActiveUserProfile() ->GetPrefs() ->FindPreference(prefs::kNaturalScroll) ->IsDefaultValue(); + if (summary.is_synced || + (WizardController::default_controller() + ->choobe_flow_controller() + ->IsScreenCompleted(TouchpadScrollScreenView::kScreenId))) { + summary.subtitle_resource = RetrieveChoobeSubtitle(); + } + return summary; }
diff --git a/chrome/browser/ash/login/screens/touchpad_scroll_screen.h b/chrome/browser/ash/login/screens/touchpad_scroll_screen.h index 71f7065..0f2ca56 100644 --- a/chrome/browser/ash/login/screens/touchpad_scroll_screen.h +++ b/chrome/browser/ash/login/screens/touchpad_scroll_screen.h
@@ -61,6 +61,8 @@ // Get user synced preferences for touchpad scroll direction. bool GetNaturalScrollPrefValue(); + std::string RetrieveChoobeSubtitle(); + bool ignore_pref_sync_for_testing_ = false; base::WeakPtr<TouchpadScrollScreenView> view_;
diff --git a/chrome/browser/ash/policy/remote_commands/device_command_fetch_support_packet_job.cc b/chrome/browser/ash/policy/remote_commands/device_command_fetch_support_packet_job.cc index 5a714d1..1f22e02 100644 --- a/chrome/browser/ash/policy/remote_commands/device_command_fetch_support_packet_job.cc +++ b/chrome/browser/ash/policy/remote_commands/device_command_fetch_support_packet_job.cc
@@ -17,6 +17,7 @@ #include "base/functional/bind.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_piece_forward.h" #include "base/strings/string_util.h" @@ -395,9 +396,8 @@ return; } - std::string error_message = - base::StringPrintf("Couldn't enqueue event to reporting queue: %s", - status.error_message().data()); + std::string error_message = base::StrCat( + {"Couldn't enqueue event to reporting queue: ", status.error_message()}); SYSLOG(ERROR) << error_message; std::move(result_callback_).Run(ResultType::kFailure, error_message);
diff --git a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_browsertest.cc b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_browsertest.cc index ef80d24..f5aa3de 100644 --- a/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_browsertest.cc +++ b/chrome/browser/ash/policy/reporting/metrics_reporting/network/network_telemetry_sampler_browsertest.cc
@@ -204,8 +204,8 @@ // PRE-condition. } -// TODO(crbug.com/1450419): Flaky on Linux + ChromeOS -#if BUILDFLAG(IS_LINUX) && BUILDFLAG(IS_CHROMEOS) +// TODO(crbug.com/1450419): Flaky on ChromeOS +#if BUILDFLAG(IS_CHROMEOS) #define MAYBE_Default DISABLED_Default #else #define MAYBE_Default Default
diff --git a/chrome/browser/ash/scalable_iph/BUILD.gn b/chrome/browser/ash/scalable_iph/BUILD.gn new file mode 100644 index 0000000..11715a5 --- /dev/null +++ b/chrome/browser/ash/scalable_iph/BUILD.gn
@@ -0,0 +1,48 @@ +# 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. + +import("//build/config/chromeos/ui_mode.gni") + +assert(is_chromeos_ash) + +source_set("scalable_iph_factory") { + sources = [ + "scalable_iph_factory.cc", + "scalable_iph_factory.h", + ] + + deps = [ + "//base", + "//chrome/browser", + "//chrome/browser/profiles:profile", + "//chromeos/ash/components/scalable_iph", + "//components/feature_engagement/public", + "//components/keyed_service/core", + "//content/public/browser", + ] +} + +source_set("browser_test_base") { + testonly = true + + sources = [ + "scalable_iph_browser_test_base.cc", + "scalable_iph_browser_test_base.h", + ] + + deps = [ + ":scalable_iph_factory", + "//base", + "//chrome/browser", + "//chrome/browser/profiles:profile", + "//chrome/browser/ui", + "//chrome/test:test_support_ui", + "//components/feature_engagement/public", + "//components/feature_engagement/test:test_support", + "//components/keyed_service/content", + "//components/keyed_service/core", + "//content/public/browser", + "//testing/gmock", + ] +}
diff --git a/chrome/browser/ash/scalable_iph/DIR_METADATA b/chrome/browser/ash/scalable_iph/DIR_METADATA new file mode 100644 index 0000000..bf1496c --- /dev/null +++ b/chrome/browser/ash/scalable_iph/DIR_METADATA
@@ -0,0 +1 @@ +mixins: "//chromeos/ash/components/scalable_iph/COMMON_METADATA"
diff --git a/chrome/browser/ash/scalable_iph/OWNERS b/chrome/browser/ash/scalable_iph/OWNERS new file mode 100644 index 0000000..08c1c2b --- /dev/null +++ b/chrome/browser/ash/scalable_iph/OWNERS
@@ -0,0 +1 @@ +file://chromeos/ash/components/scalable_iph/OWNERS
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.cc b/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.cc new file mode 100644 index 0000000..8b0557b --- /dev/null +++ b/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.cc
@@ -0,0 +1,89 @@ +// 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 "chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.h" + +#include <memory> + +#include "base/functional/bind.h" +#include "chrome/browser/feature_engagement/tracker_factory.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/keyed_service/content/browser_context_dependency_manager.h" +#include "components/keyed_service/core/keyed_service.h" +#include "content/public/browser/browser_context.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace ash { + +void ScalableIphBrowserTestBase::SetUp() { + // Keyed service is a service which is tied to an object. For our use cases, + // the object is `BrowserContext` (e.g. `Profile`). See + // //components/keyed_service/README.md for details on keyed service. + // + // We set a testing factory to inject a mock. A testing factory must be set + // early enough as a service is not created before that, e.g. a `Tracker` must + // not be created before we set `CreateMockTracker`. If a keyed service is + // created before we set our testing factory, `SetTestingFactory` will + // destruct already created keyed services at a time we set our testing + // factory. It destructs a keyed service at an unusual timing. It can trigger + // a dangling pointer issue, etc. + // + // `SetUpOnMainThread` below is too late to set a testing factory. Note that + // `InProcessBrowserTest::SetUp` is called at the very early stage, e.g. + // before command lines are set, etc. + subscription_ = + BrowserContextDependencyManager::GetInstance() + ->RegisterCreateServicesCallbackForTesting( + base::BindRepeating(&ScalableIphBrowserTestBase::CreateServices)); + + InProcessBrowserTest::SetUp(); +} + +// `SetUpOnMainThread` is called just before a test body. Do the mock set up in +// this function as `browser()` is not available in `SetUp` above. +void ScalableIphBrowserTestBase::SetUpOnMainThread() { + mock_tracker_ = static_cast<feature_engagement::test::MockTracker*>( + feature_engagement::TrackerFactory::GetForBrowserContext( + browser()->profile())); + CHECK(mock_tracker_) + << "mock_tracker_ must be non-nullptr. GetForBrowserContext should " + "create one via CreateMockTracker if it does not exist."; + + ON_CALL(*mock_tracker_, AddOnInitializedCallback) + .WillByDefault( + [](feature_engagement::Tracker::OnInitializedCallback callback) { + std::move(callback).Run(true); + }); + + ON_CALL(*mock_tracker_, IsInitialized).WillByDefault(testing::Return(true)); + + InProcessBrowserTest::SetUpOnMainThread(); +} + +void ScalableIphBrowserTestBase::TearDownOnMainThread() { + // We are going to release a reference to a MockTracker below. Verify the + // expectation in advance to have a predictable behavior. + testing::Mock::VerifyAndClearExpectations(mock_tracker_); + mock_tracker_ = nullptr; + + InProcessBrowserTest::TearDownOnMainThread(); +} + +// static +void ScalableIphBrowserTestBase::CreateServices( + content::BrowserContext* browser_context) { + feature_engagement::TrackerFactory::GetInstance()->SetTestingFactory( + browser_context, + base::BindRepeating(&ScalableIphBrowserTestBase::CreateMockTracker)); +} + +// static +std::unique_ptr<KeyedService> ScalableIphBrowserTestBase::CreateMockTracker( + content::BrowserContext* browser_context) { + return std::make_unique<feature_engagement::test::MockTracker>(); +} + +} // namespace ash
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.h b/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.h new file mode 100644 index 0000000..19bbb87 --- /dev/null +++ b/chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.h
@@ -0,0 +1,42 @@ +// 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 CHROME_BROWSER_ASH_SCALABLE_IPH_SCALABLE_IPH_BROWSER_TEST_BASE_H_ +#define CHROME_BROWSER_ASH_SCALABLE_IPH_SCALABLE_IPH_BROWSER_TEST_BASE_H_ + +#include <memory> + +#include "base/callback_list.h" +#include "base/memory/raw_ptr.h" +#include "chrome/test/base/in_process_browser_test.h" +#include "components/feature_engagement/test/mock_tracker.h" +#include "components/keyed_service/core/keyed_service.h" +#include "content/public/browser/browser_context.h" + +namespace ash { + +class ScalableIphBrowserTestBase : public InProcessBrowserTest { + public: + // InProcessBrowserTest: + void SetUp() override; + void SetUpOnMainThread() override; + void TearDownOnMainThread() override; + + protected: + feature_engagement::test::MockTracker* mock_tracker() { + return mock_tracker_; + } + + private: + static void CreateServices(content::BrowserContext* browser_context); + static std::unique_ptr<KeyedService> CreateMockTracker( + content::BrowserContext* browser_context); + + base::CallbackListSubscription subscription_; + raw_ptr<feature_engagement::test::MockTracker> mock_tracker_; +}; + +} // namespace ash + +#endif // CHROME_BROWSER_ASH_SCALABLE_IPH_SCALABLE_IPH_BROWSER_TEST_BASE_H_
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_browsertest.cc b/chrome/browser/ash/scalable_iph/scalable_iph_browsertest.cc new file mode 100644 index 0000000..95b5bdc --- /dev/null +++ b/chrome/browser/ash/scalable_iph/scalable_iph_browsertest.cc
@@ -0,0 +1,28 @@ +// 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 "chrome/browser/ash/scalable_iph/scalable_iph_browser_test_base.h" +#include "chrome/browser/ash/scalable_iph/scalable_iph_factory.h" +#include "chrome/browser/ui/browser.h" +#include "chromeos/ash/components/scalable_iph/scalable_iph.h" +#include "components/feature_engagement/test/mock_tracker.h" +#include "content/public/test/browser_test.h" +#include "testing/gmock/include/gmock/gmock.h" + +namespace { + +using ScalableIphBrowserTest = ash::ScalableIphBrowserTestBase; + +} // namespace + +IN_PROC_BROWSER_TEST_F(ScalableIphBrowserTest, RecordEvent) { + EXPECT_CALL(*mock_tracker(), NotifyEvent("ScalableIphFiveMinTick")); + + scalable_iph::ScalableIph* scalable_iph = + ash::ScalableIphFactory::GetForProfile(browser()->profile()); + scalable_iph->RecordEvent(scalable_iph::ScalableIph::Event::kFiveMinTick); +} + +// TODO(b/284053005): Add a test case for invalid event name. +// TODO(b/284053005): Add a test case for checking trigger condition.
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_factory.cc b/chrome/browser/ash/scalable_iph/scalable_iph_factory.cc new file mode 100644 index 0000000..c8d4d0a3 --- /dev/null +++ b/chrome/browser/ash/scalable_iph/scalable_iph_factory.cc
@@ -0,0 +1,47 @@ +// 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 "chrome/browser/ash/scalable_iph/scalable_iph_factory.h" + +#include "base/memory/singleton.h" +#include "chrome/browser/feature_engagement/tracker_factory.h" +#include "chrome/browser/profiles/profile_keyed_service_factory.h" +#include "chromeos/ash/components/scalable_iph/scalable_iph.h" +#include "components/feature_engagement/public/tracker.h" +#include "components/keyed_service/core/keyed_service.h" +#include "content/public/browser/browser_context.h" + +namespace ash { + +namespace { +constexpr char kScalableIphServiceName[] = "ScalableIphKeyedService"; +} + +ScalableIphFactory::ScalableIphFactory() + : ProfileKeyedServiceFactory(kScalableIphServiceName) { + DependsOn(feature_engagement::TrackerFactory::GetInstance()); +} + +ScalableIphFactory::~ScalableIphFactory() = default; + +ScalableIphFactory* ScalableIphFactory::GetInstance() { + return base::Singleton<ScalableIphFactory>::get(); +} + +scalable_iph::ScalableIph* ScalableIphFactory::GetForProfile(Profile* profile) { + return static_cast<scalable_iph::ScalableIph*>( + GetInstance()->GetServiceForBrowserContext(profile, /*create=*/true)); +} + +std::unique_ptr<KeyedService> +ScalableIphFactory::BuildServiceInstanceForBrowserContext( + content::BrowserContext* browser_context) const { + feature_engagement::Tracker* tracker = + feature_engagement::TrackerFactory::GetForBrowserContext(browser_context); + CHECK(tracker); + + return std::make_unique<scalable_iph::ScalableIph>(tracker); +} + +} // namespace ash
diff --git a/chrome/browser/ash/scalable_iph/scalable_iph_factory.h b/chrome/browser/ash/scalable_iph/scalable_iph_factory.h new file mode 100644 index 0000000..135dbb5 --- /dev/null +++ b/chrome/browser/ash/scalable_iph/scalable_iph_factory.h
@@ -0,0 +1,34 @@ +// 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 CHROME_BROWSER_ASH_SCALABLE_IPH_SCALABLE_IPH_FACTORY_H_ +#define CHROME_BROWSER_ASH_SCALABLE_IPH_SCALABLE_IPH_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_keyed_service_factory.h" +#include "chromeos/ash/components/scalable_iph/scalable_iph.h" +#include "content/public/browser/browser_context.h" + +namespace ash { + +class ScalableIphFactory : public ProfileKeyedServiceFactory { + public: + static ScalableIphFactory* GetInstance(); + static scalable_iph::ScalableIph* GetForProfile(Profile* profile); + + protected: + // ProfileKeyedServiceFactory: + std::unique_ptr<KeyedService> BuildServiceInstanceForBrowserContext( + content::BrowserContext* browser_context) const override; + + private: + friend struct base::DefaultSingletonTraits<ScalableIphFactory>; + + ScalableIphFactory(); + ~ScalableIphFactory() override; +}; +} // namespace ash + +#endif // CHROME_BROWSER_ASH_SCALABLE_IPH_SCALABLE_IPH_FACTORY_H_
diff --git a/chrome/browser/ash/system_extensions/api/test_support/system_extensions_api_browsertest.cc b/chrome/browser/ash/system_extensions/api/test_support/system_extensions_api_browsertest.cc index 705b80a8..0c6a850 100644 --- a/chrome/browser/ash/system_extensions/api/test_support/system_extensions_api_browsertest.cc +++ b/chrome/browser/ash/system_extensions/api/test_support/system_extensions_api_browsertest.cc
@@ -339,8 +339,8 @@ } // Write manifest. - const std::string manifest_str = - base::StringPrintf(manifest_template_.data(), test_file_name.data()); + const std::string manifest_str = base::StringPrintf( + manifest_template_.c_str(), std::string(test_file_name).c_str()); CHECK(base::WriteFile(system_extension_path.AppendASCII("manifest.json"), manifest_str)) << "Failed to write the manifest.";
diff --git a/chrome/browser/ash/system_web_apps/BUILD.gn b/chrome/browser/ash/system_web_apps/BUILD.gn index 2fca6371..2e89f79 100644 --- a/chrome/browser/ash/system_web_apps/BUILD.gn +++ b/chrome/browser/ash/system_web_apps/BUILD.gn
@@ -101,9 +101,7 @@ "//chrome/browser/ui/ash/system_web_apps", "//chrome/browser/web_applications:web_applications_test_support", "//chrome/test:test_support", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//extensions/browser:test_support", "//ui/base/idle:test_support", "//ui/events:test_support",
diff --git a/chrome/browser/ash/system_web_apps/test_support/BUILD.gn b/chrome/browser/ash/system_web_apps/test_support/BUILD.gn index c14e581..0f732b5 100644 --- a/chrome/browser/ash/system_web_apps/test_support/BUILD.gn +++ b/chrome/browser/ash/system_web_apps/test_support/BUILD.gn
@@ -37,11 +37,7 @@ "//chrome/browser/web_applications:web_applications_test_support", "//components/crx_file", "//components/keyed_service/content", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:app_url_handling", - "//components/services/app_service/public/cpp:protocol_handling", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//components/sync:test_support", "//components/sync_preferences:test_support", "//components/webapps/browser",
diff --git a/chrome/browser/ash/video_conference/video_conference_app_service_client.cc b/chrome/browser/ash/video_conference/video_conference_app_service_client.cc index 112bd83..1c9c5090 100644 --- a/chrome/browser/ash/video_conference/video_conference_app_service_client.cc +++ b/chrome/browser/ash/video_conference/video_conference_app_service_client.cc
@@ -189,28 +189,10 @@ if (update.CameraChanged()) { state.is_capturing_camera = is_capturing_camera; - - if (is_capturing_camera && camera_system_disabled_) { - crosapi::CrosapiManager::Get() - ->crosapi_ash() - ->video_conference_manager_ash() - ->NotifyDeviceUsedWhileDisabled( - crosapi::mojom::VideoConferenceMediaDevice::kCamera, - base::UTF8ToUTF16(app_name), base::DoNothingAs<void(bool)>()); - } } if (update.MicrophoneChanged()) { state.is_capturing_microphone = is_capturing_microphone; - - if (is_capturing_microphone && microphone_system_disabled_) { - crosapi::CrosapiManager::Get() - ->crosapi_ash() - ->video_conference_manager_ash() - ->NotifyDeviceUsedWhileDisabled( - crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, - base::UTF8ToUTF16(app_name), base::DoNothingAs<void(bool)>()); - } } // For some apps, the instance is firstly removed, and then @@ -223,6 +205,28 @@ } HandleMediaUsageUpdate(); + + // This will be an AnchoredNudge, which is only visible if the tray is + // visible; so we have to call this after HandleMediaUsageUpdate. + if (update.CameraChanged() && is_capturing_camera && + camera_system_disabled_) { + crosapi::CrosapiManager::Get() + ->crosapi_ash() + ->video_conference_manager_ash() + ->NotifyDeviceUsedWhileDisabled( + crosapi::mojom::VideoConferenceMediaDevice::kCamera, + base::UTF8ToUTF16(app_name), base::DoNothingAs<void(bool)>()); + } + + if (update.MicrophoneChanged() && is_capturing_microphone && + microphone_system_disabled_) { + crosapi::CrosapiManager::Get() + ->crosapi_ash() + ->video_conference_manager_ash() + ->NotifyDeviceUsedWhileDisabled( + crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, + base::UTF8ToUTF16(app_name), base::DoNothingAs<void(bool)>()); + } } void VideoConferenceAppServiceClient::OnAppCapabilityAccessCacheWillBeDestroyed(
diff --git a/chrome/browser/ash/web_applications/personalization_app/ambient_video_albums.cc b/chrome/browser/ash/web_applications/personalization_app/ambient_video_albums.cc index d798440..d4e310dd 100644 --- a/chrome/browser/ash/web_applications/personalization_app/ambient_video_albums.cc +++ b/chrome/browser/ash/web_applications/personalization_app/ambient_video_albums.cc
@@ -39,7 +39,7 @@ std::vector<mojom::AmbientModeAlbumPtr>& output) { for (const VideoAlbumInfo& video_album_info : kAllVideoAlbumInfo) { mojom::AmbientModeAlbumPtr album = mojom::AmbientModeAlbum::New(); - album->id = video_album_info.id.data(); + album->id = std::string(video_album_info.id); album->checked = currently_selected_video == video_album_info.video; album->title = l10n_util::GetStringUTF8(video_album_info.title_resource_id); // Product name does not need to be translated.
diff --git a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc index 629a971..a94884f 100644 --- a/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc +++ b/chrome/browser/ash/web_applications/personalization_app/personalization_app_ambient_provider_impl_unittest.cc
@@ -316,10 +316,11 @@ ambient_provider_->SetTopicSource(topic_source); } - void SetAlbumSelected(const std::string& id, + void SetAlbumSelected(base::StringPiece id, ash::AmbientModeTopicSource topic_source, bool selected) { - ambient_provider_->SetAlbumSelected(id, topic_source, selected); + ambient_provider_->SetAlbumSelected(std::string(id), topic_source, + selected); } void FetchPreviewImages() { ambient_provider_->FetchPreviewImages(); } @@ -927,19 +928,17 @@ /*new_mexico_selected=*/true); // Switch to clouds. - SetAlbumSelected(kCloudsAlbumId.data(), AmbientModeTopicSource::kVideo, true); + SetAlbumSelected(kCloudsAlbumId, AmbientModeTopicSource::kVideo, true); expect_videos_selected(/*clouds_selected=*/true, /*new_mexico_selected=*/false); // Switch back to new mexico. - SetAlbumSelected(kNewMexicoAlbumId.data(), AmbientModeTopicSource::kVideo, - true); + SetAlbumSelected(kNewMexicoAlbumId, AmbientModeTopicSource::kVideo, true); expect_videos_selected(/*clouds_selected=*/false, /*new_mexico_selected=*/true); // Should never be in a state where there are no videos selected. - SetAlbumSelected(kNewMexicoAlbumId.data(), AmbientModeTopicSource::kVideo, - false); + SetAlbumSelected(kNewMexicoAlbumId, AmbientModeTopicSource::kVideo, false); expect_videos_selected(/*clouds_selected=*/false, /*new_mexico_selected=*/true);
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc index 3b31919..9074a1c 100644 --- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc +++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.cc
@@ -130,6 +130,13 @@ int64_t recv_bytes, int64_t sent_bytes) {} +void WilcoDtcSupportdNetworkContextImpl::OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) { + std::move(callback).Run(); +} + void WilcoDtcSupportdNetworkContextImpl::Clone( mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver> observer) {
diff --git a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h index 325de1d..ac260d5 100644 --- a/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h +++ b/chrome/browser/ash/wilco_dtc_supportd/wilco_dtc_supportd_network_context.h
@@ -87,6 +87,10 @@ void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash, int64_t recv_bytes, int64_t sent_bytes) override; + void OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) override; void Clone( mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver> listener) override;
diff --git a/chrome/browser/autocomplete/autocomplete_classifier_factory.cc b/chrome/browser/autocomplete/autocomplete_classifier_factory.cc index 2db0b17f..103e310 100644 --- a/chrome/browser/autocomplete/autocomplete_classifier_factory.cc +++ b/chrome/browser/autocomplete/autocomplete_classifier_factory.cc
@@ -31,7 +31,8 @@ // static AutocompleteClassifierFactory* AutocompleteClassifierFactory::GetInstance() { - return base::Singleton<AutocompleteClassifierFactory>::get(); + static base::NoDestructor<AutocompleteClassifierFactory> instance; + return instance.get(); } // static @@ -64,8 +65,7 @@ DependsOn(RemoteSuggestionsServiceFactory::GetInstance()); } -AutocompleteClassifierFactory::~AutocompleteClassifierFactory() { -} +AutocompleteClassifierFactory::~AutocompleteClassifierFactory() = default; bool AutocompleteClassifierFactory::ServiceIsNULLWhileTesting() const { return true;
diff --git a/chrome/browser/autocomplete/autocomplete_classifier_factory.h b/chrome/browser/autocomplete/autocomplete_classifier_factory.h index 6b7ab0e..28f367b9 100644 --- a/chrome/browser/autocomplete/autocomplete_classifier_factory.h +++ b/chrome/browser/autocomplete/autocomplete_classifier_factory.h
@@ -7,7 +7,7 @@ #include <memory> -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" class AutocompleteClassifier; @@ -30,7 +30,7 @@ content::BrowserContext* context); private: - friend struct base::DefaultSingletonTraits<AutocompleteClassifierFactory>; + friend base::NoDestructor<AutocompleteClassifierFactory>; AutocompleteClassifierFactory(); ~AutocompleteClassifierFactory() override;
diff --git a/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.cc b/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.cc index 47660316..dd8a2c8 100644 --- a/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.cc +++ b/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.cc
@@ -6,7 +6,7 @@ #include <memory> -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" #include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" @@ -17,7 +17,8 @@ // static AutocompleteScoringModelServiceFactory* AutocompleteScoringModelServiceFactory::GetInstance() { - return base::Singleton<AutocompleteScoringModelServiceFactory>::get(); + static base::NoDestructor<AutocompleteScoringModelServiceFactory> instance; + return instance.get(); } // static
diff --git a/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.h b/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.h index 3bf6fa8..03476b9 100644 --- a/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.h +++ b/chrome/browser/autocomplete/autocomplete_scoring_model_service_factory.h
@@ -7,7 +7,7 @@ #include <memory> -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" namespace content { @@ -36,8 +36,7 @@ const AutocompleteScoringModelServiceFactory&) = delete; private: - friend struct base::DefaultSingletonTraits< - AutocompleteScoringModelServiceFactory>; + friend base::NoDestructor<AutocompleteScoringModelServiceFactory>; AutocompleteScoringModelServiceFactory(); ~AutocompleteScoringModelServiceFactory() override;
diff --git a/chrome/browser/autocomplete/document_suggestions_service_factory.cc b/chrome/browser/autocomplete/document_suggestions_service_factory.cc index 40627aa3b..9fcbd70 100644 --- a/chrome/browser/autocomplete/document_suggestions_service_factory.cc +++ b/chrome/browser/autocomplete/document_suggestions_service_factory.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/autocomplete/document_suggestions_service_factory.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "components/omnibox/browser/document_suggestions_service.h" @@ -21,7 +21,8 @@ // static DocumentSuggestionsServiceFactory* DocumentSuggestionsServiceFactory::GetInstance() { - return base::Singleton<DocumentSuggestionsServiceFactory>::get(); + static base::NoDestructor<DocumentSuggestionsServiceFactory> instance; + return instance.get(); } KeyedService* DocumentSuggestionsServiceFactory::BuildServiceInstanceFor( @@ -47,4 +48,5 @@ DependsOn(IdentityManagerFactory::GetInstance()); } -DocumentSuggestionsServiceFactory::~DocumentSuggestionsServiceFactory() {} +DocumentSuggestionsServiceFactory::~DocumentSuggestionsServiceFactory() = + default;
diff --git a/chrome/browser/autocomplete/document_suggestions_service_factory.h b/chrome/browser/autocomplete/document_suggestions_service_factory.h index b802010..4dbf731a 100644 --- a/chrome/browser/autocomplete/document_suggestions_service_factory.h +++ b/chrome/browser/autocomplete/document_suggestions_service_factory.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_AUTOCOMPLETE_DOCUMENT_SUGGESTIONS_SERVICE_FACTORY_H_ #define CHROME_BROWSER_AUTOCOMPLETE_DOCUMENT_SUGGESTIONS_SERVICE_FACTORY_H_ -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" class DocumentSuggestionsService; @@ -23,7 +23,7 @@ const DocumentSuggestionsServiceFactory&) = delete; private: - friend struct base::DefaultSingletonTraits<DocumentSuggestionsServiceFactory>; + friend base::NoDestructor<DocumentSuggestionsServiceFactory>; DocumentSuggestionsServiceFactory(); ~DocumentSuggestionsServiceFactory() override;
diff --git a/chrome/browser/autocomplete/in_memory_url_index_factory.cc b/chrome/browser/autocomplete/in_memory_url_index_factory.cc index 42da735..c034642 100644 --- a/chrome/browser/autocomplete/in_memory_url_index_factory.cc +++ b/chrome/browser/autocomplete/in_memory_url_index_factory.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/autocomplete/in_memory_url_index_factory.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" @@ -21,7 +21,8 @@ // static InMemoryURLIndexFactory* InMemoryURLIndexFactory::GetInstance() { - return base::Singleton<InMemoryURLIndexFactory>::get(); + static base::NoDestructor<InMemoryURLIndexFactory> instance; + return instance.get(); } InMemoryURLIndexFactory::InMemoryURLIndexFactory() @@ -38,8 +39,7 @@ DependsOn(TemplateURLServiceFactory::GetInstance()); } -InMemoryURLIndexFactory::~InMemoryURLIndexFactory() { -} +InMemoryURLIndexFactory::~InMemoryURLIndexFactory() = default; KeyedService* InMemoryURLIndexFactory::BuildServiceInstanceFor( content::BrowserContext* context) const {
diff --git a/chrome/browser/autocomplete/in_memory_url_index_factory.h b/chrome/browser/autocomplete/in_memory_url_index_factory.h index 8674049..64ea08f 100644 --- a/chrome/browser/autocomplete/in_memory_url_index_factory.h +++ b/chrome/browser/autocomplete/in_memory_url_index_factory.h
@@ -8,7 +8,8 @@ #include "chrome/browser/profiles/profile_keyed_service_factory.h" namespace base { -template <typename T> struct DefaultSingletonTraits; +template <typename T> +class NoDestructor; } class InMemoryURLIndex; @@ -20,7 +21,7 @@ static InMemoryURLIndexFactory* GetInstance(); private: - friend struct base::DefaultSingletonTraits<InMemoryURLIndexFactory>; + friend base::NoDestructor<InMemoryURLIndexFactory>; InMemoryURLIndexFactory(); ~InMemoryURLIndexFactory() override;
diff --git a/chrome/browser/autocomplete/remote_suggestions_service_factory.cc b/chrome/browser/autocomplete/remote_suggestions_service_factory.cc index 14083f5..596ea79 100644 --- a/chrome/browser/autocomplete/remote_suggestions_service_factory.cc +++ b/chrome/browser/autocomplete/remote_suggestions_service_factory.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/autocomplete/remote_suggestions_service_factory.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" #include "components/omnibox/browser/remote_suggestions_service.h" #include "content/public/browser/storage_partition.h" @@ -20,7 +20,8 @@ // static RemoteSuggestionsServiceFactory* RemoteSuggestionsServiceFactory::GetInstance() { - return base::Singleton<RemoteSuggestionsServiceFactory>::get(); + static base::NoDestructor<RemoteSuggestionsServiceFactory> instance; + return instance.get(); } KeyedService* RemoteSuggestionsServiceFactory::BuildServiceInstanceFor( @@ -41,4 +42,4 @@ .WithGuest(ProfileSelection::kOriginalOnly) .Build()) {} -RemoteSuggestionsServiceFactory::~RemoteSuggestionsServiceFactory() {} +RemoteSuggestionsServiceFactory::~RemoteSuggestionsServiceFactory() = default;
diff --git a/chrome/browser/autocomplete/remote_suggestions_service_factory.h b/chrome/browser/autocomplete/remote_suggestions_service_factory.h index 95a1440..7b98777 100644 --- a/chrome/browser/autocomplete/remote_suggestions_service_factory.h +++ b/chrome/browser/autocomplete/remote_suggestions_service_factory.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_AUTOCOMPLETE_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_ #define CHROME_BROWSER_AUTOCOMPLETE_REMOTE_SUGGESTIONS_SERVICE_FACTORY_H_ -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" class RemoteSuggestionsService; @@ -23,7 +23,7 @@ const RemoteSuggestionsServiceFactory&) = delete; private: - friend struct base::DefaultSingletonTraits<RemoteSuggestionsServiceFactory>; + friend base::NoDestructor<RemoteSuggestionsServiceFactory>; RemoteSuggestionsServiceFactory(); ~RemoteSuggestionsServiceFactory() override;
diff --git a/chrome/browser/autocomplete/shortcuts_backend_factory.cc b/chrome/browser/autocomplete/shortcuts_backend_factory.cc index 200abfd..13ef3200 100644 --- a/chrome/browser/autocomplete/shortcuts_backend_factory.cc +++ b/chrome/browser/autocomplete/shortcuts_backend_factory.cc
@@ -39,7 +39,8 @@ // static ShortcutsBackendFactory* ShortcutsBackendFactory::GetInstance() { - return base::Singleton<ShortcutsBackendFactory>::get(); + static base::NoDestructor<ShortcutsBackendFactory> instance; + return instance.get(); } // static @@ -69,7 +70,7 @@ DependsOn(TemplateURLServiceFactory::GetInstance()); } -ShortcutsBackendFactory::~ShortcutsBackendFactory() {} +ShortcutsBackendFactory::~ShortcutsBackendFactory() = default; scoped_refptr<RefcountedKeyedService> ShortcutsBackendFactory::BuildServiceInstanceFor(
diff --git a/chrome/browser/autocomplete/shortcuts_backend_factory.h b/chrome/browser/autocomplete/shortcuts_backend_factory.h index 7af30e0..e73e3815 100644 --- a/chrome/browser/autocomplete/shortcuts_backend_factory.h +++ b/chrome/browser/autocomplete/shortcuts_backend_factory.h
@@ -6,7 +6,7 @@ #define CHROME_BROWSER_AUTOCOMPLETE_SHORTCUTS_BACKEND_FACTORY_H_ #include "base/memory/ref_counted.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/refcounted_profile_keyed_service_factory.h" class Profile; @@ -34,7 +34,7 @@ content::BrowserContext* profile); private: - friend struct base::DefaultSingletonTraits<ShortcutsBackendFactory>; + friend base::NoDestructor<ShortcutsBackendFactory>; ShortcutsBackendFactory(); ~ShortcutsBackendFactory() override;
diff --git a/chrome/browser/autocomplete/zero_suggest_cache_service_factory.cc b/chrome/browser/autocomplete/zero_suggest_cache_service_factory.cc index e1253c40..93e2820 100644 --- a/chrome/browser/autocomplete/zero_suggest_cache_service_factory.cc +++ b/chrome/browser/autocomplete/zero_suggest_cache_service_factory.cc
@@ -16,7 +16,8 @@ // static ZeroSuggestCacheServiceFactory* ZeroSuggestCacheServiceFactory::GetInstance() { - return base::Singleton<ZeroSuggestCacheServiceFactory>::get(); + static base::NoDestructor<ZeroSuggestCacheServiceFactory> instance; + return instance.get(); } KeyedService* ZeroSuggestCacheServiceFactory::BuildServiceInstanceFor(
diff --git a/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h b/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h index 1d09bc3..17c0e56 100644 --- a/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h +++ b/chrome/browser/autocomplete/zero_suggest_cache_service_factory.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_ #define CHROME_BROWSER_AUTOCOMPLETE_ZERO_SUGGEST_CACHE_SERVICE_FACTORY_H_ -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" #include "components/omnibox/browser/zero_suggest_cache_service.h" @@ -17,7 +17,7 @@ static ZeroSuggestCacheServiceFactory* GetInstance(); private: - friend struct base::DefaultSingletonTraits<ZeroSuggestCacheServiceFactory>; + friend base::NoDestructor<ZeroSuggestCacheServiceFactory>; ZeroSuggestCacheServiceFactory(); ~ZeroSuggestCacheServiceFactory() override;
diff --git a/chrome/browser/auxiliary_search/BUILD.gn b/chrome/browser/auxiliary_search/BUILD.gn new file mode 100644 index 0000000..debc200b --- /dev/null +++ b/chrome/browser/auxiliary_search/BUILD.gn
@@ -0,0 +1,36 @@ +# 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. + +import("//build/config/android/config.gni") +import("//build/config/android/rules.gni") +import("//chrome/browser/buildflags.gni") + +android_library("java") { + sources = [ + "java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchController.java", + "java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerImpl.java", + ] + + deps = [ + "//chrome/browser/android/lifecycle:java", + "//chrome/browser/profiles/android:java", + "//chrome/browser/tabmodel:java", + ] + resources_package = "org.chromium.chrome.browser.auxiliary_search" + + # Add the actual implementation where necessary so that downstream targets + # can provide their own implementations. + jar_excluded_patterns = [ "*/AuxiliarySearchControllerImpl.class" ] +} + +android_library("delegate_public_impl_java") { + sources = [ "java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerImpl.java" ] + + deps = [ + ":java", + "//chrome/browser/android/lifecycle:java", + "//chrome/browser/profiles/android:java", + "//chrome/browser/tabmodel:java", + ] +}
diff --git a/chrome/browser/auxiliary_search/DIR_METADATA b/chrome/browser/auxiliary_search/DIR_METADATA new file mode 100644 index 0000000..07a4669 --- /dev/null +++ b/chrome/browser/auxiliary_search/DIR_METADATA
@@ -0,0 +1,3 @@ +monorail { + component: "UI>Browser>Omnibox" +}
diff --git a/chrome/browser/auxiliary_search/OWNERS b/chrome/browser/auxiliary_search/OWNERS new file mode 100644 index 0000000..603b9cf --- /dev/null +++ b/chrome/browser/auxiliary_search/OWNERS
@@ -0,0 +1 @@ +file://components/omnibox/browser/android/OWNERS
diff --git a/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchController.java b/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchController.java new file mode 100644 index 0000000..e0cc664 --- /dev/null +++ b/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchController.java
@@ -0,0 +1,25 @@ +// 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. + +package org.chromium.chrome.browser.auxiliary_search; + +import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; +import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; + +/** + * This Controller for the auxiliary search. + */ +public interface AuxiliarySearchController extends PauseResumeWithNativeObserver { + /** + * Registers to the given lifecycle dispatcher. + * @param lifecycleDispatcher tracks the lifecycle of the Activity of pause and resume. + */ + default void register(ActivityLifecycleDispatcher lifecycleDispatcher) {} + + @Override + default void onResumeWithNative() {} + + @Override + default void onPauseWithNative() {} +}
diff --git a/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerImpl.java b/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerImpl.java new file mode 100644 index 0000000..d362d658 --- /dev/null +++ b/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerImpl.java
@@ -0,0 +1,15 @@ +// 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. + +package org.chromium.chrome.browser.auxiliary_search; + +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.tabmodel.TabModelSelector; + +/** + * Dummy implementation of the AuxiliarySearchController. + */ +public class AuxiliarySearchControllerImpl implements AuxiliarySearchController { + public AuxiliarySearchControllerImpl(Profile profile, TabModelSelector tabModelSelector) {} +}
diff --git a/chrome/browser/back_press/android/BUILD.gn b/chrome/browser/back_press/android/BUILD.gn index a195957..b799e56 100644 --- a/chrome/browser/back_press/android/BUILD.gn +++ b/chrome/browser/back_press/android/BUILD.gn
@@ -6,8 +6,10 @@ android_library("java") { sources = [ + "java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java", "java/src/org/chromium/chrome/browser/back_press/BackPressManager.java", "java/src/org/chromium/chrome/browser/back_press/MinimizeAppAndCloseTabBackPressHandler.java", + "java/src/org/chromium/chrome/browser/back_press/SecondaryActivityBackPressUma.java", ] deps = [ @@ -21,11 +23,15 @@ "//content/public/android:content_full_java", "//third_party/androidx:androidx_activity_activity_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", ] } robolectric_library("junit") { - sources = [ "java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java" ] + sources = [ + "java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java", + "java/src/org/chromium/chrome/browser/back_press/BackPressManagerUnitTest.java", + ] deps = [ ":java", @@ -36,7 +42,10 @@ "//chrome/browser/flags:java", "//components/browser_ui/widget/android:java", "//third_party/androidx:androidx_activity_activity_java", + "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", + "//third_party/androidx:androidx_lifecycle_lifecycle_runtime_java", "//third_party/junit:junit", + "//third_party/mockito:mockito_java", ] }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/BackPressHelper.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java similarity index 74% rename from chrome/android/java/src/org/chromium/chrome/browser/BackPressHelper.java rename to chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java index 5f9a74a..10be7740 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/BackPressHelper.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelper.java
@@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser; +package org.chromium.chrome.browser.back_press; import androidx.activity.OnBackPressedCallback; import androidx.activity.OnBackPressedDispatcher; import androidx.lifecycle.LifecycleOwner; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler; /** @@ -28,31 +29,35 @@ } /** - * @deprecated Create a {@link BackPressHelper} that can handle a chain of handlers. - * Prefer {@link #create(LifecycleOwner, OnBackPressedDispatcher, BackPressHandler)} - * whenever possible. * @param lifecycleOwner {@link LifecycleOwner} managing the back press logic's lifecycle. * @param dispatcher {@link OnBackPressedDispatcher} that holds other callbacks. - * @param handler {@link ObsoleteBackPressedHandler} implementing the caller's back press - * handler. + * @param handler {@link ObsoleteBackPressedHandler} implementing the caller's back press. + * @param activity {@link SecondaryActivity} handling the back press. + * handler. + * @deprecated Create a {@link BackPressHelper} that can handle a chain of handlers. Prefer + * {@link #create(LifecycleOwner, OnBackPressedDispatcher, BackPressHandler, int)} whenever + * possible. */ @Deprecated public static void create(LifecycleOwner lifecycleOwner, OnBackPressedDispatcher dispatcher, - ObsoleteBackPressedHandler handler) { - new BackPressHelper(lifecycleOwner, dispatcher, handler); + ObsoleteBackPressedHandler handler, @SecondaryActivity int activity) { + new BackPressHelper(lifecycleOwner, dispatcher, handler, activity); } /** * Register a {@link BackPressHandler} on a given {@link OnBackPressedDispatcher}. + * * @param lifecycleOwner {@link LifecycleOwner} managing the back press logic's lifecycle. * @param dispatcher {@link OnBackPressedDispatcher} that holds other callbacks. * @param handler {@link BackPressHandler} observing back press state and consuming back press. + * @param activity {@link SecondaryActivity} handling the back press. */ public static void create(LifecycleOwner lifecycleOwner, OnBackPressedDispatcher dispatcher, - BackPressHandler handler) { + BackPressHandler handler, @SecondaryActivity int activity) { var callback = new OnBackPressedCallback(/* enabled */ false) { @Override public void handleOnBackPressed() { + SecondaryActivityBackPressUma.record(activity); handler.handleBackPress(); } }; @@ -61,20 +66,23 @@ } /** - * Register a list of {@link BackPressHandler} on a given {@link OnBackPressedDispatcher}. - * The first handler has the top priority and the last one has the least. + * Register a list of {@link BackPressHandler} on a given {@link OnBackPressedDispatcher}. The + * first handler has the top priority and the last one has the least. * TODO(https://crbug.com/1406012): consider introducing a lightweight * {@link org.chromium.chrome.browser.back_press.BackPressManager} if too many handlers should * be registered. + * * @param lifecycleOwner {@link LifecycleOwner} managing the back press logic's lifecycle. * @param dispatcher {@link OnBackPressedDispatcher} that holds other callbacks. - * @param handlers {@link BackPressHandler} observing back press state and consuming back press. + * @param handlers {@link BackPressHandler} observing back press state and consuming back + * press. + * @param activity {@link SecondaryActivity} handling the back press. */ public static void create(LifecycleOwner lifecycleOwner, OnBackPressedDispatcher dispatcher, - BackPressHandler[] handlers) { + BackPressHandler[] handlers, @SecondaryActivity int activity) { // OnBackPressedDispatcher triggers handlers in a reversed order. for (int i = handlers.length - 1; i >= 0; i--) { - create(lifecycleOwner, dispatcher, handlers[i]); + create(lifecycleOwner, dispatcher, handlers[i], activity); } } @@ -95,11 +103,15 @@ } private BackPressHelper(LifecycleOwner lifecycleOwner, OnBackPressedDispatcher dispatcher, - ObsoleteBackPressedHandler handler) { + ObsoleteBackPressedHandler handler, @SecondaryActivity int activity) { dispatcher.addCallback(lifecycleOwner, new OnBackPressedCallback(true) { @Override public void handleOnBackPressed() { - if (!handler.onBackPressed()) onBackPressed(dispatcher, this); + if (handler.onBackPressed()) { + SecondaryActivityBackPressUma.record(activity); + } else { + onBackPressed(dispatcher, this); + } } }); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/BackPressHelperUnitTest.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java similarity index 71% rename from chrome/android/junit/src/org/chromium/chrome/browser/BackPressHelperUnitTest.java rename to chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java index 7fbed96..eacbfce 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/BackPressHelperUnitTest.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressHelperUnitTest.java
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -package org.chromium.chrome.browser; +package org.chromium.chrome.browser.back_press; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.never; @@ -21,9 +21,11 @@ import org.robolectric.annotation.Config; import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.HistogramWatcher; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; /** - * Unit tests for {@link org.chromium.chrome.browser.BackPressHelper}. + * Unit tests for {@link BackPressHelper}. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) @@ -53,37 +55,54 @@ doReturn(true).when(mBackPressedHandler).onBackPressed(); // The last-added one is invoked first: mBackPressedHandler -> mBackPressedHandler2 - BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler2); - BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler); + BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler2, + SecondaryActivity.DOWNLOAD); + BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler, + SecondaryActivity.HISTORY); + + var histogramWatcher = HistogramWatcher.newSingleRecordWatcher( + "Android.BackPress.SecondaryActivity", SecondaryActivity.HISTORY); mLifecycle.setCurrentState(Lifecycle.State.STARTED); mOnBackPressedDispatcher.onBackPressed(); verify(mBackPressedHandler).onBackPressed(); verify(mBackPressedHandler2, never()).onBackPressed(); verify(mFallbackRunnable, never()).run(); + histogramWatcher.assertExpected(); } @Test public void testInvokeNextCallbackIfNotConsumed() { doReturn(false).when(mBackPressedHandler).onBackPressed(); doReturn(true).when(mBackPressedHandler2).onBackPressed(); - BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler2); - BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler); + BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler2, + SecondaryActivity.DOWNLOAD); + BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler, + SecondaryActivity.HISTORY); + + var histogramWatcher = HistogramWatcher.newSingleRecordWatcher( + "Android.BackPress.SecondaryActivity", SecondaryActivity.DOWNLOAD); mLifecycle.setCurrentState(Lifecycle.State.STARTED); mOnBackPressedDispatcher.onBackPressed(); verify(mBackPressedHandler).onBackPressed(); verify(mBackPressedHandler2).onBackPressed(); verify(mFallbackRunnable, never()).run(); + histogramWatcher.assertExpected(); } @Test public void testInvokeFallbackRunnableIfNotHandled() { doReturn(false).when(mBackPressedHandler).onBackPressed(); - BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler); + BackPressHelper.create(mLifecycleOwner, mOnBackPressedDispatcher, mBackPressedHandler, + SecondaryActivity.HISTORY); mLifecycle.setCurrentState(Lifecycle.State.STARTED); mOnBackPressedDispatcher.onBackPressed(); + var histogramWatcher = HistogramWatcher.newBuilder() + .expectNoRecords("Android.BackPress.SecondaryActivity") + .build(); verify(mFallbackRunnable).run(); + histogramWatcher.assertExpected(); } }
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/SecondaryActivityBackPressUma.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/SecondaryActivityBackPressUma.java new file mode 100644 index 0000000..038a3de --- /dev/null +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/SecondaryActivityBackPressUma.java
@@ -0,0 +1,37 @@ +// 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. + +package org.chromium.chrome.browser.back_press; + +import androidx.annotation.IntDef; + +import org.chromium.base.metrics.RecordHistogram; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Uma recorder for secondary activity back press handling. + */ +public class SecondaryActivityBackPressUma { + @IntDef({SecondaryActivity.DOWNLOAD, SecondaryActivity.BOOKMARK, SecondaryActivity.FIRST_RUN, + SecondaryActivity.LIGHTWEIGHT_FIRST_RUN, SecondaryActivity.HISTORY, + SecondaryActivity.SETTINGS, SecondaryActivity.NUM_TYPES}) + @Retention(RetentionPolicy.SOURCE) + public @interface SecondaryActivity { + int DOWNLOAD = 0; + int BOOKMARK = 1; + int FIRST_RUN = 2; + int LIGHTWEIGHT_FIRST_RUN = 3; + int HISTORY = 4; + int SETTINGS = 5; + + int NUM_TYPES = 6; + } + + public static void record(@SecondaryActivity int activity) { + RecordHistogram.recordEnumeratedHistogram( + "Android.BackPress.SecondaryActivity", activity, SecondaryActivity.NUM_TYPES); + } +}
diff --git a/chrome/browser/banners/app_banner_manager_browsertest.cc b/chrome/browser/banners/app_banner_manager_browsertest.cc index 5bb395c1..c97dfee6 100644 --- a/chrome/browser/banners/app_banner_manager_browsertest.cc +++ b/chrome/browser/banners/app_banner_manager_browsertest.cc
@@ -113,6 +113,14 @@ return false; } + void SaveInstallationDismissedForMl(const GURL& manifest_id) override {} + void SaveInstallationIgnoredForMl(const GURL& manifest_id) override {} + void SaveInstallationAcceptedForMl(const GURL& manifest_id) override {} + bool IsMlPromotionBlockedByHistoryGuardrail( + const GURL& manifest_id) override { + return false; + } + protected: // The overridden RequestAppBanner() can filter out about:blank calls // to force Stop() to be called, however, the newly introduced
diff --git a/chrome/browser/banners/app_banner_manager_desktop.cc b/chrome/browser/banners/app_banner_manager_desktop.cc index 6291cf3..d84328f 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.cc +++ b/chrome/browser/banners/app_banner_manager_desktop.cc
@@ -21,6 +21,7 @@ #include "chrome/browser/web_applications/web_app_helpers.h" #include "chrome/browser/web_applications/web_app_install_manager.h" #include "chrome/browser/web_applications/web_app_install_manager_observer.h" +#include "chrome/browser/web_applications/web_app_prefs_utils.h" #include "chrome/browser/web_applications/web_app_provider.h" #include "components/webapps/browser/banners/app_banner_metrics.h" #include "components/webapps/browser/banners/app_banner_settings_helper.h" @@ -77,21 +78,6 @@ return nullptr; } -bool AppBannerManagerDesktop::IsAppFullyInstalledForSiteUrl( - const GURL& site_url) const { - return web_app::FindInstalledAppWithUrlInScope( - Profile::FromBrowserContext(web_contents()->GetBrowserContext()), - site_url) - .has_value(); -} - -bool AppBannerManagerDesktop::IsAppPartiallyInstalledForSiteUrl( - const GURL& site_url) const { - return web_app::IsNonLocallyInstalledAppWithUrlInScope( - Profile::FromBrowserContext(web_contents()->GetBrowserContext()), - site_url); -} - AppBannerManagerDesktop::AppBannerManagerDesktop( content::WebContents* web_contents) : AppBannerManager(web_contents), @@ -164,6 +150,64 @@ .has_value(); } +bool AppBannerManagerDesktop::IsAppFullyInstalledForSiteUrl( + const GURL& site_url) const { + return web_app::FindInstalledAppWithUrlInScope( + Profile::FromBrowserContext(web_contents()->GetBrowserContext()), + site_url) + .has_value(); +} + +bool AppBannerManagerDesktop::IsAppPartiallyInstalledForSiteUrl( + const GURL& site_url) const { + return web_app::IsNonLocallyInstalledAppWithUrlInScope( + Profile::FromBrowserContext(web_contents()->GetBrowserContext()), + site_url); +} + +void AppBannerManagerDesktop::SaveInstallationDismissedForMl( + const GURL& manifest_id) { + CHECK(web_contents()); + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + CHECK(profile); + web_app::RecordMlInstallDismissed( + profile->GetPrefs(), web_app::GenerateAppIdFromManifestId(manifest_id), + base::Time::Now()); +} + +void AppBannerManagerDesktop::SaveInstallationIgnoredForMl( + const GURL& manifest_id) { + CHECK(web_contents()); + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + CHECK(profile); + web_app::RecordMlInstallIgnored( + profile->GetPrefs(), web_app::GenerateAppIdFromManifestId(manifest_id), + base::Time::Now()); +} + +void AppBannerManagerDesktop::SaveInstallationAcceptedForMl( + const GURL& manifest_id) { + CHECK(web_contents()); + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + CHECK(profile); + web_app::RecordMlInstallAccepted( + profile->GetPrefs(), web_app::GenerateAppIdFromManifestId(manifest_id), + base::Time::Now()); +} + +bool AppBannerManagerDesktop::IsMlPromotionBlockedByHistoryGuardrail( + const GURL& manifest_id) { + CHECK(web_contents()); + Profile* profile = + Profile::FromBrowserContext(web_contents()->GetBrowserContext()); + CHECK(profile); + return web_app::IsMlPromotionBlockedByHistoryGuardrail( + profile->GetPrefs(), web_app::GenerateAppIdFromManifestId(manifest_id)); +} + web_app::WebAppRegistrar& AppBannerManagerDesktop::registrar() { auto* provider = web_app::WebAppProvider::GetForWebApps( Profile::FromBrowserContext(web_contents()->GetBrowserContext()));
diff --git a/chrome/browser/banners/app_banner_manager_desktop.h b/chrome/browser/banners/app_banner_manager_desktop.h index f53215c..b272bf8 100644 --- a/chrome/browser/banners/app_banner_manager_desktop.h +++ b/chrome/browser/banners/app_banner_manager_desktop.h
@@ -43,9 +43,6 @@ virtual TestAppBannerManagerDesktop* AsTestAppBannerManagerDesktopForTesting(); - bool IsAppFullyInstalledForSiteUrl(const GURL& site_url) const override; - bool IsAppPartiallyInstalledForSiteUrl(const GURL& site_url) const override; - protected: explicit AppBannerManagerDesktop(content::WebContents* web_contents); @@ -62,6 +59,12 @@ bool IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const override; bool IsWebAppConsideredInstalled() const override; + bool IsAppFullyInstalledForSiteUrl(const GURL& site_url) const override; + bool IsAppPartiallyInstalledForSiteUrl(const GURL& site_url) const override; + void SaveInstallationDismissedForMl(const GURL& manifest_id) override; + void SaveInstallationIgnoredForMl(const GURL& manifest_id) override; + void SaveInstallationAcceptedForMl(const GURL& manifest_id) override; + bool IsMlPromotionBlockedByHistoryGuardrail(const GURL& manifest_id) override; // Called when the web app install initiated by a banner has completed. virtual void DidFinishCreatingWebApp(const web_app::AppId& app_id,
diff --git a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc index 0372ddc..d38e0a4 100644 --- a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc +++ b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
@@ -72,13 +72,13 @@ "\"taxonomyVersion\":\"1\",\"topic\":10,\"version\":\"chrome.1:1:2\"};]"; constexpr char kExpectedHeaderValueForEmptyTopics[] = - "t=(), p=P000000000000000000000000000"; + "();p=P0000000000000000000000000000000"; constexpr char kExpectedHeaderValueForSiteA[] = - "t=(1;v=chrome.1:1:2 10), p=P00000000"; + "(1 10);v=chrome.1:1:2, ();p=P00000000"; constexpr char kExpectedHeaderValueForSiteB[] = - "t=(1;v=chrome.1:1:2 7), p=P000000000"; + "(1 7);v=chrome.1:1:2, ();p=P000000000"; static constexpr char kBrowsingTopicsApiActionTypeHistogramId[] = "BrowsingTopics.ApiActionType";
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 79d6715..6427bea 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -1637,8 +1637,6 @@ registry->RegisterBooleanPref( policy::policy_prefs::kIsolatedAppsDeveloperModeAllowed, true); - registry->RegisterBooleanPref(policy::policy_prefs::kEventPathEnabled, false); - registry->RegisterBooleanPref( prefs::kStrictMimetypeCheckForWorkerScriptsEnabled, true); @@ -2758,14 +2756,6 @@ command_line->AppendSwitch(switches::kDisableScrollToTextFragment); } - // Override EventPath feature if its Enterprise Policy is specified. - if (prefs->HasPrefPath(policy::policy_prefs::kEventPathEnabled)) { - command_line->AppendSwitchASCII( - blink::switches::kEventPathPolicy, - prefs->GetBoolean(policy::policy_prefs::kEventPathEnabled) - ? blink::switches::kEventPathPolicy_ForceEnable - : blink::switches::kEventPathPolicy_ForceDisable); - } // Override OffsetParentNewSpecBehavior feature if its Enterprise policy // is specified. if (prefs->HasPrefPath(
diff --git a/chrome/browser/chromeos/kcer_nss/kcer_nss_unittest.cc b/chrome/browser/chromeos/kcer_nss/kcer_nss_unittest.cc index b7262e5..cc600e6 100644 --- a/chrome/browser/chromeos/kcer_nss/kcer_nss_unittest.cc +++ b/chrome/browser/chromeos/kcer_nss/kcer_nss_unittest.cc
@@ -236,12 +236,65 @@ crypto::ScopedTestNSSDB nss_slot_; }; +// A helper class for receiving notifications from Kcer. +class NotificationsObserver { + public: + explicit NotificationsObserver(base::test::TaskEnvironment& task_environment) + : task_environment_(task_environment) {} + + base::RepeatingClosure GetCallback() { + return base::BindRepeating(&NotificationsObserver::OnCertDbChanged, + weak_factory_.GetWeakPtr()); + } + + void OnCertDbChanged() { + notifications_counter_++; + if (run_loop_ && + notifications_counter_ >= expected_notifications_.value()) { + run_loop_->Quit(); + } + } + + // Waits until the required number of notifications is received. + bool WaitUntil(size_t notifications) { + if (notifications_counter_ < notifications) { + expected_notifications_ = notifications; + run_loop_.emplace(); + run_loop_->Run(); + run_loop_.reset(); + expected_notifications_.reset(); + } + + // An additional RunUntilIdle to try catching extra unwanted notifications. + task_environment_.RunUntilIdle(); + + if (notifications_counter_ != notifications) { + LOG(ERROR) << "Actual notifications: " << notifications_counter_; + return false; + } + return true; + } + + size_t Notifications() const { return notifications_counter_; } + + private: + base::test::TaskEnvironment& task_environment_; + size_t notifications_counter_ = 0; + absl::optional<base::RunLoop> run_loop_; + absl::optional<size_t> expected_notifications_; + base::WeakPtrFactory<NotificationsObserver> weak_factory_{this}; +}; + class KcerNssTest : public testing::Test { + public: + KcerNssTest() : observer_(task_environment_) {} + protected: content::BrowserTaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME, base::test::TaskEnvironment::MainThreadType::UI, content::BrowserTaskEnvironment::REAL_IO_THREAD}; + NotificationsObserver observer_; }; std::unique_ptr<net::CertBuilder> MakeCertIssuer() { @@ -267,12 +320,53 @@ return cert_builder; } +// Test that Kcer forwards notifications from external sources. (Notifications +// created by Kcer are tested together with the methods that create them.) +TEST_F(KcerNssTest, ObserveExternalNotification) { + TokenHolder user_token(Token::kUser); + user_token.Initialize(); + + std::unique_ptr<Kcer> kcer = + internal::CreateKcer(IOTaskRunner(), user_token.GetWeakPtr(), + /*device_token=*/nullptr); + + NotificationsObserver observer_1(task_environment_); + NotificationsObserver observer_2(task_environment_); + + // Add the first observer. + auto subscription_1 = kcer->AddObserver(observer_1.GetCallback()); + + EXPECT_EQ(observer_1.Notifications(), 0u); + + // Check that it receives a notification. + net::CertDatabase::GetInstance()->NotifyObserversCertDBChanged(); + EXPECT_TRUE(observer_1.WaitUntil(/*notifications=*/1)); + + // Add one more observer. + auto subscription_2 = kcer->AddObserver(observer_2.GetCallback()); + + // Check that both of them receive a notification. + net::CertDatabase::GetInstance()->NotifyObserversCertDBChanged(); + EXPECT_TRUE(observer_1.WaitUntil(/*notifications=*/2)); + EXPECT_TRUE(observer_2.WaitUntil(/*notifications=*/1)); + + // Destroy the first subscription, the first observer should stop receiving + // notifications now. + subscription_1 = base::CallbackListSubscription(); + + // Check that only the second observer receives a notification. + net::CertDatabase::GetInstance()->NotifyObserversCertDBChanged(); + EXPECT_TRUE(observer_2.WaitUntil(/*notifications=*/2)); + EXPECT_TRUE(observer_1.WaitUntil(/*notifications=*/2)); +} + // Test that if a method is called with a token that is not (and won't be) // available, then an error is returned. TEST_F(KcerNssTest, UseUnavailableTokenThenGetError) { std::unique_ptr<Kcer> kcer = internal::CreateKcer(IOTaskRunner(), /*user_token=*/nullptr, /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; kcer->GenerateRsaKey(Token::kUser, /*modulus_length_bits=*/2048, @@ -280,6 +374,7 @@ ASSERT_FALSE(generate_waiter.Get().has_value()); EXPECT_EQ(generate_waiter.Get().error(), Error::kTokenIsNotAvailable); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } TEST_F(KcerNssTest, ImportCertForImportedKey) { @@ -296,6 +391,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer(IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> import_key_waiter; kcer->ImportKey(Token::kUser, Pkcs8PrivateKeyInfoDer(std::move(key.value())), @@ -314,16 +410,19 @@ kcer->ImportCertFromBytes(Token::kUser, CertDer(std::move(cert.value())), import_cert_waiter.GetCallback()); EXPECT_TRUE(import_cert_waiter.Get().has_value()); + + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/1)); } -// Test that a certificate can not be imported, if there's no key for it on the -// token. +// Test that a certificate can not be imported, if there's no key for it on +// the token. TEST_F(KcerNssTest, ImportCertWithoutKeyThenFail) { TokenHolder user_token(Token::kUser); user_token.Initialize(); std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); std::unique_ptr<net::CertBuilder> issuer = MakeCertIssuer(); std::unique_ptr<net::CertBuilder> cert_builder = MakeCertBuilder( @@ -344,11 +443,12 @@ kcer->ListCerts({Token::kUser}, certs_waiter.GetCallback()); EXPECT_TRUE(certs_waiter.Get<0>().empty()); // Cert list is empty. EXPECT_TRUE(certs_waiter.Get<1>().empty()); // Error map is empty. + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test that all methods can be queued while a token is initializing and that -// the entire task queue can be processed when initialization completes (in this -// case - completes with a failure). +// the entire task queue can be processed when initialization completes (in +// this case - completes with a failure). TEST_F(KcerNssTest, QueueTasksFailInitializationThenGetErrors) { TokenHolder user_token(Token::kUser); @@ -363,6 +463,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> generate_rsa_waiter; kcer->GenerateRsaKey(Token::kUser, /*modulus_length_bits=*/2048, @@ -486,6 +587,7 @@ ASSERT_FALSE(generate_rsa_waiter_2.Get().has_value()); EXPECT_EQ(generate_rsa_waiter_2.Get().error(), Error::kTokenInitializationFailed); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } TEST_F(KcerNssTest, ListKeys) { @@ -496,6 +598,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), device_token.GetWeakPtr()); + auto subscription = kcer->AddObserver(observer_.GetCallback()); std::vector<PublicKey> all_expected_keys; std::vector<PublicKey> user_expected_keys; @@ -613,6 +716,8 @@ EXPECT_THAT(list_keys_waiter.Get<std::vector<PublicKey>>(), testing::UnorderedElementsAreArray(device_expected_keys)); } + + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test that Kcer::Sign() works correctly for RSA keys with different signing @@ -625,6 +730,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> generate_key_waiter; kcer->GenerateRsaKey(Token::kUser, /*modulus_length_bits=*/2048, @@ -682,6 +788,8 @@ signature_verifier.VerifyUpdate(data_to_sign.value()); EXPECT_TRUE(signature_verifier.VerifyFinal()); } + + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test that Kcer::Sign() works correctly for ECC keys. @@ -693,6 +801,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> generate_key_waiter; kcer->GenerateEcKey(Token::kUser, EllipticCurve::kP256, @@ -719,6 +828,8 @@ signature_verifier.VerifyUpdate(data_to_sign.value()); EXPECT_TRUE(signature_verifier.VerifyFinal()); } + + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test that `Kcer::SignRsaPkcs1Raw()` produces a correct signature. @@ -728,6 +839,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> generate_key_waiter; kcer->GenerateRsaKey(Token::kUser, /*modulus_length_bits=*/2048, @@ -769,6 +881,7 @@ data_to_sign, normal_sign_waiter.GetCallback()); ASSERT_TRUE(normal_sign_waiter.Get().has_value()); EXPECT_EQ(sign_waiter.Get().value(), normal_sign_waiter.Get().value()); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test that Kcer::GetTokenInfo() method returns meaningful values. @@ -778,6 +891,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<TokenInfo, Error>> get_token_info_waiter; @@ -792,6 +906,7 @@ EXPECT_THAT(token_info.token_name, testing::StartsWith("NSS Application Slot")); EXPECT_EQ(token_info.module_name, "NSS Internal PKCS #11 Module"); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test RSA specific fields from GetKeyInfo's result. @@ -801,6 +916,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); // Generate new key. base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; @@ -821,6 +937,7 @@ SigningScheme::kRsaPkcs1Sha384, SigningScheme::kRsaPkcs1Sha512, SigningScheme::kRsaPssRsaeSha256, SigningScheme::kRsaPssRsaeSha384, SigningScheme::kRsaPssRsaeSha512)); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test ECC specific fields from GetKeyInfo's result. @@ -830,6 +947,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); // Generate new key. base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; @@ -847,6 +965,7 @@ UnorderedElementsAre(SigningScheme::kEcdsaSecp256r1Sha256, SigningScheme::kEcdsaSecp384r1Sha384, SigningScheme::kEcdsaSecp521r1Sha512)); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test generic fields from GetKeyInfo's result and they get updated after @@ -857,6 +976,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); // Generate new key. base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; @@ -952,6 +1072,8 @@ EXPECT_TRUE( KeyInfoEquals(expected_key_info, key_info_waiter.Get().value())); } + + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } // Test different ways to call DoesPrivateKeyExist() method and that it returns @@ -962,6 +1084,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), /*user_token=*/nullptr, device_token.GetWeakPtr()); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; kcer->GenerateEcKey(Token::kDevice, EllipticCurve::kP256, @@ -1029,6 +1152,8 @@ << does_exist_waiter.Get().error(); EXPECT_EQ(does_exist_waiter.Get().value(), false); } + + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } class KcerNssAllKeyTypesTest : public KcerNssTest, @@ -1047,6 +1172,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), device_token.GetWeakPtr()); + auto subscription = kcer->AddObserver(observer_.GetCallback()); base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; switch (GetKeyType()) { @@ -1125,6 +1251,8 @@ << does_exist_waiter.Get().error(); EXPECT_EQ(does_exist_waiter.Get().value(), false); } + + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/0)); } TEST_P(KcerNssAllKeyTypesTest, RemoveKeyAndCertsWithManyCerts) { @@ -1138,10 +1266,11 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); // Generate new key. base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; - switch (GetParam()) { + switch (GetKeyType()) { case KeyType::kRsa: kcer->GenerateRsaKey(Token::kUser, /*modulus_length_bits=*/2048, /*hardware_backed=*/true, @@ -1166,6 +1295,7 @@ kcer->ImportX509Cert(Token::kUser, cert_builder->GetX509Certificate(), import_waiter.GetCallback()); EXPECT_TRUE(import_waiter.Get().has_value()); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/1)); } { std::unique_ptr<net::CertBuilder> issuer = MakeCertIssuer(); @@ -1176,6 +1306,7 @@ kcer->ImportX509Cert(Token::kUser, cert_builder->GetX509Certificate(), import_waiter.GetCallback()); EXPECT_TRUE(import_waiter.Get().has_value()); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/2)); } { std::unique_ptr<net::CertBuilder> issuer = MakeCertIssuer(); @@ -1186,6 +1317,7 @@ kcer->ImportX509Cert(Token::kUser, cert_builder->GetX509Certificate(), import_waiter.GetCallback()); EXPECT_TRUE(import_waiter.Get().has_value()); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/3)); } // Check that the imported cert can be found. @@ -1201,6 +1333,7 @@ kcer->RemoveKeyAndCerts(PrivateKeyHandle(public_key), remove_waiter.GetCallback()); EXPECT_TRUE(remove_waiter.Get().has_value()); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/4)); // Check that the imported cert cannot be found anymore. base::test::TestFuture<std::vector<scoped_refptr<const Cert>>, @@ -1227,6 +1360,7 @@ std::unique_ptr<Kcer> kcer = internal::CreateKcer( IOTaskRunner(), user_token.GetWeakPtr(), /*device_token=*/nullptr); + auto subscription = kcer->AddObserver(observer_.GetCallback()); // Generate new key. base::test::TestFuture<base::expected<PublicKey, Error>> generate_waiter; @@ -1254,6 +1388,7 @@ kcer->ImportX509Cert(Token::kUser, cert_builder->GetX509Certificate(), import_waiter.GetCallback()); EXPECT_TRUE(import_waiter.Get().has_value()); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/1)); // List certs, make sure the new cert is listed. base::test::TestFuture<std::vector<scoped_refptr<const Cert>>, @@ -1271,6 +1406,7 @@ base::test::TestFuture<base::expected<void, Error>> remove_cert_waiter; kcer->RemoveCert(certs.front(), remove_cert_waiter.GetCallback()); ASSERT_TRUE(remove_cert_waiter.Get().has_value()); + EXPECT_TRUE(observer_.WaitUntil(/*notifications=*/2)); // Check that the cert cannot be found anymore. base::test::TestFuture<std::vector<scoped_refptr<const Cert>>,
diff --git a/chrome/browser/chromeos/kcer_nss/kcer_token_impl_nss.cc b/chrome/browser/chromeos/kcer_nss/kcer_token_impl_nss.cc index d79cb6f..2289d42 100644 --- a/chrome/browser/chromeos/kcer_nss/kcer_token_impl_nss.cc +++ b/chrome/browser/chromeos/kcer_nss/kcer_token_impl_nss.cc
@@ -1497,6 +1497,7 @@ template <typename T> void KcerTokenImplNss::HandleInitializationFailed( base::OnceCallback<void(base::expected<T, Error>)> callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::IO); std::move(callback).Run(base::unexpected(Error::kTokenInitializationFailed)); // Multiple tasks might be handled in a row, schedule the next task // asynchronously to not overload the stack and not occupy the thread for
diff --git a/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc b/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc index 4ccd7bed..36942d2 100644 --- a/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc +++ b/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc
@@ -71,14 +71,16 @@ return; } + media_usage_update_callback_.Run(); + + // This will be an AnchoredNudge, which is only visible if the tray is + // visible; so we have to call this after media_usage_update_callback_. if (camera_system_disabled_ && !prev_is_capturing_video && is_capturing_video) { device_used_while_disabled_callback_.Run( crosapi::mojom::VideoConferenceMediaDevice::kCamera, contents->GetTitle()); } - - media_usage_update_callback_.Run(); } } @@ -104,14 +106,16 @@ return; } + media_usage_update_callback_.Run(); + + // This will be an AnchoredNudge, which is only visible if the tray is + // visible; so we have to call this after media_usage_update_callback_. if (microphone_system_disabled_ && !prev_is_capturing_audio && is_capturing_audio) { device_used_while_disabled_callback_.Run( crosapi::mojom::VideoConferenceMediaDevice::kMicrophone, contents->GetTitle()); } - - media_usage_update_callback_.Run(); } }
diff --git a/chrome/browser/companion/BUILD.gn b/chrome/browser/companion/BUILD.gn index 5e9a4a3..ad15c09 100644 --- a/chrome/browser/companion/BUILD.gn +++ b/chrome/browser/companion/BUILD.gn
@@ -11,6 +11,7 @@ deps += [ "core:unit_tests", "text_finder:unit_tests", + "visual_search:unit_tests", ] } }
diff --git a/chrome/browser/companion/visual_search/BUILD.gn b/chrome/browser/companion/visual_search/BUILD.gn index 63031d5e..0499b37 100644 --- a/chrome/browser/companion/visual_search/BUILD.gn +++ b/chrome/browser/companion/visual_search/BUILD.gn
@@ -2,10 +2,34 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -static_library("visual_search") { +source_set("visual_search") { sources = [ "features.cc", "features.h", + "visual_search_suggestions_service.cc", + "visual_search_suggestions_service.h", ] - deps = [ "//base" ] + deps = [ + "//base", + "//chrome/browser/profiles:profile", + "//components/optimization_guide/core", + "//components/optimization_guide/proto:optimization_guide_proto", + "//content/public/browser:browser", + "//third_party/blink/public/common:headers", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ "visual_search_suggestions_service_unittest.cc" ] + + deps = [ + ":visual_search", + "//base", + "//base/test:test_support", + "//components/optimization_guide/core:test_support", + "//components/optimization_guide/proto:optimization_guide_proto", + "//testing/gmock", + "//testing/gtest", + ] }
diff --git a/chrome/browser/companion/visual_search/features.cc b/chrome/browser/companion/visual_search/features.cc index 65113a8..05805979 100644 --- a/chrome/browser/companion/visual_search/features.cc +++ b/chrome/browser/companion/visual_search/features.cc
@@ -9,7 +9,7 @@ #include "base/metrics/field_trial_params.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace visual_search { +namespace companion::visual_search { namespace features { BASE_FEATURE(kVisualSearchSuggestions, @@ -32,4 +32,4 @@ } } // namespace switches -} // namespace visual_search +} // namespace companion::visual_search
diff --git a/chrome/browser/companion/visual_search/features.h b/chrome/browser/companion/visual_search/features.h index 38cfe44..f78ef8b 100644 --- a/chrome/browser/companion/visual_search/features.h +++ b/chrome/browser/companion/visual_search/features.h
@@ -9,7 +9,7 @@ #include "base/metrics/field_trial_params.h" #include "third_party/abseil-cpp/absl/types/optional.h" -namespace visual_search { +namespace companion::visual_search { namespace features { // Enables visual search capabilities for the companion. @@ -20,9 +20,10 @@ namespace switches { extern const char kVisualSearchConfigForCompanion[]; +// Allows us to pass in a base64 proto string in the command line absl::optional<std::string> GetVisualSearchConfigForCompanionOverride(); } // namespace switches -} // namespace visual_search +} // namespace companion::visual_search #endif // CHROME_BROWSER_COMPANION_VISUAL_SEARCH_FEATURES_H_
diff --git a/chrome/browser/companion/visual_search/visual_search_suggestions_service.cc b/chrome/browser/companion/visual_search/visual_search_suggestions_service.cc new file mode 100644 index 0000000..9fb1a16 --- /dev/null +++ b/chrome/browser/companion/visual_search/visual_search_suggestions_service.cc
@@ -0,0 +1,107 @@ +// 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 "chrome/browser/companion/visual_search/visual_search_suggestions_service.h" +#include "base/files/file.h" +#include "base/files/file_util.h" +#include "base/logging.h" +#include "base/task/sequenced_task_runner.h" +#include "components/optimization_guide/core/optimization_guide_model_provider.h" +#include "components/optimization_guide/proto/models.pb.h" +#include "content/public/browser/browser_thread.h" + +using content::BrowserThread; + +namespace companion::visual_search { + +namespace { + +// Load the model file at the provided file path. +base::File LoadModelFile(const base::FilePath& model_file_path) { + if (!base::PathExists(model_file_path)) { + return base::File(); + } + + return base::File(model_file_path, + base::File::FLAG_OPEN | base::File::FLAG_READ); +} + +// Close the provided model file. +void CloseModelFile(base::File model_file) { + if (!model_file.IsValid()) { + return; + } + model_file.Close(); +} + +} // namespace + +VisualSearchSuggestionsService::VisualSearchSuggestionsService( + optimization_guide::OptimizationGuideModelProvider* model_provider, + const scoped_refptr<base::SequencedTaskRunner>& background_task_runner) + : model_provider_(model_provider), + background_task_runner_(background_task_runner) { + if (model_provider_) { + model_provider_->AddObserverForOptimizationTargetModel( + optimization_guide::proto:: + OPTIMIZATION_TARGET_VISUAL_SEARCH_CLASSIFICATION, + /*model_metadata=*/absl::nullopt, this); + } +} + +VisualSearchSuggestionsService::~VisualSearchSuggestionsService() { + if (model_provider_) { + model_provider_->RemoveObserverForOptimizationTargetModel( + optimization_guide::proto:: + OPTIMIZATION_TARGET_VISUAL_SEARCH_CLASSIFICATION, + this); + model_provider_ = nullptr; + } +} + +void VisualSearchSuggestionsService::Shutdown() { + if (model_file_) { + // If the model file is already loaded, it should be closed on a + // background thread. + background_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&CloseModelFile, std::move(*model_file_))); + } +} + +void VisualSearchSuggestionsService::OnModelFileLoaded(base::File model_file) { + if (!model_file.IsValid()) { + return; + } + + if (model_file_) { + // If the model file is already loaded, it should be closed on a + // background thread. + background_task_runner_->PostTask( + FROM_HERE, base::BindOnce(&CloseModelFile, std::move(*model_file_))); + } + model_file_ = std::move(model_file); +} + +void VisualSearchSuggestionsService::OnModelUpdated( + optimization_guide::proto::OptimizationTarget optimization_target, + const optimization_guide::ModelInfo& model_info) { + if (optimization_target != + optimization_guide::proto:: + OPTIMIZATION_TARGET_VISUAL_SEARCH_CLASSIFICATION) { + return; + } + background_task_runner_->PostTaskAndReplyWithResult( + FROM_HERE, base::BindOnce(&LoadModelFile, model_info.GetModelFilePath()), + base::BindOnce(&VisualSearchSuggestionsService::OnModelFileLoaded, + weak_ptr_factory_.GetWeakPtr())); +} + +base::File VisualSearchSuggestionsService::GetModelFile() { + if (model_file_) { + return model_file_->Duplicate(); + } + return base::File(); +} + +} // namespace companion::visual_search
diff --git a/chrome/browser/companion/visual_search/visual_search_suggestions_service.h b/chrome/browser/companion/visual_search/visual_search_suggestions_service.h new file mode 100644 index 0000000..9d8bcc6 --- /dev/null +++ b/chrome/browser/companion/visual_search/visual_search_suggestions_service.h
@@ -0,0 +1,54 @@ +// 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 CHROME_BROWSER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_SUGGESTIONS_SERVICE_H_ +#define CHROME_BROWSER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_SUGGESTIONS_SERVICE_H_ + +#include "base/files/file.h" +#include "base/functional/callback_forward.h" +#include "components/keyed_service/core/keyed_service.h" +#include "components/optimization_guide/core/optimization_target_model_observer.h" + +namespace optimization_guide { +class OptimizationGuideModelProvider; +} // namespace optimization_guide + +namespace companion::visual_search { + +class VisualSearchSuggestionsService + : public KeyedService, + public optimization_guide::OptimizationTargetModelObserver { + public: + VisualSearchSuggestionsService( + optimization_guide::OptimizationGuideModelProvider* model_provider, + const scoped_refptr<base::SequencedTaskRunner>& background_task_runner); + + VisualSearchSuggestionsService(const VisualSearchSuggestionsService&) = + delete; + VisualSearchSuggestionsService& operator=( + const VisualSearchSuggestionsService&) = delete; + ~VisualSearchSuggestionsService() override; + + void Shutdown() override; + + // optimization_guide::OptimizationTargetModelObserver implementation: + void OnModelUpdated( + optimization_guide::proto::OptimizationTarget optimization_target, + const optimization_guide::ModelInfo& model_info) override; + + // Simple getter to access the model file. + base::File GetModelFile(); + + private: + void OnModelFileLoaded(base::File model_file); + + absl::optional<base::File> model_file_; + raw_ptr<optimization_guide::OptimizationGuideModelProvider> model_provider_; + scoped_refptr<base::SequencedTaskRunner> background_task_runner_; + base::WeakPtrFactory<VisualSearchSuggestionsService> weak_ptr_factory_{this}; +}; + +} // namespace companion::visual_search + +#endif // CHROME_BROWSER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_SUGGESTIONS_SERVICE_H_
diff --git a/chrome/browser/companion/visual_search/visual_search_suggestions_service_factory.cc b/chrome/browser/companion/visual_search/visual_search_suggestions_service_factory.cc new file mode 100644 index 0000000..46ac929 --- /dev/null +++ b/chrome/browser/companion/visual_search/visual_search_suggestions_service_factory.cc
@@ -0,0 +1,55 @@ +// 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 "chrome/browser/companion/visual_search/visual_search_suggestions_service_factory.h" + +#include "base/memory/scoped_refptr.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service.h" +#include "chrome/browser/optimization_guide/optimization_guide_keyed_service_factory.h" +#include "chrome/browser/profiles/profile.h" + +namespace companion::visual_search { + +// static +VisualSearchSuggestionsService* +VisualSearchSuggestionsServiceFactory::GetForProfile(Profile* profile) { + return static_cast<VisualSearchSuggestionsService*>( + GetInstance()->GetServiceForBrowserContext(profile, /* create= */ + true)); +} + +VisualSearchSuggestionsServiceFactory::VisualSearchSuggestionsServiceFactory() + : ProfileKeyedServiceFactory( + "VisualSearchSuggestionsService", + ProfileSelections::Builder() + .WithRegular(ProfileSelection::kOriginalOnly) + .WithGuest(ProfileSelection::kOriginalOnly) + .Build()) {} + +// static +VisualSearchSuggestionsServiceFactory* +VisualSearchSuggestionsServiceFactory::GetInstance() { + return base::Singleton<VisualSearchSuggestionsServiceFactory>::get(); +} + +KeyedService* VisualSearchSuggestionsServiceFactory::BuildServiceInstanceFor( + content::BrowserContext* context) const { + // The optimization guide service must be available for the translate model + // service to be created. + auto* opt_guide = OptimizationGuideKeyedServiceFactory::GetForProfile( + Profile::FromBrowserContext(context)); + if (opt_guide) { + scoped_refptr<base::SequencedTaskRunner> background_task_runner = + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); + return new VisualSearchSuggestionsService(opt_guide, + background_task_runner); + } + return nullptr; +} + +} // namespace companion::visual_search
diff --git a/chrome/browser/companion/visual_search/visual_search_suggestions_service_factory.h b/chrome/browser/companion/visual_search/visual_search_suggestions_service_factory.h new file mode 100644 index 0000000..5457188 --- /dev/null +++ b/chrome/browser/companion/visual_search/visual_search_suggestions_service_factory.h
@@ -0,0 +1,51 @@ +// 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 CHROME_BROWSER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_SUGGESTIONS_SERVICE_FACTORY_H_ +#define CHROME_BROWSER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_SUGGESTIONS_SERVICE_FACTORY_H_ + +#include "base/memory/singleton.h" +#include "chrome/browser/companion/visual_search/visual_search_suggestions_service.h" +#include "chrome/browser/profiles/profile_keyed_service_factory.h" +#include "content/public/browser/browser_context.h" + +class KeyedService; +class Profile; + +namespace companion::visual_search { +class VisualSearchSuggestionsService; + +// Singleton that owns VisualSearchSuggestionsService objects, one for each +// active Profile. +class VisualSearchSuggestionsServiceFactory + : public ProfileKeyedServiceFactory { + public: + // Creates the service if it does not already exist for the profile. + static VisualSearchSuggestionsService* GetForProfile(Profile* profile); + + // Get the singleton instance + static VisualSearchSuggestionsServiceFactory* GetInstance(); + + VisualSearchSuggestionsServiceFactory( + const VisualSearchSuggestionsServiceFactory&) = delete; + + VisualSearchSuggestionsServiceFactory& operator=( + const VisualSearchSuggestionsServiceFactory&) = delete; + + private: + friend struct base::DefaultSingletonTraits< + VisualSearchSuggestionsServiceFactory>; + + VisualSearchSuggestionsServiceFactory(); + + ~VisualSearchSuggestionsServiceFactory() override = default; + // BrowserContextKeyedServiceFactory: + + KeyedService* BuildServiceInstanceFor( + content::BrowserContext* context) const override; +}; + +} // namespace companion::visual_search + +#endif // CHROME_BROWSER_COMPANION_VISUAL_SEARCH_VISUAL_SEARCH_SUGGESTIONS_SERVICE_FACTORY_H_
diff --git a/chrome/browser/companion/visual_search/visual_search_suggestions_service_unittest.cc b/chrome/browser/companion/visual_search/visual_search_suggestions_service_unittest.cc new file mode 100644 index 0000000..82d20146 --- /dev/null +++ b/chrome/browser/companion/visual_search/visual_search_suggestions_service_unittest.cc
@@ -0,0 +1,77 @@ +// 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 "chrome/browser/companion/visual_search/visual_search_suggestions_service.h" + +#include "base/containers/flat_set.h" +#include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/functional/bind.h" +#include "base/memory/scoped_refptr.h" +#include "base/path_service.h" +#include "base/task/sequenced_task_runner.h" +#include "base/task/task_traits.h" +#include "base/task/thread_pool.h" +#include "base/test/task_environment.h" +#include "components/optimization_guide/core/test_model_info_builder.h" +#include "components/optimization_guide/core/test_optimization_guide_model_provider.h" +#include "components/optimization_guide/proto/models.pb.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +static const char kModelFilename[] = "visual_model.tflite"; + +} // namespace + +class VisualSearchSuggestionsServiceTest : public ::testing::Test { + protected: + void SetUp() override { + scoped_refptr<base::SequencedTaskRunner> background_task_runner = + base::ThreadPool::CreateSequencedTaskRunner( + {base::MayBlock(), base::TaskPriority::BEST_EFFORT}); + test_model_provider_ = std::make_unique< + optimization_guide::TestOptimizationGuideModelProvider>(); + service_ = std::make_unique< + companion::visual_search::VisualSearchSuggestionsService>( + test_model_provider_.get(), background_task_runner); + + base::FilePath test_data_dir; + base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir); + test_data_dir = test_data_dir.AppendASCII("components/test/data"); + + base::flat_set<base::FilePath> additional_files; + additional_files.insert(test_data_dir.AppendASCII(kModelFilename)); + + model_info_ = + optimization_guide::TestModelInfoBuilder() + .SetModelFilePath(test_data_dir.AppendASCII(kModelFilename)) + .SetAdditionalFiles(additional_files) + .SetVersion(123) + .Build(); + + task_environment_.RunUntilIdle(); + } + + void TearDown() override { + service_ = nullptr; + task_environment_.RunUntilIdle(); + } + + base::test::TaskEnvironment task_environment_; + std::unique_ptr<companion::visual_search::VisualSearchSuggestionsService> + service_; + std::unique_ptr<optimization_guide::TestOptimizationGuideModelProvider> + test_model_provider_; + std::unique_ptr<optimization_guide::ModelInfo> model_info_; +}; + +TEST_F(VisualSearchSuggestionsServiceTest, OnModelUpdated) { + service_->OnModelUpdated(optimization_guide::proto::OptimizationTarget:: + OPTIMIZATION_TARGET_VISUAL_SEARCH_CLASSIFICATION, + *model_info_); + task_environment_.RunUntilIdle(); + EXPECT_TRUE(service_->GetModelFile().IsValid()); +}
diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc index ea1a9d6..b868d9d 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc
@@ -685,8 +685,11 @@ // If a setting is constrained to a session scope and a provider is made with // the `restore_Session` flag, the setting should not be cleared. TEST_F(PrefProviderTest, SessionScopeSettingsRestoreSession) { - TestingProfile testing_profile; - PrefProvider provider(testing_profile.GetPrefs(), /*off_the_record=*/false, + sync_preferences::TestingPrefServiceSyncable prefs; + PrefProvider::RegisterProfilePrefs(prefs.registry()); + + // Create a normal provider and set a setting. + PrefProvider provider(&prefs, /*off_the_record=*/false, /*store_last_modified=*/true, /*restore_session=*/false); @@ -717,13 +720,13 @@ // back. provider.ShutdownOnUIThread(); - PrefProvider provider2(testing_profile.GetPrefs(), /*off_the_record=*/false, + PrefProvider provider2(&prefs, /*off_the_record=*/false, /*store_last_modified=*/true, /*restore_session=*/true); EXPECT_EQ( CONTENT_SETTING_BLOCK, - TestUtils::GetContentSetting(&provider, primary_url, primary_url, + TestUtils::GetContentSetting(&provider2, primary_url, primary_url, ContentSettingsType::STORAGE_ACCESS, false)); provider2.ShutdownOnUIThread(); }
diff --git a/chrome/browser/device_api/managed_configuration_api_factory.cc b/chrome/browser/device_api/managed_configuration_api_factory.cc index a1b5d6e3..57560eb 100644 --- a/chrome/browser/device_api/managed_configuration_api_factory.cc +++ b/chrome/browser/device_api/managed_configuration_api_factory.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/device_api/managed_configuration_api_factory.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/device_api/managed_configuration_api.h" #include "chrome/browser/profiles/profile.h" #include "components/pref_registry/pref_registry_syncable.h" @@ -12,7 +12,8 @@ // static ManagedConfigurationAPIFactory* ManagedConfigurationAPIFactory::GetInstance() { - return base::Singleton<ManagedConfigurationAPIFactory>::get(); + static base::NoDestructor<ManagedConfigurationAPIFactory> instance; + return instance.get(); } // static
diff --git a/chrome/browser/device_api/managed_configuration_api_factory.h b/chrome/browser/device_api/managed_configuration_api_factory.h index 50a4f90..b82cf9d 100644 --- a/chrome/browser/device_api/managed_configuration_api_factory.h +++ b/chrome/browser/device_api/managed_configuration_api_factory.h
@@ -12,7 +12,7 @@ namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base // Factory for BrowserKeyedService ManagedConfigurationAPI. @@ -28,7 +28,7 @@ const ManagedConfigurationAPIFactory&) = delete; private: - friend struct base::DefaultSingletonTraits<ManagedConfigurationAPIFactory>; + friend base::NoDestructor<ManagedConfigurationAPIFactory>; ManagedConfigurationAPIFactory(); ~ManagedConfigurationAPIFactory() override;
diff --git a/chrome/browser/dips/dips_bounce_detector_browsertest.cc b/chrome/browser/dips/dips_bounce_detector_browsertest.cc index d8d5188..c064a4a 100644 --- a/chrome/browser/dips/dips_bounce_detector_browsertest.cc +++ b/chrome/browser/dips/dips_bounce_detector_browsertest.cc
@@ -99,7 +99,7 @@ redirects->push_back(base::StringPrintf( "[%zu/%zu] %s -> %s (%s) -> %s", redirect_index + 1, chain.length, FormatURL(chain.initial_url).c_str(), FormatURL(redirect.url).c_str(), - SiteDataAccessTypeToString(redirect.access_type).data(), + std::string(SiteDataAccessTypeToString(redirect.access_type)).c_str(), FormatURL(chain.final_url).c_str())); }
diff --git a/chrome/browser/downgrade/downgrade_manager.cc b/chrome/browser/downgrade/downgrade_manager.cc index 0de94fa..3adaab6 100644 --- a/chrome/browser/downgrade/downgrade_manager.cc +++ b/chrome/browser/downgrade/downgrade_manager.cc
@@ -195,7 +195,6 @@ type_ = GetDowngradeType(user_data_dir, current_version, *last_version); DCHECK(type_ == Type::kAdministrativeWipe || type_ == Type::kUnsupported); - base::UmaHistogramEnumeration("Downgrade.Type", type_); return type_ == Type::kAdministrativeWipe; } @@ -205,8 +204,6 @@ if (current_version < *last_version) { type_ = GetDowngradeTypeWithSnapshot(user_data_dir, current_version, *last_version); - if (type_ != Type::kNone) - base::UmaHistogramEnumeration("Downgrade.Type", type_); return type_ == Type::kAdministrativeWipe || type_ == Type::kSnapshotRestore;
diff --git a/chrome/browser/downgrade/user_data_downgrade_browsertest.cc b/chrome/browser/downgrade/user_data_downgrade_browsertest.cc index b96f041..966f29e7 100644 --- a/chrome/browser/downgrade/user_data_downgrade_browsertest.cc +++ b/chrome/browser/downgrade/user_data_downgrade_browsertest.cc
@@ -197,11 +197,7 @@ } void TearDownInProcessBrowserTestFixture() override { - if (ParentClass::IsPreTest()) { - // Verify that the downgrade was detected and that the move took place. - histogram_tester_->ExpectUniqueSample( - "Downgrade.Type", 1 /* Type::kAdministrativeWipe */, 1); - } else { + if (!ParentClass::IsPreTest()) { // Verify the renamed user data directory has been deleted. EXPECT_FALSE(base::DirectoryExists(moved_user_data_dir())); }
diff --git a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java index 9cf7c21..8b9e6b5 100644 --- a/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java +++ b/chrome/browser/download/internal/android/java/src/org/chromium/chrome/browser/download/home/DownloadActivityV2Test.java
@@ -54,9 +54,11 @@ import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.DisabledTest; +import org.chromium.base.test.util.HistogramWatcher; import org.chromium.base.test.util.JniMocker; -import org.chromium.chrome.browser.BackPressHelper; +import org.chromium.chrome.browser.back_press.BackPressHelper; import org.chromium.chrome.browser.back_press.BackPressManager; +import org.chromium.chrome.browser.back_press.SecondaryActivityBackPressUma.SecondaryActivity; import org.chromium.chrome.browser.download.home.list.ListUtils; import org.chromium.chrome.browser.download.home.list.holder.ListItemViewHolder; import org.chromium.chrome.browser.download.home.rename.RenameUtils; @@ -202,10 +204,10 @@ getActivity().setContentView(mDownloadCoordinator.getView()); if (BackPressManager.isSecondaryActivityEnabled()) { BackPressHelper.create(getActivity(), getActivity().getOnBackPressedDispatcher(), - mDownloadCoordinator.getBackPressHandlers()); + mDownloadCoordinator.getBackPressHandlers(), SecondaryActivity.DOWNLOAD); } else { BackPressHelper.create(getActivity(), getActivity().getOnBackPressedDispatcher(), - mDownloadCoordinator::onBackPressed); + mDownloadCoordinator::onBackPressed, SecondaryActivity.DOWNLOAD); } mDownloadCoordinator.updateForUrl(UrlConstants.DOWNLOADS_URL); @@ -668,20 +670,26 @@ onView(withId(R.id.search_text)).check(matches(not(isDisplayed()))); // Clear the selection by back press and assert that the search view is showing again. + var backPressRecorder = HistogramWatcher.newSingleRecordWatcher( + "Android.BackPress.SecondaryActivity", SecondaryActivity.DOWNLOAD); TestThreadUtils.runOnUiThreadBlocking( getActivity().getOnBackPressedDispatcher()::onBackPressed); + backPressRecorder.assertExpected(); onView(withId(R.id.search_text)).check(matches(isDisplayed())); // Close the search view, by performing a back press. + var backPressRecorder2 = HistogramWatcher.newSingleRecordWatcher( + "Android.BackPress.SecondaryActivity", SecondaryActivity.DOWNLOAD); TestThreadUtils.runOnUiThreadBlocking( getActivity().getOnBackPressedDispatcher()::onBackPressed); + backPressRecorder2.assertExpected(); CriteriaHelper.pollInstrumentationThread( () -> { onView(withId(R.id.search_text)).check(matches(not(isDisplayed()))); }); } @Test @MediumTest - @Features.DisableFeatures({ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY}) + @Features.EnableFeatures({ChromeFeatureList.BACK_GESTURE_REFACTOR_ACTIVITY}) public void testDismissSearchViewByBackPress_BackPressRefactor() { testDismissSearchViewByBackPress(); }
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc index b30891c..319bb859 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_delegate.cc
@@ -164,7 +164,8 @@ result_.page_result = true; ReportAnalysisConnectorWarningBypass( - profile_, url_, "", "", title_, /*sha256*/ std::string(), + profile_, url_, "", /*destination*/ data_.printer_name, title_, + /*sha256*/ std::string(), /*mime_type*/ std::string(), extensions::SafeBrowsingPrivateEventRouter::kTriggerPagePrint, access_point_, /*content_size*/ -1, page_response_, user_justification); @@ -535,7 +536,8 @@ FinalContentAnalysisResult::WARNING; MaybeReportDeepScanningVerdict( - profile_, url_, "", "", title_, /*sha256*/ std::string(), + profile_, url_, "", /*destination*/ data_.printer_name, title_, + /*sha256*/ std::string(), /*mime_type*/ std::string(), extensions::SafeBrowsingPrivateEventRouter::kTriggerPagePrint, access_point_, /*content_size*/ -1, result, response,
diff --git a/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc b/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc index 88427da..d6ed06e 100644 --- a/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc +++ b/chrome/browser/enterprise/connectors/analysis/print_content_analysis_utils_unittest.cc
@@ -131,9 +131,7 @@ void UploadPageForDeepScanning( std::unique_ptr<safe_browsing::BinaryUploadService::Request> request) override { - // TODO(b/278784312): Add assertions on this like the expected printer name - // here. - + ASSERT_EQ(request->printer_name(), kPrinterName); PageRequestCallback(safe_browsing::BinaryUploadService::Result::SUCCESS, CreateResponse(action_)); } @@ -241,8 +239,7 @@ validator.ExpectSensitiveDataEvent( /*url*/ "", /*source*/ "", - // TODO(b/278784312): Add the expected printer name here. - /*destination*/ "", + /*destination*/ kPrinterName, /*filename*/ "New Tab", /*sha*/ "", /*trigger*/ @@ -284,8 +281,7 @@ validator.ExpectSensitiveDataEvent( /*url*/ "", /*source*/ "", - // TODO(b/278784312): Add the expected printer name here. - /*destination*/ "", + /*destination*/ kPrinterName, /*filename*/ "New Tab", /*sha*/ "", /*trigger*/ @@ -329,8 +325,7 @@ validator.ExpectSensitiveDataEvent( /*url*/ "", /*source*/ "", - // TODO(b/278784312): Add the expected printer name here. - /*destination*/ "", + /*destination*/ kPrinterName, /*filename*/ "New Tab", /*sha*/ "", /*trigger*/ @@ -355,8 +350,7 @@ validator.ExpectSensitiveDataEvent( /*url*/ "", /*source*/ "", - // TODO(b/278784312): Add the expected printer name here. - /*destination*/ "", + /*destination*/ kPrinterName, /*filename*/ "New Tab", /*sha*/ "", /*trigger*/ @@ -392,8 +386,7 @@ validator.ExpectSensitiveDataEvent( /*url*/ "", /*source*/ "", - // TODO(b/278784312): Add the expected printer name here. - /*destination*/ "", + /*destination*/ kPrinterName, /*filename*/ "New Tab", /*sha*/ "", /*trigger*/
diff --git a/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc b/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc index b7216c8..94ad6c1 100644 --- a/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc +++ b/chrome/browser/extensions/api/autofill_private/autofill_private_apitest.cc
@@ -2,6 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/common/extensions/api/autofill_private.h" + +#include <memory> + #include "base/allocator/partition_allocator/pointers/raw_ptr.h" #include "base/command_line.h" #include "base/test/metrics/user_action_tester.h" @@ -11,7 +15,6 @@ #include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/extensions/extension_apitest.h" #include "chrome/browser/ui/autofill/chrome_autofill_client.h" -#include "chrome/common/extensions/api/autofill_private.h" #include "components/autofill/content/browser/test_autofill_client_injector.h" #include "components/autofill/content/browser/test_content_autofill_client.h" #include "components/autofill/core/browser/autofill_test_utils.h" @@ -28,6 +31,8 @@ namespace { +// TODO(crbug.com/1449321): Remove this TestAutofillClient and use the main +// TestAutofillClient instead. class TestChromeAutofillClient : public autofill::ChromeAutofillClient { public: explicit TestChromeAutofillClient(content::WebContents* web_contents) @@ -43,6 +48,16 @@ return personal_data_manager_; } + autofill::FormDataImporter* GetFormDataImporter() override { + if (!form_data_importer_) { + form_data_importer_ = std::make_unique<autofill::FormDataImporter>( + /*client=*/this, /*payments_client=*/nullptr, + /*personal_data_manager=*/nullptr, /*app_locale=*/"en-US"); + } + + return form_data_importer_.get(); + } + void SetDeviceAuthenticator( scoped_refptr<device_reauth::MockDeviceAuthenticator> mock_auth) { mock_device_authenticator_ = mock_auth; @@ -55,6 +70,7 @@ scoped_refptr<device_reauth::MockDeviceAuthenticator> mock_device_authenticator_; raw_ptr<autofill::TestPersonalDataManager> personal_data_manager_ = nullptr; + std::unique_ptr<autofill::FormDataImporter> form_data_importer_; #endif };
diff --git a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc index 9e2aa2a..c53ab81 100644 --- a/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc +++ b/chrome/browser/extensions/api/developer_private/developer_private_api_unittest.cc
@@ -192,8 +192,8 @@ auto function = base::MakeRefCounted<api::DeveloperPrivateAddHostPermissionFunction>(); - std::string args = base::StringPrintf(R"(["%s", "%s"])", - extension.id().c_str(), host.data()); + std::string args = base::StringPrintf( + R"(["%s", "%s"])", extension.id().c_str(), std::string(host).c_str()); if (should_succeed) { EXPECT_TRUE(api_test_utils::RunFunction(function.get(), args, profile)) << function->GetError();
diff --git a/chrome/browser/extensions/api/search/search_api.cc b/chrome/browser/extensions/api/search/search_api.cc index 99b32961..f3f2bc01 100644 --- a/chrome/browser/extensions/api/search/search_api.cc +++ b/chrome/browser/extensions/api/search/search_api.cc
@@ -110,7 +110,7 @@ web_contents->GetController().LoadURL( url, content::Referrer(), ui::PageTransition::PAGE_TRANSITION_FROM_API, - /*extra_header=*/std::string()); + /*extra_headers=*/std::string()); break; case Disposition::DISPOSITION_NEW_TAB: NavigateToURL(WindowOpenDisposition::NEW_FOREGROUND_TAB, browser, url);
diff --git a/chrome/browser/extensions/api/sessions/sessions_api.cc b/chrome/browser/extensions/api/sessions/sessions_api.cc index 0d5d999..39ed6cc 100644 --- a/chrome/browser/extensions/api/sessions/sessions_api.cc +++ b/chrome/browser/extensions/api/sessions/sessions_api.cc
@@ -45,6 +45,12 @@ #include "extensions/common/error_utils.h" #include "ui/base/layout.h" +// TODO(crbug.com/1424800): Remove once the restore issue has been resolved. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#undef ENABLED_VLOG_LEVEL +#define ENABLED_VLOG_LEVEL 1 +#endif + namespace extensions { namespace windows = api::windows; @@ -621,6 +627,8 @@ // TabRestoreServiceFactory::GetForProfile() can return nullptr (i.e., when in // incognito mode) if (tab_restore_service_) { + VLOG(1) << "SessionsEventRouter::SessionsEventRouter, loading tabs from " + "last session."; tab_restore_service_->LoadTabsFromLastSession(); tab_restore_service_->AddObserver(this); }
diff --git a/chrome/browser/extensions/api/settings_private/prefs_util.cc b/chrome/browser/extensions/api/settings_private/prefs_util.cc index 1fdc700..f86c190 100644 --- a/chrome/browser/extensions/api/settings_private/prefs_util.cc +++ b/chrome/browser/extensions/api/settings_private/prefs_util.cc
@@ -936,6 +936,8 @@ settings_api::PrefType::PREF_TYPE_BOOLEAN; (*s_allowlist)[::prefs::kConsumerAutoUpdateToggle] = settings_api::PrefType::PREF_TYPE_BOOLEAN; + (*s_allowlist)[::ash::prefs::kChargingSoundsEnabled] = + settings_api::PrefType::PREF_TYPE_BOOLEAN; // Native Printing settings. (*s_allowlist)[::prefs::kUserPrintersAllowed] =
diff --git a/chrome/browser/extensions/back_forward_cache_browsertest.cc b/chrome/browser/extensions/back_forward_cache_browsertest.cc index 58d76cc..8826102 100644 --- a/chrome/browser/extensions/back_forward_cache_browsertest.cc +++ b/chrome/browser/extensions/back_forward_cache_browsertest.cc
@@ -241,16 +241,16 @@ // cache. IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheExtensionsDisabledBrowserTest, ScriptDisallowed) { - ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("trivial_extension") - .AppendASCII("extension"))); - ASSERT_TRUE(embedded_test_server()->Start()); GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); // 1) Navigate to A. - content::RenderFrameHostWrapper rfh_a( - ui_test_utils::NavigateToURL(browser(), url_a)); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_a)); + content::RenderFrameHostWrapper rfh_a(current_main_frame_host()); + + ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("trivial_extension") + .AppendASCII("extension"))); // 2) Navigate to B. ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b)); @@ -1053,12 +1053,6 @@ // cache. IN_PROC_BROWSER_TEST_F(ExtensionBackForwardCacheBlockedExtensionBrowserTest, ScriptDisallowed) { - const Extension* extension = - LoadExtension(test_data_dir_.AppendASCII("trivial_extension") - .AppendASCII("extension.crx")); - ASSERT_TRUE(extension); - ASSERT_EQ(extension->id(), "mockepjebcnmhmhcahfddgfcdgkdifnc"); - ASSERT_TRUE(embedded_test_server()->Start()); GURL url_a(embedded_test_server()->GetURL("a.com", "/title1.html")); GURL url_b(embedded_test_server()->GetURL("b.com", "/title1.html")); @@ -1067,6 +1061,12 @@ content::RenderFrameHostWrapper rfh_a( ui_test_utils::NavigateToURL(browser(), url_a)); + const Extension* extension = + LoadExtension(test_data_dir_.AppendASCII("trivial_extension") + .AppendASCII("extension.crx")); + ASSERT_TRUE(extension); + ASSERT_EQ(extension->id(), "mockepjebcnmhmhcahfddgfcdgkdifnc"); + // 2) Navigate to B. ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url_b));
diff --git a/chrome/browser/extensions/content_script_apitest.cc b/chrome/browser/extensions/content_script_apitest.cc index 875d2f5..f7c016720 100644 --- a/chrome/browser/extensions/content_script_apitest.cc +++ b/chrome/browser/extensions/content_script_apitest.cc
@@ -1774,6 +1774,7 @@ // Now, navigate the iframe to an about:blank URL. NavigateIframe(tab->GetPrimaryMainFrame(), "frames[0]", about_blank()); + child_frame = content::ChildFrameAt(tab->GetPrimaryMainFrame(), 0); // Unlike match_origin_as_fallback, match_about_blank will attempt to climb // the frame tree to find an ancestor with path. This results in finding the
diff --git a/chrome/browser/extensions/extension_api_frame_id_map_browsertest.cc b/chrome/browser/extensions/extension_api_frame_id_map_browsertest.cc index 6768ccc..163ef222 100644 --- a/chrome/browser/extensions/extension_api_frame_id_map_browsertest.cc +++ b/chrome/browser/extensions/extension_api_frame_id_map_browsertest.cc
@@ -82,7 +82,7 @@ ui_test_utils::BROWSER_TEST_WAIT_FOR_LOAD_STOP); ASSERT_TRUE(page2_new_host); base::Uuid page2_new_context_id = - ExtensionApiFrameIdMap::GetContextId(page2_host); + ExtensionApiFrameIdMap::GetContextId(page2_new_host); EXPECT_NE(page2_new_context_id, page1_a_context_id); EXPECT_NE(page2_new_context_id, page1_b_context_id);
diff --git a/chrome/browser/extensions/extension_service.cc b/chrome/browser/extensions/extension_service.cc index dcc7318..348face 100644 --- a/chrome/browser/extensions/extension_service.cc +++ b/chrome/browser/extensions/extension_service.cc
@@ -497,6 +497,7 @@ external_install_manager_->Shutdown(); corrupted_extension_reinstaller_.Shutdown(); extension_registrar_.Shutdown(); + weak_ptr_factory_.InvalidateWeakPtrs(); } void ExtensionService::Init() {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index b86d841..c7db0b40 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -97,12 +97,6 @@ "expiry_milestone": -1 }, { - "name": "allow-devtools-in-system-ui", - "owners": [ "lacros-team@google.com" ], - // This flag is needed as debugging tool for ChromeOS developers. - "expiry_milestone": -1 - }, - { "name": "allow-dsp-based-aec", "owners": [ "peah" ], "expiry_milestone": 118 @@ -405,6 +399,11 @@ "expiry_milestone": 120 }, { + "name": "audio-hfp-nbs-warning", + "owners": [ "jrwu", "chromeos-audio@google.com" ], + "expiry_milestone": 130 + }, + { "name": "audio-hfp-offload", "owners": [ "johnylin", "jrwu", "chromeos-audio@google.com" ], "expiry_milestone": 122 @@ -686,6 +685,14 @@ "expiry_milestone": 106 }, { + "name": "autofill-use-two-dots-for-last-four-digits", + "owners": [ + "smcgruer", + "chrome-payments-team@google.com" + ], + "expiry_milestone": 120 + }, + { "name": "back-forward-cache", "owners": [ "bfcache-dev@chromium.org" ], "expiry_milestone": 120 @@ -1866,11 +1873,6 @@ "expiry_milestone": -1 }, { - "name": "enable-autofill-manual-fallback", - "owners": [ "fhorschig@chromium.org" ], - "expiry_milestone": 116 - }, - { "name": "enable-autofill-touch-to-fill-for-credit-cards", "owners": [ "vishwasuppoor", "izuzic" ], "expiry_milestone": 120 @@ -2050,6 +2052,11 @@ "expiry_milestone": 125 }, { + "name": "enable-cros-autocorrect-use-replace-surrounding-text", + "owners": [ "hdchuong", "essential-inputs-team@google.com" ], + "expiry_milestone": 125 + }, + { "name": "enable-cros-avatars-cloud-migration", "owners": [ "updowndota", "angelaxiao", "assistive-eng@google.com" ], "expiry_milestone": 120 @@ -2983,6 +2990,11 @@ "expiry_milestone": -1 }, { + "name": "enable-peripheral-customization", + "owners": ["dpad", "zentaro", "cros-peripherals@google.com"], + "expiry_milestone": 126 + }, + { "name": "enable-phone-hub-call-notification", "owners": [ "jonmann", "nayebi" ], "expiry_milestone": 125 @@ -4366,11 +4378,6 @@ "expiry_milestone": 120 }, { - "name": "history-journeys-hide-visits", - "owners": [ "manukh", "chrome-journeys@google.com" ], - "expiry_milestone": 120 - }, - { "name": "history-journeys-images", "owners": [ "tommycli", "chrome-journeys@google.com" ], "expiry_milestone": 120 @@ -4674,6 +4681,11 @@ "expiry_milestone": 110 }, { + "name": "ios-payments-bottom-sheet", + "owners": ["veronguyen", "sugoi", "tmartino", "bling-integrations-team@google.com"], + "expiry_milestone": 120 + }, + { "name": "ios-promo-password-bubble", "owners": ["nicolasmacbeth@google.com", "bling-get-set-up@google.com"], "expiry_milestone": 120 @@ -4841,11 +4853,6 @@ "expiry_milestone": 130 }, { - "name": "language-packs-in-oobe", - "owners": [ "claudiomagni", "cros-borders-eng@google.com"], - "expiry_milestone": 119 - }, - { "name": "large-favicon-from-google", "owners": [ "bttk" @@ -5503,11 +5510,6 @@ "expiry_milestone": 120 }, { - "name": "omnibox-disable-cgi-param-matching", - "owners": [ "yoangela", "chrome-omnibox-team@google.com" ], - "expiry_milestone": 96 - }, - { "name": "omnibox-discard-temporary-input-on-tab-switch", "owners": [ "manukh", "chrome-desktop-search@google.com" ], "expiry_milestone": 120 @@ -6219,6 +6221,13 @@ "expiry_milestone": 122 }, { + "name": "print-preview-discovered-printers", + "owners": [ + "//ash/webui/print_management/OWNERS" + ], + "expiry_milestone": 120 + }, + { "name": "print-with-postscript-type42-fonts", "owners": [ "thestig" ], "expiry_milestone": 122 @@ -6485,11 +6494,6 @@ "expiry_milestone": -1 }, { - "name": "recover-from-never-save-android", - "owners": [ "ioanap", "fhorschig" ], - "expiry_milestone": 116 - }, - { "name": "reduce-accept-language", "owners": [ "miketaylr", "victortan"], "expiry_milestone": 120 @@ -6641,6 +6645,17 @@ "expiry_milestone": 109 }, { + "name": "scalable-iph", + "owners": [ + "angelaxiao", + "wutao", + "xiaohuic", + "yawano", + "assistive-eng@google.com" + ], + "expiry_milestone": 125 + }, + { "name": "scanning-app-jelly", "owners": [ "//ash/webui/scanning/OWNERS" @@ -7005,15 +7020,6 @@ "expiry_milestone": -1 }, { - "name": "speak-on-mute-detection", - "owners": [ - "aaronyu", - "chenjih", - "chromeos-audio@google.com" - ], - "expiry_milestone": 120 - }, - { "name": "spectre-v2-mitigation", "owners": [ "chromeos-security@google.com"
diff --git a/chrome/browser/flag-never-expire-list.json b/chrome/browser/flag-never-expire-list.json index 3ee18dedd..8ea3df6 100644 --- a/chrome/browser/flag-never-expire-list.json +++ b/chrome/browser/flag-never-expire-list.json
@@ -14,7 +14,6 @@ // test (AboutFlagsTest.OnlyPermittedFlagsNeverExpire). [ "allow-all-sites-to-initiate-mirroring", - "allow-devtools-in-system-ui", "allow-previews", "always-enable-hdcp", "arc-native-bridge-toggle",
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 3000a899..fe430e57 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1160,6 +1160,12 @@ const char kEnableInputDeviceSettingsSplitDescription[] = "Enable input device settings to be split per-device."; +const char kEnablePeripheralCustomizationName[] = + "Enable peripheral customization"; +const char kEnablePeripheralCustomizationDescription[] = + "Enable peripheral customization to allow users to customize buttons on " + "their peripherals."; + const char kExperimentalRgbKeyboardPatternsName[] = "Enable experimental RGB Keyboard patterns support"; const char kExperimentalRgbKeyboardPatternsDescription[] = @@ -1905,10 +1911,6 @@ const char kJourneysContentClusteringDescription[] = "Enables clustering page loads using content annotations."; -const char kJourneysHideVisitsName[] = "History Journeys Hide Visits"; -const char kJourneysHideVisitsDescription[] = - "Adds a UI element to hide individual cluster visits in the webUI."; - const char kJourneysImagesName[] = "History Journeys Images"; const char kJourneysImagesDescription[] = "Enables Images for the History Journeys UI."; @@ -2170,11 +2172,6 @@ const char kOmniboxCR23SteadyStateIconsDescription[] = "Updates Omnibox steady state icons to comply with CR23 guidelines."; -const char kOmniboxDisableCGIParamMatchingName[] = - "Disable CGI Param Name Matching"; -const char kOmniboxDisableCGIParamMatchingDescription[] = - "Disables using matches in CGI parameter names while scoring suggestions."; - const char kOmniboxIgnoreIntermediateResultsName[] = "Ignore intermediate Autocomplete results."; const char kOmniboxIgnoreIntermediateResultsDescription[] = @@ -3022,11 +3019,6 @@ const char kSmoothScrollingDescription[] = "Animate smoothly when scrolling page content."; -const char kSpeakOnMuteName[] = "Enable Speak On Mute Detection"; -const char kSpeakOnMuteDescription[] = - "Enable the speak-on-mute detector in CRAS. Reboot is required to let the " - "flag take effect"; - const char kSplitCacheByNetworkIsolationKeyName[] = "HTTP Cache Partitioning"; const char kSplitCacheByNetworkIsolationKeyDescription[] = "Partitions the HTTP Cache by (top-level site, current-frame site) to " @@ -3612,11 +3604,6 @@ " DisplayCompositor on Android. This feature is only available on " " android Q+ devices"; -const char kAndroidWidgetFullscreenToastName[] = - "Android widget fullscreen toast"; -const char kAndroidWidgetFullscreenToastDescription[] = - "Use Android Toast widget for fullscreen notifcation UI."; - const char kAndroidImprovedBookmarksName[] = "Android Visual Bookmark Manager"; const char kAndroidImprovedBookmarksDescription[] = "More visual changes to the bookmarks surfaces, with more thumbnails and a " @@ -5016,14 +5003,6 @@ const char kAdaptiveChargingDescription[] = "Show settings to enable/disable adaptive charging feature."; -const char kAllowDevtoolsInSystemUIName[] = "Enable DevTools in System UI"; -const char kAllowDevtoolsInSystemUIDescription[] = - "Enable the developer tools (DevTools) including the page source viewer " - "(view-source) in Ash. By default, these tools are disabled if Lacros is " - "the only browser, so as not to confuse the user by opening an Ash window. " - "By enabling this flag, you can access them via the context menu or " - "shortcuts to debug the system UI."; - const char kAllowEapDefaultCasWithoutSubjectVerificationName[] = "Allow EAP network configs with default server CAs without subject " "verification"; @@ -5202,6 +5181,10 @@ const char kAudioHFPMicSRDescription[] = "Enable super-resolution Bluetooth HFP microphone recording."; +const char kAudioHFPNbsWarningName[] = "Warn when an NBS device is selected"; +const char kAudioHFPNbsWarningDescription[] = + "Shows a warning in the quick settings when an NBS device is selected"; + const char kAudioHFPOffloadName[] = "Audio Bluetooth HFP offloaded to DSP if supported"; const char kAudioHFPOffloadDescription[] = @@ -5235,6 +5218,12 @@ const char kAutocorrectToggleDescription[] = "Enables using a toggle for enabling autocorrect on ChromeOS."; +const char kAutocorrectUseReplaceSurroundingTextName[] = + "Use ReplaceSurroundingText API for autocorrect."; +const char kAutocorrectUseReplaceSurroundingTextDescription[] = + "When autocorrect is enabled, use the ReplaceSurroundingText API " + "for better app compatibility."; + const char kAvatarsCloudMigrationName[] = "Loading CrOS avatar images from the cloud"; const char kAvatarsCloudMigrationDescription[] = @@ -6134,12 +6123,6 @@ "migration is rolled out to the user, the migration will not run and the " "user can continue to use lacros without profile migration."; -extern const char kLanguagePacksInOobeName[] = "Language Packs in OOBE"; -extern const char kLanguagePacksInOobeDescription[] = - "Enables the call to install Language Packs during the OOBE flow. This " - "logic improves the user experience by fetching language resources as " - "early as possible."; - const char kLauncherItemSuggestName[] = "Launcher ItemSuggest"; const char kLauncherItemSuggestDescription[] = "Allows configuration of experiment parameters for ItemSuggest in the " @@ -6280,6 +6263,12 @@ const char kPrinterSettingsRevampDescription[] = "Show the enhanced UI for the OS Printer settings page."; +const char kPrintPreviewDiscoveredPrintersName[] = + "Enables showing discovered printers in the Print Preview dialog."; +const char kPrintPreviewDiscoveredPrintersDescription[] = + "Shows discovered printers in the Print Preview dialog that get set up " + "once selected."; + const char kPrintingPpdChannelName[] = "Printing PPD channel"; const char kPrintingPpdChannelDescription[] = "The channel from which PPD index " @@ -6361,6 +6350,11 @@ "Enable menu and action reposition feature for Gaming Input Overlay based " "on Alpha."; +const char kScalableIphName[] = "Enable ChromeOS scalable IPH."; +const char kScalableIphDescription[] = + "Enable scalable IPH. In addition to this flag, each respective IPH " + "trigger condition needs to be met before an IPH notifier is shown."; + const char kScanningAppJellyName[] = "Enable jelly colors for the Scanning App."; const char kScanningAppJellyDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index f254cf4e..9b55446 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -736,6 +736,9 @@ extern const char kEnablePerfettoSystemTracingName[]; extern const char kEnablePerfettoSystemTracingDescription[]; +extern const char kEnablePeripheralCustomizationName[]; +extern const char kEnablePeripheralCustomizationDescription[]; + extern const char kEnablePixelCanvasRecordingName[]; extern const char kEnablePixelCanvasRecordingDescription[]; @@ -1062,9 +1065,6 @@ extern const char kJourneysContentClusteringName[]; extern const char kJourneysContentClusteringDescription[]; -extern const char kJourneysHideVisitsName[]; -extern const char kJourneysHideVisitsDescription[]; - extern const char kJourneysImagesName[]; extern const char kJourneysImagesDescription[]; @@ -1224,9 +1224,6 @@ extern const char kOmniboxCR23SteadyStateIconsName[]; extern const char kOmniboxCR23SteadyStateIconsDescription[]; -extern const char kOmniboxDisableCGIParamMatchingName[]; -extern const char kOmniboxDisableCGIParamMatchingDescription[]; - extern const char kOmniboxIgnoreIntermediateResultsName[]; extern const char kOmniboxIgnoreIntermediateResultsDescription[]; @@ -1711,9 +1708,6 @@ extern const char kSmoothScrollingName[]; extern const char kSmoothScrollingDescription[]; -extern const char kSpeakOnMuteName[]; -extern const char kSpeakOnMuteDescription[]; - extern const char kSplitCacheByNetworkIsolationKeyName[]; extern const char kSplitCacheByNetworkIsolationKeyDescription[]; @@ -2090,9 +2084,6 @@ extern const char kAndroidSurfaceControlName[]; extern const char kAndroidSurfaceControlDescription[]; -extern const char kAndroidWidgetFullscreenToastName[]; -extern const char kAndroidWidgetFullscreenToastDescription[]; - extern const char kAnimatedImageDragShadowName[]; extern const char kAnimatedImageDragShadowDescription[]; extern const char kAndroidImprovedBookmarksName[]; @@ -2889,9 +2880,6 @@ extern const char kAdaptiveChargingForTestingName[]; extern const char kAdaptiveChargingForTestingDescription[]; -extern const char kAllowDevtoolsInSystemUIName[]; -extern const char kAllowDevtoolsInSystemUIDescription[]; - extern const char kAllowEapDefaultCasWithoutSubjectVerificationName[]; extern const char kAllowEapDefaultCasWithoutSubjectVerificationDescription[]; @@ -2989,6 +2977,9 @@ extern const char kAudioHFPMicSRName[]; extern const char kAudioHFPMicSRDescription[]; +extern const char kAudioHFPNbsWarningName[]; +extern const char kAudioHFPNbsWarningDescription[]; + extern const char kAudioHFPOffloadName[]; extern const char kAudioHFPOffloadDescription[]; @@ -3010,6 +3001,9 @@ extern const char kAutocorrectToggleName[]; extern const char kAutocorrectToggleDescription[]; +extern const char kAutocorrectUseReplaceSurroundingTextName[]; +extern const char kAutocorrectUseReplaceSurroundingTextDescription[]; + extern const char kAvatarsCloudMigrationName[]; extern const char kAvatarsCloudMigrationDescription[]; @@ -3520,9 +3514,6 @@ extern const char kLacrosWaylandLoggingName[]; extern const char kLacrosWaylandLoggingDescription[]; -extern const char kLanguagePacksInOobeName[]; -extern const char kLanguagePacksInOobeDescription[]; - extern const char kLauncherItemSuggestName[]; extern const char kLauncherItemSuggestDescription[]; @@ -3601,6 +3592,9 @@ extern const char kPrinterSettingsRevampName[]; extern const char kPrinterSettingsRevampDescription[]; +extern const char kPrintPreviewDiscoveredPrintersName[]; +extern const char kPrintPreviewDiscoveredPrintersDescription[]; + extern const char kPrintingPpdChannelName[]; extern const char kPrintingPpdChannelDescription[]; @@ -3646,6 +3640,9 @@ extern const char kArcInputOverlayNameAlphaV2[]; extern const char kArcInputOverlayDescriptionAlphaV2[]; +extern const char kScalableIphName[]; +extern const char kScalableIphDescription[]; + extern const char kScanningAppJellyName[]; extern const char kScanningAppJellyDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index a10dd7b..54ddc083 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -160,7 +160,6 @@ &kAllowNewIncognitoTabIntents, &kAndroidAppIntegration, &kAndroidSearchEngineChoiceNotification, - &kAndroidWidgetFullscreenToast, &kAndroidImprovedBookmarks, &kAnimatedImageDragShadow, &kAppMenuMobileSiteOption, @@ -454,10 +453,6 @@ "AndroidImprovedBookmarks", base::FEATURE_DISABLED_BY_DEFAULT); -BASE_FEATURE(kAndroidWidgetFullscreenToast, - "AndroidWidgetFullscreenToast", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kAnimatedImageDragShadow, "AnimatedImageDragShadow", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index db2c07f..205ceda 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -20,7 +20,6 @@ BASE_DECLARE_FEATURE(kAddToHomescreenIPH); BASE_DECLARE_FEATURE(kAllowNewIncognitoTabIntents); BASE_DECLARE_FEATURE(kAndroidAppIntegration); -BASE_DECLARE_FEATURE(kAndroidWidgetFullscreenToast); BASE_DECLARE_FEATURE(kAndroidSearchEngineChoiceNotification); BASE_DECLARE_FEATURE(kAndroidImprovedBookmarks); BASE_DECLARE_FEATURE(kAnimatedImageDragShadow);
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 096642e..837c556 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -111,7 +111,6 @@ public static final String ANDROID_SEARCH_ENGINE_CHOICE_NOTIFICATION = "AndroidSearchEngineChoiceNotification"; public static final String ANDROID_IMPROVED_BOOKMARKS = "AndroidImprovedBookmarks"; - public static final String ANDROID_WIDGET_FULLSCREEN_TOAST = "AndroidWidgetFullscreenToast"; public static final String ANIMATED_IMAGE_DRAG_SHADOW = "AnimatedImageDragShadow"; public static final String APP_LANGUAGE_PROMPT = "AppLanguagePrompt"; public static final String APP_LANGUAGE_PROMPT_ULP = "AppLanguagePromptULP"; @@ -450,7 +449,8 @@ public static final String TRANSLATE_MESSAGE_UI = "TranslateMessageUI"; public static final String TRANSLATE_TFLITE = "TFLiteLanguageDetectionEnabled"; public static final String TRUSTED_WEB_ACTIVITY_POST_MESSAGE = "TrustedWebActivityPostMessage"; - public static final String UNIFIED_PASSWORD_MANAGER_ANDROID = "UnifiedPasswordManagerAndroid"; + public static final String UNIFIED_PASSWORD_MANAGER_ANDROID = + "UnifiedPasswordManagerAndroid_LAUNCHED"; public static final String UNIFIED_PASSWORD_MANAGER_ANDROID_BRANDING = "UnifiedPasswordManagerAndroidBranding"; public static final String USE_CHIME_ANDROID_SDK = "UseChimeAndroidSdk";
diff --git a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc index 90c53bb4..5d7ee811 100644 --- a/chrome/browser/media/router/providers/cast/cast_activity_manager.cc +++ b/chrome/browser/media/router/providers/cast/cast_activity_manager.cc
@@ -222,7 +222,7 @@ base::TimeDelta launch_timeout = cast_source.launch_timeout(); std::vector<std::string> type_str; for (ReceiverAppType type : cast_source.supported_app_types()) { - type_str.push_back(cast_util::EnumToString(type).value().data()); + type_str.emplace_back(cast_util::EnumToString(type).value()); } logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent, "Sent a Launch Session request.", sink.id(),
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc index c1e577b..08e217d 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider.cc
@@ -114,18 +114,28 @@ } const MediaRoute::Id& route_id = activity->route.media_route_id(); - if (activity_manager_->GetActivity(route_id) || - activity_manager_->GetActivityBySinkId(sink_id)) { + if (activity_manager_->GetActivity(route_id) != nullptr) { logger_->LogError(mojom::LogCategory::kRoute, kLoggerComponent, "Failed to create route. Route already exists.", sink_id, media_source, presentation_id); std::move(callback).Run( - absl::nullopt, nullptr, "Activity already exists", + absl::nullopt, nullptr, "Route already exists", mojom::RouteRequestResultCode::ROUTE_ALREADY_EXISTS); DialMediaRouteProviderMetrics::RecordCreateRouteResult( DialCreateRouteResult::kRouteAlreadyExists); return; } + // Check if there's already a route to sink. + if (activity_manager_->GetActivityBySinkId(sink_id) != nullptr) { + // Terminate the existing session before creating new one. + TerminateRoute( + activity_manager_->GetActivityBySinkId(sink_id)->route.media_route_id(), + base::DoNothing()); + logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent, + "Existing route terminated successfully.", sink_id, + MediaRoute::GetMediaSourceIdFromMediaRouteId(route_id), + MediaRoute::GetPresentationIdFromMediaRouteId(route_id)); + } activity_manager_->AddActivity(*activity); logger_->LogInfo(mojom::LogCategory::kRoute, kLoggerComponent,
diff --git a/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc b/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc index 46cba7ad..0d58814 100644 --- a/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc +++ b/chrome/browser/media/router/providers/dial/dial_media_route_provider_unittest.cc
@@ -666,6 +666,61 @@ TestTerminateRouteViaStopSessionMessage(); } +TEST_F(DialMediaRouteProviderTest, CreateRouteTerminatesExistingRoute) { + // Create route with `presentation_id_1`. + const std::string presentation_id_1 = "presentationId1"; + const std::string presentation_id_2 = "presentationId2"; + CreateRoute(presentation_id_1); + ASSERT_TRUE(route_); + EXPECT_EQ(presentation_id_1, route_->presentation_id()); + + // Store route messages in `received_messages`. + const MediaRoute::Id& route_id = route_->media_route_id(); + std::vector<RouteMessagePtr> received_messages; + EXPECT_CALL(mock_router_, OnRouteMessagesReceived(route_id, _)) + .WillRepeatedly([&](const auto& route_id, auto messages) { + for (auto& message : messages) { + received_messages.emplace_back(std::move(message)); + } + }); + provider_->StartListeningForRouteMessages(route_->media_route_id()); + base::RunLoop().RunUntilIdle(); + + // Verify received route message. + ASSERT_EQ(2u, received_messages.size()); + ExpectDialInternalMessageType(received_messages[0], + DialInternalMessageType::kReceiverAction); + ExpectDialInternalMessageType(received_messages[1], + DialInternalMessageType::kNewSession); + + // Expect route terminated. + EXPECT_CALL( + mock_router_, + OnPresentationConnectionStateChanged( + route_id, blink::mojom::PresentationConnectionState::TERMINATED)); + EXPECT_CALL(mock_router_, OnRoutesUpdated(_, IsEmpty())); + + // Create a new route to the same sink with `presentation_id_2`. + const MediaSink::Id& sink_id = sink_.sink().id(); + MediaSource::Id source_id = "cast-dial:YouTube?clientId=11111"; + provider_->CreateRoute( + source_id, sink_id, presentation_id_2, origin_, kFrameTreeNodeId, + base::TimeDelta(), + /* off_the_record */ false, + base::BindOnce(&DialMediaRouteProviderTest::ExpectRouteResult, + base::Unretained(this), + mojom::RouteRequestResultCode::OK)); + base::RunLoop().RunUntilIdle(); + + // Verify that the new route is created with a different presentation_id. + EXPECT_EQ(presentation_id_2, route_->presentation_id()); + + // Verify that terminate route message is received. + ASSERT_EQ(3u, received_messages.size()); + ExpectDialInternalMessageType(received_messages[2], + DialInternalMessageType::kReceiverAction); +} + TEST_F(DialMediaRouteProviderTest, CreateRouteFailsCleansUpProperly) { // For some reason the SDK client does not complete the launch sequence. // |TerminateRoute()| should stop clean up the MediaRoute that was created.
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc index f7904fe..ddaed8e 100644 --- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc +++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -111,7 +111,7 @@ #include "components/user_manager/user_manager.h" #endif // BUILDFLAG(IS_CHROMEOS_ASH) -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "components/power_metrics/system_power_monitor.h" #endif @@ -746,10 +746,10 @@ pressure_metrics_reporter_ = std::make_unique<PressureMetricsReporter>(); #endif // BUILDFLAG(IS_LINUX) -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) base::trace_event::TraceLog::GetInstance()->AddEnabledStateObserver( power_metrics::SystemPowerMonitor::GetInstance()); -#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) +#endif // BUILDFLAG(IS_WIN) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) HandleEnableBenchmarkingCountdownAsync(); }
diff --git a/chrome/browser/metrics/per_user_state_manager_chromeos.cc b/chrome/browser/metrics/per_user_state_manager_chromeos.cc index 9dec49c..b6d97df7 100644 --- a/chrome/browser/metrics/per_user_state_manager_chromeos.cc +++ b/chrome/browser/metrics/per_user_state_manager_chromeos.cc
@@ -525,9 +525,7 @@ SetUserLogStore(std::make_unique<UnsentLogStore>( std::make_unique<UnsentLogStoreMetricsImpl>(), GetCurrentUserPrefs(), prefs::kMetricsUserMetricLogs, prefs::kMetricsUserMetricLogsMetadata, - storage_limits_.min_ongoing_log_queue_count, - storage_limits_.min_ongoing_log_queue_size, - storage_limits_.max_ongoing_log_size, signing_key_, + storage_limits_.ongoing_log_queue_limits, signing_key_, // |logs_event_manager| will be set by the metrics service directly in // MetricsLogStore::SetAlternateOngoingLogStore(). /*logs_event_manager=*/nullptr));
diff --git a/chrome/browser/metrics/per_user_state_manager_chromeos_unittest.cc b/chrome/browser/metrics/per_user_state_manager_chromeos_unittest.cc index 1cbcdc92..1c414cec 100644 --- a/chrome/browser/metrics/per_user_state_manager_chromeos_unittest.cc +++ b/chrome/browser/metrics/per_user_state_manager_chromeos_unittest.cc
@@ -193,9 +193,21 @@ protected: void SetUp() override { - storage_limits_.min_ongoing_log_queue_count = 5; - storage_limits_.min_ongoing_log_queue_size = 10000; - storage_limits_.max_ongoing_log_size = 0; + // Limits to ensure at least some logs will be persisted for the tests. + storage_limits_ = { + // Log store that can hold up to 5 logs. Set so that logs are not + // dropped in the tests. + .initial_log_queue_limits = + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 5, + }, + // Log store that can hold up to 5 logs. Set so that logs are not + // dropped in the tests. + .ongoing_log_queue_limits = + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 5, + }, + }; test_user_manager_ = std::make_unique<ash::FakeChromeUserManager>();
diff --git a/chrome/browser/paint_preview/android/BUILD.gn b/chrome/browser/paint_preview/android/BUILD.gn index d10ad4cb..760b630c 100644 --- a/chrome/browser/paint_preview/android/BUILD.gn +++ b/chrome/browser/paint_preview/android/BUILD.gn
@@ -91,6 +91,7 @@ "//third_party/hamcrest:hamcrest_library_java", "//third_party/junit", "//third_party/mockito:mockito_java", + "//ui/accessibility:ax_base_java", "//ui/android:ui_java_test_support", "//ui/android:ui_no_recycler_view_java", "//url:gurl_java",
diff --git a/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java b/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java index fc92020..f201347 100644 --- a/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java +++ b/chrome/browser/paint_preview/android/javatests/src/org/chromium/chrome/browser/paint_preview/TabbedPaintPreviewAccessibilityTest.java
@@ -27,6 +27,7 @@ import org.chromium.components.paintpreview.player.PlayerManager; import org.chromium.content_public.browser.WebContentsAccessibility; import org.chromium.content_public.browser.test.util.TestThreadUtils; +import org.chromium.ui.accessibility.AccessibilityState; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeoutException; @@ -106,7 +107,7 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { WebContentsAccessibility wcax = tabbedPaintPreview.getPlayerManagerForTesting() .getWebContentsAccessibilityForTesting(); - wcax.setAccessibilityEnabledForTesting(); + AccessibilityState.setIsAnyAccessibilityServiceEnabledForTesting(true); long time = SystemClock.uptimeMillis(); MotionEvent e = MotionEvent.obtain(time, time, MotionEvent.ACTION_HOVER_ENTER, 20, 20, 0);
diff --git a/chrome/browser/partnercustomizations/BUILD.gn b/chrome/browser/partnercustomizations/BUILD.gn index 7152cf7..7526f233 100644 --- a/chrome/browser/partnercustomizations/BUILD.gn +++ b/chrome/browser/partnercustomizations/BUILD.gn
@@ -12,6 +12,7 @@ ] deps = [ + ":uma_java", "//base:base_java", "//components/embedder_support/android:util_java", "//components/version_info/android:version_constants_java", @@ -30,10 +31,19 @@ sources = [ "java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java" ] } +android_library("uma_java") { + sources = [ "java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUma.java" ] + deps = [ + "//base:base_java", + "//third_party/androidx:androidx_annotation_annotation_java", + ] +} + android_library("java") { sources = [ "java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java" ] deps = [ ":delegate_java", + ":uma_java", "//base:base_java", "//base:jni_java", "//chrome/browser/flags:java", @@ -85,3 +95,18 @@ "//url:gurl_java", ] } + +robolectric_library("junit") { + sources = [ "java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUmaUnitTest.java" ] + + deps = [ + ":java", + ":uma_java", + "//base:base_java", + "//base:base_java_test_support", + "//base:base_junit_test_support", + "//base/test:test_support_java", + "//chrome/browser/flags:java", + "//third_party/junit:junit", + ] +}
diff --git a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/CustomizationProviderDelegateUpstreamImpl.java b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/CustomizationProviderDelegateUpstreamImpl.java index c4f75175..650db5a7 100644 --- a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/CustomizationProviderDelegateUpstreamImpl.java +++ b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/CustomizationProviderDelegateUpstreamImpl.java
@@ -8,12 +8,14 @@ import android.content.pm.ProviderInfo; import android.database.Cursor; import android.net.Uri; +import android.os.SystemClock; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.chromium.base.ContextUtils; import org.chromium.base.Log; +import org.chromium.chrome.browser.partnercustomizations.PartnerCustomizationsUma.DelegateUnusedReason; import org.chromium.components.embedder_support.util.UrlConstants; import org.chromium.components.version_info.VersionInfo; @@ -26,9 +28,25 @@ private static final String PARTNER_HOMEPAGE_PATH = "homepage"; private static String sProviderAuthority = PROVIDER_AUTHORITY; - private static Boolean sIgnoreSystemPackageCheck; + private static Boolean sIgnoreSystemPackageCheckForTesting; private static Boolean sValid; + /** Provides a way to do some post-process timing for the validation function. */ + interface DelegateValidationCompletion { + /** + * When validation has completed, notify the closure of how long that took, regardless of + * outcome. + */ + void validated(long startTime); + } + + /** + * A completion to call after determining isValid that includes timing information. Typically + * {@code null} on Chromium but can be set from Downstream. + */ + @Nullable + private DelegateValidationCompletion mValidationCompletion; + @Override public @Nullable String getHomepage() { if (!isValid()) { @@ -85,6 +103,8 @@ ContextUtils.getApplicationContext().getPackageManager().resolveContentProvider( sProviderAuthority, 0); if (providerInfo == null) { + PartnerCustomizationsUma.logDelegateUnusedReason( + DelegateUnusedReason.PRELOAD_APK_CANNOT_RESOLVE_PROVIDER); return false; } if ((providerInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) { @@ -95,7 +115,7 @@ // is rejected unless Chrome Android is a local build. // When sIgnoreBrowserProviderSystemPackageCheck is true, accept non-system package. // When sIgnoreBrowserProviderSystemPackageCheck is false, reject non-system package. - if (sIgnoreSystemPackageCheck != null && sIgnoreSystemPackageCheck) { + if (sIgnoreSystemPackageCheckForTesting != null && sIgnoreSystemPackageCheckForTesting) { return true; } @@ -104,7 +124,7 @@ + ", is not a system package. " + "This could be a malicious attempt from a third party " + "app, so skip reading the browser content provider."); - if (sIgnoreSystemPackageCheck != null && !sIgnoreSystemPackageCheck) { + if (sIgnoreSystemPackageCheckForTesting != null && !sIgnoreSystemPackageCheckForTesting) { return false; } if (VersionInfo.isLocalBuild()) { @@ -114,16 +134,35 @@ + "to make debugging customization easier."); return true; } + // ProviderInfo was present, but flags don't indicate it was a System APK (above), and none + // of our overrides apply. + PartnerCustomizationsUma.logDelegateUnusedReason( + DelegateUnusedReason.PRELOAD_APK_NOT_SYSTEM_PROVIDER); return false; } - private boolean isValid() { + /** + * May be called by Downstream to determine if the default Upstream delegate is actually being + * used. + */ + boolean isValid() { if (sValid == null) { + long validationStartTime = SystemClock.elapsedRealtime(); sValid = isValidInternal(); + if (mValidationCompletion != null) { + mValidationCompletion.validated(validationStartTime); + } } return sValid; } + /** Sets a function to call when validation has been performed. */ + void setValidationCompletion(DelegateValidationCompletion validationCompletion) { + assert mValidationCompletion + == null : "Coding error: setValidationCompletion may only be called once!"; + mValidationCompletion = validationCompletion; + } + static Uri buildQueryUri(String path) { return new Uri.Builder() .scheme(UrlConstants.CONTENT_SCHEME) @@ -146,6 +185,6 @@ */ @VisibleForTesting static void ignoreBrowserProviderSystemPackageCheckForTesting(boolean ignore) { - sIgnoreSystemPackageCheck = ignore; + sIgnoreSystemPackageCheckForTesting = ignore; } } \ No newline at end of file
diff --git a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUma.java b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUma.java new file mode 100644 index 0000000..cc9b64f5 --- /dev/null +++ b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUma.java
@@ -0,0 +1,176 @@ +// 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. + +package org.chromium.chrome.browser.partnercustomizations; + +import android.os.SystemClock; + +import androidx.annotation.IntDef; +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.metrics.RecordHistogram; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * Centralizes UMA data collection for partner customizations and loading. + */ +public class PartnerCustomizationsUma { + /** + * Tracks which delegate is first used for any purpose. + * Trying to switch to another is logged. + */ + private static @CustomizationProviderDelegateType int sWhichDelegate = + CustomizationProviderDelegateType.NONE_VALID; + + /** + * Constants used to identify the delegate being used. + * These correspond to PartnerCustomizationProviderDelegate in enums.xml. + * These values are recorded as histogram values. Entries should not be renumbered and numeric + * values should never be reused. + */ + @IntDef({CustomizationProviderDelegateType.NONE_VALID, + CustomizationProviderDelegateType.PHENOTYPE, + CustomizationProviderDelegateType.G_SERVICE, + CustomizationProviderDelegateType.PRELOAD_APK, + CustomizationProviderDelegateType.NUM_ENTRIES}) + @Retention(RetentionPolicy.SOURCE) + @interface CustomizationProviderDelegateType { + int NONE_VALID = 0; + int PHENOTYPE = 1; + int G_SERVICE = 2; + int PRELOAD_APK = 3; + + int NUM_ENTRIES = 4; + } + + /** + * Records which delegate will be used to provide the home page URL that is needed for a custom + * provider's home page. Should be called at startup. Called from Downstream, or unused. + * @param whichDelegate The {@link CustomizationProviderDelegateType} being used. + */ + public static void logPartnerCustomizationDelegate( + @CustomizationProviderDelegateType int whichDelegate) { + RecordHistogram.recordEnumeratedHistogram("Android.PartnerHomepageCustomization.Delegate2", + whichDelegate, CustomizationProviderDelegateType.NUM_ENTRIES); + + // Log whether we're getting conflicts with our static member tracking which delegate is + // actually used - e.g. when running multiple activities. + boolean tryingToSwitchDelegate = whichDelegate != sWhichDelegate + && sWhichDelegate != CustomizationProviderDelegateType.NONE_VALID; + RecordHistogram.recordBooleanHistogram( + "Android.PartnerCustomization.DelegateConflict", tryingToSwitchDelegate); + if (tryingToSwitchDelegate) sWhichDelegate = whichDelegate; + } + + /** + * What kind of customization is actually used. + * These correspond to PartnerCustomizationUsage in enums.xml. + * These values are recorded as histogram values. Entries should not be renumbered and numeric + * values should never be reused. + */ + @IntDef({CustomizationUsage.HOMEPAGE, CustomizationUsage.BOOKMARKS, + CustomizationUsage.INCOGNITO, CustomizationUsage.NUM_ENTRIES}) + @Retention(RetentionPolicy.SOURCE) + @interface CustomizationUsage { + int HOMEPAGE = 0; + int BOOKMARKS = 1; + int INCOGNITO = 2; + + int NUM_ENTRIES = 3; + } + + /** + * Records which customization usage is being invoked, at the time it is requested. Called from + * Downstream, or unused. + * @param usage The {@link CustomizationUsage} used, e.g. home page vs incognito. + */ + public static void logPartnerCustomizationUsage(@CustomizationUsage int usage) { + RecordHistogram.recordEnumeratedHistogram( + "Android.PartnerCustomization.Usage", usage, CustomizationUsage.NUM_ENTRIES); + } + + /** + * Describes why a particular Customization Delegate could not be used. + * These correspond to PartnerDelegateUnusedReason in enums.xml. + * These values are recorded as histogram values. Entries should not be renumbered and numeric + * values should never be reused. + */ + @IntDef({ + DelegateUnusedReason.PHENOTYPE_BEFORE_PIE, + DelegateUnusedReason.PHENOTYPE_FLAG_CANT_COMMIT, + DelegateUnusedReason.PHENOTYPE_FLAG_CONFIG_EMPTY, + DelegateUnusedReason.GSERVICES_GET_TIMESTAMP_EXCEPTION, + DelegateUnusedReason.GSERVICES_TIMESTAMP_MISSING, + DelegateUnusedReason.PRELOAD_APK_CANNOT_RESOLVE_PROVIDER, + DelegateUnusedReason.PRELOAD_APK_NOT_SYSTEM_PROVIDER, + DelegateUnusedReason.NUM_ENTRIES, + }) + @Retention(RetentionPolicy.SOURCE) + @interface DelegateUnusedReason { + int PHENOTYPE_BEFORE_PIE = 0; + int PHENOTYPE_FLAG_CANT_COMMIT = 1; + int PHENOTYPE_FLAG_CONFIG_EMPTY = 2; + int GSERVICES_GET_TIMESTAMP_EXCEPTION = 3; + int GSERVICES_TIMESTAMP_MISSING = 4; + int PRELOAD_APK_CANNOT_RESOLVE_PROVIDER = 5; + int PRELOAD_APK_NOT_SYSTEM_PROVIDER = 6; + + int NUM_ENTRIES = 7; + } + + /** + * Logs a reason that a Partner Customization Delegate was not used. + * May be recorded up to 3 times when all 3 are delegates are skipped. + * Called from Downstream, or unused. + * @param reasonForDelegateNotUsed The delegate and reason it's not usable. + */ + static void logDelegateUnusedReason(@DelegateUnusedReason int reasonForDelegateNotUsed) { + RecordHistogram.recordEnumeratedHistogram( + "Android.PartnerCustomization.DelegateUnusedReason", reasonForDelegateNotUsed, + DelegateUnusedReason.NUM_ENTRIES); + } + + /** + * Logs that we just tried to create a customization delegate, if that failed, and the duration. + * Called from Downstream, or unused. + * @param delegate The kind of delegate we tried to create. + * @param startTime The elapsed real time when we started to create it. + * @param didTryCreateSucceed Whether the create operation did succeed. + */ + static void logDelegateTryCreateDuration(@CustomizationProviderDelegateType int delegate, + long startTime, boolean didTryCreateSucceed) { + final long createdTime = SystemClock.elapsedRealtime(); + logDelegateTryCreateDuration(delegate, startTime, createdTime, didTryCreateSucceed); + } + + @VisibleForTesting + static void logDelegateTryCreateDuration(@CustomizationProviderDelegateType int delegate, + long startTime, long endTime, boolean didTryCreateSucceed) { + long duration = endTime - startTime; + String durationHistogramName; + if (didTryCreateSucceed) { + durationHistogramName = "Android.PartnerCustomization.TrySucceededDuration."; + } else { + durationHistogramName = "Android.PartnerCustomization.TryFailedDuration."; + } + RecordHistogram.recordTimesHistogram( + durationHistogramName + delegateName(delegate), duration); + } + + /** @return the variant name for the given delegate for use in variant histograms. */ + private static String delegateName(@CustomizationProviderDelegateType int delegate) { + switch (delegate) { + case CustomizationProviderDelegateType.G_SERVICE: + return "GService"; + case CustomizationProviderDelegateType.PHENOTYPE: + return "Phenotype"; + case CustomizationProviderDelegateType.PRELOAD_APK: + return "PreloadApk"; + default: + return "None"; + } + } +}
diff --git a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUmaUnitTest.java b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUmaUnitTest.java new file mode 100644 index 0000000..711f427 --- /dev/null +++ b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerCustomizationsUmaUnitTest.java
@@ -0,0 +1,93 @@ +// 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. + +package org.chromium.chrome.browser.partnercustomizations; + +import android.os.SystemClock; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.base.test.util.HistogramWatcher; +import org.chromium.chrome.browser.partnercustomizations.PartnerCustomizationsUma.CustomizationProviderDelegateType; +import org.chromium.chrome.browser.partnercustomizations.PartnerCustomizationsUma.DelegateUnusedReason; + +/** + * Unit tests for {@link PartnerCustomizationsUma}. + */ +@RunWith(BaseRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class PartnerCustomizationsUmaUnitTest { + @Test + public void testLogPartnerCustomizationDelegate() { + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord("Android.PartnerHomepageCustomization.Delegate2", + CustomizationProviderDelegateType.G_SERVICE) + .build(); + PartnerCustomizationsUma.logPartnerCustomizationDelegate( + CustomizationProviderDelegateType.G_SERVICE); + histogramWatcher.assertExpected(); + } + + @Test + public void testLogPartnerCustomizationUsage() { + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord("Android.PartnerCustomization.Usage", + CustomizationProviderDelegateType.G_SERVICE) + .build(); + PartnerCustomizationsUma.logPartnerCustomizationUsage( + CustomizationProviderDelegateType.G_SERVICE); + histogramWatcher.assertExpected(); + } + + @Test + public void testLogDelegateUnusedReason() { + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord("Android.PartnerCustomization.DelegateUnusedReason", + DelegateUnusedReason.GSERVICES_TIMESTAMP_MISSING) + .build(); + PartnerCustomizationsUma.logDelegateUnusedReason( + DelegateUnusedReason.GSERVICES_TIMESTAMP_MISSING); + histogramWatcher.assertExpected(); + } + + @Test + public void testLogDelegateTryCreateDuration() { + @CustomizationProviderDelegateType + int delegate = CustomizationProviderDelegateType.G_SERVICE; + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + "Android.PartnerCustomization.TrySucceededDuration.GService", 7) + .build(); + + long startTime = SystemClock.elapsedRealtime(); + long endTime = startTime + 7; + PartnerCustomizationsUma.logDelegateTryCreateDuration(delegate, startTime, endTime, true); + + histogramWatcher.assertExpected(); + } + + @Test + public void testLogDelegateTryCreateDuration_failed() { + @CustomizationProviderDelegateType + int delegate = CustomizationProviderDelegateType.PRELOAD_APK; + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord( + "Android.PartnerCustomization.TryFailedDuration.PreloadApk", 9) + .build(); + + long startTime = SystemClock.elapsedRealtime(); + long endTime = startTime + 9; + PartnerCustomizationsUma.logDelegateTryCreateDuration(delegate, startTime, endTime, false); + + histogramWatcher.assertExpected(); + } +}
diff --git a/chrome/browser/password_manager/android/BUILD.gn b/chrome/browser/password_manager/android/BUILD.gn index 1686239..4becb50 100644 --- a/chrome/browser/password_manager/android/BUILD.gn +++ b/chrome/browser/password_manager/android/BUILD.gn
@@ -423,6 +423,7 @@ "all_passwords_bottom_sheet_controller_unittest.cc", "all_passwords_bottom_sheet_helper_unittest.cc", "auto_signin_first_run_dialog_android_unittest.cc", + "cred_man_controller_unittest.cc", "credential_leak_controller_android_unittest.cc", "fake_password_manager_lifecycle_helper.cc", "fake_password_manager_lifecycle_helper.h",
diff --git a/chrome/browser/password_manager/android/cred_man_controller.cc b/chrome/browser/password_manager/android/cred_man_controller.cc new file mode 100644 index 0000000..0e76509e --- /dev/null +++ b/chrome/browser/password_manager/android/cred_man_controller.cc
@@ -0,0 +1,41 @@ +// 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 "chrome/browser/password_manager/android/cred_man_controller.h" + +#include "components/password_manager/content/browser/content_password_manager_driver.h" +#include "components/password_manager/core/browser/password_manager_client.h" +#include "components/webauthn/android/webauthn_cred_man_delegate.h" + +namespace password_manager { + +CredManController::CredManController(PasswordManagerClient* client) + : client_(client) {} + +CredManController::~CredManController() = default; + +bool CredManController::Show(PasswordManagerDriver* driver, + bool is_webauthn_form) { + if (!is_webauthn_form || !WebAuthnCredManDelegate::IsCredManEnabled()) { + return false; + } + WebAuthnCredManDelegate* cred_man_delegate = + client_->GetWebAuthnCredManDelegateForDriver(driver); + // webauthn forms without passkeys should show TouchToFill bottom sheet. + if (cred_man_delegate->HasResults()) { + // TODO(crbug/1434278): Avoid using KeyboardReplacingSurfaceClosed. + cred_man_delegate->SetRequestCompletionCallback(base::BindRepeating( + [](base::WeakPtr<password_manager::PasswordManagerDriver> driver, + bool success) { + driver->KeyboardReplacingSurfaceClosed( + PasswordManagerDriver::ToShowVirtualKeyboard(!success)); + }, + driver->AsWeakPtr())); + cred_man_delegate->TriggerFullRequest(); + return true; + } + return false; +} + +} // namespace password_manager
diff --git a/chrome/browser/password_manager/android/cred_man_controller.h b/chrome/browser/password_manager/android/cred_man_controller.h new file mode 100644 index 0000000..dcb42a5 --- /dev/null +++ b/chrome/browser/password_manager/android/cred_man_controller.h
@@ -0,0 +1,39 @@ +// 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 CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_CRED_MAN_CONTROLLER_H_ +#define CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_CRED_MAN_CONTROLLER_H_ + +#include "base/memory/raw_ptr.h" + +namespace password_manager { + +class PasswordManagerClient; +class PasswordManagerDriver; + +// This class is responsible for the logic to show Credential Manager UI. The +// interaction with Credential Manager UI is delegated to WebAuthnCredMan class. +// Its lifecycle is tied to ChromePasswordManagerClient. CredManController is +// used in Android U+ only. +class CredManController { + public: + explicit CredManController(PasswordManagerClient* client); + + CredManController(const CredManController&) = delete; + CredManController& operator=(const CredManController&) = delete; + + ~CredManController(); + + // Determines if the Android Credential Manager UI should be shown and shows + // if required. Returns true if the Android Credential Manager UI is shown, + // false otherwise. + bool Show(PasswordManagerDriver* driver, bool is_webauthn_form); + + private: + raw_ptr<PasswordManagerClient> client_; +}; + +} // namespace password_manager + +#endif // CHROME_BROWSER_PASSWORD_MANAGER_ANDROID_CRED_MAN_CONTROLLER_H_
diff --git a/chrome/browser/password_manager/android/cred_man_controller_unittest.cc b/chrome/browser/password_manager/android/cred_man_controller_unittest.cc new file mode 100644 index 0000000..c2ee0f4 --- /dev/null +++ b/chrome/browser/password_manager/android/cred_man_controller_unittest.cc
@@ -0,0 +1,91 @@ +// 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 "chrome/browser/password_manager/android/cred_man_controller.h" +#include <memory> + +#include "base/android/build_info.h" +#include "base/test/mock_callback.h" +#include "base/test/scoped_feature_list.h" +#include "components/password_manager/core/browser/password_manager_client.h" +#include "components/password_manager/core/browser/stub_password_manager_client.h" +#include "components/password_manager/core/browser/stub_password_manager_driver.h" +#include "components/webauthn/android/webauthn_cred_man_delegate.h" +#include "device/fido/features.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +using testing::Return; + +namespace password_manager { + +class TestPasswordManagerClient : public StubPasswordManagerClient { + public: + MOCK_METHOD(WebAuthnCredManDelegate*, + GetWebAuthnCredManDelegateForDriver, + (PasswordManagerDriver*), + (override)); +}; + +class CredManControllerTest : public testing::Test { + public: + void SetUp() override { + client_ = std::make_unique<TestPasswordManagerClient>(); + controller_ = std::make_unique<CredManController>(client_.get()); + driver_ = std::make_unique<StubPasswordManagerDriver>(); + web_authn_cred_man_delegate_ = + std::make_unique<WebAuthnCredManDelegate>(nullptr); + + ON_CALL(*client(), GetWebAuthnCredManDelegateForDriver) + .WillByDefault(Return(web_authn_cred_man_delegate())); + } + + CredManController* controller() { return controller_.get(); } + PasswordManagerDriver* driver() { return driver_.get(); } + WebAuthnCredManDelegate* web_authn_cred_man_delegate() { + return web_authn_cred_man_delegate_.get(); + } + TestPasswordManagerClient* client() { return client_.get(); } + + private: + std::unique_ptr<CredManController> controller_; + std::unique_ptr<TestPasswordManagerClient> client_; + std::unique_ptr<StubPasswordManagerDriver> driver_; + std::unique_ptr<WebAuthnCredManDelegate> web_authn_cred_man_delegate_; +}; + +TEST_F(CredManControllerTest, DoesNotShowIfNonWebAuthnForm) { + ASSERT_FALSE(controller()->Show(driver(), /*is_webauthn_form=*/false)); +} + +TEST_F(CredManControllerTest, DoesNotShowIfFeatureDisabled) { + ASSERT_FALSE(controller()->Show(driver(), /*is_webauthn_form=*/true)); +} + +TEST_F(CredManControllerTest, DoesNotShowIfNoResults) { + base::test::ScopedFeatureList enable_feature(device::kWebAuthnAndroidCredMan); + + base::MockRepeatingClosure mock_full_assertion_request; + web_authn_cred_man_delegate()->OnCredManConditionalRequestPending( + /*render_frame_host=*/nullptr, /*has_results=*/false, + mock_full_assertion_request.Get()); + + ASSERT_FALSE(controller()->Show(driver(), /*is_webauthn_form=*/true)); +} + +TEST_F(CredManControllerTest, ShowIfResultsExist) { + if (!base::android::BuildInfo::GetInstance()->is_at_least_u()) { + return; + } + base::test::ScopedFeatureList enable_feature(device::kWebAuthnAndroidCredMan); + + base::MockRepeatingClosure mock_full_assertion_request; + web_authn_cred_man_delegate()->OnCredManConditionalRequestPending( + /*render_frame_host=*/nullptr, /*has_results=*/true, + mock_full_assertion_request.Get()); + + ASSERT_TRUE(controller()->Show(driver(), /*is_webauthn_form=*/true)); +} + +} // namespace password_manager
diff --git a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc index 87bc3ea..e90d84d 100644 --- a/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc +++ b/chrome/browser/password_manager/android/password_accessory_controller_impl_unittest.cc
@@ -1021,7 +1021,7 @@ CreateSheetController(); cred_man_delegate()->OnCredManConditionalRequestPending( /*render_frame_host=*/nullptr, /*has_results=*/true, - base::RepeatingClosure()); + base::RepeatingCallback<void(bool)>()); EXPECT_CALL(mock_manual_filling_controller_, OnAccessoryActionAvailabilityChanged( @@ -1040,7 +1040,7 @@ CreateSheetController(); cred_man_delegate()->OnCredManConditionalRequestPending( /*render_frame_host=*/nullptr, /*has_results=*/false, - base::RepeatingClosure()); + base::RepeatingCallback<void(bool)>()); EXPECT_CALL(mock_manual_filling_controller_, OnAccessoryActionAvailabilityChanged( @@ -1059,7 +1059,7 @@ CreateSheetController(); cred_man_delegate()->OnCredManConditionalRequestPending( /*render_frame_host=*/nullptr, /*has_results=*/true, - base::RepeatingClosure()); + base::RepeatingCallback<void(bool)>()); EXPECT_CALL(mock_manual_filling_controller_, OnAccessoryActionAvailabilityChanged( @@ -1089,7 +1089,7 @@ } base::test::ScopedFeatureList enable_feature(device::kWebAuthnAndroidCredMan); CreateSheetController(); - base::MockRepeatingClosure cred_man_callback; + base::MockCallback<base::RepeatingCallback<void(bool)>> cred_man_callback; cred_man_delegate()->OnCredManConditionalRequestPending( /*render_frame_host=*/nullptr, /*has_results=*/true, cred_man_callback.Get());
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.cc b/chrome/browser/password_manager/chrome_password_manager_client.cc index c2d1f4d..ef3a17f 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.cc +++ b/chrome/browser/password_manager/chrome_password_manager_client.cc
@@ -28,6 +28,7 @@ #include "chrome/browser/history/history_tab_helper.h" #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" #include "chrome/browser/password_manager/account_password_store_factory.h" +#include "chrome/browser/password_manager/android/cred_man_controller.h" #include "chrome/browser/password_manager/chrome_webauthn_credentials_delegate.h" #include "chrome/browser/password_manager/chrome_webauthn_credentials_delegate_factory.h" #include "chrome/browser/password_manager/field_info_manager_factory.h" @@ -407,9 +408,13 @@ } } -void ChromePasswordManagerClient::ShowTouchToFill( - PasswordManagerDriver* driver, - autofill::mojom::SubmissionReadinessState submission_readiness) { +void ChromePasswordManagerClient::ShowKeyboardReplacingSurface( + password_manager::PasswordManagerDriver* driver, + autofill::mojom::SubmissionReadinessState submission_readiness, + bool is_webauthn_form) { + if (GetOrCreateCredManController()->Show(driver, is_webauthn_form)) { + return; + } auto* webauthn_delegate = GetWebAuthnCredentialsDelegateForDriver(driver); std::vector<password_manager::PasskeyCredential> passkeys; if (webauthn_delegate && webauthn_delegate->GetPasskeys().has_value()) { @@ -1244,6 +1249,15 @@ } return touch_to_fill_controller_.get(); } + +password_manager::CredManController* +ChromePasswordManagerClient::GetOrCreateCredManController() { + if (!cred_man_controller_) { + cred_man_controller_ = + std::make_unique<password_manager::CredManController>(this); + } + return cred_man_controller_.get(); +} #endif // BUILDFLAG(IS_ANDROID) ChromePasswordManagerClient::ChromePasswordManagerClient( @@ -1376,6 +1390,10 @@ if (touch_to_fill_controller_) { touch_to_fill_controller_->Reset(); } + + if (cred_man_controller_) { + cred_man_controller_.reset(); + } #endif // BUILDFLAG(IS_ANDROID) }
diff --git a/chrome/browser/password_manager/chrome_password_manager_client.h b/chrome/browser/password_manager/chrome_password_manager_client.h index f326285..5c90777 100644 --- a/chrome/browser/password_manager/chrome_password_manager_client.h +++ b/chrome/browser/password_manager/chrome_password_manager_client.h
@@ -88,6 +88,7 @@ namespace password_manager { class WebAuthnCredentialsDelegate; +class CredManController; } // ChromePasswordManagerClient implements the PasswordManagerClient interface. @@ -139,9 +140,10 @@ password_manager::ErrorMessageFlowType flow_type, password_manager::PasswordStoreBackendErrorType error_type) override; - void ShowTouchToFill( + void ShowKeyboardReplacingSurface( password_manager::PasswordManagerDriver* driver, - autofill::mojom::SubmissionReadinessState submission_readiness) override; + autofill::mojom::SubmissionReadinessState submission_readiness, + bool is_webauthn_form) override; #endif // Returns a pointer to the DeviceAuthenticator which is created on demand. @@ -366,6 +368,8 @@ #if BUILDFLAG(IS_ANDROID) void ResetErrorMessageDelegate(); + + password_manager::CredManController* GetOrCreateCredManController(); #endif const raw_ptr<Profile> profile_; @@ -382,6 +386,9 @@ // call to GetOrCreateTouchToFillController(). std::unique_ptr<TouchToFillController> touch_to_fill_controller_; + // Controller for Android Credential Manager API. Created on demand. + std::unique_ptr<password_manager::CredManController> cred_man_controller_; + std::unique_ptr<PasswordManagerErrorMessageDelegate> password_manager_error_message_delegate_;
diff --git a/chrome/browser/payments/manifest_verifier_browsertest.cc b/chrome/browser/payments/manifest_verifier_browsertest.cc index 5bf980f..94eea9d 100644 --- a/chrome/browser/payments/manifest_verifier_browsertest.cc +++ b/chrome/browser/payments/manifest_verifier_browsertest.cc
@@ -441,7 +441,7 @@ SinglePaymentMethodName404) { std::string expected_pattern = "Unable to download payment manifest " - "\"https://127.0.0.1:\\d+/404.test/webpay\"."; + "\"https://127.0.0.1:\\d+/404.test/webpay\". HTTP 404 Not Found."; { content::InstalledPaymentAppsFinder::PaymentApps apps; apps[0] = std::make_unique<content::StoredPaymentApp>(); @@ -480,7 +480,8 @@ MultiplePaymentMethodName404) { std::string expected_pattern = "Unable to download payment manifest " - "\"https://127.0.0.1:\\d+/404(aswell)?.test/webpay\"."; + "\"https://127.0.0.1:\\d+/404(aswell)?.test/webpay\". HTTP 404 Not " + "Found."; { content::InstalledPaymentAppsFinder::PaymentApps apps; apps[0] = std::make_unique<content::StoredPaymentApp>();
diff --git a/chrome/browser/policy/BUILD.gn b/chrome/browser/policy/BUILD.gn index a263815..a4250ce 100644 --- a/chrome/browser/policy/BUILD.gn +++ b/chrome/browser/policy/BUILD.gn
@@ -182,7 +182,6 @@ "policy_network_browsertest.cc", "site_isolation_policy_browsertest.cc", "test/certificate_transparency_policy_browsertest.cc", - "test/event_path_policy_browsertest.cc", "test/hsts_policy_browsertest.cc", "test/network_prediction_policy_browsertest.cc", "test/offset_parent_new_spec_behavior_policy_browsertest.cc",
diff --git a/chrome/browser/policy/configuration_policy_handler_list_factory.cc b/chrome/browser/policy/configuration_policy_handler_list_factory.cc index b50c4b4..b30d827 100644 --- a/chrome/browser/policy/configuration_policy_handler_list_factory.cc +++ b/chrome/browser/policy/configuration_policy_handler_list_factory.cc
@@ -318,6 +318,9 @@ { key::kDataUrlInSvgUseEnabled, prefs::kDataUrlInSvgUseEnabled, base::Value::Type::BOOLEAN }, + { key::kPolicyTestPageEnabled, + policy_prefs::kPolicyTestPageEnabled, + base::Value::Type::BOOLEAN}, // Policies for all platforms - End #if BUILDFLAG(IS_ANDROID) { key::kAuthAndroidNegotiateAccountType, @@ -1843,9 +1846,6 @@ { key::kAccessControlAllowMethodsInCORSPreflightSpecConformant, prefs::kAccessControlAllowMethodsInCORSPreflightSpecConformant, base::Value::Type::BOOLEAN}, - { key::kEventPathEnabled, - policy_prefs::kEventPathEnabled, - base::Value::Type::BOOLEAN}, { key::kOffsetParentNewSpecBehaviorEnabled, policy_prefs::kOffsetParentNewSpecBehaviorEnabled, base::Value::Type::BOOLEAN},
diff --git a/chrome/browser/policy/test/event_path_policy_browsertest.cc b/chrome/browser/policy/test/event_path_policy_browsertest.cc deleted file mode 100644 index c2ecd2f..0000000 --- a/chrome/browser/policy/test/event_path_policy_browsertest.cc +++ /dev/null
@@ -1,75 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <string> - -#include "chrome/browser/policy/policy_test_utils.h" -#include "chrome/common/channel_info.h" -#include "chrome/common/pref_names.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_pref_names.h" -#include "components/policy/policy_constants.h" -#include "components/version_info/channel.h" -#include "content/public/test/browser_test.h" -#include "url/gurl.h" - -namespace policy { - -enum class EventPathPolicyValue { - kUnset, - kEnabled, - kDisabled, -}; - -class EventPathPolicyTest - : public testing::WithParamInterface<EventPathPolicyValue>, - public PolicyTest { - protected: - void SetUpInProcessBrowserTestFixture() override { - PolicyTest::SetUpInProcessBrowserTestFixture(); - if (GetParam() == EventPathPolicyValue::kUnset) - return; - PolicyMap policies; - SetPolicy(&policies, policy::key::kEventPathEnabled, - base::Value(GetParam() == EventPathPolicyValue::kEnabled)); - provider_.UpdateChromePolicy(policies); - } - - void AssertEventPathEnabled(bool enabled) { - ASSERT_TRUE(embedded_test_server()->Start()); - const GURL url(embedded_test_server()->GetURL("/empty.html")); - ASSERT_TRUE(NavigateToUrl(url, this)); - - content::DOMMessageQueue message_queue( - chrome_test_utils::GetActiveWebContents(this)); - content::ExecuteScriptAsync( - chrome_test_utils::GetActiveWebContents(this), - "window.domAutomationController.send('path' in Event.prototype)"); - std::string message; - EXPECT_TRUE(message_queue.WaitForMessage(&message)); - EXPECT_EQ(enabled ? "true" : "false", message); - } -}; - -IN_PROC_BROWSER_TEST_P(EventPathPolicyTest, Test) { - bool expected_enabled; - if (GetParam() == EventPathPolicyValue::kUnset) { - // Otherwise, Event.path API is disabled by default. - expected_enabled = false; - } else { - // If the EventPathEnabled policy is set, the Event.path API status should - // follow the policy value. - expected_enabled = GetParam() == EventPathPolicyValue::kEnabled; - } - AssertEventPathEnabled(expected_enabled); -} - -INSTANTIATE_TEST_SUITE_P( - /* no prefix */, - EventPathPolicyTest, - ::testing::Values(EventPathPolicyValue::kUnset, - EventPathPolicyValue::kEnabled, - EventPathPolicyValue::kDisabled)); - -} // namespace policy
diff --git a/chrome/browser/policy/test/policy_browsertest.cc b/chrome/browser/policy/test/policy_browsertest.cc index 8aa701c0..1077919 100644 --- a/chrome/browser/policy/test/policy_browsertest.cc +++ b/chrome/browser/policy/test/policy_browsertest.cc
@@ -120,7 +120,7 @@ // TODO(crbug.com/1378338): Re-enable this flaky test on Linux // and lacros asan builder. #if BUILDFLAG(IS_LINUX) || \ - BUILDFLAG(IS_CHROMEOS_LACROS) && defined(ADDRESS_SANITIZER) + (BUILDFLAG(IS_CHROMEOS) && defined(ADDRESS_SANITIZER)) #define MAYBE_HomepageLocation DISABLED_HomepageLocation #else #define MAYBE_HomepageLocation HomepageLocation
diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index ea397813..6892c1b9 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc
@@ -84,6 +84,7 @@ #include "chrome/browser/ui/webui/bookmarks/bookmark_prefs.h" #include "chrome/browser/ui/webui/flags/flags_ui.h" #include "chrome/browser/ui/webui/ntp/new_tab_ui.h" +#include "chrome/browser/ui/webui/policy/policy_ui.h" #include "chrome/browser/ui/webui/print_preview/policy_settings.h" #include "chrome/browser/updates/announcement_notification/announcement_notification_service.h" #include "chrome/browser/webauthn/chrome_authenticator_request_delegate.h" @@ -1532,6 +1533,7 @@ PermissionBubbleMediaAccessHandler::RegisterProfilePrefs(registry); PlatformNotificationServiceImpl::RegisterProfilePrefs(registry); policy::URLBlocklistManager::RegisterProfilePrefs(registry); + PolicyUI::RegisterProfilePrefs(registry); PrefProxyConfigTrackerImpl::RegisterProfilePrefs(registry); prefetch::RegisterPredictionOptionsProfilePrefs(registry); PrefetchOriginDecider::RegisterPrefs(registry);
diff --git a/chrome/browser/private_network_access/private_network_device_chooser_controller.cc b/chrome/browser/private_network_access/private_network_device_chooser_controller.cc index d6919e2..ef24b2b 100644 --- a/chrome/browser/private_network_access/private_network_device_chooser_controller.cc +++ b/chrome/browser/private_network_access/private_network_device_chooser_controller.cc
@@ -35,7 +35,7 @@ CreateChooserTitle(render_frame_host, IDS_PRIVATE_NETWORK_DEVICE_CHOOSER_PROMPT_ORIGIN)), device_(std::move(device)), - event_handler_(std::move(event_handler)) { + event_handler_(event_handler) { RenderFrameHost* main_frame = render_frame_host->GetMainFrame(); origin_ = main_frame->GetLastCommittedOrigin(); }
diff --git a/chrome/browser/private_network_access/private_network_device_chooser_controller.h b/chrome/browser/private_network_access/private_network_device_chooser_controller.h index 9de611d..9398d87c 100644 --- a/chrome/browser/private_network_access/private_network_device_chooser_controller.h +++ b/chrome/browser/private_network_access/private_network_device_chooser_controller.h
@@ -11,6 +11,7 @@ #include <vector> #include "base/memory/raw_ptr.h" +#include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "chrome/browser/private_network_access/chrome_private_network_device_chooser.h" @@ -60,7 +61,8 @@ url::Origin origin_; std::unique_ptr<blink::mojom::PrivateNetworkDevice> device_; - const ChromePrivateNetworkDeviceChooser::EventHandler& event_handler_; + const raw_ref<const ChromePrivateNetworkDeviceChooser::EventHandler> + event_handler_; base::WeakPtrFactory<PrivateNetworkDeviceChooserController> weak_factory_{ this};
diff --git a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc index 478289b..6031260 100644 --- a/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc +++ b/chrome/browser/profiles/chrome_browser_main_extra_parts_profiles.cc
@@ -266,6 +266,7 @@ #include "chrome/browser/ash/app_list/app_list_syncable_service_factory.h" #include "chrome/browser/ash/browser_context_keyed_service_factories.h" #include "chrome/browser/ash/login/security_token_session_controller_factory.h" +#include "chrome/browser/ash/policy/dlp/files_policy_notification_manager_factory.h" #include "chrome/browser/ash/system_extensions/api/window_management/cros_window_management_context_factory.h" #include "chrome/browser/ash/system_extensions/system_extensions_provider_factory.h" #include "chrome/browser/ash/system_web_apps/system_web_app_manager_factory.h" @@ -884,6 +885,9 @@ policy::PolicyCertServiceFactory::GetInstance(); policy::UserNetworkConfigurationUpdaterFactory::GetInstance(); #endif +#if BUILDFLAG(IS_CHROMEOS_ASH) + policy::FilesPolicyNotificationManagerFactory::GetInstance(); +#endif policy::UserCloudPolicyInvalidatorFactory::GetInstance(); #if !BUILDFLAG(IS_CHROMEOS_ASH) policy::UserPolicySigninServiceFactory::GetInstance();
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu.cc b/chrome/browser/renderer_context_menu/render_view_context_menu.cc index 5a08d19f5..5fbfed7 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu.cc
@@ -1474,11 +1474,6 @@ IsDevToolsURL(params_.page_url) && params_.page_url.query().find("debugFrontend=true") == std::string::npos; -#if BUILDFLAG(IS_CHROMEOS_ASH) - hide_developer_items = - hide_developer_items || !crosapi::browser_util::IsAshDevToolEnabled(); -#endif - if (hide_developer_items) return;
diff --git a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc index 10a9ab5..8a18c9b1 100644 --- a/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc +++ b/chrome/browser/renderer_context_menu/render_view_context_menu_unittest.cc
@@ -597,77 +597,6 @@ menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_OPENLINKOFFTHERECORD)); } -#if BUILDFLAG(IS_CHROMEOS_ASH) -// Verify that the "Inspect" item and the "View page source" item are not -// present in the context menu if the lacros is the only browser and the -// `kAllowDevtoolsInSystemUI` flag is not enabled. -// TODO(junis): Change test fixture since this test has little to do with Prefs -TEST_F(RenderViewContextMenuPrefsTest, - DeveloperItemsAreNotPresentByDefaultIfAshBrowserIsDisabled) { - base::test::ScopedFeatureList features; - features.InitWithFeatures( - {ash::features::kLacrosSupport, ash::features::kLacrosPrimary, - ash::features::kLacrosOnly, - ash::features::kLacrosProfileMigrationForceOff}, - {}); - - auto fake_user_manager = std::make_unique<user_manager::FakeUserManager>(); - auto* primary_user = - fake_user_manager->AddUser(AccountId::FromUserEmail("test@test")); - fake_user_manager->UserLoggedIn(primary_user->GetAccountId(), - primary_user->username_hash(), - /*browser_restart=*/false, - /*is_child=*/false); - auto scoped_user_manager = std::make_unique<user_manager::ScopedUserManager>( - std::move(fake_user_manager)); - - ASSERT_FALSE(crosapi::browser_util::IsAshDevToolEnabled()); - - content::ContextMenuParams params = CreateParams(MenuItem::PAGE); - auto menu = std::make_unique<TestRenderViewContextMenu>( - *web_contents()->GetPrimaryMainFrame(), params); - menu->Init(); - - EXPECT_FALSE(menu->IsItemPresent(IDC_VIEW_SOURCE)); - EXPECT_FALSE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_INSPECTELEMENT)); -} - -// Verify that the "Inspect" item and the "View page source" are present in the -// context menu if the lacros is the only browser and the -// `kAllowDevtoolsInSystemUI` flag is enabled. -// TODO(junis): Change test fixture since this test has little to do with Prefs -TEST_F(RenderViewContextMenuPrefsTest, - DeveloperItemsArePresentIfAshBrowserIsDisabledAndFlagIsEnabled) { - base::test::ScopedFeatureList features; - features.InitWithFeatures( - {ash::features::kLacrosSupport, ash::features::kLacrosPrimary, - ash::features::kLacrosOnly, - ash::features::kLacrosProfileMigrationForceOff, - ash::features::kAllowDevtoolsInSystemUI}, - {}); - - auto fake_user_manager = std::make_unique<user_manager::FakeUserManager>(); - auto* primary_user = - fake_user_manager->AddUser(AccountId::FromUserEmail("test@test")); - fake_user_manager->UserLoggedIn(primary_user->GetAccountId(), - primary_user->username_hash(), - /*browser_restart=*/false, - /*is_child=*/false); - auto scoped_user_manager = std::make_unique<user_manager::ScopedUserManager>( - std::move(fake_user_manager)); - - ASSERT_TRUE(crosapi::browser_util::IsAshDevToolEnabled()); - - content::ContextMenuParams params = CreateParams(MenuItem::PAGE); - auto menu = std::make_unique<TestRenderViewContextMenu>( - *web_contents()->GetPrimaryMainFrame(), params); - menu->Init(); - - EXPECT_TRUE(menu->IsItemPresent(IDC_VIEW_SOURCE)); - EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_INSPECTELEMENT)); -} -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - #if BUILDFLAG(IS_CHROMEOS) class RenderViewContextMenuDlpPrefsTest : public RenderViewContextMenuPrefsTest {
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js index 237fd34..b94ce55 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_captions_background.js
@@ -154,8 +154,8 @@ */ static getVirtualDisplayState() { if (BrailleCaptionsBackground.isEnabled()) { - const rows = Number(SettingsManager.get('virtualBrailleRows')); - const columns = Number(SettingsManager.get('virtualBrailleColumns')); + const rows = SettingsManager.getNumber('virtualBrailleRows'); + const columns = SettingsManager.getNumber('virtualBrailleColumns'); return {available: true, textRowCount: rows, textColumnCount: columns}; } else { return {available: false, textRowCount: 0, textColumnCount: 0};
diff --git a/chrome/browser/resources/chromeos/cloud_upload/BUILD.gn b/chrome/browser/resources/chromeos/cloud_upload/BUILD.gn index 4910f8f8..af20f6f 100644 --- a/chrome/browser/resources/chromeos/cloud_upload/BUILD.gn +++ b/chrome/browser/resources/chromeos/cloud_upload/BUILD.gn
@@ -25,12 +25,15 @@ "images/connect_one_drive.svg", "images/install_office_app_icon.svg", "images/install_office.svg", + "images/install_onedrive_alone.svg", "images/one_drive_success.svg", + "images/onedrive_app_icon.svg", "images/welcome.svg", "main.html", ] web_component_files = [ "base_setup_page.ts", + "connect_onedrive.ts", "file_handler_card.ts", "file_handler_page.ts", "move_confirmation_page.ts",
diff --git a/chrome/browser/resources/chromeos/cloud_upload/base_setup_page.html b/chrome/browser/resources/chromeos/cloud_upload/base_setup_page.html index 4e27de16..e771742 100644 --- a/chrome/browser/resources/chromeos/cloud_upload/base_setup_page.html +++ b/chrome/browser/resources/chromeos/cloud_upload/base_setup_page.html
@@ -69,7 +69,8 @@ ::slotted([slot=header-image]) { /* As this surface is a dialog, replace the color palette with its elevated - * variant. */ + * variant. We also do this for GM3 assets so that they correctly map back + * to GM2 tokens when the jelly flag is off. */ --cros-illustration-color-1-shade-1: var( --cros-illustration-elevation-color-1-shade-1); --cros-illustration-color-1-shade-2: var( @@ -78,6 +79,11 @@ --cros-illustration-elevation-base-color); --cros-illustration-secondary-color: var( --cros-illustration-elevation-secondary-color); + --cros-sys-illo-color1-1: var(--cros-sys-illo-elevated-color-1-1); + --cros-sys-illo-color1-2: var(--cros-sys-illo-elevated-color-1-2); + --cros-sys-illo-base: var(--cros-sys-illo-elevated-base); + --cros-sys-illo-secondary: var(--cros-sys-illo-elevated-secondary); + height: 100%; width: 100%;
diff --git a/chrome/browser/resources/chromeos/cloud_upload/connect_onedrive.html b/chrome/browser/resources/chromeos/cloud_upload/connect_onedrive.html new file mode 100644 index 0000000..b806323 --- /dev/null +++ b/chrome/browser/resources/chromeos/cloud_upload/connect_onedrive.html
@@ -0,0 +1,147 @@ +<style> + #dialog { + box-sizing: border-box; + display: flex; + flex-direction: column; + width: 512px; + } + + .body-wrapper { + padding: 32px; + } + + #dialog:focus-visible { + outline: none; + } + + svg { + background-color: var(--cros-highlight-color); + height: 236px; + width: 512px; + } + + #title { + color: var(--cros-text-color-primary); + font: var(--cros-display-6-font); + } + + .normal-text { + color: var(--cros-text-color-secondary); + font: var(--cros-body-1-font); + height: 148px; + margin-block-start: 16px; + } + + #error-message { + align-items: center; + color: var(--cros-text-color-alert); + display: flex; + margin-top: 12px; + } + + #error-message[hidden] { + /* display: flex overrides the hidden visibility */ + display: none; + } + + .error-text { + margin-inline-start: 5px; + } + + .icon { + -webkit-mask-image: url(icons/error.svg); + background-color: var(--cros-icon-color-alert); + height: 17px; + width: 17px; + } + + #button-container { + display: flex; + justify-content: flex-end; + margin-top: 32px; + } + + :host-context([theme='legacy']) cr-button { + border-radius: 16px; + } + + :host-context([theme='legacy']) cr-button:focus-visible { + /* disable cr-button default keyboard focus style */ + box-shadow: none; + outline: 2px solid var(--cros-focus-ring-color); + outline-offset: 2px; + } + + :host-context([theme='refresh23']) cr-button { + --active-bg: transparent; + --active-shadow: none; + --active-shadow-action: none; + --bg-action: var(--cros-sys-primary); + --cr-button-height: 36px; + --disabled-bg-action: + var(--cros-sys-disabled_container); + --disabled-bg: var(--cros-sys-disabled_container);; + --disabled-text-color: var(--cros-sys-disabled); + /* Use the default bg color as hover color because we + rely on hoverBackground layer below. */ + --hover-bg-action: var(--cros-sys-primary); + --hover-bg-color: var(--cros-sys-primary_container); + --ink-color: var(--cros-sys-ripple_primary); + --ripple-opacity-action: 1; + --ripple-opacity: 1; + --text-color-action: var(--cros-sys-on_primary); + --text-color: var(--cros-sys-on_primary_container); + border: none; + border-radius: 18px; + box-shadow: none; + } + + :host-context([theme='refresh23']) cr-button.cancel-button { + background-color: var(--cros-sys-primary_container); + } + + :host-context([theme='refresh23']) + cr-button.cancel-button:hover::part(hoverBackground) { + background-color: var(--cros-sys-hover_on_subtle); + display: block; + } + + :host-context([theme='refresh23']) + cr-button.action-button:hover::part(hoverBackground) { + background-color: var(--cros-sys-hover_on_prominent); + display: block; + } + + :host-context([theme='refresh23']):host-context(.focus-outline-visible) + cr-button:focus { + outline: 2px solid var(--cros-sys-focus_ring); + outline-offset: 2px; + } +</style> + +<svg viewBox="0 0 448 200"> + <use id="install" href="images/install_onedrive_alone.svg#EXPORT_image"></use> + <use id="success" visibility="hidden" + href="images/one_drive_success.svg#EXPORT_image"></use> +</svg> +<!-- autofocus for screen reader to read header on dialog open--> +<div id="dialog" role="dialog" autofocus tabindex="-1" aria-labelledby="title"> + <div class="body-wrapper"> + <div id="title"> + $i18n{connectToOneDriveTitle} + </div> + <div class="normal-text" id="body-text"> + $i18n{connectToOneDriveBodyText} + <div id="error-message" hidden> + <div class="icon"></div> + <span class="error-text"> + $i18n{cantConnectOneDrive} + </span> + </div> + </div> + <div id="button-container"> + <cr-button class="cancel-button">$i18n{close}</cr-button> + <cr-button class="action-button">$i18n{connectOneDrive}</cr-button> + </div> + </div> +</div>
diff --git a/chrome/browser/resources/chromeos/cloud_upload/connect_onedrive.ts b/chrome/browser/resources/chromeos/cloud_upload/connect_onedrive.ts new file mode 100644 index 0000000..562181ef --- /dev/null +++ b/chrome/browser/resources/chromeos/cloud_upload/connect_onedrive.ts
@@ -0,0 +1,71 @@ +// 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. + +import 'chrome://resources/cr_elements/cr_button/cr_button.js'; +import './strings.m.js'; + +import {loadTimeData} from 'chrome://resources/ash/common/load_time_data.m.js'; + +import {UserAction} from './cloud_upload.mojom-webui.js'; +import {CloudUploadBrowserProxy} from './cloud_upload_browser_proxy.js'; +import {getTemplate} from './connect_onedrive.html.js'; + +/** + * The ConnectOneDriveElement represents the dialog shown when the user selects + * OneDrive from the Files app Services menu, without going through the normal + * setup flow. + */ +export class ConnectOneDriveElement extends HTMLElement { + private proxy: CloudUploadBrowserProxy = + CloudUploadBrowserProxy.getInstance(); + + constructor() { + super(); + + const shadowRoot = this.attachShadow({mode: 'open'}); + + shadowRoot.innerHTML = getTemplate(); + const connectButton = this.$('.action-button')!; + const closeButton = this.$('.cancel-button')!; + + connectButton.addEventListener('click', () => this.onConnectButtonClick()); + closeButton.addEventListener('click', () => this.onCloseButtonClick()); + } + + $<T extends HTMLElement>(query: string): T { + return this.shadowRoot!.querySelector(query)!; + } + + private async onConnectButtonClick(): Promise<void> { + const {success: signInSuccess} = + await this.proxy.handler.signInToOneDrive(); + + if (signInSuccess) { + // Change to success page. + this.shadowRoot!.querySelector<SVGUseElement>('#install')!.setAttribute( + 'visibility', 'hidden'); + this.shadowRoot!.querySelector<SVGUseElement>('#success')!.setAttribute( + 'visibility', 'visible'); + this.$('#title').innerText = + loadTimeData.getString('oneDriveConnectedTitle'); + this.$('#body-text').innerText = + loadTimeData.getString('oneDriveConnectedBodyText'); + this.$('.action-button')!.remove(); + } else { + this.$('#error-message').toggleAttribute('hidden', false); + } + } + + private onCloseButtonClick(): void { + this.proxy.handler.respondWithUserActionAndClose(UserAction.kCancel); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'connect-onedrive': ConnectOneDriveElement; + } +} + +customElements.define('connect-onedrive', ConnectOneDriveElement);
diff --git a/chrome/browser/resources/chromeos/cloud_upload/images/install_onedrive_alone.svg b/chrome/browser/resources/chromeos/cloud_upload/images/install_onedrive_alone.svg new file mode 100644 index 0000000..dcd76552 --- /dev/null +++ b/chrome/browser/resources/chromeos/cloud_upload/images/install_onedrive_alone.svg
@@ -0,0 +1 @@ +<svg id="EXPORT_image" xmlns="http://www.w3.org/2000/svg" data-name="Layer 1" viewBox="0 0 448 200"><defs><clipPath id="a"><rect width="448" height="200" rx="12" style="fill:none"/></clipPath></defs><g style="clip-path:url(#a)"><circle cx="225" cy="100" r="82.5" style="stroke:var(--cros-illustration-color-1-shade-2);stroke-width:3px;fill:none"/><circle cx="225" cy="100" r="174" style="stroke-linecap:round;stroke-dasharray:4 12;stroke:var(--cros-illustration-color-1-shade-2);stroke-width:3px;fill:none"/><image href="images/onedrive_app_icon.svg" height="200" width="448"/></g></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/cloud_upload/images/onedrive_app_icon.svg b/chrome/browser/resources/chromeos/cloud_upload/images/onedrive_app_icon.svg new file mode 100644 index 0000000..460dcf1 --- /dev/null +++ b/chrome/browser/resources/chromeos/cloud_upload/images/onedrive_app_icon.svg
@@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" style="enable-background:new 0 0 448 200" viewBox="0 0 448 200"><circle cx="225.5" cy="100.5" r="41.5" style="fill:#fff"/><path d="m218.4 91.4 13.4 8.1 8.1-3.4c1.6-.7 3.4-1.1 5.2-1.1h.9c-2.7-10.7-13.6-17.2-24.3-14.4-4.8 1.2-9.1 4.2-11.8 8.4h.2c3 .1 5.8.9 8.3 2.4z" style="fill:#0364b8"/><path d="M218.4 91.4c-2.5-1.5-5.4-2.3-8.4-2.4h-.2c-8.8 0-16 7.3-15.9 16.1 0 3.3 1 6.4 2.9 9.1l11.9-5 5.3-2.2 11.7-4.9 6.1-2.6-13.4-8.1z" style="fill:#0078d4"/><path d="M245.9 95h-.9c-1.8 0-3.5.4-5.2 1.1l-8 3.4 2.3 1.4 7.6 4.5 3.2 2 11.4 6.8c3.4-6.3 1.1-14.2-5.2-17.6-1.5-.9-3.4-1.5-5.2-1.6z" style="fill:#1490df"/><path d="m245.1 107.4-3.2-2-7.6-4.6-2.3-1.4-6.2 2.6-11.7 4.9-5.3 2.2-11.9 5c3 4.3 7.9 6.9 13.1 6.9h35c4.8 0 9.2-2.6 11.4-6.8l-11.3-6.8z" style="fill:#28a8ea"/></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/cloud_upload/main.ts b/chrome/browser/resources/chromeos/cloud_upload/main.ts index 106cf5c..5a64f49 100644 --- a/chrome/browser/resources/chromeos/cloud_upload/main.ts +++ b/chrome/browser/resources/chromeos/cloud_upload/main.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import './cloud_upload_dialog.js'; +import './connect_onedrive.js'; import './file_handler_page.js'; import './strings.m.js'; @@ -51,4 +52,8 @@ document.body.append(movePage); break; } + case DialogPage.kConnectToOneDrive: { + document.body.append(document.createElement('connect-onedrive')); + break; + } }
diff --git a/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html b/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html index a30c887..aaccf66a 100644 --- a/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html +++ b/chrome/browser/resources/chromeos/cloud_upload/welcome_page.html
@@ -76,8 +76,7 @@ <div id="description"></div> <p> <a href="#" onclick="e => e.preventDefault()">Learn more</a> about - Microsoft 365 on your Chromebook. Read the <a href="#" - onclick="e => e.preventDefault()">Microsoft terms and conditions.</a> + Microsoft 365 on your Chromebook. </p> </div> <div slot="button-container">
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.html index 44240a5..e5d2e5e8 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.html
@@ -39,6 +39,6 @@ class$="[[calculateClassName(active, searchActive)]]" iron-icon="[[icon]]" on-click="handleClick" - aria-label="[[name]]" + aria-label$="[[getAriaLabel(name, gifSupport)]]" > </cr-icon-button>
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.ts b/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.ts index a1a2d29..b199796f 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.ts +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_category_button.ts
@@ -9,6 +9,14 @@ import {getTemplate} from './emoji_category_button.html.js'; import {CATEGORY_BUTTON_CLICK, CategoryButtonClickEvent, createCustomEvent} from './events.js'; +import {CategoryEnum} from './types.js'; + +const DEFAULT_ARIA_LABELS: Record<CategoryEnum, string> = { + [CategoryEnum.EMOJI]: 'Emoji category', + [CategoryEnum.SYMBOL]: 'Symbol category', + [CategoryEnum.EMOTICON]: 'Emoticon category', + [CategoryEnum.GIF]: 'GIF category', +}; export class EmojiCategoryButton extends PolymerElement { static get is() { @@ -28,7 +36,7 @@ gifSupport: {type: Boolean, value: false}, }; } - name: string; + name: CategoryEnum; icon: string; active: boolean; private gifSupport: boolean; @@ -45,6 +53,16 @@ } return active ? 'category-button-active' : ''; } + + private getAriaLabel(name: CategoryEnum, gifSupport: boolean): string { + // TODO(b/281609806): Remove this condition once GIF support is fully + // launched. + if (!gifSupport) { + return name; + } + + return DEFAULT_ARIA_LABELS[name] ?? name; + } } declare global {
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html index d6d32f9d..e0eeb41 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_group.html
@@ -220,7 +220,8 @@ <div id="heading-left">[[group]]</div> <template is="dom-if" if="[[clearable]]"> <cr-icon-button id="show-clear" iron-icon="emoji_picker:more_horizontal" - on-click="onClearClick"> + on-click="onClearClick" + aria-label="More options"> </cr-icon-button> </template> </div>
diff --git a/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.ts b/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.ts index 0e088227..fd04fac 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.ts +++ b/chrome/browser/resources/chromeos/emoji_picker/metadata_extension.ts
@@ -10,7 +10,7 @@ */ -import {CategoryEnum, GifSubcategoryData, SubcategoryData} from './types.js'; +import {CategoryData, CategoryEnum, GifSubcategoryData, SubcategoryData} from './types.js'; const RECENTLY_USED_NAME = 'Recently used'; @@ -67,8 +67,7 @@ return groupTabs; } -export const CATEGORY_METADATA: - Array<{name: CategoryEnum, icon: string, active: boolean}> = [ +export const CATEGORY_METADATA: CategoryData[] = [ { name: CategoryEnum.EMOJI, icon: 'emoji_picker_v2:emoji_emojis_outlined', @@ -86,8 +85,7 @@ }, ]; -export const GIF_CATEGORY_METADATA: - Array<{name: CategoryEnum, icon: string, active: boolean}> = [ +export const GIF_CATEGORY_METADATA: CategoryData[] = [ ...CATEGORY_METADATA, { name: CategoryEnum.GIF,
diff --git a/chrome/browser/resources/chromeos/emoji_picker/types.ts b/chrome/browser/resources/chromeos/emoji_picker/types.ts index a6e29a5e..0847ec79 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/types.ts +++ b/chrome/browser/resources/chromeos/emoji_picker/types.ts
@@ -6,7 +6,7 @@ import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; export interface CategoryData { - name: string; + name: CategoryEnum; icon: string; active: boolean; }
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn index 0f1d7013..519759a 100644 --- a/chrome/browser/resources/chromeos/login/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -311,6 +311,9 @@ "screens/common/os_trial.js", "screens/common/parental_handoff.js", "screens/common/pin_setup.js", + + # Template used by the `tools/oobe/generate_screen_template.py` script. + "screens/common/placeholder.js", "screens/common/recommend_apps.js", "screens/common/saml_confirm_password.js", "screens/common/signin_fatal_error.js",
diff --git a/chrome/browser/resources/chromeos/login/components/dialogs/oobe_modal_dialog.html b/chrome/browser/resources/chromeos/login/components/dialogs/oobe_modal_dialog.html index ff28b6a..d668725 100644 --- a/chrome/browser/resources/chromeos/login/components/dialogs/oobe_modal_dialog.html +++ b/chrome/browser/resources/chromeos/login/components/dialogs/oobe_modal_dialog.html
@@ -16,15 +16,20 @@ } #modalDialogTitle { - font-family: var(--oobe-default-font-family); + font-family: var(--oobe-modal-dialog-header-font-family); font-size: var(--oobe-modal-dialog-header-font-size); font-weight: var(--oobe-modal-dialog-header-font-weight); + line-height: var(--oobe-modal-dialog-header-line-height); margin: 0; user-select: none; } #contentContainer { + font-family: var(--oobe-modal-dialog-content-font-family); + font-size: var(--oobe-modal-dialog-content-font-size); + font-weight: var(--oobe-modal-dialog-content-font-weight); height: var(--oobe-modal-dialog-content-height); + line-height: var(--oobe-modal-dialog-content-line-height); padding-bottom: var(--oobe-modal-dialog-content-slot-padding-bottom, 12px); padding-inline-end: @@ -44,7 +49,7 @@ </slot> </div> <!-- Content to be shown --> - <div id="contentContainer" class="oobe-default-font" slot="body" + <div id="contentContainer" slot="body" class="flex-grow layout vertical not-resizable"> <slot name="content"> <template is="dom-if" if="[[contentKey]]">
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_icons.html b/chrome/browser/resources/chromeos/login/components/oobe_icons.html index 95b89c3..02c7ef1 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_icons.html +++ b/chrome/browser/resources/chromeos/login/components/oobe_icons.html
@@ -253,12 +253,23 @@ </g> </g> </g> + <g id="theme-light"> + <path d="M6 4C4.89543 4 4 4.89543 4 6V26C4 27.1046 4.89543 28 6 28H16V22C12.6863 22 10 19.3137 10 16C10 12.6863 12.6863 10 16 10V4H6Z" fill="var(--cros-sys-primary)"></path> + <path d="M16 22C19.3137 22 22 19.3137 22 16C22 12.6863 19.3137 10 16 10V22Z" fill="var(--cros-sys-primary)"></path> + <path fill-rule="evenodd" clip-rule="evenodd" d="M25 6H16V4H25C26.6569 4 28 5.34315 28 7V25C28 26.6569 26.6569 28 25 28H16V26H25C25.5523 26 26 25.5523 26 25V7C26 6.44772 25.5523 6 25 6Z" fill="var(--cros-sys-primary)"></path> + </g> <g id="scroll-direction"> - <path fill-rule="evenodd" clip-rule="evenodd" d="M5.39961 5.86341L2.40441 8.99088L0.599609 7.14506L6.99961 0.599609L13.3996 7.14506L11.5948 8.99088L8.59961 5.99307V24.1358L11.5948 21.0083L13.3996 22.8542L6.99961 29.3996L0.599609 22.8542L2.40441 21.0083L5.39961 24.0062V5.86341Z" fill="var(--cros-sys-primary)"></path> + <path d="M6 13C6 11.8954 6.89543 11 8 11H24C25.1046 11 26 11.8954 26 13V19C26 20.1046 25.1046 21 24 21H8C6.89543 21 6 20.1046 6 19V13Z" fill="var(--cros-sys-primary)"></path> + <path d="M15.6558 2.32919C16.0487 1.71066 16.9513 1.71066 17.3441 2.32919L20.2876 6.96389C20.7104 7.62965 20.2321 8.5 19.4434 8.5H13.5566C12.7679 8.5 12.2896 7.62965 12.7124 6.96389L15.6558 2.32919Z" fill="var(--cros-sys-primary)"></path> + <path d="M17.3441 29.6708C16.9513 30.2893 16.0487 30.2893 15.6558 29.6708L12.7124 25.0361C12.2896 24.3703 12.7679 23.5 13.5566 23.5L19.4434 23.5C20.2321 23.5 20.7104 24.3703 20.2876 25.0361L17.3441 29.6708Z" fill="var(--cros-sys-primary)"></path> </g> <g id="display"> - <path fill-rule="evenodd" clip-rule="evenodd" d="M10 6C8.89543 6 8 6.89543 8 8V17H13C14.1046 17 15 17.8954 15 19V25H25C26.1046 25 27 24.1046 27 23V8C27 6.89543 26.1046 6 25 6H10Z"></path> - <rect x="5" y="19" width="8" height="8" rx="2"></rect> + <rect x="4" y="18" width="10" height="10" rx="2" fill="var(--cros-sys-primary)"></rect> + <path fill-rule="evenodd" clip-rule="evenodd" d="M8 20H6V22H8V26H10V22H12V20H10H8Z" fill="white"></path> + <path fill-rule="evenodd" clip-rule="evenodd" d="M9 6C9 4.89543 9.89543 4 11 4H26C27.1046 4 28 4.89543 28 6V21C28 22.1046 27.1046 23 26 23H15V19C15 17.8954 14.1046 17 13 17H9V6ZM17 8H13V11H17V18H20V11H24V8H20H17Z" fill="var(--cros-sys-primary)"></path> + </g> + <g id="choobe-icon"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M0.199951 0.200012H14.6V14.6H0.199951V0.200012ZM4.99995 5.00001V9.80001H9.79995V5.00001H4.99995ZM0.199951 19.4H14.6V33.8H0.199951V19.4ZM4.99995 24.2V29H9.79995V24.2H4.99995ZM19.4 0.200012H33.7999V14.6H19.4V0.200012ZM24.1999 5.00001V9.80001H29V5.00001H24.1999ZM26.5999 16.4177L36.7823 26.6L26.5999 36.7823L16.4176 26.6L26.5999 16.4177ZM26.5999 23.2059L23.2058 26.6L26.5999 29.9941L29.9941 26.6L26.5999 23.2059Z" fill="var(--cros-sys-primary)"></path> </g> <!-- OS Sync Consent Icons --> <g id="sync-app">
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_screens_list.html b/chrome/browser/resources/chromeos/login/components/oobe_screens_list.html index b675d33..18840ee8 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_screens_list.html +++ b/chrome/browser/resources/chromeos/login/components/oobe_screens_list.html
@@ -51,8 +51,7 @@ } .text-container { - align-items: center; - display: flex; + display: block; flex-direction: column; justify-content: center; margin-inline-end: 16px; @@ -134,10 +133,12 @@ </div> <div class="text-container"> <div class="screen-title"> [[i18nDynamic(locale, screen.title)]]</div> - <div class="screen-subtitle">[[getSubtitile_(locale)]]</div> + <div class="screen-subtitle">[[getSubtitle_(locale, screen.subtitle, + screen.screenID )]]</div> </div> <div class="info-icon"> <iron-icon hidden="[[isSyncedIconHidden(screen.is_synced , + screen.is_completed , screen.selected)]]" id="sync" icon="oobe-20:sync"></iron-icon> <iron-icon hidden="[[!screen.selected]]"
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_screens_list.js b/chrome/browser/resources/chromeos/login/components/oobe_screens_list.js index e01e778..2266431 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_screens_list.js +++ b/chrome/browser/resources/chromeos/login/components/oobe_screens_list.js
@@ -105,8 +105,13 @@ this.notifyPath('screensList_'); } - getSubtitile_(locale, screen_subtitle) { + getSubtitle_(locale, screen_subtitle, screen_id) { if (screen_subtitle) { + // display size screen is special case as the subtitle include directly + // the percentage and will be displayed directly without i18n. + if (screen_id === 'display-size') { + return screen_subtitle; + } return this.i18nDynamic(locale, screen_subtitle); } return ''; @@ -116,8 +121,8 @@ return (!is_revisitable) && is_completed; } - isSyncedIconHidden(is_synced, is_selected) { - return (!is_synced) || (is_selected); + isSyncedIconHidden(is_synced, is_completed, is_selected) { + return (!is_synced) || (is_selected) || (is_completed); } isScreenVisited(is_selected, is_completed) {
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars.css b/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars.css index ea1e29a1..11cb025 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars.css +++ b/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars.css
@@ -49,6 +49,22 @@ --oobe-welcome-header-font-weight: 500; /* medium */ + --oobe-content-dialog-font-family: var(--oobe-default-font-family); + --oobe-content-dialog-font-size: var(--oobe-default-font-size); + --oobe-content-dialog-font-weight: var(--oobe-default-font-weight); + --oobe-content-dialog-line-height: var(--oobe-default-line-height); + + --oobe-modal-dialog-header-font-family: var(--oobe-default-font-family); + --oobe-modal-dialog-header-font-size: + var(--oobe-modal-dialog-header-font-size); + --oobe-modal-dialog-header-font-weight: + var(--oobe-modal-dialog-header-font-weight); + + --oobe-modal-dialog-content-font-family: var(--oobe-default-font-family); + --oobe-modal-dialog-content-font-size: var(--oobe-default-font-size); + --oobe-modal-dialog-content-font-weight: var(--oobe-default-font-weight); + --oobe-modal-dialog-content-line-height: var(--oobe-default-line-height); + /* Select */ --oobe-select-height: 32px; @@ -63,6 +79,39 @@ --oobe-network-row-height: 48px; } + html.jelly-enabled { + /* Fonts */ + --oobe-default-font-family: var(--cros-body-2-font-family); + --oobe-default-font-size: var(--cros-body-2-font-size); + --oobe-default-line-height: var(--cros-body-2-line-height); + --oobe-default-font-weight: var(--cros-body-2-font-weight); + + --oobe-header-font-size: var(--cros-display-3_regular-font-size); + --oobe-header-line-height: var(--cros-display-3_regular-line-height); + --oobe-header-font-weight: var(--cros-display-3_regular-font-weight); + --oobe-header-font-family: var(--cros-display-3_regular-font-family); + + --oobe-subheader-font-family: var(--cros-body-0-font-family); + --oobe-subheader-font-size: var(--cros-body-0-font-size); + --oobe-subheader-line-height: var(--cros-body-0-line-height); + --oobe-subheader-font-weight: var(--cros-body-0-font-weight); + + --oobe-content-dialog-font-family: var(--oobe-default-font-family); + --oobe-content-dialog-font-size: var(--oobe-default-font-size); + --oobe-content-dialog-font-weight: var(--oobe-default-font-weight); + --oobe-content-dialog-line-height: var(--oobe-default-line-height); + + --oobe-modal-dialog-header-font-family: var(--cros-display-7-font-family); + --oobe-modal-dialog-header-font-size: var(--cros-display-7-font-size); + --oobe-modal-dialog-header-font-weight: var(--cros-display-7-font-weight); + --oobe-modal-dialog-header-line-height: var(--cros-display-7-line-height); + + --oobe-modal-dialog-content-font-family: var(--cros-body-1-font-family); + --oobe-modal-dialog-content-font-size: var(--cros-body-1-font-size); + --oobe-modal-dialog-content-font-weight: var(--cros-body-1-font-weight); + --oobe-modal-dialog-content-line-height: var(--cros-body-1-line-height); + } + html.simon-enabled { --oobe-welcome-header-font-weight: 400; /* regular */ }
diff --git a/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars_remora.css b/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars_remora.css index a7b6d25..ea26fcc 100644 --- a/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars_remora.css +++ b/chrome/browser/resources/chromeos/login/components/oobe_vars/oobe_custom_vars_remora.css
@@ -46,6 +46,22 @@ --oobe-welcome-header-font-weight: 400; /* regular */ + --oobe-content-dialog-font-family: var(--oobe-default-font-family); + --oobe-content-dialog-font-size: var(--oobe-default-font-size); + --oobe-content-dialog-font-weight: var(--oobe-default-font-weight); + --oobe-content-dialog-line-height: var(--oobe-default-line-height); + + --oobe-modal-dialog-header-font-family: var(--oobe-default-font-family); + --oobe-modal-dialog-header-font-size: + var(--oobe-modal-dialog-header-font-size); + --oobe-modal-dialog-header-font-weight: + var(--oobe-modal-dialog-header-font-weight); + + --oobe-modal-dialog-content-font-family: var(--oobe-default-font-family); + --oobe-modal-dialog-content-font-size: var(--oobe-default-font-size); + --oobe-modal-dialog-content-font-weight: var(--oobe-default-font-weight); + --oobe-modal-dialog-content-line-height: var(--oobe-default-line-height); + /* Select */ --oobe-select-height: 44px;
diff --git a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn index 849baa4..01160154 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/screens/common/BUILD.gn
@@ -56,6 +56,7 @@ ":os_trial", ":parental_handoff", ":pin_setup", + ":placeholder", ":recommend_apps", ":saml_confirm_password", ":signin_fatal_error", @@ -545,6 +546,18 @@ extra_deps = [ ":web_components" ] } +# Template used by the `tools/oobe/generate_screen_template.py` script. +js_library("placeholder") { + sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/placeholder.js" ] + deps = [ + "../../components/behaviors:login_screen_behavior", + "../../components/behaviors:oobe_dialog_host_behavior", + "../../components/behaviors:oobe_i18n_behavior", + "../../components/dialogs:oobe_adaptive_dialog", + ] + extra_deps = [ ":web_components" ] +} + js_library("recommend_apps") { sources = [ "$root_gen_dir/chrome/browser/resources/chromeos/login/screens/common/recommend_apps.js" ] deps = [ @@ -738,6 +751,7 @@ "os_trial.js", "parental_handoff.js", "pin_setup.js", + "placeholder.js", "recommend_apps.js", "saml_confirm_password.js", "signin_fatal_error.js",
diff --git a/chrome/browser/resources/chromeos/login/screens/common/choobe.html b/chrome/browser/resources/chromeos/login/screens/common/choobe.html index 63dd65ca..6ab397e 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/choobe.html +++ b/chrome/browser/resources/chromeos/login/screens/common/choobe.html
@@ -9,7 +9,7 @@ </style> <oobe-adaptive-dialog id="choobeDialog" role="presentation" for-step="overview"> - <iron-icon slot="icon" icon="oobe-32:game-controller"></iron-icon> + <iron-icon slot="icon" icon="oobe-32:choobe-icon"></iron-icon> <h1 slot="title" id="choobe-title"> [[i18nDynamic(locale, 'choobeScreenTitle')]] </h1>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/placeholder.html b/chrome/browser/resources/chromeos/login/screens/common/placeholder.html new file mode 100644 index 0000000..d02eab9 --- /dev/null +++ b/chrome/browser/resources/chromeos/login/screens/common/placeholder.html
@@ -0,0 +1,30 @@ +<!-- +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. +--> +<style include="oobe-dialog-host-styles"> + +/* Add styles here */ + +</style> +<oobe-adaptive-dialog role="dialog"> + <!-- Add HTML content here --> + <h1 slot="title"> + Your title + </h1> + <div slot="subtitle"> + Your subtitle + </div> + <div slot="content" class="layout vertical"> + Your content + </div> + <div slot="back-navigation"> + <oobe-back-button id="backButton" + on-click="onBackClicked_"></oobe-back-button> + </div> + <div slot="bottom-buttons"> + <oobe-next-button id="nextButton" + on-click="onNextClicked_"></oobe-next-button> + </div> +</oobe-adaptive-dialog>
diff --git a/chrome/browser/resources/chromeos/login/screens/common/placeholder.js b/chrome/browser/resources/chromeos/login/screens/common/placeholder.js new file mode 100644 index 0000000..3dc715f --- /dev/null +++ b/chrome/browser/resources/chromeos/login/screens/common/placeholder.js
@@ -0,0 +1,66 @@ +// 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. + +import '../../components/buttons/oobe_back_button.js'; +import '../../components/buttons/oobe_next_button.js'; +import '../../components/common_styles/oobe_common_styles.css.js'; +import '../../components/common_styles/oobe_dialog_host_styles.css.js'; +import '../../components/dialogs/oobe_adaptive_dialog.js'; + +import {html, mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; + +import {LoginScreenBehavior, LoginScreenBehaviorInterface} from '../../components/behaviors/login_screen_behavior.js'; +import {OobeDialogHostBehavior} from '../../components/behaviors/oobe_dialog_host_behavior.js'; +import {OobeI18nBehavior, OobeI18nBehaviorInterface} from '../../components/behaviors/oobe_i18n_behavior.js'; + +/** + * @constructor + * @extends {PolymerElement} + * @implements {LoginScreenBehaviorInterface} + * @implements {OobeI18nBehaviorInterface} + */ +const PlaceholderScreenElementBase = mixinBehaviors( + [OobeI18nBehavior, OobeDialogHostBehavior, LoginScreenBehavior], + PolymerElement); + +/** + * @polymer + */ +class PlaceholderScreen extends PlaceholderScreenElementBase { + static get is() { + return 'placeholder-element'; + } + + static get template() { + return html`{__html_template__}`; + } + + static get properties() { + return {}; + } + + /** @override */ + ready() { + super.ready(); + this.initializeLoginScreen('PlaceholderScreen'); + } + + /** + * Next button click handler. + * @private + */ + onNextClicked_() { + this.userActed('next'); + } + + /** + * Back button click handler. + * @private + */ + onBackClicked_() { + this.userActed('back'); + } +} + +customElements.define(PlaceholderScreen.is, PlaceholderScreen);
diff --git a/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html b/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html index 2b88f950..815535c 100644 --- a/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html +++ b/chrome/browser/resources/chromeos/login/screens/common/theme_selection.html
@@ -26,7 +26,7 @@ </style> <oobe-adaptive-dialog id="themeSelectionDialog" role="presentation" for-step="overview" aria-live="polite"> - <iron-icon slot="icon" icon="oobe-32:stars"></iron-icon> + <iron-icon slot="icon" icon="oobe-32:theme-light"></iron-icon> <h1 slot="title" id="theme-selection-title"> [[i18nDynamic(locale, 'themeSelectionScreenTitle')]] </h1>
diff --git a/chrome/browser/resources/device_log_ui/device_log_ui.css b/chrome/browser/resources/device_log_ui/device_log_ui.css index 470aa69..170e2c1 100644 --- a/chrome/browser/resources/device_log_ui/device_log_ui.css +++ b/chrome/browser/resources/device_log_ui/device_log_ui.css
@@ -27,13 +27,14 @@ margin-inline-end: 8px; } +#log-checkbox-container, label { align-items: center; display: inline-flex; - vertical-align: middle; } #log-level-select { + margin: 0 3px; padding: 0 5px; }
diff --git a/chrome/browser/resources/device_log_ui/device_log_ui.html b/chrome/browser/resources/device_log_ui/device_log_ui.html index 8898224b..88ee49db 100644 --- a/chrome/browser/resources/device_log_ui/device_log_ui.html +++ b/chrome/browser/resources/device_log_ui/device_log_ui.html
@@ -22,7 +22,7 @@ <div id="header"> <span>$i18n{autoRefreshText}</span> </div> - <div> + <div id="log-checkbox-container"> <button id="log-refresh">$i18n{logRefreshText}</button> <button id="log-clear">$i18n{logClearText}</button> <span>$i18n{logLevelLabel}</span>
diff --git a/chrome/browser/resources/memory_internals/memory_internals.ts b/chrome/browser/resources/memory_internals/memory_internals.ts index 0ec479cd..16d23661 100644 --- a/chrome/browser/resources/memory_internals/memory_internals.ts +++ b/chrome/browser/resources/memory_internals/memory_internals.ts
@@ -20,10 +20,6 @@ chrome.send('saveDump'); } -function reportProcess(pid: number) { - chrome.send('reportProcess', [pid]); -} - function startProfiling(pid: number) { chrome.send('startProfiling', [pid]); } @@ -72,8 +68,7 @@ const button = document.createElement('button'); if (profiled) { - button.innerText = '\uD83D\uDC1E Report'; - button.onclick = () => reportProcess(procId); + button.innerText = 'Profiling...'; } else { button.innerText = '\u2600 Start profiling'; button.onclick = () => startProfiling(procId);
diff --git a/chrome/browser/resources/settings/chromeos/device_page/audio.html b/chrome/browser/resources/settings/chromeos/device_page/audio.html index 1d916af..20b45ff 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/audio.html +++ b/chrome/browser/resources/settings/chromeos/device_page/audio.html
@@ -204,4 +204,9 @@ </div> </div> </div> + <settings-toggle-button hidden$="[[!systemSoundsEnabled_]]" + id="chargingSoundsToggle" pref="{{prefs.ash.charging_sounds.enabled}}" + label="$i18n{chargingSoundsLabel}" + deep-link-focus-id$="[[Setting.kChargingSounds]]"> + </settings-toggle-button> </template>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/audio.ts b/chrome/browser/resources/settings/chromeos/device_page/audio.ts index 54bc989..7568243 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/audio.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/audio.ts
@@ -14,12 +14,16 @@ import '../icons.html.js'; import '../settings_shared.css.js'; +import {PrefsMixin} from 'chrome://resources/cr_components/settings_prefs/prefs_mixin.js'; import {CrSliderElement} from 'chrome://resources/cr_elements/cr_slider/cr_slider.js'; import {I18nMixin} from 'chrome://resources/cr_elements/i18n_mixin.js'; import {assert} from 'chrome://resources/js/assert_ts.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {DeepLinkingMixin} from '../deep_linking_mixin.js'; import {AudioDevice, AudioDeviceType, AudioEffectState, AudioSystemProperties, AudioSystemPropertiesObserverReceiver, MuteState} from '../mojom-webui/cros_audio_config.mojom-webui.js'; +import {Setting} from '../mojom-webui/setting.mojom-webui.js'; import {routes} from '../os_settings_routes.js'; import {RouteObserverMixin} from '../route_observer_mixin.js'; import {Route} from '../router.js'; @@ -33,7 +37,8 @@ return Math.max(0, Math.min(percent, 100)); } -const SettingsAudioElementBase = RouteObserverMixin(I18nMixin(PolymerElement)); +const SettingsAudioElementBase = + DeepLinkingMixin(PrefsMixin(RouteObserverMixin(I18nMixin(PolymerElement)))); const VOLUME_ICON_OFF_LEVEL = 0; // TODO(b/271871947): Match volume icon logic to QS revamp sliders. // Matches level calculated in unified_volume_view.cc. @@ -82,6 +87,24 @@ outputVolume_: { type: Number, }, + + systemSoundsEnabled_: { + type: Boolean, + value() { + return loadTimeData.getBoolean('areSystemSoundsEnabled'); + }, + readOnly: true, + }, + + /** + * Used by DeepLinkingMixin to focus this page's deep links. + */ + supportedSettingIds: { + type: Object, + value: () => new Set<Setting>([ + Setting.kChargingSounds, + ]), + }, }; } @@ -94,6 +117,7 @@ private isNoiseCancellationEnabled_: boolean; private isNoiseCancellationSupported_: boolean; private outputVolume_: number; + private systemSoundsEnabled_: boolean; constructor() { super();
diff --git a/chrome/browser/resources/settings/chromeos/device_page/device_page.html b/chrome/browser/resources/settings/chromeos/device_page/device_page.html index cff9054c..d98bfec 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/device_page.html +++ b/chrome/browser/resources/settings/chromeos/device_page/device_page.html
@@ -145,7 +145,8 @@ </template> <template is="dom-if" route-path="/audio"> <os-settings-subpage page-title="$i18n{audioTitle}"> - <settings-audio show-audio-info="[[showAudioInfo_]]"></settings-audio> + <settings-audio prefs="{{prefs}}" show-audio-info="[[showAudioInfo_]]"> + </settings-audio> </os-settings-subpage> </template> <template is="dom-if" route-path="/storage">
diff --git a/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_settings_provider.ts b/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_settings_provider.ts index 5ff7021..be7fdae 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_settings_provider.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_settings_provider.ts
@@ -4,7 +4,7 @@ import {assert} from 'chrome://resources/js/assert_ts.js'; -import {InputDeviceSettingsProviderInterface, Keyboard, KeyboardObserverInterface, KeyboardSettings, Mouse, MouseObserverInterface, MouseSettings, PointingStick, PointingStickObserverInterface, PointingStickSettings, Touchpad, TouchpadObserverInterface, TouchpadSettings} from './input_device_settings_types.js'; +import {InputDeviceSettingsProviderInterface, Keyboard, KeyboardObserverInterface, KeyboardSettings, MetaKey, ModifierKey, Mouse, MouseObserverInterface, MouseSettings, PointingStick, PointingStickObserverInterface, PointingStickSettings, Touchpad, TouchpadObserverInterface, TouchpadSettings} from './input_device_settings_types.js'; /** * @fileoverview @@ -124,6 +124,22 @@ return this.methods.resolveMethod('fakePointingSticks'); } + restoreDefaultKeyboardModifierRemappings(id: number): void { + const keyboards = this.methods.getResult('fakeKeyboards'); + for (const keyboard of keyboards) { + if (keyboard.id === id) { + keyboard.settings.modifierRemappings = + keyboard.metaKey === MetaKey.kCommand ? { + [ModifierKey.kControl]: ModifierKey.kMeta, + [ModifierKey.kMeta]: ModifierKey.kControl, + } : + {}; + } + } + this.methods.setResult('fakeKeyboards', keyboards); + this.notifyKeboardListUpdated(); + } + setKeyboardSettings(id: number, settings: KeyboardSettings): void { const keyboards = this.methods.getResult('fakeKeyboards'); for (const keyboard of keyboards) { @@ -166,8 +182,11 @@ notifyKeboardListUpdated(): void { const keyboards = this.methods.getResult('fakeKeyboards'); + // Make a deep copy to notify the functions observing keyboard settings. + const keyboardsClone = + !keyboards ? keyboards : JSON.parse(JSON.stringify(keyboards)); for (const observer of this.keyboardObservers) { - observer.onKeyboardListUpdated(keyboards); + observer.onKeyboardListUpdated(keyboardsClone); } }
diff --git a/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts b/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts index 07dfa31..c41bd696 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts
@@ -73,6 +73,7 @@ interface FakeInputDeviceSettingsProviderInterface extends InputDeviceSettingsProviderTypes.InputDeviceSettingsProviderInterface { + RestoreDefaultKeyboardModifierRemappings(id: number): void; setKeyboardSettings(id: number, settings: KeyboardSettings): void; setMouseSettings(id: number, settings: MouseSettings): void; setTouchpadSettings(id: number, settings: TouchpadSettings): void;
diff --git a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts index 9a840e6..2700b9f3 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/per_device_keyboard_remap_keys.ts
@@ -320,13 +320,8 @@ } restoreDefaults(): void { - // When defaults are restored, set isInitialized to false while the - // prefs are being updated. Then, once prefs are all done being updated - // back to defaults, make sure onSettingsUpdated is called. - this.isInitialized = false; - this.defaultInitializePrefs(); - this.isInitialized = true; - this.onSettingsChanged(); + this.inputDeviceSettingsProvider.restoreDefaultKeyboardModifierRemappings( + this.keyboardId); } private setRemappedKey(originalKey: ModifierKey): void {
diff --git a/chrome/browser/resources/settings/chromeos/lazy_load.ts b/chrome/browser/resources/settings/chromeos/lazy_load.ts index 191ef03..af5b707 100644 --- a/chrome/browser/resources/settings/chromeos/lazy_load.ts +++ b/chrome/browser/resources/settings/chromeos/lazy_load.ts
@@ -130,6 +130,7 @@ export {SettingsMultideviceFeatureItemElement} from './multidevice_page/multidevice_feature_item.js'; export {SettingsMultideviceFeatureToggleElement} from './multidevice_page/multidevice_feature_toggle.js'; export {SettingsMultideviceSmartlockItemElement} from './multidevice_page/multidevice_smartlock_item.js'; +export {SettingsMultideviceSubpageElement} from './multidevice_page/multidevice_subpage.js'; export {SettingsMultideviceTaskContinuationDisabledLinkElement} from './multidevice_page/multidevice_task_continuation_disabled_link.js'; export {SettingsMultideviceTaskContinuationItemElement} from './multidevice_page/multidevice_task_continuation_item.js'; export {SettingsMultideviceWifiSyncDisabledLinkElement} from './multidevice_page/multidevice_wifi_sync_disabled_link.js'; @@ -171,6 +172,7 @@ export {OsSyncBrowserProxy, OsSyncBrowserProxyImpl, OsSyncPrefs} from './os_people_page/os_sync_browser_proxy.js'; export {FingerprintSetupStep, SettingsSetupFingerprintDialogElement} from './os_people_page/setup_fingerprint_dialog.js'; export {PrinterListEntry, PrinterType} from './os_printing_page/cups_printer_types.js'; +export {PrinterSettingsUserAction} from './os_printing_page/cups_printers.js'; export {CupsPrintersBrowserProxy, CupsPrintersBrowserProxyImpl, PrinterSetupResult, PrintServerResult} from './os_printing_page/cups_printers_browser_proxy.js'; export {SettingsCupsPrintersEntryElement} from './os_printing_page/cups_printers_entry.js'; export {CupsPrintersEntryManager} from './os_printing_page/cups_printers_entry_manager.js';
diff --git a/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.html b/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.html index 46b952fe..3d59df9 100644 --- a/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.html +++ b/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.html
@@ -97,6 +97,10 @@ eol-offer-section { margin-top: 20px; } + + :host-context(.revamp-wayfinding-enabled) os-settings-section:not([active]) { + display: none; + } </style> <template is="dom-if" if="[[showBasicPage_( currentRoute_, hasExpandedSection_)]]">
diff --git a/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.ts b/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.ts index 722ff68..21247d9 100644 --- a/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.ts +++ b/chrome/browser/resources/settings/chromeos/main_page_container/main_page_container.ts
@@ -48,8 +48,7 @@ import {AboutPageBrowserProxyImpl} from '../os_about_page/about_page_browser_proxy.js'; import {AndroidAppsBrowserProxyImpl, AndroidAppsInfo} from '../os_apps_page/android_apps_browser_proxy.js'; import {OsPageAvailability} from '../os_page_availability.js'; -import {routes} from '../os_settings_routes.js'; -import {Route, Router} from '../router.js'; +import {isAdvancedRoute, isBasicRoute, Route, Router} from '../router.js'; import {getTemplate} from './main_page_container.html.js'; @@ -191,7 +190,7 @@ override currentRouteChanged(newRoute: Route, oldRoute?: Route) { this.currentRoute_ = newRoute; - if (routes.ADVANCED && routes.ADVANCED.contains(newRoute)) { + if (isAdvancedRoute(newRoute)) { this.advancedToggleExpanded = true; } @@ -209,9 +208,8 @@ super.currentRouteChanged(newRoute, oldRoute); } - override containsRoute(route: Route) { - return !route || routes.BASIC.contains(route) || - routes.ADVANCED.contains(route); + override containsRoute(route: Route|undefined) { + return !route || isBasicRoute(route) || isAdvancedRoute(route); } /** Stamp page in the DOM depending on page availability */ @@ -319,7 +317,7 @@ */ private showBasicPage_(currentRoute: Route, hasExpandedSection: boolean): boolean { - return !hasExpandedSection || routes.BASIC.contains(currentRoute); + return !hasExpandedSection || isBasicRoute(currentRoute); } /** @@ -329,9 +327,8 @@ private showAdvancedPage_( currentRoute: Route, hasExpandedSection: boolean, advancedToggleExpanded: boolean): boolean { - return hasExpandedSection ? - (routes.ADVANCED && routes.ADVANCED.contains(currentRoute)) : - advancedToggleExpanded; + return hasExpandedSection ? isAdvancedRoute(currentRoute) : + advancedToggleExpanded; } private showAdvancedSettings_(visibility?: boolean): boolean {
diff --git a/chrome/browser/resources/settings/chromeos/main_page_mixin.ts b/chrome/browser/resources/settings/chromeos/main_page_mixin.ts index 208baa88..23d7d89 100644 --- a/chrome/browser/resources/settings/chromeos/main_page_mixin.ts +++ b/chrome/browser/resources/settings/chromeos/main_page_mixin.ts
@@ -11,7 +11,7 @@ import {ensureLazyLoaded} from './ensure_lazy_loaded.js'; import {SettingsIdleLoadElement} from './os_settings_page/settings_idle_load.js'; import {RouteObserverMixin, RouteObserverMixinInterface} from './route_observer_mixin.js'; -import {Route, Router} from './router.js'; +import {isAdvancedRoute, Route, Router} from './router.js'; /** * A categorization of every possible Settings URL, necessary for implementing @@ -49,11 +49,6 @@ return RouteState.SECTION; } -function isAdvancedRoute(route: Route): boolean { - const routes = Router.getInstance().routes; - return routes.ADVANCED && routes.ADVANCED.contains(route); -} - const ALL_STATES = new Set([ RouteState.DIALOG, RouteState.SECTION, @@ -188,7 +183,7 @@ /** * Simple helper method to display a page/section depending on if the - * Revamp Wayfinding feature flag is enabled. + * `OsSettingsRevampWayfinding` is enabled. */ private activatePage(route: Route): void { if (isRevampWayfindingEnabled()) { @@ -209,8 +204,8 @@ * Queries the shadow DOM for the respective os-settings-section element * for the given |route| and marks it as active. * - * NOTE: This method should only be used when the Revamp Wayfinding - * feature flag is enabled. + * NOTE: This method should only be used when the + * `OsSettingsRevampWayfinding` feature flag is enabled. */ private async showPage(route: Route): Promise<void> { const page = await this.ensureSectionForRoute_(route);
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.ts b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.ts index 898f330..228c084 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.ts +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_subpage.ts
@@ -36,7 +36,7 @@ import {MultiDeviceFeatureMixin} from './multidevice_feature_mixin.js'; import {getTemplate} from './multidevice_subpage.html.js'; -interface SettingsMultideviceSubpageElement { +export interface SettingsMultideviceSubpageElement { $: { forgetDeviceDialog: CrDialogElement, }; @@ -45,7 +45,7 @@ const SettingsMultideviceSubpageElementBase = MultiDeviceFeatureMixin( DeepLinkingMixin(RouteObserverMixin(PolymerElement))); -class SettingsMultideviceSubpageElement extends +export class SettingsMultideviceSubpageElement extends SettingsMultideviceSubpageElementBase { static get is() { return 'settings-multidevice-subpage' as const;
diff --git a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts index cdbbc5b..0802c337 100644 --- a/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts +++ b/chrome/browser/resources/settings/chromeos/os_about_page/os_about_page.ts
@@ -40,7 +40,7 @@ import {recordSettingChange} from '../metrics_recorder.js'; import {Setting} from '../mojom-webui/setting.mojom-webui.js'; import {routes} from '../os_settings_routes.js'; -import {Route, Router} from '../router.js'; +import {isAboutRoute, Route, Router} from '../router.js'; import {AboutPageBrowserProxy, AboutPageBrowserProxyImpl, AboutPageUpdateInfo, BrowserChannel, browserChannelToI18nId, RegulatoryInfo, TpmFirmwareUpdateStatusChangedEvent, UpdateStatus, UpdateStatusChangedEvent} from './about_page_browser_proxy.js'; import {getTemplate} from './os_about_page.html.js'; @@ -348,8 +348,8 @@ }); } - override containsRoute(route: Route) { - return !route || routes.ABOUT.contains(route); + override containsRoute(route: Route|undefined) { + return !route || isAboutRoute(route); } private startListening_() {
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.html b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.html index c0cb52c..edf0de3 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.html +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.html
@@ -28,4 +28,8 @@ </div> </div> </div> + <template is="dom-if" if="[[isManaged_(app, permissionType)]]"> + <cr-policy-indicator indicator-type="devicePolicy"> + </cr-policy-indicator> + </template> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.ts b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.ts index b2f7ec4..08e4049 100644 --- a/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.ts +++ b/chrome/browser/resources/settings/chromeos/os_apps_page/app_management_page/read_only_permission_item.ts
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'chrome://resources/cr_elements/policy/cr_policy_indicator.js'; + import {App, TriState} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js'; import {PermissionTypeIndex} from 'chrome://resources/cr_components/app_management/permission_constants.js'; import {getPermission, getPermissionValueAsTriState} from 'chrome://resources/cr_components/app_management/util.js'; @@ -97,6 +99,19 @@ return this.i18n('appManagementPermissionAsk'); } } + + private isManaged_( + app: App|undefined, + permissionType: PermissionTypeIndex|undefined): boolean { + if (app === undefined || permissionType === undefined) { + return false; + } + + const permission = getPermission(app, permissionType); + assert(permission); + + return permission.isManaged; + } } declare global {
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/google_drive_subpage.ts b/chrome/browser/resources/settings/chromeos/os_files_page/google_drive_subpage.ts index d2a26a9..069f5670 100644 --- a/chrome/browser/resources/settings/chromeos/os_files_page/google_drive_subpage.ts +++ b/chrome/browser/resources/settings/chromeos/os_files_page/google_drive_subpage.ts
@@ -80,6 +80,16 @@ * is updated. */ totalPinnedSize_: String, + + /** + * Ensures the showSpinner variable is bound to the parent element and + * updates are propagated as the spinner element is in the parent element. + */ + showSpinner: { + type: Boolean, + notify: true, + value: false, + }, }; } @@ -125,6 +135,11 @@ private totalPinnedSize_: string|null = null; /** + * Whether to show the spinner in the top right of the settings page. + */ + private showSpinner: boolean = false; + + /** * Returns the browser proxy page handler (to invoke functions). */ get pageHandler() { @@ -193,6 +208,16 @@ status.requiredSpace !== this.bulkPinningStatus_?.requiredSpace) { this.bulkPinningStatus_ = status; } + + let requiredSpace: number; + try { + requiredSpace = parseInt(status?.requiredSpace); + } catch (e) { + console.error('Could not parse required space', e); + return; + } + + this.showSpinner = (status?.stage === Stage.kSyncing && requiredSpace > 0); } /**
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.html b/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.html index 3ffc6a25..8150ce5 100644 --- a/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.html +++ b/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.html
@@ -9,7 +9,8 @@ </cr-button> </div> <template is="dom-if" if="[[connected_]]"> - <cr-link-row class="hr" + <cr-link-row id="openOneDriveFolder" + class="hr" on-click="onOpenOneDriveFolderClick_" label="$i18n{openOneDriveFolder}" external>
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.ts b/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.ts index 2d5dee7d..873e2dba 100644 --- a/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.ts +++ b/chrome/browser/resources/settings/chromeos/os_files_page/one_drive_subpage.ts
@@ -77,25 +77,30 @@ return this.i18n(connected ? 'oneDriveDisconnect' : 'oneDriveConnect'); } - private onOpenOneDriveFolderClick_(): void { - // TODO(jboulic): Implement open OneDrive folder. - } - private async onConnectDisconnectButtonClick_(): Promise<void> { if (this.connected_) { - const {success} = + const {success}: {success: boolean} = await this.oneDriveProxy_.handler.disconnectFromOneDrive(); if (!success) { console.error('Disconnecting from OneDrive failed'); } } else { - const {success} = await this.oneDriveProxy_.handler.connectToOneDrive(); + const {success}: {success: boolean} = + await this.oneDriveProxy_.handler.connectToOneDrive(); if (!success) { console.error('Connecting to OneDrive failed'); } } // The UI is updated by listening to `onODFSMountOrUnmount`. } + + private async onOpenOneDriveFolderClick_(): Promise<void> { + const {success}: {success: boolean} = + await this.oneDriveProxy_.handler.openOneDriveFolder(); + if (!success) { + console.error('Opening OneDrive folder failed'); + } + } } declare global {
diff --git a/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html b/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html index c238f6d2..4c4b9233 100644 --- a/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html +++ b/chrome/browser/resources/settings/chromeos/os_files_page/os_files_page.html
@@ -45,8 +45,12 @@ </os-settings-subpage> </template> <template is="dom-if" route-path="/googleDrive"> - <os-settings-subpage page-title="$i18n{googleDriveLabel}"> - <settings-google-drive-subpage prefs="{{prefs}}"> + <os-settings-subpage + page-title="$i18n{googleDriveLabel}" + show-spinner="[[showSpinner_]]"> + <settings-google-drive-subpage + prefs="{{prefs}}" + show-spinner="{{showSpinner_}}"> </settings-google-drive-subpage> </os-settings-subpage> </template>
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.ts b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.ts index 98db9ba..7b5e251 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.ts +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers.ts
@@ -56,6 +56,31 @@ import {CupsPrintersEntryManager} from './cups_printers_entry_manager.js'; import {SettingsCupsAddPrinterDialogElement} from './cups_settings_add_printer_dialog.js'; +/** + * Enumeration of the user actions that can be taken on the Printer settings + * page. + * This enum is tied directly to a UMA enum defined in + * //tools/metrics/histograms/enums.xml, and should always reflect it (do not + * change one without changing the other). + * These values are persisted to logs. Entries should not be renumbered and + * numeric values should never be reused. + * @enum {number} + */ +export enum PrinterSettingsUserAction { + ADD_PRINTER_MANUALLY = 0, + SAVE_PRINTER = 1, + EDIT_PRINTER = 2, + REMOVE_PRINTER = 3, + CLICK_HELP_LINK = 4, +} + +export function recordPrinterSettingsUserAction( + userAction: PrinterSettingsUserAction) { + chrome.metricsPrivate.recordEnumerationValue( + 'Printing.CUPS.SettingsUserAction', userAction, + Object.keys(PrinterSettingsUserAction).length); +} + const SettingsCupsPrintersElementBase = mixinBehaviors( [ @@ -429,6 +454,8 @@ private onAddPrinterClick_(): void { this.$.addPrinterDialog.open(); + recordPrinterSettingsUserAction( + PrinterSettingsUserAction.ADD_PRINTER_MANUALLY); } private onAddPrinterDialogClose_(): void {
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts index 09cb3a4..14170a4 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_printers_entry.ts
@@ -18,6 +18,7 @@ import {PolymerElement} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {PrinterListEntry, PrinterType} from './cups_printer_types.js'; +import {PrinterSettingsUserAction, recordPrinterSettingsUserAction} from './cups_printers.js'; import {getTemplate} from './cups_printers_entry.html.js'; import {computePrinterState, PrinterState, PrinterStatusReason, STATUS_REASON_STRING_KEY_MAP} from './printer_status.js'; @@ -123,6 +124,7 @@ detail: {item: this.printerEntry}, }); this.dispatchEvent(queryDiscoveredPrinterEvent); + recordPrinterSettingsUserAction(PrinterSettingsUserAction.SAVE_PRINTER); } private onAddAutomaticPrinterClick_(): void { @@ -132,6 +134,7 @@ detail: {item: this.printerEntry}, }); this.dispatchEvent(addAutomaticPrinterEvent); + recordPrinterSettingsUserAction(PrinterSettingsUserAction.SAVE_PRINTER); } private onAddServerPrinterClick_(): void {
diff --git a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts index 31da9c0..30f060a 100644 --- a/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts +++ b/chrome/browser/resources/settings/chromeos/os_printing_page/cups_saved_printers.ts
@@ -25,6 +25,7 @@ import {matchesSearchTerm, sortPrinters} from './cups_printer_dialog_util.js'; import {PrinterListEntry} from './cups_printer_types.js'; +import {PrinterSettingsUserAction, recordPrinterSettingsUserAction} from './cups_printers.js'; import {CupsPrinterInfo, CupsPrintersBrowserProxy, CupsPrintersBrowserProxyImpl} from './cups_printers_browser_proxy.js'; import {CupsPrintersEntryListMixin} from './cups_printers_entry_list_mixin.js'; import {getTemplate} from './cups_saved_printers.html.js'; @@ -271,6 +272,7 @@ }); this.dispatchEvent(editCupsPrinterDetailsEvent); this.closeActionMenu_(); + recordPrinterSettingsUserAction(PrinterSettingsUserAction.EDIT_PRINTER); } private onRemoveClick_(): void { @@ -280,6 +282,7 @@ this.activePrinter = null; this.activePrinterListEntryIndex_ = -1; this.closeActionMenu_(); + recordPrinterSettingsUserAction(PrinterSettingsUserAction.REMOVE_PRINTER); } private onShowMoreClick_(): void {
diff --git a/chrome/browser/resources/settings/chromeos/os_settings.ts b/chrome/browser/resources/settings/chromeos/os_settings.ts index dc90dc6..030afe8 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings.ts +++ b/chrome/browser/resources/settings/chromeos/os_settings.ts
@@ -181,7 +181,7 @@ export {OsSettingsMainElement} from './os_settings_main/os_settings_main.js'; export {OsSettingsMenuElement} from './os_settings_menu/os_settings_menu.js'; export {OsSettingsSectionElement} from './os_settings_page/os_settings_section.js'; -export {OsSettingsRoutes, routes} from './os_settings_routes.js'; +export {createRoutesForTesting, OsSettingsRoutes, routes} from './os_settings_routes.js'; export {OsSettingsSearchBoxElement} from './os_settings_search_box/os_settings_search_box.js'; export {OsSettingsSearchBoxBrowserProxyImpl} from './os_settings_search_box/os_settings_search_box_browser_proxy.js'; export {OsSettingsHatsBrowserProxy, OsSettingsHatsBrowserProxyImpl} from './os_settings_ui/os_settings_hats_browser_proxy.js';
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.ts b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.ts index 90218d0..2349ab2 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.ts +++ b/chrome/browser/resources/settings/chromeos/os_settings_menu/os_settings_menu.ts
@@ -21,9 +21,8 @@ import * as routesMojom from '../mojom-webui/routes.mojom-webui.js'; import {OsPageAvailability} from '../os_page_availability.js'; -import {routes} from '../os_settings_routes.js'; import {RouteObserverMixin} from '../route_observer_mixin.js'; -import {Route, Router} from '../router.js'; +import {isAdvancedRoute, Route, Router} from '../router.js'; import {getTemplate} from './os_settings_menu.html.js'; @@ -111,8 +110,7 @@ Router.getInstance().getQueryParameters().get('search'); // If the route navigated to by a search result is in the advanced // section, the advanced menu will expand. - if (urlSearchQuery && routes.ADVANCED && - routes.ADVANCED.contains(newRoute)) { + if (urlSearchQuery && isAdvancedRoute(newRoute)) { this.advancedOpened = true; }
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_routes.ts b/chrome/browser/resources/settings/chromeos/os_settings_routes.ts index 6352eb7..1e978de 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_routes.ts +++ b/chrome/browser/resources/settings/chromeos/os_settings_routes.ts
@@ -220,7 +220,7 @@ /** * Creates Route objects for each path corresponding to CrOS settings content. */ -function createOsSettingsRoutes(): OsSettingsRoutes { +function createRoutes(): OsSettingsRoutes { const r: Partial<OsSettingsRoutes> = {}; const {Section, Subpage} = routesMojom; @@ -584,4 +584,5 @@ return r as OsSettingsRoutes; } -export const routes = createOsSettingsRoutes(); +export const createRoutesForTesting = createRoutes; +export const routes = createRoutes();
diff --git a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts index fadf3b73..4ff455ae3 100644 --- a/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts +++ b/chrome/browser/resources/settings/chromeos/os_settings_ui/os_settings_ui.ts
@@ -34,6 +34,7 @@ import {castExists} from '../assert_extras.js'; import {setGlobalScrollTarget} from '../common/global_scroll_target_mixin.js'; +import {isRevampWayfindingEnabled} from '../common/load_time_booleans.js'; import {recordClick, recordNavigation, recordPageBlur, recordPageFocus, recordSettingChange} from '../metrics_recorder.js'; import {convertPrefToSettingMetric} from '../metrics_utils.js'; import {createPageAvailability, OsPageAvailability} from '../os_page_availability.js'; @@ -293,6 +294,11 @@ // Clicks need to be captured because unlike focus/blur to the settings // window, a click's propagation can be stopped by child elements. window.addEventListener('click', recordClick, /*capture=*/ true); + + if (isRevampWayfindingEnabled()) { + // Add class which activates styles for the wayfinding update + document.body.classList.add('revamp-wayfinding-enabled'); + } } override disconnectedCallback() { @@ -399,7 +405,7 @@ const url = e.detail.selected; const path = new URL(url).pathname; const route = Router.getInstance().getRouteForPath(path); - assert(route, 'os-settings-menu has an entry with an invalid route.'); + assert(route, `os-settings-menu has an item with invalid route: ${path}`); this.activeRoute_ = route; if (this.isNarrow) {
diff --git a/chrome/browser/resources/settings/chromeos/router.ts b/chrome/browser/resources/settings/chromeos/router.ts index 0ec00f5..457e2a93 100644 --- a/chrome/browser/resources/settings/chromeos/router.ts +++ b/chrome/browser/resources/settings/chromeos/router.ts
@@ -12,6 +12,37 @@ export {Route}; /** + * @returns true if this route exists under the Advanced section. + * Note: Use the routes contained by the Router instance to ensure the routes + * are up-to-date (ie. in the case the routes are overriden in tests) + */ +export function isAdvancedRoute(route: Route): boolean { + const routes = Router.getInstance().routes; + return routes.ADVANCED && routes.ADVANCED.contains(route); +} + +/** + * @returns true if this route exists under the Basic section (not advanced + * section). + * Note: Use the routes contained by the Router instance to ensure the routes + * are up-to-date (ie. in the case the routes are overriden in tests) + */ +export function isBasicRoute(route: Route): boolean { + const routes = Router.getInstance().routes; + return routes.BASIC.contains(route); +} + +/** + * @returns true if this route exists under the About page + * Note: Use the routes contained by the Router instance to ensure the routes + * are up-to-date (ie. in the case the routes are overriden in tests) + */ +export function isAboutRoute(route: Route): boolean { + const routes = Router.getInstance().routes; + return routes.ABOUT.contains(route); +} + +/** * Regular expression that captures the leading slash, the content and the * trailing slash in three different groups. */
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.ts index 5012037..1c73a1d 100644 --- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.ts +++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_add_input.ts
@@ -46,10 +46,6 @@ assert(!this.submitDisabled); const rule = this.rule.trim(); this.appendPrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, rule); - this.dispatchEvent(new CustomEvent('add-exception', { - bubbles: true, - composed: true, - })); this.metricsProxy_.recordExceptionListAction( HighEfficiencyModeExceptionListAction.ADD); }
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_current_sites_list.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_current_sites_list.ts index b634febe..bde24b04 100644 --- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_current_sites_list.ts +++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_current_sites_list.ts
@@ -93,15 +93,11 @@ return index + 1; } - async submit() { + submit() { assert(!this.submitDisabled); this.selectedSites_.forEach(rule => { this.appendPrefListItem(TAB_DISCARD_EXCEPTIONS_PREF, rule); }); - this.dispatchEvent(new CustomEvent('add-exception', { - bubbles: true, - composed: true, - })); this.metricsProxy_.recordExceptionListAction( HighEfficiencyModeExceptionListAction.ADD); }
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html index 7d34d0c..cc8f6981 100644 --- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html +++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.html
@@ -73,12 +73,12 @@ </cr-lazy-render> <template is="dom-if" if="[[showAddDialog_]]" restamp> <tab-discard-exception-add-dialog prefs="{{prefs}}" - on-close="onAddDialogClose_" on-add-exception="onAddException_"> + on-close="onAddDialogClose_"> </tab-discard-exception-add-dialog> </template> <template is="dom-if" if="[[showTabbedAddDialog_]]" restamp> <tab-discard-exception-tabbed-add-dialog prefs="{{prefs}}" - on-close="onTabbedAddDialogClose_" on-add-exception="onAddException_"> + on-close="onTabbedAddDialogClose_"> </tab-discard-exception-tabbed-add-dialog> </template> <template is="dom-if" if="[[showEditDialog_]]" restamp>
diff --git a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts index 7c6f9b2..7132a64 100644 --- a/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts +++ b/chrome/browser/resources/settings/performance_page/tab_discard_exception_list.ts
@@ -140,11 +140,13 @@ } private getSiteList_() { - return this.siteList_.slice(0, TAB_DISCARD_EXCEPTIONS_OVERFLOW_SIZE); + return this.siteList_.slice(-TAB_DISCARD_EXCEPTIONS_OVERFLOW_SIZE) + .reverse(); } private getOverflowSiteList_() { - return this.siteList_.slice(TAB_DISCARD_EXCEPTIONS_OVERFLOW_SIZE); + return this.siteList_.slice(0, -TAB_DISCARD_EXCEPTIONS_OVERFLOW_SIZE) + .reverse(); } private onAddClick_() { @@ -189,10 +191,6 @@ this.showEditDialog_ = false; } - private onAddException_() { - this.overflowSiteListExpanded = true; - } - private onPrefsChanged_() { const newSites: TabDiscardExceptionEntry[] = []; for (const pref
diff --git a/chrome/browser/resources/settings/privacy_page/privacy_page.html b/chrome/browser/resources/settings/privacy_page/privacy_page.html index 51778a0..98b66911 100644 --- a/chrome/browser/resources/settings/privacy_page/privacy_page.html +++ b/chrome/browser/resources/settings/privacy_page/privacy_page.html
@@ -1117,6 +1117,13 @@ block-option-label="$i18n{storageAccessBlocked}" block-option-icon="settings:block"> </settings-category-default-radio-group> + <category-setting-exceptions + category="[[contentSettingsTypesEnum_.STORAGE_ACCESS]]" + block-header="$i18n{storageAccessBlockedExceptions}" + allow-header="$i18n{storageAccessAllowedExceptions}" + search-filter="[[searchFilter_]]" + read-only-list> + </category-setting-exceptions> </settings-subpage> </template> </template>
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.html b/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.html index dfc123f..fd77068 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.html +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.html
@@ -71,7 +71,7 @@ <cr-input slot="content" id="input" value="[[bookmark.title]]" class="sp-labelless-input" on-change="onInputChange_" on-blur="onInputChange_" - on-keypress="onInputKeyPress_" + on-keydown="onInputKeyDown_" aria-label="[[rowAriaLabel]]" aria-description="[[rowAriaDescription]]"> </cr-input>
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts index 1ceb1f2..5f3febe3 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmark_row.ts
@@ -242,8 +242,9 @@ * Triggers an input change event on enter. Extends default input behavior * which only triggers a change event if the value of the input has changed. */ - private onInputKeyPress_(event: KeyboardEvent) { + private onInputKeyDown_(event: KeyboardEvent) { if (event.key === 'Enter') { + event.stopPropagation(); this.onInputChange_(event); } }
diff --git a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts index 90b57850d..9246afb 100644 --- a/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts +++ b/chrome/browser/resources/side_panel/bookmarks/power_bookmarks_list.ts
@@ -42,7 +42,7 @@ import {PluralStringProxyImpl} from '//resources/js/plural_string_proxy.js'; import {listenOnce} from '//resources/js/util_ts.js'; import {IronListElement} from '//resources/polymer/v3_0/iron-list/iron-list.js'; -import {DomRepeatEvent, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {afterNextRender, DomRepeatEvent, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {ActionSource, SortOrder, ViewType} from './bookmarks.mojom-webui.js'; import {BookmarksApiProxy, BookmarksApiProxyImpl} from './bookmarks_api_proxy.js'; @@ -240,6 +240,7 @@ override connectedCallback() { super.connectedCallback(); + this.setAttribute('role', 'application'); listenOnce(this.$.powerBookmarksContainer, 'dom-change', () => { setTimeout(() => this.bookmarksApi_.showUi(), 0); }); @@ -691,9 +692,9 @@ this.push('activeFolderPath_', event.detail.bookmark); // Cancel search when changing active folder. this.$.searchField.setValue(''); - if (this.shownBookmarks_.length > 0) { + afterNextRender(this, () => { this.$.shownBookmarksIronList.focusItem(0); - } + }); } else { this.bookmarksApi_.openBookmark( event.detail.bookmark.id, this.activeFolderPath_.length, {
diff --git a/chrome/browser/resources/side_panel/customize_chrome/categories.html b/chrome/browser/resources/side_panel/customize_chrome/categories.html index 74722f5..e72a839 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/categories.html +++ b/chrome/browser/resources/side_panel/customize_chrome/categories.html
@@ -14,6 +14,11 @@ padding: 0 16px 32px; } + :host-context([chrome-refresh-2023]) cr-grid { + --cr-grid-gap: 8px; + padding: 0 var(--sp-card-inline-padding) 16px; + } + .tile { cursor: pointer; grid-column: span 2; @@ -70,16 +75,48 @@ text-align: center; } + :host-context([chrome-refresh-2023]) .label { + font-size: 11px; + font-weight: 400; + line-height: 16px; + } + .tile:nth-child(-n+4) { grid-column: span 3; + /* To result in an extra 5px horizontal gap between first 4 tiles. */ padding-inline-end: 2.5px; } + :host-context([chrome-refresh-2023]) .tile:nth-child(-n+4) { + /* To result in an extra 8px horizontal gap between first 4 tiles. */ + padding-inline-end: 4px; + } + + :host-context([chrome-refresh-2023]) .tile:nth-child(-n+4) { + /* To result in an extra 10px vertical gap between large and small tiles. */ + padding-block-end: 10px; + /* To result in an extra 8px vertical gap between first 4 tiles. */ + padding-block-start: 4px; + } + + :host-context([chrome-refresh-2023]) .tile:nth-child(-n+2) { + /* To result in an extra 8px vertical gap between first 4 tiles. */ + padding-block-end: 4px; + padding-block-start: 0; + } + .tile:nth-child(-n+4):nth-child(even) { padding-inline-end: 0; + /* To result in an extra 5px horizontal gap between first 4 tiles. */ padding-inline-start: 2.5px; } + :host-context([chrome-refresh-2023]) .tile:nth-child(-n+4):nth-child(even) { + padding-inline-end: 0; + /* To result in an extra 8px horizontal gap between first 4 tiles. */ + padding-inline-start: 4px; + } + .tile:nth-child(-n+4) .image-container { border-radius: 16px; } @@ -90,6 +127,12 @@ padding-top: 12px; } + :host-context([chrome-refresh-2023]) .tile:nth-child(-n+4) .label { + font-size: 12px; + line-height: 16px; + padding-top: 8px; + } + .image-container { border-radius: 12px; } @@ -100,6 +143,10 @@ padding-top: 7px; } + :host-context([chrome-refresh-2023]) .label { + padding-top: 4px; + } + .icon-external { --cr-icon-size: 13px; display: inline-block;
diff --git a/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn b/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn index 392d0fee9..3e244399 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn +++ b/chrome/browser/resources/side_panel/customize_chrome/icons/BUILD.gn
@@ -12,6 +12,7 @@ input_files = [ "chrome_web_store.svg", "corner_new_tab_page.svg", + "gm3_mini_new_tab_page.svg", "image.svg", "mini_new_tab_page.svg", "reset.svg",
diff --git a/chrome/browser/resources/side_panel/customize_chrome/icons/gm3_mini_new_tab_page.svg b/chrome/browser/resources/side_panel/customize_chrome/icons/gm3_mini_new_tab_page.svg new file mode 100644 index 0000000..92959967 --- /dev/null +++ b/chrome/browser/resources/side_panel/customize_chrome/icons/gm3_mini_new_tab_page.svg
@@ -0,0 +1 @@ +<svg width="240" height="126" viewBox="0 0 240 126" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#a)"><path fill="#fff" d="M0 0h240v126H0z"/><path d="M0 0h240v40H0V0Z" fill="#D3E3FD"/><rect x="6" y="6" width="28" height="28" rx="10" fill="#ECF3FE"/><g clip-path="url(#b)"><path d="m24 19-4 4-4-4 1.06-1.06L20 20.88l2.94-2.94L24 19Z" fill="#041E49"/></g><path fill="#fff" d="M0 86h240v40H0zm0-38a8 8 0 0 1 8-8h224a8 8 0 0 1 8 8v38H0V48Z"/><g clip-path="url(#c)"><path d="M22 69.083 15.917 63 22 56.917l1.23 1.229-3.98 3.979h8.833v1.75H19.25l3.98 3.98L22 69.082Z" fill="#474747"/></g><g clip-path="url(#d)"><path d="m58 69.083-1.23-1.229 3.98-3.979h-8.833v-1.75h8.833l-3.98-3.98L58 56.918 64.083 63 58 69.083Z" fill="#474747"/></g><g clip-path="url(#e)"><path d="M93.98 69.167c-1.71 0-3.168-.598-4.376-1.792-1.194-1.208-1.791-2.667-1.791-4.375 0-1.708.597-3.16 1.791-4.354 1.209-1.209 2.667-1.813 4.375-1.813.93 0 1.792.195 2.584.584a6.203 6.203 0 0 1 2.041 1.541v-2.125h1.584v5.25h-5.25V60.5h2.708a4.378 4.378 0 0 0-3.667-1.938c-1.236 0-2.285.431-3.146 1.292-.86.861-1.291 1.91-1.291 3.146s.43 2.285 1.291 3.146c.861.86 1.91 1.291 3.146 1.291 1.153 0 2.14-.374 2.959-1.124a4.404 4.404 0 0 0 1.416-2.813h1.771c-.125 1.597-.778 2.944-1.958 4.042-1.167 1.083-2.563 1.625-4.188 1.625Z" fill="#474747"/></g><path d="M120 63c0-7.18 5.82-13 13-13h107v26H133c-7.18 0-13-5.82-13-13Z" fill="#FDFCFB"/><path d="M120 63c0-7.18 5.82-13 13-13h107v26H133c-7.18 0-13-5.82-13-13Z" fill="#6991D6" fill-opacity=".12"/><path d="M40 16c0-5.523 4.477-10 10-10h190v34H40V16Z" fill="#fff"/><path fill-rule="evenodd" clip-rule="evenodd" d="M40 28v12H28c6.627 0 12-5.373 12-12Z" fill="#fff"/><g clip-path="url(#f)"><g clip-path="url(#g)"><path d="M53.25 20c0 .76.27 1.4.81 1.94s1.19.81 1.94.81 1.4-.27 1.94-.81.81-1.19.81-1.94-.27-1.4-.81-1.94-1.19-.81-1.94-.81-1.4.27-1.94.81-.81 1.19-.81 1.94ZM56 24.25c.15 0 .3 0 .44-.02.14-.01.28-.04.42-.07L55.22 27c-1.76-.2-3.24-.95-4.43-2.26C49.6 23.42 49 21.86 49 20.05c0-.49.05-.96.14-1.42.09-.47.23-.91.42-1.33l2.8 4.85c.36.63.86 1.14 1.5 1.52.64.38 1.35.58 2.14.58Zm0-8.4c-.93 0-1.76.27-2.48.82-.72.54-1.23 1.23-1.51 2.07l-1.65-2.84c.64-.86 1.45-1.55 2.42-2.07.98-.53 2.05-.79 3.22-.79 1.17 0 2.22.26 3.19.77.97.5 1.77 1.18 2.42 2.03h-5.6l-.01.01Zm6.41 1.4c.2.43.34.88.44 1.35.1.47.16.95.16 1.45 0 1.81-.59 3.37-1.79 4.67-1.18 1.31-2.64 2.06-4.37 2.27l2.8-4.85c.18-.3.31-.63.4-.98.1-.36.16-.74.16-1.12 0-.55-.1-1.06-.3-1.52-.19-.48-.45-.9-.79-1.28h3.29v.01Z" fill="#1F1F1F"/></g></g><path fill="#E1E3E1" d="M0 86h240v-1H0z"/></g><defs><clipPath id="a"><path fill="#fff" d="M0 0h240v126H0z"/></clipPath><clipPath id="b"><path fill="#fff" transform="rotate(-90 20 8)" d="M0 0h16v16H0z"/></clipPath><clipPath id="c"><path fill="#fff" transform="translate(12 53)" d="M0 0h20v20H0z"/></clipPath><clipPath id="d"><path fill="#fff" transform="translate(48 53)" d="M0 0h20v20H0z"/></clipPath><clipPath id="e"><path fill="#fff" transform="translate(84 53)" d="M0 0h20v20H0z"/></clipPath><clipPath id="f"><path fill="#fff" transform="translate(48 12)" d="M0 0h16v16H0z"/></clipPath><clipPath id="g"><path fill="#fff" transform="translate(48 12)" d="M0 0h16v16H0z"/></clipPath></defs></svg> \ No newline at end of file
diff --git a/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html b/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html index bcb1330..1050455 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html +++ b/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.html
@@ -56,7 +56,7 @@ border-radius: 8px; box-shadow: var(--cr-elevation-2); height: 126px; - margin-bottom: 0; + margin: 16px; width: 240px; z-index: 1; } @@ -112,9 +112,16 @@ <div class="snapshot-container" theme-type="classicChrome"> <div class="image-background image" id="classicChromeBackground"> - <img id="miniNewTabPage" src="icons/mini_new_tab_page.svg" - aria-labelledby="classicChromeThemeTitle"> - </img> + <template is="dom-if" if="[[!chromeRefresh2023Enabled_]]"> + <img id="miniNewTabPage" src="icons/mini_new_tab_page.svg" + aria-labelledby="classicChromeThemeTitle"> + </img> + </template> + <template is="dom-if" if="[[chromeRefresh2023Enabled_]]"> + <img src="icons/gm3_mini_new_tab_page.svg" + aria-labelledby="classicChromeThemeTitle"> + </img> + </template> <div class="overlay"></div> <paper-ripple></paper-ripple> </div>
diff --git a/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.ts b/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.ts index 95f9ae58..dc083a3f 100644 --- a/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.ts +++ b/chrome/browser/resources/side_panel/customize_chrome/theme_snapshot.ts
@@ -32,6 +32,10 @@ static get properties() { return { + chromeRefresh2023Enabled_: { + type: Boolean, + }, + theme_: Object, themeType_: { @@ -41,12 +45,13 @@ }; } + private chromeRefresh2023Enabled_: boolean; private theme_: Theme|undefined = undefined; - private setThemeListenerId_: number|null = null; private themeType_: CustomizeThemeType|null = null; private callbackRouter_: CustomizeChromePageCallbackRouter; private pageHandler_: CustomizeChromePageHandlerInterface; + private setThemeListenerId_: number|null = null; constructor() { super(); @@ -56,6 +61,8 @@ override connectedCallback() { super.connectedCallback(); + this.chromeRefresh2023Enabled_ = + document.documentElement.hasAttribute('chrome-refresh-2023'); this.setThemeListenerId_ = this.callbackRouter_.setTheme.addListener((theme: Theme) => { this.theme_ = theme;
diff --git a/chrome/browser/resources/webui_gallery/BUILD.gn b/chrome/browser/resources/webui_gallery/BUILD.gn index 6904103..b4a74be4 100644 --- a/chrome/browser/resources/webui_gallery/BUILD.gn +++ b/chrome/browser/resources/webui_gallery/BUILD.gn
@@ -10,35 +10,13 @@ grd_prefix = "webui_gallery" static_files = [ - "demos/buttons/index.html", - "demos/card/index.html", - "demos/cr_a11y_announcer/index.html", - "demos/cr_action_menu/index.html", - "demos/cr_checkbox/index.html", - "demos/cr_dialog/index.html", - "demos/cr_icons/index.html", - "demos/cr_input/index.html", - "demos/cr_radio/index.html", - "demos/cr_slider/index.html", - "demos/cr_tab_box/index.html", - "demos/cr_tabs/index.html", - "demos/cr_toast/index.html", - "demos/cr_toggle/index.html", - "demos/cr_toolbar/index.html", - "demos/cr_tree/index.html", - "demos/cr_url_list_item/index.html", - "demos/demo.css", - "demos/md_select/index.html", - "demos/nav_menu/index.html", - "demos/progress_indicators/index_native.html", - "demos/progress_indicators/index_polymer.html", - "demos/scroll_view/index.html", "demos/side_panel/empty.svg", "demos/side_panel/empty_dark.svg", - "demos/side_panel/index.html", "webui_gallery.html", ] + css_files = [ "demos/demo.css" ] + # Files holding a Polymer or native custom element definition AND have an # equivalent .html template file. web_component_files = [
diff --git a/chrome/browser/resources/webui_gallery/app.html b/chrome/browser/resources/webui_gallery/app.html index 7d4656e..2eb6c60 100644 --- a/chrome/browser/resources/webui_gallery/app.html +++ b/chrome/browser/resources/webui_gallery/app.html
@@ -7,10 +7,10 @@ #sidebar { border-inline-end: 1px solid var(--cr-separator-color); box-sizing: border-box; + min-width: 256px; overflow: auto; padding-block-end: 12px; padding-inline-end: 12px; - width: 256px; } h1 { @@ -28,12 +28,14 @@ #main { flex: 1; + overflow: auto; + padding: 16px; } </style> <div id="sidebar"> <h1>WebUI Gallery</h1> <cr-menu-selector id="selector" selectable="a" selected-attribute="selected"> - <template is="dom-repeat" items="[[demos]]"> + <template is="dom-repeat" items="[[demos_]]"> <a role="menuitem" href="[[item.path]]" class="cr-nav-menu-item">[[item.name]]</a> </template> @@ -42,6 +44,4 @@ <iron-location path="{{path_}}"></iron-location> -<div id="main"> - <iframe id="iframe"></iframe> -</div> +<div id="main"></div>
diff --git a/chrome/browser/resources/webui_gallery/app.ts b/chrome/browser/resources/webui_gallery/app.ts index 909c92b8..99fcc4c 100644 --- a/chrome/browser/resources/webui_gallery/app.ts +++ b/chrome/browser/resources/webui_gallery/app.ts
@@ -7,13 +7,20 @@ import '//resources/polymer/v3_0/iron-location/iron-location.js'; import {CrMenuSelector} from '//resources/cr_elements/cr_menu_selector/cr_menu_selector.js'; +import {assert} from '//resources/js/assert_ts.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './app.html.js'; +interface Demo { + name: string; + path: string; + src: string; +} + export interface WebuiGalleryAppElement { $: { - iframe: HTMLIFrameElement, + main: HTMLElement, selector: CrMenuSelector, }; } @@ -29,124 +36,124 @@ static get properties() { return { - demos: { + demos_: { type: Array, value: function() { return [ { name: 'Accessibility Live Regions', path: 'a11y', - src: 'cr_a11y_announcer/index.html', + src: 'cr_a11y_announcer/cr_a11y_announcer_demo.js', }, { name: 'Action Menus', path: 'action-menus', - src: 'cr_action_menu/index.html', + src: 'cr_action_menu/cr_action_menu_demo.js', }, { name: 'Buttons', path: 'buttons', - src: 'buttons/index.html', + src: 'buttons/buttons_demo.js', }, { name: 'Cards and rows', path: 'cards', - src: 'card/index.html', + src: 'card/card_demo.js', }, { name: 'Checkboxes', path: 'checkboxes', - src: 'cr_checkbox/index.html', + src: 'cr_checkbox/cr_checkbox_demo.js', }, { name: 'Dialogs', path: 'dialogs', - src: 'cr_dialog/index.html', + src: 'cr_dialog/cr_dialog_demo.js', }, { name: 'Icons', path: 'icons', - src: 'cr_icons/index.html', + src: 'cr_icons/cr_icons_demo.js', }, { name: 'Inputs', path: 'inputs', - src: 'cr_input/index.html', + src: 'cr_input/cr_input_demo.js', }, { name: 'Navigation menus', path: 'nav-menus', - src: 'nav_menu/index.html', + src: 'nav_menu/nav_menu_demo.js', }, { name: 'Progress indicators, Polymer', path: 'progress-polymer', - src: 'progress_indicators/index_polymer.html', + src: 'progress_indicators/progress_indicator_polymer_demo.js', }, { name: 'Progress indicators, non-Polymer', path: 'progress-nonpolymer', - src: 'progress_indicators/index_native.html', + src: 'progress_indicators/progress_indicator_native_demo.js', }, { name: 'Radio buttons and groups', path: 'radios', - src: 'cr_radio/index.html', + src: 'cr_radio/cr_radio_demo.js', }, { name: 'Scroll view', path: 'scroll-view', - src: 'scroll_view/index.html', + src: 'scroll_view/scroll_view_demo.js', }, { name: 'Select menu', path: 'select-menu', - src: 'md_select/index.html', + src: 'md_select/md_select_demo.js', }, { name: 'Side panel', path: 'side-panel', - src: 'side_panel/index.html', + src: 'side_panel/sp_components_demo.js', }, { name: 'Sliders', path: 'sliders', - src: 'cr_slider/index.html', + src: 'cr_slider/cr_slider_demo.js', }, { name: 'Tabs, non-Polymer', path: 'tabs1', - src: 'cr_tab_box/index.html', + src: 'cr_tab_box/cr_tab_box_demo.js', }, { name: 'Tabs, Polymer', path: 'tabs2', - src: 'cr_tabs/index.html', + src: 'cr_tabs/cr_tabs_demo.js', }, { name: 'Toast', path: 'toast', - src: 'cr_toast/index.html', + src: 'cr_toast/cr_toast_demo.js', }, { name: 'Toggles', path: 'toggles', - src: 'cr_toggle/index.html', + src: 'cr_toggle/cr_toggle_demo.js', }, { name: 'Toolbar', path: 'toolbar', - src: 'cr_toolbar/index.html', + src: 'cr_toolbar/cr_toolbar_demo.js', }, { name: 'Tree, non-Polymer', path: 'tree', - src: 'cr_tree/index.html', + src: 'cr_tree/cr_tree_demo.js', }, { name: 'URL List Item', path: 'url-list-item', - src: 'cr_url_list_item/index.html', + src: 'cr_url_list_item/cr_url_list_item_demo.js', }, ]; }, @@ -159,18 +166,24 @@ }; } - demos: Array<{name: string, path: string, src: string}>; + private demos_: Demo[]; private path_: string; - private onPathChanged_() { - const selectedIndex = Math.max( - 0, this.demos.findIndex(demo => demo.path === this.path_.substring(1))); - this.$.selector.selected = selectedIndex; + private async onPathChanged_() { + const path = this.path_.substring(1); + const demoIndex = + path === '' ? 0 : this.demos_.findIndex(demo => demo.path === path); + assert(demoIndex !== -1); + this.$.selector.selected = demoIndex; - // Use `location.replace` instead of iframe's `src` to prevent the iframe's - // source from interfering with tab's history. - this.$.iframe.contentWindow!.location.replace( - 'demos/' + this.demos[selectedIndex]!.src); + const demo = this.demos_[demoIndex]!; + + const {tagName} = await import(`./demos/${demo.src}`); + assert(tagName); + + const demoElement = document.createElement(tagName); + this.$.main.innerHTML = window.trustedTypes!.emptyHTML; + this.$.main.appendChild(demoElement); } }
diff --git a/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.html b/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.html index 7e3eed0..2795d01 100644 --- a/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.html
@@ -1,6 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> - -<style> +<style include="demo"> cr-button[circle-ripple] { border-radius: 50%; height: 60px;
diff --git a/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.ts b/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.ts index 5bb723b..1336e726 100644 --- a/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/buttons/buttons_demo.ts
@@ -7,6 +7,7 @@ import '//resources/cr_elements/cr_icon_button/cr_icon_button.js'; import '//resources/cr_elements/icons.html.js'; import '//resources/polymer/v3_0/iron-collapse/iron-collapse.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -30,4 +31,6 @@ private exapanded_: boolean; } +export const tagName = ButtonsDemoElement.is; + customElements.define(ButtonsDemoElement.is, ButtonsDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/buttons/index.html b/chrome/browser/resources/webui_gallery/demos/buttons/index.html deleted file mode 100644 index 1ebe2ce..0000000 --- a/chrome/browser/resources/webui_gallery/demos/buttons/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html $i18n{chromeRefresh2023Attribute}> - <head> - <meta charset="utf-8"> - <title>buttons demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <buttons-demo></buttons-demo> - <script src="buttons_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/card/card_demo.ts b/chrome/browser/resources/webui_gallery/demos/card/card_demo.ts index 6b36b95b..d12d439c 100644 --- a/chrome/browser/resources/webui_gallery/demos/card/card_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/card/card_demo.ts
@@ -39,4 +39,6 @@ } } +export const tagName = CardDemoElement.is; + customElements.define(CardDemoElement.is, CardDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/card/index.html b/chrome/browser/resources/webui_gallery/demos/card/index.html deleted file mode 100644 index 5440a90..0000000 --- a/chrome/browser/resources/webui_gallery/demos/card/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Cards demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <card-demo></card-demo> - <script src="card_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.html index 1fd995f..4f1c8af 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style> +<style include="demo"> :host([force-show-announcer_]) cr-a11y-announcer { overflow: visible; position: static;
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.ts index 67b083ed..183e28b 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/cr_a11y_announcer_demo.ts
@@ -4,6 +4,7 @@ import '//resources/cr_elements/cr_button/cr_button.js'; import '//resources/cr_elements/cr_checkbox/cr_checkbox.js'; +import '../demo.css.js'; import {getInstance as getAnnouncerInstance} from '//resources/cr_elements/cr_a11y_announcer/cr_a11y_announcer.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -54,5 +55,7 @@ } } +export const tagName = CrA11yAnnouncerDemoElement.is; + customElements.define( CrA11yAnnouncerDemoElement.is, CrA11yAnnouncerDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/index.html b/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/index.html deleted file mode 100644 index 97242895..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_a11y_announcer/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-a11y-announcer demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-a11y-announcer-demo></cr-a11y-announcer-demo> - <script src="cr_a11y_announcer_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.html index 161dc39..73a1edf 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.html
@@ -1,6 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> - -<style include="cr-icons"> +<style include="cr-icons demo"> cr-input { --cr-input-error-display: none; }
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.ts index 2baac4a4..c66f4d6 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_action_menu/cr_action_menu_demo.ts
@@ -10,6 +10,7 @@ import '//resources/cr_elements/cr_input/cr_input.js'; import '//resources/cr_elements/icons.html.js'; import '//resources/cr_elements/cr_shared_vars.css.js'; +import '../demo.css.js'; import {AnchorAlignment, CrActionMenuElement, ShowAtPositionConfig} from '//resources/cr_elements/cr_action_menu/cr_action_menu.js'; import {CrInputElement} from '//resources/cr_elements/cr_input/cr_input.js'; @@ -130,4 +131,6 @@ } } +export const tagName = CrActionMenuDemoElement.is; + customElements.define(CrActionMenuDemoElement.is, CrActionMenuDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_action_menu/index.html b/chrome/browser/resources/webui_gallery/demos/cr_action_menu/index.html deleted file mode 100644 index 57b6aef..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_action_menu/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-action-menu demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-action-menu-demo></cr-action-menu-demo> - <script src="cr_action_menu_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.html index e9d4670..1b208e7 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> - +<style include="demo"></style> <h1>cr-checkbox</h1> <div class="demos"> <cr-checkbox checked="{{myValue_}}">Checkbox</cr-checkbox>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.ts index 8e66dbd..a47b84d0 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_checkbox/cr_checkbox_demo.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import '//resources/cr_elements/cr_checkbox/cr_checkbox.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -26,4 +27,6 @@ private myValue_: boolean; } +export const tagName = CrCheckboxDemoElement.is; + customElements.define(CrCheckboxDemoElement.is, CrCheckboxDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_checkbox/index.html b/chrome/browser/resources/webui_gallery/demos/cr_checkbox/index.html deleted file mode 100644 index 7224fc9..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_checkbox/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html $i18n{chromeRefresh2023Attribute}> - <head> - <meta charset="utf-8"> - <title>cr-checkbox demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-checkbox-demo></cr-checkbox-demo> - <script src="cr_checkbox_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.html index d71198cd..439da758 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.html
@@ -1,6 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> - -<style> +<style include="demo"> cr-input:first-of-type { margin-block-start: 16px; }
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.ts index f905a17..c5a1b24 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_dialog/cr_dialog_demo.ts
@@ -7,6 +7,7 @@ import '//resources/cr_elements/cr_checkbox/cr_checkbox.js'; import '//resources/cr_elements/cr_input/cr_input.js'; import '//resources/cr_elements/cr_shared_vars.css.js'; +import '../demo.css.js'; import {CrDialogElement} from '//resources/cr_elements/cr_dialog/cr_dialog.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -86,4 +87,6 @@ } } +export const tagName = CrDialogDemoElement.is; + customElements.define(CrDialogDemoElement.is, CrDialogDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_dialog/index.html b/chrome/browser/resources/webui_gallery/demos/cr_dialog/index.html deleted file mode 100644 index 6d301d2..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_dialog/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-dialog demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-dialog-demo></cr-dialog-demo> - <script src="cr_dialog_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.html index 99413df..638788a 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style include="cr-icons"> +<style include="cr-icons demo"> .icons { display: grid; font-size: 11px;
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.ts index da1c68f..85013322 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_icons/cr_icons_demo.ts
@@ -6,6 +6,7 @@ import '//resources/cr_elements/cr_input/cr_input.js'; import '//resources/cr_elements/icons.html.js'; import '//resources/polymer/v3_0/iron-icon/iron-icon.js'; +import '../demo.css.js'; import {assert} from '//resources/js/assert_ts.js'; import {IronIconsetSvgElement} from '//resources/polymer/v3_0/iron-iconset-svg/iron-iconset-svg.js'; @@ -66,4 +67,6 @@ } } +export const tagName = CrIconsDemoElement.is; + customElements.define(CrIconsDemoElement.is, CrIconsDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_icons/index.html b/chrome/browser/resources/webui_gallery/demos/cr_icons/index.html deleted file mode 100644 index 8d1882d6..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_icons/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-icons demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-icons-demo></cr-icons-demo> - <script src="cr_icons_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html index 98cfc83..c77997a3 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style include="cr-hidden-style cr-icons"> +<style include="cr-hidden-style cr-icons demo"> cr-input, cr-textarea { max-width: 400px;
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts index f33535d..02cd735a 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_input/cr_input_demo.ts
@@ -8,6 +8,7 @@ import '//resources/cr_elements/cr_icons.css.js'; import '//resources/cr_elements/cr_input/cr_input.js'; import '//resources/cr_elements/cr_textarea/cr_textarea.js'; +import '../demo.css.js'; import {CrInputElement} from '//resources/cr_elements/cr_input/cr_input.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -56,4 +57,6 @@ } } +export const tagName = CrInputDemoElement.is; + customElements.define(CrInputDemoElement.is, CrInputDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_input/index.html b/chrome/browser/resources/webui_gallery/demos/cr_input/index.html deleted file mode 100644 index 6a4ef4a..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_input/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<html $i18n{chromeRefresh2023Attribute}> - <head> - <meta charset="utf-8"> - <title>cr-input demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-input-demo></cr-input-demo> - <script src="cr_input_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.html index 08384a2..f038615 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style include="cr-icons"> +<style include="cr-icons demo"> #segmentedButtonDemo { display: none; }
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.ts index b02fc32..378ef5c 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_radio/cr_radio_demo.ts
@@ -7,6 +7,7 @@ import '//resources/cr_elements/cr_radio_button/cr_radio_button.js'; import '//resources/cr_elements/cr_segmented_button/cr_segmented_button.js'; import '//resources/cr_elements/cr_segmented_button/cr_segmented_button_option.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -32,4 +33,6 @@ private selectedSegmentedButtonOption_: string; } +export const tagName = CrRadioDemoElement.is; + customElements.define(CrRadioDemoElement.is, CrRadioDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_radio/index.html b/chrome/browser/resources/webui_gallery/demos/cr_radio/index.html deleted file mode 100644 index 4ab0e41b..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_radio/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html $i18n{chromeRefresh2023Attribute}> - <head> - <meta charset="utf-8"> - <title>cr-radio demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-radio-demo></cr-radio-demo> - <script src="cr_radio_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.html index 92408cbd..c3c761c 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style> +<style include="demo"> cr-slider { width: 200px; }
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.ts index ebeadfef..10767d57 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_slider/cr_slider_demo.ts
@@ -4,6 +4,7 @@ import '//resources/cr_elements/cr_checkbox/cr_checkbox.js'; import '//resources/cr_elements/cr_slider/cr_slider.js'; +import '../demo.css.js'; import {CrSliderElement, SliderTick} from '//resources/cr_elements/cr_slider/cr_slider.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -75,4 +76,6 @@ } } +export const tagName = CrSliderDemoElement.is; + customElements.define(CrSliderDemoElement.is, CrSliderDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_slider/index.html b/chrome/browser/resources/webui_gallery/demos/cr_slider/index.html deleted file mode 100644 index 0064969..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_slider/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-slider demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-slider-demo></cr-slider-demo> - <script src="cr_slider_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.html index f019f2c..db114233 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.html
@@ -1,4 +1,3 @@ -<link rel="stylesheet" href="../demo.css"> <style> div[slot='panel'] { padding: 90px 0; @@ -27,6 +26,14 @@ font-family: sans-serif; font-size: 10pt; } + + .demos { + align-items: flex-start; + display: flex; + flex-direction: column; + gap: 16px; + margin-bottom: 24px; + } </style> <h1>cr-tab-box</h1> <div class="demos">
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.ts index d63af8c8..503bfc2 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/cr_tab_box_demo.ts
@@ -11,6 +11,10 @@ import {getTemplate} from './cr_tab_box_demo.html.js'; class CrTabBoxDemoElement extends CustomElement { + static get is() { + return 'cr-tab-box-demo'; + } + static override get template() { return getTemplate(); } @@ -91,4 +95,6 @@ } } -customElements.define('cr-tab-box-demo', CrTabBoxDemoElement); +export const tagName = CrTabBoxDemoElement.is; + +customElements.define(CrTabBoxDemoElement.is, CrTabBoxDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/index.html b/chrome/browser/resources/webui_gallery/demos/cr_tab_box/index.html deleted file mode 100644 index d17ddb3..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_tab_box/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-tab-box demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-tab-box-demo></cr-tab-box-demo> - <script src="cr_tab_box_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.html index e2c1a83b..c922ad3 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style> +<style include="demo"> cr-tabs, iron-pages { width: 100%;
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.ts index 5bef7174..5af947c 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_tabs/cr_tabs_demo.ts
@@ -5,6 +5,7 @@ import '//resources/cr_elements/cr_button/cr_button.js'; import '//resources/cr_elements/cr_tabs/cr_tabs.js'; import '//resources/polymer/v3_0/iron-pages/iron-pages.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -42,4 +43,6 @@ } } +export const tagName = CrTabsDemoElement.is; + customElements.define(CrTabsDemoElement.is, CrTabsDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tabs/index.html b/chrome/browser/resources/webui_gallery/demos/cr_tabs/index.html deleted file mode 100644 index 41d8dd73..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_tabs/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-tabs demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-tabs-demo></cr-tabs-demo> - <script src="cr_tabs_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.html index 68e03dc7..874c644 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style> +<style include="demo"> cr-input { --cr-input-error-display: none; }
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.ts index da0a655..1809ba63 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_toast/cr_toast_demo.ts
@@ -6,6 +6,7 @@ import '//resources/cr_elements/cr_checkbox/cr_checkbox.js'; import '//resources/cr_elements/cr_input/cr_input.js'; import '//resources/cr_elements/cr_toast/cr_toast.js'; +import '../demo.css.js'; import {CrToastElement} from '//resources/cr_elements/cr_toast/cr_toast.js'; import {getToastManager} from '//resources/cr_elements/cr_toast/cr_toast_manager.js'; @@ -62,4 +63,6 @@ } } +export const tagName = CrToastDemoElement.is; + customElements.define(CrToastDemoElement.is, CrToastDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toast/index.html b/chrome/browser/resources/webui_gallery/demos/cr_toast/index.html deleted file mode 100644 index 67a338e..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_toast/index.html +++ /dev/null
@@ -1,15 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-toast demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-toast-demo></cr-toast-demo> - <cr-toast-manager duration="5000"></cr-toast-manager> - <script src="//resources/cr_elements/cr_toast/cr_toast_manager.js" - type="module"></script> - <script src="cr_toast_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.html index 87ee66b..e1ce442 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.html
@@ -1,6 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> - -<style> +<style include="demo"> :host-context([chrome-refresh-2023]) .row:has(cr-toggle[dark]) { display: none; }
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.ts index 5619c04..2e93b0b 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_toggle/cr_toggle_demo.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import '//resources/cr_elements/cr_toggle/cr_toggle.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -26,4 +27,6 @@ private checked_: boolean; } +export const tagName = CrToggleDemoElement.is; + customElements.define(CrToggleDemoElement.is, CrToggleDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toggle/index.html b/chrome/browser/resources/webui_gallery/demos/cr_toggle/index.html deleted file mode 100644 index 31492d2..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_toggle/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html $i18n{chromeRefresh2023Attribute}> - <head> - <meta charset="utf-8"> - <title>cr-toggle demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-toggle-demo></cr-toggle-demo> - <script src="cr_toggle_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html index b0b9487..759629f 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style> +<style include="demo"> .content { padding: 16px; }
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts index 50643c1a..6f4e5a5 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/cr_toolbar_demo.ts
@@ -5,6 +5,7 @@ import '//resources/cr_elements/cr_checkbox/cr_checkbox.js'; import '//resources/cr_elements/cr_input/cr_input.js'; import '//resources/cr_elements/cr_toolbar/cr_toolbar.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -60,4 +61,6 @@ } } +export const tagName = CrToolbarDemoElement.is; + customElements.define(CrToolbarDemoElement.is, CrToolbarDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/index.html b/chrome/browser/resources/webui_gallery/demos/cr_toolbar/index.html deleted file mode 100644 index 0be56d5..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_toolbar/index.html +++ /dev/null
@@ -1,17 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-toolbar demo</title> - <link rel="stylesheet" href="../demo.css"> - <style> - body { - padding: 0; - } - </style> - </head> - <body> - <cr-toolbar-demo></cr-toolbar-demo> - <script src="cr_toolbar_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.html index 8a3b4fa6..5b2c116c 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.html
@@ -1,4 +1,3 @@ -<link rel="stylesheet" href="../demo.css"> <style> cr-tree:not([has-children]) ~ #clearAll, cr-tree:not([has-children]) ~ #collapseAll,
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.ts index 3e917ba..3cda2c22 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_tree/cr_tree_demo.ts
@@ -13,6 +13,10 @@ import {getTemplate} from './cr_tree_demo.html.js'; class CrTreeDemoElement extends CustomElement { + static get is() { + return 'cr-tree-demo'; + } + static override get template() { return getTemplate(); } @@ -25,7 +29,6 @@ this.tree_ = this.shadowRoot!.querySelector('cr-tree'); assert(this.tree_); - this.populateTree_(); this.tree_.addEventListener( 'cr-tree-change', () => this.addLogItem_('Selected item changed')); this.tree_.addEventListener( @@ -53,6 +56,11 @@ const addItemButton = this.shadowRoot!.querySelector('#addItem'); assert(addItemButton); addItemButton.addEventListener('click', () => this.addItem_()); + + window.setTimeout(() => { + // Need to wait so that the cr-tree instance has been upgraded. + this.populateTree_(); + }); } private addItem_() { @@ -147,4 +155,6 @@ } } -customElements.define('cr-tree-demo', CrTreeDemoElement); +export const tagName = CrTreeDemoElement.is; + +customElements.define(CrTreeDemoElement.is, CrTreeDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_tree/index.html b/chrome/browser/resources/webui_gallery/demos/cr_tree/index.html deleted file mode 100644 index 8deba0e..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_tree/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>cr-tree demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-tree-demo></cr-tree-demo> - <script src="cr_tree_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.html b/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.html index bb16422a..b10f723 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style> +<style include="demo"> .badge { align-items: center; background: var(--google-grey-200);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.ts b/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.ts index bf4a8c4..e2d7ce9 100644 --- a/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/cr_url_list_item_demo.ts
@@ -7,6 +7,7 @@ import '//resources/cr_elements/cr_input/cr_input.js'; import '//resources/cr_elements/cr_url_list_item/cr_url_list_item.js'; import '//resources/cr_elements/icons.html.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -22,4 +23,6 @@ } } +export const tagName = CrUrlListItemDemoElement.is; + customElements.define(CrUrlListItemDemoElement.is, CrUrlListItemDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/index.html b/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/index.html deleted file mode 100644 index 6f158d6d..0000000 --- a/chrome/browser/resources/webui_gallery/demos/cr_url_list_item/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<html $i18n{chromeRefresh2023Attribute}> - <head> - <meta charset="utf-8"> - <title>cr-url-list-item demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <cr-url-list-item-demo></cr-url-list-item-demo> - <script src="cr_url_list_item_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/demo.css b/chrome/browser/resources/webui_gallery/demos/demo.css index 4abeeee..e63303e 100644 --- a/chrome/browser/resources/webui_gallery/demos/demo.css +++ b/chrome/browser/resources/webui_gallery/demos/demo.css
@@ -2,26 +2,19 @@ * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ -@import '//resources/css/md_colors.css'; -@import '//resources/css/text_defaults_md.css'; +/* #css_wrapper_metadata_start + * #type=style + * #css_wrapper_metadata_end */ -html { +:host { --google-grey-200: rgb(232, 234, 237); --google-grey-900: rgb(32, 33, 36); -} -body { - box-sizing: border-box; - color: var(--google-grey-900); - height: 100%; - margin: 0; - padding: 16px; - width: 100%; + display: block; } @media (prefers-color-scheme: dark) { - body { - background: var(--md-background-color); + :host { color: var(--google-grey-200); } }
diff --git a/chrome/browser/resources/webui_gallery/demos/md_select/index.html b/chrome/browser/resources/webui_gallery/demos/md_select/index.html deleted file mode 100644 index c48732bc..0000000 --- a/chrome/browser/resources/webui_gallery/demos/md_select/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>md-select demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <md-select-demo></md-select-demo> - <script src="md_select_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.html b/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.html index 90a21b7c0..89712c6 100644 --- a/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.html
@@ -1,6 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style include="md-select"> -</style> +<style include="md-select demo"></style> <h1>Select menus</h1> <div class="demos">
diff --git a/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.ts b/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.ts index 0824f63..c7450dd 100644 --- a/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/md_select/md_select_demo.ts
@@ -3,6 +3,7 @@ // found in the LICENSE file. import '//resources/cr_elements/md_select.css.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -36,4 +37,6 @@ } } +export const tagName = MdSelectDemoElement.is; + customElements.define(MdSelectDemoElement.is, MdSelectDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/nav_menu/index.html b/chrome/browser/resources/webui_gallery/demos/nav_menu/index.html deleted file mode 100644 index 94086d9..0000000 --- a/chrome/browser/resources/webui_gallery/demos/nav_menu/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!doctype html> -<html> - <head> - <meta charset="utf-8"> - <title>Nav menu items demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <nav-menu-demo></nav-menu-demo> - <script src="nav_menu_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.html b/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.html index 3af91c3..a377215 100644 --- a/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style include="cr-hidden-style cr-nav-menu-item-style"> +<style include="cr-hidden-style cr-nav-menu-item-style demo"> nav-menu { display: block; width: 100%;
diff --git a/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.ts b/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.ts index 5d66cabf..a165c426 100644 --- a/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/nav_menu/nav_menu_demo.ts
@@ -7,6 +7,7 @@ import '//resources/cr_elements/cr_drawer/cr_drawer.js'; import '//resources/cr_elements/cr_hidden_style.css.js'; import './nav_menu.js'; +import '../demo.css.js'; import {CrDrawerElement} from '//resources/cr_elements/cr_drawer/cr_drawer.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -68,4 +69,6 @@ } } +export const tagName = NavMenuDemoElement.is; + customElements.define(NavMenuDemoElement.is, NavMenuDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/index_native.html b/chrome/browser/resources/webui_gallery/demos/progress_indicators/index_native.html deleted file mode 100644 index ae2f703..0000000 --- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/index_native.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Progress indicators demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <progress-indicator-native-demo></progress-indicator-native-demo> - <script src="progress_indicator_native_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/index_polymer.html b/chrome/browser/resources/webui_gallery/demos/progress_indicators/index_polymer.html deleted file mode 100644 index f906caff..0000000 --- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/index_polymer.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Progress indicators demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <progress-indicator-polymer-demo></progress-indicator-polymer-demo> - <script src="progress_indicator_polymer_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.html b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.html index b28fb9d..3187e19 100644 --- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.html
@@ -1,6 +1,15 @@ <link rel="stylesheet" href="//resources/css/spinner.css"> <link rel="stylesheet" href="//resources/css/throbber.css"> -<link rel="stylesheet" href="../demo.css"> + +<style> + .demos { + align-items: flex-start; + display: flex; + flex-direction: column; + gap: 16px; + margin-bottom: 24px; + } +</style> <h1>throbber, 16px</h1> <div class="demos">
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.ts b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.ts index 7ee7da2..48c307e 100644 --- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_native_demo.ts
@@ -17,5 +17,7 @@ } } +export const tagName = ProgressIndicatorNativeDemoElement.is; + customElements.define( ProgressIndicatorNativeDemoElement.is, ProgressIndicatorNativeDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html index 8770f71..8275d95b 100644 --- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style> +<style include="demo"> paper-progress { --paper-progress-active-color: var(--google-blue-500); }
diff --git a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts index ae96f0b..c30d423c 100644 --- a/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/progress_indicators/progress_indicator_polymer_demo.ts
@@ -6,6 +6,7 @@ import '//resources/cr_elements/cr_shared_vars.css.js'; import '//resources/polymer/v3_0/paper-progress/paper-progress.js'; import '//resources/polymer/v3_0/paper-spinner/paper-spinner-lite.js'; +import '../demo.css.js'; import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; @@ -21,6 +22,8 @@ } } +export const tagName = ProgressIndicatorPolymerDemoElement.is; + customElements.define( ProgressIndicatorPolymerDemoElement.is, ProgressIndicatorPolymerDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/scroll_view/index.html b/chrome/browser/resources/webui_gallery/demos/scroll_view/index.html deleted file mode 100644 index 78163044..0000000 --- a/chrome/browser/resources/webui_gallery/demos/scroll_view/index.html +++ /dev/null
@@ -1,12 +0,0 @@ -<!DOCTYPE html> -<html> - <head> - <meta charset="utf-8"> - <title>Scroll view demo</title> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <scroll-view-demo></scroll-view-demo> - <script src="scroll_view_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.html b/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.html index e7332b5..9502ae0 100644 --- a/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style include="cr-shared-style"> +<style include="cr-shared-style demo"> #layout { display: flex; flex-direction: column;
diff --git a/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.ts b/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.ts index 4698a64..03831f39 100644 --- a/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/scroll_view/scroll_view_demo.ts
@@ -6,6 +6,7 @@ import '//resources/cr_elements/cr_shared_vars.css.js'; import '//resources/polymer/v3_0/iron-list/iron-list.js'; import '//resources/cr_elements/cr_slider/cr_slider.js'; +import '../demo.css.js'; import {CrContainerShadowMixin} from '//resources/cr_elements/cr_container_shadow_mixin.js'; import {CrScrollableMixin} from '//resources/cr_elements/cr_scrollable_mixin.js'; @@ -59,4 +60,6 @@ } } +export const tagName = ScrollViewDemoElement.is; + customElements.define(ScrollViewDemoElement.is, ScrollViewDemoElement);
diff --git a/chrome/browser/resources/webui_gallery/demos/side_panel/index.html b/chrome/browser/resources/webui_gallery/demos/side_panel/index.html deleted file mode 100644 index de486d1..0000000 --- a/chrome/browser/resources/webui_gallery/demos/side_panel/index.html +++ /dev/null
@@ -1,13 +0,0 @@ -<!doctype html> -<html $i18n{chromeRefresh2023Attribute}> - <head> - <meta charset="utf-8"> - <title>Side panel components demo</title> - <link rel="stylesheet" href="chrome://theme/colors.css?sets=ui,chrome"> - <link rel="stylesheet" href="../demo.css"> - </head> - <body> - <sp-components-demo></sp-components-demo> - <script src="sp_components_demo.js" type="module"></script> - </body> -</html>
diff --git a/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.html b/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.html index 7141a6a2..4a68e09d 100644 --- a/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.html +++ b/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.html
@@ -1,5 +1,4 @@ -<link rel="stylesheet" href="../demo.css"> -<style include="md-select sp-shared-style"> +<style include="md-select sp-shared-style demo"> #urlCountSlider { width: 200px; } @@ -147,8 +146,8 @@ <h2>Empty state</h2> <div id="emptyStateDemo" class="demos"> <sp-empty-state - image-path="./empty.svg" - dark-image-path="./empty_dark.svg" + image-path="./demos/side_panel/empty.svg" + dark-image-path="./demos/side_panel/empty_dark.svg" heading="There is no content" body="Some more descriptive text explaining how to add content"> </sp-empty-state>
diff --git a/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.ts b/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.ts index 8074e62..4ff2f2b 100644 --- a/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.ts +++ b/chrome/browser/resources/webui_gallery/demos/side_panel/sp_components_demo.ts
@@ -18,6 +18,7 @@ import '//webui-gallery/shared/sp_list_item_badge.js'; import '//webui-gallery/shared/sp_shared_style.css.js'; import '//webui-gallery/shared/sp_shared_vars.css.js'; +import '../demo.css.js'; import {CrSliderElement} from '//resources/cr_elements/cr_slider/cr_slider.js'; import {CrUrlListItemSize} from '//resources/cr_elements/cr_url_list_item/cr_url_list_item.js'; @@ -103,4 +104,6 @@ } } +export const tagName = SpComponentsDemo.is; + customElements.define(SpComponentsDemo.is, SpComponentsDemo);
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc index 341bf7e..f07e4177 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc
@@ -268,6 +268,12 @@ return content_analysis_request_.request_data().tab_title(); } +const std::string& BinaryUploadService::Request::printer_name() const { + return content_analysis_request_.request_data() + .print_metadata() + .printer_name(); +} + uint64_t BinaryUploadService::Request::user_action_requests_count() const { return content_analysis_request_.user_action_requests_count(); }
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h index c459f9bc..1b49802 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h
@@ -185,6 +185,7 @@ const std::string& content_type() const; const std::string& user_action_id() const; const std::string& tab_title() const; + const std::string& printer_name() const; uint64_t user_action_requests_count() const; GURL tab_url() const;
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_util.cc b/chrome/browser/safe_browsing/download_protection/download_protection_util.cc index 8829ed5..4b6fe57 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_util.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_util.cc
@@ -69,7 +69,7 @@ } } -void SelectWildcardEntry( +void SelectWildcardEntryAtFront( std::vector<ClientDownloadRequest::ArchivedBinary>* considering, google::protobuf::RepeatedPtrField<ClientDownloadRequest::ArchivedBinary>* selected) { @@ -81,6 +81,12 @@ // leads to a uniform distribution over all executables. if (remaining_executables * base::RandDouble() < 1) { *selected->Add() = *it; + // Move the selected entry to the front. There's no easy way to insert + // at a specific location in a RepeatedPtrField, so we do the move as a + // series of swaps. + for (int i = 0; i < selected->size() - 1; ++i) { + selected->SwapElements(i, selected->size() - 1); + } considering->erase(it); return; } @@ -182,13 +188,6 @@ SelectDeepestEntry(&considering, &selected); } - // Only add the wildcard if we otherwise wouldn't be able to fit all the - // entries. - if (static_cast<size_t>(selected.size()) < limit && - considering.size() + selected.size() > limit) { - SelectWildcardEntry(&considering, &selected); - } - std::sort(considering.begin(), considering.end(), [](const ClientDownloadRequest::ArchivedBinary& lhs, const ClientDownloadRequest::ArchivedBinary& rhs) { @@ -201,16 +200,35 @@ return ArchiveEntryWeight(lhs) > ArchiveEntryWeight(rhs); }); - for (const ClientDownloadRequest::ArchivedBinary& binary : considering) { + // Only add the wildcard if we otherwise wouldn't be able to fit all the + // entries. + bool should_choose_wildcard = static_cast<size_t>(selected.size()) < limit && + considering.size() + selected.size() > limit; + if (should_choose_wildcard) { + --limit; + } + + auto last_taken_it = considering.begin(); + for (auto binary_it = considering.begin(); binary_it != considering.end(); + ++binary_it) { if (static_cast<size_t>(selected.size()) >= limit) { break; } - if (binary.is_executable() || binary.is_archive()) { - *selected.Add() = binary; + if (binary_it->is_executable() || binary_it->is_archive()) { + *selected.Add() = std::move(*binary_it); + last_taken_it = binary_it; } } + // By actually choosing the wildcard at the end, we ensure that all the other + // entries in the ping are completely deterministic. + if (should_choose_wildcard && last_taken_it != considering.end()) { + ++last_taken_it; + considering.erase(considering.begin(), last_taken_it); + SelectWildcardEntryAtFront(&considering, &selected); + } + return selected; }
diff --git a/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc b/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc index da7b6fa..1984091 100644 --- a/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc +++ b/chrome/browser/safe_browsing/download_protection/download_protection_util_unittest.cc
@@ -6,6 +6,7 @@ #include "base/hash/sha1.h" #include "base/path_service.h" +#include "base/strings/string_number_conversions.h" #include "chrome/browser/safe_browsing/download_protection/download_protection_unittest_util.h" #include "components/safe_browsing/content/common/file_type_policies_test_util.h" #include "net/cert/x509_util.h" @@ -289,4 +290,38 @@ EXPECT_EQ(selected_binaries[2].file_path(), "hidden/in/deep/path/other.dll"); } +TEST(DownloadProtectionUtilTest, NonWildcardEntryDeterministic) { + safe_browsing::FileTypePoliciesTestOverlay scoped_dangerous; + { + // Setup fake file-type config so that this test is not dependent on the + // actual policy values. + auto fake_config = std::make_unique<DownloadFileTypeConfig>(); + fake_config->set_max_archived_binaries_to_report(10); + fake_config->mutable_default_file_type()->add_platform_settings(); + scoped_dangerous.SwapConfig(fake_config); + } + + google::protobuf::RepeatedPtrField<ClientDownloadRequest::ArchivedBinary> + binaries; + for (int i = 0; i < 12; i++) { + ClientDownloadRequest::ArchivedBinary exe; + exe.set_file_path("evil" + base::NumberToString(i + 1) + ".exe"); + exe.set_is_executable(true); + *binaries.Add() = exe; + } + + google::protobuf::RepeatedPtrField<ClientDownloadRequest::ArchivedBinary> + selected_binaries = SelectArchiveEntries(binaries); + ASSERT_EQ(selected_binaries.size(), 10); + for (int i = 0; i < 9; i++) { + EXPECT_EQ(selected_binaries[i + 1].file_path(), + "evil" + base::NumberToString(i + 1) + ".exe"); + } + + EXPECT_TRUE(selected_binaries[0].file_path() == "evil10.exe" || + selected_binaries[0].file_path() == "evil11.exe" || + selected_binaries[0].file_path() == "evil12.exe") + << "Wilcard entry is " << selected_binaries[0].file_path(); +} + } // namespace safe_browsing
diff --git a/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc b/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc index 054c3576..f15e088 100644 --- a/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc +++ b/chrome/browser/safe_browsing/tailored_security/notification_handler_desktop.cc
@@ -18,6 +18,7 @@ #include "chrome/grit/chromium_strings.h" #include "chrome/grit/generated_resources.h" #include "chrome/grit/google_chrome_strings.h" +#include "chrome/grit/theme_resources.h" #include "components/prefs/pref_service.h" #include "components/safe_browsing/core/browser/tailored_security_service/tailored_security_outcome.h" #include "components/safe_browsing/core/common/features.h" @@ -111,6 +112,16 @@ std::move(completed_closure).Run(); } +ui::ImageModel GetNotificationIcon() { +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + return ui::ImageModel::FromResourceId( + IDR_TAILORED_SECURITY_UNCONSENTED_NOTIFICATION); +#else + return ui::ImageModel::FromVectorIcon(kSafetyCheckIcon, ui::kColorAccent, + message_center::kNotificationIconSize); +#endif +} + void DisplayTailoredSecurityUnconsentedPromotionNotification(Profile* profile) { std::string notification_id = kTailoredSecurityUnconsentedPromotionNotificationId; @@ -132,12 +143,12 @@ #else const message_center::NotifierId notifier_id = GetNotifierId(); #endif - - // TODO(crbug/1257622): Confirm with UX that it's appropriate to use the - // blue color here. - auto icon = - ui::ImageModel::FromVectorIcon(kSafetyCheckIcon, ui::kColorAccent, - message_center::kNotificationIconSize); + auto icon = (base::FeatureList::IsEnabled( + safe_browsing::kTailoredSecurityUpdatedMessages)) + ? GetNotificationIcon() + : ui::ImageModel::FromVectorIcon( + kSafetyCheckIcon, ui::kColorAccent, + message_center::kNotificationIconSize); LogUnconsentedOutcome(TailoredSecurityOutcome::kShown); message_center::Notification notification( message_center::NOTIFICATION_TYPE_SIMPLE, notification_id, title,
diff --git a/chrome/browser/sessions/session_restore_browsertest.cc b/chrome/browser/sessions/session_restore_browsertest.cc index d6c49fe..dd96b488 100644 --- a/chrome/browser/sessions/session_restore_browsertest.cc +++ b/chrome/browser/sessions/session_restore_browsertest.cc
@@ -683,6 +683,8 @@ // there is no guarantee that the SessionID for the tab has remained the same. base::Time timestamp; int http_status_code = 0; + ui_test_utils::BrowserChangeObserver browser_change_observer( + nullptr, ui_test_utils::BrowserChangeObserver::ChangeType::kAdded); for (const auto& tab_ptr : window->tabs) { const sessions::TabRestoreService::Tab& tab = *tab_ptr; // If this tab held url2, then restore this single tab. @@ -710,10 +712,11 @@ service->entries().front().get()); EXPECT_EQ(2U, window->tabs.size()); + Browser* restored_browser = browser_change_observer.Wait(); // Make sure that the restored tab was restored with the correct // timestamp and status code. content::WebContents* contents = - browser()->tab_strip_model()->GetActiveWebContents(); + restored_browser->tab_strip_model()->GetActiveWebContents(); ASSERT_TRUE(contents); content::NavigationEntry* entry = contents->GetController().GetLastCommittedEntry();
diff --git a/chrome/browser/sessions/session_service_base.cc b/chrome/browser/sessions/session_service_base.cc index 75108a6..c5471d23 100644 --- a/chrome/browser/sessions/session_service_base.cc +++ b/chrome/browser/sessions/session_service_base.cc
@@ -47,6 +47,12 @@ #include "chrome/browser/app_controller_mac.h" #endif +// TODO(crbug.com/1424800): Remove once the restore issue has been resolved. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#undef ENABLED_VLOG_LEVEL +#define ENABLED_VLOG_LEVEL 1 +#endif + using base::Time; using content::NavigationEntry; using content::WebContents; @@ -321,6 +327,8 @@ sessions::GetLastSessionCallback callback) { // OnGotSessionCommands maps the SessionCommands to browser state, then run // the callback. + VLOG(1) << "SessionServiceBase::GetLastSession, getting session restore " + "commands."; return command_storage_manager_->GetLastSessionCommands( base::BindOnce(&SessionServiceBase::OnGotSessionCommands, weak_factory_.GetWeakPtr(), std::move(callback)));
diff --git a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java index 81ed6b6..f77e40b1 100644 --- a/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java +++ b/chrome/browser/share/android/java/src/org/chromium/chrome/browser/share/share_sheet/ChromeProvidedSharingOptionsProvider.java
@@ -173,7 +173,8 @@ mFeatureEngagementTracker.notifyEvent(EventConstants.SHARE_SCREENSHOT_SELECTED); ScreenshotCoordinator coordinator = new ScreenshotCoordinator(mActivity, mShareParams.getWindow(), mUrl, mChromeOptionShareCallback, - mBottomSheetController, mImageEditorModuleProvider); + mBottomSheetController, + usePolishedActionOrderedList() ? null : mImageEditorModuleProvider); mBottomSheetController.addObserver(coordinator); mBottomSheetController.hideContent(mBottomSheetContent, true); }) @@ -192,7 +193,8 @@ mFeatureEngagementTracker.notifyEvent(EventConstants.SHARE_SCREENSHOT_SELECTED); LongScreenshotsCoordinator coordinator = LongScreenshotsCoordinator.create( mActivity, mTabProvider.get(), mUrl, mChromeOptionShareCallback, - mBottomSheetController, mImageEditorModuleProvider); + mBottomSheetController, + usePolishedActionOrderedList() ? null : mImageEditorModuleProvider); mBottomSheetController.addObserver(coordinator); mBottomSheetController.hideContent(mBottomSheetContent, true); })
diff --git a/chrome/browser/ssl/ssl_browsertest.cc b/chrome/browser/ssl/ssl_browsertest.cc index f89a427..368f7c9 100644 --- a/chrome/browser/ssl/ssl_browsertest.cc +++ b/chrome/browser/ssl/ssl_browsertest.cc
@@ -2751,7 +2751,15 @@ // Tests that closing a page that opened a pop-up with an interstitial does not // crash the browser (crbug.com/1966). -IN_PROC_BROWSER_TEST_F(SSLUITest, TestCloseTabWithUnsafePopup) { +// TODO(crbug.com/1119359, crbug.com/1338068): Test is flaky on Linux and Chrome +// OS. +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || \ + BUILDFLAG(IS_CHROMEOS_LACROS) +#define MAYBE_TestCloseTabWithUnsafePopup DISABLED_TestCloseTabWithUnsafePopup +#else +#define MAYBE_TestCloseTabWithUnsafePopup TestCloseTabWithUnsafePopup +#endif +IN_PROC_BROWSER_TEST_F(SSLUITest, MAYBE_TestCloseTabWithUnsafePopup) { ASSERT_TRUE(embedded_test_server()->Start()); ASSERT_TRUE(https_server_expired_.Start());
diff --git a/chrome/browser/sync/bookmark_sync_service_factory.cc b/chrome/browser/sync/bookmark_sync_service_factory.cc index f09a696..a10cc2d4 100644 --- a/chrome/browser/sync/bookmark_sync_service_factory.cc +++ b/chrome/browser/sync/bookmark_sync_service_factory.cc
@@ -17,7 +17,8 @@ // static BookmarkSyncServiceFactory* BookmarkSyncServiceFactory::GetInstance() { - return base::Singleton<BookmarkSyncServiceFactory>::get(); + static base::NoDestructor<BookmarkSyncServiceFactory> instance; + return instance.get(); } BookmarkSyncServiceFactory::BookmarkSyncServiceFactory()
diff --git a/chrome/browser/sync/bookmark_sync_service_factory.h b/chrome/browser/sync/bookmark_sync_service_factory.h index 8bd9c65..cc463224 100644 --- a/chrome/browser/sync/bookmark_sync_service_factory.h +++ b/chrome/browser/sync/bookmark_sync_service_factory.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_SYNC_BOOKMARK_SYNC_SERVICE_FACTORY_H_ #define CHROME_BROWSER_SYNC_BOOKMARK_SYNC_SERVICE_FACTORY_H_ -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" class Profile; @@ -30,7 +30,7 @@ delete; private: - friend struct base::DefaultSingletonTraits<BookmarkSyncServiceFactory>; + friend base::NoDestructor<BookmarkSyncServiceFactory>; BookmarkSyncServiceFactory(); ~BookmarkSyncServiceFactory() override;
diff --git a/chrome/browser/sync/desk_sync_service_factory.cc b/chrome/browser/sync/desk_sync_service_factory.cc index d194903..a10b383 100644 --- a/chrome/browser/sync/desk_sync_service_factory.cc +++ b/chrome/browser/sync/desk_sync_service_factory.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/sync/desk_sync_service_factory.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/model_type_store_service_factory.h" #include "chrome/browser/ui/ash/multi_user/multi_user_util.h" @@ -21,7 +21,8 @@ // static DeskSyncServiceFactory* DeskSyncServiceFactory::GetInstance() { - return base::Singleton<DeskSyncServiceFactory>::get(); + static base::NoDestructor<DeskSyncServiceFactory> instance; + return instance.get(); } DeskSyncServiceFactory::DeskSyncServiceFactory()
diff --git a/chrome/browser/sync/desk_sync_service_factory.h b/chrome/browser/sync/desk_sync_service_factory.h index 379bdb5e..72f1f916 100644 --- a/chrome/browser/sync/desk_sync_service_factory.h +++ b/chrome/browser/sync/desk_sync_service_factory.h
@@ -11,7 +11,7 @@ namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base namespace desks_storage { @@ -25,7 +25,7 @@ static DeskSyncServiceFactory* GetInstance(); private: - friend struct base::DefaultSingletonTraits<DeskSyncServiceFactory>; + friend base::NoDestructor<DeskSyncServiceFactory>; DeskSyncServiceFactory(); DeskSyncServiceFactory(const DeskSyncServiceFactory&) = delete;
diff --git a/chrome/browser/sync/device_info_sync_service_factory.cc b/chrome/browser/sync/device_info_sync_service_factory.cc index 99b6d15..5d78518 100644 --- a/chrome/browser/sync/device_info_sync_service_factory.cc +++ b/chrome/browser/sync/device_info_sync_service_factory.cc
@@ -10,7 +10,7 @@ #include <vector> #include "base/functional/bind.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "base/time/default_clock.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -36,7 +36,8 @@ // static DeviceInfoSyncServiceFactory* DeviceInfoSyncServiceFactory::GetInstance() { - return base::Singleton<DeviceInfoSyncServiceFactory>::get(); + static base::NoDestructor<DeviceInfoSyncServiceFactory> instance; + return instance.get(); } // static
diff --git a/chrome/browser/sync/device_info_sync_service_factory.h b/chrome/browser/sync/device_info_sync_service_factory.h index 1c36504..36f8d0d0 100644 --- a/chrome/browser/sync/device_info_sync_service_factory.h +++ b/chrome/browser/sync/device_info_sync_service_factory.h
@@ -13,7 +13,7 @@ namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base namespace syncer { @@ -37,7 +37,7 @@ std::vector<const syncer::DeviceInfoTracker*>* trackers); private: - friend struct base::DefaultSingletonTraits<DeviceInfoSyncServiceFactory>; + friend base::NoDestructor<DeviceInfoSyncServiceFactory>; DeviceInfoSyncServiceFactory(); ~DeviceInfoSyncServiceFactory() override;
diff --git a/chrome/browser/sync/model_type_store_service_factory.cc b/chrome/browser/sync/model_type_store_service_factory.cc index fd6339b..acbf606c 100644 --- a/chrome/browser/sync/model_type_store_service_factory.cc +++ b/chrome/browser/sync/model_type_store_service_factory.cc
@@ -9,7 +9,8 @@ // static ModelTypeStoreServiceFactory* ModelTypeStoreServiceFactory::GetInstance() { - return base::Singleton<ModelTypeStoreServiceFactory>::get(); + static base::NoDestructor<ModelTypeStoreServiceFactory> instance; + return instance.get(); } // static
diff --git a/chrome/browser/sync/model_type_store_service_factory.h b/chrome/browser/sync/model_type_store_service_factory.h index 79b80d35..17f6525 100644 --- a/chrome/browser/sync/model_type_store_service_factory.h +++ b/chrome/browser/sync/model_type_store_service_factory.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_SYNC_MODEL_TYPE_STORE_SERVICE_FACTORY_H_ #define CHROME_BROWSER_SYNC_MODEL_TYPE_STORE_SERVICE_FACTORY_H_ -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" class Profile; @@ -24,7 +24,7 @@ delete; private: - friend struct base::DefaultSingletonTraits<ModelTypeStoreServiceFactory>; + friend base::NoDestructor<ModelTypeStoreServiceFactory>; ModelTypeStoreServiceFactory(); ~ModelTypeStoreServiceFactory() override;
diff --git a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc index 44a65344..b4bad4ac 100644 --- a/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc +++ b/chrome/browser/sync/send_tab_to_self_sync_service_factory.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/sync/send_tab_to_self_sync_service_factory.h" #include "base/functional/bind.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/history/history_service_factory.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/device_info_sync_service_factory.h" @@ -25,7 +25,8 @@ // static SendTabToSelfSyncServiceFactory* SendTabToSelfSyncServiceFactory::GetInstance() { - return base::Singleton<SendTabToSelfSyncServiceFactory>::get(); + static base::NoDestructor<SendTabToSelfSyncServiceFactory> instance; + return instance.get(); } SendTabToSelfSyncServiceFactory::SendTabToSelfSyncServiceFactory()
diff --git a/chrome/browser/sync/send_tab_to_self_sync_service_factory.h b/chrome/browser/sync/send_tab_to_self_sync_service_factory.h index 82076cba..b6f48da 100644 --- a/chrome/browser/sync/send_tab_to_self_sync_service_factory.h +++ b/chrome/browser/sync/send_tab_to_self_sync_service_factory.h
@@ -11,7 +11,7 @@ namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base namespace send_tab_to_self { @@ -30,7 +30,7 @@ const SendTabToSelfSyncServiceFactory&) = delete; private: - friend struct base::DefaultSingletonTraits<SendTabToSelfSyncServiceFactory>; + friend base::NoDestructor<SendTabToSelfSyncServiceFactory>; SendTabToSelfSyncServiceFactory(); ~SendTabToSelfSyncServiceFactory() override;
diff --git a/chrome/browser/sync/session_sync_service_factory.cc b/chrome/browser/sync/session_sync_service_factory.cc index 8838e1a..bc529ff 100644 --- a/chrome/browser/sync/session_sync_service_factory.cc +++ b/chrome/browser/sync/session_sync_service_factory.cc
@@ -5,7 +5,7 @@ #include "chrome/browser/sync/session_sync_service_factory.h" #include "base/memory/raw_ptr.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "build/build_config.h" #include "chrome/browser/favicon/favicon_service_factory.h" #include "chrome/browser/history/history_service_factory.h" @@ -128,7 +128,8 @@ // static SessionSyncServiceFactory* SessionSyncServiceFactory::GetInstance() { - return base::Singleton<SessionSyncServiceFactory>::get(); + static base::NoDestructor<SessionSyncServiceFactory> instance; + return instance.get(); } // static
diff --git a/chrome/browser/sync/session_sync_service_factory.h b/chrome/browser/sync/session_sync_service_factory.h index 0254412..a50e104 100644 --- a/chrome/browser/sync/session_sync_service_factory.h +++ b/chrome/browser/sync/session_sync_service_factory.h
@@ -12,7 +12,7 @@ namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base namespace sync_sessions { @@ -31,7 +31,7 @@ static bool ShouldSyncURLForTesting(const GURL& url); private: - friend struct base::DefaultSingletonTraits<SessionSyncServiceFactory>; + friend base::NoDestructor<SessionSyncServiceFactory>; SessionSyncServiceFactory(); ~SessionSyncServiceFactory() override;
diff --git a/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.cc b/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.cc index ac8ce91..d32affa5 100644 --- a/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.cc +++ b/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.cc
@@ -3,7 +3,7 @@ // found in the LICENSE file. #include "chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/sessions/sync_sessions_web_contents_router.h" @@ -19,7 +19,8 @@ // static SyncSessionsWebContentsRouterFactory* SyncSessionsWebContentsRouterFactory::GetInstance() { - return base::Singleton<SyncSessionsWebContentsRouterFactory>::get(); + static base::NoDestructor<SyncSessionsWebContentsRouterFactory> instance; + return instance.get(); } SyncSessionsWebContentsRouterFactory::SyncSessionsWebContentsRouterFactory()
diff --git a/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h b/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h index 4ff3d3fc..d461b551 100644 --- a/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h +++ b/chrome/browser/sync/sessions/sync_sessions_web_contents_router_factory.h
@@ -11,7 +11,7 @@ namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base namespace sync_sessions { @@ -33,8 +33,7 @@ const SyncSessionsWebContentsRouterFactory&) = delete; private: - friend struct base::DefaultSingletonTraits< - SyncSessionsWebContentsRouterFactory>; + friend base::NoDestructor<SyncSessionsWebContentsRouterFactory>; SyncSessionsWebContentsRouterFactory(); ~SyncSessionsWebContentsRouterFactory() override;
diff --git a/chrome/browser/sync/test/integration/ash_lacros_sync_test.cc b/chrome/browser/sync/test/integration/ash_lacros_sync_test.cc index 35ba19db..c9f69180 100644 --- a/chrome/browser/sync/test/integration/ash_lacros_sync_test.cc +++ b/chrome/browser/sync/test/integration/ash_lacros_sync_test.cc
@@ -136,8 +136,8 @@ EXPECT_EQ(sync_service->GetActiveDataTypes(), expected_active_types); } -// TODO(crbug.com/1450589): Flaky on linux_chromeOS bot -#if BUILDFLAG(IS_LINUX) && BUILDFLAG(IS_CHROMEOS) +// TODO(crbug.com/1450589): Flaky on ChromeOS bot +#if BUILDFLAG(IS_CHROMEOS) #define MAYBE_AshSyncsOnlyOSTypes DISABLED_AshSyncsOnlyOSTypes #else #define MAYBE_AshSyncsOnlyOSTypes AshSyncsOnlyOSTypes
diff --git a/chrome/browser/sync/user_event_service_factory.cc b/chrome/browser/sync/user_event_service_factory.cc index db8ac09e..d5f5526 100644 --- a/chrome/browser/sync/user_event_service_factory.cc +++ b/chrome/browser/sync/user_event_service_factory.cc
@@ -26,7 +26,8 @@ // static UserEventServiceFactory* UserEventServiceFactory::GetInstance() { - return base::Singleton<UserEventServiceFactory>::get(); + static base::NoDestructor<UserEventServiceFactory> instance; + return instance.get(); } // static
diff --git a/chrome/browser/sync/user_event_service_factory.h b/chrome/browser/sync/user_event_service_factory.h index 1234bfc7..7a8b790b 100644 --- a/chrome/browser/sync/user_event_service_factory.h +++ b/chrome/browser/sync/user_event_service_factory.h
@@ -5,7 +5,7 @@ #ifndef CHROME_BROWSER_SYNC_USER_EVENT_SERVICE_FACTORY_H_ #define CHROME_BROWSER_SYNC_USER_EVENT_SERVICE_FACTORY_H_ -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/profiles/profile_keyed_service_factory.h" class Profile; @@ -25,7 +25,7 @@ UserEventServiceFactory& operator=(const UserEventServiceFactory&) = delete; private: - friend struct base::DefaultSingletonTraits<UserEventServiceFactory>; + friend base::NoDestructor<UserEventServiceFactory>; UserEventServiceFactory(); ~UserEventServiceFactory() override;
diff --git a/chrome/browser/sync/wifi_configuration_sync_service_factory.cc b/chrome/browser/sync/wifi_configuration_sync_service_factory.cc index b6b6090..35eccb6e 100644 --- a/chrome/browser/sync/wifi_configuration_sync_service_factory.cc +++ b/chrome/browser/sync/wifi_configuration_sync_service_factory.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/sync/wifi_configuration_sync_service_factory.h" -#include "base/memory/singleton.h" +#include "base/no_destructor.h" #include "chrome/browser/ash/profiles/profile_helper.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/model_type_store_service_factory.h" @@ -31,7 +31,8 @@ // static WifiConfigurationSyncServiceFactory* WifiConfigurationSyncServiceFactory::GetInstance() { - return base::Singleton<WifiConfigurationSyncServiceFactory>::get(); + static base::NoDestructor<WifiConfigurationSyncServiceFactory> instance; + return instance.get(); } // static
diff --git a/chrome/browser/sync/wifi_configuration_sync_service_factory.h b/chrome/browser/sync/wifi_configuration_sync_service_factory.h index 75a3b5f..e3ce6b04 100644 --- a/chrome/browser/sync/wifi_configuration_sync_service_factory.h +++ b/chrome/browser/sync/wifi_configuration_sync_service_factory.h
@@ -15,7 +15,7 @@ namespace base { template <typename T> -struct DefaultSingletonTraits; +class NoDestructor; } // namespace base class WifiConfigurationSyncServiceFactory : public ProfileKeyedServiceFactory { @@ -33,8 +33,7 @@ static bool ShouldRunInProfile(const Profile* profile); private: - friend struct base::DefaultSingletonTraits< - WifiConfigurationSyncServiceFactory>; + friend base::NoDestructor<WifiConfigurationSyncServiceFactory>; WifiConfigurationSyncServiceFactory(); ~WifiConfigurationSyncServiceFactory() override;
diff --git a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java index fb712cf..ee2b13a 100644 --- a/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java +++ b/chrome/browser/tab/java/src/org/chromium/chrome/browser/tab/TabStateAttributes.java
@@ -52,7 +52,7 @@ /** Whether or not the TabState has changed. */ @DirtinessState - private int mDirtinessState; + private int mDirtinessState = DirtinessState.CLEAN; private WebContentsObserver mWebContentsObserver; private boolean mPendingLowPrioritySave; @@ -90,14 +90,12 @@ super(tab); mTab = tab; if (creationState == null || creationState == TabCreationState.FROZEN_FOR_LAZY_LOAD) { - mDirtinessState = DirtinessState.DIRTY; - CriticalPersistedTabData.from(mTab).setShouldSave(); + updateIsDirty(DirtinessState.DIRTY); } else if (creationState == TabCreationState.LIVE_IN_FOREGROUND || creationState == TabCreationState.LIVE_IN_BACKGROUND) { - mDirtinessState = DirtinessState.UNTIDY; + updateIsDirty(DirtinessState.UNTIDY); } else { assert creationState == TabCreationState.FROZEN_ON_RESTORE; - mDirtinessState = DirtinessState.CLEAN; } // TODO(crbug/1374456): Should this also handle mTab.getPendingLoadParams(), and ignore // URL updates when the URL matches the pending load?
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index 67dc4a2..78e01fb9 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -509,6 +509,13 @@ return profile_->GetPrefs()->GetInteger(prefs::kPolicyThemeColor); } +void ThemeService::SetBrowserColorScheme( + ThemeService::BrowserColorScheme color_scheme) { + profile_->GetPrefs()->SetInteger(prefs::kBrowserColorScheme, + static_cast<int>(color_scheme)); + NotifyThemeChanged(); +} + ThemeService::BrowserColorScheme ThemeService::GetBrowserColorScheme() const { return static_cast<BrowserColorScheme>( profile_->GetPrefs()->GetInteger(prefs::kBrowserColorScheme));
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h index c23f2d3..4e25f3f2 100644 --- a/chrome/browser/themes/theme_service.h +++ b/chrome/browser/themes/theme_service.h
@@ -185,8 +185,11 @@ // Returns the theme color for the current policy theme. virtual SkColor GetPolicyThemeColor() const; + // Sets the browser color scheme preference. + virtual void SetBrowserColorScheme(BrowserColorScheme color_scheme); + // Gets the browser color scheme preference. - BrowserColorScheme GetBrowserColorScheme() const; + virtual BrowserColorScheme GetBrowserColorScheme() const; // Returns |ThemeService::ThemeReinstaller| for the current theme. std::unique_ptr<ThemeService::ThemeReinstaller>
diff --git a/chrome/browser/themes/theme_service_unittest.cc b/chrome/browser/themes/theme_service_unittest.cc index 8902a73..a59d612 100644 --- a/chrome/browser/themes/theme_service_unittest.cc +++ b/chrome/browser/themes/theme_service_unittest.cc
@@ -779,4 +779,18 @@ EXPECT_TRUE(registry_->GetInstalledExtension(scoper.extension_id())); } +// Sets and gets browser color scheme. +TEST_F(ThemeServiceTest, SetBrowserColorScheme) { + // Default without anything explicitly set should be kSystem. + ThemeService::BrowserColorScheme color_scheme = + theme_service_->GetBrowserColorScheme(); + EXPECT_EQ(color_scheme, ThemeService::BrowserColorScheme::kSystem); + + // Set browser color scheme to light mode. + theme_service_->SetBrowserColorScheme( + ThemeService::BrowserColorScheme::kLight); + color_scheme = theme_service_->GetBrowserColorScheme(); + EXPECT_EQ(color_scheme, ThemeService::BrowserColorScheme::kLight); +} + } // namespace theme_service_internal
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc index 3a3183d4..3beb757 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate.cc
@@ -26,8 +26,8 @@ namespace { -using ShowVirtualKeyboard = - password_manager::PasswordManagerDriver::ShowVirtualKeyboard; +using ToShowVirtualKeyboard = + password_manager::PasswordManagerDriver::ToShowVirtualKeyboard; using autofill::mojom::SubmissionReadinessState; using password_manager::PasswordManagerDriver; using password_manager::UiCredential; @@ -230,7 +230,7 @@ password_manager::metrics_util::LogFilledCredentialIsFromAndroidApp( credential.is_affiliation_based_match().value()); - driver_->KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false)); + driver_->KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false)); driver_->FillSuggestion(credential.username(), credential.password()); @@ -256,6 +256,6 @@ bool show_virtual_keyboard) { std::exchange(driver_, nullptr) ->KeyboardReplacingSurfaceClosed( - ShowVirtualKeyboard(show_virtual_keyboard)); + ToShowVirtualKeyboard(show_virtual_keyboard)); base::UmaHistogramEnumeration("PasswordManager.TouchToFill.Outcome", outcome); }
diff --git a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc index e8de5115..417c83f1 100644 --- a/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc +++ b/chrome/browser/touch_to_fill/touch_to_fill_controller_autofill_delegate_unittest.cc
@@ -38,8 +38,8 @@ namespace { -using ShowVirtualKeyboard = - password_manager::PasswordManagerDriver::ShowVirtualKeyboard; +using ToShowVirtualKeyboard = + password_manager::PasswordManagerDriver::ToShowVirtualKeyboard; using autofill::mojom::SubmissionReadinessState; using base::test::RunOnceCallback; using device_reauth::DeviceAuthRequester; @@ -83,7 +83,7 @@ (override)); MOCK_METHOD(void, KeyboardReplacingSurfaceClosed, - (ShowVirtualKeyboard), + (ToShowVirtualKeyboard), (override)); MOCK_METHOD(void, TriggerFormSubmission, (), (override)); MOCK_METHOD(const GURL&, GetLastCommittedURL, (), (const override)); @@ -226,7 +226,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); touch_to_fill_controller().OnCredentialSelected(credentials[0]); histogram_tester().ExpectUniqueSample( "PasswordManager.TouchToFill.NumCredentialsShown", 1, 1); @@ -269,7 +269,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(driver(), TriggerFormSubmission()); EXPECT_CALL(client(), StartSubmissionTrackingAfterTouchToFill(Eq(u"alice"))); @@ -299,7 +299,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(driver(), TriggerFormSubmission()).Times(0); EXPECT_CALL(client(), StartSubmissionTrackingAfterTouchToFill(_)).Times(0); @@ -336,7 +336,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u""), std::u16string(u"p4ssw0rd"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); touch_to_fill_controller().OnCredentialSelected(credentials[0]); } @@ -368,7 +368,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u""), std::u16string(u"p4ssw0rd"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); touch_to_fill_controller().OnCredentialSelected(credentials[0]); } @@ -392,7 +392,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(*authenticator(), CanAuthenticateWithBiometrics) .WillOnce(Return(false)); @@ -430,7 +430,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"alice"), std::u16string(u"p4ssw0rd"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(*authenticator(), CanAuthenticateWithBiometrics) .WillOnce(Return(true)); @@ -462,7 +462,7 @@ EXPECT_CALL(driver(), FillSuggestion(_, _)).Times(0); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(true))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(true))); EXPECT_CALL(*authenticator(), CanAuthenticateWithBiometrics) .WillOnce(Return(true)); @@ -540,7 +540,7 @@ EXPECT_CALL(driver(), FillSuggestion(std::u16string(u"bob"), std::u16string(u"s3cr3t"))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(*authenticator(), CanAuthenticateWithBiometrics) .WillOnce(Return(false)); touch_to_fill_controller().OnCredentialSelected(credentials[1]); @@ -612,7 +612,7 @@ autofill::mojom::SubmissionReadinessState::kNoInformation)); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(true))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(true))); touch_to_fill_controller().OnDismiss(); auto entries = test_recorder().GetEntriesByName(UkmBuilder::kEntryName); @@ -648,7 +648,7 @@ autofill::mojom::SubmissionReadinessState::kNoInformation)); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(client(), NavigateToManagePasswordsPage( password_manager::ManagePasswordsReferrer::kTouchToFill)); @@ -723,7 +723,7 @@ EXPECT_CALL(*webauthn_credentials_delegate(), SelectPasskey(base::Base64Encode(credential.credential_id()))); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); touch_to_fill_controller().OnPasskeyCredentialSelected(credentials[0]); histogram_tester().ExpectUniqueSample( "PasswordManager.TouchToFill.NumCredentialsShown", 1, 1); @@ -762,7 +762,7 @@ credentials, {}, MakeTouchToFillControllerDelegate(submission_readiness)); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(false))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(false))); EXPECT_CALL(driver(), FillSuggestion(credential.username(), credential.password())); EXPECT_CALL(driver(), TriggerFormSubmission()) @@ -790,7 +790,7 @@ credentials, {}, MakeTouchToFillControllerDelegate(submission_readiness)); EXPECT_CALL(driver(), - KeyboardReplacingSurfaceClosed(ShowVirtualKeyboard(true))); + KeyboardReplacingSurfaceClosed(ToShowVirtualKeyboard(true))); touch_to_fill_controller().OnDismiss(); uma_recorder.ExpectUniqueSample(
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 9fd14ef..856dc0d 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1093,6 +1093,8 @@ "bookmarks/bookmark_editor.h", "bookmarks/bookmark_stats.cc", "bookmarks/bookmark_stats.h", + "bookmarks/bookmark_stats_tab_helper.cc", + "bookmarks/bookmark_stats_tab_helper.h", "bookmarks/bookmark_tab_helper.cc", "bookmarks/bookmark_tab_helper.h", "bookmarks/bookmark_tab_helper_observer.h", @@ -1994,13 +1996,7 @@ "//components/safety_check", "//components/saved_tab_groups:core", "//components/search_provider_logos", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:preferred_app", - "//components/services/app_service/public/cpp:preferred_apps", - "//components/services/app_service/public/cpp:run_on_os_login", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//components/supervised_user/core/common", "//components/ui_metrics", "//components/url_formatter", @@ -3034,6 +3030,10 @@ "webui/ash/login/parental_handoff_screen_handler.h", "webui/ash/login/pin_setup_screen_handler.cc", "webui/ash/login/pin_setup_screen_handler.h", + + # Template used by the `tools/oobe/generate_screen_template.py` script. + "webui/ash/login/placeholder_screen_handler.cc", + "webui/ash/login/placeholder_screen_handler.h", "webui/ash/login/quick_start_screen_handler.cc", "webui/ash/login/quick_start_screen_handler.h", "webui/ash/login/recommend_apps_screen_handler.cc", @@ -3578,11 +3578,7 @@ "//components/exo", "//components/login", "//components/metrics/structured:structured_events", - "//components/services/app_service/public/cpp:app_file_handling", - "//components/services/app_service/public/cpp:app_share_target", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_loader", - "//components/services/app_service/public/cpp:instance_update", + "//components/services/app_service", "//components/session_manager/core", "//components/supervised_user/core/browser:fetcher", "//components/tab_groups",
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java index 5e81efc7..fcf12ff 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/LocationBarLayout.java
@@ -339,11 +339,9 @@ // Set the left space expansion width. ViewGroup.LayoutParams leftSpacingParams = mStatusViewLeftSpace.getLayoutParams(); - int dimen = OmniboxResourceProvider.selectMarginDimen( - R.dimen.location_bar_status_view_left_space_width, - R.dimen.location_bar_status_view_left_space_width_bigger, - R.dimen.location_bar_status_view_left_space_width_bigger); - leftSpacingParams.width = (int) (getResources().getDimensionPixelSize(dimen) * percent); + int fullSpacing = OmniboxResourceProvider.getFocusedStatusViewLeftSpacing(getContext()); + + leftSpacingParams.width = (int) (fullSpacing * percent); mStatusViewLeftSpace.setLayoutParams(leftSpacingParams); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java index 3214b4bb..d70004e 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/OmniboxFeatures.java
@@ -105,24 +105,18 @@ /** * Returns whether smaller vertical and horizontal margins should be used in the visual update. */ - public static boolean shouldShowSmallerMargins() { - return MODERNIZE_VISUAL_UPDATE_SMALLER_MARGINS.getValue(); + public static boolean shouldShowSmallerMargins(Context context) { + return shouldShowModernizeVisualUpdate(context) + && MODERNIZE_VISUAL_UPDATE_SMALLER_MARGINS.getValue(); } /** * Returns whether even smaller vertical and horizontal margins should be used in the visual * update. */ - public static boolean shouldShowSmallestMargins() { - return MODERNIZE_VISUAL_UPDATE_SMALLEST_MARGINS.getValue(); - } - - /** - * Returns whether the clipboard suggestion should be grouped with other zero suggest items on - * the NTP or start surface in the visual update. - * */ - public static boolean shouldMergeClipboardOnNtp() { - return MODERNIZE_VISUAL_UPDATE_MERGE_CLIPBOARD_ON_NTP.getValue(); + public static boolean shouldShowSmallestMargins(Context context) { + return shouldShowModernizeVisualUpdate(context) + && MODERNIZE_VISUAL_UPDATE_SMALLEST_MARGINS.getValue(); } /** Returns whether the omnibox should directly consume IME (keyboard) insets. */
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java index a04a844..612eab3 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/styles/OmniboxResourceProvider.java
@@ -383,31 +383,45 @@ /** Gets the margin, in pixels, on either side of an omnibox suggestion. */ public static @Px int getSideSpacing(@NonNull Context context) { return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_suggestion_side_spacing, + selectMarginDimen(context, R.dimen.omnibox_suggestion_side_spacing, R.dimen.omnibox_suggestion_side_spacing_smaller, R.dimen.omnibox_suggestion_side_spacing_smallest)); } /** Gets the start padding for an omnibox suggestion's decoration icon. */ public static @Px int getIconStartPadding(Context context) { - return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_suggestion_24dp_icon_margin_start_modern_bigger, - R.dimen.omnibox_suggestion_24dp_icon_margin_start, - R.dimen.omnibox_suggestion_24dp_icon_margin_start)); + if (!OmniboxFeatures.shouldShowModernizeVisualUpdate(context)) { + return context.getResources().getDimensionPixelSize( + R.dimen.omnibox_suggestion_24dp_icon_margin_start); + } + return context.getResources().getDimensionPixelSize(selectMarginDimen(context, + R.dimen.omnibox_suggestion_24dp_icon_margin_start_modern_bigger, + R.dimen.omnibox_suggestion_24dp_icon_margin_start, + R.dimen.omnibox_suggestion_24dp_icon_margin_start)); } /** Gets the start padding for a large omnibox suggestion decoration icon. */ public static @Px int getLargeIconStartPadding(Context context) { - return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_suggestion_36dp_icon_margin_start_smallest, - R.dimen.omnibox_suggestion_36dp_icon_margin_start, - R.dimen.omnibox_suggestion_36dp_icon_margin_start)); + if (!OmniboxFeatures.shouldShowModernizeVisualUpdate(context)) { + return context.getResources().getDimensionPixelSize( + R.dimen.omnibox_suggestion_36dp_icon_margin_start); + } + + return context.getResources().getDimensionPixelSize(selectMarginDimen(context, + R.dimen.omnibox_suggestion_36dp_icon_margin_start_smallest, + R.dimen.omnibox_suggestion_36dp_icon_margin_start, + R.dimen.omnibox_suggestion_36dp_icon_margin_start)); } /** Gets the end padding for a large omnibox suggestion decoration icon. */ public static @Px int getLargeIconEndPadding(Context context) { + if (!OmniboxFeatures.shouldShowModernizeVisualUpdate(context)) { + return context.getResources().getDimensionPixelSize( + R.dimen.omnibox_suggestion_36dp_icon_margin_end); + } + return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_suggestion_36dp_icon_margin_end_smallest, + selectMarginDimen(context, R.dimen.omnibox_suggestion_36dp_icon_margin_end_smallest, R.dimen.omnibox_suggestion_36dp_icon_margin_end, R.dimen.omnibox_suggestion_36dp_icon_margin_end)); } @@ -415,7 +429,7 @@ /** Get the top margin for a suggestion that is the beginning of a group. */ public static int getSuggestionGroupTopMargin(Context context) { return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_suggestion_group_vertical_margin, + selectMarginDimen(context, R.dimen.omnibox_suggestion_group_vertical_margin, R.dimen.omnibox_suggestion_group_vertical_smaller_margin, R.dimen.omnibox_suggestion_group_vertical_smallest_margin)); } @@ -428,14 +442,14 @@ } return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_carousel_suggestion_padding_smaller, + selectMarginDimen(context, R.dimen.omnibox_carousel_suggestion_padding_smaller, R.dimen.omnibox_carousel_suggestion_padding_smallest, R.dimen.omnibox_carousel_suggestion_padding_smaller)); } /** Get the bottom padding for the MV carousel. */ public static @Px int getCarouselBottomPadding(Context context) { - if (OmniboxFeatures.shouldShowSmallerMargins()) { + if (OmniboxFeatures.shouldShowSmallerMargins(context)) { return 0; } @@ -447,27 +461,64 @@ } /** Get the top margin for first suggestion in the omnibox with "active color" enabled. */ - public static int getActiveOmniboxTopSmallMargin(Context context) { + public static @Px int getActiveOmniboxTopSmallMargin(Context context) { return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_suggestion_list_active_top_small_margin, + selectMarginDimen(context, R.dimen.omnibox_suggestion_list_active_top_small_margin, R.dimen.omnibox_suggestion_list_active_top_smaller_margin, R.dimen.omnibox_suggestion_list_active_top_small_margin)); } /** Gets the start padding for a header suggestion. */ - public static int getHeaderStartPadding(Context context) { + public static @Px int getHeaderStartPadding(Context context) { return context.getResources().getDimensionPixelSize( - selectMarginDimen(R.dimen.omnibox_suggestion_header_padding_start_modern, + selectMarginDimen(context, R.dimen.omnibox_suggestion_header_padding_start_modern, R.dimen.omnibox_suggestion_header_padding_start_modern_smaller, R.dimen.omnibox_suggestion_header_padding_start_modern_smallest)); } + /** + * Returns the size of the spacer on the left side of the status view when the omnibox is + * focused. + */ + public static @Px int getFocusedStatusViewLeftSpacing(Context context) { + return context.getResources().getDimensionPixelSize( + selectMarginDimen(context, R.dimen.location_bar_status_view_left_space_width, + R.dimen.location_bar_status_view_left_space_width_bigger, + R.dimen.location_bar_status_view_left_space_width_bigger)); + } + + /** + * Returns the amount of pixels the toolbar should increased its height by when the omnibox is + * focused. + */ + public static @Px int getToolbarOnFocusHeightIncrease(Context context) { + if (!OmniboxFeatures.shouldShowModernizeVisualUpdate(context)) { + return 0; + } + + return context.getResources().getDimensionPixelSize( + OmniboxFeatures.shouldShowActiveColorOnOmnibox() + ? R.dimen.toolbar_url_focus_height_increase_active_color + : R.dimen.toolbar_url_focus_height_increase_no_active_color); + } + + /** Returns the amount of pixels for the toolbar's side padding when the omnibox is focused. */ + public static @Px int getToolbarSidePadding(Context context) { + return context.getResources().getDimensionPixelSize( + OmniboxFeatures.shouldShowModernizeVisualUpdate(context) + ? OmniboxResourceProvider.selectMarginDimen(context, + R.dimen.toolbar_edge_padding_modern, + R.dimen.toolbar_edge_padding_modern_smaller, + R.dimen.toolbar_edge_padding) + : R.dimen.toolbar_edge_padding); + } + /** */ public static @DimenRes int selectMarginDimen( - @DimenRes int regular, @DimenRes int smaller, @DimenRes int smallest) { - if (OmniboxFeatures.shouldShowSmallestMargins()) { + Context context, @DimenRes int regular, @DimenRes int smaller, @DimenRes int smallest) { + if (OmniboxFeatures.shouldShowSmallestMargins(context)) { return smallest; - } else if (OmniboxFeatures.shouldShowSmallerMargins()) { + } else if (OmniboxFeatures.shouldShowSmallerMargins(context)) { return smaller; } return regular;
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java index 9b7e40f..2676af5c 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/DropdownItemViewInfoListManager.java
@@ -111,7 +111,7 @@ ? SuggestionCommonProperties.FormFactor.TABLET : SuggestionCommonProperties.FormFactor.PHONE; DropdownItemViewInfo previousItem = null; - boolean useSmallestMargins = OmniboxFeatures.shouldShowSmallestMargins(); + boolean useSmallestMargins = OmniboxFeatures.shouldShowSmallestMargins(mContext); int groupTopMargin = OmniboxResourceProvider.getSuggestionGroupTopMargin(mContext); int groupBottomMargin = mContext.getResources().getDimensionPixelSize( R.dimen.omnibox_suggestion_group_vertical_smallest_margin); @@ -168,7 +168,7 @@ previousItemWasHeader = item.processor.getViewTypeId() == OmniboxSuggestionUiType.HEADER && shouldShowModernizeVisualUpdate - && (useSmallestMargins || OmniboxFeatures.shouldShowSmallerMargins()); + && (useSmallestMargins || OmniboxFeatures.shouldShowSmallerMargins(mContext)); suggestionsList.add(item); } @@ -194,15 +194,16 @@ */ private @Px int getSuggestionListTopMargin(@OmniboxSuggestionUiType int firstSuggestionUiType) { if (firstSuggestionUiType == OmniboxSuggestionUiType.EDIT_URL_SUGGESTION) { - return OmniboxFeatures.shouldShowSmallerMargins() ? mListActiveOmniboxTopSmallMargin - : 0; + return OmniboxFeatures.shouldShowSmallerMargins(mContext) + ? mListActiveOmniboxTopSmallMargin + : 0; } if (OmniboxFeatures.shouldShowActiveColorOnOmnibox()) { - if (OmniboxFeatures.shouldShowSmallestMargins()) { + if (OmniboxFeatures.shouldShowSmallestMargins(mContext)) { return 0; } else if (OmniboxFeatures.shouldShowSmallBottomMargin() - || OmniboxFeatures.shouldShowSmallerMargins()) { + || OmniboxFeatures.shouldShowSmallerMargins(mContext)) { return mListActiveOmniboxTopSmallMargin; } else { return mListActiveOmniboxTopBigMargin;
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java index 4e3242d6..675dffe 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/OmniboxSuggestionsDropdownAdapter.java
@@ -37,7 +37,7 @@ super.onAttachedToRecyclerView(view); mLayoutManager = view.getLayoutManager(); mSelectedItem = RecyclerView.NO_POSITION; - if (OmniboxFeatures.shouldShowSmallestMargins()) { + if (OmniboxFeatures.shouldShowSmallestMargins(view.getContext())) { view.addItemDecoration(new SuggestionHorizontalDivider(view.getContext())); } }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersAction.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersAction.java index a59ae77..f2218b6 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersAction.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersAction.java
@@ -26,8 +26,10 @@ /** Associated user query, guaranteed to be a non-empty string. */ public final @NonNull String query; - public HistoryClustersAction(long nativeInstance, @NonNull String hint, @NonNull String query) { - super(OmniboxActionId.HISTORY_CLUSTERS, nativeInstance, hint, JOURNEYS_ICON); + public HistoryClustersAction(long nativeInstance, @NonNull String hint, + @NonNull String accessibilityHint, @NonNull String query) { + super(OmniboxActionId.HISTORY_CLUSTERS, nativeInstance, hint, accessibilityHint, + JOURNEYS_ICON); assert !TextUtils.isEmpty(query); this.query = query; }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersActionUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersActionUnitTest.java index 5182692..309c30e 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersActionUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/HistoryClustersActionUnitTest.java
@@ -33,28 +33,32 @@ @Test public void creation_usesExpectedIcon() { - var action = new HistoryClustersAction(0, "hint", "query"); + var action = new HistoryClustersAction(0, "hint", "accessibility", "query"); assertEquals(HistoryClustersAction.JOURNEYS_ICON, action.icon); } @Test public void creation_failsWithNullHint() { - assertThrows(AssertionError.class, () -> new HistoryClustersAction(0, null, "query")); + assertThrows(AssertionError.class, + () -> new HistoryClustersAction(0, null, "accessibility", "query")); } @Test public void creation_failsWithEmptyHint() { - assertThrows(AssertionError.class, () -> new HistoryClustersAction(0, "", "query")); + assertThrows(AssertionError.class, + () -> new HistoryClustersAction(0, "", "accessibility", "query")); } @Test public void creation_failsWithNullQuery() { - assertThrows(AssertionError.class, () -> new HistoryClustersAction(0, "hint", null)); + assertThrows(AssertionError.class, + () -> new HistoryClustersAction(0, "hint", "accessibility", null)); } @Test public void creation_failsWithEmptyQuery() { - assertThrows(AssertionError.class, () -> new HistoryClustersAction(0, "hint", "")); + assertThrows(AssertionError.class, + () -> new HistoryClustersAction(0, "hint", "accessibility", "")); } @Test @@ -66,23 +70,23 @@ public void safeCasting_assertsWithWrongClassType() { assertThrows(AssertionError.class, () - -> HistoryClustersAction.from( - new OmniboxAction(OmniboxActionId.HISTORY_CLUSTERS, 0, "", null) { - @Override - public void execute(OmniboxActionDelegate d) {} - })); + -> HistoryClustersAction.from(new OmniboxAction( + OmniboxActionId.HISTORY_CLUSTERS, 0, "", "", null) { + @Override + public void execute(OmniboxActionDelegate d) {} + })); } @Test public void safeCasting_successWithFactoryBuiltAction() { - HistoryClustersAction.from( - OmniboxActionFactoryImpl.get().buildHistoryClustersAction(0, "hint", "query")); + HistoryClustersAction.from(OmniboxActionFactoryImpl.get().buildHistoryClustersAction( + 0, "hint", "accessibility", "query")); } @Test public void executeHistoryClusters() { String testJourneyName = "example journey name"; - var action = new HistoryClustersAction(0, "hint", testJourneyName); + var action = new HistoryClustersAction(0, "hint", "accessibility", testJourneyName); action.execute(mDelegate); verify(mDelegate).openHistoryClustersPage(testJourneyName); verifyNoMoreInteractions(mDelegate);
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImpl.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImpl.java index 8307fb0..bc9c6f6 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImpl.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImpl.java
@@ -56,23 +56,25 @@ } @Override - public @Nullable OmniboxAction buildOmniboxPedal( - long nativeInstance, @NonNull String hint, @OmniboxPedalId int pedalId) { - return new OmniboxPedal(nativeInstance, hint, pedalId); + public @Nullable OmniboxAction buildOmniboxPedal(long nativeInstance, @NonNull String hint, + @NonNull String accessibilityHint, @OmniboxPedalId int pedalId) { + return new OmniboxPedal(nativeInstance, hint, accessibilityHint, pedalId); } @Override public @Nullable OmniboxAction buildActionInSuggest(long nativeInstance, @NonNull String hint, + @NonNull String accessibilityHint, /* EntityInfoProto.ActionInfo.ActionType */ int actionType, @NonNull String actionUri) { if (actionType == EntityInfoProto.ActionInfo.ActionType.CALL_VALUE && !mDialerAvailable) { return null; } - return new OmniboxActionInSuggest(nativeInstance, hint, actionType, actionUri); + return new OmniboxActionInSuggest( + nativeInstance, hint, accessibilityHint, actionType, actionUri); } @Override - public @Nullable OmniboxAction buildHistoryClustersAction( - long nativeInstance, @NonNull String hint, @NonNull String query) { - return new HistoryClustersAction(nativeInstance, hint, query); + public @Nullable OmniboxAction buildHistoryClustersAction(long nativeInstance, + @NonNull String hint, @NonNull String accessibilityHint, @NonNull String query) { + return new HistoryClustersAction(nativeInstance, hint, accessibilityHint, query); } }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImplUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImplUnitTest.java index 0a176f4..72f9fac 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImplUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionFactoryImplUnitTest.java
@@ -75,34 +75,37 @@ // The underlying code will throw if instance is not valid. // Checking for null in case that changes. assertNotNull(HistoryClustersAction.from( - OmniboxActionFactoryImpl.get().buildHistoryClustersAction(0, "hint", "query"))); + OmniboxActionFactoryImpl.get().buildHistoryClustersAction( + 0, "hint", "accessibility", "query"))); } @Test public void omniboxPedalsDowncasting() { // The underlying code will throw if instance is not valid. // Checking for null in case that changes. - assertNotNull( - OmniboxPedal.from(OmniboxActionFactoryImpl.get().buildOmniboxPedal(0, "hint", 1))); + assertNotNull(OmniboxPedal.from( + OmniboxActionFactoryImpl.get().buildOmniboxPedal(0, "hint", "accessibility", 1))); } @Test public void omniboxActionInSuggestDowncasting() { // The underlying code will throw if instance is not valid. // Checking for null in case that changes. - assertNotNull(OmniboxActionInSuggest.from( - OmniboxActionFactoryImpl.get().buildActionInSuggest(0, "hint", 1, "url"))); + assertNotNull( + OmniboxActionInSuggest.from(OmniboxActionFactoryImpl.get().buildActionInSuggest( + 0, "hint", "accessibility", 1, "url"))); } @Test public void actionInSuggest_callActionNotCreatedWhenDialerUnavailable() { - assertNull(OmniboxActionFactoryImpl.get().setDialerAvailable(false).buildActionInSuggest( - 0, "hint", EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, "url")); + assertNull(OmniboxActionFactoryImpl.get().setDialerAvailable(false).buildActionInSuggest(0, + "hint", "accessibility", EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, "url")); } @Test public void actionInSuggest_callActionCreatedWhenDialerAvailable() { assertNotNull(OmniboxActionFactoryImpl.get().setDialerAvailable(true).buildActionInSuggest( - 0, "hint", EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, "url")); + 0, "hint", "accessibility", EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, + "url")); } }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggest.java index 781ccb3..a9982d8 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggest.java
@@ -29,8 +29,9 @@ private final @NonNull String mActionUri; public OmniboxActionInSuggest(long nativeInstance, @NonNull String hint, + @NonNull String accessibilityHint, /* EntityInfoProto.ActionInfo.ActionType */ int actionType, @NonNull String actionUri) { - super(OmniboxActionId.ACTION_IN_SUGGEST, nativeInstance, hint, + super(OmniboxActionId.ACTION_IN_SUGGEST, nativeInstance, hint, accessibilityHint, ICON_MAP.get(actionType, null)); this.actionType = actionType; mActionUri = actionUri;
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggestUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggestUnitTest.java index fca88f3e..7b41757 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggestUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxActionInSuggestUnitTest.java
@@ -59,7 +59,8 @@ @Test public void creation_usesCustomIconForKnownActionTypes() { for (var kesemActionType : sKnownActionTypes) { - var action = new OmniboxActionInSuggest(0, "hint", kesemActionType, ""); + var action = + new OmniboxActionInSuggest(0, "hint", "accessibility", kesemActionType, ""); assertNotEquals(OmniboxAction.DEFAULT_ICON, action.icon); } } @@ -68,7 +69,8 @@ public void creation_usesFallbackIconForUnknownActionTypes() { for (var kesemActionType : EntityInfoProto.ActionInfo.ActionType.values()) { if (sKnownActionTypes.contains(kesemActionType.getNumber())) continue; - var action = new OmniboxActionInSuggest(0, "hint", kesemActionType.getNumber(), ""); + var action = new OmniboxActionInSuggest( + 0, "hint", "accessibility", kesemActionType.getNumber(), ""); assertEquals(OmniboxAction.DEFAULT_ICON, action.icon); } } @@ -78,7 +80,7 @@ assertThrows(AssertionError.class, () -> new OmniboxActionInSuggest( - 0, null, EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, "")); + 0, null, "", EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, "")); } @Test @@ -86,7 +88,7 @@ assertThrows(AssertionError.class, () -> new OmniboxActionInSuggest( - 0, "", EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, "")); + 0, "", "", EntityInfoProto.ActionInfo.ActionType.CALL_VALUE, "")); } @Test @@ -99,7 +101,8 @@ assertThrows(AssertionError.class, () -> OmniboxActionInSuggest.from(new OmniboxAction( - OmniboxActionId.ACTION_IN_SUGGEST, 0, "hint", null) { + OmniboxActionId.ACTION_IN_SUGGEST, 0, "hint", "accessibility", + null) { @Override public void execute(OmniboxActionDelegate d) {} })); @@ -107,8 +110,8 @@ @Test public void safeCasting_successWithFactoryBuiltAction() { - OmniboxActionInSuggest.from(OmniboxActionFactoryImpl.get().buildActionInSuggest( - 0, "hint", EntityInfoProto.ActionInfo.ActionType.REVIEWS_VALUE, "")); + OmniboxActionInSuggest.from(OmniboxActionFactoryImpl.get().buildActionInSuggest(0, "hint", + "accessibility", EntityInfoProto.ActionInfo.ActionType.REVIEWS_VALUE, "")); } /** @@ -117,7 +120,7 @@ private OmniboxAction buildActionInSuggest( EntityInfoProto.ActionInfo.ActionType type, Intent intent) { var uri = intent.toUri(Intent.URI_INTENT_SCHEME); - return new OmniboxActionInSuggest(0, "wink", type.getNumber(), uri); + return new OmniboxActionInSuggest(0, "wink", "accessibility", type.getNumber(), uri); } @Test
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedal.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedal.java index 9685bcc..53e1646 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedal.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedal.java
@@ -25,8 +25,9 @@ /** The type of the underlying pedal. */ public final @OmniboxPedalId int pedalId; - public OmniboxPedal(long nativeInstance, @NonNull String hint, @OmniboxPedalId int pedalId) { - super(OmniboxActionId.PEDAL, nativeInstance, hint, + public OmniboxPedal(long nativeInstance, @NonNull String hint, + @NonNull String accessibilityHint, @OmniboxPedalId int pedalId) { + super(OmniboxActionId.PEDAL, nativeInstance, hint, accessibilityHint, pedalId == OmniboxPedalId.PLAY_CHROME_DINO_GAME ? DINO_GAME_ICON : null); this.pedalId = pedalId; }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedalUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedalUnitTest.java index 39c56787..bc0b78c 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedalUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/action/OmniboxPedalUnitTest.java
@@ -42,27 +42,31 @@ @Test public void creation_usesExpectedCustomIconForDinoGame() { assertEquals(OmniboxPedal.DINO_GAME_ICON, - new OmniboxPedal(0, "hint", OmniboxPedalId.PLAY_CHROME_DINO_GAME).icon); + new OmniboxPedal(0, "hint", "accessibility", OmniboxPedalId.PLAY_CHROME_DINO_GAME) + .icon); } @Test public void creation_usesDefaultIconForAllNonCustomizedCases() { for (int type = OmniboxPedalId.NONE; type < OmniboxPedalId.TOTAL_COUNT; type++) { if (sPedalsWithCustomIcons.contains(type)) continue; - assertEquals(OmniboxAction.DEFAULT_ICON, new OmniboxPedal(0, "hint", type).icon); + assertEquals(OmniboxAction.DEFAULT_ICON, + new OmniboxPedal(0, "hint", "accessibility", type).icon); } } @Test public void creation_failsWithNullHint() { assertThrows(AssertionError.class, - () -> new OmniboxPedal(0, null, OmniboxPedalId.CLEAR_BROWSING_DATA)); + () + -> new OmniboxPedal( + 0, null, "accessibility", OmniboxPedalId.CLEAR_BROWSING_DATA)); } @Test public void creation_failsWithEmptyHint() { assertThrows(AssertionError.class, - () -> new OmniboxPedal(0, "", OmniboxPedalId.CLEAR_BROWSING_DATA)); + () -> new OmniboxPedal(0, "", "accessibility", OmniboxPedalId.CLEAR_BROWSING_DATA)); } @Test @@ -73,7 +77,7 @@ @Test public void safeCasting_assertsWithWrongClassType() { assertThrows(AssertionError.class, - () -> OmniboxPedal.from(new OmniboxAction(OmniboxActionId.PEDAL, 0, "", null) { + () -> OmniboxPedal.from(new OmniboxAction(OmniboxActionId.PEDAL, 0, "", "", null) { @Override public void execute(OmniboxActionDelegate d) {} })); @@ -81,76 +85,77 @@ @Test public void safeCasting_successWithFactoryBuiltAction() { - OmniboxPedal.from( - OmniboxActionFactoryImpl.get().buildOmniboxPedal(0, "hint", OmniboxPedalId.NONE)); + OmniboxPedal.from(OmniboxActionFactoryImpl.get().buildOmniboxPedal( + 0, "hint", "accessibility", OmniboxPedalId.NONE)); } @Test public void executePedal_manageChromeSettings() { - new OmniboxPedal(0, "hint", OmniboxPedalId.MANAGE_CHROME_SETTINGS).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.MANAGE_CHROME_SETTINGS).execute(mDelegate); verify(mDelegate, times(1)).openSettingsPage(SettingsFragment.MAIN); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_clearBrowsingData() { - new OmniboxPedal(0, "hint", OmniboxPedalId.CLEAR_BROWSING_DATA).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.CLEAR_BROWSING_DATA).execute(mDelegate); verify(mDelegate, times(1)).openSettingsPage(SettingsFragment.CLEAR_BROWSING_DATA); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_managePasswords() { - new OmniboxPedal(0, "hint", OmniboxPedalId.MANAGE_PASSWORDS).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.MANAGE_PASSWORDS).execute(mDelegate); verify(mDelegate, times(1)).openPasswordManager(); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_updateCreditCard() { - new OmniboxPedal(0, "hint", OmniboxPedalId.UPDATE_CREDIT_CARD).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.UPDATE_CREDIT_CARD).execute(mDelegate); verify(mDelegate, times(1)).openSettingsPage(SettingsFragment.PAYMENT_METHODS); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_runChromeSafetyCheck() { - new OmniboxPedal(0, "hint", OmniboxPedalId.RUN_CHROME_SAFETY_CHECK).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.RUN_CHROME_SAFETY_CHECK).execute(mDelegate); verify(mDelegate, times(1)).openSettingsPage(SettingsFragment.SAFETY_CHECK); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_manageSiteSettings() { - new OmniboxPedal(0, "hint", OmniboxPedalId.MANAGE_SITE_SETTINGS).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.MANAGE_SITE_SETTINGS).execute(mDelegate); verify(mDelegate, times(1)).openSettingsPage(SettingsFragment.SITE); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_manageChromeAccessibility() { - new OmniboxPedal(0, "hint", OmniboxPedalId.MANAGE_CHROME_ACCESSIBILITY).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.MANAGE_CHROME_ACCESSIBILITY) + .execute(mDelegate); verify(mDelegate, times(1)).openSettingsPage(SettingsFragment.ACCESSIBILITY); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_launchIncognito() { - new OmniboxPedal(0, "hint", OmniboxPedalId.LAUNCH_INCOGNITO).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.LAUNCH_INCOGNITO).execute(mDelegate); verify(mDelegate, times(1)).openIncognitoTab(); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_viewChromeHistory() { - new OmniboxPedal(0, "hint", OmniboxPedalId.VIEW_CHROME_HISTORY).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.VIEW_CHROME_HISTORY).execute(mDelegate); verify(mDelegate, times(1)).loadPageInCurrentTab(UrlConstants.HISTORY_URL); verifyNoMoreInteractions(mDelegate); } @Test public void executePedal_playChromeDinoGame() { - new OmniboxPedal(0, "hint", OmniboxPedalId.PLAY_CHROME_DINO_GAME).execute(mDelegate); + new OmniboxPedal(0, "hint", "", OmniboxPedalId.PLAY_CHROME_DINO_GAME).execute(mDelegate); verify(mDelegate, times(1)).loadPageInCurrentTab(UrlConstants.CHROME_DINO_URL); verifyNoMoreInteractions(mDelegate); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java index f9f3d55..08c6d7ad 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/ActionChipsProcessor.java
@@ -10,7 +10,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.chromium.chrome.browser.omnibox.R; import org.chromium.chrome.browser.omnibox.suggestions.SuggestionHost; import org.chromium.components.browser_ui.widget.chips.ChipProperties; import org.chromium.components.omnibox.AutocompleteMatch; @@ -74,9 +73,7 @@ final var chipModel = new PropertyModel.Builder(ChipProperties.ALL_KEYS) .with(ChipProperties.TEXT, chip.hint) - .with(ChipProperties.CONTENT_DESCRIPTION, - mContext.getString( - R.string.accessibility_omnibox_pedal, chip.hint)) + .with(ChipProperties.CONTENT_DESCRIPTION, chip.accessibilityHint) .with(ChipProperties.ENABLED, true) .with(ChipProperties.CLICK_HANDLER, m -> executeAction(chip, position)) .with(ChipProperties.ICON, chip.icon.iconRes)
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewBinderUnitTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewBinderUnitTest.java index 4e6f018..3a48af6 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewBinderUnitTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/BaseSuggestionViewBinderUnitTest.java
@@ -469,4 +469,102 @@ Assert.assertEquals(state1, state2); } + + @Test + public void iconPadding() { + BaseSuggestionViewBinder.initializeDimensions(mActivity); + int startPadding = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_24dp_icon_margin_start); + int startPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_start); + int endPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_end); + + SuggestionDrawableState smallState = + SuggestionDrawableState.Builder.forColor(0).setUseRoundedCorners(true).build(); + mModel.set(BaseSuggestionViewProperties.ICON, smallState); + verify(mIconView).setPadding(startPadding, 0, startPadding, 0); + + SuggestionDrawableState largeState = SuggestionDrawableState.Builder.forColor(0) + .setUseRoundedCorners(true) + .setLarge(true) + .build(); + mModel.set(BaseSuggestionViewProperties.ICON, largeState); + verify(mIconView).setPadding(startPaddingLarge, 0, endPaddingLarge, 0); + } + + @Test + @EnableFeatures(ChromeFeatureList.OMNIBOX_MODERNIZE_VISUAL_UPDATE) + public void iconStartPadding_smallestMarginsRevamp() { + OmniboxFeatures.MODERNIZE_VISUAL_UPDATE_SMALLEST_MARGINS.setForTesting(true); + BaseSuggestionViewBinder.initializeDimensions(mActivity); + int padding = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_24dp_icon_margin_start); + int startPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_start); + int endPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_start); + + SuggestionDrawableState smallState = + SuggestionDrawableState.Builder.forColor(0).setUseRoundedCorners(true).build(); + mModel.set(BaseSuggestionViewProperties.ICON, smallState); + verify(mIconView).setPadding(padding, 0, padding, 0); + + SuggestionDrawableState largeState = SuggestionDrawableState.Builder.forColor(0) + .setUseRoundedCorners(true) + .setLarge(true) + .build(); + mModel.set(BaseSuggestionViewProperties.ICON, largeState); + verify(mIconView).setPadding(startPaddingLarge, 0, endPaddingLarge, 0); + } + + @Test + @EnableFeatures(ChromeFeatureList.OMNIBOX_MODERNIZE_VISUAL_UPDATE) + public void iconStartPadding_smallerMarginsRevamp() { + OmniboxFeatures.MODERNIZE_VISUAL_UPDATE_SMALLEST_MARGINS.setForTesting(true); + BaseSuggestionViewBinder.initializeDimensions(mActivity); + int startPadding = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_24dp_icon_margin_start); + int startPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_start); + int endPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_start); + + SuggestionDrawableState smallState = + SuggestionDrawableState.Builder.forColor(0).setUseRoundedCorners(true).build(); + mModel.set(BaseSuggestionViewProperties.ICON, smallState); + verify(mIconView).setPadding(startPadding, 0, startPadding, 0); + + SuggestionDrawableState largeState = SuggestionDrawableState.Builder.forColor(0) + .setUseRoundedCorners(true) + .setLarge(true) + .build(); + mModel.set(BaseSuggestionViewProperties.ICON, largeState); + verify(mIconView).setPadding(startPaddingLarge, 0, endPaddingLarge, 0); + } + + @Test + @EnableFeatures(ChromeFeatureList.OMNIBOX_MODERNIZE_VISUAL_UPDATE) + @Config(qualifiers = "w600dp-h820dp") + public void iconStartPadding_tabletRevamp() { + BaseSuggestionViewBinder.initializeDimensions(mActivity); + int startPadding = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_24dp_icon_margin_start); + int startPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_start); + int endPaddingLarge = + mResources.getDimensionPixelSize(R.dimen.omnibox_suggestion_36dp_icon_margin_end); + + SuggestionDrawableState smallState = + SuggestionDrawableState.Builder.forColor(0).setUseRoundedCorners(true).build(); + mModel.set(BaseSuggestionViewProperties.ICON, smallState); + verify(mIconView).setPadding(startPadding, 0, startPadding, 0); + + SuggestionDrawableState largeState = SuggestionDrawableState.Builder.forColor(0) + .setUseRoundedCorners(true) + .setLarge(true) + .build(); + mModel.set(BaseSuggestionViewProperties.ICON, largeState); + verify(mIconView).setPadding(startPaddingLarge, 0, endPaddingLarge, 0); + } }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/HistoryClustersProcessorTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/HistoryClustersProcessorTest.java index 7ac6722..1f919969 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/HistoryClustersProcessorTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/HistoryClustersProcessorTest.java
@@ -134,7 +134,8 @@ return AutocompleteMatchBuilder.searchWithType(OmniboxSuggestionType.SEARCH_WHAT_YOU_TYPED) .setDisplayText(query) .setIsSearch(true) - .setActions(Arrays.asList(new HistoryClustersAction(0, "hint", query))) + .setActions( + Arrays.asList(new HistoryClustersAction(0, "hint", "accessibility", query))) .build(); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/SuggestionLayout.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/SuggestionLayout.java index fdb16ab..cf032bf 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/SuggestionLayout.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/suggestions/base/SuggestionLayout.java
@@ -6,7 +6,6 @@ import android.content.Context; import android.graphics.Rect; -import android.view.View.MeasureSpec; import android.view.ViewGroup; import androidx.annotation.IntDef;
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 5e1c4c8..2ababf7 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -4142,9 +4142,6 @@ <message name="IDS_ACCESSIBILITY_OMNIBOX_SHOWING_SUGGESTIONS_FOR_WEBSITE" desc="Whenever the User is visiting a Website, when they click the Omnibox, we will announce this message, if we have suggestions to show."> Showing suggestions for <ph name="WEBSITE_TITLE">%1$s<ex>Crater Lake National Park (U.S. National Park Service)</ex></ph> </message> - <message name="IDS_ACCESSIBILITY_OMNIBOX_PEDAL" desc="Announce focused Chrome Action Button on the Omnibox Suggestions List. List of known Action buttons is defined here: https://source.chromium.org/chromium/chromium/src/+/main:chrome/browser/ui/omnibox/omnibox_pedal_implementations.cc"> - Chrome action button: <ph name="ACTION">%s<ex>clear browsing data</ex></ph> - </message> <message name="IDS_ACCESSIBILITY_OMNIBOX_SUGGESTED_ITEMS" desc="Announcement about the presence and volume of suggestions below the Omnibox."> <ph name="SUGGESTIONS_COUNT">%d<ex>12</ex></ph> suggested items in list below. </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_OMNIBOX_PEDAL.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_OMNIBOX_PEDAL.png.sha1 deleted file mode 100644 index 30eb4ab..0000000 --- a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_ACCESSIBILITY_OMNIBOX_PEDAL.png.sha1 +++ /dev/null
@@ -1 +0,0 @@ -b98b9d86e06782c7aae72662b0da0214ce2acc17 \ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java index ecc029b..804935b 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarPhone.java
@@ -302,18 +302,9 @@ public ToolbarPhone(Context context, AttributeSet attrs) { super(context, attrs); mShouldShowModernizeVisualUpdate = OmniboxFeatures.shouldShowModernizeVisualUpdate(context); - final int edgePaddingRes = mShouldShowModernizeVisualUpdate - ? OmniboxResourceProvider.selectMarginDimen(R.dimen.toolbar_edge_padding_modern, - R.dimen.toolbar_edge_padding_modern_smaller, R.dimen.toolbar_edge_padding) - : R.dimen.toolbar_edge_padding; - mToolbarSidePadding = getResources().getDimensionPixelOffset(edgePaddingRes); - - mBackgroundHeightIncreaseWhenFocus = mShouldShowModernizeVisualUpdate - ? getResources().getDimensionPixelSize( - OmniboxFeatures.shouldShowActiveColorOnOmnibox() - ? R.dimen.toolbar_url_focus_height_increase_active_color - : R.dimen.toolbar_url_focus_height_increase_no_active_color) - : 0; + mToolbarSidePadding = OmniboxResourceProvider.getToolbarSidePadding(context); + mBackgroundHeightIncreaseWhenFocus = + OmniboxResourceProvider.getToolbarOnFocusHeightIncrease(context); } @Override
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc index ec02510..5311411 100644 --- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc +++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view.cc
@@ -13,6 +13,7 @@ #include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" #include "ash/style/ash_color_provider.h" #include "ash/style/typography.h" +#include "base/check_op.h" #include "base/i18n/rtl.h" #include "base/memory/raw_ptr.h" #include "base/scoped_observation.h" @@ -190,14 +191,9 @@ main_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( views::BoxLayout::Orientation::kVertical)); - // TODO(melzhang): Clean this up after MTP Copy To Clipboard changes land, - // which makes Copy To Clipboard always visible. - // - // When there are no targets, don't show any previews. - bool show_content_previews = !targets.empty(); header_view_ = main_view_->AddChildView(std::make_unique<SharesheetHeaderView>( - intent_->Clone(), delegator_->GetProfile(), show_content_previews)); + intent_->Clone(), delegator_->GetProfile())); body_view_ = main_view_->AddChildView(std::make_unique<views::View>()); body_view_->SetID(BODY_VIEW_ID); body_view_->SetLayoutManager(std::make_unique<views::BoxLayout>( @@ -213,58 +209,35 @@ footer_layout->set_cross_axis_alignment( views::BoxLayout::CrossAxisAlignment::kCenter); - if (targets.empty()) { - auto* image = - body_view_->AddChildView(std::make_unique<views::ImageView>()); - image->SetImage( - ui::ResourceBundle::GetSharedInstance().GetThemedLottieImageNamed( - IDR_SHARESHEET_EMPTY_STATE_IMAGE)); - image->SetProperty(views::kMarginsKey, - gfx::Insets::TLBR(0, 0, kSpacing, 0)); - auto* color_provider = AshColorProvider::Get(); - body_view_->AddChildView(CreateShareLabel( - l10n_util::GetStringUTF16(IDS_SHARESHEET_ZERO_STATE_PRIMARY_LABEL), - CONTEXT_SHARESHEET_BUBBLE_BODY, kPrimaryTextLineHeight, - color_provider->GetContentLayerColor( - AshColorProvider::ContentLayerType::kTextColorPrimary), - gfx::ALIGN_CENTER)); - body_view_->AddChildView(CreateShareLabel( - l10n_util::GetStringUTF16(IDS_SHARESHEET_ZERO_STATE_SECONDARY_LABEL), - CONTEXT_SHARESHEET_BUBBLE_BODY_SECONDARY, kPrimaryTextLineHeight, - color_provider->GetContentLayerColor( - AshColorProvider::ContentLayerType::kTextColorSecondary), - gfx::ALIGN_CENTER, views::style::STYLE_PRIMARY)); - } else { - if (show_content_previews) { - header_body_separator_ = - body_view_->AddChildView(std::make_unique<views::Separator>()); - if (chromeos::features::IsJellyEnabled()) { - header_body_separator_->SetColorId(cros_tokens::kCrosSysSeparator); - } - } + // There is always at least 1 target as Copy To Clipboard is always visible. + CHECK_GT(targets.size(), 0u); + header_body_separator_ = + body_view_->AddChildView(std::make_unique<views::Separator>()); + if (chromeos::features::IsJellyEnabled()) { + header_body_separator_->SetColorId(cros_tokens::kCrosSysSeparator); + } - const size_t targets_size = targets.size(); - auto scroll_view = std::make_unique<views::ScrollView>(); - scroll_view->SetContents(MakeScrollableTargetView(std::move(targets))); - scroll_view->ClipHeightTo(kTargetViewHeight, kTargetViewExpandedHeight); - body_view_->AddChildView(std::move(scroll_view)); + const size_t targets_size = targets.size(); + auto scroll_view = std::make_unique<views::ScrollView>(); + scroll_view->SetContents(MakeScrollableTargetView(std::move(targets))); + scroll_view->ClipHeightTo(kTargetViewHeight, kTargetViewExpandedHeight); + body_view_->AddChildView(std::move(scroll_view)); - if (expanded_view_) { - body_footer_separator_ = - body_view_->AddChildView(std::make_unique<views::Separator>()); - if (chromeos::features::IsJellyEnabled()) { - body_footer_separator_->SetColorId(cros_tokens::kCrosSysSeparator); - } - expand_button_ = - footer_view_->AddChildView(std::make_unique<SharesheetExpandButton>( - base::BindRepeating(&SharesheetBubbleView::ExpandButtonPressed, - base::Unretained(this)))); - } else if (targets_size <= kMaxTargetsPerRow * kMaxRowsForDefaultView) { - // When we have between 1 and 8 targets inclusive. Update |footer_layout| - // padding. - footer_layout->set_inside_border_insets( - gfx::Insets::VH(kFooterNoExtensionVerticalPadding, 0)); + if (expanded_view_) { + body_footer_separator_ = + body_view_->AddChildView(std::make_unique<views::Separator>()); + if (chromeos::features::IsJellyEnabled()) { + body_footer_separator_->SetColorId(cros_tokens::kCrosSysSeparator); } + expand_button_ = + footer_view_->AddChildView(std::make_unique<SharesheetExpandButton>( + base::BindRepeating(&SharesheetBubbleView::ExpandButtonPressed, + base::Unretained(this)))); + } else if (targets_size <= kMaxTargetsPerRow * kMaxRowsForDefaultView) { + // When we have between 1 and 8 targets inclusive. Update |footer_layout| + // padding. + footer_layout->set_inside_border_insets( + gfx::Insets::VH(kFooterNoExtensionVerticalPadding, 0)); } main_view_->SetFocusBehavior(View::FocusBehavior::NEVER);
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc index 869b7a1..b24af4c 100644 --- a/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc +++ b/chrome/browser/ui/ash/sharesheet/sharesheet_bubble_view_unittest.cc
@@ -34,7 +34,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/compositor/scoped_animation_duration_scale_mode.h" #include "ui/events/base_event_utils.h" -#include "ui/lottie/resource.h" #include "ui/views/controls/native/native_view_host.h" #include "ui/views/test/widget_test.h" #include "ui/views/view.h" @@ -94,10 +93,6 @@ widget->GetContentsView()->AddChildView(content_view); parent_window_ = widget->GetNativeWindow(); - - ui::ResourceBundle::SetLottieParsingFunctions( - &lottie::ParseLottieAsStillImage, - &lottie::ParseLottieAsThemedStillImage); } void ShowAndVerifyBubble(apps::IntentPtr intent, @@ -177,23 +172,6 @@ CloseBubble(); } -TEST_F(SharesheetBubbleViewTest, EmptyState) { - ShowAndVerifyBubble(::sharesheet::CreateInvalidIntent(), - ::sharesheet::LaunchSource::kUnknown); - - // Header should contain Share label. - ASSERT_TRUE(header_view()->GetVisible()); - ASSERT_EQ(header_view()->children().size(), 1u); - - // Body view should contain 3 children, an image and 2 labels. - ASSERT_TRUE(body_view()->GetVisible()); - ASSERT_EQ(body_view()->children().size(), 3u); - - // Footer should be an empty view that just acts as padding. - ASSERT_TRUE(footer_view()->GetVisible()); - ASSERT_EQ(footer_view()->children().size(), 0u); -} - TEST_F(SharesheetBubbleViewTest, RecordLaunchSource) { base::HistogramTester histograms; @@ -233,17 +211,6 @@ histograms.ExpectBucketCount( ::sharesheet::kSharesheetShareActionResultHistogram, ::sharesheet::SharesheetMetrics::UserAction::kCopyAction, 2); - - // Invalid intent should not show any actions. - ShowAndVerifyBubble(::sharesheet::CreateInvalidIntent(), - ::sharesheet::LaunchSource::kUnknown); - CloseBubble(); - histograms.ExpectBucketCount( - ::sharesheet::kSharesheetShareActionResultHistogram, - ::sharesheet::SharesheetMetrics::UserAction::kDriveAction, 1); - histograms.ExpectBucketCount( - ::sharesheet::kSharesheetShareActionResultHistogram, - ::sharesheet::SharesheetMetrics::UserAction::kCopyAction, 2); } TEST_F(SharesheetBubbleViewTest, ClickCopyToClipboard) {
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc index 666739ba..48dcab61 100644 --- a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc +++ b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.cc
@@ -259,8 +259,7 @@ // SharesheetHeaderView -------------------------------------------------------- SharesheetHeaderView::SharesheetHeaderView(apps::IntentPtr intent, - Profile* profile, - bool show_content_previews) + Profile* profile) : profile_(profile), intent_(std::move(intent)), thumbnail_loader_(profile) { @@ -284,11 +283,10 @@ const bool has_files = !intent_->files.empty(); // The image view is initialised first to ensure its left most placement. - if (show_content_previews) { - auto file_count = intent_->files.size(); - image_preview_ = - AddChildView(std::make_unique<SharesheetImagePreview>(file_count)); - } + auto file_count = intent_->files.size(); + image_preview_ = + AddChildView(std::make_unique<SharesheetImagePreview>(file_count)); + // A separate view is created for the share title and preview string views. text_view_ = AddChildView(std::make_unique<views::View>()); text_view_->SetID(HEADER_VIEW_TEXT_PREVIEW_ID); @@ -308,21 +306,20 @@ AshColorProvider::Get()->GetContentLayerColor( AshColorProvider::ContentLayerType::kTextColorPrimary), gfx::ALIGN_LEFT)); - if (show_content_previews) { - ShowTextPreview(); - if (has_files) { - ResolveImages(); - } else { - DCHECK_GT(image_preview_->GetImageViewCount(), 0u); - const auto icon_color = ColorProvider::Get()->GetContentLayerColor( - ColorProvider::ContentLayerType::kIconColorProminent); - gfx::ImageSkia file_type_icon = gfx::CreateVectorIcon( - GetTextVectorIcon(), - sharesheet::kImagePreviewPlaceholderIconContentSize, icon_color); - image_preview_->GetImageViewAt(0)->SetImage( - CreateMimeTypeIcon(file_type_icon, kImagePreviewFullSize)); - image_preview_->SetBackgroundColorForIndex(0, icon_color); - } + + ShowTextPreview(); + if (has_files) { + ResolveImages(); + } else { + DCHECK_GT(image_preview_->GetImageViewCount(), 0u); + const auto icon_color = ColorProvider::Get()->GetContentLayerColor( + ColorProvider::ContentLayerType::kIconColorProminent); + gfx::ImageSkia file_type_icon = gfx::CreateVectorIcon( + GetTextVectorIcon(), + sharesheet::kImagePreviewPlaceholderIconContentSize, icon_color); + image_preview_->GetImageViewAt(0)->SetImage( + CreateMimeTypeIcon(file_type_icon, kImagePreviewFullSize)); + image_preview_->SetBackgroundColorForIndex(0, icon_color); } }
diff --git a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h index cb307fc..1c40683 100644 --- a/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h +++ b/chrome/browser/ui/ash/sharesheet/sharesheet_header_view.h
@@ -29,9 +29,7 @@ public: METADATA_HEADER(SharesheetHeaderView); - explicit SharesheetHeaderView(apps::IntentPtr intent, - Profile* profile, - bool show_content_previews); + explicit SharesheetHeaderView(apps::IntentPtr intent, Profile* profile); ~SharesheetHeaderView() override; SharesheetHeaderView(const SharesheetHeaderView&) = delete; SharesheetHeaderView& operator=(const SharesheetHeaderView&) = delete;
diff --git a/chrome/browser/ui/bookmarks/bookmark_stats.cc b/chrome/browser/ui/bookmarks/bookmark_stats.cc index 45f661fa..7ae18c5 100644 --- a/chrome/browser/ui/bookmarks/bookmark_stats.cc +++ b/chrome/browser/ui/bookmarks/bookmark_stats.cc
@@ -29,6 +29,13 @@ } // namespace +std::ostream& operator<<(std::ostream& out, + const BookmarkLaunchAction& launch_action) { + return out << "BookmarkLaunchAction(location = " + << static_cast<int>(launch_action.location) + << ", action_time = " << launch_action.action_time << ")"; +} + void RecordBookmarkLaunch(BookmarkLaunchLocation location, profile_metrics::BrowserProfileType profile_type) { if (IsBookmarkBarLocation(location)) {
diff --git a/chrome/browser/ui/bookmarks/bookmark_stats.h b/chrome/browser/ui/bookmarks/bookmark_stats.h index cf794a4a..58a0737d 100644 --- a/chrome/browser/ui/bookmarks/bookmark_stats.h +++ b/chrome/browser/ui/bookmarks/bookmark_stats.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_STATS_H_ #define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_STATS_H_ +#include "base/time/time.h" #include "components/profile_metrics/browser_profile_type.h" class Profile; @@ -64,6 +65,17 @@ kMaxValue = kSidePanelContextMenu }; +// Captures information related to a bookmark's launch event. Used for metrics +// collection. +struct BookmarkLaunchAction { + // The location of the open action. + BookmarkLaunchLocation location = BookmarkLaunchLocation::kNone; + + // The time at which the launch action was initiated. + base::TimeTicks action_time = base::TimeTicks::Now(); +}; +std::ostream& operator<<(std::ostream& out, const BookmarkLaunchAction& action); + // Records the launch of a bookmark for UMA purposes. void RecordBookmarkLaunch(BookmarkLaunchLocation location, profile_metrics::BrowserProfileType profile_type);
diff --git a/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.cc b/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.cc new file mode 100644 index 0000000..0082680 --- /dev/null +++ b/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.cc
@@ -0,0 +1,59 @@ +// 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 "chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.h" + +#include "base/metrics/histogram_functions.h" +#include "base/time/time.h" +#include "content/public/browser/navigation_handle.h" + +BookmarkStatsTabHelper::~BookmarkStatsTabHelper() = default; + +bool BookmarkStatsTabHelper::SetLaunchAction( + const BookmarkLaunchAction& launch_action, + WindowOpenDisposition tab_disposition) { + if (web_contents()->GetController().GetPendingEntry()) { + launch_action_ = launch_action; + tab_disposition_ = tab_disposition; + // The launch data should remain valid through to the end of the current + // navigation and the begging of the next navigation. + should_reset_launch_data_ = false; + return true; + } + return false; +} + +void BookmarkStatsTabHelper::DidStartNavigation( + content::NavigationHandle* navigation_handle) { + // Reset the launch action data at the beginning of the next navigation. + if (navigation_handle->IsInPrimaryMainFrame() && should_reset_launch_data_) { + tab_disposition_.reset(); + launch_action_.reset(); + should_reset_launch_data_ = false; + } +} + +void BookmarkStatsTabHelper::DidFinishNavigation( + content::NavigationHandle* navigation_handle) { + if (navigation_handle->IsInPrimaryMainFrame()) { + should_reset_launch_data_ = true; + } +} + +void BookmarkStatsTabHelper::DidFirstVisuallyNonEmptyPaint() { + if (launch_action_ && + tab_disposition_ == WindowOpenDisposition::CURRENT_TAB && + launch_action_->location == BookmarkLaunchLocation::kAttachedBar) { + base::UmaHistogramTimes( + "Bookmarks.AttachedBar.CurrentTab.TimeToFirstVisuallyNonEmptyPaint", + base::TimeTicks::Now() - launch_action_->action_time); + } +} + +BookmarkStatsTabHelper::BookmarkStatsTabHelper( + content::WebContents* web_contents) + : content::WebContentsObserver(web_contents), + content::WebContentsUserData<BookmarkStatsTabHelper>(*web_contents) {} + +WEB_CONTENTS_USER_DATA_KEY_IMPL(BookmarkStatsTabHelper);
diff --git a/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.h b/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.h new file mode 100644 index 0000000..2f0f454 --- /dev/null +++ b/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.h
@@ -0,0 +1,65 @@ +// 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 CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_STATS_TAB_HELPER_H_ +#define CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_STATS_TAB_HELPER_H_ + +#include "chrome/browser/ui/bookmarks/bookmark_stats.h" +#include "content/public/browser/web_contents_observer.h" +#include "content/public/browser/web_contents_user_data.h" +#include "ui/base/window_open_disposition.h" + +// A tab helper responsible for reporting metrics on various bookmarks user +// journeys. +class BookmarkStatsTabHelper + : public content::WebContentsObserver, + public content::WebContentsUserData<BookmarkStatsTabHelper> { + public: + BookmarkStatsTabHelper(); + BookmarkStatsTabHelper(const BookmarkStatsTabHelper&) = delete; + BookmarkStatsTabHelper& operator=(const BookmarkStatsTabHelper&) = delete; + ~BookmarkStatsTabHelper() override; + + // The launch action should be set immediately after a given tab has been + // navigated following a bookmark launch action. The launch action will only + // be set if there is a pending navigation for the current tab. + // `tab_disposition` is the disposition requested for by this tab for the + // navigation. + bool SetLaunchAction(const BookmarkLaunchAction& launch_action, + WindowOpenDisposition tab_disposition); + + // content::WebContentsObserver: + void DidStartNavigation( + content::NavigationHandle* navigation_handle) override; + void DidFinishNavigation( + content::NavigationHandle* navigation_handle) override; + void DidFirstVisuallyNonEmptyPaint() override; + + const absl::optional<BookmarkLaunchAction>& launch_action_for_testing() + const { + return launch_action_; + } + const absl::optional<WindowOpenDisposition>& tab_disposition_for_testing() + const { + return tab_disposition_; + } + + private: + friend class content::WebContentsUserData<BookmarkStatsTabHelper>; + + explicit BookmarkStatsTabHelper(content::WebContents* web_contents); + + // The launch action and requested tab disposition for the current navigation. + // These will be reset after the following navigation begins. + absl::optional<BookmarkLaunchAction> launch_action_; + absl::optional<WindowOpenDisposition> tab_disposition_; + + // Tracks whether launch data should be reset as a new primary frame + // navigation begins. + bool should_reset_launch_data_ = false; + + WEB_CONTENTS_USER_DATA_KEY_DECL(); +}; + +#endif // CHROME_BROWSER_UI_BOOKMARKS_BOOKMARK_STATS_TAB_HELPER_H_
diff --git a/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper_unittest.cc b/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper_unittest.cc new file mode 100644 index 0000000..e6784724 --- /dev/null +++ b/chrome/browser/ui/bookmarks/bookmark_stats_tab_helper_unittest.cc
@@ -0,0 +1,136 @@ +// 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 "chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.h" + +#include <memory> + +#include "base/test/metrics/histogram_tester.h" +#include "chrome/test/base/testing_profile.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/navigation_entry.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_renderer_host.h" +#include "content/public/test/web_contents_tester.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace { + +constexpr char kTestUrl1[] = "https://www.test-url-1.com/"; +constexpr char kTestUrl2[] = "https://www.test-url-2.com/"; + +} // namespace + +namespace test { + +class BookmarkStatsTabHelperTest : public ::testing::Test { + public: + // ::testing::Test: + void SetUp() override { + web_contents_ = + content::WebContentsTester::CreateTestWebContents(&profile_, nullptr); + Test::SetUp(); + } + + protected: + void LoadUrl(const char* url) { + web_contents()->GetController().LoadURL(GURL(url), content::Referrer(), + ui::PAGE_TRANSITION_AUTO_TOPLEVEL, + std::string()); + } + + void CommitPendingNavigation() { + content::WebContentsTester::For(web_contents())->CommitPendingNavigation(); + } + + BookmarkStatsTabHelper* GetHelper() { + BookmarkStatsTabHelper::CreateForWebContents(web_contents_.get()); + return BookmarkStatsTabHelper::FromWebContents(web_contents_.get()); + } + + content::WebContents* web_contents() { return web_contents_.get(); } + + base::HistogramTester& histogram_tester() { return histogram_tester_; } + + private: + content::BrowserTaskEnvironment task_environment_; + content::RenderViewHostTestEnabler rvh_enabler_; + TestingProfile profile_; + std::unique_ptr<content::WebContents> web_contents_; + base::HistogramTester histogram_tester_; +}; + +TEST_F(BookmarkStatsTabHelperTest, LaunchActionAddedWithPendingEntry) { + // The launch action should start unset. + BookmarkStatsTabHelper* helper = GetHelper(); + EXPECT_FALSE(helper->launch_action_for_testing().has_value()); + EXPECT_FALSE(helper->tab_disposition_for_testing().has_value()); + + // Attempting to set the launch action without a pending navigation having + // been set should result in a no-op. + helper->SetLaunchAction( + {BookmarkLaunchLocation::kAttachedBar, base::TimeTicks::Now()}, + WindowOpenDisposition::CURRENT_TAB); + EXPECT_FALSE(helper->launch_action_for_testing().has_value()); + EXPECT_FALSE(helper->tab_disposition_for_testing().has_value()); + + // Begin a navigation and attempt to set the launch action. This should now + // be reflected in the helper. + LoadUrl(kTestUrl1); + helper->SetLaunchAction( + {BookmarkLaunchLocation::kAttachedBar, base::TimeTicks::Now()}, + WindowOpenDisposition::CURRENT_TAB); + EXPECT_TRUE(helper->launch_action_for_testing().has_value()); + EXPECT_TRUE(helper->tab_disposition_for_testing().has_value()); + + // After the navigation completes the launch action data should remain. + CommitPendingNavigation(); + EXPECT_TRUE(helper->launch_action_for_testing().has_value()); + EXPECT_TRUE(helper->tab_disposition_for_testing().has_value()); + + // A following navigation should clear the launch action data. + LoadUrl(kTestUrl2); + CommitPendingNavigation(); + EXPECT_FALSE(helper->launch_action_for_testing().has_value()); + EXPECT_FALSE(helper->tab_disposition_for_testing().has_value()); +} + +TEST_F(BookmarkStatsTabHelperTest, EmitsNonEmptyPaintMetrics) { + // The launch action should start unset. + BookmarkStatsTabHelper* helper = GetHelper(); + EXPECT_FALSE(helper->launch_action_for_testing().has_value()); + EXPECT_FALSE(helper->tab_disposition_for_testing().has_value()); + histogram_tester().ExpectTotalCount( + "Bookmarks.AttachedBar.CurrentTab.TimeToFirstVisuallyNonEmptyPaint", 0); + + // Begin a navigation and attempt to set the launch action. This should now + // be reflected in the helper. + LoadUrl(kTestUrl1); + helper->SetLaunchAction( + {BookmarkLaunchLocation::kAttachedBar, base::TimeTicks::Now()}, + WindowOpenDisposition::CURRENT_TAB); + EXPECT_TRUE(helper->launch_action_for_testing().has_value()); + EXPECT_TRUE(helper->tab_disposition_for_testing().has_value()); + + // Simulate a non-empty paint event. The non-empty paint metric should be + // emitted. + helper->DidFirstVisuallyNonEmptyPaint(); + histogram_tester().ExpectTotalCount( + "Bookmarks.AttachedBar.CurrentTab.TimeToFirstVisuallyNonEmptyPaint", 1); + + // A following navigation should clear the launch action data. + LoadUrl(kTestUrl2); + CommitPendingNavigation(); + EXPECT_FALSE(helper->launch_action_for_testing().has_value()); + EXPECT_FALSE(helper->tab_disposition_for_testing().has_value()); + + // Simulate a non-empty paint event. No metrics should have been emitted as + // the launch action should have been reset. + helper->DidFirstVisuallyNonEmptyPaint(); + histogram_tester().ExpectTotalCount( + "Bookmarks.AttachedBar.CurrentTab.TimeToFirstVisuallyNonEmptyPaint", 1); +} + +} // namespace test
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc index 3807df2..e47ca3353 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc +++ b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.cc
@@ -19,6 +19,7 @@ #include "chrome/browser/renderer_host/chrome_navigation_ui_data.h" #include "chrome/browser/ui/bookmarks/bookmark_editor.h" #include "chrome/browser/ui/bookmarks/bookmark_stats.h" +#include "chrome/browser/ui/bookmarks/bookmark_stats_tab_helper.h" #include "chrome/browser/ui/bookmarks/bookmark_utils.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" @@ -141,9 +142,11 @@ // Opens all of the URLs in `bookmark_urls` using `navigator` and // `initial_disposition` as a starting point. Returns a reference set of the // WebContents created; see OpenedWebContentsSet. -OpenedWebContentsSet OpenAllHelper(Browser* browser, - std::vector<UrlAndId> bookmark_urls, - WindowOpenDisposition initial_disposition) { +OpenedWebContentsSet OpenAllHelper( + Browser* browser, + std::vector<UrlAndId> bookmark_urls, + WindowOpenDisposition initial_disposition, + absl::optional<BookmarkLaunchAction> launch_action) { OpenedWebContentsSet::container_type opened_tabs; WindowOpenDisposition disposition = initial_disposition; // We keep track of (potentially) two browsers in addition to the original @@ -196,6 +199,12 @@ if (!opened_tab) continue; + if (launch_action.has_value()) { + BookmarkStatsTabHelper::CreateForWebContents(opened_tab); + BookmarkStatsTabHelper::FromWebContents(opened_tab) + ->SetLaunchAction(launch_action.value(), disposition); + } + if (url_and_id_it->id.is_valid()) { ChromeNavigationUIData* ui_data = static_cast<ChromeNavigationUIData*>(handle->GetNavigationUIData()); @@ -246,18 +255,21 @@ void OpenAllIfAllowed(Browser* browser, const std::vector<const bookmarks::BookmarkNode*>& nodes, WindowOpenDisposition initial_disposition, - bool add_to_group) { + bool add_to_group, + absl::optional<BookmarkLaunchAction> launch_action) { std::vector<UrlAndId> url_and_ids = GetURLsToOpen( nodes, browser->profile(), initial_disposition == WindowOpenDisposition::OFF_THE_RECORD); auto do_open = [](Browser* browser, std::vector<UrlAndId> url_and_ids_to_open, WindowOpenDisposition initial_disposition, absl::optional<std::u16string> folder_title, + absl::optional<BookmarkLaunchAction> launch_action, chrome::MessageBoxResult result) { if (result != chrome::MESSAGE_BOX_RESULT_YES) return; - const auto opened_web_contents = OpenAllHelper( - browser, std::move(url_and_ids_to_open), initial_disposition); + const auto opened_web_contents = + OpenAllHelper(browser, std::move(url_and_ids_to_open), + initial_disposition, std::move(launch_action)); if (folder_title.has_value()) { TabStripModel* model = browser->tab_strip_model(); @@ -299,7 +311,7 @@ add_to_group ? absl::optional<std::u16string>( nodes[0]->GetTitledUrlNodeTitle()) : absl::nullopt, - chrome::MESSAGE_BOX_RESULT_YES); + std::move(launch_action), chrome::MESSAGE_BOX_RESULT_YES); return; } @@ -316,7 +328,8 @@ initial_disposition, add_to_group ? absl::optional<std::u16string>( nodes[0]->GetTitledUrlNodeTitle()) - : absl::nullopt)); + : absl::nullopt, + absl::nullopt)); } int OpenCount(gfx::NativeWindow parent,
diff --git a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.h b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.h index 6934b5b..28c6812 100644 --- a/chrome/browser/ui/bookmarks/bookmark_utils_desktop.h +++ b/chrome/browser/ui/bookmarks/bookmark_utils_desktop.h
@@ -9,6 +9,7 @@ #include "base/functional/callback_forward.h" #include "chrome/browser/ui/bookmarks/bookmark_editor.h" +#include "chrome/browser/ui/bookmarks/bookmark_stats.h" #include "chrome/browser/ui/simple_message_box.h" #include "chrome/browser/ui/tabs/tab_group.h" #include "ui/base/window_open_disposition.h" @@ -23,7 +24,6 @@ namespace content { class BrowserContext; -class PageNavigator; class NavigationHandle; } @@ -52,18 +52,21 @@ // value. extern size_t kNumBookmarkUrlsBeforePrompting; -// Tries to open all bookmarks in |nodes|. If there are many, prompts +// Tries to open all bookmarks in `nodes`. If there are many, prompts // the user first. Returns immediately, opening the bookmarks -// asynchronously if prompting the user. |browser| is the browser from +// asynchronously if prompting the user. `browser` is the browser from // which the bookmarks were opened. Its window is used as the anchor for -// the dialog (if shown). |get_navigator| is used to fetch the -// PageNavigator used for opening the bookmarks. It may be called -// arbitrarily later as long as |browser| is alive. If it is not -// callable or returns null, this will fail gracefully. -void OpenAllIfAllowed(Browser* browser, - const std::vector<const bookmarks::BookmarkNode*>& nodes, - WindowOpenDisposition initial_disposition, - bool add_to_group); +// the dialog (if shown). +// `launch_action` represents the location and time of the bookmark launch +// action for callsites that support it. +// TODO(crbug.com/1449016): This should be made non-optional once all callsites +// have all the information needed to correctly construct the `launch_action`. +void OpenAllIfAllowed( + Browser* browser, + const std::vector<const bookmarks::BookmarkNode*>& nodes, + WindowOpenDisposition initial_disposition, + bool add_to_group, + absl::optional<BookmarkLaunchAction> launch_action = absl::nullopt); // Returns the count of bookmarks that would be opened by OpenAll. If // |incognito_context| is set, the function will use it to check if the URLs
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc index 71297e1..9125b6d 100644 --- a/chrome/browser/ui/browser.cc +++ b/chrome/browser/ui/browser.cc
@@ -577,6 +577,7 @@ // The tab strip should not have any tabs at this point. // // TODO(crbug.com/1407055): This DCHECK doesn't always pass. + // TODO(crbug.com/1434387): convert this to CHECK. DCHECK(tab_strip_model_->empty()); // Destroy the BrowserCommandController before removing the browser, so that @@ -1309,6 +1310,7 @@ // immediately deletes, where was Close() is a hide, and then delete after // posting a task. window_->Close(); + is_delete_scheduled_ = true; // Instant may have visible WebContents that need to be detached before the // window system closes. @@ -2395,6 +2397,14 @@ // Browser, Command and state updating (private): void Browser::OnTabInsertedAt(WebContents* contents, int index) { + // If this Browser is about to be deleted, then WebContents should not be + // added to it. This is because scheduling the delete can not be undone, and + // proper cleanup is not done if a WebContents is added once delete it + // scheduled (WebContents is leaked, unload handlers aren't checked...). + // TODO(crbug.com/1434387): this should check that `is_delete_scheduled_` is + // false. + DUMP_WILL_BE_CHECK(!is_delete_scheduled_); + SetAsDelegate(contents, true); sessions::SessionTabHelper::FromWebContents(contents)->SetWindowID(
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h index 0908c122..2cbbda0 100644 --- a/chrome/browser/ui/browser.h +++ b/chrome/browser/ui/browser.h
@@ -414,6 +414,8 @@ } CreationSource creation_source() const { return creation_source_; } + bool is_delete_scheduled() const { return is_delete_scheduled_; } + // |window()| will return NULL if called before |CreateBrowserWindow()| // is done. BrowserWindow* window() const { return window_; } @@ -1336,6 +1338,10 @@ WebContentsCollection web_contents_collection_{this}; + // If true, the Browser window has been closed and this will be deleted + // shortly (after a PostTask). + bool is_delete_scheduled_ = false; + // The following factory is used for chrome update coalescing. base::WeakPtrFactory<Browser> chrome_updater_factory_{this};
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc index bf36ee0..4698cf4 100644 --- a/chrome/browser/ui/browser_command_controller.cc +++ b/chrome/browser/ui/browser_command_controller.cc
@@ -113,6 +113,12 @@ #include "components/user_manager/user_manager.h" #endif +// TODO(crbug.com/1424800): Remove once the restore issue has been resolved. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#undef ENABLED_VLOG_LEVEL +#define ENABLED_VLOG_LEVEL 1 +#endif + #if BUILDFLAG(IS_LINUX) #include "ui/linux/linux_ui.h" #endif @@ -237,8 +243,11 @@ TabRestoreServiceFactory::GetForProfile(profile()); if (tab_restore_service) { tab_restore_service->AddObserver(this); - if (!tab_restore_service->IsLoaded()) + if (!tab_restore_service->IsLoaded()) { + VLOG(1) << "BrowserCommandController::BrowserCommandController, loading " + "tabs from last session."; tab_restore_service->LoadTabsFromLastSession(); + } } }
diff --git a/chrome/browser/ui/browser_live_tab_context.cc b/chrome/browser/ui/browser_live_tab_context.cc index 116b6eb..696a152 100644 --- a/chrome/browser/ui/browser_live_tab_context.cc +++ b/chrome/browser/ui/browser_live_tab_context.cc
@@ -324,14 +324,18 @@ sessions::LiveTabContext* BrowserLiveTabContext::FindContextForWebContents( const WebContents* contents) { Browser* browser = chrome::FindBrowserWithWebContents(contents); - return browser ? browser->live_tab_context() : nullptr; + return browser && !browser->is_delete_scheduled() + ? browser->live_tab_context() + : nullptr; } // static sessions::LiveTabContext* BrowserLiveTabContext::FindContextWithID( SessionID desired_id) { Browser* browser = chrome::FindBrowserWithID(desired_id); - return browser ? browser->live_tab_context() : nullptr; + return browser && !browser->is_delete_scheduled() + ? browser->live_tab_context() + : nullptr; } // static @@ -339,5 +343,7 @@ tab_groups::TabGroupId group, Profile* profile) { Browser* browser = chrome::FindBrowserWithGroup(group, profile); - return browser ? browser->live_tab_context() : nullptr; + return browser && !browser->is_delete_scheduled() + ? browser->live_tab_context() + : nullptr; }
diff --git a/chrome/browser/ui/browser_tab_restorer.cc b/chrome/browser/ui/browser_tab_restorer.cc index 7449acb3..466d762 100644 --- a/chrome/browser/ui/browser_tab_restorer.cc +++ b/chrome/browser/ui/browser_tab_restorer.cc
@@ -17,6 +17,12 @@ #include "components/sessions/core/tab_restore_service.h" #include "components/sessions/core/tab_restore_service_observer.h" +// TODO(crbug.com/1424800): Remove once the restore issue has been resolved. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#undef ENABLED_VLOG_LEVEL +#define ENABLED_VLOG_LEVEL 1 +#endif + namespace chrome { namespace { @@ -79,6 +85,8 @@ BrowserList::AddObserver(this); browser_->profile()->SetUserData(kBrowserTabRestorerKey, base::WrapUnique(this)); + VLOG(1) << "BrowserTabRestorer::BrowserTabRestorer, loading tabs from last " + "session."; tab_restore_service_->LoadTabsFromLastSession(); }
diff --git a/chrome/browser/ui/browser_ui_prefs.cc b/chrome/browser/ui/browser_ui_prefs.cc index 16ab8096..31af7b49 100644 --- a/chrome/browser/ui/browser_ui_prefs.cc +++ b/chrome/browser/ui/browser_ui_prefs.cc
@@ -56,6 +56,8 @@ registry->RegisterIntegerPref( prefs::kMacRestoreLocationPermissionsExperimentCount, 0); #endif // BUILDFLAG(IS_MAC) + + registry->RegisterBooleanPref(prefs::kHoverCardImagesEnabled, true); } void RegisterBrowserUserPrefs(user_prefs::PrefRegistrySyncable* registry) {
diff --git a/chrome/browser/ui/commerce/price_tracking/DEPS b/chrome/browser/ui/commerce/price_tracking/DEPS new file mode 100644 index 0000000..53060c3 --- /dev/null +++ b/chrome/browser/ui/commerce/price_tracking/DEPS
@@ -0,0 +1,5 @@ +specific_include_rules = { + "shopping_list_ui_tab_helper.*": [ + "+chrome/browser/ui/views", + ] +}
diff --git a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc index f3ab997..42246dc 100644 --- a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc +++ b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.cc
@@ -7,20 +7,36 @@ #include "base/check_is_test.h" #include "base/functional/bind.h" #include "base/strings/string_number_conversions.h" +#include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/side_panel/side_panel_ui.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" +#include "chrome/browser/ui/views/frame/browser_view.h" +#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" +#include "chrome/browser/ui/views/side_panel/side_panel_entry.h" +#include "chrome/browser/ui/views/side_panel/side_panel_registry.h" +#include "chrome/browser/ui/views/side_panel/side_panel_web_ui_view.h" +#include "chrome/browser/ui/webui/commerce/shopping_insights_side_panel_ui.h" #include "chrome/common/pref_names.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "components/commerce/core/commerce_constants.h" #include "components/commerce/core/commerce_feature_list.h" #include "components/commerce/core/price_tracking_utils.h" #include "components/image_fetcher/core/image_fetcher.h" +#include "components/strings/grit/components_strings.h" +#include "components/vector_icons/vector_icons.h" #include "content/public/browser/browser_task_traits.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "net/traffic_annotation/network_traffic_annotation.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/models/image_model.h" +#include "ui/views/vector_icons.h" +#include "ui/views/view_class_properties.h" #include "url/gurl.h" namespace commerce { @@ -114,13 +130,18 @@ pending_tracking_state_.reset(); is_first_load_for_nav_finished_ = false; - if (!shopping_service_ || !shopping_service_->IsShoppingListEligible()) + MakeShoppingInsightsSidePanelUnavailable(); + + if (!shopping_service_) { return; + } // Cancel any pending callbacks by invalidating any weak pointers. weak_ptr_factory_.InvalidateWeakPtrs(); - UpdatePriceTrackingIconView(); + if (shopping_service_->IsShoppingListEligible()) { + UpdatePriceTrackingIconView(); + } shopping_service_->GetProductInfoForUrl( web_contents()->GetLastCommittedURL(), @@ -215,21 +236,26 @@ if (url != web_contents()->GetLastCommittedURL()) return; - if (!CanTrackPrice(info) || !info.has_value() || info->image_url.is_empty()) { - return; + if (shopping_service_->IsShoppingListEligible() && CanTrackPrice(info) && + info.has_value() && !info->image_url.is_empty()) { + cluster_id_for_page_.emplace(info->product_cluster_id.value()); + UpdatePriceTrackingStateFromSubscriptions(); + + // TODO(1360850): Delay this fetch by possibly waiting until page load has + // finished. + image_fetcher_->FetchImage( + info.value().image_url, + base::BindOnce(&ShoppingListUiTabHelper::HandleImageFetcherResponse, + weak_ptr_factory_.GetWeakPtr(), info.value().image_url), + image_fetcher::ImageFetcherParams(kTrafficAnnotation, + kImageFetcherUmaClient)); } - cluster_id_for_page_.emplace(info->product_cluster_id.value()); - UpdatePriceTrackingStateFromSubscriptions(); - - // TODO(1360850): Delay this fetch by possibly waiting until page load has - // finished. - image_fetcher_->FetchImage( - info.value().image_url, - base::BindOnce(&ShoppingListUiTabHelper::HandleImageFetcherResponse, - weak_ptr_factory_.GetWeakPtr(), info.value().image_url), - image_fetcher::ImageFetcherParams(kTrafficAnnotation, - kImageFetcherUmaClient)); + if (shopping_service_->IsPriceInsightsEligible() && info.has_value()) { + // TODO(zhiyuancai): Also check whether we have price insights info for + // current url. + MakeShoppingInsightsSidePanelAvailable(); + } } void ShoppingListUiTabHelper::SetPriceTrackingState( @@ -333,6 +359,62 @@ browser->window()->UpdatePageActionIcon(PageActionIconType::kPriceTracking); } +void ShoppingListUiTabHelper::MakeShoppingInsightsSidePanelAvailable() { + auto* registry = SidePanelRegistry::Get(web_contents()); + if (!registry) { + return; + } + + auto entry = std::make_unique<SidePanelEntry>( + SidePanelEntry::Id::kShoppingInsights, + l10n_util::GetStringUTF16(IDS_SHOPPING_INSIGHTS_SIDE_PANEL_TITLE), + ui::ImageModel::FromVectorIcon(vector_icons::kShoppingBagIcon, + ui::kColorIcon), + base::BindRepeating( + &ShoppingListUiTabHelper::CreateShoppingInsightsWebView, + base::Unretained(this))); + registry->Register(std::move(entry)); +} + +void ShoppingListUiTabHelper::MakeShoppingInsightsSidePanelUnavailable() { + auto* side_panel_ui = GetSidePanelUI(); + if (side_panel_ui && side_panel_ui->IsSidePanelShowing() && + side_panel_ui->GetCurrentEntryId() == + SidePanelEntry::Id::kShoppingInsights) { + side_panel_ui->Close(); + } + + auto* registry = SidePanelRegistry::Get(web_contents()); + if (!registry) { + return; + } + registry->Deregister( + SidePanelEntry::Key(SidePanelEntry::Id::kShoppingInsights)); +} + +std::unique_ptr<views::View> +ShoppingListUiTabHelper::CreateShoppingInsightsWebView() { + auto shopping_insights_web_view = + std::make_unique<SidePanelWebUIViewT<ShoppingInsightsSidePanelUI>>( + base::RepeatingClosure(), base::RepeatingClosure(), + std::make_unique<BubbleContentsWrapperT<ShoppingInsightsSidePanelUI>>( + GURL(kChromeUIShoppingInsightsSidePanelUrl), + Profile::FromBrowserContext(web_contents()->GetBrowserContext()), + IDS_SHOPPING_INSIGHTS_SIDE_PANEL_TITLE, + /*webui_resizes_host=*/false, + /*esc_closes_ui=*/false)); + // Call ShowUI() to make the UI ready, this doesn't really open/switch the + // side panel. + shopping_insights_web_view->ShowUI(); + + return shopping_insights_web_view; +} + +SidePanelUI* ShoppingListUiTabHelper::GetSidePanelUI() const { + auto* browser = chrome::FindBrowserWithWebContents(web_contents()); + return browser ? SidePanelUI::GetSidePanelUIForBrowser(browser) : nullptr; +} + const absl::optional<bool>& ShoppingListUiTabHelper::GetPendingTrackingStateForTesting() { return pending_tracking_state_;
diff --git a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h index 4d5ab302..2ebe8618 100644 --- a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h +++ b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h
@@ -17,7 +17,7 @@ #include "ui/gfx/image/image.h" class GURL; - +class SidePanelUI; namespace bookmarks { class BookmarkModel; } @@ -31,12 +31,18 @@ class ImageFetcher; } +namespace views { +class View; +} // namespace views + namespace commerce { struct CommerceSubscription; // This tab helper is used to update and maintain the state of the shopping list // and price tracking UI on desktop. +// TODO(b:283833590): Rename this class since it serves for all shopping +// features now. class ShoppingListUiTabHelper : public content::WebContentsObserver, public content::WebContentsUserData<ShoppingListUiTabHelper>, @@ -118,6 +124,18 @@ bool IsSameDocumentWithSameCommittedUrl( content::NavigationHandle* navigation_handle); + // Make the ShoppingInsights entry available in the side panel. + void MakeShoppingInsightsSidePanelAvailable(); + + // Make the ShoppingInsights entry unavailable in the side panel. If the + // ShoppingInsights side panel is currently showing, close the side panel + // first. + void MakeShoppingInsightsSidePanelUnavailable(); + + std::unique_ptr<views::View> CreateShoppingInsightsWebView(); + + SidePanelUI* GetSidePanelUI() const; + // The shopping service is tied to the lifetime of the browser context // which will always outlive this tab helper. raw_ptr<ShoppingService, DanglingUntriaged> shopping_service_;
diff --git a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper_unittest.cc b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper_unittest.cc index a10dbbb..ba1e7cf 100644 --- a/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper_unittest.cc +++ b/chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper_unittest.cc
@@ -9,6 +9,9 @@ #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "chrome/browser/ui/commerce/price_tracking/shopping_list_ui_tab_helper.h" +#include "chrome/browser/ui/views/side_panel/side_panel_entry.h" +#include "chrome/browser/ui/views/side_panel/side_panel_registry.h" +#include "chrome/browser/ui/views/side_panel/side_panel_util.h" #include "chrome/test/base/testing_profile.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/test/test_bookmark_client.h" @@ -350,4 +353,40 @@ EXPECT_FALSE(tab_helper_->ShouldShowPriceTrackingIconView()); } +TEST_F(ShoppingListUiTabHelperTest, TestShoppingInsightsSidePanelAvailable) { + ASSERT_FALSE(SidePanelRegistry::Get(web_contents_.get()) + ->GetEntryForKey(SidePanelEntry::Key( + SidePanelEntry::Id::kShoppingInsights))); + + absl::optional<ProductInfo> info = + CreateProductInfo(kClusterId, GURL(kProductImageUrl)); + shopping_service_->SetResponseForGetProductInfoForUrl(info); + shopping_service_->SetIsPriceInsightsEligible(true); + + SimulateNavigationCommitted(GURL(kProductUrl)); + + base::RunLoop().RunUntilIdle(); + + ASSERT_TRUE(SidePanelRegistry::Get(web_contents_.get()) + ->GetEntryForKey(SidePanelEntry::Key( + SidePanelEntry::Id::kShoppingInsights))); +} + +TEST_F(ShoppingListUiTabHelperTest, TestShoppingInsightsSidePanelUnavailable) { + ASSERT_FALSE(SidePanelRegistry::Get(web_contents_.get()) + ->GetEntryForKey(SidePanelEntry::Key( + SidePanelEntry::Id::kShoppingInsights))); + + shopping_service_->SetResponseForGetProductInfoForUrl(absl::nullopt); + shopping_service_->SetIsPriceInsightsEligible(true); + + SimulateNavigationCommitted(GURL(kProductUrl)); + + base::RunLoop().RunUntilIdle(); + + ASSERT_FALSE(SidePanelRegistry::Get(web_contents_.get()) + ->GetEntryForKey(SidePanelEntry::Key( + SidePanelEntry::Id::kShoppingInsights))); +} + } // namespace commerce
diff --git a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc index 4a11b74..b5fd6315 100644 --- a/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc +++ b/chrome/browser/ui/exclusive_access/fullscreen_controller_interactive_browsertest.cc
@@ -453,10 +453,17 @@ ASSERT_FALSE(IsExclusiveAccessBubbleDisplayed()); +#if !defined(MEMORY_SANITIZER) // Lock the mouse without a user gesture, expect no response. PressKeyAndWaitForMouseLockRequest(ui::VKEY_D); ASSERT_FALSE(IsExclusiveAccessBubbleDisplayed()); ASSERT_FALSE(IsMouseLocked()); +#else + // MSan builds change the timing of user gestures, which this part of the test + // depends upon. See `fullscreen_mouselock.html` for more details, but the + // main idea is that it waits ~5 seconds after the keypress and assumes that + // the user gesture has expired. +#endif // Lock the mouse with a user gesture. PressKeyAndWaitForMouseLockRequest(ui::VKEY_1);
diff --git a/chrome/browser/ui/layout_constants.cc b/chrome/browser/ui/layout_constants.cc index 6977ac3..9149318 100644 --- a/chrome/browser/ui/layout_constants.cc +++ b/chrome/browser/ui/layout_constants.cc
@@ -33,6 +33,8 @@ return features::IsChromeRefresh2023() ? (touch_ui ? 0 : 8) : GetLayoutConstant(TOOLBAR_ELEMENT_PADDING); + case BOOKMARK_BAR_BUTTON_IMAGE_LABEL_PADDING: + return features::IsChromeRefresh2023() ? 6 : 8; case WEB_APP_MENU_BUTTON_SIZE: return 24; case WEB_APP_PAGE_ACTION_ICON_SIZE:
diff --git a/chrome/browser/ui/layout_constants.h b/chrome/browser/ui/layout_constants.h index 01636de..0989680 100644 --- a/chrome/browser/ui/layout_constants.h +++ b/chrome/browser/ui/layout_constants.h
@@ -24,6 +24,10 @@ // The horizontal padding between buttons within the Bookmarks Bar. BOOKMARK_BAR_BUTTON_PADDING, + // The horizontal padding between the image and the title of the bookmark + // button. + BOOKMARK_BAR_BUTTON_IMAGE_LABEL_PADDING, + // The size of icons used in Download bubbles. // TODO(crbug/1296323): We should be sourcing the size of the file icon from // the layout
diff --git a/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc b/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc index 3353f38..966fdf64 100644 --- a/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc +++ b/chrome/browser/ui/quick_answers/quick_answers_browsertest.cc
@@ -14,6 +14,7 @@ #include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "build/build_config.h" #include "chrome/browser/notifications/notification_display_service.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/quick_answers/quick_answers_browsertest_base.h" @@ -125,8 +126,16 @@ } }; +// Test is flaky on ChromeOS. https://crbug.com/1450432 +#if BUILDFLAG(IS_CHROMEOS) +#define MAYBE_QuickAnswersViewAboveNotification \ + DISABLED_QuickAnswersViewAboveNotification +#else +#define MAYBE_QuickAnswersViewAboveNotification \ + QuickAnswersViewAboveNotification +#endif IN_PROC_BROWSER_TEST_F(QuickAnswersBrowserTest, - QuickAnswersViewAboveNotification) { + MAYBE_QuickAnswersViewAboveNotification) { SetQuickAnswersEnabled(true); views::NamedWidgetShownWaiter quick_answers_view_widget_waiter( @@ -167,8 +176,15 @@ quick_answers_view_widget->GetNativeView())); } +// Test is flaky on ChromeOS. https://crbug.com/1450432 +#if BUILDFLAG(IS_CHROMEOS) +#define MAYBE_UserConsentViewAboveNotification \ + DISABLED_UserConsentViewAboveNotification +#else +#define MAYBE_UserConsentViewAboveNotification UserConsentViewAboveNotification +#endif IN_PROC_BROWSER_TEST_F(QuickAnswersBrowserTest, - UserConsentViewAboveNotification) { + MAYBE_UserConsentViewAboveNotification) { views::NamedWidgetShownWaiter user_consent_view_widget_waiter( views::test::AnyWidgetTestPasskey(), UserConsentView::kWidgetName);
diff --git a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc index 6a91025..14b3240 100644 --- a/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.cc
@@ -141,7 +141,6 @@ SetAccessibleName( l10n_util::GetStringUTF16(IDS_QUICK_ANSWERS_VIEW_A11Y_NAME_TEXT)); SetInstallFocusRingOnFocus(false); - set_suppress_default_focus_handling(); // This is because waiting for mouse-release to fire buttons would be too // late, since mouse-press dismisses the menu. @@ -376,6 +375,18 @@ return widget; } +void QuickAnswersView::RequestFocus() { + // When the Quick Answers view is focused, we actually want `main_view_` + // to have the focus for highlight and selection purposes. + main_view_->RequestFocus(); +} + +bool QuickAnswersView::HasFocus() const { + // When the Quick Answers view is focused, `main_view_` should have + // the focus. + return main_view_->HasFocus(); +} + void QuickAnswersView::OnFocus() { View* wants_focus = focus_search_->FindNextFocusableView( nullptr, views::FocusSearch::SearchDirection::kForwards, @@ -824,10 +835,10 @@ std::vector<views::View*> QuickAnswersView::GetFocusableViews() { std::vector<views::View*> focusable_views; - // The view itself does not gain focus for retry-view and transfers it to the + // The main view does not gain focus for retry-view and transfers it to the // retry-label, and so is not included when this is the case. if (!retry_label_) { - focusable_views.push_back(this); + focusable_views.push_back(main_view_); } if (dogfood_feedback_button_ && dogfood_feedback_button_->GetVisible()) { focusable_views.push_back(dogfood_feedback_button_);
diff --git a/chrome/browser/ui/quick_answers/ui/quick_answers_view.h b/chrome/browser/ui/quick_answers/ui/quick_answers_view.h index 29af549..e7b8fa3 100644 --- a/chrome/browser/ui/quick_answers/ui/quick_answers_view.h +++ b/chrome/browser/ui/quick_answers/ui/quick_answers_view.h
@@ -56,6 +56,8 @@ base::WeakPtr<QuickAnswersUiController> controller); // views::View: + void RequestFocus() override; + bool HasFocus() const override; void OnFocus() override; void OnThemeChanged() override; views::FocusTraversable* GetPaneFocusTraversable() override;
diff --git a/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc b/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc index 1c607b0..8ecd846 100644 --- a/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc +++ b/chrome/browser/ui/side_panel/companion/companion_tab_helper.cc
@@ -139,6 +139,13 @@ } } +void CompanionTabHelper::OnCompanionSidePanelClosed() { + image_query_.reset(); + text_query_.clear(); + side_panel_open_trigger_ = absl::nullopt; + delegate_->OnCompanionSidePanelClosed(); +} + void CompanionTabHelper::CreateAndRegisterEntry() { delegate_->CreateAndRegisterEntry(); }
diff --git a/chrome/browser/ui/side_panel/companion/companion_tab_helper.h b/chrome/browser/ui/side_panel/companion/companion_tab_helper.h index 3b04e513..8b75f22f 100644 --- a/chrome/browser/ui/side_panel/companion/companion_tab_helper.h +++ b/chrome/browser/ui/side_panel/companion/companion_tab_helper.h
@@ -42,6 +42,8 @@ SidePanelOpenTrigger side_panel_open_trigger) = 0; // Triggers an update of the 'open in new tab' button. virtual void UpdateNewTabButton(GURL url_to_open) = 0; + // Called when the companion side panel is closed. + virtual void OnCompanionSidePanelClosed() = 0; // Retrieves the web contents for testing purposes. virtual content::WebContents* GetCompanionWebContentsForTesting() = 0; }; @@ -77,6 +79,10 @@ // handler or an empty pointer if none. std::unique_ptr<side_panel::mojom::ImageQuery> GetImageQuery(); + // Called when the companion side panel is closed. Used for cleaning up any + // local state. + void OnCompanionSidePanelClosed(); + // Triggers the companion side panel entry to be created and registered for // the tab. void CreateAndRegisterEntry();
diff --git a/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc b/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc index 19afee4e..d31d523 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_iterator_unittest.cc
@@ -118,6 +118,7 @@ // Close some tabs. browser2->tab_strip_model()->CloseAllTabs(); + EXPECT_TRUE(browser2->is_delete_scheduled()); browser3->tab_strip_model()->CloseWebContentsAt(1, TabCloseTypes::CLOSE_NONE); count = 0; @@ -129,22 +130,21 @@ ADD_FAILURE(); } - // Now make it one tab per browser. + // Add one tab back to browser. chrome::NewTab(browser()); - chrome::NewTab(browser2.get()); count = 0; for (auto iterator = all_tabs.begin(), end = all_tabs.end(); iterator != end; ++iterator, ++count) { - if (count == 0) + if (count == 0) { EXPECT_EQ(browser(), iterator.browser()); - else if (count == 1) - EXPECT_EQ(browser2.get(), iterator.browser()); - else if (count == 2) + } else if (count == 1) { EXPECT_EQ(browser3.get(), iterator.browser()); - else + } else { ADD_FAILURE(); + } } + EXPECT_EQ(2u, count); // Close all remaining tabs to keep all the destructors happy. browser2->tab_strip_model()->CloseAllTabs();
diff --git a/chrome/browser/ui/tab_helpers.cc b/chrome/browser/ui/tab_helpers.cc index 4e8f049..f895075 100644 --- a/chrome/browser/ui/tab_helpers.cc +++ b/chrome/browser/ui/tab_helpers.cc
@@ -507,10 +507,8 @@ performance_manager::user_tuning::UserPerformanceTuningManager:: ResourceUsageTabHelper::CreateForWebContents(web_contents); } - if (base::FeatureList::IsEnabled(features::kTabHoverCardImages) || - base::FeatureList::IsEnabled(features::kWebUITabStrip)) { - ThumbnailTabHelper::CreateForWebContents(web_contents); - } + ThumbnailTabHelper::CreateForWebContents(web_contents); + web_modal::WebContentsModalDialogManager::CreateForWebContents(web_contents); if (OmniboxFieldTrial::IsZeroSuggestPrefetchingEnabled()) { ZeroSuggestPrefetchTabHelper::CreateForWebContents(web_contents);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_controller.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_controller.h index 6b1ea2e..efd2420 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_controller.h +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_controller.h
@@ -44,7 +44,7 @@ // Begins listening to the Tab Group in the TabStrip if a local to saved group // connection can be made. Adds the local tab group id and web content tokens. - virtual void ConnectLocalTabGroupIfPossible( + virtual void ConnectLocalTabGroup( const tab_groups::TabGroupId& local_group_id, const base::Uuid& saved_group_guid) = 0; };
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc index d66680d..061a82c 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.cc
@@ -90,7 +90,7 @@ // crashed session / window. This means we will have to manually trigger the // local to saved group linking. if (model()->is_loaded()) { - ConnectLocalTabGroupIfPossible(local_group_id, saved_guid); + ConnectLocalTabGroup(local_group_id, saved_guid); } else { saved_guid_to_local_group_id_mapping_.emplace_back(saved_guid, local_group_id); @@ -264,43 +264,45 @@ model_.OnGroupClosedInTabStrip(group_id); } -void SavedTabGroupKeyedService::ConnectLocalTabGroupIfPossible( +void SavedTabGroupKeyedService::ConnectLocalTabGroup( const tab_groups::TabGroupId& local_group_id, const base::Uuid& saved_guid) { - const TabStripModel* tab_strip_model = - GetTabStripModelWithTabGroupId(local_group_id); + Browser* const browser = + SavedTabGroupUtils::GetBrowserWithTabGroupId(local_group_id); + CHECK(browser); + + TabStripModel* const tab_strip_model = browser->tab_strip_model(); + CHECK(tab_strip_model); + TabGroup* const tab_group = tab_strip_model->group_model()->GetTabGroup(local_group_id); CHECK(tab_group); - const gfx::Range& tab_range = tab_group->ListTabs(); const SavedTabGroup* const saved_group = model_.Get(saved_guid); CHECK(saved_group); - if (tab_range.length() != saved_group->saved_tabs().size()) { - return; + const size_t tabs_in_group = tab_group->tab_count(); + const size_t tabs_in_saved_group = saved_group->saved_tabs().size(); + const bool saved_group_has_less_tabs = tabs_in_saved_group < tabs_in_group; + const bool saved_group_has_more_tabs = tabs_in_saved_group > tabs_in_group; + + if (saved_group_has_more_tabs) { + AddMissingTabsToOutOfSyncLocalTabGroup(browser, tab_group, saved_group); + } else if (saved_group_has_less_tabs) { + RemoveExtraTabsFromOutOfSyncLocalTabGroup(tab_strip_model, tab_group, + saved_group); } - std::vector<std::pair<content::WebContents*, base::Uuid>> - web_contents_to_guid_mapping; + const gfx::Range& tab_range = tab_group->ListTabs(); + CHECK(tab_range.length() == tabs_in_saved_group); - for (size_t index_in_tabstrip = tab_range.start(); - index_in_tabstrip < tab_range.end(); ++index_in_tabstrip) { - content::WebContents* web_contents = - tab_strip_model->GetWebContentsAt(index_in_tabstrip); - CHECK(web_contents); - - const int saved_tab_index = index_in_tabstrip - tab_range.start(); - const SavedTabGroupTab& saved_tab = - saved_group->saved_tabs()[saved_tab_index]; - - web_contents_to_guid_mapping.emplace_back(web_contents, - saved_tab.saved_tab_guid()); - } + UpdateWebContentsToMatchSavedTabGroupTabs(tab_strip_model, saved_group, + tab_range); model_.OnGroupOpenedInTabStrip(saved_guid, local_group_id); - listener_.ConnectToLocalTabGroup(*model_.Get(saved_guid), - std::move(web_contents_to_guid_mapping)); + listener_.ConnectToLocalTabGroup( + *model_.Get(saved_guid), GetWebContentsToTabGuidMappingForSavedGroup( + tab_strip_model, saved_group, tab_range)); UpdateGroupVisualData(saved_guid, local_group_id); } @@ -312,7 +314,7 @@ continue; } - ConnectLocalTabGroupIfPossible(local_group_id, saved_guid); + ConnectLocalTabGroup(local_group_id, saved_guid); } // Clear `saved_guid_to_local_group_id_mapping_` to save space when finished. @@ -325,6 +327,17 @@ CHECK(saved_guid_to_local_group_id_mapping_.empty()); } +void SavedTabGroupKeyedService::SavedTabGroupRemovedFromSync( + const SavedTabGroup* removed_group) { + // Do nothing if `removed_group` is not open in the tabstrip. + if (!removed_group->local_group_id().has_value()) { + return; + } + + // Update the local group's contents to match the saved group's. + listener_.RemoveLocalGroupFromSync(removed_group->local_group_id().value()); +} + void SavedTabGroupKeyedService::SavedTabGroupUpdatedFromSync( const base::Uuid& group_guid, const absl::optional<base::Uuid>& tab_guid) { @@ -342,15 +355,95 @@ listener_.UpdateLocalGroupFromSync(saved_group->local_group_id().value()); } -void SavedTabGroupKeyedService::SavedTabGroupRemovedFromSync( - const SavedTabGroup* removed_group) { - // Do nothing if `removed_group` is not open in the tabstrip. - if (!removed_group->local_group_id().has_value()) { - return; +void SavedTabGroupKeyedService::AddMissingTabsToOutOfSyncLocalTabGroup( + Browser* browser, + const TabGroup* const tab_group, + const SavedTabGroup* const saved_group) { + size_t num_tabs_in_saved_group = saved_group->saved_tabs().size(); + size_t num_tabs_in_local_group = tab_group->tab_count(); + + for (size_t relative_index_in_group = num_tabs_in_local_group; + relative_index_in_group < num_tabs_in_saved_group; + ++relative_index_in_group) { + const GURL url_to_add = + saved_group->saved_tabs()[relative_index_in_group].url(); + + // Open the tab in the tabstrip and add it to the end of the group. + const content::WebContents* const new_tab = + SavedTabGroupUtils::OpenTabInBrowser( + url_to_add, browser, profile_, + WindowOpenDisposition::NEW_BACKGROUND_TAB); + + const int tab_index = + browser->tab_strip_model()->GetIndexOfWebContents(new_tab); + browser->tab_strip_model()->AddToExistingGroup({tab_index}, + tab_group->id()); } - // Update the local group's contents to match the saved group's. - listener_.RemoveLocalGroupFromSync(removed_group->local_group_id().value()); + CHECK(size_t(tab_group->tab_count()) == num_tabs_in_saved_group); +} + +void SavedTabGroupKeyedService::RemoveExtraTabsFromOutOfSyncLocalTabGroup( + TabStripModel* tab_strip_model, + TabGroup* const tab_group, + const SavedTabGroup* const saved_group) { + size_t num_tabs_in_saved_group = saved_group->saved_tabs().size(); + + // Remove tabs from the end of the tab group to even out the number of tabs in + // the local and saved group. + while (tab_group->tab_count() > int(num_tabs_in_saved_group)) { + const int last_tab = tab_group->GetLastTab().value(); + tab_strip_model->CloseWebContentsAt( + last_tab, TabCloseTypes::CLOSE_CREATE_HISTORICAL_TAB); + } + + CHECK(size_t(tab_group->tab_count()) == num_tabs_in_saved_group); +} + +void SavedTabGroupKeyedService::UpdateWebContentsToMatchSavedTabGroupTabs( + const TabStripModel* const tab_strip_model, + const SavedTabGroup* const saved_group, + const gfx::Range& tab_range) { + for (size_t index_in_tabstrip = tab_range.start(); + index_in_tabstrip < tab_range.end(); ++index_in_tabstrip) { + content::WebContents* const web_contents = + tab_strip_model->GetWebContentsAt(index_in_tabstrip); + CHECK(web_contents); + + const int saved_tab_index = index_in_tabstrip - tab_range.start(); + const SavedTabGroupTab& saved_tab = + saved_group->saved_tabs()[saved_tab_index]; + + if (saved_tab.url() != web_contents->GetLastCommittedURL()) { + web_contents->GetController().LoadURLWithParams( + content::NavigationController::LoadURLParams(saved_tab.url())); + } + } +} + +std::vector<std::pair<content::WebContents*, base::Uuid>> +SavedTabGroupKeyedService::GetWebContentsToTabGuidMappingForSavedGroup( + const TabStripModel* const tab_strip_model, + const SavedTabGroup* const saved_group, + const gfx::Range& tab_range) { + std::vector<std::pair<content::WebContents*, base::Uuid>> + web_contents_to_guid_mapping; + + for (size_t index_in_tabstrip = tab_range.start(); + index_in_tabstrip < tab_range.end(); ++index_in_tabstrip) { + content::WebContents* const web_contents = + tab_strip_model->GetWebContentsAt(index_in_tabstrip); + CHECK(web_contents); + + const int saved_tab_index = index_in_tabstrip - tab_range.start(); + const SavedTabGroupTab& saved_tab = + saved_group->saved_tabs()[saved_tab_index]; + + web_contents_to_guid_mapping.emplace_back(web_contents, + saved_tab.saved_tab_guid()); + } + + return web_contents_to_guid_mapping; } void SavedTabGroupKeyedService::FocusFirstTabInOpenGroup(
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h index 3d6a19e..0044dd6 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service.h
@@ -13,8 +13,10 @@ #include "components/saved_tab_groups/saved_tab_group_model.h" #include "components/saved_tab_groups/saved_tab_group_sync_bridge.h" #include "components/tab_groups/tab_group_id.h" +#include "ui/gfx/range/range.h" class Profile; +class TabGroup; // Serves to instantiate and own the SavedTabGroup infrastructure for the // browser. @@ -50,9 +52,8 @@ const base::Uuid& saved_group_guid, const tab_groups::TabGroupId& group_id) override; void DisconnectLocalTabGroup(const tab_groups::TabGroupId& group_id) override; - void ConnectLocalTabGroupIfPossible( - const tab_groups::TabGroupId& group_id, - const base::Uuid& saved_group_guid) override; + void ConnectLocalTabGroup(const tab_groups::TabGroupId& group_id, + const base::Uuid& saved_group_guid) override; // SavedTabGroupModelObserver void SavedTabGroupModelLoaded() override; @@ -62,6 +63,35 @@ const absl::optional<base::Uuid>& tab_guid) override; private: + // Adds tabs to `tab_group` if `saved_group` was modified and has more tabs + // than `tab_group` when a restore happens. + void AddMissingTabsToOutOfSyncLocalTabGroup( + Browser* browser, + const TabGroup* const tab_group, + const SavedTabGroup* const saved_group); + + // Remove tabs from `tab_group` if `saved_group` was modified and has less + // tabs than `tab_group` when a restore happens. + void RemoveExtraTabsFromOutOfSyncLocalTabGroup( + TabStripModel* tab_strip_model, + TabGroup* const tab_group, + const SavedTabGroup* const saved_group); + + // Updates the tabs in the range `tab_range` to match the URLs of the + // SavedTabGroupTabs in `saved_group`. + void UpdateWebContentsToMatchSavedTabGroupTabs( + const TabStripModel* const tab_strip_model, + const SavedTabGroup* const saved_group, + const gfx::Range& tab_range); + + // Connects all SavedTabGroupTabs from a SavedTabGroup to their respective + // WebContents in the local TabGroup. + std::vector<std::pair<content::WebContents*, base::Uuid>> + GetWebContentsToTabGuidMappingForSavedGroup( + const TabStripModel* const tab_strip_model, + const SavedTabGroup* const saved_group, + const gfx::Range& tab_range); + // Activates the first tab in saved group that is already opened when its // button is pressed. void FocusFirstTabInOpenGroup(tab_groups::TabGroupId local_group_id);
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc index af85041..78e9195ca 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_keyed_service_unittest.cc
@@ -445,6 +445,109 @@ EXPECT_EQ(tab_group->visual_data()->color(), retrieved_saved_group->color()); } +TEST_F(SavedTabGroupKeyedServiceUnitTest, + KeyedServiceUpdatesRestoredGroupWithOneLessTabToMatchSavedGroup) { + Browser* browser = AddBrowser(); + ASSERT_EQ(0, browser->tab_strip_model()->count()); + + // Add 1 tab to the browser. + AddTabToBrowser(browser, 0); + ASSERT_EQ(1, browser->tab_strip_model()->count()); + + const tab_groups::TabGroupId tab_group_id = + browser->tab_strip_model()->AddToNewGroup({0}); + const base::Uuid guid = base::Uuid::GenerateRandomV4(); + + // Store the guid to tab_group_id association in the keyed service. + service()->StoreLocalToSavedId(guid, tab_group_id); + + // Populate the SavedTabGroupModel with some test data to simulate the browser + // loading persisted data on startup. + std::vector<SavedTabGroupTab> group_tabs = { + SavedTabGroupTab(GURL("https://www.google.com"), u"Google", guid, + /*position=*/0), + SavedTabGroupTab(GURL("https://www.youtube.com"), u"Youtube", guid, + /*position=*/1)}; + + SavedTabGroup saved_group(u"Group", tab_groups::TabGroupColorId::kGrey, + std::move(group_tabs), absl::nullopt, guid); + service()->model()->Add(saved_group); + + // Notify the KeyedService that the SavedTabGroupModel has loaded all local + // data triggered by the completion of SavedTabGroupModel::LoadStoredEntries. + service()->model()->LoadStoredEntries({}); + + // Retrieve the saved group from the SavedTabGroupModel. + SavedTabGroupModel* model = service()->model(); + const SavedTabGroup* retrieved_saved_group = model->Get(guid); + + // Retrieve the tab group from the TabStripModel. + const TabStripModel* tab_strip_model = browser->tab_strip_model(); + ASSERT_TRUE(tab_strip_model); + + const TabGroup* tab_group = + tab_strip_model->group_model()->GetTabGroup(tab_group_id); + ASSERT_TRUE(tab_group); + + // Verify the tabs of the groups are the same and have the same order. + const gfx::Range& tab_range = tab_group->ListTabs(); + ASSERT_EQ(tab_range.length(), retrieved_saved_group->saved_tabs().size()); + + // TODO(crbug/1450319): Compare tabs and ensure they are in the same order and + // contain the same data. +} + +TEST_F(SavedTabGroupKeyedServiceUnitTest, + KeyedServiceUpdatesRestoredGroupWithExtraTabToMatchSavedGroup) { + Browser* browser = AddBrowser(); + ASSERT_EQ(0, browser->tab_strip_model()->count()); + + // Add 2 tabs to the browser. + AddTabToBrowser(browser, 0); + AddTabToBrowser(browser, 1); + ASSERT_EQ(2, browser->tab_strip_model()->count()); + + const tab_groups::TabGroupId tab_group_id = + browser->tab_strip_model()->AddToNewGroup({0, 1}); + const base::Uuid guid = base::Uuid::GenerateRandomV4(); + + // Store the guid to tab_group_id association in the keyed service. + service()->StoreLocalToSavedId(guid, tab_group_id); + + // Populate the SavedTabGroupModel with some test data to simulate the browser + // loading persisted data on startup. + std::vector<SavedTabGroupTab> group_tabs = { + SavedTabGroupTab(GURL("https://www.google.com"), u"Google", guid, + /*position=*/0)}; + + SavedTabGroup saved_group(u"Group", tab_groups::TabGroupColorId::kGrey, + std::move(group_tabs), absl::nullopt, guid); + service()->model()->Add(saved_group); + + // Notify the KeyedService that the SavedTabGroupModel has loaded all local + // data triggered by the completion of SavedTabGroupModel::LoadStoredEntries. + service()->model()->LoadStoredEntries({}); + + // Retrieve the saved group from the SavedTabGroupModel. + SavedTabGroupModel* model = service()->model(); + const SavedTabGroup* retrieved_saved_group = model->Get(guid); + + // Retrieve the tab group from the TabStripModel. + const TabStripModel* tab_strip_model = browser->tab_strip_model(); + ASSERT_TRUE(tab_strip_model); + + const TabGroup* tab_group = + tab_strip_model->group_model()->GetTabGroup(tab_group_id); + ASSERT_TRUE(tab_group); + + // Verify the tabs of the groups are the same and have the same order. + const gfx::Range& tab_range = tab_group->ListTabs(); + ASSERT_EQ(tab_range.length(), retrieved_saved_group->saved_tabs().size()); + + // TODO(crbug/1450319): Compare tabs and ensure they are in the same order and + // contain the same data. +} + TEST_F(SavedTabGroupKeyedServiceUnitTest, NewTabFromSyncOpensInLocalGroup) { Browser* const browser = AddBrowser(); TabStripModel* const tabstrip = browser->tab_strip_model();
diff --git a/chrome/browser/ui/tabs/tab_style.cc b/chrome/browser/ui/tabs/tab_style.cc index b764cb8..3c8dc35 100644 --- a/chrome/browser/ui/tabs/tab_style.cc +++ b/chrome/browser/ui/tabs/tab_style.cc
@@ -39,6 +39,7 @@ int GetTopCornerRadius() const override; int GetBottomCornerRadius() const override; gfx::Size GetSeparatorSize() const override; + int GetContentsHorizontalInsetSize() const override; }; } // namespace @@ -105,6 +106,10 @@ return gfx::Size(kChromeRefreshSeparatorThickness, GetSeparatorHeight()); } +int ChromeRefresh2023TabStyle::GetContentsHorizontalInsetSize() const { + return GetBottomCornerRadius() + 8; +} + // static const TabStyle* TabStyle::Get() { static TabStyle* const tab_style =
diff --git a/chrome/browser/ui/tabs/tab_style.h b/chrome/browser/ui/tabs/tab_style.h index b7c6bb96..96f9dcd 100644 --- a/chrome/browser/ui/tabs/tab_style.h +++ b/chrome/browser/ui/tabs/tab_style.h
@@ -133,6 +133,10 @@ // Opacity of the active tab background painted over inactive selected tabs. virtual float GetSelectedTabOpacity() const = 0; + // Returns how far from the leading and trailing edges of a tab the contents + // should actually be laid out. + virtual int GetContentsHorizontalInsetSize() const; + // The largest valid value of TabStyle::GetZValue(). Currently, // GM2TabStyle::GetZValue is the only implementation, and it can't return // values larger than 7. @@ -142,10 +146,6 @@ static const TabStyle* Get(); - // Returns how far from the leading and trailing edges of a tab the contents - // should actually be laid out. - int GetContentsHorizontalInsetSize() const; - protected: // Avoid implicitly-deleted constructor. TabStyle() = default;
diff --git a/chrome/browser/ui/test/popup_test_base.cc b/chrome/browser/ui/test/popup_test_base.cc index 3c2ef5ba..3229fe5 100644 --- a/chrome/browser/ui/test/popup_test_base.cc +++ b/chrome/browser/ui/test/popup_test_base.cc
@@ -114,11 +114,34 @@ permissions::PermissionRequestManager::FromWebContents(web_contents); permission_request_manager->set_auto_response_for_test( permissions::PermissionRequestManager::ACCEPT_ALL); + // TODO(crbug.com/1450391): Resolve flaky permission failures. + content::RenderFrameHost* rfh = web_contents->GetPrimaryMainFrame(); + ASSERT_TRUE(content::WaitForLoadStop(web_contents)); + ASSERT_TRUE(content::WaitForRenderFrameReady(rfh)); + ASSERT_EQ("complete", EvalJs(web_contents, "document.readyState")); + ASSERT_EQ("visible", EvalJs(web_contents, "document.visibilityState")); ASSERT_GT(EvalJs(web_contents, R"JS(getScreenDetails().then(s => { window.screenDetails = s; return s.screens.length; }))JS"), - 0); + 0) + << " GetVisibleURL: " + << web_contents->GetVisibleURL().possibly_invalid_spec() + << " GetLastCommittedURL: " + << rfh->GetLastCommittedURL().possibly_invalid_spec() + << " GetLastCommittedOrigin: " + << rfh->GetLastCommittedOrigin().GetDebugString() + << " IsInPrimaryMainFrame: " << rfh->IsInPrimaryMainFrame() + << " GetLifecycleState: " + << static_cast<std::underlying_type< + content::RenderFrameHost::LifecycleState>::type>( + rfh->GetLifecycleState()) + << " IsActive: " << rfh->IsActive() + << " IsDOMContentLoaded: " << rfh->IsDOMContentLoaded() + << " IsFeatureEnabled: " + << rfh->IsFeatureEnabled( + blink::mojom::PermissionsPolicyFeature::kWindowManagement); + // Do not auto-accept any other permission requests. permission_request_manager->set_auto_response_for_test( permissions::PermissionRequestManager::NONE);
diff --git a/chrome/browser/ui/views/BUILD.gn b/chrome/browser/ui/views/BUILD.gn index 6313a62..a44c21e3 100644 --- a/chrome/browser/ui/views/BUILD.gn +++ b/chrome/browser/ui/views/BUILD.gn
@@ -49,10 +49,7 @@ ] if (is_chromeos_ash) { - deps += [ - "//ash", - "//chrome/browser/ash/crosapi:browser_util", - ] + deps += [ "//ash" ] } }
diff --git a/chrome/browser/ui/views/accelerator_table.cc b/chrome/browser/ui/views/accelerator_table.cc index 728f29f..08b9080 100644 --- a/chrome/browser/ui/views/accelerator_table.cc +++ b/chrome/browser/ui/views/accelerator_table.cc
@@ -24,10 +24,6 @@ #include "ui/base/ui_base_features.h" #include "ui/events/event_constants.h" -#if BUILDFLAG(IS_CHROMEOS_ASH) -#include "chrome/browser/ash/crosapi/browser_util.h" -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - namespace { // For ChromeOS only: If you plan on adding a new accelerator and want it @@ -48,6 +44,7 @@ #if !BUILDFLAG(IS_CHROMEOS) {ui::VKEY_F7, ui::EF_NONE, IDC_CARET_BROWSING_TOGGLE}, #endif + {ui::VKEY_F12, ui::EF_NONE, IDC_DEV_TOOLS_TOGGLE}, {ui::VKEY_ESCAPE, ui::EF_NONE, IDC_CLOSE_FIND_OR_STOP}, #if !BUILDFLAG(IS_MAC) @@ -122,7 +119,7 @@ {ui::VKEY_8, ui::EF_ALT_DOWN, IDC_SELECT_TAB_7}, {ui::VKEY_NUMPAD8, ui::EF_ALT_DOWN, IDC_SELECT_TAB_7}, {ui::VKEY_BROWSER_FAVORITES, ui::EF_NONE, IDC_SHOW_BOOKMARK_BAR}, -#endif // BUILDFLAG(IS_LINUX) +#endif // BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR, IDC_SHOW_BOOKMARK_BAR}, {ui::VKEY_OEM_MINUS, ui::EF_PLATFORM_ACCELERATOR, IDC_ZOOM_MINUS}, @@ -197,9 +194,9 @@ {ui::VKEY_BROWSER_SEARCH, ui::EF_NONE, IDC_FOCUS_SEARCH}, #endif // BUILDFLAG(IS_CHROMEOS) -#if BUILDFLAG(GOOGLE_CHROME_BRANDING) +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_MAC) {ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, IDC_FEEDBACK}, -#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) +#endif // BUILDFLAG(GOOGLE_CHROME_BRANDING) && !BUILDFLAG(IS_MAC) {ui::VKEY_N, ui::EF_SHIFT_DOWN | ui::EF_PLATFORM_ACCELERATOR, IDC_NEW_INCOGNITO_WINDOW}, {ui::VKEY_T, ui::EF_PLATFORM_ACCELERATOR, IDC_NEW_TAB}, @@ -216,6 +213,11 @@ #if BUILDFLAG(ENABLE_PRINTING) {ui::VKEY_P, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_BASIC_PRINT}, #endif // ENABLE_PRINTING + {ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_DEV_TOOLS}, + {ui::VKEY_J, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, + IDC_DEV_TOOLS_CONSOLE}, + {ui::VKEY_C, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, + IDC_DEV_TOOLS_INSPECT}, {ui::VKEY_B, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, IDC_FOCUS_BOOKMARKS}, {ui::VKEY_A, ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, IDC_FOCUS_INACTIVE_POPUP_FOR_ACCESSIBILITY}, @@ -232,6 +234,7 @@ IDC_SHOW_BOOKMARK_MANAGER}, {ui::VKEY_J, ui::EF_CONTROL_DOWN, IDC_SHOW_DOWNLOADS}, {ui::VKEY_H, ui::EF_CONTROL_DOWN, IDC_SHOW_HISTORY}, + {ui::VKEY_U, ui::EF_CONTROL_DOWN, IDC_VIEW_SOURCE}, #if !BUILDFLAG(IS_CHROMEOS) // On Chrome OS, these keys are assigned to change UI scale. {ui::VKEY_OEM_MINUS, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, @@ -250,18 +253,6 @@ #endif }; -const AcceleratorMapping kDevToolsAcceleratorMap[] = { - {ui::VKEY_F12, ui::EF_NONE, IDC_DEV_TOOLS_TOGGLE}, -#if !BUILDFLAG(IS_MAC) - {ui::VKEY_I, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, IDC_DEV_TOOLS}, - {ui::VKEY_J, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, - IDC_DEV_TOOLS_CONSOLE}, - {ui::VKEY_C, ui::EF_SHIFT_DOWN | ui::EF_CONTROL_DOWN, - IDC_DEV_TOOLS_INSPECT}, - {ui::VKEY_U, ui::EF_CONTROL_DOWN, IDC_VIEW_SOURCE}, -#endif // !BUILDFLAG(IS_MAC) -}; - #if BUILDFLAG(IS_CHROMEOS_ASH) // Accelerators to enable if features::IsNewShortcutMappingEnabled is false. const AcceleratorMapping kDisableWithNewMappingAcceleratorMap[] = { @@ -312,20 +303,6 @@ if (accelerators->empty()) { accelerators->insert(accelerators->begin(), std::begin(kAcceleratorMap), std::end(kAcceleratorMap)); - - // TODO(junis): Add unit tests for DevTools accelerators - bool enable_devtools = true; -#if BUILDFLAG(IS_CHROMEOS_ASH) - // In Ash, DevTools is disabled by default if lacros is the only browser, in - // order not to confuse users by opening Ash browser windows. - enable_devtools = crosapi::browser_util::IsAshDevToolEnabled(); -#endif // BUILDFLAG(IS_CHROMEOS_ASH) - if (enable_devtools) { - accelerators->insert(accelerators->begin(), - std::begin(kDevToolsAcceleratorMap), - std::end(kDevToolsAcceleratorMap)); - } - // See https://devblogs.microsoft.com/oldnewthing/20040329-00/?p=40003 // Doing this check here and not at the bottom since kUIDebugAcceleratorMap // contains Ctrl+Alt keys but we don't enable those for the public.
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc index 512d5cb4..75b9243 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view.cc
@@ -218,8 +218,9 @@ BookmarkButtonBase(PressedCallback callback, const std::u16string& title) : LabelButton(std::move(callback), title) { ConfigureInkDropForToolbar(this); - SetImageLabelSpacing(ChromeLayoutProvider::Get()->GetDistanceMetric( - DISTANCE_RELATED_LABEL_HORIZONTAL_LIST)); + + SetImageLabelSpacing( + GetLayoutConstant(BOOKMARK_BAR_BUTTON_IMAGE_LABEL_PADDING)); views::InstallPillHighlightPathGenerator(this); @@ -1566,8 +1567,9 @@ // are directed to ::OnMenuButtonPressed(). DCHECK(node->is_url()); RecordAppLaunch(browser_->profile(), node->url()); - chrome::OpenAllIfAllowed(browser_, {node}, - ui::DispositionFromEventFlags(event.flags()), false); + chrome::OpenAllIfAllowed( + browser_, {node}, ui::DispositionFromEventFlags(event.flags()), false, + {{BookmarkLaunchLocation::kAttachedBar, base::TimeTicks::Now()}}); if (event.IsMouseEvent()) { base::UmaHistogramEnumeration( "Prerender.Experimental.BookmarkUrlButtonEvent", @@ -1586,7 +1588,8 @@ (event.flags() & ui::EF_PLATFORM_ACCELERATOR)) { RecordBookmarkFolderLaunch(BookmarkLaunchLocation::kAttachedBar); chrome::OpenAllIfAllowed( - browser_, {node}, ui::DispositionFromEventFlags(event.flags()), false); + browser_, {node}, ui::DispositionFromEventFlags(event.flags()), false, + {{BookmarkLaunchLocation::kAttachedBar, base::TimeTicks::Now()}}); } else { RecordBookmarkFolderOpen(BookmarkLaunchLocation::kAttachedBar); const size_t start_index = (node == bookmark_model_->bookmark_bar_node())
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc index a16c34d..839b267 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_test.cc
@@ -54,6 +54,7 @@ #include "components/constrained_window/constrained_window_views.h" #include "components/prefs/pref_service.h" #include "content/public/browser/page_navigator.h" +#include "third_party/abseil-cpp/absl/cleanup/cleanup.h" #include "ui/base/test/ui_controls.h" #include "ui/display/display_switches.h" #include "ui/events/keycodes/keyboard_codes.h" @@ -403,9 +404,13 @@ return size; } - views::LabelButton* GetBookmarkButton(size_t view_index) { + const views::LabelButton* GetBookmarkButton(size_t view_index) const { return bb_view_->bookmark_buttons_[view_index]; } + views::LabelButton* GetBookmarkButton(size_t view_index) { + return const_cast<views::LabelButton*>( + std::as_const(*this).GetBookmarkButton(view_index)); + } // See comment above class description for what this does. virtual bool CreateBigMenu() { return false; } @@ -471,11 +476,13 @@ } void OnWidgetDragComplete(views::Widget* widget) override { + absl::Cleanup done = [&] { Done(); }; + // All drag tests drag node f1a, so at the end of the test, if the node was // dropped where it was expected, the dropped node should have f1a's URL. - EXPECT_EQ(f1a_url_, GetDroppedNode()->url()); - - Done(); + const BookmarkNode* dropped_node = GetDroppedNode(); + ASSERT_TRUE(dropped_node); + EXPECT_EQ(f1a_url_, dropped_node->url()); } void OnWidgetDestroying(views::Widget* widget) override { @@ -776,9 +783,8 @@ base::OnceClosure task_; }; -// Tests context menus by way of opening a context menu for a bookmark, -// then right clicking to get context menu and selecting the first menu item -// (open). +// Opens a bookmark folder, right clicks on the first bookmark to get a context +// menu, and selects the first menu item (open). class BookmarkBarViewTest4 : public BookmarkBarViewEventTestBase { public: BookmarkBarViewTest4() @@ -2314,3 +2320,58 @@ #endif VIEW_TEST(BookmarkBarViewTest28, MAYBE_ClickWithModifierOnFolderOpensAllBookmarks) + +// Tests drag and drop to an empty menu. +class BookmarkBarViewTest29 : public BookmarkBarViewDragTestBase { + public: + // BookmarkBarViewDragTestBase: + void OnDropMenuShown() override { + // The folder's menu should be open, showing an "(empty)" placeholder. + views::MenuItemView* drop_menu = bb_view_->GetDropMenu(); + ASSERT_NE(nullptr, drop_menu); + views::SubmenuView* drop_submenu = drop_menu->GetSubmenu(); + ASSERT_TRUE(drop_submenu->IsShowing()); + ASSERT_FALSE(drop_submenu->children().empty()); + const views::View* target_view = drop_submenu->children().front(); + EXPECT_TRUE(views::IsViewClass<views::EmptyMenuMenuItem>(target_view)); + + // Drag to the "(empty)" placeholder item, then release. + const gfx::Point target = + ui_test_utils::GetCenterInScreenCoordinates(target_view); + GetDragTaskRunner()->PostTask( + FROM_HERE, + base::BindOnce(base::IgnoreResult(&ui_controls::SendMouseMove), + target.x(), target.y(), ui_controls::kNoWindowHint)); + // The placeholder item is not an event target, so we can't automatically + // stop the drag when over it. Just post the mouse release after the move. + OnDragEntered(); + } + + protected: + // BookmarkBarViewDragTestBase: + const BookmarkNode* GetDroppedNode() const override { + // Should be the first (and only) child of folder F2. + if (model_->bookmark_bar_node()->children().size() < 6) { + return nullptr; + } + const auto* f2 = model_->bookmark_bar_node()->children()[5].get(); + return f2->children().empty() ? nullptr : f2->children().front().get(); + } + + gfx::Point GetDragTargetInScreen() const override { + // Drag over folder F2. + return ui_test_utils::GetCenterInScreenCoordinates(GetBookmarkButton(5)); + } +}; + +// TODO(https://crbug.com/1448943): Fails on Linux/CrOS, perhaps because +// OnDropMenuShown() tries to call OnDragEntered() before waiting for +// verification that we're actually over the target. +// +// Flaky on Mac. +#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_MAC) +#define MAYBE_DNDToEmptyMenu DISABLED_DNDToEmptyMenu +#else +#define MAYBE_DNDToEmptyMenu DNDToEmptyMenu +#endif +VIEW_TEST(BookmarkBarViewTest29, MAYBE_DNDToEmptyMenu)
diff --git a/chrome/browser/ui/views/borealis/borealis_installer_disallowed_dialog.cc b/chrome/browser/ui/views/borealis/borealis_installer_disallowed_dialog.cc index b8b0bc15..6eb0384 100644 --- a/chrome/browser/ui/views/borealis/borealis_installer_disallowed_dialog.cc +++ b/chrome/browser/ui/views/borealis/borealis_installer_disallowed_dialog.cc
@@ -70,9 +70,6 @@ case AllowStatus::kUserPrefBlocked: return {l10n_util::GetStringUTF16(IDS_BOREALIS_DISALLOWED_ADMIN), absl::nullopt}; - case AllowStatus::kBlockedOnStable: - return {l10n_util::GetStringUTF16(IDS_BOREALIS_DISALLOWED_CHANNEL), - GURL("https://support.google.com/chromebook/answer/177889")}; case AllowStatus::kBlockedByFlag: return {l10n_util::GetStringUTF16(IDS_BOREALIS_DISALLOWED_FLAG), absl::nullopt};
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc b/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc index d5cdebe30..36d7477 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_coordinator.cc
@@ -7,6 +7,7 @@ #include <memory> #include "base/feature_list.h" +#include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/extensions/extensions_menu_view_controller.h" #include "extensions/common/extension_features.h" #include "ui/views/bubble/bubble_dialog_delegate_view.h" @@ -72,7 +73,7 @@ bubble_delegate->set_margins(gfx::Insets(0)); bubble_delegate->set_fixed_width( views::LayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_BUBBLE_PREFERRED_WIDTH)); + ChromeDistanceMetric::DISTANCE_LARGE_MODAL_DIALOG_PREFERRED_WIDTH)); // Let anchor view's MenuButtonController handle the highlight. bubble_delegate->set_highlight_button_when_shown(false); bubble_delegate->SetButtons(ui::DIALOG_BUTTON_NONE);
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc index 6d091fb..1e81e62 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view.cc
@@ -241,11 +241,8 @@ .SetTextStyle(views::style::STYLE_EMPHASIZED) .SetHorizontalAlignment(gfx::ALIGN_LEFT), // Empty container for the extensions requesting access. - views::Builder<views::BoxLayoutView>() - .SetOrientation(views::BoxLayout::Orientation::kVertical) - .SetProperty( - views::kMarginsKey, - gfx::Insets::TLBR(control_vertical_margin, 0, 0, 0)))) + views::Builder<views::BoxLayoutView>().SetOrientation( + views::BoxLayout::Orientation::kVertical))) .BuildChildren(); } @@ -311,6 +308,9 @@ auto* layout_provider = ChromeLayoutProvider::Get(); const int control_vertical_margin = layout_provider->GetDistanceMetric( DISTANCE_RELATED_CONTROL_VERTICAL_SMALL); + const int related_control_horizontal_margin = + layout_provider->GetDistanceMetric( + DISTANCE_RELATED_LABEL_HORIZONTAL_LIST); auto item = views::Builder<views::FlexLayoutView>() @@ -327,13 +327,18 @@ views::MinimumFlexSizeRule::kScaleToZero, views::MaximumFlexSizeRule::kUnbounded)), views::Builder<views::MdTextButton>() - .SetCallback(base::BindRepeating(allow_callback_, id)) - .SetText(l10n_util::GetStringUTF16( - IDS_EXTENSIONS_MENU_REQUESTS_ACCESS_SECTION_ALLOW_BUTTON_TEXT)), - views::Builder<views::MdTextButton>() .SetCallback(base::BindRepeating(dismiss_callback_, id)) .SetText(l10n_util::GetStringUTF16( - IDS_EXTENSIONS_MENU_REQUESTS_ACCESS_SECTION_DISMISS_BUTTON_TEXT))) + + IDS_EXTENSIONS_MENU_REQUESTS_ACCESS_SECTION_DISMISS_BUTTON_TEXT)), + views::Builder<views::MdTextButton>() + .SetCallback(base::BindRepeating(allow_callback_, id)) + .SetText(l10n_util::GetStringUTF16( + IDS_EXTENSIONS_MENU_REQUESTS_ACCESS_SECTION_ALLOW_BUTTON_TEXT)) + .SetProperty( + views::kMarginsKey, + gfx::Insets::TLBR(0, related_control_horizontal_margin, + 0, 0))) .Build(); extension_entries_.insert({id, item.get()}); requests_access_container_->children()[1]->AddChildViewAt(std::move(item),
diff --git a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc index 2a6a073f..d7d54cc 100644 --- a/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc +++ b/chrome/browser/ui/views/extensions/extensions_menu_main_page_view_unittest.cc
@@ -1142,7 +1142,7 @@ main_page()->GetExtensionRequestingAccessEntryForTesting(extension->id()); ASSERT_TRUE(extension_entry); views::Button* extension_allow_button = - static_cast<views::Button*>(extension_entry->children()[2]); + static_cast<views::Button*>(extension_entry->children()[3]); ClickButton(extension_allow_button); WaitForAnimation(); @@ -1190,7 +1190,7 @@ ASSERT_TRUE(extension_entry); ASSERT_EQ(extension_entry->children().size(), 4u); views::Button* extension_dismiss_button = - static_cast<views::Button*>(extension_entry->children()[3]); + static_cast<views::Button*>(extension_entry->children()[2]); ClickButton(extension_dismiss_button); WaitForAnimation();
diff --git a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc index 755f83d4..eb1368e 100644 --- a/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc +++ b/chrome/browser/ui/views/global_media_controls/media_dialog_view.cc
@@ -528,13 +528,6 @@ void MediaDialogView::InitializeLiveCaptionSection() { auto live_caption_container = std::make_unique<View>(); - auto* live_caption_container_layout = - live_caption_container->SetLayoutManager( - std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, - gfx::Insets::VH(kVerticalMarginDip, kHorizontalMarginDip), - ChromeLayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_RELATED_LABEL_HORIZONTAL))); auto live_caption_image = std::make_unique<views::ImageView>(); live_caption_image->SetImage(ui::ImageModel::FromVectorIcon( @@ -548,7 +541,6 @@ live_caption_title->SetMultiLine(true); live_caption_title_ = live_caption_container->AddChildView(std::move(live_caption_title)); - live_caption_container_layout->SetFlexForView(live_caption_title_, 1); auto live_caption_button = std::make_unique<views::ToggleButton>( base::BindRepeating(&MediaDialogView::OnLiveCaptionButtonPressed, @@ -559,6 +551,17 @@ live_caption_button_ = live_caption_container->AddChildView(std::move(live_caption_button)); + auto* live_caption_container_layout = + live_caption_container->SetLayoutManager( + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets::TLBR( + kVerticalMarginDip, kHorizontalMarginDip, kVerticalMarginDip, + kHorizontalMarginDip - + live_caption_button_->GetVisualHorizontalMargin()), + ChromeLayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_RELATED_LABEL_HORIZONTAL))); + live_caption_container_layout->SetFlexForView(live_caption_title_, 1); live_caption_container_ = AddChildView(std::move(live_caption_container)); } @@ -566,15 +569,6 @@ auto live_translate_container = std::make_unique<View>(); live_translate_container->SetVisible( profile_->GetPrefs()->GetBoolean(prefs::kLiveCaptionEnabled)); - auto* live_translate_container_layout = - live_translate_container->SetLayoutManager( - std::make_unique<views::BoxLayout>( - views::BoxLayout::Orientation::kHorizontal, - gfx::Insets::VH(kVerticalMarginDip, kHorizontalMarginDip), - ChromeLayoutProvider::Get()->GetDistanceMetric( - views::DISTANCE_RELATED_LABEL_HORIZONTAL))); - live_translate_container_layout->set_cross_axis_alignment( - views::BoxLayout::CrossAxisAlignment::kStart); auto live_translate_image = std::make_unique<views::ImageView>(); live_translate_image->SetImage(ui::ImageModel::FromVectorIcon( @@ -604,8 +598,6 @@ live_translate_label_wrapper_ = live_translate_container->AddChildView( std::move(live_translate_label_wrapper)); - live_translate_container_layout->SetFlexForView(live_translate_label_wrapper_, - 1); auto live_translate_button = std::make_unique<views::ToggleButton>( base::BindRepeating(&MediaDialogView::OnLiveTranslateButtonPressed, @@ -613,6 +605,20 @@ live_translate_button->SetIsOn( profile_->GetPrefs()->GetBoolean(prefs::kLiveTranslateEnabled)); live_translate_button->SetAccessibleName(live_translate_title_->GetText()); + auto* live_translate_container_layout = + live_translate_container->SetLayoutManager( + std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kHorizontal, + gfx::Insets::TLBR( + kVerticalMarginDip, kHorizontalMarginDip, kVerticalMarginDip, + kHorizontalMarginDip - + live_translate_button->GetVisualHorizontalMargin()), + ChromeLayoutProvider::Get()->GetDistanceMetric( + views::DISTANCE_RELATED_LABEL_HORIZONTAL))); + live_translate_container_layout->set_cross_axis_alignment( + views::BoxLayout::CrossAxisAlignment::kStart); + live_translate_container_layout->SetFlexForView(live_translate_label_wrapper_, + 1); live_translate_button_ = live_translate_container->AddChildView(std::move(live_translate_button)); live_translate_container_ = AddChildView(std::move(live_translate_container));
diff --git a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc index 3601b71e..6049b60 100644 --- a/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/icon_label_bubble_view.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/layout_constants.h" #include "chrome/browser/ui/omnibox/omnibox_theme.h" +#include "chrome/browser/ui/views/location_bar/location_bar_util.h" #include "components/omnibox/browser/omnibox_field_trial.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -247,10 +248,22 @@ void IconLabelBubbleView::UpdateBackground() { // If the label is showing we must ensure the icon label is painted over a // solid background. - SetBackground(paint_label_over_solid_backround_ && ShouldShowLabel() + const bool painted_on_solid_background = + paint_label_over_solid_backround_ && ShouldShowLabel(); + SetBackground(painted_on_solid_background ? views::CreateThemedRoundedRectBackground( - kColorToolbar, GetPreferredSize().height()) + kColorPageInfoBackground, GetPreferredSize().height()) : nullptr); + // TODO(pbos): Consider renaming kPageInfo/kPageAction color IDs to share the + // same prefix. Here PageInfo assumes to have a background and PageAction + // assumes to not have one. + if (OmniboxFieldTrial::IsChromeRefreshIconsEnabled()) { + ConfigureInkDropForRefresh2023(this, + painted_on_solid_background + ? kColorPageInfoIconHover + : kColorPageActionIconHover, + kColorPageInfoIconPressed); + } } bool IconLabelBubbleView::ShouldShowSeparator() const {
diff --git a/chrome/browser/ui/views/page_action/page_action_icon_view.cc b/chrome/browser/ui/views/page_action/page_action_icon_view.cc index 14d3e3d..c0278f29 100644 --- a/chrome/browser/ui/views/page_action/page_action_icon_view.cc +++ b/chrome/browser/ui/views/page_action/page_action_icon_view.cc
@@ -19,7 +19,6 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/models/image_model.h" -#include "ui/base/ui_base_features.h" #include "ui/events/event.h" #include "ui/gfx/color_utils.h" #include "ui/gfx/paint_vector_icon.h" @@ -81,47 +80,6 @@ views::InkDrop::Get(this)->SetMode(views::InkDropHost::InkDropMode::ON); SetFocusBehavior(views::PlatformStyle::kDefaultFocusBehavior); - if (OmniboxFieldTrial::IsChromeRefreshIconsEnabled()) { - // TODO(crbug/1399991): Use the ConfigureInkDropForRefresh2023 method once - // you do not need to hardcode color values. - views::InkDrop::Get(this)->SetMode(views::InkDropHost::InkDropMode::ON); - views::InkDrop::Get(this)->SetLayerRegion(views::LayerRegion::kAbove); - views::InkDrop::Get(this)->SetCreateRippleCallback(base::BindRepeating( - [](views::View* host) -> std::unique_ptr<views::InkDropRipple> { - const auto* color_provider = host->GetColorProvider(); - const SkColor pressed_color = - color_provider - ? color_provider->GetColor(kColorPageActionIconPressed) - : gfx::kPlaceholderColor; - const float pressed_alpha = SkColorGetA(pressed_color); - return std::make_unique<views::FloodFillInkDropRipple>( - views::InkDrop::Get(host), host->size(), - host->GetLocalBounds().CenterPoint(), - SkColorSetA(pressed_color, SK_AlphaOPAQUE), - pressed_alpha / SK_AlphaOPAQUE); - }, - this)); - - views::InkDrop::Get(this)->SetCreateHighlightCallback(base::BindRepeating( - [](views::View* host) { - const auto* color_provider = host->GetColorProvider(); - const SkColor hover_color = - color_provider - ? color_provider->GetColor(kColorPageActionIconHover) - : gfx::kPlaceholderColor; - const float hover_alpha = SkColorGetA(hover_color); - auto ink_drop_highlight = std::make_unique<views::InkDropHighlight>( - host->size(), host->height() / 2, - gfx::PointF(host->GetLocalBounds().CenterPoint()), - SkColorSetA(hover_color, SK_AlphaOPAQUE)); - ink_drop_highlight->set_visible_opacity(hover_alpha / SK_AlphaOPAQUE); - return ink_drop_highlight; - }, - this)); - if (auto* focus_ring = views::FocusRing::Get(this); focus_ring) { - focus_ring->SetOutsetFocusRingDisabled(true); - } - } // Only shows bubble after mouse is released. button_controller()->set_notify_action( views::ButtonController::NotifyAction::kOnRelease);
diff --git a/chrome/browser/ui/views/page_info/page_info_view_factory.cc b/chrome/browser/ui/views/page_info/page_info_view_factory.cc index 79c855a..3525faa 100644 --- a/chrome/browser/ui/views/page_info/page_info_view_factory.cc +++ b/chrome/browser/ui/views/page_info/page_info_view_factory.cc
@@ -270,8 +270,8 @@ : &vector_icons::kPhotoChromeRefreshIcon; break; case ContentSettingsType::JAVASCRIPT: - icon = show_blocked_badge ? &vector_icons::kCodeOffIcon - : &vector_icons::kCodeIcon; + icon = show_blocked_badge ? &vector_icons::kCodeOffChromeRefreshIcon + : &vector_icons::kCodeChromeRefreshIcon; break; case ContentSettingsType::POPUPS: icon = show_blocked_badge ? &vector_icons::kLaunchOffChromeRefreshIcon @@ -308,8 +308,8 @@ break; #endif case ContentSettingsType::MIDI_SYSEX: - icon = show_blocked_badge ? &vector_icons::kMidiOffIcon - : &vector_icons::kMidiIcon; + icon = show_blocked_badge ? &vector_icons::kMidiOffChromeRefreshIcon + : &vector_icons::kMidiChromeRefreshIcon; break; case ContentSettingsType::BACKGROUND_SYNC: icon = show_blocked_badge ? &vector_icons::kSyncOffChromeRefreshIcon @@ -329,8 +329,8 @@ : &vector_icons::kPageInfoContentPasteChromeRefreshIcon; break; case ContentSettingsType::SENSORS: - icon = show_blocked_badge ? &vector_icons::kSensorsOffIcon - : &vector_icons::kSensorsIcon; + icon = show_blocked_badge ? &vector_icons::kSensorsOffChromeRefreshIcon + : &vector_icons::kSensorsChromeRefreshIcon; break; case ContentSettingsType::USB_GUARD: icon = show_blocked_badge ? &vector_icons::kUsbOffChromeRefreshIcon @@ -361,8 +361,8 @@ : &vector_icons::kVrHeadsetChromeRefreshIcon; break; case ContentSettingsType::AR: - icon = show_blocked_badge ? &vector_icons::kViewInArOffIcon - : &vector_icons::kViewInArIcon; + icon = show_blocked_badge ? &vector_icons::kViewInArOffChromeRefreshIcon + : &vector_icons::kViewInArChromeRefreshIcon; break; case ContentSettingsType::WINDOW_MANAGEMENT: icon = show_blocked_badge @@ -380,8 +380,8 @@ : &vector_icons::kVideogameAssetChromeRefreshIcon; break; case ContentSettingsType::IDLE_DETECTION: - icon = show_blocked_badge ? &vector_icons::kDevicesOffIcon - : &vector_icons::kDevicesIcon; + icon = show_blocked_badge ? &vector_icons::kDevicesOffChromeRefreshIcon + : &vector_icons::kDevicesChromeRefreshIcon; break; default: break;
diff --git a/chrome/browser/ui/views/passwords/credentials_item_view.cc b/chrome/browser/ui/views/passwords/credentials_item_view.cc index 95380d7..60f46188 100644 --- a/chrome/browser/ui/views/passwords/credentials_item_view.cc +++ b/chrome/browser/ui/views/passwords/credentials_item_view.cc
@@ -12,7 +12,9 @@ #include "chrome/browser/ui/passwords/ui_utils.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/browser/ui/views/chrome_typography.h" +#include "chrome/grit/generated_resources.h" #include "chrome/grit/theme_resources.h" +#include "components/password_manager/core/browser/affiliation/affiliation_utils.h" #include "components/password_manager/core/browser/password_manager_util.h" #include "components/vector_icons/vector_icons.h" #include "third_party/skia/include/core/SkPath.h" @@ -130,10 +132,24 @@ lower_label_ = text_container->AddChildView(std::move(lower_label)); } + // Add info icon with a tooltip providing the source of the credential if + // this is not an exact match. if (password_manager_util::GetMatchType(*form) != password_manager_util::GetLoginMatchType::kExact) { - info_icon_ = AddChildView(std::make_unique<views::TooltipIcon>( - base::UTF8ToUTF16(form->url.DeprecatedGetOriginAsURL().spec()))); + auto facet = password_manager::FacetURI::FromPotentiallyInvalidSpec( + form->signon_realm); + if (facet.IsValidAndroidFacetURI()) { + std::u16string app_name = base::UTF8ToUTF16(form->app_display_name); + if (app_name.empty()) { + app_name = l10n_util::GetStringFUTF16( + IDS_SETTINGS_PASSWORDS_ANDROID_APP, + base::UTF8ToUTF16(facet.android_package_name())); + } + info_icon_ = AddChildView(std::make_unique<views::TooltipIcon>(app_name)); + } else { + info_icon_ = AddChildView(std::make_unique<views::TooltipIcon>( + base::UTF8ToUTF16(form->url.DeprecatedGetOriginAsURL().spec()))); + } } if (!upper_text.empty() && !lower_text.empty())
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc index 959000f..e728b79 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_page_browsertest.cc
@@ -969,12 +969,25 @@ builder2.is_exps_opted_in = true; EXPECT_TRUE(ExecJs(builder2.Build())); WaitForHistogram("Companion.IsUserOptedInToExps"); - side_panel_coordinator()->OpenInNewTab(); + EXPECT_EQ(side_panel_coordinator() + ->GetCurrentSidePanelEntryForTesting() + ->GetOpenInNewTabURL(), + open_in_new_tab_url); + side_panel_coordinator()->OpenInNewTab(); WaitForTabCount(2); EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); EXPECT_TRUE(web_contents()->GetVisibleURL().spec().starts_with( open_in_new_tab_url.spec())); + + // Close side panel and reopen. The new tab button shouldn't be shown. + side_panel_coordinator()->Close(); + side_panel_coordinator()->Show(SidePanelEntry::Id::kSearchCompanion); + WaitForCompanionToBeLoaded(); + EXPECT_EQ(side_panel_coordinator() + ->GetCurrentSidePanelEntryForTesting() + ->GetOpenInNewTabURL(), + GURL()); } IN_PROC_BROWSER_TEST_F(CompanionPageBrowserTest, PhFeedbackWithReportContent) {
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc index 9f1d061..e74f466 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.cc
@@ -79,6 +79,10 @@ ->UpdateNewTabButtonState(); } +void CompanionSidePanelController::OnCompanionSidePanelClosed() { + open_in_new_tab_url_ = GURL(); +} + content::WebContents* CompanionSidePanelController::GetCompanionWebContentsForTesting() { return web_contents(); @@ -144,10 +148,11 @@ if (open_in_current_tab) { // Add metrics to record the open trigger for the companion page as a link - // click from side panel. + // click from side panel. Note, the user can click on links even before the + // metrics is consumed, e.g. a double click. Either way, just overwrite the + // metrics if it already exists. auto* tab_helper = companion::CompanionTabHelper::FromWebContents(tab_web_contents); - CHECK(!tab_helper->GetAndResetMostRecentSidePanelOpenTrigger().has_value()); tab_helper->SetMostRecentSidePanelOpenTrigger( SidePanelOpenTrigger::kOpenedInNewTabFromSidePanel); }
diff --git a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h index eb56bafb..0e3c650 100644 --- a/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h +++ b/chrome/browser/ui/views/side_panel/search_companion/companion_side_panel_controller.h
@@ -36,6 +36,7 @@ void ShowCompanionSidePanel( SidePanelOpenTrigger side_panel_open_trigger) override; void UpdateNewTabButton(GURL url_to_open) override; + void OnCompanionSidePanelClosed() override; content::WebContents* GetCompanionWebContentsForTesting() override; private:
diff --git a/chrome/browser/ui/views/tabs/tab.cc b/chrome/browser/ui/views/tabs/tab.cc index bc1ae80f..4033f6317 100644 --- a/chrome/browser/ui/views/tabs/tab.cc +++ b/chrome/browser/ui/views/tabs/tab.cc
@@ -64,6 +64,7 @@ #include "ui/base/pointer/touch_ui_controller.h" #include "ui/base/resource/resource_bundle.h" #include "ui/base/theme_provider.h" +#include "ui/base/ui_base_features.h" #include "ui/compositor/clip_recorder.h" #include "ui/compositor/compositor.h" #include "ui/gfx/animation/tween.h" @@ -290,7 +291,10 @@ UpdateIconVisibility(); int start = contents_rect.x(); - if (extra_padding_before_content_) { + + // ChromeRefresh doesnt respect this extra padding since it has exact values + // for left/right padding. + if (extra_padding_before_content_ && !features::IsChromeRefresh2023()) { constexpr int kExtraLeftPaddingToBalanceCloseButtonPadding = 4; start += kExtraLeftPaddingToBalanceCloseButtonPadding; }
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc index 77f4beae..61da9c3 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.cc
@@ -12,6 +12,7 @@ #include "base/memory/raw_ptr.h" #include "base/time/time.h" #include "build/build_config.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/ui/tabs/tab_style.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/chrome_widget_sublevel.h" @@ -23,6 +24,7 @@ #include "chrome/browser/ui/views/tabs/tab_hover_card_thumbnail_observer.h" #include "chrome/browser/ui/views/tabs/tab_strip.h" #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" +#include "chrome/common/pref_names.h" #include "components/omnibox/browser/omnibox_edit_model.h" #include "components/omnibox/browser/omnibox_popup_view.h" #include "components/user_education/common/help_bubble_factory_registry.h" @@ -245,6 +247,23 @@ TabHoverCardController::TabHoverCardController(TabStrip* tab_strip) : tab_strip_(tab_strip) { + if (PrefService* pref_service = g_browser_process->local_state()) { + // Hovercard image previews are still not fully rolled out to all platforms + // so we default the pref to the state of the feature rollout. + pref_service->SetDefaultPrefValue(prefs::kHoverCardImagesEnabled, + base::Value(base::FeatureList::IsEnabled( + features::kTabHoverCardImages))); + + // Register for previews enabled pref change events. + hover_card_image_previews_enabled_ = AreHoverCardImagesEnabled(); + pref_change_registrar_.Init(pref_service); + pref_change_registrar_.Add( + prefs::kHoverCardImagesEnabled, + base::BindRepeating( + &TabHoverCardController::OnHovercardImagesEnabledChanged, + base::Unretained(this))); + } + // Possibly apply memory pressure override for testing. auto override = GetMemoryPressureOverride(); if (override) { @@ -261,7 +280,8 @@ // static bool TabHoverCardController::AreHoverCardImagesEnabled() { - return base::FeatureList::IsEnabled(features::kTabHoverCardImages); + PrefService* pref_service = g_browser_process->local_state(); + return pref_service->GetBoolean(prefs::kHoverCardImagesEnabled); } // static @@ -525,10 +545,10 @@ base::BindRepeating(&TabHoverCardController::OnFadeAnimationEnded, weak_ptr_factory_.GetWeakPtr())); - if (!thumbnail_observer_ && AreHoverCardImagesEnabled()) { + if (!thumbnail_observer_ && hover_card_image_previews_enabled_) { thumbnail_observer_ = std::make_unique<TabHoverCardThumbnailObserver>(); thumbnail_subscription_ = thumbnail_observer_->AddCallback( - base::BindRepeating(&TabHoverCardController::OnPreviewImageAvaialble, + base::BindRepeating(&TabHoverCardController::OnPreviewImageAvailable, weak_ptr_factory_.GetWeakPtr())); } } @@ -755,7 +775,7 @@ OnCardFullyVisible(); } -void TabHoverCardController::OnPreviewImageAvaialble( +void TabHoverCardController::OnPreviewImageAvailable( TabHoverCardThumbnailObserver* observer, gfx::ImageSkia thumbnail_image) { DCHECK_EQ(thumbnail_observer_.get(), observer); @@ -791,3 +811,11 @@ // hovering a card through an entire CRITICAL -> NORMAL transition so as a // simplification we simply don't care. } + +void TabHoverCardController::OnHovercardImagesEnabledChanged() { + hover_card_image_previews_enabled_ = AreHoverCardImagesEnabled(); + if (!hover_card_image_previews_enabled_) { + thumbnail_subscription_ = base::CallbackListSubscription(); + thumbnail_observer_.reset(); + } +}
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller.h b/chrome/browser/ui/views/tabs/tab_hover_card_controller.h index aa321c6a..31c56d8 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller.h +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller.h
@@ -16,6 +16,7 @@ #include "base/time/time.h" #include "base/timer/timer.h" #include "chrome/browser/ui/views/tabs/tab_slot_controller.h" +#include "components/prefs/pref_change_registrar.h" #include "ui/events/event.h" #include "ui/views/animation/bubble_slide_animator.h" #include "ui/views/animation/widget_fade_animator.h" @@ -65,6 +66,8 @@ FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, ShowWrongTabDoesntCrash); FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, SetPreviewWithNoHoverCardDoesntCrash); + FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, ShowPreviewsForTab); + FRIEND_TEST_ALL_PREFIXES(TabHoverCardControllerTest, DisablePreviewsForTab); class EventSniffer; enum ThumbnailWaitState { @@ -111,12 +114,14 @@ double value); void OnSlideAnimationComplete(views::BubbleSlideAnimator* animator); - void OnPreviewImageAvaialble(TabHoverCardThumbnailObserver* observer, + void OnPreviewImageAvailable(TabHoverCardThumbnailObserver* observer, gfx::ImageSkia thumbnail_image); void OnMemoryPressureChanged( base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level); + void OnHovercardImagesEnabledChanged(); + bool waiting_for_preview() const { return thumbnail_wait_state_ != ThumbnailWaitState::kNotWaiting; } @@ -162,6 +167,10 @@ base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE; std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; + // Tracks changes to the hover card image previews preferences + PrefChangeRegistrar pref_change_registrar_; + bool hover_card_image_previews_enabled_ = false; + // Ensure that this timer is destroyed before anything else is cleaned up. base::OneShotTimer delayed_show_timer_; base::WeakPtrFactory<TabHoverCardController> weak_ptr_factory_{this};
diff --git a/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc b/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc index fbbab05..8da114dc 100644 --- a/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc +++ b/chrome/browser/ui/views/tabs/tab_hover_card_controller_unittest.cc
@@ -4,8 +4,12 @@ #include "chrome/browser/ui/views/tabs/tab_hover_card_controller.h" +#include "chrome/browser/browser_process.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/tabs/tab_strip.h" +#include "chrome/common/pref_names.h" // These are regression tests for possible crashes. @@ -29,6 +33,56 @@ std::make_unique<TabHoverCardController>(browser_view()->tabstrip()); // If the safeguard is not in place, this could crash in either metrics // collection *or* in trying to set the actual thumbnail image on the card. - controller->OnPreviewImageAvaialble(controller->thumbnail_observer_.get(), + controller->OnPreviewImageAvailable(controller->thumbnail_observer_.get(), gfx::ImageSkia()); } + +TEST_F(TabHoverCardControllerTest, ShowPreviewsForTab) { + g_browser_process->local_state()->SetBoolean(prefs::kHoverCardImagesEnabled, + true); + + AddTab(browser_view()->browser(), GURL("http://foo1.com")); + AddTab(browser_view()->browser(), GURL("http://foo2.com")); + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + + auto controller = + std::make_unique<TabHoverCardController>(browser_view()->tabstrip()); + + Tab* const target_tab = browser_view()->tabstrip()->tab_at(1); + controller->target_tab_ = target_tab; + + controller->CreateHoverCard(target_tab); + EXPECT_TRUE(controller->ArePreviewsEnabled()); +} + +TEST_F(TabHoverCardControllerTest, DisablePreviewsForTab) { + g_browser_process->local_state()->SetBoolean(prefs::kHoverCardImagesEnabled, + false); + + AddTab(browser_view()->browser(), GURL("http://foo1.com")); + AddTab(browser_view()->browser(), GURL("http://foo2.com")); + browser_view()->browser()->tab_strip_model()->ActivateTabAt(0); + + auto controller = + std::make_unique<TabHoverCardController>(browser_view()->tabstrip()); + + Tab* const target_tab = browser_view()->tabstrip()->tab_at(1); + controller->target_tab_ = target_tab; + + controller->CreateHoverCard(target_tab); + EXPECT_FALSE(controller->ArePreviewsEnabled()); +} + +class TabHoverCardPreviewsEnabledPrefTest : public TestWithBrowserView { + public: + TabHoverCardPreviewsEnabledPrefTest() { + feature_list_.InitAndDisableFeature(features::kTabHoverCardImages); + } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +TEST_F(TabHoverCardPreviewsEnabledPrefTest, DefaultState) { + EXPECT_FALSE(TabHoverCardController::AreHoverCardImagesEnabled()); +}
diff --git a/chrome/browser/ui/views/user_education/browser_user_education_service.cc b/chrome/browser/ui/views/user_education/browser_user_education_service.cc index b488281..efc2d68 100644 --- a/chrome/browser/ui/views/user_education/browser_user_education_service.cc +++ b/chrome/browser/ui/views/user_education/browser_user_education_service.cc
@@ -483,9 +483,11 @@ // kIPHDownloadToolbarButtonFeature: registry.RegisterFeature( - std::move(FeaturePromoSpecification::CreateForSnoozePromo( + std::move(FeaturePromoSpecification::CreateForToastPromo( feature_engagement::kIPHDownloadToolbarButtonFeature, - kDownloadToolbarButtonElementId, IDS_DOWNLOAD_BUBBLE_PROMO) + kDownloadToolbarButtonElementId, IDS_DOWNLOAD_BUBBLE_PROMO, + IDS_DOWNLOAD_BUBBLE_PROMO_SCREENREADER, + FeaturePromoSpecification::AcceleratorInfo()) .SetBubbleArrow(HelpBubbleArrow::kTopRight) .SetBubbleTitleText(IDS_DOWNLOAD_BUBBLE_PROMO_TITLE)));
diff --git a/chrome/browser/ui/webauthn/sheet_models_unittest.cc b/chrome/browser/ui/webauthn/sheet_models_unittest.cc index ad2af4f..b80b48d 100644 --- a/chrome/browser/ui/webauthn/sheet_models_unittest.cc +++ b/chrome/browser/ui/webauthn/sheet_models_unittest.cc
@@ -68,10 +68,10 @@ MechanismVisibility::kVisible); std::vector<Mechanism> mechanisms; mechanisms.emplace_back(Mechanism::Phone("phone"), u"phone", u"ph", - kPasskeyAoaIcon, base::DoNothing(), false); + kPasskeyAoaIcon, base::DoNothing()); mechanisms.emplace_back( Mechanism::Transport(AuthenticatorTransport::kUsbHumanInterfaceDevice), - u"security key", u"usb", kPasskeyAoaIcon, base::DoNothing(), false); + u"security key", u"usb", kPasskeyAoaIcon, base::DoNothing()); EXPECT_CALL(dialog_model, mechanisms) .WillOnce(testing::Return(base::make_span(mechanisms))); EXPECT_TRUE(sheet_model.IsOtherMechanismButtonVisible());
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload.mojom b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload.mojom index 25ad063..e584c3f5 100644 --- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload.mojom +++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload.mojom
@@ -24,6 +24,9 @@ kMoveConfirmationOneDrive, // Confirm that the user wants to move the file to Google Drive. kMoveConfirmationGoogleDrive, + + // A separate dialog when we're only connecting OneDrive by itself. + kConnectToOneDrive, }; // Operation used to upload the source file.
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc index 8eb87efc..e8aeeb9 100644 --- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc +++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.cc
@@ -1187,6 +1187,9 @@ const int kDialogHeightForMoveConfirmationWithCheckbox = 500; const int kDialogHeightForMoveConfirmationWithoutCheckbox = 448; + +const int kDialogWidthForConnectToOneDrive = 512; +const int kDialogHeightForConnectToOneDrive = 556; } // namespace void CloudUploadDialog::GetDialogSize(gfx::Size* size) const { @@ -1213,7 +1216,36 @@ } return; } + case mojom::DialogPage::kConnectToOneDrive: { + size->set_width(kDialogWidthForConnectToOneDrive); + size->set_height(kDialogHeightForConnectToOneDrive); + } } } +bool ShowConnectOneDriveDialog(gfx::NativeWindow modal_parent) { + DCHECK(modal_parent); + + // Allow no more than one upload dialog at a time. Only one of either this + // dialog, or CloudOpenTask can be shown at a time because they use the same + // WebUI for dialogs. + if (SystemWebDialogDelegate::HasInstance( + GURL(chrome::kChromeUICloudUploadURL))) { + return false; + } + + mojom::DialogArgsPtr args = mojom::DialogArgs::New(); + args->dialog_page = mojom::DialogPage::kConnectToOneDrive; + + // This CloudUploadDialog pointer is managed by an instance of + // `views::WebDialogView` and deleted in + // `SystemWebDialogDelegate::OnDialogClosed`. + CloudUploadDialog* dialog = new CloudUploadDialog( + std::move(args), base::DoNothing(), mojom::DialogPage::kConnectToOneDrive, + /*office_move_confirmation_shown=*/false); + + dialog->ShowSystemDialog(modal_parent); + return true; +} + } // namespace ash::cloud_upload
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h index e1bf7c8..f485c42 100644 --- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h +++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h
@@ -232,6 +232,12 @@ Profile* profile, const FileSystemURL& android_onedrive_file_url); +// Launches the 'Connect OneDrive' dialog which is triggered from the Services +// menu in Files app. This is a simplified version of setup where we just +// connect to OneDrive. There is no 'done' callback because files app doesn't +// need it. +bool ShowConnectOneDriveDialog(gfx::NativeWindow modal_parent); + // Defines the web dialog used to help users upload Office files to the cloud. class CloudUploadDialog : public SystemWebDialogDelegate { public:
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc index c06c4b19..8f568c0 100644 --- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc +++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.cc
@@ -599,6 +599,54 @@ &default_task)); } +// Helper to launch Files app and return its NativeWindow. +gfx::NativeWindow LaunchFilesAppAndWait(Profile* profile) { + GURL files_swa_url = file_manager::util::GetFileManagerMainPageUrlWithParams( + ui::SelectFileDialog::SELECT_NONE, /*title=*/std::u16string(), + /*current_directory_url=*/{}, + /*selection_url=*/GURL(), + /*target_name=*/{}, /*file_types=*/{}, + /*file_type_index=*/0, + /*search_query=*/{}, + /*show_android_picker_apps=*/false, + /*volume_filter=*/{}); + ash::SystemAppLaunchParams params; + params.url = files_swa_url; + ash::LaunchSystemWebAppAsync(profile, ash::SystemWebAppType::FILE_MANAGER, + params); + Browser* files_app = ui_test_utils::WaitForBrowserToOpen(); + return files_app->window()->GetNativeWindow(); +} + +IN_PROC_BROWSER_TEST_F(FileHandlerDialogBrowserTest, + ShowConnectOneDriveDialog_OpensAndClosesDialog) { + // Watch for the Connect OneDrive dialog URL chrome://cloud-upload. + content::TestNavigationObserver navigation_observer_dialog( + (GURL(chrome::kChromeUICloudUploadURL))); + navigation_observer_dialog.StartWatchingNewWebContents(); + + // Launch the Connect OneDrive dialog. + gfx::NativeWindow modal_parent = LaunchFilesAppAndWait(browser()->profile()); + ASSERT_TRUE(ShowConnectOneDriveDialog(modal_parent)); + + // Wait for the Connect OneDrive dialog to open at chrome://cloud-upload. + navigation_observer_dialog.Wait(); + ASSERT_TRUE(navigation_observer_dialog.last_navigation_succeeded()); + + // Check that we have the right dialog page (Connect OneDrive). + content::WebContents* web_contents = GetWebContentsFromCloudUploadDialog(); + content::EvalJsResult eval_result = content::EvalJs( + web_contents, "!!document.querySelector('connect-onedrive')"); + ASSERT_TRUE(eval_result.ExtractBool()); + + // Click the close button and wait for the dialog to close. + content::WebContentsDestroyedWatcher watcher(web_contents); + EXPECT_TRUE(content::ExecJs(web_contents, + "document.querySelector('connect-onedrive')" + ".$('.cancel-button').click()")); + watcher.Wait(); +} + // Tests that OnDialogComplete() opens the specified fake file task. IN_PROC_BROWSER_TEST_F(FileHandlerDialogBrowserTest, OnDialogCompleteOpensFileTasks) { @@ -693,26 +741,6 @@ apps::AppServiceProxyFactory::GetForProfile(profile())); } - // Launch Files app and return its NativeWindow. - gfx::NativeWindow LaunchFilesAppAndWait() { - GURL files_swa_url = - file_manager::util::GetFileManagerMainPageUrlWithParams( - ui::SelectFileDialog::SELECT_NONE, /*title=*/std::u16string(), - /*current_directory_url=*/{}, - /*selection_url=*/GURL(), - /*target_name=*/{}, /*file_types=*/{}, - /*file_type_index=*/0, - /*search_query=*/{}, - /*show_android_picker_apps=*/false, - /*volume_filter=*/{}); - ash::SystemAppLaunchParams params; - params.url = files_swa_url; - ash::LaunchSystemWebAppAsync(browser()->profile(), - ash::SystemWebAppType::FILE_MANAGER, params); - Browser* files_app = ui_test_utils::WaitForBrowserToOpen(); - return files_app->window()->GetNativeWindow(); - } - protected: // Use a non-managed user in this browser test to ensure // |IsEligibleAndEnabledUploadOfficeToCloud| returns the result of @@ -747,7 +775,7 @@ (GURL(chrome::kChromeUICloudUploadURL))); navigation_observer_dialog.StartWatchingNewWebContents(); - gfx::NativeWindow modal_parent = LaunchFilesAppAndWait(); + gfx::NativeWindow modal_parent = LaunchFilesAppAndWait(browser()->profile()); CloudOpenTask::Execute(profile(), files_, CloudProvider::kOneDrive, modal_parent); @@ -792,7 +820,7 @@ (GURL(chrome::kChromeUICloudUploadURL))); navigation_observer_dialog.StartWatchingNewWebContents(); - gfx::NativeWindow modal_parent = LaunchFilesAppAndWait(); + gfx::NativeWindow modal_parent = LaunchFilesAppAndWait(browser()->profile()); CloudOpenTask::Execute(profile(), files_, CloudProvider::kOneDrive, modal_parent);
diff --git a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_ui.cc b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_ui.cc index ee488206..536f25f 100644 --- a/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_ui.cc +++ b/chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_ui.cc
@@ -12,6 +12,7 @@ #include "chrome/common/webui_url_constants.h" #include "chrome/grit/cloud_upload_resources.h" #include "chrome/grit/cloud_upload_resources_map.h" +#include "chrome/grit/generated_resources.h" #include "chromeos/constants/chromeos_features.h" #include "components/strings/grit/components_strings.h" #include "content/public/browser/web_ui.h" @@ -33,7 +34,13 @@ static constexpr webui::LocalizedString kStrings[] = { {"cancel", IDS_CANCEL}, - }; + {"close", IDS_CLOSE}, + {"connectToOneDriveTitle", IDS_CONNECT_TO_ONEDRIVE_TITLE}, + {"connectToOneDriveBodyText", IDS_CONNECT_TO_ONEDRIVE_BODY_TEXT}, + {"cantConnectOneDrive", IDS_CANT_CONNECT_ONEDRIVE}, + {"connectOneDrive", IDS_CONNECT_ONEDRIVE}, + {"oneDriveConnectedTitle", IDS_ONEDRIVE_CONNECTED_TITLE}, + {"oneDriveConnectedBodyText", IDS_ONEDRIVE_CONNECTED_BODY_TEXT}}; source->AddLocalizedStrings(kStrings); source->AddBoolean("isJellyEnabled", chromeos::features::IsJellyEnabled()); webui::SetupWebUIDataSource(
diff --git a/chrome/browser/ui/webui/ash/login/choobe_screen_handler.cc b/chrome/browser/ui/webui/ash/login/choobe_screen_handler.cc index 0185567ba..f2f6ccc 100644 --- a/chrome/browser/ui/webui/ash/login/choobe_screen_handler.cc +++ b/chrome/browser/ui/webui/ash/login/choobe_screen_handler.cc
@@ -26,6 +26,10 @@ builder->Add("choobeScreenDescription", IDS_OOBE_CHOOBE_DESCRIPTION); builder->Add("choobeScreenSkip", IDS_OOBE_CHOOBE_SKIP_BUTTON); builder->Add("choobeReturnButton", IDS_OOBE_CHOOBE_RETURN_BUTTON); + + // Accessibility Message. + builder->Add("choobeSyncedTile", IDS_OOBE_CHOOBE_TILE_SYNCED); + builder->Add("choobeVisitedTile", IDS_OOBE_CHOOBE_TILE_VISITED); } void ChoobeScreenHandler::Show(const std::vector<ScreenSummary>& screens) { @@ -34,6 +38,10 @@ base::Value::Dict screen_dict; screen_dict.Set("screenID", base::Value(screen.screen_id.name)); screen_dict.Set("title", base::Value(screen.title_id)); + if (screen.subtitle_resource.has_value()) { + screen_dict.Set("subtitle", + base::Value(screen.subtitle_resource.value())); + } screen_dict.Set("icon", base::Value(screen.icon_id)); screen_dict.Set("selected", false); screen_dict.Set("is_revisitable", screen.is_revisitable);
diff --git a/chrome/browser/ui/webui/ash/login/placeholder_screen_handler.cc b/chrome/browser/ui/webui/ash/login/placeholder_screen_handler.cc new file mode 100644 index 0000000..62dc67b3 --- /dev/null +++ b/chrome/browser/ui/webui/ash/login/placeholder_screen_handler.cc
@@ -0,0 +1,25 @@ +// 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 "chrome/browser/ui/webui/ash/login/placeholder_screen_handler.h" + +#include "chrome/browser/ui/webui/ash/login/base_screen_handler.h" +#include "components/login/localized_values_builder.h" + +namespace ash { + +PlaceholderScreenHandler::PlaceholderScreenHandler() + : BaseScreenHandler(kScreenId) {} + +PlaceholderScreenHandler::~PlaceholderScreenHandler() = default; + +// Add localized values that you want to propagate to the JS side here. +void PlaceholderScreenHandler::DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) {} + +void PlaceholderScreenHandler::Show() { + ShowInWebUI(); +} + +} // namespace ash
diff --git a/chrome/browser/ui/webui/ash/login/placeholder_screen_handler.h b/chrome/browser/ui/webui/ash/login/placeholder_screen_handler.h new file mode 100644 index 0000000..b06dbf1 --- /dev/null +++ b/chrome/browser/ui/webui/ash/login/placeholder_screen_handler.h
@@ -0,0 +1,53 @@ +// 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 CHROME_BROWSER_UI_WEBUI_ASH_LOGIN_PLACEHOLDER_SCREEN_HANDLER_H_ +#define CHROME_BROWSER_UI_WEBUI_ASH_LOGIN_PLACEHOLDER_SCREEN_HANDLER_H_ + +#include "base/memory/weak_ptr.h" +#include "chrome/browser/ash/login/oobe_screen.h" +#include "chrome/browser/ui/webui/ash/login/base_screen_handler.h" +#include "components/login/localized_values_builder.h" + +namespace ash { + +class PlaceholderScreen; + +// Interface for dependency injection between PlaceholderScreen and its +// WebUI representation. +class PlaceholderScreenView + : public base::SupportsWeakPtr<PlaceholderScreenView> { + public: + inline constexpr static StaticOobeScreenId kScreenId{"placeholder", + "PlaceholderScreen"}; + + virtual ~PlaceholderScreenView() = default; + + // Shows the contents of the screen. + virtual void Show() = 0; +}; + +class PlaceholderScreenHandler : public BaseScreenHandler, + public PlaceholderScreenView { + public: + using TView = PlaceholderScreenView; + + PlaceholderScreenHandler(); + + PlaceholderScreenHandler(const PlaceholderScreenHandler&) = delete; + PlaceholderScreenHandler& operator=(const PlaceholderScreenHandler&) = delete; + + ~PlaceholderScreenHandler() override; + + // BaseScreenHandler: + void DeclareLocalizedValues( + ::login::LocalizedValuesBuilder* builder) override; + + // PlaceholderScreenView: + void Show() override; +}; + +} // namespace ash + +#endif // CHROME_BROWSER_UI_WEBUI_ASH_LOGIN_PLACEHOLDER_SCREEN_HANDLER_H_
diff --git a/chrome/browser/ui/webui/ash/login/touchpad_scroll_screen_handler.cc b/chrome/browser/ui/webui/ash/login/touchpad_scroll_screen_handler.cc index 5fb9f98..1490b17 100644 --- a/chrome/browser/ui/webui/ash/login/touchpad_scroll_screen_handler.cc +++ b/chrome/browser/ui/webui/ash/login/touchpad_scroll_screen_handler.cc
@@ -32,6 +32,10 @@ IDS_OOBE_TOUCHPAD_SCROLL_AREA_DESC); builder->Add("choobeTouchpadScrollTitle", IDS_OOBE_CHOOBE_TOUCHPAD_SCROLL_TILE_TITLE); + builder->Add("choobeTouchpadScrollSubtitleEnabled", + IDS_OOBE_CHOOBE_TOUCHPAD_SCROLL_SUBTITLE_ENABLED); + builder->Add("choobeTouchpadScrollSubtitleDisabled", + IDS_OOBE_CHOOBE_TOUCHPAD_SCROLL_SUBTITLE_DISABLED); } void TouchpadScrollScreenHandler::SetReverseScrolling(bool value) {
diff --git a/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc b/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc index 7b33a14e..b69822c1 100644 --- a/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc +++ b/chrome/browser/ui/webui/cr_components/history_clusters/history_clusters_util.cc
@@ -40,10 +40,6 @@ prefs->IsManagedPreference(history_clusters::prefs::kVisible)); source->AddBoolean("isHistoryClustersDebug", history_clusters::GetConfig().user_visible_debug); - source->AddBoolean("isHideVisitsEnabled", - history_clusters::GetConfig().hide_visits); - source->AddBoolean("isHideVisitsIconEnabled", - history_clusters::GetConfig().hide_visits_icon); source->AddBoolean( "isHistoryClustersImagesEnabled", history_clusters::GetConfig().images &&
diff --git a/chrome/browser/ui/webui/memory_internals_ui.cc b/chrome/browser/ui/webui/memory_internals_ui.cc index fb7b37f..d407639 100644 --- a/chrome/browser/ui/webui/memory_internals_ui.cc +++ b/chrome/browser/ui/webui/memory_internals_ui.cc
@@ -143,9 +143,6 @@ // Callback for the "saveDump" message. void HandleSaveDump(const base::Value::List& args); - // Callback for the "reportProcess" message. - void HandleReportProcess(const base::Value::List& args); - // Callback for the "startProfiling" message. void HandleStartProfiling(const base::Value::List& args); @@ -194,10 +191,6 @@ base::BindRepeating(&MemoryInternalsDOMHandler::HandleSaveDump, base::Unretained(this))); web_ui()->RegisterMessageCallback( - "reportProcess", - base::BindRepeating(&MemoryInternalsDOMHandler::HandleReportProcess, - base::Unretained(this))); - web_ui()->RegisterMessageCallback( "startProfiling", base::BindRepeating(&MemoryInternalsDOMHandler::HandleStartProfiling, base::Unretained(this))); @@ -273,11 +266,6 @@ #endif } -void MemoryInternalsDOMHandler::HandleReportProcess( - const base::Value::List& args) { - // TODO(etienneb): Delete the use of this method. -} - void MemoryInternalsDOMHandler::HandleStartProfiling( const base::Value::List& args) { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
diff --git a/chrome/browser/ui/webui/policy/policy_ui.cc b/chrome/browser/ui/webui/policy/policy_ui.cc index 7f1930f2..8c5c355 100644 --- a/chrome/browser/ui/webui/policy/policy_ui.cc +++ b/chrome/browser/ui/webui/policy/policy_ui.cc
@@ -15,6 +15,8 @@ #include "chrome/grit/chromium_strings.h" #include "components/grit/policy_resources.h" #include "components/grit/policy_resources_map.h" +#include "components/policy/core/common/policy_pref_names.h" +#include "components/prefs/pref_registry_simple.h" #include "components/strings/grit/components_strings.h" #include "content/public/browser/web_ui.h" #include "services/network/public/mojom/content_security_policy.mojom.h" @@ -174,3 +176,9 @@ } PolicyUI::~PolicyUI() = default; + +// static +void PolicyUI::RegisterProfilePrefs(PrefRegistrySimple* registry) { + registry->RegisterBooleanPref(policy::policy_prefs::kPolicyTestPageEnabled, + true); +}
diff --git a/chrome/browser/ui/webui/policy/policy_ui.h b/chrome/browser/ui/webui/policy/policy_ui.h index fb89e33..aefde9cc 100644 --- a/chrome/browser/ui/webui/policy/policy_ui.h +++ b/chrome/browser/ui/webui/policy/policy_ui.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_H_ #define CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_H_ +#include "components/prefs/pref_registry_simple.h" #include "content/public/browser/web_ui_controller.h" namespace content { @@ -20,6 +21,8 @@ PolicyUI& operator=(const PolicyUI&) = delete; ~PolicyUI() override; + + static void RegisterProfilePrefs(PrefRegistrySimple* registry); }; #endif // CHROME_BROWSER_UI_WEBUI_POLICY_POLICY_UI_H_
diff --git a/chrome/browser/ui/webui/settings/ash/device_section.cc b/chrome/browser/ui/webui/settings/ash/device_section.cc index 2cb8a77c..148d798 100644 --- a/chrome/browser/ui/webui/settings/ash/device_section.cc +++ b/chrome/browser/ui/webui/settings/ash/device_section.cc
@@ -573,6 +573,20 @@ return *tags; } +const std::vector<SearchConcept>& GetAudioPowerSoundsSearchConcepts() { + static const base::NoDestructor<std::vector<SearchConcept>> tags({ + { + IDS_OS_SETTINGS_TAG_CHARGING_SOUNDS, + mojom::kAudioSubpagePath, + mojom::SearchResultIcon::kAudio, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSetting, + {.setting = mojom::Setting::kChargingSounds}, + }, + }); + return *tags; +} + const std::vector<SearchConcept>& GetDisplayArrangementSearchConcepts() { static const base::NoDestructor<std::vector<SearchConcept>> tags({ {IDS_OS_SETTINGS_TAG_DISPLAY_ARRANGEMENT, @@ -988,9 +1002,14 @@ {"audioToggleToUnmuteTooltip", IDS_SETTINGS_AUDIO_TOGGLE_TO_UNMUTE_TOOLTIP}, {"audioVolumeTitle", IDS_SETTINGS_AUDIO_VOLUME_TITLE}, + {"chargingSoundsLabel", + IDS_SETTINGS_AUDIO_DEVICE_SOUNDS_CHARGING_SOUNDS_LABEL}, }; html_source->AddLocalizedStrings(kAudioStrings); + + html_source->AddBoolean("areSystemSoundsEnabled", + ash::features::AreSystemSoundsEnabled()); } void AddDevicePowerStrings(content::WebUIDataSource* html_source) { @@ -1062,6 +1081,12 @@ if (ash::features::IsAudioSettingsPageEnabled()) { updater.AddSearchTags(GetAudioSearchConcepts()); + + // Only when the feature is enabled, the toggle buttons for charging sounds + // and the low battery sound will be shown up. + if (ash::features::AreSystemSoundsEnabled()) { + updater.AddSearchTags(GetAudioPowerSoundsSearchConcepts()); + } } chromeos::PowerManagerClient* power_manager_client = @@ -1340,6 +1365,8 @@ IDS_SETTINGS_AUDIO_TITLE, mojom::Subpage::kAudio, mojom::SearchResultIcon::kAudio, mojom::SearchResultDefaultRank::kMedium, mojom::kAudioSubpagePath); + generator->RegisterNestedSetting(mojom::Setting::kChargingSounds, + mojom::Subpage::kAudio); // Power. generator->RegisterTopLevelSubpage(
diff --git a/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom b/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom index 2001665e6..1f0fb68d 100644 --- a/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom +++ b/chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom
@@ -24,6 +24,9 @@ // Emits a OneDrive unmount request and returns whether the request succeeded. DisconnectFromOneDrive() => (bool success); + + // Opens Files app on OneDrive folder location. + OpenOneDriveFolder() => (bool success); }; // Interface for the OneDrive settings. Implemented in Javascript and
diff --git a/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc b/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc index 1ab3623..6009cc5 100644 --- a/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc +++ b/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.cc
@@ -4,10 +4,12 @@ #include "chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h" +#include "chrome/browser/ash/file_manager/open_util.h" #include "chrome/browser/ash/file_system_provider/mount_path_util.h" #include "chrome/browser/ash/file_system_provider/provided_file_system_info.h" #include "chrome/browser/ash/file_system_provider/provided_file_system_interface.h" #include "chrome/browser/ash/file_system_provider/service.h" +#include "chrome/browser/platform_util.h" #include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog.h" #include "chrome/browser/ui/webui/settings/ash/files_page/mojom/one_drive_handler.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -38,6 +40,13 @@ base::File::Error result) { std::move(callback).Run(result == base::File::Error::FILE_OK); } + +void OnShowItemInFolder( + OneDrivePageHandler::OpenOneDriveFolderCallback callback, + platform_util::OpenOperationResult result) { + std::move(callback).Run(result == + platform_util::OpenOperationResult::OPEN_SUCCEEDED); +} } // namespace OneDrivePageHandler::OneDrivePageHandler( @@ -94,7 +103,7 @@ ConnectToOneDriveCallback callback) { file_system_provider::Service* service = file_system_provider::Service::Get(profile_); - DCHECK(service); + CHECK(service); file_system_provider::ProviderId provider_id = file_system_provider::ProviderId::CreateFromExtensionId( file_manager::file_tasks::GetODFSExtensionId(profile_)); @@ -114,7 +123,7 @@ DisconnectFromOneDriveCallback callback) { file_system_provider::Service* service = file_system_provider::Service::Get(profile_); - DCHECK(service); + CHECK(service); file_system_provider::ProviderId provider_id = file_system_provider::ProviderId::CreateFromExtensionId( file_manager::file_tasks::GetODFSExtensionId(profile_)); @@ -131,6 +140,27 @@ odfs_file_system_infos[0].file_system_id())); } +void OneDrivePageHandler::OpenOneDriveFolder( + OpenOneDriveFolderCallback callback) { + file_system_provider::Service* service = + file_system_provider::Service::Get(profile_); + CHECK(service); + file_system_provider::ProviderId provider_id = + file_system_provider::ProviderId::CreateFromExtensionId( + file_manager::file_tasks::GetODFSExtensionId(profile_)); + std::vector<file_system_provider::ProvidedFileSystemInfo> + odfs_file_system_infos = + service->GetProvidedFileSystemInfoList(provider_id); + if (odfs_file_system_infos.size() == 0) { + // ODFS is not mounted. + std::move(callback).Run(false); + return; + } + file_manager::util::ShowItemInFolder( + profile_, odfs_file_system_infos[0].mount_path(), + base::BindOnce(&OnShowItemInFolder, std::move(callback))); +} + void OneDrivePageHandler::OnProvidedFileSystemMount( const ash::file_system_provider::ProvidedFileSystemInfo& file_system_info, ash::file_system_provider::MountContext context,
diff --git a/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h b/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h index 56384ed..371a39e 100644 --- a/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h +++ b/chrome/browser/ui/webui/settings/ash/files_page/one_drive_page_handler.h
@@ -37,6 +37,7 @@ void GetUserEmailAddress(GetUserEmailAddressCallback callback) override; void ConnectToOneDrive(ConnectToOneDriveCallback callback) override; void DisconnectFromOneDrive(DisconnectFromOneDriveCallback callback) override; + void OpenOneDriveFolder(OpenOneDriveFolderCallback callback) override; // ash::file_system_provider::Observer overrides. void OnProvidedFileSystemMount(
diff --git a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc index 9f070664..d91e57d 100644 --- a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc +++ b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.cc
@@ -69,6 +69,14 @@ receiver_.Bind(std::move(receiver)); } +void InputDeviceSettingsProvider::RestoreDefaultKeyboardModifierRemappings( + uint32_t device_id) { + DCHECK(features::IsInputDeviceSettingsSplitEnabled()); + DCHECK(InputDeviceSettingsController::Get()); + InputDeviceSettingsController::Get() + ->RestoreDefaultKeyboardModifierRemappings(device_id); +} + void InputDeviceSettingsProvider::SetKeyboardSettings( uint32_t device_id, ::ash::mojom::KeyboardSettingsPtr settings) {
diff --git a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h index 8e97fe3..cf121a8 100644 --- a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h +++ b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.h
@@ -38,6 +38,7 @@ override; void ObserveMouseSettings( mojo::PendingRemote<mojom::MouseSettingsObserver> observer) override; + void RestoreDefaultKeyboardModifierRemappings(uint32_t device_id) override; void SetKeyboardSettings(uint32_t device_id, ::ash::mojom::KeyboardSettingsPtr settings) override; void SetPointingStickSettings(
diff --git a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom index f75ae9fd..4aa3c00 100644 --- a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom +++ b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider.mojom
@@ -63,6 +63,8 @@ // The observer which is registered is immediately informed // of the current state via its ObserveMouseSettings function. ObserveMouseSettings(pending_remote<MouseSettingsObserver> observer); + // Restore the keyboard modifier remappings to default base on its id. + RestoreDefaultKeyboardModifierRemappings(uint32 device_id); // Sets the keyboard settings based on its id. SetKeyboardSettings(uint32 device_id, ash.mojom.KeyboardSettings settings); // Sets the point stick settings based on its id.
diff --git a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc index 4f0d0a7..02c9db0 100644 --- a/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc +++ b/chrome/browser/ui/webui/settings/ash/input_device_settings/input_device_settings_provider_unittest.cc
@@ -244,6 +244,9 @@ const ::ash::mojom::MousePolicies& GetMousePolicies() override { return *mouse_policies_; } + void RestoreDefaultKeyboardModifierRemappings(DeviceId id) override { + ++num_times_restore_default_keyboard_modifier_remappings_called_; + } void SetKeyboardSettings( DeviceId id, ::ash::mojom::KeyboardSettingsPtr settings) override { @@ -339,6 +342,9 @@ pointing_sticks_.erase(iter); observer_->OnPointingStickDisconnected(*temp_pointing_stick); } + int num_times_restore_default_keyboard_modifier_remappings_called() { + return num_times_restore_default_keyboard_modifier_remappings_called_; + } int num_times_set_keyboard_settings_called() { return num_times_set_keyboard_settings_called_; } @@ -363,6 +369,7 @@ ::ash::mojom::MousePolicies::New(); raw_ptr<InputDeviceSettingsController::Observer> observer_ = nullptr; + int num_times_restore_default_keyboard_modifier_remappings_called_ = 0; int num_times_set_keyboard_settings_called_ = 0; int num_times_set_pointing_stick_settings_called_ = 0; int num_times_set_mouse_settings_called_ = 0; @@ -411,6 +418,25 @@ EXPECT_EQ(2, controller_->num_times_set_keyboard_settings_called()); } +TEST_F(InputDeviceSettingsProviderTest, + TestRestoreDefaultKeyboardModifierRemappings) { + controller_->AddKeyboard(kKeyboard1.Clone()); + provider_->RestoreDefaultKeyboardModifierRemappings(kKeyboard1.id); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + 1, controller_ + ->num_times_restore_default_keyboard_modifier_remappings_called()); + + controller_->AddKeyboard(kKeyboard2.Clone()); + provider_->RestoreDefaultKeyboardModifierRemappings(kKeyboard2.id); + + base::RunLoop().RunUntilIdle(); + EXPECT_EQ( + 2, controller_ + ->num_times_restore_default_keyboard_modifier_remappings_called()); +} + TEST_F(InputDeviceSettingsProviderTest, TestSetPointingStickSettings) { controller_->AddPointingStick(kPointingStick1.Clone()); provider_->SetPointingStickSettings(kPointingStick1.id,
diff --git a/chrome/browser/ui/webui/settings/ash/privacy_section.cc b/chrome/browser/ui/webui/settings/ash/privacy_section.cc index 37d96e8..57aea46 100644 --- a/chrome/browser/ui/webui/settings/ash/privacy_section.cc +++ b/chrome/browser/ui/webui/settings/ash/privacy_section.cc
@@ -431,7 +431,7 @@ html_source->AddBoolean("showPrivacyHubFuturePage", ash::features::IsCrosPrivacyHubV2Enabled()); html_source->AddBoolean("showSpeakOnMuteDetectionPage", - ash::features::IsSpeakOnMuteEnabled()); + ash::features::IsVideoConferenceEnabled()); html_source->AddString( "smartPrivacyDesc",
diff --git a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom index baa854f..e2428e43 100644 --- a/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom +++ b/chrome/browser/ui/webui/settings/chromeos/constants/setting.mojom
@@ -144,6 +144,7 @@ kAdaptiveCharging = 440, kKeyboardBlockMetaFkeyRewrites = 441, kKeyboardRemapKeys = 442, + kChargingSounds = 443, // Personalization section. kOpenWallpaper = 500,
diff --git a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc index 308ef5e3..c020dcd 100644 --- a/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc +++ b/chrome/browser/ui/webui/settings/settings_localized_strings_provider.cc
@@ -3293,6 +3293,10 @@ {"storageAccessDescription", IDS_SETTINGS_STORAGE_ACCESS_DESCRIPTION}, {"storageAccessAllowed", IDS_SETTINGS_STORAGE_ACCESS_ALLOWED}, {"storageAccessBlocked", IDS_SETTINGS_STORAGE_ACCESS_BLOCKED}, + {"storageAccessAllowedExceptions", + IDS_SETTINGS_STORAGE_ACCESS_ALLOWED_EXCEPTIONS}, + {"storageAccessBlockedExceptions", + IDS_SETTINGS_STORAGE_ACCESS_BLOCKED_EXCEPTIONS}, }; html_source->AddLocalizedStrings(kLocalizedStrings); }
diff --git a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc index 49a01ff5..c9c505a 100644 --- a/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc +++ b/chrome/browser/ui/webui/side_panel/companion/companion_page_handler.cc
@@ -58,6 +58,11 @@ CompanionPageHandler::~CompanionPageHandler() { consent_helper_->RemoveObserver(this); + if (web_contents() && !web_contents()->IsBeingDestroyed()) { + auto* tab_helper = + companion::CompanionTabHelper::FromWebContents(web_contents()); + tab_helper->OnCompanionSidePanelClosed(); + } } void CompanionPageHandler::OnUrlKeyedDataCollectionConsentStateChanged(
diff --git a/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc b/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc index 6e9ce498..cedc0623 100644 --- a/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc +++ b/chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.cc
@@ -5,12 +5,14 @@ #include "chrome/browser/ui/webui/webui_gallery/webui_gallery_ui.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/webui/favicon_source.h" #include "chrome/browser/ui/webui/webui_util.h" #include "chrome/common/webui_url_constants.h" #include "chrome/grit/side_panel_shared_resources.h" #include "chrome/grit/side_panel_shared_resources_map.h" #include "chrome/grit/webui_gallery_resources.h" #include "chrome/grit/webui_gallery_resources_map.h" +#include "components/favicon_base/favicon_url_parser.h" #include "content/public/browser/web_ui_data_source.h" #include "services/network/public/mojom/content_security_policy.mojom.h" #include "ui/base/ui_base_features.h" @@ -43,6 +45,10 @@ // as well. source->AddResourcePaths(base::make_span(kSidePanelSharedResources, kSidePanelSharedResourcesSize)); + + content::URLDataSource::Add( + profile, std::make_unique<FaviconSource>( + profile, chrome::FaviconUrlFormat::kFavicon2)); } } // namespace
diff --git a/chrome/browser/ui/window_sizer/window_sizer.cc b/chrome/browser/ui/window_sizer/window_sizer.cc index 3d41a3b..94fff050 100644 --- a/chrome/browser/ui/window_sizer/window_sizer.cc +++ b/chrome/browser/ui/window_sizer/window_sizer.cc
@@ -136,13 +136,25 @@ if (window) { #if BUILDFLAG(IS_CHROMEOS) - if (window->IsVisible()) + if (window->IsVisible()) { *bounds = window->GetRestoredBounds(); + } #else *bounds = window->GetRestoredBounds(); #endif - if (*show_state == ui::SHOW_STATE_DEFAULT && window->IsMaximized()) + + // On Mac GetRestoredBounds already returns the maximized bounds for + // maximized windows. Additionally creating a window with a maximized + // show state results in an invisible window if the window is a PWA + // (i.e. out-of-process remote cocoa) window (https://crbug.com/1441966). + // Never using SHOW_STATE_MAXIMIZED on Mac is also consistent with + // NativeWidgetMac::Show, which does not support SHOW_STATE_MAXIMIZED + // either. +#if !BUILDFLAG(IS_MAC) + if (*show_state == ui::SHOW_STATE_DEFAULT && window->IsMaximized()) { *show_state = ui::SHOW_STATE_MAXIMIZED; + } +#endif return true; }
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 930be12..0e0fe38a 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -397,14 +397,7 @@ "//components/policy/core/browser", "//components/pref_registry", "//components/resources:components_resources_grit", - "//components/services/app_service/public/cpp:app_file_handling", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:app_url_handling", - "//components/services/app_service/public/cpp:preferred_apps", - "//components/services/app_service/public/cpp:protocol_handling", - "//components/services/app_service/public/cpp:run_on_os_login", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//components/services/storage:lock_manager", "//components/site_engagement/content", "//components/site_engagement/core/mojom:mojo_bindings", @@ -585,12 +578,7 @@ "//chrome/browser/ui", "//components/crx_file:crx_file", "//components/keyed_service/content", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:app_url_handling", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:protocol_handling", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//components/sync:test_support", "//components/sync_preferences:test_support", "//components/web_package/test_support",
diff --git a/chrome/browser/web_applications/adjustments/BUILD.gn b/chrome/browser/web_applications/adjustments/BUILD.gn index 13b0535..b32b056a 100644 --- a/chrome/browser/web_applications/adjustments/BUILD.gn +++ b/chrome/browser/web_applications/adjustments/BUILD.gn
@@ -20,9 +20,7 @@ "//chrome/browser/web_applications", "//chrome/common", "//components/keyed_service/content", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", ] if (is_chromeos_ash) {
diff --git a/chrome/browser/web_applications/app_service/BUILD.gn b/chrome/browser/web_applications/app_service/BUILD.gn index 95e6583..9b71190 100644 --- a/chrome/browser/web_applications/app_service/BUILD.gn +++ b/chrome/browser/web_applications/app_service/BUILD.gn
@@ -32,12 +32,7 @@ "//chrome/browser/web_applications", "//chrome/common", "//components/content_settings/core/browser", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:run_on_os_login", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//components/sessions", "//components/webapps/browser", "//url", @@ -116,12 +111,7 @@ "//build:chromeos_buildflags", "//chrome/browser/apps/app_service", "//chromeos/crosapi/mojom", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:preferred_app", - "//components/services/app_service/public/cpp:preferred_apps", + "//components/services/app_service", "//mojo/public/cpp/bindings", ] }
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsing_data_browsertest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsing_data_browsertest.cc index c6520991..bb21c41 100644 --- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsing_data_browsertest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_browsing_data_browsertest.cc
@@ -79,8 +79,9 @@ const controlledframe = document.createElement('controlledframe'); controlledframe.setAttribute('src', $1); controlledframe.setAttribute('partition', $2); - await new Promise((resolve) => { + await new Promise((resolve, reject) => { controlledframe.addEventListener('loadcommit', resolve); + controlledframe.addEventListener('loadabort', reject); document.body.appendChild(controlledframe); }); })(); @@ -108,7 +109,7 @@ EXPECT_THAT(GetIwaUsage(url_info), IsApproximately(1000)); // Create a persisted <controlledframe>, add some usage to it. - EXPECT_TRUE(CreateControlledFrame(web_contents, + ASSERT_TRUE(CreateControlledFrame(web_contents, dev_server()->GetURL("/empty_title.html"), "persist:partition_name")); ASSERT_EQ(1UL, web_contents->GetInnerWebContents().size()); @@ -116,7 +117,7 @@ EXPECT_THAT(GetIwaUsage(url_info), IsApproximately(2000)); // Create another persisted <controlledframe> with a different partition name. - EXPECT_TRUE(CreateControlledFrame(web_contents, + ASSERT_TRUE(CreateControlledFrame(web_contents, dev_server()->GetURL("/empty_title.html"), "persist:partition_name_2")); ASSERT_EQ(2UL, web_contents->GetInnerWebContents().size()); @@ -125,7 +126,7 @@ EXPECT_THAT(GetIwaUsage(url_info), IsApproximately(3000)); // Create an in-memory <controlledframe> that won't count towards IWA usage. - EXPECT_TRUE(CreateControlledFrame( + ASSERT_TRUE(CreateControlledFrame( web_contents, dev_server()->GetURL("/empty_title.html"), "unpersisted")); ASSERT_EQ(3UL, web_contents->GetInnerWebContents().size()); AddUsageIfMissing(web_contents->GetInnerWebContents()[0]);
diff --git a/chrome/browser/web_applications/ml_promotion_browsertest.cc b/chrome/browser/web_applications/ml_promotion_browsertest.cc index 72d81158..2ed6aae 100644 --- a/chrome/browser/web_applications/ml_promotion_browsertest.cc +++ b/chrome/browser/web_applications/ml_promotion_browsertest.cc
@@ -69,7 +69,8 @@ } private: - void OnRegistrationCompleted(const GURL& pattern) override { + void OnRegistrationStored(int64_t registration_id, + const GURL& pattern) override { if (content::ServiceWorkerContext::ScopeMatches(pattern, site_url_)) { service_worker_reg_complete_ = true; run_loop_.Quit(); @@ -260,9 +261,16 @@ } // SiteQualityMetrics tests. -// TODO(crbug.com/1450421): Disabled for being flaky. +#if BUILDFLAG(IS_MAC) +// TODO(crbug.com/1450786): Fix the flakiness of the test. +#define MAYBE_SiteQualityMetrics_ServiceWorker_FetchHandler \ + DISABLED_SiteQualityMetrics_ServiceWorker_FetchHandler +#else +#define MAYBE_SiteQualityMetrics_ServiceWorker_FetchHandler \ + SiteQualityMetrics_ServiceWorker_FetchHandler +#endif IN_PROC_BROWSER_TEST_F(MLPromotionBrowsertest, - DISABLED_SiteQualityMetrics_ServiceWorker_FetchHandler) { + MAYBE_SiteQualityMetrics_ServiceWorker_FetchHandler) { NavigateAndAwaitMetricsCollectionPending(GetInstallableAppURL()); AwaitServiceWorkerRegistrationAndPendingDelayedTask(GetInstallableAppURL()); task_runner_->RunPendingTasks(); @@ -272,10 +280,7 @@ EXPECT_TRUE(quality_metrics.has_service_worker); EXPECT_TRUE(quality_metrics.has_fetch_handler); - - // TODO(b/284157768): The quota service does not accurately collect service - // worker script data, uncomment once that is fixed. - // EXPECT_GT(quality_metrics.service_worker_script_size, 0); + EXPECT_GT(quality_metrics.service_worker_script_size, 0); } IN_PROC_BROWSER_TEST_F(MLPromotionBrowsertest, @@ -290,10 +295,17 @@ EXPECT_EQ(quality_metrics.service_worker_script_size, 0); } -// TODO(crbug.com/1450421): Disabled for being flaky. +#if BUILDFLAG(IS_MAC) +// TODO(crbug.com/1450786): Fix the flakiness of the test. +#define MAYBE_SiteQualityMetrics_ServiceWorker_EmptyFetchHandler \ + DISABLED_SiteQualityMetrics_ServiceWorker_EmptyFetchHandler +#else +#define MAYBE_SiteQualityMetrics_ServiceWorker_EmptyFetchHandler \ + SiteQualityMetrics_ServiceWorker_EmptyFetchHandler +#endif IN_PROC_BROWSER_TEST_F( MLPromotionBrowsertest, - DISABLED_SiteQualityMetrics_ServiceWorker_EmptyFetchHandler) { + MAYBE_SiteQualityMetrics_ServiceWorker_EmptyFetchHandler) { NavigateAndAwaitMetricsCollectionPending(GetUrlWithSWEmptyFetchHandler()); AwaitServiceWorkerRegistrationAndPendingDelayedTask( GetUrlWithSWEmptyFetchHandler()); @@ -307,10 +319,16 @@ EXPECT_TRUE(quality_metrics.has_fetch_handler); } -// TODO(crbug.com/1450421): Disabled for being flaky. -IN_PROC_BROWSER_TEST_F( - MLPromotionBrowsertest, - DISABLED_SiteQualityMetrics_ServiceWorker_NoFetchHandler) { +#if BUILDFLAG(IS_MAC) +// TODO(crbug.com/1450786): Fix the flakiness of the test. +#define MAYBE_SiteQualityMetrics_ServiceWorker_NoFetchHandler \ + DISABLED_SiteQualityMetrics_ServiceWorker_NoFetchHandler +#else +#define MAYBE_SiteQualityMetrics_ServiceWorker_NoFetchHandler \ + SiteQualityMetrics_ServiceWorker_NoFetchHandler +#endif +IN_PROC_BROWSER_TEST_F(MLPromotionBrowsertest, + MAYBE_SiteQualityMetrics_ServiceWorker_NoFetchHandler) { NavigateAndAwaitMetricsCollectionPending(GetUrlWithSwNoFetchHandler()); AwaitServiceWorkerRegistrationAndPendingDelayedTask( GetUrlWithSwNoFetchHandler());
diff --git a/chrome/browser/web_applications/test/web_app_test_utils.h b/chrome/browser/web_applications/test/web_app_test_utils.h index 91ff530e..4fd5e21c 100644 --- a/chrome/browser/web_applications/test/web_app_test_utils.h +++ b/chrome/browser/web_applications/test/web_app_test_utils.h
@@ -65,7 +65,7 @@ // Do not use this for installation! Instead, use the utilities in // web_app_install_test_util.h. struct CreateRandomWebAppParams { - const GURL& base_url = GURL("https://example.com/path"); + GURL base_url{"https://example.com/path"}; uint32_t seed = 0; bool non_zero = false; bool allow_system_source = true;
diff --git a/chrome/browser/web_applications/web_app_prefs_utils.cc b/chrome/browser/web_applications/web_app_prefs_utils.cc index e2150bb..af41228 100644 --- a/chrome/browser/web_applications/web_app_prefs_utils.cc +++ b/chrome/browser/web_applications/web_app_prefs_utils.cc
@@ -78,15 +78,28 @@ // "web_app_ids": { // "<app_id_1>": { // "was_external_app_uninstalled_by_user": true, -// A double representing the number of seconds since epoch, in local time. -// Convert from/to using base::Time::FromDoubleT() and -// base::Time::ToDoubleT(). // "IPH_num_of_consecutive_ignore": 2, // A string-flavored base::value representing the int64_t number of // microseconds since the Windows epoch, using base::TimeToValue(). // "IPH_last_ignore_time": "13249617864945580", +// A string-flavored base::value representing the int64_t number of +// microseconds since the Windows epoch, using base::TimeToValue(). +// "ML_last_time_install_ignored": "13249617864945580", +// A string-flavored base::value representing the int64_t number of +// microseconds since the Windows epoch, using base::TimeToValue(). +// "ML_last_time_install_dismissed": "13249617864945580", +// "ML_num_of_consecutive_not_accepted": 2, // }, // }, +// "app_agnostic_ml_state": { +// A string-flavored base::value representing the int64_t number of +// microseconds since the Windows epoch, using base::TimeToValue(). +// "ML_last_time_install_ignored": "13249617864945580", +// A string-flavored base::value representing the int64_t number of +// microseconds since the Windows epoch, using base::TimeToValue(). +// "ML_last_time_install_dismissed": "13249617864945580", +// "ML_num_of_consecutive_not_accepted": 2, +// }, // "app_agnostic_iph_state": { // "IPH_num_of_consecutive_ignore": 3, // A string-flavored base::Value representing int64_t number of microseconds @@ -109,6 +122,7 @@ user_prefs::PrefRegistrySyncable* registry) { registry->RegisterDictionaryPref(::prefs::kWebAppsPreferences); registry->RegisterDictionaryPref(::prefs::kWebAppsAppAgnosticIphState); + registry->RegisterDictionaryPref(::prefs::kWebAppsAppAgnosticMlState); } bool GetBoolWebAppPref(const PrefService* pref_service, @@ -288,4 +302,127 @@ return true; } +const char kLastTimeMlInstallIgnored[] = "ML_last_time_install_ignored"; +const char kLastTimeMlInstallDismissed[] = "ML_last_time_install_dismissed"; +const char kConsecutiveMlInstallNotAcceptedCount[] = + "ML_num_of_consecutive_not_accepted"; + +void RecordMlInstallIgnored(PrefService* pref_service, + const AppId& app_id, + base::Time time) { + CHECK(pref_service); + + absl::optional<int> ignored_count = GetIntWebAppPref( + pref_service, app_id, kConsecutiveMlInstallNotAcceptedCount); + int new_count = base::saturated_cast<int>(1 + ignored_count.value_or(0)); + + UpdateIntWebAppPref(pref_service, app_id, + kConsecutiveMlInstallNotAcceptedCount, new_count); + UpdateTimeWebAppPref(pref_service, app_id, kLastTimeMlInstallIgnored, time); + + ScopedDictPrefUpdate update(pref_service, prefs::kWebAppsAppAgnosticMlState); + int global_count = + update->FindInt(kConsecutiveMlInstallNotAcceptedCount).value_or(0); + update->Set(kConsecutiveMlInstallNotAcceptedCount, + base::saturated_cast<int>(global_count + 1)); + update->Set(kLastTimeMlInstallIgnored, base::TimeToValue(time)); +} +void RecordMlInstallDismissed(PrefService* pref_service, + const AppId& app_id, + base::Time time) { + CHECK(pref_service); + + absl::optional<int> ignored_count = + GetIntWebAppPref(pref_service, app_id, kLastTimeMlInstallDismissed); + int new_count = base::saturated_cast<int>(1 + ignored_count.value_or(0)); + + UpdateIntWebAppPref(pref_service, app_id, kLastTimeMlInstallDismissed, + new_count); + UpdateTimeWebAppPref(pref_service, app_id, kLastTimeMlInstallIgnored, time); + + ScopedDictPrefUpdate update(pref_service, prefs::kWebAppsAppAgnosticMlState); + int global_count = update->FindInt(kLastTimeMlInstallDismissed).value_or(0); + update->Set(kConsecutiveMlInstallNotAcceptedCount, + base::saturated_cast<int>(global_count + 1)); + update->Set(kLastTimeMlInstallDismissed, base::TimeToValue(time)); +} + +void RecordMlInstallAccepted(PrefService* pref_service, + const AppId& app_id, + base::Time time) { + // The ignored count is meant to track consecutive occurrences of the user + // ignoring ML install, to help determine when ML install should be muted. + // Therefore resetting ignored count on successful install. + UpdateIntWebAppPref(pref_service, app_id, + kConsecutiveMlInstallNotAcceptedCount, 0); + + ScopedDictPrefUpdate update(pref_service, prefs::kWebAppsAppAgnosticMlState); + update->Set(kConsecutiveMlInstallNotAcceptedCount, 0); +} + +bool IsMlPromotionBlockedByHistoryGuardrail(PrefService* pref_service, + const AppId& app_id) { + constexpr int kMuteMlInstallAfterConsecutiveAppSpecificIgnores = 3; + constexpr int kMuteMlInstallAfterIgnoreForDays = 2; + constexpr int kMuteMlInstallAfterDismissForDays = 14; + + constexpr int kMuteMlInstallAfterConsecutiveAppAgnosticIgnores = 5; + constexpr int kMuteMlInstallAfterAnyIgnoreForDays = 1; + constexpr int kMuteMlInstallAfterAnyDismissForDays = 7; + + // Do not show Ml install if the user ignored the last N+ promos for this app. + int app_ignored_count = + GetIntWebAppPref(pref_service, app_id, + kConsecutiveMlInstallNotAcceptedCount) + .value_or(0); + if (app_ignored_count >= kMuteMlInstallAfterConsecutiveAppSpecificIgnores) { + return true; + } + // Do not show Ml install if the user ignored a promo for this app within N + // days. + auto app_last_ignore = + GetTimeWebAppPref(pref_service, app_id, kLastTimeMlInstallIgnored); + if (TimeOccurredWithinDays(app_last_ignore, + kMuteMlInstallAfterIgnoreForDays)) { + return true; + } + // Do not show Ml install if the user dismissed a promo for this app within N + // days. + auto app_last_dismissed = + GetTimeWebAppPref(pref_service, app_id, kLastTimeMlInstallDismissed); + if (TimeOccurredWithinDays(app_last_dismissed, + kMuteMlInstallAfterDismissForDays)) { + return true; + } + + const base::Value::Dict& dict = + pref_service->GetDict(prefs::kWebAppsAppAgnosticMlState); + + // Do not show Ml install if the user ignored the last N+ promos for any app. + int global_ignored_count = + dict.FindInt(kConsecutiveMlInstallNotAcceptedCount).value_or(0); + if (global_ignored_count >= + kMuteMlInstallAfterConsecutiveAppAgnosticIgnores) { + return true; + } + + // Do not show Ml install if the user ignored a promo for any app within N + // days. + auto global_last_ignore = + base::ValueToTime(dict.Find(kConsecutiveMlInstallNotAcceptedCount)); + if (TimeOccurredWithinDays(global_last_ignore, + kMuteMlInstallAfterAnyIgnoreForDays)) { + return true; + } + // Do not show Ml install if the user ignored a promo for any app within N + // days. + auto global_last_dismiss = + base::ValueToTime(dict.Find(kLastTimeMlInstallDismissed)); + if (TimeOccurredWithinDays(global_last_dismiss, + kMuteMlInstallAfterAnyDismissForDays)) { + return true; + } + return false; +} + } // namespace web_app
diff --git a/chrome/browser/web_applications/web_app_prefs_utils.h b/chrome/browser/web_applications/web_app_prefs_utils.h index d14f803..1a273c03 100644 --- a/chrome/browser/web_applications/web_app_prefs_utils.h +++ b/chrome/browser/web_applications/web_app_prefs_utils.h
@@ -87,6 +87,26 @@ // previous interactions with this promo. bool ShouldShowIph(PrefService* pref_service, const AppId& app_id); +extern const char kLastTimeMlInstallIgnored[]; +extern const char kLastTimeMlInstallDismissed[]; +extern const char kConsecutiveMlInstallNotAcceptedCount[]; + +// The user has ignored the installation dialog and it went away due to +// another interaction (e.g. the tab was changed, page navigated, etc). +void RecordMlInstallIgnored(PrefService* pref_service, + const AppId& app_id, + base::Time time); +// The user has taken active action on the dialog to make it go away. +void RecordMlInstallDismissed(PrefService* pref_service, + const AppId& app_id, + base::Time time); +void RecordMlInstallAccepted(PrefService* pref_service, + const AppId& app_id, + base::Time time); + +bool IsMlPromotionBlockedByHistoryGuardrail(PrefService* pref_service, + const AppId& app_id); + } // namespace web_app #endif // CHROME_BROWSER_WEB_APPLICATIONS_WEB_APP_PREFS_UTILS_H_
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.cc b/chrome/browser/webauthn/authenticator_request_dialog_model.cc index 6d3f6d8..5c1d6c3 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.cc
@@ -166,14 +166,12 @@ std::u16string in_name, std::u16string in_short_name, const gfx::VectorIcon& in_icon, - base::RepeatingClosure in_callback, - bool is_priority) + base::RepeatingClosure in_callback) : type(std::move(in_type)), name(std::move(in_name)), short_name(std::move(in_short_name)), icon(in_icon), - callback(std::move(in_callback)), - priority(is_priority) {} + callback(std::move(in_callback)) {} AuthenticatorRequestDialogModel::Mechanism::~Mechanism() = default; AuthenticatorRequestDialogModel::Mechanism::Mechanism(Mechanism&&) = default; @@ -224,19 +222,7 @@ use_conditional_mediation_ = use_conditional_mediation; PopulateMechanisms(); - if (base::FeatureList::IsEnabled(device::kWebAuthnNewPrioritiesImpl)) { - priority_mechanism_index_ = IndexOfPriorityMechanism(); - } else { - priority_mechanism_index_.reset(); - if (mechanisms_.size() == 1) { - priority_mechanism_index_ = 0; - } else if (mechanisms_.size() > 1) { - const auto it = base::ranges::find_if(mechanisms_, &Mechanism::priority); - if (it != mechanisms_.end()) { - priority_mechanism_index_ = std::distance(mechanisms_.begin(), it); - } - } - } + priority_mechanism_index_ = IndexOfPriorityMechanism(); if (use_conditional_mediation_) { // This is a conditional mediation request. @@ -1124,15 +1110,6 @@ void AuthenticatorRequestDialogModel::PopulateMechanisms() { const bool is_get_assertion = transport_availability_.request_type == device::FidoRequestType::kGetAssertion; - const bool is_passkey_request = - ((is_get_assertion && - (transport_availability_.has_empty_allow_list || - transport_availability_.is_only_hybrid_or_internal)) || - (!is_get_assertion && resident_key_requirement() != - device::ResidentKeyRequirement::kDiscouraged)); - // priority_transport contains the transport that should be activated - // immediately, if this is a getAssertion. - absl::optional<AuthenticatorTransport> priority_transport; std::vector<AuthenticatorTransport> transports_to_list_if_active; if (!use_conditional_mediation_ && @@ -1140,20 +1117,6 @@ AuthenticatorTransport::kInternal)) { // Conditional requests offer platform credentials through the autofill UI. transports_to_list_if_active.push_back(AuthenticatorTransport::kInternal); - bool make_credential_prefer_internal = - !is_get_assertion && kShowCreatePlatformPasskeyStep; - if (base::FeatureList::IsEnabled(device::kWebAuthPasskeysUI)) { - // Do not prefer the internal authenticator for passkeys requests if the - // QR-code first flow is enabled. - make_credential_prefer_internal = - make_credential_prefer_internal && !is_passkey_request; - } - if (transport_availability_.has_platform_authenticator_credential == - device::FidoRequestHandlerBase::RecognizedCredential:: - kHasRecognizedCredential || - make_credential_prefer_internal) { - priority_transport = AuthenticatorTransport::kInternal; - } } transports_to_list_if_active.push_back( AuthenticatorTransport::kUsbHumanInterfaceDevice); @@ -1179,9 +1142,6 @@ if (base::Contains(transport_availability_.available_transports, kCable)) { transports_to_list_if_active.push_back(kCable); - if (!priority_transport) { - priority_transport = kCable; - } // If this is a caBLEv1 or server-link request then offering to "Try // Again" is unfortunate because the server won't send another ping @@ -1200,8 +1160,7 @@ Mechanism::ICloudKeychain(), name, name, kSmartphoneIcon, base::BindRepeating( &AuthenticatorRequestDialogModel::StartICloudKeychain, - base::Unretained(this), mechanisms_.size()), - /*priority=*/false); + base::Unretained(this), mechanisms_.size())); } // The Windows API option comes first so that it gets focus and people can @@ -1214,20 +1173,11 @@ // request, except for: // - conditional UI // - "legacy" caBLE (caBLEv1 and server-link caBLEv2 on a.g.c) - bool is_legacy_cable = - cable_ui_type_ && cable_ui_type_ != CableUIType::CABLE_V2_2ND_FACTOR; - bool win_api_should_be_priority = - !use_conditional_mediation_ && !is_legacy_cable && - (!is_passkey_request || - transport_availability_.has_platform_authenticator_credential == - device::FidoRequestHandlerBase::RecognizedCredential:: - kHasRecognizedCredential); mechanisms_.emplace_back( Mechanism::WindowsAPI(), desc, desc, GetTransportIcon(AuthenticatorTransport::kInternal), base::BindRepeating(&AuthenticatorRequestDialogModel::StartWinNativeApi, - base::Unretained(this), mechanisms_.size()), - !priority_transport.has_value() && win_api_should_be_priority); + base::Unretained(this), mechanisms_.size())); } bool specific_phones_listed = false; @@ -1245,12 +1195,10 @@ std::move(short_name), kSmartphoneIcon, base::BindRepeating(&AuthenticatorRequestDialogModel::ContactPhone, base::Unretained(this), phone_name, - mechanisms_.size()), - /*priority=*/false); + mechanisms_.size())); specific_phones_listed = true; } bool skip_to_phone_confirmation = - base::FeatureList::IsEnabled(device::kWebAuthnPhoneConfirmationSheet) && is_get_assertion && transport_availability_.has_platform_authenticator_credential == device::FidoRequestHandlerBase::RecognizedCredential:: @@ -1263,24 +1211,6 @@ } if (include_add_phone_option) { - // If there's no other priority mechanism, no phones, no platform - // credentials, and this is a passkey request, jump directly to showing a QR - // code. - bool is_priority = false; - if (base::FeatureList::IsEnabled(device::kWebAuthPasskeysUI)) { - // On Windows WebAuthn API < 4, we cannot tell in advance if the platform - // authenticator can fulfill a get assertion request. In that case, don't - // jump to the QR code. - bool platform_authenticator_could_fulfill_get_assertion = - is_get_assertion && !use_conditional_mediation_ && - transport_availability_.has_platform_authenticator_credential != - device::FidoRequestHandlerBase::RecognizedCredential:: - kNoRecognizedCredential; - is_priority = !priority_transport.has_value() && - !base::ranges::any_of(mechanisms_, &Mechanism::priority) && - paired_phone_names().empty() && is_passkey_request && - !platform_authenticator_could_fulfill_get_assertion; - } const std::u16string label = l10n_util::GetStringUTF16( specific_phones_listed ? IDS_WEBAUTHN_PASSKEY_DIFFERENT_PHONE_OR_TABLET_LABEL @@ -1289,8 +1219,7 @@ Mechanism::AddPhone(), label, label, kQrcodeGeneratorIcon, base::BindRepeating( &AuthenticatorRequestDialogModel::StartGuidedFlowForAddPhone, - base::Unretained(this), mechanisms_.size()), - is_priority); + base::Unretained(this), mechanisms_.size())); } for (const auto transport : transports_to_list_if_active) { @@ -1304,12 +1233,8 @@ GetTransportShortDescription(transport), GetTransportIcon(transport), base::BindRepeating( &AuthenticatorRequestDialogModel::StartGuidedFlowForTransport, - base::Unretained(this), transport, mechanisms_.size()), - priority_transport.has_value() && *priority_transport == transport); + base::Unretained(this), transport, mechanisms_.size())); } - - // At most one mechanism has priority. - DCHECK_LE(base::ranges::count_if(mechanisms_, &Mechanism::priority), 1); } absl::optional<size_t> @@ -1372,8 +1297,7 @@ } } - if (base::FeatureList::IsEnabled(device::kWebAuthPasskeysUI) && - is_passkey_request && paired_phone_names().empty() && + if (is_passkey_request && paired_phone_names().empty() && // On Windows WebAuthn API < 4, we cannot tell in advance if the // platform authenticator can fulfill a get assertion request. In that // case, don't jump to the QR code. @@ -1389,35 +1313,25 @@ const bool is_passkey_request = resident_key_requirement() != device::ResidentKeyRequirement::kDiscouraged; - if (base::FeatureList::IsEnabled(device::kWebAuthPasskeysUI)) { - if (is_passkey_request) { - // If attachment=any, then don't jump to suggesting a phone. - // TODO(crbug.com/1426628): makeCredential requests should always have - // `make_credential_attachment` set. Stop being hesitant. - if ((!transport_availability_.make_credential_attachment || - *transport_availability_.make_credential_attachment != - device::AuthenticatorAttachment::kAny) && - paired_phone_names().empty()) { - priority_list.emplace_back(Mechanism::AddPhone()); - } - } else { - // This seems like it might be an error (crbug.com/1426244) as we might - // still want to jump to platform authenticators for passkey requests if - // we don't jump to a phone. - if (kShowCreatePlatformPasskeyStep) { - priority_list.emplace_back( - Mechanism::Transport(AuthenticatorTransport::kInternal)); - } - priority_list.emplace_back(Mechanism::WindowsAPI()); + if (is_passkey_request) { + // If attachment=any, then don't jump to suggesting a phone. + // TODO(crbug.com/1426628): makeCredential requests should always have + // `make_credential_attachment` set. Stop being hesitant. + if ((!transport_availability_.make_credential_attachment || + *transport_availability_.make_credential_attachment != + device::AuthenticatorAttachment::kAny) && + paired_phone_names().empty()) { + priority_list.emplace_back(Mechanism::AddPhone()); } } else { + // This seems like it might be an error (crbug.com/1426244) as we might + // still want to jump to platform authenticators for passkey requests if + // we don't jump to a phone. if (kShowCreatePlatformPasskeyStep) { priority_list.emplace_back( Mechanism::Transport(AuthenticatorTransport::kInternal)); } - if (!is_passkey_request) { - priority_list.emplace_back(Mechanism::WindowsAPI()); - } + priority_list.emplace_back(Mechanism::WindowsAPI()); } }
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model.h b/chrome/browser/webauthn/authenticator_request_dialog_model.h index c9d13dfd..df095ac 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model.h +++ b/chrome/browser/webauthn/authenticator_request_dialog_model.h
@@ -196,8 +196,7 @@ std::u16string name, std::u16string short_name, const gfx::VectorIcon& icon, - base::RepeatingClosure callback, - bool is_priority); + base::RepeatingClosure callback); ~Mechanism(); Mechanism(Mechanism&&); Mechanism(const Mechanism&) = delete; @@ -208,9 +207,6 @@ const std::u16string short_name; const raw_ref<const gfx::VectorIcon> icon; const base::RepeatingClosure callback; - // priority is true if this mechanism should be activated immediately. - // Only a single Mechanism in a list should have priority. - const bool priority; }; // PairedPhone represents a paired caBLEv2 device.
diff --git a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc index 6a73d797..13829d5 100644 --- a/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc +++ b/chrome/browser/webauthn/authenticator_request_dialog_model_unittest.cc
@@ -217,11 +217,6 @@ const auto qr = Step::kCableV2QRCode; const auto pconf = Step::kPhoneConfirmationSheet; - const auto qr1st = base::test::FeatureRef(device::kWebAuthPasskeysUI); - const auto p1st = - base::test::FeatureRef(device::kWebAuthnPhoneConfirmationSheet); - const std::vector<base::test::FeatureRef> kAllFeatures = {qr1st, p1st}; - const struct { int line_num; RequestType request_type; @@ -335,20 +330,18 @@ {p("a"), add, t(usb)}, mss}, - // On Windows, mc with rk=required shows mechanism selection, unless caBLE - // isn't an option. - {L, mc, {cable}, {has_winapi, rk}, {}, {winapi, add}, mss}, + // On Windows, mc with rk=required jumps to the platform UI when caBLE + // isn't an option. The case where caBLE is possible is tested below. {L, mc, {}, {has_winapi, rk}, {}, {winapi}, plat_ui}, - // But for rk=discouraged, always jump to Windows UI. + // For rk=discouraged, always jump to Windows UI. {L, mc, {cable}, {has_winapi}, {}, {winapi, add}, plat_ui}, {L, mc, {}, {has_winapi}, {}, {winapi}, plat_ui}, - // On Windows, ga with empty allow list shows mechanism selection, unless - // caBLE isn't an option. - {L, ga, {cable}, {has_winapi, empty_al}, {}, {winapi, add}, mss}, + // On Windows, ga with an empty allow list goes to the platform UI unless + // caBLE is an option and resident-key is required, which is tested below. {L, ga, {}, {has_winapi, empty_al}, {}, {winapi}, plat_ui}, - // But with a non-empty allow list containing non phone credentials, - // always jump to Windows UI. + // With a non-empty allow list containing non phone credentials, always + // jump to Windows UI. {L, ga, {cable}, {has_winapi}, {}, {winapi, add}, plat_ui}, {L, ga, {}, {has_winapi}, {}, {winapi}, plat_ui}, // Except when the request is legacy cable. @@ -362,14 +355,7 @@ cable_ui}, // QR code first: Make credential should jump to the QR code with RK=true. - {L, - mc, - {usb, internal, cable}, - {rk}, - {}, - {add, t(internal), t(usb)}, - qr, - {qr1st}}, + {L, mc, {usb, internal, cable}, {rk}, {}, {add, t(internal), t(usb)}, qr}, // Unless there is a phone paired already. {L, mc, @@ -377,8 +363,7 @@ {rk}, {"a"}, {p("a"), add, t(internal), t(usb)}, - mss, - {qr1st}}, + mss}, // Or if attachment=any {L, mc, @@ -386,8 +371,7 @@ {rk, att_any}, {}, {add, t(internal), t(usb)}, - mss, - {qr1st}}, + mss}, // But not for any attachment, like platform {L, mc, @@ -395,23 +379,23 @@ {rk, att_xplat}, {}, {add, t(internal), t(usb)}, - qr, - {qr1st}}, + qr}, // If RK=false, go to the default for the platform instead. - {L, - mc, - {usb, internal, cable}, - {}, - {}, - {add, t(internal), t(usb)}, + { + L, + mc, + {usb, internal, cable}, + {}, + {}, + {add, t(internal), t(usb)}, #if BUILDFLAG(IS_MAC) - create_pk, + create_pk, #else - mss, + mss, #endif - {qr1st}}, + }, // Windows should also jump to the QR code first. - {L, mc, {cable}, {rk, has_winapi}, {}, {winapi, add}, qr, {qr1st}}, + {L, mc, {cable}, {rk, has_winapi}, {}, {winapi, add}, qr}, // QR code first: Get assertion should jump to the QR code with empty // allow-list. @@ -421,8 +405,7 @@ {empty_al}, {}, {add, t(internal), t(usb)}, - qr, - {qr1st, p1st}}, + qr}, // And if the allow list only contains phones. {L, ga, @@ -430,8 +413,7 @@ {only_hybrid_or_internal}, {}, {add, t(internal)}, - qr, - {qr1st}}, + qr}, // Unless there is a phone paired already. {L, ga, @@ -439,8 +421,7 @@ {empty_al}, {"a"}, {p("a"), add, t(internal), t(usb)}, - mss, - {qr1st}}, + mss}, // Or a recognized platform credential. {L, ga, @@ -448,8 +429,7 @@ {empty_al, has_plat}, {}, {add, t(internal), t(usb)}, - plat_ui, - {qr1st}}, + plat_ui}, // Ignore the platform credential for conditional ui requests {L, ga, @@ -457,20 +437,12 @@ {c_ui, empty_al, has_plat}, {}, {add, t(usb)}, - qr, - {qr1st}}, + qr}, // If there is an allow-list containing USB, go to transport selection // instead. - {L, - ga, - {usb, internal, cable}, - {}, - {}, - {add, t(internal), t(usb)}, - mss, - {qr1st}}, + {L, ga, {usb, internal, cable}, {}, {}, {add, t(internal), t(usb)}, mss}, // Windows should also jump to the QR code first. - {L, ga, {cable}, {empty_al, has_winapi}, {}, {winapi, add}, qr, {qr1st}}, + {L, ga, {cable}, {empty_al, has_winapi}, {}, {winapi, add}, qr}, // Unless there is a recognized platform credential. {L, ga, @@ -478,8 +450,7 @@ {empty_al, has_winapi, has_plat}, {}, {winapi, add}, - plat_ui, - {qr1st}}, + plat_ui}, // For <=Win 10, we can't tell if there is a credential or not. Show the // mechanism selection screen instead. {L, @@ -488,8 +459,7 @@ {empty_al, has_winapi, maybe_plat}, {}, {winapi, add}, - mss, - {qr1st}}, + mss}, // Phone confirmation sheet: Get assertion should jump to it if there is a // single phone paired. @@ -499,8 +469,7 @@ {only_hybrid_or_internal}, {"a"}, {p("a"), add, t(internal)}, - pconf, - {qr1st, p1st}}, + pconf}, // Even on Windows. {L, ga, @@ -508,8 +477,7 @@ {only_hybrid_or_internal, has_winapi}, {"a"}, {winapi, p("a"), add}, - pconf, - {qr1st, p1st}}, + pconf}, // Unless there is a recognized platform credential. {L, ga, @@ -517,8 +485,7 @@ {only_hybrid_or_internal, has_plat}, {"a"}, {p("a"), add, t(internal)}, - plat_ui, - {qr1st, p1st}}, + plat_ui}, // Or a USB credential. {L, ga, @@ -526,8 +493,7 @@ {}, {"a"}, {p("a"), add, t(internal), t(usb)}, - mss, - {qr1st, p1st}}, + mss}, // Or this is a conditional UI request. {L, ga, @@ -535,8 +501,7 @@ {only_hybrid_or_internal, c_ui}, {"a"}, {p("a"), add}, - mss, - {qr1st, p1st}}, + mss}, // Go to the mechanism selection screen if there are more phones paired. {L, ga, @@ -544,8 +509,7 @@ {only_hybrid_or_internal}, {"a", "b"}, {p("a"), p("b"), add, t(internal)}, - mss, - {qr1st, p1st}}, + mss}, #undef L }; @@ -559,13 +523,6 @@ SCOPED_TRACE(RequestTypeToString(test.request_type)); SCOPED_TRACE(testing::Message() << "At line number: " << test.line_num); - std::vector<base::test::FeatureRef> disabled_features = kAllFeatures; - base::EraseIf(disabled_features, [&test](const auto& feature) { - return base::Contains(test.features, feature); - }); - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures(test.features, disabled_features); - TransportAvailabilityInfo transports_info; transports_info.is_ble_powered = true; transports_info.request_type = test.request_type;
diff --git a/chrome/browser/win/conflicts/inspection_results_cache.cc b/chrome/browser/win/conflicts/inspection_results_cache.cc index 3d6eeb4..3fb614a 100644 --- a/chrome/browser/win/conflicts/inspection_results_cache.cc +++ b/chrome/browser/win/conflicts/inspection_results_cache.cc
@@ -208,9 +208,6 @@ const base::FilePath& file_path, uint32_t min_time_stamp, InspectionResultsCache* inspection_results_cache) { - if (!base::FeatureList::IsEnabled(kInspectionResultsCache)) - return ReadCacheResult::kSuccess; - std::string contents; if (!ReadFileToString(file_path, &contents)) return ReadCacheResult::kFailReadFile; @@ -230,9 +227,6 @@ bool WriteInspectionResultsCache( const base::FilePath& file_path, const InspectionResultsCache& inspection_results_cache) { - if (!base::FeatureList::IsEnabled(kInspectionResultsCache)) - return true; - base::Pickle pickle = SerializeInspectionResultsCache(inspection_results_cache);
diff --git a/chrome/browser/win/conflicts/inspection_results_cache.h b/chrome/browser/win/conflicts/inspection_results_cache.h index f7d59b6c..ddfa570 100644 --- a/chrome/browser/win/conflicts/inspection_results_cache.h +++ b/chrome/browser/win/conflicts/inspection_results_cache.h
@@ -8,7 +8,6 @@ #include <map> #include <utility> -#include "base/feature_list.h" #include "chrome/browser/win/conflicts/module_info.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -41,10 +40,6 @@ kMaxValue = kFailInvalidMD5 }; -BASE_FEATURE(kInspectionResultsCache, - "InspectionResultsCache", - base::FEATURE_ENABLED_BY_DEFAULT); - // The InspectionResultsCache maps ModuleInfoKey to a ModuleInspectionResult. // The uint32_t is a time stamp that keep tracks of when the inspection result // was needed (i.e. It was queried using GetInspectionResultFromCache() or added
diff --git a/chrome/browser/win/conflicts/inspection_results_cache_unittest.cc b/chrome/browser/win/conflicts/inspection_results_cache_unittest.cc index 6a206f0..4a374b4 100644 --- a/chrome/browser/win/conflicts/inspection_results_cache_unittest.cc +++ b/chrome/browser/win/conflicts/inspection_results_cache_unittest.cc
@@ -9,7 +9,6 @@ #include <utility> #include "base/files/scoped_temp_dir.h" -#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "base/time/time.h" #include "testing/gtest/include/gtest/gtest.h" @@ -54,10 +53,7 @@ InspectionResultsCacheTest& operator=(const InspectionResultsCacheTest&) = delete; - void SetUp() override { - ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); - scoped_feature_list_.InitAndEnableFeature(kInspectionResultsCache); - } + void SetUp() override { ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir()); } void RunUntilIdle() { task_environment_.RunUntilIdle(); } @@ -66,8 +62,6 @@ } private: - base::test::ScopedFeatureList scoped_feature_list_; - base::test::TaskEnvironment task_environment_; base::ScopedTempDir scoped_temp_dir_;
diff --git a/chrome/browser/win/conflicts/module_inspector_unittest.cc b/chrome/browser/win/conflicts/module_inspector_unittest.cc index 92a62a26..eb3a45e 100644 --- a/chrome/browser/win/conflicts/module_inspector_unittest.cc +++ b/chrome/browser/win/conflicts/module_inspector_unittest.cc
@@ -193,9 +193,6 @@ } TEST_F(ModuleInspectorTest, InspectionResultsCache) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(kInspectionResultsCache); - base::ScopedTempDir scoped_temp_dir; ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); @@ -226,12 +223,9 @@ ASSERT_EQ(inspected_modules()[0].basename, inspection_result.basename); } -// Tests that when OnModuleDatabaseIdle() notificate is received, the cache is +// Tests that when OnModuleDatabaseIdle() notification is received, the cache is // flushed to disk. TEST_F(ModuleInspectorTest, InspectionResultsCache_OnModuleDatabaseIdle) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(kInspectionResultsCache); - base::ScopedTempDir scoped_temp_dir; ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); @@ -268,9 +262,6 @@ // Tests that when the timer expires before the OnModuleDatabaseIdle() // notification, the cache is flushed to disk. TEST_F(ModuleInspectorTest, InspectionResultsCache_TimerExpired) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(kInspectionResultsCache); - base::ScopedTempDir scoped_temp_dir; ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir()); @@ -328,9 +319,6 @@ // the connection error handler. // Regression test for https://crbug.com/1213241. TEST_F(ModuleInspectorTest, WaitingOnCacheConnectionError) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(kInspectionResultsCache); - base::ScopedTempDir scoped_temp_dir; ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
diff --git a/chrome/build/lacros-arm.pgo.txt b/chrome/build/lacros-arm.pgo.txt index 1a024ffb..52664f7 100644 --- a/chrome/build/lacros-arm.pgo.txt +++ b/chrome/build/lacros-arm.pgo.txt
@@ -1 +1 @@ -chrome-chromeos-arm-generic-main-1685620819-0d03dca17bb095ac73db01f5d50122324abcf6be.profdata +chrome-chromeos-arm-generic-main-1685663915-f43ef28d0df270e31b637313f7e889d2c0bb0185.profdata
diff --git a/chrome/build/lacros-arm64.pgo.txt b/chrome/build/lacros-arm64.pgo.txt index a423206..475a147 100644 --- a/chrome/build/lacros-arm64.pgo.txt +++ b/chrome/build/lacros-arm64.pgo.txt
@@ -1 +1 @@ -chrome-chromeos-arm64-generic-main-1685620819-b3af48096871c98987796531b209703d6dc98893.profdata +chrome-chromeos-arm64-generic-main-1685663915-b3533da63ffd6acebbd33a8baea58a34187eebd1.profdata
diff --git a/chrome/build/lacros64.pgo.txt b/chrome/build/lacros64.pgo.txt index 82a6c759..03f137d 100644 --- a/chrome/build/lacros64.pgo.txt +++ b/chrome/build/lacros64.pgo.txt
@@ -1 +1 @@ -chrome-chromeos-amd64-generic-main-1685620819-f7adbfb15d4124307f646192aa29c71df61daf77.profdata +chrome-chromeos-amd64-generic-main-1685664511-db2646580398de14c51868ca04dc3506fe4a8ec1.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index f2cb3187..8d2e8882 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1685620781-b9e5f3394e49fe2db2d949e1cd072a1c79303831.profdata +chrome-linux-main-1685663915-064c37fc1816bc4555275efe04e48ba6509af68b.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 6589eeb..77d2b043 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1685620781-63a5bcce260de7cd2cadeca2bc94913e8f351c28.profdata +chrome-mac-main-1685663915-8e33d907b423d057db8fdd63008fce34ec32d473.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 94f9706..68e32ba 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1685620781-3975d832ba4791bcd64a8f167687d463dc396de9.profdata +chrome-win32-main-1685663915-c897d968dfdf6b97ee97c610289eff5a054200e6.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index ed3a1d0..22d8dcb9 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1685620781-7f8e11b971ef7d71d9f86f1dcb4d78b4cb799f2a.profdata +chrome-win64-main-1685663915-9ac8b26bb7805d70320281353009a034bfae274c.profdata
diff --git a/chrome/common/media/cdm_registration.cc b/chrome/common/media/cdm_registration.cc index 9de0d996..7b1abfc 100644 --- a/chrome/common/media/cdm_registration.cc +++ b/chrome/common/media/cdm_registration.cc
@@ -48,7 +48,7 @@ #endif // BUILDFLAG(ENABLE_WIDEVINE) #if BUILDFLAG(IS_ANDROID) -#include "media/base/android/media_drm_bridge.h" +#include "components/cdm/common/android_cdm_registration.h" #endif // BUILDFLAG(IS_ANDROID) namespace { @@ -348,34 +348,6 @@ } #endif // BUILDFLAG(IS_WIN) -#if BUILDFLAG(IS_ANDROID) -void AddOtherAndroidKeySystems(std::vector<content::CdmInfo>* cdms) { - // CdmInfo needs a CdmType, but on Android it is not used as the key system - // is supported by MediaDrm. Using a random value as something needs to be - // specified, but must be different than other CdmTypes specified. - // (On Android the key system is identified by UUID, and that mapping is - // maintained by MediaDrmBridge.) - const media::CdmType kAndroidCdmType{0x2e9dabb9c171c28cull, - 0xf455252ec70b52adull}; - - // MediaDrmBridge returns a list of key systems available on the device - // that are not Widevine. Register them with no capabilities specified so - // that lazy evaluation can figure out what is supported when requested. - // We don't know if either software secure or hardware secure support is - // available, so register them both. Lazy evaluation will remove them - // if they aren't supported. - const auto key_system_names = - media::MediaDrmBridge::GetPlatformKeySystemNames(); - for (const auto& key_system : key_system_names) { - DVLOG(3) << __func__ << " key_system:" << key_system; - cdms->push_back(content::CdmInfo(key_system, Robustness::kSoftwareSecure, - absl::nullopt, kAndroidCdmType)); - cdms->push_back(content::CdmInfo(key_system, Robustness::kHardwareSecure, - absl::nullopt, kAndroidCdmType)); - } -} -#endif // BUILDFLAG(IS_ANDROID) - } // namespace void RegisterCdmInfo(std::vector<content::CdmInfo>* cdms) { @@ -396,7 +368,7 @@ #endif #if BUILDFLAG(IS_ANDROID) - AddOtherAndroidKeySystems(cdms); + cdm::AddOtherAndroidCdms(cdms); #endif // BUILDFLAG(IS_ANDROID) DVLOG(3) << __func__ << " done with " << cdms->size() << " cdms";
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 70835a9..858e4dd 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc
@@ -2151,6 +2151,9 @@ // Dictionary that stores IPH state not scoped to a particular app. const char kWebAppsAppAgnosticIphState[] = "web_apps.app_agnostic_iph_state"; +// Dictionary that stores ML state not scoped to a particular app. +const char kWebAppsAppAgnosticMlState[] = "web_apps.app_agnostic_ml_state"; + // A string representing the last version of Chrome preinstalled web apps were // synchronised for. const char kWebAppsLastPreinstallSynchronizeVersion[] = @@ -3681,4 +3684,7 @@ // `HttpsUpgradesEnabled` enterprise policy. const char kHttpsUpgradesEnabled[] = "https_upgrades.policy.upgrades_enabled"; +// Whether the hovercard image previews is enabled +const char kHoverCardImagesEnabled[] = "browser.hovercard_images_enabled"; + } // namespace prefs
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 2107163..39ae4dc8 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h
@@ -702,6 +702,7 @@ extern const char kWebAppsDailyMetricsDate[]; extern const char kWebAppsExtensionIDs[]; extern const char kWebAppsAppAgnosticIphState[]; +extern const char kWebAppsAppAgnosticMlState[]; extern const char kWebAppsLastPreinstallSynchronizeVersion[]; extern const char kWebAppsDidMigrateDefaultChromeApps[]; extern const char kWebAppsUninstalledDefaultChromeApps[]; @@ -1295,6 +1296,8 @@ extern const char kHttpAllowlist[]; extern const char kHttpsUpgradesEnabled[]; +extern const char kHoverCardImagesEnabled[]; + } // namespace prefs #endif // CHROME_COMMON_PREF_NAMES_H_
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 224508a3..352a2d8 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -4202,6 +4202,7 @@ "../browser/ash/preferences_browsertest.cc", "../browser/ash/privacy_hub/privacy_hub_hats_trigger_browsertest.cc", "../browser/ash/remote_apps/remote_apps_manager_browsertest.cc", + "../browser/ash/scalable_iph/scalable_iph_browsertest.cc", "../browser/ash/scoped_test_system_nss_key_slot_mixin.cc", "../browser/ash/scoped_test_system_nss_key_slot_mixin.h", "../browser/ash/shutdown_policy_browsertest.cc", @@ -4505,6 +4506,8 @@ "//chrome/browser/ash/crosapi", "//chrome/browser/ash/crosapi:test_support", "//chrome/browser/ash/login/oobe_quick_start/connectivity:test_support", + "//chrome/browser/ash/scalable_iph:browser_test_base", + "//chrome/browser/ash/scalable_iph:scalable_iph_factory", "//chrome/browser/ash/system_extensions:browser_tests", "//chrome/browser/ash/system_web_apps/types:types", "//chrome/browser/ash/wilco_dtc_supportd:mojo_utils", @@ -4576,6 +4579,7 @@ "//chromeos/ash/components/login/login_state:test_support", "//chromeos/ash/components/mojo_service_manager", "//chromeos/ash/components/network/portal_detector", + "//chromeos/ash/components/scalable_iph", "//chromeos/ash/components/smbfs", "//chromeos/ash/components/system", "//chromeos/ash/components/timezone", @@ -4630,12 +4634,7 @@ "//components/reporting/storage:test_support", "//components/reporting/util:test_callbacks_support", "//components/rlz", - "//components/services/app_service/public/cpp:icon_loader", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:instance_update", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:preferred_apps", - "//components/services/app_service/public/cpp:run_on_os_login", + "//components/services/app_service", "//components/services/app_service/public/cpp:test_support", "//components/session_manager/core", "//components/upload_list", @@ -6403,12 +6402,7 @@ "//components/segmentation_platform/public", "//components/segmentation_platform/public:test_support", "//components/send_tab_to_self", - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:icon_types", - "//components/services/app_service/public/cpp:intents", - "//components/services/app_service/public/cpp:protocol_handling", - "//components/services/app_service/public/cpp:run_on_os_login", + "//components/services/app_service", "//components/services/paint_preview_compositor/public/mojom", "//components/services/patch/content", "//components/services/storage/public/cpp:prefs", @@ -7179,6 +7173,7 @@ "../browser/ui/bookmarks/bookmark_context_menu_controller_unittest.cc", "../browser/ui/bookmarks/bookmark_drag_drop_unittest.cc", "../browser/ui/bookmarks/bookmark_editor_unittest.cc", + "../browser/ui/bookmarks/bookmark_stats_tab_helper_unittest.cc", "../browser/ui/bookmarks/bookmark_ui_utils_desktop_unittest.cc", "../browser/ui/bookmarks/bookmark_unittest.cc", "../browser/ui/bookmarks/recently_used_folders_combo_model_unittest.cc", @@ -7604,10 +7599,8 @@ "//components/safe_browsing/core/common:safe_browsing_policy_handler", "//components/safety_check:test_support", "//components/send_tab_to_self:test_support", - "//components/services/app_service/public/cpp:icon_loader", + "//components/services/app_service", "//components/services/app_service/public/cpp:icon_loader_test_support", - "//components/services/app_service/public/cpp:preferred_app", - "//components/services/app_service/public/cpp:preferred_apps", "//components/services/app_service/public/cpp:test_support", "//components/services/app_service/public/cpp:unit_tests", "//components/session_proto_db:session_proto_db", @@ -7985,10 +7978,7 @@ "//components/metrics/structured:structured_events", "//components/metrics/structured:test_support", "//components/omnibox/browser:vector_icons", - "//components/services/app_service/public/cpp:app_update", - "//components/services/app_service/public/cpp:instance_update", - "//components/services/app_service/public/cpp:preferred_apps", - "//components/services/app_service/public/cpp:types", + "//components/services/app_service", "//components/session_manager/core", "//components/soda:soda", "//components/webapk:proto",
diff --git a/chrome/test/data/webui/BUILD.gn b/chrome/test/data/webui/BUILD.gn index c81ecc30..48de934 100644 --- a/chrome/test/data/webui/BUILD.gn +++ b/chrome/test/data/webui/BUILD.gn
@@ -159,6 +159,7 @@ "chromeos/ash_common/post_message_api/post_message_api_browsertest.js", "chromeos/bluetooth_pairing_dialog_browsertest.js", "chromeos/cloud_upload/cloud_upload_dialog_browsertest.js", + "chromeos/cloud_upload/connect_onedrive_browsertest.js", "chromeos/cloud_upload/file_handler_page_browsertest.js", "chromeos/cloud_upload/move_confirmation_page_browsertest.js", "chromeos/edu_coexistence/edu_coexistence_browsertest.js",
diff --git a/chrome/test/data/webui/chromeos/cloud_upload/BUILD.gn b/chrome/test/data/webui/chromeos/cloud_upload/BUILD.gn index 7d22b00..83c1e14e 100644 --- a/chrome/test/data/webui/chromeos/cloud_upload/BUILD.gn +++ b/chrome/test/data/webui/chromeos/cloud_upload/BUILD.gn
@@ -11,6 +11,7 @@ tsconfig_base = "../../tsconfig_base.json" in_files = [ "cloud_upload_dialog_test.ts", + "connect_onedrive_test.ts", "file_handler_page_test.ts", "move_confirmation_page_test.ts", "cloud_upload_test_browser_proxy.ts",
diff --git a/chrome/test/data/webui/chromeos/cloud_upload/connect_onedrive_browsertest.js b/chrome/test/data/webui/chromeos/cloud_upload/connect_onedrive_browsertest.js new file mode 100644 index 0000000..3a15de5b --- /dev/null +++ b/chrome/test/data/webui/chromeos/cloud_upload/connect_onedrive_browsertest.js
@@ -0,0 +1,25 @@ +// 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. + +/** + * @fileoverview Test suite for chrome://cloud-upload/connect_onedrive.js. + */ + +GEN_INCLUDE(['//chrome/test/data/webui/polymer_browser_test_base.js']); + +GEN('#include "chrome/browser/ui/webui/ash/cloud_upload/cloud_upload_dialog_browsertest.h"'); +GEN('#include "content/public/test/browser_test.h"'); + +var ConnectOneDriveTest = class extends PolymerTest { + get browsePreload() { + return 'chrome://cloud-upload/test_loader.html?module=chromeos/' + + 'cloud_upload/connect_onedrive_test.js'; + } + + get typedefCppFixture() { + return 'NonManagedUserWebUIBrowserTest'; + } +}; + +TEST_F('ConnectOneDriveTest', 'All', () => mocha.run());
diff --git a/chrome/test/data/webui/chromeos/cloud_upload/connect_onedrive_test.ts b/chrome/test/data/webui/chromeos/cloud_upload/connect_onedrive_test.ts new file mode 100644 index 0000000..790981f --- /dev/null +++ b/chrome/test/data/webui/chromeos/cloud_upload/connect_onedrive_test.ts
@@ -0,0 +1,106 @@ +// 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. + +import 'chrome://cloud-upload/connect_onedrive.js'; + +import {DialogPage, OperationType} from 'chrome://cloud-upload/cloud_upload.mojom-webui.js'; +import {CloudUploadBrowserProxy} from 'chrome://cloud-upload/cloud_upload_browser_proxy.js'; +import {ConnectOneDriveElement} from 'chrome://cloud-upload/connect_onedrive.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; + +import {CloudUploadTestBrowserProxy, ProxyOptions} from './cloud_upload_test_browser_proxy.js'; + +suite('<connect-onedrive>', () => { + /* Holds the <connect-onedrive> app. */ + let container: HTMLDivElement; + /* The <connect-onedrive> app. */ + let connectOneDriveApp: ConnectOneDriveElement; + /* The BrowserProxy element to make assertions on when mojo methods are + called. */ + let testProxy: CloudUploadTestBrowserProxy; + + async function setUp(options: ProxyOptions) { + testProxy = new CloudUploadTestBrowserProxy(options); + CloudUploadBrowserProxy.setInstance(testProxy); + + // Creates and attaches the <connect-onedrive> element to the DOM + // tree. + connectOneDriveApp = + document.createElement('connect-onedrive') as ConnectOneDriveElement; + container.appendChild(connectOneDriveApp); + } + + /** + * Runs prior to all the tests running, attaches a div to enable isolated + * clearing and attaching of the web component. + */ + suiteSetup(() => { + container = document.createElement('div'); + document.body.appendChild(container); + }); + + /** + * Runs after each test. Removes all elements from the <div> that holds + * the <connect-onedrive> component. + */ + teardown(() => { + assert(window.trustedTypes); + container.innerHTML = window.trustedTypes.emptyHTML; + testProxy.handler.reset(); + }); + + test('Successful connection leads to finished page', async () => { + await setUp({ + officeWebAppInstalled: true, + installOfficeWebAppResult: true, + odfsMounted: true, + dialogPage: DialogPage.kConnectToOneDrive, + operationType: OperationType.kMove, + }); + + const svgSuccess = connectOneDriveApp.$('#success')!; + const title = connectOneDriveApp.$('#title')!; + const bodyText = connectOneDriveApp.$('#body-text')!; + + assertEquals(svgSuccess.getAttribute('visibility'), 'hidden'); + assertTrue(title.innerText.includes('Connect to'), title.innerText); + assertTrue( + bodyText.innerText.includes('Connect OneDrive to'), bodyText.innerText); + + connectOneDriveApp.$('.action-button').click(); + + await testProxy.handler.whenCalled('signInToOneDrive'); + assertEquals(svgSuccess.getAttribute('visibility'), 'visible'); + assertTrue(title.innerText.includes('connected'), title.innerText); + assertTrue( + bodyText.innerText.includes('OneDrive will now'), bodyText.innerText); + }); + + test('Failed connection leads to error page', async () => { + await setUp({ + officeWebAppInstalled: true, + installOfficeWebAppResult: true, + odfsMounted: true, + dialogPage: DialogPage.kConnectToOneDrive, + operationType: OperationType.kMove, + }); + + testProxy.handler.setResultFor('signInToOneDrive', {success: false}); + + const errorMessage = connectOneDriveApp.$('#error-message')!; + assertTrue(errorMessage.hasAttribute('hidden')); + + connectOneDriveApp.$('.action-button').click(); + + await testProxy.handler.whenCalled('signInToOneDrive'); + assertFalse(errorMessage.hasAttribute('hidden')); + + // Try again but still fail. + connectOneDriveApp.$('.action-button').click(); + + await testProxy.handler.whenCalled('signInToOneDrive'); + assertFalse(errorMessage.hasAttribute('hidden')); + }); +});
diff --git a/chrome/test/data/webui/settings/chromeos/BUILD.gn b/chrome/test/data/webui/settings/chromeos/BUILD.gn index 624ac7c..f0825b1 100644 --- a/chrome/test/data/webui/settings/chromeos/BUILD.gn +++ b/chrome/test/data/webui/settings/chromeos/BUILD.gn
@@ -116,7 +116,7 @@ "app_management/arc_detail_view_test.js", "app_management/dom_switch_test.js", "app_management/fake_page_handler.ts", - "app_management/file_handling_item_test.js", + "app_management/file_handling_item_test.ts", "app_management/managed_apps_test.js", "app_management/pin_to_shelf_item_test.js", "app_management/plugin_vm_detail_view_test.js", @@ -176,7 +176,7 @@ "multidevice_page/multidevice_notification_access_setup_dialog_test.ts", "multidevice_page/multidevice_permissions_setup_dialog_test.ts", "multidevice_page/multidevice_smartlock_item_test.ts", - "multidevice_page/multidevice_subpage_tests.js", + "multidevice_page/multidevice_subpage_test.ts", "multidevice_page/multidevice_task_continuation_disabled_link_test.ts", "multidevice_page/multidevice_task_continuation_item_test.ts", "multidevice_page/multidevice_wifi_sync_disabled_link_test.ts", @@ -251,6 +251,7 @@ "os_settings_ui/os_settings_ui_about_page_test.js", "os_settings_ui/os_settings_ui_menu_test.js", "os_settings_ui/os_settings_ui_page_availability_test.ts", + "os_settings_ui/os_settings_ui_page_visibility_test.ts", "os_settings_ui/os_settings_ui_test.ts", "os_settings_ui/os_settings_hats_ui_test.ts", "os_settings_ui/test_os_settings_hats_browser_proxy.ts",
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js b/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js index 4132be1..4e77b20 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/arc_detail_view_test.js
@@ -274,6 +274,34 @@ assertFalse(locationItem.shadowRoot.querySelector('#description') .textContent.includes('While in use')); }); + + test('Managed permission has policy indicator', async () => { + const permission = createBoolPermission( + PermissionType.kLocation, /*value=*/ true, + /*is_managed=*/ true); + + fakeHandler.setPermission(arcPermissionView.app_.id, permission); + await flushTasks(); + + const locationItem = + getPermissionItemByType(arcPermissionView, 'kLocation'); + assertTrue( + !!locationItem.shadowRoot.querySelector('cr-policy-indicator')); + }); + + test('Unmanaged permission has no policy indicator', async () => { + const permission = createBoolPermission( + PermissionType.kLocation, /*value=*/ true, + /*is_managed=*/ false); + + fakeHandler.setPermission(arcPermissionView.app_.id, permission); + await flushTasks(); + + const locationItem = + getPermissionItemByType(arcPermissionView, 'kLocation'); + assertFalse( + !!locationItem.shadowRoot.querySelector('cr-policy-indicator')); + }); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.js b/chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.ts similarity index 66% rename from chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.js rename to chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.ts index 7822d8fd..186a7b3 100644 --- a/chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.js +++ b/chrome/test/data/webui/settings/chromeos/app_management/file_handling_item_test.ts
@@ -2,18 +2,21 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -'use strict'; - import {AppManagementStore, updateSelectedAppId} from 'chrome://os-settings/os_settings.js'; -import {setupFakeHandler, replaceStore, replaceBody} from './test_util.js'; -import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; import {AppType} from 'chrome://resources/cr_components/app_management/app_management.mojom-webui.js'; +import {AppManagementFileHandlingItemElement} from 'chrome://resources/cr_components/app_management/file_handling_item.js'; +import {AppManagementToggleRowElement} from 'chrome://resources/cr_components/app_management/toggle_row.js'; +import {assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; + +import {FakePageHandler} from './fake_page_handler.js'; +import {replaceBody, replaceStore, setupFakeHandler} from './test_util.js'; suite('<app-management-file-handling-item>', () => { - let fileHandlingItem; - let fakeHandler; + let fileHandlingItem: AppManagementFileHandlingItemElement; + let fakeHandler: FakePageHandler; - setup(async function() { + setup(() => { fakeHandler = setupFakeHandler(); replaceStore(); @@ -27,7 +30,7 @@ // Simple test that just verifies the file handling item is present and // doesn't throw errors. More comprehensive testing is in cross platform // app_management tests. - test('PWA - basic file handling test', async function() { + test('PWA - basic file handling test', async () => { const pwaOptions = { type: AppType.kWeb, fileHandlingState: { @@ -54,7 +57,10 @@ fakeHandler.flushPipesForTesting(); flushTasks(); - assertFalse( - fileHandlingItem.shadowRoot.querySelector('#toggle-row').isChecked()); + const toggleRow = + fileHandlingItem.shadowRoot! + .querySelector<AppManagementToggleRowElement>('#toggle-row'); + assertTrue(!!toggleRow); + assertFalse(toggleRow.isChecked()); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js b/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js index 94276c6f..6d7360b 100644 --- a/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/cups_printer_landing_page_tests.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {CupsPrintersBrowserProxyImpl, PRINTER_STATUS_QUERY_SHORT_DELAY_RANGE_MS, PrinterStatusReason, PrinterStatusSeverity, PrinterType} from 'chrome://os-settings/lazy_load.js'; +import {CupsPrintersBrowserProxyImpl, PRINTER_STATUS_QUERY_SHORT_DELAY_RANGE_MS, PrinterSettingsUserAction, PrinterStatusReason, PrinterStatusSeverity, PrinterType} from 'chrome://os-settings/lazy_load.js'; import {Router, routes} from 'chrome://os-settings/os_settings.js'; import {webUIListenerCallback} from 'chrome://resources/ash/common/cr.m.js'; import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; @@ -10,11 +10,12 @@ import {NetworkStateProperties} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/cros_network_config.mojom-webui.js'; import {ConnectionStateType, NetworkType} from 'chrome://resources/mojo/chromeos/services/network_config/public/mojom/network_types.mojom-webui.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertFalse, assertGE, assertNotReached, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertFalse, assertGE, assertNotReached, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {MockTimer} from 'chrome://webui-test/mock_timer.js'; import {flushTasks, waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; import {createCupsPrinterInfo, createPrinterListEntry, getPrinterEntries} from './cups_printer_test_utils.js'; +import {FakeMetricsPrivate} from './fake_metrics_private.js'; import {TestCupsPrintersBrowserProxy} from './test_cups_printers_browser_proxy.js'; const arrowUpEvent = new KeyboardEvent( @@ -1100,6 +1101,49 @@ '#show-more-container')); }); }); + + test('RecordUserActionMetric', function() { + const fakeMetricsPrivate = new FakeMetricsPrivate(); + chrome.metricsPrivate = fakeMetricsPrivate; + + createCupsPrinterPage([ + createCupsPrinterInfo('test1', '1', 'id1'), + createCupsPrinterInfo('test2', '2', 'id2'), + ]); + return cupsPrintersBrowserProxy.whenCalled('getCupsSavedPrintersList') + .then(() => { + // Wait for saved printers to populate. + flush(); + + savedPrintersElement = + page.shadowRoot.querySelector('settings-cups-saved-printers'); + assertTrue(!!savedPrintersElement); + + // Remove the first saved printer then verify the action is recorded. + return removePrinter( + cupsPrintersBrowserProxy, savedPrintersElement, /*index=*/ 0); + }) + .then(() => { + assertEquals( + 1, + fakeMetricsPrivate.countMetricValue( + 'Printing.CUPS.SettingsUserAction', + PrinterSettingsUserAction.REMOVE_PRINTER)); + + // Click the next printer's Edit button then verify the action is + // recorded. + const savedPrinterEntries = getPrinterEntries(savedPrintersElement); + clickButton(savedPrinterEntries[0].shadowRoot.querySelector( + '.icon-more-vert')); + clickButton( + savedPrintersElement.shadowRoot.querySelector('#editButton')); + assertEquals( + 1, + fakeMetricsPrivate.countMetricValue( + 'Printing.CUPS.SettingsUserAction', + PrinterSettingsUserAction.EDIT_PRINTER)); + }); + }); }); suite('CupsNearbyPrintersTests', function() {
diff --git a/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js b/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js index 6d7e4ac..f4531ec 100644 --- a/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js +++ b/chrome/test/data/webui/settings/chromeos/cups_printer_page_tests.js
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {CupsPrintersBrowserProxyImpl, CupsPrintersEntryManager, PrinterSetupResult, PrinterType, PrintServerResult} from 'chrome://os-settings/lazy_load.js'; +import {CupsPrintersBrowserProxyImpl, CupsPrintersEntryManager, PrinterSettingsUserAction, PrinterSetupResult, PrinterType, PrintServerResult} from 'chrome://os-settings/lazy_load.js'; import {Router, routes} from 'chrome://os-settings/os_settings.js'; import {webUIListenerCallback} from 'chrome://resources/ash/common/cr.m.js'; import {OncMojo} from 'chrome://resources/ash/common/network/onc_mojo.js'; @@ -15,6 +15,7 @@ import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; import {createCupsPrinterInfo, createPrinterListEntry} from './cups_printer_test_utils.js'; +import {FakeMetricsPrivate} from './fake_metrics_private.js'; import {TestCupsPrintersBrowserProxy} from './test_cups_printers_browser_proxy.js'; /* @@ -154,6 +155,31 @@ }); }); }); + + // Verify clicking the add printer manually button is recorded to metrics. + test('RecordUserActionMetric', () => { + const fakeMetricsPrivate = new FakeMetricsPrivate(); + chrome.metricsPrivate = fakeMetricsPrivate; + + // Enable the add printer manually button. + page.prefs = { + native_printing: { + user_native_printers_allowed: { + value: true, + }, + }, + }; + page.canAddPrinter = true; + + return flushTasks().then(() => { + page.shadowRoot.querySelector('.add-manual-printer-icon').click(); + assertEquals( + 1, + fakeMetricsPrivate.countMetricValue( + 'Printing.CUPS.SettingsUserAction', + PrinterSettingsUserAction.ADD_PRINTER_MANUALLY)); + }); + }); }); suite('CupsAddPrinterDialogTests', function() {
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/fake_input_device_settings_provider_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/fake_input_device_settings_provider_test.ts index 2d8353e..33e15420 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page/fake_input_device_settings_provider_test.ts +++ b/chrome/test/data/webui/settings/chromeos/device_page/fake_input_device_settings_provider_test.ts
@@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {FakeInputDeviceSettingsProvider, fakeKeyboards, fakeMice, fakePointingSticks, fakeTouchpads} from 'chrome://os-settings/os_settings.js'; +import {FakeInputDeviceSettingsProvider, fakeKeyboards, fakeMice, fakePointingSticks, fakeTouchpads, ModifierKey} from 'chrome://os-settings/os_settings.js'; import {assertDeepEquals} from 'chrome://webui-test/chai_assert.js'; suite('FakeInputDeviceSettings', () => { @@ -92,4 +92,16 @@ const result = await provider.getConnectedPointingStickSettings(); assertDeepEquals(updatedFirstPointingStick, result[0]); }); + + test('restoreDefaultKeyboardModifierRemappings', async () => { + provider.setFakeKeyboards(fakeKeyboards); + // Restore the default modifier remappings for the first keyboard settings. + provider.restoreDefaultKeyboardModifierRemappings(fakeKeyboards[0]!.id!); + // Verify if the first keyboard settings are updated. + const result = await provider.getConnectedKeyboardSettings(); + assertDeepEquals(result[0]!.settings!.modifierRemappings, { + [ModifierKey.kControl]: ModifierKey.kMeta, + [ModifierKey.kMeta]: ModifierKey.kControl, + }); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts b/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts index 0cce31c..4fe50dd 100644 --- a/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts +++ b/chrome/test/data/webui/settings/chromeos/device_page/per_device_keyboard_remap_keys_test.ts
@@ -28,6 +28,7 @@ /* dynamicParams= */ url, /* removeSearch= */ true); document.body.appendChild(page); + provider.observeKeyboardSettings(page); await flushTasks(); });
diff --git a/chrome/test/data/webui/settings/chromeos/fake_metrics_private.ts b/chrome/test/data/webui/settings/chromeos/fake_metrics_private.ts index 991a5bf..818eda90 100644 --- a/chrome/test/data/webui/settings/chromeos/fake_metrics_private.ts +++ b/chrome/test/data/webui/settings/chromeos/fake_metrics_private.ts
@@ -2,8 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +const FALSE_COUNT: number = 0; +const TRUE_COUNT: number = 1; + export class FakeMetricsPrivate { - collectedMetrics: Map<string, {[key: string]: number}>; + collectedMetrics: Map<string, {[key: number]: number}>; constructor() { this.collectedMetrics = new Map(); } @@ -23,7 +26,7 @@ this.collectedMetrics.set(metric, metricEntry); } - countMetricValue(metric: string, value: string): number { + countMetricValue(metric: string, value: number): number { const metricEntry = this.collectedMetrics.get(metric); if (metricEntry) { @@ -35,12 +38,12 @@ } recordBoolean(metric: string, value: boolean): void { - const metricEntry = - this.collectedMetrics.get(metric) || {trueCnt: 0, falseCnt: 0}; + const metricEntry = this.collectedMetrics.get(metric) || + {[TRUE_COUNT]: 0, [FALSE_COUNT]: 0}; if (value) { - metricEntry['trueCnt'] += 1; + metricEntry[TRUE_COUNT] += 1; } else { - metricEntry['falseCnt'] += 1; + metricEntry[FALSE_COUNT] += 1; } this.collectedMetrics.set(metric, metricEntry); } @@ -50,9 +53,9 @@ if (metricEntry) { if (value) { - return metricEntry['trueCnt'] as number; + return metricEntry[TRUE_COUNT] as number; } else { - return metricEntry['falseCnt'] as number; + return metricEntry[FALSE_COUNT] as number; } } else { return 0;
diff --git a/chrome/test/data/webui/settings/chromeos/main_page_container_test.js b/chrome/test/data/webui/settings/chromeos/main_page_container_test.js index d51e270..e1bd69a 100644 --- a/chrome/test/data/webui/settings/chromeos/main_page_container_test.js +++ b/chrome/test/data/webui/settings/chromeos/main_page_container_test.js
@@ -8,7 +8,7 @@ import {setBluetoothConfigForTesting} from 'chrome://resources/ash/common/bluetooth/cros_bluetooth_config.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertNotEquals, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {FakeBluetoothConfig} from 'chrome://webui-test/cr_components/chromeos/bluetooth/fake_bluetooth_config.js'; import {FakeContactManager} from 'chrome://webui-test/nearby_share/shared/fake_nearby_contact_manager.js'; import {FakeNearbyShareSettings} from 'chrome://webui-test/nearby_share/shared/fake_nearby_share_settings.js'; @@ -170,7 +170,10 @@ suite('Revamp: Wayfinding', () => { suite('when enabled', () => { suiteSetup(async () => { + // Simulate feature flag enabled loadTimeData.overrideValues({isRevampWayfindingEnabled: true}); + document.body.classList.add('revamp-wayfinding-enabled'); + Router.getInstance().navigateTo(routes.BASIC); mainPageContainer = init(); }); @@ -192,9 +195,29 @@ }); suite('Route navigations', () => { - function queryActivePages() { - return mainPageContainer.shadowRoot.querySelectorAll( - 'os-settings-section[active]'); + /** + * Asserts the following: + * - Only one page is marked active + * - Active page does not have style "display: none" + * - Inactive pages have style "display: none" + */ + function assertOnlyActivePageIsVisible(pageName) { + const pages = mainPageContainer.shadowRoot.querySelectorAll( + 'os-settings-section'); + let numActive = 0; + + for (const page of pages) { + const displayStyle = getComputedStyle(page).display; + if (page.hasAttribute('active')) { + numActive++; + assertNotEquals('none', displayStyle); + assertEquals(pageName, page.section); + } else { + assertEquals('none', displayStyle); + } + } + + assertEquals(1, numActive); } suite('From Root', () => { @@ -205,9 +228,7 @@ Router.getInstance().navigateTo(routes.INTERNET); await navigationCompletePromise; - const activePages = queryActivePages(); - assertEquals(1, activePages.length); - assertEquals('internet', activePages[0].section); + assertOnlyActivePageIsVisible('internet'); }); test('to Subpage should result in only one active page', async () => { @@ -217,9 +238,7 @@ Router.getInstance().navigateTo(routes.BLUETOOTH_DEVICES); await navigationCompletePromise; - const activePages = queryActivePages(); - assertEquals(1, activePages.length); - assertEquals('bluetooth', activePages[0].section); + assertOnlyActivePageIsVisible('bluetooth'); }); }); @@ -234,9 +253,7 @@ Router.getInstance().navigateTo(routes.BLUETOOTH); await navigationCompletePromise; - const activePages = queryActivePages(); - assertEquals(1, activePages.length); - assertEquals('bluetooth', activePages[0].section); + assertOnlyActivePageIsVisible('bluetooth'); }); test('to Subpage should result in only one active page', async () => { @@ -248,9 +265,7 @@ routes.A11Y_DISPLAY_AND_MAGNIFICATION); await navigationCompletePromise; - const activePages = queryActivePages(); - assertEquals(1, activePages.length); - assertEquals('osAccessibility', activePages[0].section); + assertOnlyActivePageIsVisible('osAccessibility'); }); test('to Root should result in only one active page', async () => { @@ -261,9 +276,7 @@ Router.getInstance().navigateTo(routes.BASIC); await navigationCompletePromise; - const activePages = queryActivePages(); - assertEquals(1, activePages.length); - assertEquals('internet', activePages[0].section); + assertOnlyActivePageIsVisible('internet'); }); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_subpage_tests.js b/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_subpage_test.ts similarity index 61% rename from chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_subpage_tests.js rename to chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_subpage_test.ts index 7bb3ea6..519698d 100644 --- a/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_subpage_tests.js +++ b/chrome/test/data/webui/settings/chromeos/multidevice_page/multidevice_subpage_test.ts
@@ -2,27 +2,30 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import {MultiDeviceBrowserProxyImpl, MultiDeviceFeature, MultiDeviceFeatureState, MultiDeviceSettingsMode, PhoneHubFeatureAccessStatus, Router, routes} from 'chrome://os-settings/os_settings.js'; -import {getDeepActiveElement} from 'chrome://resources/ash/common/util.js'; +import 'chrome://os-settings/lazy_load.js'; + +import {SettingsMultideviceFeatureItemElement, SettingsMultideviceSubpageElement} from 'chrome://os-settings/lazy_load.js'; +import {MultiDeviceBrowserProxyImpl, MultiDeviceFeature, MultiDeviceFeatureState, MultiDeviceSettingsMode, PhoneHubFeatureAccessStatus, Router, routes, settingMojom} from 'chrome://os-settings/os_settings.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; +import {getDeepActiveElement} from 'chrome://resources/js/util_ts.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {waitAfterNextRender} from 'chrome://webui-test/polymer_test_util.js'; import {TestMultideviceBrowserProxy} from './test_multidevice_browser_proxy.js'; -suite('Multidevice', function() { - let multideviceSubpage = null; - let browserProxy = null; +suite('<settings-multidevice-subpage>', () => { + let multideviceSubpage: SettingsMultideviceSubpageElement; + let browserProxy: TestMultideviceBrowserProxy; // Although HOST_SET_MODES is effectively a constant, it cannot reference the // enum MultiDeviceSettingsMode from here so its initialization is // deferred to the suiteSetup function. - let HOST_SET_MODES; + let HOST_SET_MODES: MultiDeviceSettingsMode[]; /** * Observably sets mode. Everything else remains unchanged. - * @param {MultiDeviceSettingsMode} newMode */ - function setMode(newMode) { + function setMode(newMode: MultiDeviceSettingsMode): void { multideviceSubpage.pageContentData = Object.assign({}, multideviceSubpage.pageContentData, { mode: newMode, @@ -33,9 +36,8 @@ /** * Observably resets feature states so that each feature is supported if and * only if it is in the provided array. Everything else remains unchanged. - * @param {Array<MultiDeviceFeature>} supportedFeatures */ - function setSupportedFeatures(supportedFeatures) { + function setSupportedFeatures(supportedFeatures: MultiDeviceFeature[]): void { multideviceSubpage.pageContentData = Object.assign({}, multideviceSubpage.pageContentData, { betterTogetherState: supportedFeatures.includes( @@ -85,10 +87,7 @@ flush(); } - /** - * @param {boolean} pairingComplete - */ - function setAndroidSmsPairingComplete(pairingComplete) { + function setAndroidSmsPairingComplete(pairingComplete: boolean): void { multideviceSubpage.pageContentData = Object.assign({}, multideviceSubpage.pageContentData, { messagesState: pairingComplete ? @@ -99,7 +98,7 @@ flush(); } - suiteSetup(function() { + suiteSetup(() => { HOST_SET_MODES = [ MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_SERVER, MultiDeviceSettingsMode.HOST_SET_WAITING_FOR_VERIFICATION, @@ -107,210 +106,208 @@ ]; }); - setup(function() { + setup(() => { browserProxy = new TestMultideviceBrowserProxy(); MultiDeviceBrowserProxyImpl.setInstanceForTesting(browserProxy); - PolymerTest.clearBody(); multideviceSubpage = document.createElement('settings-multidevice-subpage'); - multideviceSubpage.pageContentData = {hostDeviceName: 'Pixel XL'}; + assertTrue(!!multideviceSubpage); + multideviceSubpage.pageContentData = { + ...multideviceSubpage.pageContentData, + hostDeviceName: 'Pixel XL', + }; + setMode(MultiDeviceSettingsMode.HOST_SET_VERIFIED); - setSupportedFeatures(Object.values(MultiDeviceFeature)); + setSupportedFeatures( + Object.values(MultiDeviceFeature) as MultiDeviceFeature[]); document.body.appendChild(multideviceSubpage); flush(); }); - teardown(function() { + teardown(() => { multideviceSubpage.remove(); + browserProxy.reset(); Router.getInstance().resetRouteForTesting(); }); - test('individual features appear only if host is verified', function() { + test('individual features appear only if host is verified', () => { for (const mode of HOST_SET_MODES) { setMode(mode); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector('#smartLockItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector('#smartLockItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector( - '#instantTetheringItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector( + '#instantTetheringItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector('#messagesItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector('#messagesItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubNotificationsItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubNotificationsItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubTaskContinuationItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubTaskContinuationItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector('#wifiSyncItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector('#wifiSyncItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); assertEquals( - !!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubCameraRollItem'), - mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED); + mode === MultiDeviceSettingsMode.HOST_SET_VERIFIED, + !!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubCameraRollItem')); } }); - test( - 'individual features are attached only if they are supported', - function() { - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#smartLockItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#instantTetheringItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#messagesItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubNotificationsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubTaskContinuationItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#wifiSyncItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubCameraRollItem')); + test('individual features are attached only if they are supported', () => { + assertTrue( + !!multideviceSubpage.shadowRoot!.querySelector('#smartLockItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#instantTetheringItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector('#messagesItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubNotificationsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubTaskContinuationItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector('#wifiSyncItem')); + assertTrue( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubCameraRollItem')); - setSupportedFeatures([ - MultiDeviceFeature.SMART_LOCK, - MultiDeviceFeature.MESSAGES, - MultiDeviceFeature.PHONE_HUB, - MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, - MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION, - MultiDeviceFeature.WIFI_SYNC, - MultiDeviceFeature.ECHE, - MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL, - ]); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#smartLockItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#instantTetheringItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#messagesItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubNotificationsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubTaskContinuationItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#wifiSyncItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubCameraRollItem')); + setSupportedFeatures([ + MultiDeviceFeature.SMART_LOCK, + MultiDeviceFeature.MESSAGES, + MultiDeviceFeature.PHONE_HUB, + MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, + MultiDeviceFeature.PHONE_HUB_TASK_CONTINUATION, + MultiDeviceFeature.WIFI_SYNC, + MultiDeviceFeature.ECHE, + MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL, + ]); + assertTrue( + !!multideviceSubpage.shadowRoot!.querySelector('#smartLockItem')); + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#instantTetheringItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector('#messagesItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubNotificationsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubTaskContinuationItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector('#wifiSyncItem')); + assertTrue( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubCameraRollItem')); - setSupportedFeatures([MultiDeviceFeature.INSTANT_TETHERING]); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#smartLockItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( - '#instantTetheringItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#messagesItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubNotificationsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubTaskContinuationItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#wifiSyncItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubCameraRollItem')); + setSupportedFeatures([MultiDeviceFeature.INSTANT_TETHERING]); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#smartLockItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#instantTetheringItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#messagesItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubNotificationsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubTaskContinuationItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#wifiSyncItem')); + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubCameraRollItem')); - setSupportedFeatures([]); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#smartLockItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#instantTetheringItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#messagesItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubNotificationsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubTaskContinuationItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#wifiSyncItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( - '#phoneHubCameraRollItem')); - }); + setSupportedFeatures([]); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#smartLockItem')); + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#instantTetheringItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#messagesItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubNotificationsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubTaskContinuationItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector('#wifiSyncItem')); + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubCameraRollItem')); + }); test( 'setting isSmartLockSignInRemoved flag removes SmartLock subpage route', - function() { + () => { multideviceSubpage.remove(); loadTimeData.overrideValues({'isSmartLockSignInRemoved': true}); browserProxy = new TestMultideviceBrowserProxy(); MultiDeviceBrowserProxyImpl.setInstanceForTesting(browserProxy); - PolymerTest.clearBody(); multideviceSubpage = document.createElement('settings-multidevice-subpage'); - multideviceSubpage.pageContentData = {hostDeviceName: 'Pixel XL'}; + multideviceSubpage.pageContentData = { + ...multideviceSubpage.pageContentData, + hostDeviceName: 'Pixel XL', + }; setMode(MultiDeviceSettingsMode.HOST_SET_VERIFIED); - setSupportedFeatures(Object.values(MultiDeviceFeature)); + setSupportedFeatures( + Object.values(MultiDeviceFeature) as MultiDeviceFeature[]); document.body.appendChild(multideviceSubpage); flush(); - assertEquals( - undefined, - multideviceSubpage.shadowRoot.querySelector('#smartLockItem') - .subpageRoute); + const smartLockItem = + multideviceSubpage.shadowRoot! + .querySelector<SettingsMultideviceFeatureItemElement>( + '#smartLockItem'); + assertTrue(!!smartLockItem); + assertEquals(undefined, smartLockItem.subpageRoute); const routeBefore = Router.getInstance().currentRoute; - multideviceSubpage.shadowRoot.querySelector('#smartLockItem') - .shadowRoot.querySelector('.link-wrapper') - .click(); - assertEquals(Router.getInstance().currentRoute, routeBefore); + const linkWrapper = + smartLockItem.shadowRoot!.querySelector<HTMLElement>( + '.link-wrapper'); + assertTrue(!!linkWrapper); + linkWrapper.click(); + assertEquals(routeBefore, Router.getInstance().currentRoute); loadTimeData.overrideValues({'isSmartLockSignInRemoved': false}); }); - test('AndroidMessages item shows button when not set up', function() { + test('AndroidMessages item shows button when not set up', () => { setAndroidSmsPairingComplete(false); flush(); const controllerSelector = '#messagesItem > [slot=feature-controller]'; - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector(controllerSelector)); - assertTrue(multideviceSubpage.shadowRoot.querySelector(controllerSelector) - .tagName.includes('BUTTON')); + const selector = + multideviceSubpage.shadowRoot!.querySelector(controllerSelector); + assertTrue(!!selector); + assertTrue(selector.tagName.includes('BUTTON')); setAndroidSmsPairingComplete(true); flush(); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector(controllerSelector)); + assertNull( + multideviceSubpage.shadowRoot!.querySelector(controllerSelector)); }); test( 'AndroidMessages set up button calls browser proxy function', - async function() { + async () => { setAndroidSmsPairingComplete(false); flush(); - const setUpButton = multideviceSubpage.shadowRoot.querySelector( - '#messagesItem > [slot=feature-controller]'); + const setUpButton = + multideviceSubpage.shadowRoot!.querySelector<HTMLElement>( + '#messagesItem > [slot=feature-controller]'); assertTrue(!!setUpButton); setUpButton.click(); @@ -318,42 +315,43 @@ await browserProxy.whenCalled('setUpAndroidSms'); }); - test( - 'AndroidMessages toggle is disabled when prohibited by policy', - function() { - // Verify that setup button is disabled when prohibited by policy. - multideviceSubpage.pageContentData = - Object.assign({}, multideviceSubpage.pageContentData, { - messagesState: MultiDeviceFeatureState.PROHIBITED_BY_POLICY, - isAndroidSmsPairingComplete: false, - }); - flush(); + test('AndroidMessages toggle is disabled when prohibited by policy', () => { + // Verify that setup button is disabled when prohibited by policy. + multideviceSubpage.pageContentData = { + ...multideviceSubpage.pageContentData, + messagesState: MultiDeviceFeatureState.PROHIBITED_BY_POLICY, + isAndroidSmsPairingComplete: false, + }; + flush(); - let setUpButton = multideviceSubpage.shadowRoot.querySelector( + let setUpButton = + multideviceSubpage.shadowRoot!.querySelector<HTMLButtonElement>( '#messagesItem > [slot=feature-controller]'); - assertFalse(!!setUpButton); + assertNull(setUpButton); - // Verify that setup button is not disabled when feature is enabled. - setAndroidSmsPairingComplete(false); - setUpButton = multideviceSubpage.shadowRoot.querySelector( - '#messagesItem > [slot=feature-controller]'); - assertTrue(!!setUpButton); - assertTrue(setUpButton.tagName.includes('BUTTON')); - assertFalse(setUpButton.disabled); - }); + // Verify that setup button is not disabled when feature is enabled. + setAndroidSmsPairingComplete(false); + setUpButton = multideviceSubpage.shadowRoot!.querySelector( + '#messagesItem > [slot=feature-controller]'); + assertTrue(!!setUpButton); + assertTrue(setUpButton.tagName.includes('BUTTON')); + assertFalse(setUpButton.disabled); + }); test('Deep link to setup messages', async () => { setAndroidSmsPairingComplete(false); flush(); const params = new URLSearchParams(); - params.append('settingId', '205'); + params.append('settingId', settingMojom.Setting.kMessagesSetUp.toString()); Router.getInstance().navigateTo(routes.MULTIDEVICE_FEATURES, params); flush(); - const deepLinkElement = multideviceSubpage.shadowRoot.querySelector( - '#messagesItem > [slot=feature-controller]'); + const deepLinkElement = + multideviceSubpage.shadowRoot!.querySelector<HTMLElement>( + '#messagesItem > [slot=feature-controller]'); + assertTrue(!!deepLinkElement); await waitAfterNextRender(deepLinkElement); assertEquals( deepLinkElement, getDeepActiveElement(), @@ -365,15 +363,20 @@ flush(); const params = new URLSearchParams(); - params.append('settingId', '206'); + params.append('settingId', settingMojom.Setting.kMessagesOnOff.toString()); Router.getInstance().navigateTo(routes.MULTIDEVICE_FEATURES, params); flush(); + const messagesItem = + multideviceSubpage.shadowRoot!.querySelector('#messagesItem'); + assertTrue(!!messagesItem); + const featureToggle = messagesItem.shadowRoot!.querySelector( + 'settings-multidevice-feature-toggle'); + assertTrue(!!featureToggle); const deepLinkElement = - multideviceSubpage.shadowRoot.querySelector('#messagesItem') - .shadowRoot.querySelector('settings-multidevice-feature-toggle') - .shadowRoot.querySelector('cr-toggle'); + featureToggle.shadowRoot!.querySelector('cr-toggle'); + assertTrue(!!deepLinkElement); await waitAfterNextRender(deepLinkElement); assertEquals( deepLinkElement, getDeepActiveElement(), @@ -382,15 +385,20 @@ test('Deep link to phone hub on/off', async () => { const params = new URLSearchParams(); - params.append('settingId', '209'); + params.append('settingId', settingMojom.Setting.kPhoneHubOnOff.toString()); Router.getInstance().navigateTo(routes.MULTIDEVICE_FEATURES, params); flush(); + const phoneHubItem = + multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem'); + assertTrue(!!phoneHubItem); + const featureToggle = phoneHubItem.shadowRoot!.querySelector( + 'settings-multidevice-feature-toggle'); + assertTrue(!!featureToggle); const deepLinkElement = - multideviceSubpage.shadowRoot.querySelector('#phoneHubItem') - .shadowRoot.querySelector('settings-multidevice-feature-toggle') - .shadowRoot.querySelector('cr-toggle'); + featureToggle.shadowRoot!.querySelector('cr-toggle'); + assertTrue(!!deepLinkElement); await waitAfterNextRender(deepLinkElement); assertEquals( deepLinkElement, getDeepActiveElement(), @@ -402,15 +410,21 @@ {}, multideviceSubpage.pageContentData, {isPhoneHubAppsAccessGranted: true}); const params = new URLSearchParams(); - params.append('settingId', '218'); + params.append( + 'settingId', settingMojom.Setting.kPhoneHubAppsOnOff.toString()); Router.getInstance().navigateTo(routes.MULTIDEVICE_FEATURES, params); flush(); + const phoneHubAppsItem = + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem'); + assertTrue(!!phoneHubAppsItem); + const featureToggle = phoneHubAppsItem.shadowRoot!.querySelector( + 'settings-multidevice-feature-toggle'); + assertTrue(!!featureToggle); const deepLinkElement = - multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem') - .shadowRoot.querySelector('settings-multidevice-feature-toggle') - .shadowRoot.querySelector('cr-toggle'); + featureToggle.shadowRoot!.querySelector('cr-toggle'); + assertTrue(!!deepLinkElement); await waitAfterNextRender(deepLinkElement); assertEquals( deepLinkElement, getDeepActiveElement(), @@ -419,7 +433,7 @@ test( 'Phone Hub Camera Roll, Notifications, Apps and Combined items are shown/hidden correctly', - function() { + () => { setSupportedFeatures([ MultiDeviceFeature.PHONE_HUB, MultiDeviceFeature.PHONE_HUB_NOTIFICATIONS, @@ -437,14 +451,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -459,14 +473,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -482,14 +496,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -505,14 +519,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); setSupportedFeatures([ @@ -534,14 +548,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -557,14 +571,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -581,14 +595,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -605,14 +619,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -630,20 +644,19 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); const controllerSelector = '#phoneHubAppsItem > [slot=feature-controller]'; - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector(controllerSelector)); - assertTrue( - multideviceSubpage.shadowRoot.querySelector(controllerSelector) - .tagName.includes('BUTTON')); + const selector = + multideviceSubpage.shadowRoot!.querySelector(controllerSelector); + assertTrue(!!selector); + assertTrue(selector.tagName.includes('BUTTON')); multideviceSubpage.pageContentData = Object.assign({}, multideviceSubpage.pageContentData, { @@ -660,14 +673,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); setSupportedFeatures([ @@ -690,14 +703,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -714,14 +727,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -738,14 +751,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -762,14 +775,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); setSupportedFeatures([ @@ -795,14 +808,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -821,14 +834,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -847,14 +860,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -874,14 +887,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -901,14 +914,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -928,14 +941,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -954,14 +967,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); multideviceSubpage.pageContentData = @@ -981,20 +994,20 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); }); test( 'Enterprise policies should properly affect Phone Hub Camera Roll, Notifications, Apps, and Combined items.', - function() { + () => { setSupportedFeatures([ MultiDeviceFeature.PHONE_HUB, MultiDeviceFeature.PHONE_HUB_CAMERA_ROLL, @@ -1023,14 +1036,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); // Notifications, CameraRoll and Apps features are not grant, but @@ -1055,14 +1068,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); // Notifications, CameraRoll and Apps features are not grant, but Apps @@ -1085,14 +1098,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); // Notifications, CameraRoll and Apps features are not grant, but @@ -1117,14 +1130,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); // Notifications, CameraRoll and Apps features are not grant, but Phone @@ -1150,14 +1163,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); // Test Phone's enterprise policy: @@ -1182,14 +1195,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertFalse( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertNull( + multideviceSubpage.shadowRoot!.querySelector('#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); // Notifications, CameraRoll and Apps features are not grant, but @@ -1213,14 +1226,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); // Notifications, CameraRoll and Apps features are not grant, but @@ -1243,14 +1256,14 @@ flush(); assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + !!multideviceSubpage.shadowRoot!.querySelector('#phoneHubItem')); + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCameraRollItem')); - assertTrue(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( '#phoneHubNotificationsItem')); - assertTrue( - !!multideviceSubpage.shadowRoot.querySelector('#phoneHubAppsItem')); - assertFalse(!!multideviceSubpage.shadowRoot.querySelector( + assertTrue(!!multideviceSubpage.shadowRoot!.querySelector( + '#phoneHubAppsItem')); + assertNull(multideviceSubpage.shadowRoot!.querySelector( '#phoneHubCombinedSetupItem')); }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_page_test.ts b/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_page_test.ts index d835830..f5cb840 100644 --- a/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_page_test.ts +++ b/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_page_test.ts
@@ -8,7 +8,7 @@ import {OneDriveBrowserProxy} from 'chrome://os-settings/os_settings.js'; import {CrButtonElement} from 'chrome://resources/cr_elements/cr_button/cr_button.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertEquals} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {assertAsync} from '../utils.js'; @@ -34,22 +34,24 @@ flush(); } - test( - 'display user email address and disconnect button when signed in', - async () => { - const email = 'email@gmail.com'; - await setupOneDrivePage({email}); - const signedInAsLabelElement = - oneDrivePage.shadowRoot!.querySelector<HTMLDivElement>( - '#signedInAsLabel')!; - const connectDisconnectButton = - oneDrivePage.shadowRoot!.querySelector<CrButtonElement>( - '#oneDriveConnectDisconnect')!; - assertEquals('Signed in as ' + email, signedInAsLabelElement.innerText); - assertEquals('Disconnect', connectDisconnectButton.textContent!.trim()); - }); + test('Signed in page content', async () => { + const email = 'email@gmail.com'; + await setupOneDrivePage({email}); + const signedInAsLabelElement = + oneDrivePage.shadowRoot!.querySelector<HTMLDivElement>( + '#signedInAsLabel')!; + const connectDisconnectButton = + oneDrivePage.shadowRoot!.querySelector<CrButtonElement>( + '#oneDriveConnectDisconnect')!; + const openOneDriveFolderButton = + oneDrivePage.shadowRoot!.querySelector<CrButtonElement>( + '#openOneDriveFolder')!; + assertEquals('Signed in as ' + email, signedInAsLabelElement.innerText); + assertEquals('Disconnect', connectDisconnectButton.textContent!.trim()); + assertTrue(!!openOneDriveFolderButton); + }); - test('display disconnected and connect button when signed out', async () => { + test('Signed out page content', async () => { await setupOneDrivePage({ email: null, }); @@ -59,9 +61,13 @@ const connectDisconnectButton = oneDrivePage.shadowRoot!.querySelector<CrButtonElement>( '#oneDriveConnectDisconnect')!; + const openOneDriveFolderButton = + oneDrivePage.shadowRoot!.querySelector<CrButtonElement>( + '#openOneDriveFolder')!; assertEquals('Disconnected', signedInAsLabelElement.innerText); assertEquals( 'Connect account', connectDisconnectButton.textContent!.trim()); + assertFalse(!!openOneDriveFolderButton); }); test('Update page to signed in state on OneDrive mount', async () => { @@ -140,4 +146,16 @@ assertEquals( 1, testOneDriveProxy.handler.getCallCount('disconnectFromOneDrive')); }); + + test('Open OneDrive folder', async () => { + const email = 'email@gmail.com'; + await setupOneDrivePage({email}); + const openOneDriveFolderButton = + oneDrivePage.shadowRoot!.querySelector<CrButtonElement>( + '#openOneDriveFolder')!; + + openOneDriveFolderButton.click(); + assertEquals( + 1, testOneDriveProxy.handler.getCallCount('openOneDriveFolder')); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_test_browser_proxy.ts b/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_test_browser_proxy.ts index 7a67784..3192d15 100644 --- a/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_test_browser_proxy.ts +++ b/chrome/test/data/webui/settings/chromeos/os_files_page/one_drive_test_browser_proxy.ts
@@ -26,5 +26,6 @@ this.handler.setResultFor('getUserEmailAddress', {email: options.email}); this.handler.setResultFor('connectToOneDrive', {success: true}); this.handler.setResultFor('disconnectFromOneDrive', {success: true}); + this.handler.setResultFor('openOneDriveFolder', {success: true}); } }
diff --git a/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printers_entry_test.ts b/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printers_entry_test.ts index 58d01792..d2a6dc5 100644 --- a/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printers_entry_test.ts +++ b/chrome/test/data/webui/settings/chromeos/os_printing_page/cups_printers_entry_test.ts
@@ -4,13 +4,15 @@ import 'chrome://os-settings/lazy_load.js'; -import {PrinterListEntry, PrinterStatusReason, PrinterType, SettingsCupsPrintersEntryElement} from 'chrome://os-settings/lazy_load.js'; +import {PrinterListEntry, PrinterSettingsUserAction, PrinterStatusReason, PrinterType, SettingsCupsPrintersEntryElement} from 'chrome://os-settings/lazy_load.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {IronIconElement} from 'chrome://resources/polymer/v3_0/iron-icon/iron-icon.js'; import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {assertEquals, assertFalse, assertNull, assertTrue} from 'chrome://webui-test/chai_assert.js'; import {isVisible} from 'chrome://webui-test/test_util.js'; +import {FakeMetricsPrivate} from '../fake_metrics_private.js'; + function createPrinterEntry(printerType: PrinterType): PrinterListEntry { return { printerInfo: { @@ -189,4 +191,39 @@ assertTrue(isVisible(printerEntryTestElement.shadowRoot!.querySelector( '#printerStatusIcon'))); }); + + // Verify clicking the setup or save button is recorded to metrics. + test('recordUserActionMetric', () => { + const fakeMetricsPrivate = new FakeMetricsPrivate(); + chrome.metricsPrivate = + fakeMetricsPrivate as unknown as typeof chrome.metricsPrivate; + + // Enable the save printer buttons. + printerEntryTestElement.savingPrinter = false; + printerEntryTestElement.userPrintersAllowed = true; + + // Verify saving an automatic printer is recorded. + printerEntryTestElement.printerEntry = + createPrinterEntry(PrinterType.AUTOMATIC); + flush(); + printerEntryTestElement.shadowRoot! + .querySelector<HTMLElement>('#automaticPrinterButton')!.click(); + assertEquals( + 1, + fakeMetricsPrivate.countMetricValue( + 'Printing.CUPS.SettingsUserAction', + PrinterSettingsUserAction.SAVE_PRINTER)); + + // Verify saving a discovered printer is recorded. + printerEntryTestElement.printerEntry = + createPrinterEntry(PrinterType.DISCOVERED); + flush(); + printerEntryTestElement.shadowRoot! + .querySelector<HTMLElement>('#setupPrinterButton')!.click(); + assertEquals( + 2, + fakeMetricsPrivate.countMetricValue( + 'Printing.CUPS.SettingsUserAction', + PrinterSettingsUserAction.SAVE_PRINTER)); + }); });
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js index 0ec57d5..cd29273 100644 --- a/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js +++ b/chrome/test/data/webui/settings/chromeos/os_settings_browsertest.js
@@ -408,7 +408,7 @@ ], [ 'MultidevicePageMultideviceSubPage', - 'multidevice_page/multidevice_subpage_tests.js' + 'multidevice_page/multidevice_subpage_test.js' ], [ 'MultiDevicePageMultideviceCombinedSetupItem', @@ -604,6 +604,10 @@ 'OsSettingsUiPageAvailability', 'os_settings_ui/os_settings_ui_page_availability_test.js', ], + [ + 'OsSettingsUiPageVisibility', + 'os_settings_ui/os_settings_ui_page_visibility_test.js', + ], ['OsSettingsUiToolbar', 'os_settings_ui/os_settings_ui_toolbar_test.js'], [ 'OsSettingsUiUserActionRecorder',
diff --git a/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_page_visibility_test.ts b/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_page_visibility_test.ts new file mode 100644 index 0000000..40bac88 --- /dev/null +++ b/chrome/test/data/webui/settings/chromeos/os_settings_ui/os_settings_ui_page_visibility_test.ts
@@ -0,0 +1,128 @@ +// 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. + +/** + * @fileoverview + * Suite of tests for page visibility in the CrOS Settings UI. These tests + * expect the OsSettingsRevampWayfinding feature flag to be enabled. + * Separated into a separate file to mitigate test timeouts. + */ + +import 'chrome://os-settings/os_settings.js'; + +import {createRoutesForTesting, CrSettingsPrefs, MainPageContainerElement, OsSettingsMainElement, OsSettingsMenuElement, OsSettingsSectionElement, OsSettingsUiElement, Router} from 'chrome://os-settings/os_settings.js'; +import {assert} from 'chrome://resources/js/assert_ts.js'; +import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; +import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {assertEquals, assertNotEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; + +suite('<os-settings-ui> page visibility', () => { + let ui: OsSettingsUiElement; + let settingsMain: OsSettingsMainElement; + let mainPageContainer: MainPageContainerElement; + let menu: OsSettingsMenuElement; + + async function createUi() { + ui = document.createElement('os-settings-ui'); + document.body.appendChild(ui); + flush(); + await CrSettingsPrefs.initialized; + + const mainEl = ui.shadowRoot!.querySelector('os-settings-main'); + assert(mainEl); + settingsMain = mainEl; + + const mainPageContainerEl = + settingsMain.shadowRoot!.querySelector('main-page-container'); + assert(mainPageContainerEl); + mainPageContainer = mainPageContainerEl; + + const menuEl = ui.shadowRoot!.querySelector<OsSettingsMenuElement>( + '#left os-settings-menu'); + assert(menuEl); + menu = menuEl; + + const idleRender = + mainPageContainer.shadowRoot!.querySelector('settings-idle-load'); + assert(idleRender); + await idleRender.get(); + flush(); + } + + function queryActivePages(): NodeListOf<OsSettingsSectionElement> { + return mainPageContainer.shadowRoot! + .querySelectorAll<OsSettingsSectionElement>( + `os-settings-section[active]`); + } + + function queryMenuItem(pageName: string): HTMLElement|null { + return menu.shadowRoot!.querySelector<HTMLElement>( + `a.item[data-page-name='${pageName}']`); + } + + suiteSetup(async () => { + loadTimeData.overrideValues({ + isRevampWayfindingEnabled: true, + isKerberosEnabled: true, // Simulate kerberos page available + }); + + // Recreate routes and Router so Kerberos route exists + const testRoutes = createRoutesForTesting(); + Router.resetInstanceForTesting(new Router(testRoutes)); + + await createUi(); + }); + + suiteTeardown(() => { + ui.remove(); + Router.getInstance().resetRouteForTesting(); + }); + + test('Document body has feature class when feature flag is enabled', () => { + assertTrue(document.body.classList.contains('revamp-wayfinding-enabled')); + }); + + const pageNames = [ + 'apps', + 'bluetooth', + 'crostini', + 'dateTime', + 'device', + 'files', + 'internet', + 'kerberos', + 'multidevice', + 'osAccessibility', + 'osLanguages', + 'osPeople', + 'osPrinting', + 'osPrivacy', + 'osReset', + 'osSearch', + 'personalization', + ]; + for (const pageName of pageNames) { + test( + `Clicking menu item for ${pageName} page should show that page`, + async () => { + const pageReadyPromise = eventToPromise('show-container', window); + + const menuItem = queryMenuItem(pageName); + assert(menuItem); + menuItem.click(); + flush(); + + await pageReadyPromise; + + const activePages = queryActivePages(); + assertEquals(1, activePages.length); + + const page = activePages[0]; + assert(page); + assertEquals(pageName, page.section); + assertNotEquals('none', getComputedStyle(page).display); + }); + } +});
diff --git a/chrome/test/data/webui/settings/performance_page_test.ts b/chrome/test/data/webui/settings/performance_page_test.ts index 5e60d60..40cb4ab 100644 --- a/chrome/test/data/webui/settings/performance_page_test.ts +++ b/chrome/test/data/webui/settings/performance_page_test.ts
@@ -268,7 +268,8 @@ function assertExceptionListEquals(rules: string[], message?: string) { const actual = tabDiscardExceptionsList.$.list.items! .concat(tabDiscardExceptionsList.$.overflowList.items!) - .map(entry => entry.site); + .map(entry => entry.site) + .reverse(); assertDeepEquals(rules, actual, message); } @@ -283,9 +284,10 @@ } function getExceptionListEntry(idx: number): TabDiscardExceptionEntryElement { - const entry = [...tabDiscardExceptionsList.shadowRoot! - .querySelectorAll<TabDiscardExceptionEntryElement>( - 'tab-discard-exception-entry')][idx]; + const entries = [...tabDiscardExceptionsList.shadowRoot! + .querySelectorAll<TabDiscardExceptionEntryElement>( + 'tab-discard-exception-entry')]; + const entry = entries[entries.length - 1 - idx]; assertTrue(!!entry); return entry; } @@ -446,9 +448,7 @@ const addDialog = await getAddDialog(); assertTrue(addDialog.$.dialog.open); assertEquals('', addDialog.$.input.$.input.value); - const addExceptionEvent = eventToPromise('add-exception', addDialog); await inputDialog(addDialog, 'bar'); - await addExceptionEvent; assertEquals( HighEfficiencyModeExceptionListAction.ADD, await performanceMetricsProxy.whenCalled('recordExceptionListAction')); @@ -506,7 +506,7 @@ const newRule = `rule${TAB_DISCARD_EXCEPTIONS_OVERFLOW_SIZE + 1}`; const addDialog = await getAddDialog(); await inputDialog(addDialog, newRule); - assertTrue(tabDiscardExceptionsList.$.collapse.opened); + assertFalse(tabDiscardExceptionsList.$.collapse.opened); assertExceptionListEquals([...entries, newRule]); }); @@ -514,13 +514,17 @@ if (!loadTimeData.getBoolean('isDiscardExceptionsImprovementsEnabled')) { return; } - performanceBrowserProxy.setCurrentOpenSites([ - ...Array(3).keys(), - ].map(index => `rule${index}`)); + const existingEntry = 'www.foo.com'; + setupExceptionListEntries([existingEntry]); + const entries = [ + ...Array(TAB_DISCARD_EXCEPTIONS_OVERFLOW_SIZE).keys(), + ].map(index => `rule${index}`); + performanceBrowserProxy.setCurrentOpenSites(entries); tabDiscardExceptionsList.$.addButton.click(); flush(); const addDialog = await getTabbedAddDialog(); + await eventToPromise('iron-resize', addDialog); flush(); addDialog.$.list.$.list @@ -528,13 +532,12 @@ .forEach(checkboxElement => { checkboxElement.click(); }); - const addExceptionEvent = eventToPromise('add-exception', addDialog); assertFalse(addDialog.$.actionButton.disabled); addDialog.$.actionButton.click(); - await addExceptionEvent; flush(); - assertTrue(tabDiscardExceptionsList.$.collapse.opened); + assertEquals(false, tabDiscardExceptionsList.$.collapse.opened); + assertExceptionListEquals([existingEntry, ...entries]); }); test('testTabDiscardExceptionsListOverflowEdit', async function() {
diff --git a/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts b/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts index f63c8fa7..b7641ad 100644 --- a/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts +++ b/chrome/test/data/webui/settings/tab_discard_exception_dialog_test.ts
@@ -180,9 +180,7 @@ test('testTabDiscardExceptionsAddDialogSubmit', async function() { dialog = setupAddDialog(); await assertUserInputValidated(VALID_RULE); - const addExceptionEvent = eventToPromise('add-exception', dialog); assertSubmit([EXISTING_RULE, VALID_RULE]); - await addExceptionEvent; const action = await performanceMetricsProxy.whenCalled('recordExceptionListAction'); assertEquals(HighEfficiencyModeExceptionListAction.ADD, action); @@ -197,9 +195,7 @@ test('testTabDiscardExceptionsTabbedAddDialogSubmit', async function() { dialog = await setupTabbedAddDialog(); await assertUserInputValidated(VALID_RULE); - const addExceptionEvent = eventToPromise('add-exception', dialog); assertSubmit([EXISTING_RULE, VALID_RULE]); - await addExceptionEvent; const action = await performanceMetricsProxy.whenCalled('recordExceptionListAction'); assertEquals(HighEfficiencyModeExceptionListAction.ADD, action); @@ -269,9 +265,7 @@ getRulesListEntry(dialog, 2).click(); assertFalse(dialog.$.actionButton.disabled); getRulesListEntry(dialog, 4).click(); - const addExceptionEvent = eventToPromise('add-exception', dialog); assertSubmit([EXISTING_RULE, 'rule2', 'rule4']); - await addExceptionEvent; }); function switchAddDialogTab(
diff --git a/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts b/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts index 2a413cb..9643acb 100644 --- a/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts +++ b/chrome/test/data/webui/side_panel/customize_chrome/theme_snapshot_test.ts
@@ -95,8 +95,13 @@ CustomizeThemeType.CLASSIC_CHROME); assertEquals( $$<HTMLImageElement>( - themeSnapshotElement, '.snapshot-container #miniNewTabPage')! - .getAttribute('aria-labelledby'), + themeSnapshotElement, '#classicChromeBackground img')!.src, + 'chrome://customize-chrome-side-panel.top-chrome/icons/' + + 'mini_new_tab_page.svg'); + assertEquals( + $$<HTMLImageElement>( + themeSnapshotElement, + '#classicChromeBackground img')!.getAttribute('aria-labelledby'), 'classicChromeThemeTitle'); assertEquals( 'Classic Chrome', @@ -109,6 +114,32 @@ 'background-color', 'rgb(20, 83, 154)'); }); + test('gm3 classic chrome preview shows correct image', async () => { + // Arrange. + document.documentElement.toggleAttribute('chrome-refresh-2023', true); + createThemeSnapshotElement(); + const theme = createTheme(); + + // Act. + callbackRouterRemote.setTheme(theme); + await callbackRouterRemote.$.flushForTesting(); + + // Assert. + assertEquals(1, handler.getCallCount('updateTheme')); + const shownPages = + themeSnapshotElement.shadowRoot!.querySelectorAll('.iron-selected'); + assertTrue(!!shownPages); + assertEquals(shownPages.length, 1); + assertEquals( + shownPages[0]!.getAttribute('theme-type'), + CustomizeThemeType.CLASSIC_CHROME); + assertEquals( + $$<HTMLImageElement>( + themeSnapshotElement, '#classicChromeBackground img')!.src, + 'chrome://customize-chrome-side-panel.top-chrome/icons/' + + 'gm3_mini_new_tab_page.svg'); + }); + test('uploading a background updates theme snapshot', async () => { // Arrange. createThemeSnapshotElement();
diff --git a/chrome/test/webapps/PRESUBMIT.py b/chrome/test/webapps/PRESUBMIT.py index 0775a216..5a5892fd 100644 --- a/chrome/test/webapps/PRESUBMIT.py +++ b/chrome/test/webapps/PRESUBMIT.py
@@ -19,8 +19,6 @@ output_api, this_dir, files_to_check=['.*unittest.py$'], - env=None, - run_on_python2=False, - run_on_python3=True)) + env=None)) return results
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 2c7b119..8a772ef 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -110,8 +110,6 @@ int expected_exit_code) const = 0; virtual void ExpectLegacyPolicyStatusSucceeds() const = 0; virtual void RunUninstallCmdLine() const = 0; - virtual void SetUpTestService() const = 0; - virtual void TearDownTestService() const = 0; virtual void RunHandoff(const std::string& app_id) const = 0; #endif // BUILDFLAG(IS_WIN) virtual void StressUpdateService() const = 0;
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index 853094a91..ab5852c6 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -296,14 +296,6 @@ RunCommand("run_uninstall_cmd_line"); } - void SetUpTestService() const override { - updater::test::RunTestServiceCommand("setup"); - } - - void TearDownTestService() const override { - updater::test::RunTestServiceCommand("teardown"); - } - void RunHandoff(const std::string& app_id) const override { RunCommand("run_handoff", {Param("app_id", app_id)}); }
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index a6f708eb..832bd25 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -264,10 +264,6 @@ updater::test::RunUninstallCmdLine(updater_scope_); } - void SetUpTestService() const override {} - - void TearDownTestService() const override {} - void RunHandoff(const std::string& app_id) const override { updater::test::RunHandoff(updater_scope_, app_id); }
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index 118edaa2..a95f8a86 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -100,8 +100,6 @@ ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(Clean()); ASSERT_NO_FATAL_FAILURE(ExpectClean()); - // TODO(crbug.com/1233612) - reenable the code when system tests pass. - // SetUpTestService(); ASSERT_NO_FATAL_FAILURE(EnterTestMode(GURL("http://localhost:1234"), GURL("http://localhost:1235"), GURL("http://localhost:1236"))); @@ -139,9 +137,6 @@ DMCleanup(); - // TODO(crbug.com/1233612) - reenable the code when system tests pass. - // TearDownTestService(); - // Updater process must not be running for `Clean()` to succeed. ASSERT_TRUE(WaitForUpdaterExit()); Clean(); @@ -339,18 +334,6 @@ return test_commands_->WaitForUpdaterExit(); } - void SetUpTestService() { -#if BUILDFLAG(IS_WIN) - test_commands_->SetUpTestService(); -#endif // BUILDFLAG(IS_WIN) - } - - void TearDownTestService() { -#if BUILDFLAG(IS_WIN) - test_commands_->TearDownTestService(); -#endif // BUILDFLAG(IS_WIN) - } - void ExpectUpdateCheckSequence(ScopedServer* test_server, const std::string& app_id, UpdateService::Priority priority,
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index 6fffebcfc..de4ac77 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -211,7 +211,6 @@ const base::Value::List& parameters, int expected_exit_code); void ExpectLegacyPolicyStatusSucceeds(UpdaterScope scope); -void RunTestServiceCommand(const std::string& sub_command); // Calls a function defined in test/service/win/rpc_client.py. // Entries of the `arguments` dictionary should be the function's parameter
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc index 9fb5e208..7586a328 100644 --- a/chrome/updater/test/integration_tests_win.cc +++ b/chrome/updater/test/integration_tests_win.cc
@@ -1359,20 +1359,6 @@ return exit_code; } -void RunTestServiceCommand(const std::string& sub_command) { - base::FilePath path(base::CommandLine::ForCurrentProcess()->GetProgram()); - path = path.DirName(); - path = MakeAbsoluteFilePath(path); - path = path.Append(FILE_PATH_LITERAL("test_service")) - .Append(FILE_PATH_LITERAL("updater_test_service_control.py")); - EXPECT_TRUE(base::PathExists(path)); - - base::CommandLine command(path); - command.AppendArg(sub_command); - - EXPECT_EQ(RunVPythonCommand(command), 0); -} - void InvokeTestServiceFunction(const std::string& function_name, const base::Value::Dict& arguments) { std::string arguments_json_string; @@ -1714,7 +1700,7 @@ void UninstallApp(UpdaterScope scope, const std::string& app_id) { base::win::RegKey key; ASSERT_EQ( - key.Open(UpdaterScopeToHKeyRoot(scope), CLIENTS_KEY, Wow6432(KEY_WRITE)), + key.Open(UpdaterScopeToHKeyRoot(scope), CLIENTS_KEY, Wow6432(DELETE)), ERROR_SUCCESS); ASSERT_EQ(key.DeleteKey(base::SysUTF8ToWide(app_id).c_str()), ERROR_SUCCESS); }
diff --git a/chrome/updater/test/service/win/rpc_client.py b/chrome/updater/test/service/win/rpc_client.py index 42fefd4e..ac80fa9 100644 --- a/chrome/updater/test/service/win/rpc_client.py +++ b/chrome/updater/test/service/win/rpc_client.py
@@ -8,8 +8,6 @@ import sys import xmlrpc.client -# TODO(crbug.com/1233612): Query XML RPC server port once the server propgate -# the value. _UPDATER_XML_RPC_PORT = 9090 # Errors that might be raised when interacting with the RPC server.
diff --git a/chrome/updater/test/service/win/rpc_handler.py b/chrome/updater/test/service/win/rpc_handler.py index ba1cc4a..7bc8a210 100644 --- a/chrome/updater/test/service/win/rpc_handler.py +++ b/chrome/updater/test/service/win/rpc_handler.py
@@ -37,17 +37,13 @@ env=env, cwd=cwd) - # TODO(crbug.com/1233612): `communicate()` in Python 2.7 does not - # support timeout value, pass the value here once we migrate - # to Python 3. Also don't forget to handle subprocess.TimeoutExpired - # exception. - stdout, stderr = process.communicate() + stdout, stderr = process.communicate(timeout) logging.info('Command %s stdout:\n %s', command, stdout) if stderr: logging.error('Command %s stderr:\n %s', command, stderr) return (process.pid, process.returncode, stdout, stderr) - except OSError as err: + except (OSError, subprocess.TimeoutExpired) as err: logging.exception(err) return (None, None, None, None)
diff --git a/chrome/updater/test/service/win/updater_test_service.py b/chrome/updater/test/service/win/updater_test_service.py index 9a8adb3..c321d1e 100644 --- a/chrome/updater/test/service/win/updater_test_service.py +++ b/chrome/updater/test/service/win/updater_test_service.py
@@ -15,8 +15,13 @@ import rpc_handler -# TODO(crbug.com/1233612): Use portpick to choose an available port, and -# propagate the port to clients (for example, via a pre-defined registry key). +# Ideally we should pick an unused port instead of the hard-coded value. But a +# dynamic service port number means: +# 1. We need to bring dependencies on some python libraries, say portpicker. +# 2. We need to broadcast the port number to clients. +# 3. The port number probably changes every time the service is restarted. +# Those additional complexity seems outweigh the benefits it brings. And +# empirical results show that a pre-defined port works well enough. _XML_RPC_SERVER_PORT = 9090
diff --git a/chrome/updater/update_usage_stats_task_unittest.cc b/chrome/updater/update_usage_stats_task_unittest.cc index 531efbc..b2d449c 100644 --- a/chrome/updater/update_usage_stats_task_unittest.cc +++ b/chrome/updater/update_usage_stats_task_unittest.cc
@@ -68,9 +68,10 @@ #elif BUILDFLAG(IS_WIN) for (const auto& key_path : UsageStatsRegKeyPaths()) { LONG outcome = base::win::RegKey(UpdaterScopeToHKeyRoot(GetTestScope()), - key_path.c_str(), Wow6432(KEY_WRITE)) + key_path.c_str(), Wow6432(DELETE)) .DeleteKey(base::SysUTF8ToWide(app_id).c_str()); - ASSERT_TRUE(outcome == ERROR_SUCCESS || outcome == ERROR_FILE_NOT_FOUND); + ASSERT_TRUE(outcome == ERROR_SUCCESS || outcome == ERROR_FILE_NOT_FOUND || + outcome == ERROR_INVALID_HANDLE); } #endif }
diff --git a/chrome/updater/win/installer/BUILD.gn b/chrome/updater/win/installer/BUILD.gn index db6555e..1cda757 100644 --- a/chrome/updater/win/installer/BUILD.gn +++ b/chrome/updater/win/installer/BUILD.gn
@@ -33,6 +33,7 @@ "//chrome/updater:branding_header", "//chrome/updater:constants_prod", "//chrome/updater/win:tag_extractor", + "//third_party/abseil-cpp:absl", ] } @@ -120,6 +121,7 @@ ":version", "//build/win:default_exe_manifest", "//chrome/updater:base", + "//third_party/abseil-cpp:absl", ] } }
diff --git a/chrome/updater/win/installer/installer.cc b/chrome/updater/win/installer/installer.cc index 701b64b..15958e1 100644 --- a/chrome/updater/win/installer/installer.cc +++ b/chrome/updater/win/installer/installer.cc
@@ -22,6 +22,7 @@ // code size. #include "base/check.h" #include "base/command_line.h" +#include "base/files/file_enumerator.h" #include "base/files/file_path.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" @@ -163,6 +164,24 @@ return TRUE; } +absl::optional<base::FilePath> FindOfflineDir( + const base::FilePath& unpack_path) { + const base::FilePath base_offline_dir = + unpack_path.Append(L"bin").Append(L"Offline"); + if (!base::PathExists(base_offline_dir)) { + return absl::nullopt; + } + base::FileEnumerator file_enumerator(base_offline_dir, false, + base::FileEnumerator::DIRECTORIES); + for (base::FilePath path = file_enumerator.Next(); !path.empty(); + path = file_enumerator.Next()) { + if (IsGuid(path.BaseName().value())) { + return path; + } + } + return absl::nullopt; +} + // Finds and writes to disk resources of type 'B7' (7zip archive). Returns false // if there is a problem in writing any resource to disk. ProcessExitResult UnpackBinaryResources(const Configuration& configuration, @@ -434,6 +453,20 @@ ::SetProcessWorkingSetSize(::GetCurrentProcess(), static_cast<SIZE_T>(-1), static_cast<SIZE_T>(-1)); + // Determine if an offlinedir is embedded and, if it is, add an + // --offlinedir={GUID} switch to indicate that an offline install should + // be performed. + const absl::optional<base::FilePath> offline_dir = + FindOfflineDir(unpack_path); + if (offline_dir.has_value()) { + if (!cmd_line_args.append(L" --") || + !cmd_line_args.append(base::SysUTF8ToWide(kOfflineDirSwitch).c_str()) || + !cmd_line_args.append(L"=") || + !cmd_line_args.append(offline_dir->BaseName().value().c_str())) { + return ProcessExitResult(COMMAND_STRING_OVERFLOW); + } + } + PathString setup_path; if (!setup_path.assign(unpack_path.value().c_str()) || !setup_path.append(L"\\bin\\updater.exe")) {
diff --git a/chrome/updater/win/installer/installer.h b/chrome/updater/win/installer/installer.h index c10876574..fdbbfcd 100644 --- a/chrome/updater/win/installer/installer.h +++ b/chrome/updater/win/installer/installer.h
@@ -10,6 +10,11 @@ #include "base/command_line.h" #include "chrome/updater/win/installer/exit_code.h" #include "chrome/updater/win/installer/string.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace base { +class FilePath; +} // namespace base namespace updater { @@ -30,6 +35,9 @@ // (which is a path), plus a few extra arguments. using CommandString = StackString<MAX_PATH * 4>; +absl::optional<base::FilePath> FindOfflineDir( + const base::FilePath& unpack_path); + // Handles elevating the installer, waiting for the installer process, and // returning the resulting process exit code. ProcessExitResult HandleRunElevated(const base::CommandLine& command_line);
diff --git a/chrome/updater/win/installer/installer_unittest.cc b/chrome/updater/win/installer/installer_unittest.cc index b4a2827..68ac37e 100644 --- a/chrome/updater/win/installer/installer_unittest.cc +++ b/chrome/updater/win/installer/installer_unittest.cc
@@ -8,6 +8,8 @@ #include "base/command_line.h" #include "base/files/file_path.h" +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" #include "chrome/updater/constants.h" #include "chrome/updater/win/installer/exit_code.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,3 +32,25 @@ EXPECT_EQ(exit_result.exit_code, updater::UNABLE_TO_ELEVATE_METAINSTALLER); EXPECT_EQ(exit_result.windows_error, 0U); } + +TEST(InstallerTest, FindOfflineDir) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + base::FilePath unpack_path = temp_dir.GetPath(); + base::FilePath metainstall_dir = unpack_path.Append(L"bin"); + ASSERT_TRUE(base::CreateDirectory(metainstall_dir)); + + EXPECT_FALSE(updater::FindOfflineDir(unpack_path).has_value()); + + base::FilePath offline_install_dir = + metainstall_dir.Append(L"Offline") + .Append(L"{8D5D0563-F2A0-40E3-932D-AFEAE261A9D1}"); + ASSERT_TRUE(base::CreateDirectory(offline_install_dir)); + + absl::optional<base::FilePath> offline_dir = + updater::FindOfflineDir(unpack_path); + EXPECT_TRUE(offline_dir.has_value()); + EXPECT_EQ(offline_dir->BaseName(), + base::FilePath(L"{8D5D0563-F2A0-40E3-932D-AFEAE261A9D1}")); +}
diff --git a/chrome/updater/win/installer_api.cc b/chrome/updater/win/installer_api.cc index aa58dc9..d8cd105 100644 --- a/chrome/updater/win/installer_api.cc +++ b/chrome/updater/win/installer_api.cc
@@ -46,7 +46,8 @@ } base::win::RegKey key(UpdaterScopeToHKeyRoot(updater_scope), CLIENT_STATE_KEY, Wow6432(regsam)); - if (key.CreateKey(subkey.c_str(), Wow6432(regsam)) != ERROR_SUCCESS) { + if (!key.Valid() || + key.CreateKey(subkey.c_str(), Wow6432(regsam)) != ERROR_SUCCESS) { return absl::nullopt; } return key; @@ -99,6 +100,13 @@ kRegValueLastInstallerSuccessLaunchCmdLine); } +bool ClientStateAppKeyExists(UpdaterScope updater_scope, + const std::string& app_id) { + return base::win::RegKey(UpdaterScopeToHKeyRoot(updater_scope), + CLIENT_STATE_KEY, Wow6432(KEY_QUERY_VALUE)) + .Valid(); +} + } // namespace InstallerOutcome::InstallerOutcome() = default; @@ -115,7 +123,8 @@ } base::win::RegKey key(UpdaterScopeToHKeyRoot(updater_scope), CLIENT_STATE_KEY, Wow6432(regsam)); - if (key.OpenKey(subkey.c_str(), Wow6432(regsam)) != ERROR_SUCCESS) { + if (!key.Valid() || + key.OpenKey(subkey.c_str(), Wow6432(regsam)) != ERROR_SUCCESS) { return absl::nullopt; } return key; @@ -128,7 +137,7 @@ return false; } return base::win::RegKey(UpdaterScopeToHKeyRoot(updater_scope), - CLIENT_STATE_KEY, Wow6432(KEY_WRITE)) + CLIENT_STATE_KEY, Wow6432(DELETE)) .DeleteKey(subkey.c_str()) == ERROR_SUCCESS; } @@ -157,6 +166,9 @@ bool DeleteInstallerProgress(UpdaterScope updater_scope, const std::string& app_id) { + if (!ClientStateAppKeyExists(updater_scope, app_id)) { + return false; + } absl::optional<base::win::RegKey> key = ClientStateAppKeyOpen(updater_scope, app_id, KEY_SET_VALUE); return key && key->DeleteValue(kRegValueInstallerProgress) == ERROR_SUCCESS; @@ -164,6 +176,9 @@ bool DeleteInstallerOutput(UpdaterScope updater_scope, const std::string& app_id) { + if (!ClientStateAppKeyExists(updater_scope, app_id)) { + return false; + } absl::optional<base::win::RegKey> key = ClientStateAppKeyOpen( updater_scope, app_id, KEY_SET_VALUE | KEY_QUERY_VALUE); if (!key) {
diff --git a/chrome/updater/win/installer_api_unittest.cc b/chrome/updater/win/installer_api_unittest.cc index e448b4dd..72bc5de 100644 --- a/chrome/updater/win/installer_api_unittest.cc +++ b/chrome/updater/win/installer_api_unittest.cc
@@ -10,6 +10,7 @@ #include "base/test/test_reg_util_win.h" #include "base/win/registry.h" #include "chrome/updater/updater_scope.h" +#include "chrome/updater/util/win_util.h" #include "chrome/updater/win/win_constants.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -77,8 +78,8 @@ UpdaterScope::kSystem)); TEST_P(InstallerAPITest, InstallerProgress) { - ASSERT_NO_FATAL_FAILURE( - registry_override_.OverrideRegistry(HKEY_LOCAL_MACHINE)); + ASSERT_NO_FATAL_FAILURE(registry_override_.OverrideRegistry( + UpdaterScopeToHKeyRoot(updater_scope_))); ClientStateAppKeyDelete(updater_scope_, kAppId); EXPECT_EQ(GetInstallerProgress(updater_scope_, kAppId), -1); @@ -98,8 +99,8 @@ } TEST_P(InstallerAPITest, GetInstallerOutcome) { - ASSERT_NO_FATAL_FAILURE( - registry_override_.OverrideRegistry(HKEY_LOCAL_MACHINE)); + ASSERT_NO_FATAL_FAILURE(registry_override_.OverrideRegistry( + UpdaterScopeToHKeyRoot(updater_scope_))); ClientStateAppKeyDelete(updater_scope_, kAppId); @@ -272,4 +273,13 @@ } } +TEST_P(InstallerAPITest, ClientStateAppKeyOpen) { + ASSERT_NO_FATAL_FAILURE(registry_override_.OverrideRegistry( + UpdaterScopeToHKeyRoot(updater_scope_))); + EXPECT_FALSE( + ClientStateAppKeyOpen(updater_scope_, "invalid-app-id", KEY_READ)); + SetInstallerProgressForTesting(updater_scope_, kAppId, 0); + EXPECT_TRUE(ClientStateAppKeyOpen(updater_scope_, kAppId, KEY_READ)); +} + } // namespace updater
diff --git a/chrome/updater/win/manifest_util.cc b/chrome/updater/win/manifest_util.cc index f7292b1e..1416a5d 100644 --- a/chrome/updater/win/manifest_util.cc +++ b/chrome/updater/win/manifest_util.cc
@@ -85,7 +85,6 @@ } // namespace -// TODO(crbug/1409111): Handle errors for offline dir or manifest errors. void ReadInstallCommandFromManifest( const std::wstring& offline_dir_guid, const std::string& app_id,
diff --git a/chromecast/app/cast_test_launcher.cc b/chromecast/app/cast_test_launcher.cc index 9dba721..1685083b 100644 --- a/chromecast/app/cast_test_launcher.cc +++ b/chromecast/app/cast_test_launcher.cc
@@ -61,6 +61,6 @@ chromecast::shell::CastTestLauncherDelegate launcher_delegate; mojo::core::Init(); - content::ForceInProcessNetworkService(true); + content::ForceInProcessNetworkService(); return content::LaunchTests(&launcher_delegate, parallel_jobs, argc, argv); }
diff --git a/chromecast/metrics/cast_metrics_service_client_unittest.cc b/chromecast/metrics/cast_metrics_service_client_unittest.cc index 160b1c9..737662b 100644 --- a/chromecast/metrics/cast_metrics_service_client_unittest.cc +++ b/chromecast/metrics/cast_metrics_service_client_unittest.cc
@@ -63,26 +63,36 @@ FakeCastMetricsServiceDelegate delegate; CastMetricsServiceClient client(&delegate, nullptr, nullptr); + // Set arbitrary limits to ensure the limits propagate to the client + // correctly. ::metrics::MetricsLogStore::StorageLimits expected_limits = { - /*min_initial_log_queue_count=*/10, - /*min_initial_log_queue_size=*/2000, - /*min_ongoing_log_queue_count=*/30, - /*min_ongoing_log_queue_size=*/4000, - /*max_ongoing_log_size=*/5000, + .initial_log_queue_limits = + ::metrics::UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 10, + .min_queue_size_bytes = 2000, + }, + .ongoing_log_queue_limits = + ::metrics::UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 30, + .min_queue_size_bytes = 4000, + .max_log_size_bytes = 5000, + }, }; delegate.SetStorageLimits(expected_limits); ::metrics::MetricsLogStore::StorageLimits actual_limits = client.GetStorageLimits(); - EXPECT_EQ(actual_limits.min_initial_log_queue_count, - expected_limits.min_initial_log_queue_count); - EXPECT_EQ(actual_limits.min_initial_log_queue_size, - expected_limits.min_initial_log_queue_size); - EXPECT_EQ(actual_limits.min_ongoing_log_queue_count, - expected_limits.min_ongoing_log_queue_count); - EXPECT_EQ(actual_limits.min_ongoing_log_queue_size, - expected_limits.min_ongoing_log_queue_size); - EXPECT_EQ(actual_limits.max_ongoing_log_size, - expected_limits.max_ongoing_log_size); + EXPECT_EQ(actual_limits.initial_log_queue_limits.min_log_count, + expected_limits.initial_log_queue_limits.min_log_count); + EXPECT_EQ(actual_limits.initial_log_queue_limits.min_queue_size_bytes, + expected_limits.initial_log_queue_limits.min_queue_size_bytes); + EXPECT_EQ(actual_limits.initial_log_queue_limits.max_log_size_bytes, + expected_limits.initial_log_queue_limits.max_log_size_bytes); + EXPECT_EQ(actual_limits.ongoing_log_queue_limits.min_log_count, + expected_limits.ongoing_log_queue_limits.min_log_count); + EXPECT_EQ(actual_limits.ongoing_log_queue_limits.min_queue_size_bytes, + expected_limits.ongoing_log_queue_limits.min_queue_size_bytes); + EXPECT_EQ(actual_limits.ongoing_log_queue_limits.max_log_size_bytes, + expected_limits.ongoing_log_queue_limits.max_log_size_bytes); } } // namespace
diff --git a/chromeos/ash/components/language_packs/language_pack_manager.cc b/chromeos/ash/components/language_packs/language_pack_manager.cc index 182197d..c87da0a 100644 --- a/chromeos/ash/components/language_packs/language_pack_manager.cc +++ b/chromeos/ash/components/language_packs/language_pack_manager.cc
@@ -188,9 +188,11 @@ void OnInstallDlcComplete(OnInstallCompleteCallback callback, const std::string& feature_id, + const std::string& locale, const DlcserviceClient::InstallResult& dlc_result) { PackResult result; result.operation_error = dlc_result.error; + result.language_code = locale; const bool success = dlc_result.error == dlcservice::kErrorNone; if (success) { @@ -215,9 +217,11 @@ } void OnUninstallDlcComplete(OnUninstallCompleteCallback callback, + const std::string& locale, const std::string& err) { PackResult result; result.operation_error = err; + result.language_code = locale; const bool success = err == dlcservice::kErrorNone; if (success) { @@ -233,15 +237,18 @@ } void OnGetDlcState(GetPackStateCallback callback, + const std::string& locale, const std::string& err, const dlcservice::DlcState& dlc_state) { PackResult result; + if (err == dlcservice::kErrorNone) { result = ConvertDlcStateToPackResult(dlc_state); } else { result.pack_state = PackResult::UNKNOWN; } + result.language_code = locale; result.operation_error = err; std::move(callback).Run(result); @@ -285,7 +292,7 @@ } InstallDlc(*dlc_id, base::BindOnce(&OnInstallDlcComplete, std::move(callback), - feature_id)); + feature_id, locale)); } void LanguagePackManager::GetPackState(const std::string& feature_id, @@ -307,7 +314,7 @@ GetFeatureIdValueForUma(feature_id)); DlcserviceClient::Get()->GetDlcState( - *dlc_id, base::BindOnce(&OnGetDlcState, std::move(callback))); + *dlc_id, base::BindOnce(&OnGetDlcState, std::move(callback), locale)); } void LanguagePackManager::RemovePack(const std::string& feature_id, @@ -324,7 +331,8 @@ } DlcserviceClient::Get()->Uninstall( - *dlc_id, base::BindOnce(&OnUninstallDlcComplete, std::move(callback))); + *dlc_id, + base::BindOnce(&OnUninstallDlcComplete, std::move(callback), locale)); } void LanguagePackManager::InstallBasePack( @@ -344,7 +352,7 @@ GetFeatureIdValueForUma(feature_id)); InstallDlc(*dlc_id, base::BindOnce(&OnInstallDlcComplete, std::move(callback), - feature_id)); + feature_id, "")); } void LanguagePackManager::UpdatePacksForOobe(const std::string& locale) { @@ -362,7 +370,7 @@ if (dlc_id) { InstallDlc(*dlc_id, base::BindOnce(&OnInstallDlcComplete, base::DoNothing(), - kTtsFeatureId)); + kTtsFeatureId, locale)); } }
diff --git a/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc b/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc index e6a50d27..9e0fe62 100644 --- a/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc +++ b/chromeos/ash/components/language_packs/language_pack_manager_unittest.cc
@@ -142,6 +142,7 @@ EXPECT_EQ(pack_result_.operation_error, dlcservice::kErrorNone); EXPECT_EQ(pack_result_.pack_state, PackResult::INSTALLED); EXPECT_EQ(pack_result_.path, "/path"); + EXPECT_EQ(pack_result_.language_code, kSupportedLocale); // Test UMA metrics: post-condition. histogram_tester.ExpectBucketCount( @@ -227,6 +228,7 @@ EXPECT_EQ(pack_result_.operation_error, dlcservice::kErrorNone); EXPECT_EQ(pack_result_.pack_state, PackResult::INSTALLED); EXPECT_EQ(pack_result_.path, "/path"); + EXPECT_EQ(pack_result_.language_code, kSupportedLocale); // Test UMA metrics: post-condition. histogram_tester.ExpectBucketCount(kHistogramGetPackStateFeatureId, @@ -301,6 +303,7 @@ EXPECT_EQ(pack_result_.operation_error, dlcservice::kErrorNone); EXPECT_EQ(pack_result_.pack_state, PackResult::NOT_INSTALLED); + EXPECT_EQ(pack_result_.language_code, kSupportedLocale); // Test UMA metrics: post-condition. histogram_tester.ExpectBucketCount(kHistogramUninstallCompleteSuccess,
diff --git a/chromeos/ash/components/scalable_iph/BUILD.gn b/chromeos/ash/components/scalable_iph/BUILD.gn new file mode 100644 index 0000000..f55aa15f --- /dev/null +++ b/chromeos/ash/components/scalable_iph/BUILD.gn
@@ -0,0 +1,20 @@ +# 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. + +import("//build/config/chromeos/ui_mode.gni") + +assert(is_chromeos_ash) + +source_set("scalable_iph") { + sources = [ + "scalable_iph.cc", + "scalable_iph.h", + ] + + deps = [ + "//base", + "//components/feature_engagement/public", + "//components/keyed_service/core", + ] +}
diff --git a/chromeos/ash/components/scalable_iph/COMMON_METADATA b/chromeos/ash/components/scalable_iph/COMMON_METADATA new file mode 100644 index 0000000..54955ea7 --- /dev/null +++ b/chromeos/ash/components/scalable_iph/COMMON_METADATA
@@ -0,0 +1,5 @@ +os: CHROME_OS + +buganizer { + component_id: 905229 +}
diff --git a/chromeos/ash/components/scalable_iph/DEPS b/chromeos/ash/components/scalable_iph/DEPS new file mode 100644 index 0000000..743278b --- /dev/null +++ b/chromeos/ash/components/scalable_iph/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+components/feature_engagement/public", + "+components/keyed_service/core", +]
diff --git a/chromeos/ash/components/scalable_iph/DIR_METADATA b/chromeos/ash/components/scalable_iph/DIR_METADATA new file mode 100644 index 0000000..bf1496c --- /dev/null +++ b/chromeos/ash/components/scalable_iph/DIR_METADATA
@@ -0,0 +1 @@ +mixins: "//chromeos/ash/components/scalable_iph/COMMON_METADATA"
diff --git a/chromeos/ash/components/scalable_iph/OWNERS b/chromeos/ash/components/scalable_iph/OWNERS new file mode 100644 index 0000000..157b326 --- /dev/null +++ b/chromeos/ash/components/scalable_iph/OWNERS
@@ -0,0 +1,4 @@ +angelaxiao@chromium.org +wutao@chromium.org +xiaohuic@chromium.org +yawano@google.com \ No newline at end of file
diff --git a/chromeos/ash/components/scalable_iph/scalable_iph.cc b/chromeos/ash/components/scalable_iph/scalable_iph.cc new file mode 100644 index 0000000..d6ce4d29 --- /dev/null +++ b/chromeos/ash/components/scalable_iph/scalable_iph.cc
@@ -0,0 +1,96 @@ +// 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/ash/components/scalable_iph/scalable_iph.h" + +#include "base/no_destructor.h" + +namespace scalable_iph { + +namespace { + +constexpr char kFunctionCallAfterKeyedServiceShutdown[] = + "Function call after keyed service shutdown."; + +const std::map<ScalableIph::Event, std::string>& GetEventNamesMap() { + // IPH events are put in a global namespace. Prefix with ScalableIph for all + // events. + static const base::NoDestructor<std::map<ScalableIph::Event, std::string>> + event_names_map( + {{ScalableIph::Event::kFiveMinTick, "ScalableIphFiveMinTick"}}); + return *event_names_map; +} + +// The list of IPH features `SclableIph` supports. `ScalableIph` checks trigger +// conditions of all events listed in this list when it receives an `Event`. +const std::vector<const base::Feature*>& GetFeatureList() { + static const base::NoDestructor<std::vector<const base::Feature*>> + feature_list({}); + return *feature_list; +} + +} // namespace + +ScalableIph::ScalableIph(feature_engagement::Tracker* tracker) + : tracker_(tracker) { + CHECK(tracker_); +} + +ScalableIph::~ScalableIph() = default; + +void ScalableIph::Shutdown() { + tracker_ = nullptr; +} + +void ScalableIph::RecordEvent(ScalableIph::Event event) { + if (!tracker_) { + DCHECK(false) << kFunctionCallAfterKeyedServiceShutdown; + return; + } + + // `AddOnInitializedCallback` immediately calls the callback if it's already + // initialized. + tracker_->AddOnInitializedCallback( + base::BindOnce(&ScalableIph::RecordEventInternal, + weak_ptr_factory_.GetWeakPtr(), event)); +} + +void ScalableIph::RecordEventInternal(ScalableIph::Event event, + bool init_success) { + if (!tracker_) { + DCHECK(false) << kFunctionCallAfterKeyedServiceShutdown; + return; + } + + if (!init_success) { + DCHECK(false) << "Failed to initialize feature_engagement::Tracker."; + return; + } + + auto it = GetEventNamesMap().find(event); + if (it == GetEventNamesMap().end()) { + DCHECK(false) << "Missing ScalableIph::Event to event name string mapping."; + return; + } + + tracker_->NotifyEvent(it->second); + + CheckTriggerConditions(); +} + +void ScalableIph::CheckTriggerConditions() { + // Make sure that `tracker_` is initialized. `tracker_` should not cause crash + // even if we call `ShouldTriggerHelpUI` before initialization. But it returns + // false. It can become a difficult to notice/debug bug if we accidentally + // introduce a code path where we call it before initialization. + DCHECK(tracker_->IsInitialized()); + + for (const base::Feature* feature : GetFeatureList()) { + if (tracker_->ShouldTriggerHelpUI(*feature)) { + // TODO(b/284053005): Call the UI framework to trigger a help UI. + } + } +} + +} // namespace scalable_iph
diff --git a/chromeos/ash/components/scalable_iph/scalable_iph.h b/chromeos/ash/components/scalable_iph/scalable_iph.h new file mode 100644 index 0000000..bab8662 --- /dev/null +++ b/chromeos/ash/components/scalable_iph/scalable_iph.h
@@ -0,0 +1,39 @@ +// 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_ASH_COMPONENTS_SCALABLE_IPH_SCALABLE_IPH_H_ +#define CHROMEOS_ASH_COMPONENTS_SCALABLE_IPH_SCALABLE_IPH_H_ + +#include "base/memory/weak_ptr.h" +#include "components/feature_engagement/public/tracker.h" +#include "components/keyed_service/core/keyed_service.h" + +namespace scalable_iph { + +class ScalableIph : public KeyedService { + public: + // List of events ScalableIph supports. + enum Event { kFiveMinTick }; + + explicit ScalableIph(feature_engagement::Tracker* tracker); + + void RecordEvent(Event event); + + // KeyedService: + ~ScalableIph() override; + void Shutdown() override; + + private: + void RecordEventInternal(Event event, bool init_success); + void CheckTriggerConditions(); + void TriggerIph(const base::Feature& feature); + + raw_ptr<feature_engagement::Tracker> tracker_; + + base::WeakPtrFactory<ScalableIph> weak_ptr_factory_{this}; +}; + +} // namespace scalable_iph + +#endif // CHROMEOS_ASH_COMPONENTS_SCALABLE_IPH_SCALABLE_IPH_H_
diff --git a/chromeos/chromeos_strings.grd b/chromeos/chromeos_strings.grd index 4479b7a..f628519 100644 --- a/chromeos/chromeos_strings.grd +++ b/chromeos/chromeos_strings.grd
@@ -2747,6 +2747,36 @@ <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_CHANGE_WALLPAPER_ALT2" desc="Text for search result item which, when clicked, navigates the user to wallpaper settings. Alternate phrase for: 'Change wallpaper', 'Background'"> Desktop </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER" desc="Text for search result item which, when clicked, navigates the user to time of day wallpaper settings. Alternate phrase for: 'Time of day wallpaper'"> + <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph> exclusive wallpaper + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT1" desc="Text for search result item which, when clicked, navigates the user to time of day wallpaper settings. Alternate phrase for: 'Time of day wallpaper'"> + Dawn to dark wallpaper + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT2" desc="Text for search result item which, when clicked, navigates the user to time of day wallpaper settings. Alternate phrase for: 'Time of day wallpaper'"> + Cloud flow wallpaper + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT3" desc="Text for search result item which, when clicked, navigates the user to time of day wallpaper settings. Alternate phrase for: 'Time of day wallpaper'"> + Earth flow wallpaper + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT4" desc="Text for search result item which, when clicked, navigates the user to time of day wallpaper settings. Alternate phrase for: 'Time of day wallpaper'"> + Sunrise wallpaper + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT5" desc="Text for search result item which, when clicked, navigates the user to time of day wallpaper settings. Alternate phrase for: 'Time of day wallpaper'"> + Sunset wallpaper + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY" desc="Text for search result item which, when clicked, navigates the user to time of day ambient mode settings, which allow the user to set special video backgrounds to be displayed when the device is idle. Alternate phrase for: 'Time of day screen saver'"> + <ph name="PRODUCT_NAME">$1<ex>Chromebook</ex></ph> exclusive screen saver + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT1" desc="Text for search result item which, when clicked, navigates the user to time of day ambient mode settings, which allow the user to set special video backgrounds to be displayed when the device is idle. Alternate phrase for: 'Time of day screen saver'"> + Dawn to dark screen saver + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT2" desc="Text for search result item which, when clicked, navigates the user to time of day ambient mode settings, which allow the user to set special video backgrounds to be displayed when the device is idle. Alternate phrase for: 'Time of day screen saver'"> + Cloud flow screen saver + </message> + <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT3" desc="Text for search result item which, when clicked, navigates the user to time of day ambient mode settings, which allow the user to set special video backgrounds to be displayed when the device is idle. Alternate phrase for: 'Time of day screen saver'"> + Earth flow screen saver + </message> <message name="IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE" desc="Text for search result item which, when clicked, navigates the user to ambient mode settings, which allow the user to set backgrounds to be displayed when the device is idle."> Screen saver </message>
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY.png.sha1 new file mode 100644 index 0000000..df77ad3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY.png.sha1
@@ -0,0 +1 @@ +c5b778ad16a65608275e73058f76e083b29d8e09 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT1.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT1.png.sha1 new file mode 100644 index 0000000..2f0236bb --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT1.png.sha1
@@ -0,0 +1 @@ +1ff5d1547dce8a334ea80ef1b787b7c0aeabb086 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT2.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT2.png.sha1 new file mode 100644 index 0000000..25a71158 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT2.png.sha1
@@ -0,0 +1 @@ +1d54b9c8f47751ff7d72d532d8534d91635df60a \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT3.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT3.png.sha1 new file mode 100644 index 0000000..03893be --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_AMBIENT_MODE_TIME_OF_DAY_ALT3.png.sha1
@@ -0,0 +1 @@ +294f55459399a7a7f1d07b5b7c6c1c623e96c6e4 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER.png.sha1 new file mode 100644 index 0000000..df77ad3 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER.png.sha1
@@ -0,0 +1 @@ +c5b778ad16a65608275e73058f76e083b29d8e09 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT1.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT1.png.sha1 new file mode 100644 index 0000000..2f0236bb --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT1.png.sha1
@@ -0,0 +1 @@ +1ff5d1547dce8a334ea80ef1b787b7c0aeabb086 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT2.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT2.png.sha1 new file mode 100644 index 0000000..25a71158 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT2.png.sha1
@@ -0,0 +1 @@ +1d54b9c8f47751ff7d72d532d8534d91635df60a \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT3.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT3.png.sha1 new file mode 100644 index 0000000..03893be --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT3.png.sha1
@@ -0,0 +1 @@ +294f55459399a7a7f1d07b5b7c6c1c623e96c6e4 \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT4.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT4.png.sha1 new file mode 100644 index 0000000..f3ca1a9 --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT4.png.sha1
@@ -0,0 +1 @@ +cee95fd60d1126cf56c0a627f2a176ff9f13748a \ No newline at end of file
diff --git a/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT5.png.sha1 b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT5.png.sha1 new file mode 100644 index 0000000..ece7dda --- /dev/null +++ b/chromeos/chromeos_strings_grd/IDS_PERSONALIZATION_APP_SEARCH_RESULT_TIME_OF_DAY_WALLPAPER_ALT5.png.sha1
@@ -0,0 +1 @@ +54b230ee74375be2d5d9ff884a284a84e64f373e \ No newline at end of file
diff --git a/chromeos/components/kcer/BUILD.gn b/chromeos/components/kcer/BUILD.gn index b3d084c..79bd809b 100644 --- a/chromeos/components/kcer/BUILD.gn +++ b/chromeos/components/kcer/BUILD.gn
@@ -13,6 +13,8 @@ "kcer.h", "kcer_impl.cc", "kcer_impl.h", + "kcer_notifier_net.cc", + "kcer_notifier_net.h", "kcer_token.h", "token_key_finder.cc", "token_key_finder.h",
diff --git a/chromeos/components/kcer/kcer_impl.cc b/chromeos/components/kcer/kcer_impl.cc index ba2a1d4..ba10714 100644 --- a/chromeos/components/kcer/kcer_impl.cc +++ b/chromeos/components/kcer/kcer_impl.cc
@@ -30,14 +30,17 @@ base::WeakPtr<KcerToken> device_token) : token_task_runner_(std::move(token_task_runner)), user_token_(std::move(user_token)), - device_token_(std::move(device_token)) {} + device_token_(std::move(device_token)) { + if (user_token_.MaybeValid() || device_token_.MaybeValid()) { + notifier_.Initialize(); + } +} KcerImpl::~KcerImpl() = default; base::CallbackListSubscription KcerImpl::AddObserver( base::RepeatingClosure callback) { - // TODO(244408716): Implement. - return {}; + return notifier_.AddObserver(std::move(callback)); } void KcerImpl::GenerateRsaKey(Token token,
diff --git a/chromeos/components/kcer/kcer_impl.h b/chromeos/components/kcer/kcer_impl.h index 123ecb6..95d90c2 100644 --- a/chromeos/components/kcer/kcer_impl.h +++ b/chromeos/components/kcer/kcer_impl.h
@@ -17,6 +17,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/task_runner.h" #include "chromeos/components/kcer/kcer.h" +#include "chromeos/components/kcer/kcer_notifier_net.h" #include "chromeos/components/kcer/kcer_token.h" #include "net/cert/x509_certificate.h" @@ -161,8 +162,7 @@ // very limited way (consult documentation for WeakPtr for details). base::WeakPtr<KcerToken> user_token_; base::WeakPtr<KcerToken> device_token_; - - base::RepeatingCallbackList<void()> observers_; + KcerNotifierNet notifier_; base::WeakPtrFactory<KcerImpl> weak_factory_{this}; };
diff --git a/chromeos/components/kcer/kcer_notifier_net.cc b/chromeos/components/kcer/kcer_notifier_net.cc new file mode 100644 index 0000000..530c975 --- /dev/null +++ b/chromeos/components/kcer/kcer_notifier_net.cc
@@ -0,0 +1,29 @@ +// 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/components/kcer/kcer_notifier_net.h" +#include "base/callback_list.h" + +namespace kcer::internal { + +KcerNotifierNet::KcerNotifierNet() = default; + +KcerNotifierNet::~KcerNotifierNet() { + net::CertDatabase::GetInstance()->RemoveObserver(this); +} + +void KcerNotifierNet::Initialize() { + net::CertDatabase::GetInstance()->AddObserver(this); +} + +base::CallbackListSubscription KcerNotifierNet::AddObserver( + base::RepeatingClosure callback) { + return observers_.Add(std::move(callback)); +} + +void KcerNotifierNet::OnCertDBChanged() { + observers_.Notify(); +} + +} // namespace kcer::internal
diff --git a/chromeos/components/kcer/kcer_notifier_net.h b/chromeos/components/kcer/kcer_notifier_net.h new file mode 100644 index 0000000..fb6ed8a0 --- /dev/null +++ b/chromeos/components/kcer/kcer_notifier_net.h
@@ -0,0 +1,38 @@ +// 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_COMPONENTS_KCER_KCER_NOTIFIER_NET_H_ +#define CHROMEOS_COMPONENTS_KCER_KCER_NOTIFIER_NET_H_ + +#include "base/callback_list.h" +#include "net/cert/cert_database.h" + +namespace kcer::internal { + +// A helper class that implements notifications for Kcer. This implementation +// just listens to the notifications from net::CertDatabase and forwards them to +// the observers. +// In the future this is planned to be replaced by listening to notifications +// from Chaps. KcerToken-s will receive notifications related to them and +// forward them to KcerImpl to notify the observers. +class KcerNotifierNet : public net::CertDatabase::Observer { + public: + KcerNotifierNet(); + ~KcerNotifierNet() override; + + // Starts observing the notifications from net::CertDatabase. + void Initialize(); + + base::CallbackListSubscription AddObserver(base::RepeatingClosure callback); + + // Implements net::CertDatabase::Observer + void OnCertDBChanged() override; + + private: + base::RepeatingCallbackList<void()> observers_; +}; + +} // namespace kcer::internal + +#endif // CHROMEOS_COMPONENTS_KCER_KCER_NOTIFIER_NET_H_
diff --git a/chromeos/crosapi/mojom/BUILD.gn b/chromeos/crosapi/mojom/BUILD.gn index 8c09d1d..08636f1 100644 --- a/chromeos/crosapi/mojom/BUILD.gn +++ b/chromeos/crosapi/mojom/BUILD.gn
@@ -267,20 +267,20 @@ ] traits_headers = [ "//chromeos/crosapi/mojom/app_service_types_mojom_traits.h", - "//chromeos/crosapi/mojom/cert_database_mojom_traits.h", - "//chromeos/crosapi/mojom/policy_namespace_mojom_traits.h", - "//chromeos/crosapi/mojom/policy_domain_mojom_traits.h", - "//chromeos/crosapi/mojom/desk_template_mojom_traits.h", - "//chromeos/crosapi/mojom/web_app_types_mojom_traits.h", - "//chromeos/crosapi/mojom/desk_mojom_traits.h", "//chromeos/crosapi/mojom/browser_app_instance_registry_mojom_traits.h", + "//chromeos/crosapi/mojom/cert_database_mojom_traits.h", + "//chromeos/crosapi/mojom/desk_mojom_traits.h", + "//chromeos/crosapi/mojom/desk_template_mojom_traits.h", + "//chromeos/crosapi/mojom/policy_domain_mojom_traits.h", + "//chromeos/crosapi/mojom/policy_namespace_mojom_traits.h", + "//chromeos/crosapi/mojom/sharesheet_mojom_traits.h", "//chromeos/crosapi/mojom/ui_constants_mojom_traits.h", + "//chromeos/crosapi/mojom/web_app_types_mojom_traits.h", "//components/services/app_service/public/cpp/app_launch_util.h", "//components/services/app_service/public/cpp/app_types.h", "//components/services/app_service/public/cpp/capability_access.h", - "//components/services/app_service/public/cpp/preferred_app.h", - "//chromeos/crosapi/mojom/sharesheet_mojom_traits.h", "//components/services/app_service/public/cpp/icon_types.h", + "//components/services/app_service/public/cpp/preferred_app.h", ] traits_sources = [ "//chromeos/crosapi/mojom/app_service_types_mojom_traits.cc",
diff --git a/components/PRESUBMIT.py b/components/PRESUBMIT.py index d7d4f1a..575bc2da 100644 --- a/components/PRESUBMIT.py +++ b/components/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def CheckChangeOnUpload(input_api, output_api): return _CommonChecks(input_api, output_api)
diff --git a/components/android_autofill/PRESUBMIT.py b/components/android_autofill/PRESUBMIT.py index a4694057..bd8120c 100644 --- a/components/android_autofill/PRESUBMIT.py +++ b/components/android_autofill/PRESUBMIT.py
@@ -8,7 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' def IsComponentsAndroidAutofillFile(f, name_suffix):
diff --git a/components/android_autofill/browser/BUILD.gn b/components/android_autofill/browser/BUILD.gn index 435b49b..248b469 100644 --- a/components/android_autofill/browser/BUILD.gn +++ b/components/android_autofill/browser/BUILD.gn
@@ -30,12 +30,12 @@ ] annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ] sources = [ - "java/src/org/chromium/components/autofill/AutofillActionModeCallback.java", "java/src/org/chromium/components/autofill/AutofillHintsService.java", "java/src/org/chromium/components/autofill/AutofillManagerWrapper.java", "java/src/org/chromium/components/autofill/AutofillProvider.java", "java/src/org/chromium/components/autofill/AutofillProviderUMA.java", "java/src/org/chromium/components/autofill/AutofillRequest.java", + "java/src/org/chromium/components/autofill/AutofillSelectionMenuItemProvider.java", "java/src/org/chromium/components/autofill/FormData.java", "java/src/org/chromium/components/autofill/FormFieldData.java", "java/src/org/chromium/components/autofill_public/ViewType.java",
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java deleted file mode 100644 index 9de74924..0000000 --- a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillActionModeCallback.java +++ /dev/null
@@ -1,64 +0,0 @@ -// Copyright 2017 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.components.autofill; - -import android.content.Context; -import android.os.Build; -import android.view.ActionMode; -import android.view.Menu; -import android.view.MenuItem; - -/** - * The class to implement autofill context menu. To match the Android native view behavior, the - * autofill context menu only appears when there is no text selected. - */ -public class AutofillActionModeCallback implements ActionMode.Callback { - private final Context mContext; - private final AutofillProvider mAutofillProvider; - private final int mAutofillMenuItemTitle; - - // using getIdentifier to work around not-exposed framework resource ID - @SuppressWarnings("DiscouragedApi") - public AutofillActionModeCallback(Context context, AutofillProvider autofillProvider) { - mContext = context; - mAutofillProvider = autofillProvider; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { - mAutofillMenuItemTitle = android.R.string.autofill; - } else { - // The string resource was not made public until O MR1, so on O we look it up by name. - mAutofillMenuItemTitle = - mContext.getResources().getIdentifier("autofill", "string", "android"); - } - } - - @Override - public boolean onCreateActionMode(ActionMode mode, Menu menu) { - return mAutofillMenuItemTitle != 0; - } - - @Override - public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - if (mAutofillMenuItemTitle != 0 && mAutofillProvider.shouldQueryAutofillSuggestion()) { - MenuItem item = menu.add(Menu.NONE, android.R.id.autofill, Menu.CATEGORY_SECONDARY, - mAutofillMenuItemTitle); - item.setShowAsActionFlags( - MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT); - } - return true; - } - - @Override - public boolean onActionItemClicked(ActionMode mode, MenuItem item) { - if (item.getItemId() == android.R.id.autofill) { - mAutofillProvider.queryAutofillSuggestion(); - mode.finish(); - return true; - } - return false; - } - - @Override - public void onDestroyActionMode(ActionMode mode) {} -}
diff --git a/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillSelectionMenuItemProvider.java b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillSelectionMenuItemProvider.java new file mode 100644 index 0000000..1f41edc --- /dev/null +++ b/components/android_autofill/browser/java/src/org/chromium/components/autofill/AutofillSelectionMenuItemProvider.java
@@ -0,0 +1,62 @@ +// 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. + +package org.chromium.components.autofill; + +import android.content.Context; +import android.os.Build; +import android.view.Menu; +import android.view.MenuItem; + +import org.chromium.content_public.browser.AdditionalSelectionMenuItemProvider; +import org.chromium.content_public.browser.SelectionMenuItem; + +import java.util.ArrayList; +import java.util.List; + +/** + * The class to provide autofill selection context menu items. To match the Android native view + * behavior, the autofill context menu only appears when there is no text selected. + */ +public class AutofillSelectionMenuItemProvider implements AdditionalSelectionMenuItemProvider { + private final AutofillProvider mAutofillProvider; + private final int mAutofillMenuItemTitle; + + // using getIdentifier to work around not-exposed framework resource ID + @SuppressWarnings("DiscouragedApi") + public AutofillSelectionMenuItemProvider(Context context, AutofillProvider autofillProvider) { + mAutofillProvider = autofillProvider; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { + mAutofillMenuItemTitle = android.R.string.autofill; + } else { + // The string resource was not made public until O MR1, so on O we look it up by name. + mAutofillMenuItemTitle = + context.getResources().getIdentifier("autofill", "string", "android"); + } + } + + @Override + public List<SelectionMenuItem> getItems() { + List<SelectionMenuItem> autofillItems = new ArrayList<>(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (mAutofillMenuItemTitle != 0 && mAutofillProvider.shouldQueryAutofillSuggestion()) { + SelectionMenuItem autofillItem = + new SelectionMenuItem.Builder(mAutofillMenuItemTitle) + .setId(android.R.id.autofill) + .setOrderInCategory(Menu.CATEGORY_SECONDARY) + .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_NEVER + | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setClickListener(v -> mAutofillProvider.queryAutofillSuggestion()) + .build(); + autofillItems.add(autofillItem); + } + } + return autofillItems; + } + + @Override + public void onMenuDestroyed() { + // no-op + } +}
diff --git a/components/arc/PRESUBMIT.py b/components/arc/PRESUBMIT.py index ce427fd..bcfcc18 100644 --- a/components/arc/PRESUBMIT.py +++ b/components/arc/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def CheckChangeOnUpload(input_api, output_api): results = [] results += input_api.canned_checks.CheckChangeLintsClean(
diff --git a/components/autofill/PRESUBMIT.py b/components/autofill/PRESUBMIT.py index 2ff5967..d147679 100644 --- a/components/autofill/PRESUBMIT.py +++ b/components/autofill/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def IsComponentsAutofillFile(f, name_suffix): # The exact path can change. Only check the containing folder. return (f.LocalPath().startswith('components/autofill/') and
diff --git a/components/autofill/content/browser/PRESUBMIT.py b/components/autofill/content/browser/PRESUBMIT.py index 96532be4..d9de507 100644 --- a/components/autofill/content/browser/PRESUBMIT.py +++ b/components/autofill/content/browser/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - """Chromium presubmit script to check that BadMessage enums in histograms.xml match the corresponding bad_message.h file. """
diff --git a/components/autofill/content/renderer/PRESUBMIT.py b/components/autofill/content/renderer/PRESUBMIT.py index f3f71d78..09d6bf1 100644 --- a/components/autofill/content/renderer/PRESUBMIT.py +++ b/components/autofill/content/renderer/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def _CheckNoDirectPasswordCalls(input_api, output_api): """Checks that no files call IsPasswordField() or FormControlType().""" pattern = input_api.re.compile(
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn index 609ca7d..ed39597 100644 --- a/components/autofill/core/browser/BUILD.gn +++ b/components/autofill/core/browser/BUILD.gn
@@ -1098,6 +1098,10 @@ "//third_party/blink/public/common", ] } + + if (is_ios) { + deps += [ "//base/ios" ] + } } fuzzer_test("form_structure_fuzzer") {
diff --git a/components/autofill/core/browser/autofill_suggestion_generator.cc b/components/autofill/core/browser/autofill_suggestion_generator.cc index 99fa51c..373ef04 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator.cc
@@ -74,9 +74,19 @@ } int GetObfuscationLength() { - // The obfuscation length is 2 for the Android keyboard accessory. It is 4 for - // other platforms. +#if BUILDFLAG(IS_ANDROID) + // On Android, the obfuscation length is 2 when the Android keyboard + // accessory is enabled (though this length applies to all Suggestions + // created for Android). return IsKeyboardAccessoryEnabled() ? 2 : 4; +#elif BUILDFLAG(IS_IOS) + return base::FeatureList::IsEnabled( + features::kAutofillUseTwoDotsForLastFourDigits) + ? 2 + : 4; +#else + return 4; +#endif } bool ShouldSplitCardNameAndLastFourDigits() { @@ -592,7 +602,8 @@ } #if BUILDFLAG(IS_IOS) - // On iOS, the label is formatted as "••••1234". + // On iOS, the label is formatted as either "••••1234" or "••1234", depending + // on the obfuscation length. return { Suggestion::Text(credit_card.ObfuscatedNumberWithVisibleLastFourDigits( GetObfuscationLength()))};
diff --git a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc index fed6cef..904eef8 100644 --- a/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/autofill_suggestion_generator_unittest.cc
@@ -811,6 +811,19 @@ #endif } +#if BUILDFLAG(IS_IOS) + // Return the obfuscation length for the last four digits on iOS. + // Although this depends on the kAutofillUseTwoDotsForLastFourDigits flag, + // that flag is not tested explicitly by this test; see + // AutofillCreditCardSuggestionIOSObfuscationLengthContentTest instead. + int ios_obfuscation_length() const { + return base::FeatureList::IsEnabled( + features::kAutofillUseTwoDotsForLastFourDigits) + ? 2 + : 4; + } +#endif + private: #if BUILDFLAG(IS_ANDROID) bool keyboard_accessory_enabled_; @@ -851,12 +864,13 @@ #if BUILDFLAG(IS_IOS) // There should be 2 lines of labels: - // 1. Obfuscated last 4 digits "....1111". + // 1. Obfuscated last 4 digits "..1111" or "....1111". // 2. Virtual card label. ASSERT_EQ(virtual_card_name_field_suggestion.labels.size(), 2U); ASSERT_EQ(virtual_card_name_field_suggestion.labels[0].size(), 1U); EXPECT_EQ(virtual_card_name_field_suggestion.labels[0][0].value, - internal::GetObfuscatedStringForCardDigits(u"1111", 4)); + internal::GetObfuscatedStringForCardDigits( + u"1111", ios_obfuscation_length())); #else if (keyboard_accessory_enabled()) { // There should be only 1 line of label: obfuscated last 4 digits "..1111". @@ -903,7 +917,7 @@ // Only card number is displayed on the first line. EXPECT_EQ(virtual_card_number_field_suggestion.main_text.value, base::StrCat({u"Visa ", internal::GetObfuscatedStringForCardDigits( - u"1111", 4)})); + u"1111", ios_obfuscation_length())})); EXPECT_EQ(virtual_card_number_field_suggestion.minor_text.value, u""); #else if (keyboard_accessory_enabled()) { @@ -952,11 +966,12 @@ EXPECT_EQ(real_card_name_field_suggestion.minor_text.value, u""); #if BUILDFLAG(IS_IOS) - // For IOS, the label is "....1111". + // For IOS, the label is "..1111" or "....1111". ASSERT_EQ(real_card_name_field_suggestion.labels.size(), 1U); ASSERT_EQ(real_card_name_field_suggestion.labels[0].size(), 1U); EXPECT_EQ(real_card_name_field_suggestion.labels[0][0].value, - internal::GetObfuscatedStringForCardDigits(u"1111", 4)); + internal::GetObfuscatedStringForCardDigits( + u"1111", ios_obfuscation_length())); #else if (keyboard_accessory_enabled()) { // For the keyboard accessory, the label is "..1111". @@ -993,7 +1008,7 @@ // Only the card number is displayed on the first line. EXPECT_EQ(real_card_number_field_suggestion.main_text.value, base::StrCat({u"Visa ", internal::GetObfuscatedStringForCardDigits( - u"1111", 4)})); + u"1111", ios_obfuscation_length())})); EXPECT_EQ(real_card_number_field_suggestion.minor_text.value, u""); #else // For Desktop/Android, split the first line and populate the card name and @@ -1012,6 +1027,64 @@ base::UTF8ToUTF16(test::NextYear().substr(2))})); } +#if BUILDFLAG(IS_IOS) +// Tests that credit card suggestions on iOS use the correct number of '•' +// characters depending on the kAutofillUseTwoDotsForLastFourDigits feature. +class AutofillCreditCardSuggestionIOSObfuscationLengthContentTest + : public AutofillSuggestionGeneratorTest, + public testing::WithParamInterface<bool> { + public: + AutofillCreditCardSuggestionIOSObfuscationLengthContentTest() { + feature_list_.InitWithFeatureState( + features::kAutofillUseTwoDotsForLastFourDigits, GetParam()); + } + + ~AutofillCreditCardSuggestionIOSObfuscationLengthContentTest() override = + default; + + int expected_obfuscation_length() const { return GetParam() ? 2 : 4; } + + private: + base::test::ScopedFeatureList feature_list_; +}; + +INSTANTIATE_TEST_SUITE_P( + AutofillCreditCardSuggestionContentTest, + AutofillCreditCardSuggestionIOSObfuscationLengthContentTest, + testing::Bool()); + +TEST_P(AutofillCreditCardSuggestionIOSObfuscationLengthContentTest, + CreateCreditCardSuggestion_CorrectObfuscationLength) { + CreditCard server_card = CreateServerCard(); + + // Name field suggestion. + Suggestion card_name_field_suggestion = + suggestion_generator()->CreateCreditCardSuggestion( + server_card, AutofillType(CREDIT_CARD_NAME_FULL), + /*virtual_card_option=*/false, + /*card_linked_offer_available=*/false); + + ASSERT_EQ(card_name_field_suggestion.labels.size(), 1U); + ASSERT_EQ(card_name_field_suggestion.labels[0].size(), 1U); + EXPECT_EQ(card_name_field_suggestion.labels[0][0].value, + internal::GetObfuscatedStringForCardDigits( + u"1111", expected_obfuscation_length())); + + // Card number field suggestion. + Suggestion card_number_field_suggestion = + suggestion_generator()->CreateCreditCardSuggestion( + server_card, AutofillType(CREDIT_CARD_NUMBER), + /*virtual_card_option=*/false, + /*card_linked_offer_available=*/false); + + EXPECT_EQ( + card_number_field_suggestion.main_text.value, + base::StrCat({u"Visa ", internal::GetObfuscatedStringForCardDigits( + u"1111", expected_obfuscation_length())})); +} + +#endif // BUILDFLAG(IS_IOS) + class AutofillSuggestionGeneratorTestForMetadata : public AutofillSuggestionGeneratorTest, public testing::WithParamInterface<std::tuple<bool, bool, bool>> {
diff --git a/components/autofill/core/browser/autofill_test_utils.h b/components/autofill/core/browser/autofill_test_utils.h index ab388d17..b1ab031 100644 --- a/components/autofill/core/browser/autofill_test_utils.h +++ b/components/autofill/core/browser/autofill_test_utils.h
@@ -510,11 +510,7 @@ AutofillExternalDelegate* autofill_external_delegate); std::string ObfuscatedCardDigitsAsUTF8(const std::string& str, -#if BUILDFLAG(IS_ANDROID) - int obfuscation_length = 2); -#else - int obfuscation_length = 4); -#endif + int obfuscation_length); // Returns 2-digit month string, like "02", "10". std::string NextMonth();
diff --git a/components/autofill/core/browser/browser_autofill_manager_unittest.cc b/components/autofill/core/browser/browser_autofill_manager_unittest.cc index bcb0cdd..ccbcc0f8 100644 --- a/components/autofill/core/browser/browser_autofill_manager_unittest.cc +++ b/components/autofill/core/browser/browser_autofill_manager_unittest.cc
@@ -1131,6 +1131,11 @@ virtual int ObfuscationLength() { #if BUILDFLAG(IS_ANDROID) return IsKeyboardAccessoryEnabled() ? 2 : 4; +#elif BUILDFLAG(IS_IOS) + return base::FeatureList::IsEnabled( + features::kAutofillUseTwoDotsForLastFourDigits) + ? 2 + : 4; #else return 4; #endif @@ -1319,6 +1324,11 @@ int ObfuscationLength() override { #if BUILDFLAG(IS_ANDROID) return is_keyboard_accessory_enabled_ ? 2 : 4; +#elif BUILDFLAG(IS_IOS) + return base::FeatureList::IsEnabled( + features::kAutofillUseTwoDotsForLastFourDigits) + ? 2 + : 4; #else return 4; #endif @@ -1932,11 +1942,11 @@ // Test that we sent the credit card suggestions to the external delegate. CheckSuggestions( form.fields[1].global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("8765"), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "8765", ObfuscationLength()), master_card_label, kMasterCard, PopupItemId::kCreditCardEntry)); } @@ -1963,11 +1973,11 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( field.global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("8765"), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "8765", ObfuscationLength()), master_card_label, kMasterCard, PopupItemId::kCreditCardEntry)); } @@ -1994,11 +2004,11 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( field.global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("8765"), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "8765", ObfuscationLength()), master_card_label, kMasterCard, PopupItemId::kCreditCardEntry)); } @@ -2026,11 +2036,11 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( field.global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("8765"), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "8765", ObfuscationLength()), master_card_label, kMasterCard, PopupItemId::kCreditCardEntry)); } @@ -2062,11 +2072,12 @@ #endif // Test that we sent the right value to the external delegate. - CheckSuggestions(field.global_id(), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("3123"), - master_card_label, kMasterCard, - PopupItemId::kCreditCardEntry)); + CheckSuggestions( + field.global_id(), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "3123", ObfuscationLength()), + master_card_label, kMasterCard, + PopupItemId::kCreditCardEntry)); } // Test that we return only matching credit card profile suggestions when the @@ -2089,9 +2100,9 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( field.global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry)); + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry)); } // Test that we return credit card profile suggestions when the selected form @@ -2240,11 +2251,11 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( form.fields[1].global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("8765"), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "8765", ObfuscationLength()), master_card_label, kMasterCard, PopupItemId::kCreditCardEntry)); } @@ -2272,11 +2283,11 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( form.fields[1].global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("8765"), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "8765", ObfuscationLength()), master_card_label, kMasterCard, PopupItemId::kCreditCardEntry)); } @@ -2314,15 +2325,15 @@ // Test that we sent the right values to the external delegate. CheckSuggestions( form.fields[1].global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("8765"), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "8765", ObfuscationLength()), master_card_label1, kMasterCard, PopupItemId::kCreditCardEntry), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("3456"), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), master_card_label2, kMasterCard, PopupItemId::kCreditCardEntry)); } @@ -2408,15 +2419,16 @@ CheckSuggestions( form.fields[1].global_id(), - Suggestion(std::string("Mastercard ") + - test::ObfuscatedCardDigitsAsUTF8("5100"), + Suggestion(std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8( + "5100", ObfuscationLength()), master_card_label, kMasterCard, PopupItemId::kCreditCardEntry), - Suggestion( - std::string("Amex ") + test::ObfuscatedCardDigitsAsUTF8("0005"), - amex_card_label, kAmericanExpressCard, PopupItemId::kCreditCardEntry), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry)); + Suggestion(std::string("Amex ") + test::ObfuscatedCardDigitsAsUTF8( + "0005", ObfuscationLength()), + amex_card_label, kAmericanExpressCard, + PopupItemId::kCreditCardEntry), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry)); } // Test cards that are expired AND disused are suppressed when suppression is @@ -2466,15 +2478,18 @@ #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) const std::string mastercard_label = - test::ObfuscatedCardDigitsAsUTF8("5100"); - const std::string visa_label = test::ObfuscatedCardDigitsAsUTF8("3456"); + test::ObfuscatedCardDigitsAsUTF8("5100", ObfuscationLength()); + const std::string visa_label = + test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()); #else const std::string mastercard_label = - std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8("5100") + + std::string("Mastercard ") + + test::ObfuscatedCardDigitsAsUTF8("5100", ObfuscationLength()) + std::string(", expires on 04/99"); - const std::string visa_label = std::string("Visa ") + - test::ObfuscatedCardDigitsAsUTF8("3456") + - std::string(", expires on 04/10"); + const std::string visa_label = + std::string("Visa ") + + test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()) + + std::string(", expires on 04/10"); #endif CheckSuggestions(form.fields[0].global_id(), @@ -2492,10 +2507,11 @@ #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) const std::string mastercard_label = - test::ObfuscatedCardDigitsAsUTF8("5100"); + test::ObfuscatedCardDigitsAsUTF8("5100", ObfuscationLength()); #else const std::string mastercard_label = - std::string("Mastercard ") + test::ObfuscatedCardDigitsAsUTF8("5100") + + std::string("Mastercard ") + + test::ObfuscatedCardDigitsAsUTF8("5100", ObfuscationLength()) + std::string(", expires on 04/99"); #endif @@ -2511,11 +2527,13 @@ GetAutofillSuggestions(form, field); #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) - const std::string visa_label = test::ObfuscatedCardDigitsAsUTF8("3456"); + const std::string visa_label = + test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()); #else - const std::string visa_label = std::string("Visa ") + - test::ObfuscatedCardDigitsAsUTF8("3456") + - std::string(", expires on 04/10"); + const std::string visa_label = + std::string("Visa ") + + test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()) + + std::string(", expires on 04/10"); #endif CheckSuggestions(form.fields[0].global_id(), @@ -2530,11 +2548,13 @@ GetAutofillSuggestions(form, field); #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) - const std::string amex_label = test::ObfuscatedCardDigitsAsUTF8("0005"); + const std::string amex_label = + test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()); #else - const std::string amex_label = std::string("Amex ") + - test::ObfuscatedCardDigitsAsUTF8("0005") + - std::string(", expires on 01/10"); + const std::string amex_label = + std::string("Amex ") + + test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()) + + std::string(", expires on 01/10"); #endif CheckSuggestions( @@ -2585,21 +2605,24 @@ const std::string amex_card_exp_label = std::string("Expires on 04/99"); #endif - CheckSuggestions(form.fields[1].global_id(), - Suggestion(std::string("Amex ") + - test::ObfuscatedCardDigitsAsUTF8("0005"), - amex_card_exp_label, kAmericanExpressCard, - PopupItemId::kCreditCardEntry)); + CheckSuggestions( + form.fields[1].global_id(), + Suggestion(std::string("Amex ") + test::ObfuscatedCardDigitsAsUTF8( + "0005", ObfuscationLength()), + amex_card_exp_label, kAmericanExpressCard, + PopupItemId::kCreditCardEntry)); // Query by cardholder name field. GetAutofillSuggestions(form, form.fields[0]); #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) - const std::string amex_card_label = test::ObfuscatedCardDigitsAsUTF8("0005"); + const std::string amex_card_label = + test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()); #else - const std::string amex_card_label = std::string("Amex ") + - test::ObfuscatedCardDigitsAsUTF8("0005") + - std::string(", expires on 04/99"); + const std::string amex_card_label = + std::string("Amex ") + + test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()) + + std::string(", expires on 04/99"); #endif CheckSuggestions( @@ -8139,9 +8162,9 @@ CheckSuggestions( form.fields[3].global_id(), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - visa_label, kVisaCard, PopupItemId::kCreditCardEntry)); + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + visa_label, kVisaCard, PopupItemId::kCreditCardEntry)); } // Test that inputs detected to be CVC inputs are forced to @@ -8845,21 +8868,24 @@ Suggestion virtual_card_suggestion = Suggestion( "Virtual card", - std::string("nickname ") + test::ObfuscatedCardDigitsAsUTF8("3456"), + std::string("nickname ") + + test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()), label, kVisaCard, autofill::PopupItemId::kVirtualCreditCardEntry); - CheckSuggestions(form.fields[1].global_id(), virtual_card_suggestion, - Suggestion(std::string("nickname ") + - test::ObfuscatedCardDigitsAsUTF8("3456"), - label, kVisaCard, PopupItemId::kCreditCardEntry)); + CheckSuggestions( + form.fields[1].global_id(), virtual_card_suggestion, + Suggestion(std::string("nickname ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + label, kVisaCard, PopupItemId::kCreditCardEntry)); // Non card number field (cardholder name field). GetAutofillSuggestions(form, form.fields[0]); #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS) - label = test::ObfuscatedCardDigitsAsUTF8("3456"); + label = test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()); #else - label = std::string("nickname ") + test::ObfuscatedCardDigitsAsUTF8("3456") + + label = std::string("nickname ") + + test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()) + std::string(", expires on 04/99"); #endif @@ -10429,11 +10455,11 @@ external_delegate_->CheckSuggestionCount(field_id, 1); // Suggestion details need to match the credit card added in the SetUp() // above. - CheckSuggestions( - field_id, - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry)); + CheckSuggestions(field_id, Suggestion(std::string("Visa ") + + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + "Expires on 04/99", kVisaCard, + PopupItemId::kCreditCardEntry)); } private: @@ -10497,10 +10523,10 @@ GetAutofillSuggestions(form, form.fields[0]); // Cardholder name field. external_delegate_->CheckSuggestionCount(form.fields[0].global_id(), 1); - const std::string visa_label = - base::JoinString({"Visa ", test::ObfuscatedCardDigitsAsUTF8("3456"), - ", expires on 04/99"}, - ""); + const std::string visa_label = base::JoinString( + {"Visa ", test::ObfuscatedCardDigitsAsUTF8("3456", ObfuscationLength()), + ", expires on 04/99"}, + ""); CheckSuggestions(form.fields[0].global_id(), Suggestion("Elvis Presley", visa_label, kVisaCard, PopupItemId::kCreditCardEntry)); @@ -10589,9 +10615,9 @@ external_delegate_->CheckSuggestionCount(field_id, 2); CheckSuggestions( field_id, - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), Suggestion(l10n_util::GetStringUTF8( IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL), "", "", PopupItemId::kUseVirtualCard)); @@ -10628,12 +10654,12 @@ external_delegate_->CheckSuggestionCount(field_id, 3); CheckSuggestions( field_id, - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("1111"), - "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), - Suggestion( - std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8("3456"), - "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "1111", ObfuscationLength()), + "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), + Suggestion(std::string("Visa ") + test::ObfuscatedCardDigitsAsUTF8( + "3456", ObfuscationLength()), + "Expires on 04/99", kVisaCard, PopupItemId::kCreditCardEntry), Suggestion(l10n_util::GetStringUTF8( IDS_AUTOFILL_CLOUD_TOKEN_DROPDOWN_OPTION_LABEL), "", "", PopupItemId::kUseVirtualCard)); @@ -10890,11 +10916,12 @@ CheckSuggestions( form.fields[1].global_id(), - Suggestion((expected_nickname_.empty() ? std::string("Amex") - : expected_nickname_) + - " " + test::ObfuscatedCardDigitsAsUTF8("0005"), - exp_label, kAmericanExpressCard, - PopupItemId::kCreditCardEntry)); + Suggestion( + (expected_nickname_.empty() ? std::string("Amex") + : expected_nickname_) + + " " + + test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()), + exp_label, kAmericanExpressCard, PopupItemId::kCreditCardEntry)); } TEST_P(BrowserAutofillManagerTestForSharingNickname, @@ -10929,11 +10956,13 @@ form.fields[1].global_id(), Suggestion( (local_nickname_.empty() ? std::string("Amex") : local_nickname_) + - " " + test::ObfuscatedCardDigitsAsUTF8("0005"), + " " + + test::ObfuscatedCardDigitsAsUTF8("0005", ObfuscationLength()), exp_label, kAmericanExpressCard, PopupItemId::kCreditCardEntry), Suggestion( (server_nickname_.empty() ? std::string("Amex") : server_nickname_) + - " " + test::ObfuscatedCardDigitsAsUTF8("8431"), + " " + + test::ObfuscatedCardDigitsAsUTF8("8431", ObfuscationLength()), exp_label, kAmericanExpressCard, PopupItemId::kCreditCardEntry)); }
diff --git a/components/autofill/core/browser/form_data_importer.cc b/components/autofill/core/browser/form_data_importer.cc index 581c3b1..888f7ab 100644 --- a/components/autofill/core/browser/form_data_importer.cc +++ b/components/autofill/core/browser/form_data_importer.cc
@@ -1055,4 +1055,16 @@ form_associator_.OnBrowsingHistoryCleared(deletion_info); } +void FormDataImporter::SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted( + absl::optional<std::string> + guid_of_card_if_no_interactive_authentication_flow_completed) { + guid_of_card_if_no_interactive_authentication_flow_completed_ = + std::move(guid_of_card_if_no_interactive_authentication_flow_completed); +} + +absl::optional<std::string>& +FormDataImporter::GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() { + return guid_of_card_if_no_interactive_authentication_flow_completed_; +} + } // namespace autofill
diff --git a/components/autofill/core/browser/form_data_importer.h b/components/autofill/core/browser/form_data_importer.h index bf29a28..70875de 100644 --- a/components/autofill/core/browser/form_data_importer.h +++ b/components/autofill/core/browser/form_data_importer.h
@@ -135,6 +135,16 @@ return iban_save_manager_.get(); } + // This should only set + // `guid_of_card_if_no_interactive_authentication_flow_completed_` to a value + // when there was an autofill with no interactive authentication, otherwise it + // should set to nullopt. + void SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted( + absl::optional<std::string> + guid_of_card_if_no_interactive_authentication_flow_completed); + absl::optional<std::string>& + GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted(); + protected: void set_credit_card_save_manager_for_testing( std::unique_ptr<CreditCardSaveManager> credit_card_save_manager) { @@ -378,6 +388,16 @@ // Enables associating recently submitted forms with each other. FormAssociator form_associator_; + // Optional that will have a value when the most recent payments autofill flow + // had no interactive authentication. It will contain the GUID of the card + // where the most recent no interactive authentication has occurred. If this + // is empty upon form submission, it implies that the most recent autofill had + // an interactive authentication. Set when + // `SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted()` is called, and + // cleared on pag navigation. + absl::optional<std::string> + guid_of_card_if_no_interactive_authentication_flow_completed_; + friend class AutofillMergeTest; friend class FormDataImporterTest; friend class FormDataImporterTestBase;
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.cc b/components/autofill/core/browser/payments/credit_card_access_manager.cc index c2d9639..4a93bd4 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager.cc
@@ -24,6 +24,7 @@ #include "components/autofill/core/browser/autofill_progress_dialog_type.h" #include "components/autofill/core/browser/browser_autofill_manager.h" #include "components/autofill/core/browser/data_model/credit_card.h" +#include "components/autofill/core/browser/form_data_importer.h" #include "components/autofill/core/browser/metrics/form_events/credit_card_form_event_logger.h" #include "components/autofill/core/browser/metrics/payments/better_auth_metrics.h" #include "components/autofill/core/browser/metrics/payments/card_unmask_flow_metrics.h" @@ -68,7 +69,19 @@ personal_data_manager_(personal_data_manager), form_event_logger_(form_event_logger) {} -CreditCardAccessManager::~CreditCardAccessManager() = default; +CreditCardAccessManager::~CreditCardAccessManager() { + // This clears the GUID of the most recently autofilled card with no + // interactive authentication flow upon page navigation, as page navigation + // results in us destroying the current CreditCardAccessManager and creating a + // new one. + if (client_) { + if (auto* form_data_importer = client_->GetFormDataImporter()) { + form_data_importer + ->SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted( + absl::nullopt); + } + } +} void CreditCardAccessManager::UpdateCreditCardFormEventLogger() { std::vector<CreditCard*> credit_cards = @@ -1101,6 +1114,13 @@ // the user. accessor_->OnCreditCardFetched(CreditCardFetchResult::kSuccess, card_.get(), /*cvc=*/u""); + + // This local card autofill flow did not have any interactive + // authentication, so notify the FormDataImporter of this. + client_->GetFormDataImporter() + ->SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted( + card_->guid()); + // `accessor_->OnCreditCardFetched()` makes a copy of `card` and `cvc` // before it asynchronously fills them into the form. Thus we can safely // call `Reset()` here, and we should as from this class' point of view the @@ -1162,6 +1182,15 @@ accessor_->OnCreditCardFetched( CreditCardFetchResult::kSuccess, card_.get(), base::UTF8ToUTF16(response_details.dcvv)); + + // If the server responded with success and the real pan, no interactive + // authentication happened. It's also possible that the server does not + // provide the real pan but requests an authentication which is handled + // below. + client_->GetFormDataImporter() + ->SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted( + card_->guid()); + autofill_metrics::LogServerCardUnmaskResult( autofill_metrics::ServerCardUnmaskResult::kRiskBasedUnmasked, AutofillClient::PaymentsRpcCardType::kVirtualCard,
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager.h b/components/autofill/core/browser/payments/credit_card_access_manager.h index 4d6ba86..31c82e5c 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager.h +++ b/components/autofill/core/browser/payments/credit_card_access_manager.h
@@ -263,6 +263,8 @@ // Determines what type of authentication is required. |fido_auth_enabled| // suggests whether the server has offered FIDO auth as an option. + // TODO(crbug.com/1449351): Prefix these functions with + // "StartAuthenticationFlow" instead of "GetAuthenticationType". void GetAuthenticationType(bool fido_auth_enabled); void GetAuthenticationTypeForVirtualCard(bool fido_auth_enabled); void GetAuthenticationTypeForMaskedServerCard(bool fido_auth_enabled);
diff --git a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc index df624b53..092b097 100644 --- a/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_access_manager_unittest.cc
@@ -207,10 +207,10 @@ autofill_driver_.get(), &autofill_client_); credit_card_access_manager_ = browser_autofill_manager_->GetCreditCardAccessManager(); - -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) autofill_driver_->set_autofill_manager( std::move(browser_autofill_manager_)); + +#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_ANDROID) autofill_driver_->SetAuthenticator(new TestInternalAuthenticator()); auto fido_authenticator = std::make_unique<TestCreditCardFidoAuthenticator>( autofill_driver_.get(), &autofill_client_); @@ -782,6 +782,13 @@ EXPECT_EQ(accessor_->result(), CreditCardFetchResult::kSuccess); EXPECT_EQ(kTestNumber16, accessor_->number()); + + // There was no interactive authentication in this flow, so check that this + // is signaled correctly. + const absl::optional<std::string>& guid = + autofill_client_.GetFormDataImporter() + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted(); + EXPECT_EQ(guid, kTestGUID); } // Ensures that FetchCreditCard() reports a failure when a card does not exist. @@ -838,6 +845,11 @@ histogram_tester.ExpectBucketCount( "Autofill.ServerCardUnmask.ServerCard.Attempt", true, 0); } + // Expect that we did not signal that there was no interactive + // authentication. + EXPECT_FALSE(autofill_client_.GetFormDataImporter() + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() + .has_value()); } } @@ -2525,6 +2537,14 @@ EXPECT_EQ(accessor_->expiry_month(), base::UTF8ToUTF16(test::NextMonth())); EXPECT_EQ(accessor_->expiry_year(), base::UTF8ToUTF16(test::NextYear())); + // There was no interactive authentication in this flow, so check that this + // is signaled correctly. + const absl::optional<std::string>& guid = + autofill_client_.GetFormDataImporter() + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted(); + EXPECT_TRUE(guid.has_value()); + EXPECT_EQ(guid.value(), kTestGUID); + // Expect the metrics are logged correctly. histogram_tester.ExpectUniqueSample( "Autofill.ServerCardUnmask.VirtualCard.Attempt", true, 1); @@ -2556,6 +2576,11 @@ otp_response.cvc = u"123"; credit_card_access_manager_->OnOtpAuthenticationComplete(otp_response); + // Expect that we did not signal that there was no interactive authentication. + EXPECT_FALSE(autofill_client_.GetFormDataImporter() + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() + .has_value()); + // Expect the metrics are logged correctly. histogram_tester.ExpectUniqueSample( "Autofill.ServerCardUnmask.VirtualCard.Attempt", true, 1); @@ -2584,6 +2609,11 @@ .with_card(&card) .with_cvc(u"123")); + // Expect that we did not signal that there was no interactive authentication. + EXPECT_FALSE(autofill_client_.GetFormDataImporter() + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() + .has_value()); + // Expect the metrics are logged correctly. histogram_tester.ExpectUniqueSample( "Autofill.ServerCardUnmask.VirtualCard.Attempt", true, 1); @@ -2634,6 +2664,11 @@ } } + // Expect that we did not signal that there was no interactive authentication. + EXPECT_FALSE(autofill_client_.GetFormDataImporter() + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() + .has_value()); + // Expect the metrics are logged correctly. histogram_tester.ExpectUniqueSample( "Autofill.ServerCardUnmask.VirtualCard.Attempt", true, 2); @@ -3059,6 +3094,22 @@ autofill_metrics::ServerCardUnmaskResult::kFlowCancelled, 1); } +// Test that the CreditCardAccessManager's destructor resets the GUID of the +// card that had no interactive authentication flows completed in the associated +// FormDataImporter. +TEST_F(CreditCardAccessManagerTest, DestructorResetsCardGuid) { + auto* form_data_importer = autofill_client_.GetFormDataImporter(); + form_data_importer->SetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted( + "TestGuid"); + EXPECT_TRUE(form_data_importer + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() + .has_value()); + autofill_driver_.reset(); + EXPECT_FALSE(form_data_importer + ->GetGuidOfCardIfNoInteractiveAuthenticationFlowCompleted() + .has_value()); +} + // Params of the CreditCardAccessManagerCardMetadataTest: // -- bool card_name_available; // -- bool card_art_available;
diff --git a/components/autofill/core/browser/test_autofill_client.h b/components/autofill/core/browser/test_autofill_client.h index d199f2c..f66858e 100644 --- a/components/autofill/core/browser/test_autofill_client.h +++ b/components/autofill/core/browser/test_autofill_client.h
@@ -166,6 +166,12 @@ } FormDataImporter* GetFormDataImporter() override { + if (!form_data_importer_) { + set_test_form_data_importer(std::make_unique<FormDataImporter>( + /*client=*/this, /*payments_client=*/nullptr, + /*personal_data_manager=*/nullptr, /*app_locale=*/"en-US")); + } + return form_data_importer_.get(); }
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index b34fa5d..43fff51e 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -278,6 +278,14 @@ &kAutofillEnforceDelaysInStrikeDatabase, "autofill_virtual_card_enroll_delay_in_strike_database_in_days", 7}; +#if BUILDFLAG(IS_IOS) +// When enabled, use two '•' when displaying the last four digits of a credit +// card number. (E.g., '•• 8888' rather than '•••• 8888'). +BASE_FEATURE(kAutofillUseTwoDotsForLastFourDigits, + "AutofillUseTwoDotsForLastFourDigits", + base::FEATURE_DISABLED_BY_DEFAULT); +#endif + bool ShouldShowImprovedUserConsentForCreditCardSave() { // TODO(crbug.com/1052397): Revisit the macro expression once build flag switch // of lacros-chrome is complete.
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index e696cea4..5c25357 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -54,6 +54,10 @@ extern const base::FeatureParam<int> kAutofillVirtualCardEnrollDelayInStrikeDatabaseInDays; +#if BUILDFLAG(IS_IOS) +BASE_DECLARE_FEATURE(kAutofillUseTwoDotsForLastFourDigits); +#endif + // Return whether a [No thanks] button and new messaging is shown in the save // card bubbles. This will be called only on desktop platforms. bool ShouldShowImprovedUserConsentForCreditCardSave();
diff --git a/components/autofill/ios/browser/autofill_agent.mm b/components/autofill/ios/browser/autofill_agent.mm index 8bd61f8e..7345154 100644 --- a/components/autofill/ios/browser/autofill_agent.mm +++ b/components/autofill/ios/browser/autofill_agent.mm
@@ -55,7 +55,6 @@ #import "components/prefs/pref_service.h" #import "components/ukm/ios/ukm_url_recorder.h" #import "ios/web/common/url_scheme_util.h" -#import "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/public/js_messaging/web_frame.h" #import "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/js_messaging/web_frames_manager_observer_bridge.h"
diff --git a/components/browser_sync/PRESUBMIT.py b/components/browser_sync/PRESUBMIT.py index 073d8af9..e2f86017 100644 --- a/components/browser_sync/PRESUBMIT.py +++ b/components/browser_sync/PRESUBMIT.py
@@ -10,8 +10,6 @@ import re -USE_PYTHON3 = True - BROWSER_SYNC_SOURCE_FILES = (r'^components[\\/]browser_sync[\\/].*\.(cc|h)$',) def CheckChangeLintsClean(input_api, output_api):
diff --git a/components/cdm/DEPS b/components/cdm/DEPS index 86694de..a6a821b 100644 --- a/components/cdm/DEPS +++ b/components/cdm/DEPS
@@ -5,5 +5,6 @@ "+media/cdm", "+media/media_buildflags.h", "+ppapi/buildflags", + "+third_party/widevine/cdm/buildflags.h", "+third_party/widevine/cdm/widevine_cdm_common.h", ]
diff --git a/components/cdm/common/BUILD.gn b/components/cdm/common/BUILD.gn index 373ce6c..a90fd83 100644 --- a/components/cdm/common/BUILD.gn +++ b/components/cdm/common/BUILD.gn
@@ -10,16 +10,6 @@ "cdm_message_generator.h", ] - if (is_android) { - sources += [ - "cdm_messages_android.h", - "clearkey_drm_delegate_android.cc", - "clearkey_drm_delegate_android.h", - "widevine_drm_delegate_android.cc", - "widevine_drm_delegate_android.h", - ] - } - deps = [ "//base", "//content/public/common", @@ -27,6 +17,19 @@ "//media", ] + if (is_android) { + sources += [ + "android_cdm_registration.cc", + "android_cdm_registration.h", + "cdm_messages_android.h", + "clearkey_drm_delegate_android.cc", + "clearkey_drm_delegate_android.h", + "widevine_drm_delegate_android.cc", + "widevine_drm_delegate_android.h", + ] + deps += [ "//third_party/widevine/cdm:buildflags" ] + } + if (enable_library_cdms) { sources += [ "cdm_manifest.cc",
diff --git a/components/cdm/common/android_cdm_registration.cc b/components/cdm/common/android_cdm_registration.cc new file mode 100644 index 0000000..8e1f79a --- /dev/null +++ b/components/cdm/common/android_cdm_registration.cc
@@ -0,0 +1,59 @@ +// 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 "components/cdm/common/android_cdm_registration.h" + +#include "base/logging.h" +#include "media/base/android/media_drm_bridge.h" +#include "media/cdm/cdm_type.h" + +#if BUILDFLAG(ENABLE_WIDEVINE) +#include "third_party/widevine/cdm/widevine_cdm_common.h" // nogncheck +#endif + +namespace cdm { + +#if BUILDFLAG(ENABLE_WIDEVINE) +void AddAndroidWidevineCdm(std::vector<content::CdmInfo>* cdms) { + // Widevine is done by MediaDrm, and should be supported on all devices. + // Register Widevine without any capabilities so that it will be + // checked the first time it is used. + cdms->emplace_back(kWidevineKeySystem, + content::CdmInfo::Robustness::kSoftwareSecure, + absl::nullopt, kWidevineCdmType); + cdms->emplace_back(kWidevineKeySystem, + content::CdmInfo::Robustness::kHardwareSecure, + absl::nullopt, kWidevineCdmType); +} +#endif // BUILDFLAG(ENABLE_WIDEVINE) + +void AddOtherAndroidCdms(std::vector<content::CdmInfo>* cdms) { + // CdmInfo needs a CdmType, but on Android it is not used as the key system + // is supported by MediaDrm. Using a random value as something needs to be + // specified, but must be different than other CdmTypes specified. + // (On Android the key system is identified by UUID, and that mapping is + // maintained by MediaDrmBridge.) + const media::CdmType kAndroidCdmType{0x2e9dabb9c171c28cull, + 0xf455252ec70b52adull}; + + // MediaDrmBridge returns a list of key systems available on the device + // that are not Widevine. Register them with no capabilities specified so + // that lazy evaluation can figure out what is supported when requested. + // We don't know if either software secure or hardware secure support is + // available, so register them both. Lazy evaluation will remove them + // if they aren't supported. + const auto key_system_names = + media::MediaDrmBridge::GetPlatformKeySystemNames(); + for (const auto& key_system : key_system_names) { + DVLOG(3) << __func__ << " key_system:" << key_system; + cdms->emplace_back(key_system, + content::CdmInfo::Robustness::kSoftwareSecure, + absl::nullopt, kAndroidCdmType); + cdms->emplace_back(key_system, + content::CdmInfo::Robustness::kHardwareSecure, + absl::nullopt, kAndroidCdmType); + } +} + +} // namespace cdm
diff --git a/components/cdm/common/android_cdm_registration.h b/components/cdm/common/android_cdm_registration.h new file mode 100644 index 0000000..70323ce --- /dev/null +++ b/components/cdm/common/android_cdm_registration.h
@@ -0,0 +1,26 @@ +// 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 COMPONENTS_CDM_COMMON_ANDROID_CDM_REGISTRATION_H_ +#define COMPONENTS_CDM_COMMON_ANDROID_CDM_REGISTRATION_H_ + +#include <vector> + +#include "content/public/common/cdm_info.h" +#include "third_party/widevine/cdm/buildflags.h" + +namespace cdm { + +#if BUILDFLAG(ENABLE_WIDEVINE) +// Add Widevine Content Decryption Module, if enabled. +void AddAndroidWidevineCdm(std::vector<content::CdmInfo>* cdms); +#endif + +// Add other platform-supported Widevine Content Decryption Modules which are +// not explicitly handled by Chrome. +void AddOtherAndroidCdms(std::vector<content::CdmInfo>* cdms); + +} // namespace cdm + +#endif // COMPONENTS_CDM_COMMON_ANDROID_CDM_REGISTRATION_H_
diff --git a/components/certificate_transparency/tools/PRESUBMIT.py b/components/certificate_transparency/tools/PRESUBMIT.py index d6646f8..2eca31b 100644 --- a/components/certificate_transparency/tools/PRESUBMIT.py +++ b/components/certificate_transparency/tools/PRESUBMIT.py
@@ -5,8 +5,6 @@ """Chromium presubmit script for src/net/tools/ct_log_list.""" -USE_PYTHON3 = True - def _RunMakeCTLogListTests(input_api, output_api): """Runs make_ct_known_logs_list unittests if related files were modified.""" files = (input_api.os_path.normpath(x) for x in
diff --git a/components/commerce/core/commerce_constants.cc b/components/commerce/core/commerce_constants.cc index 014853c..6c9148a4 100644 --- a/components/commerce/core/commerce_constants.cc +++ b/components/commerce/core/commerce_constants.cc
@@ -11,4 +11,7 @@ const char kChromeUIShoppingInsightsSidePanelHost[] = "shopping-insights-side-panel.top-chrome"; +const char kChromeUIShoppingInsightsSidePanelUrl[] = + "chrome://shopping-insights-side-panel.top-chrome"; + } // namespace commerce
diff --git a/components/commerce/core/commerce_constants.h b/components/commerce/core/commerce_constants.h index a97fab4..1f21c92 100644 --- a/components/commerce/core/commerce_constants.h +++ b/components/commerce/core/commerce_constants.h
@@ -13,6 +13,9 @@ // The host for the shopping insights side panel page. extern const char kChromeUIShoppingInsightsSidePanelHost[]; +// The url for the shopping insights side panel page. +extern const char kChromeUIShoppingInsightsSidePanelUrl[]; + } // namespace commerce #endif // COMPONENTS_COMMERCE_CORE_COMMERCE_CONSTANTS_H_
diff --git a/components/cronet/PRESUBMIT.py b/components/cronet/PRESUBMIT.py index 7a83643..cfd8439 100644 --- a/components/cronet/PRESUBMIT.py +++ b/components/cronet/PRESUBMIT.py
@@ -10,9 +10,6 @@ import os -USE_PYTHON3 = True - - def _PyLintChecks(input_api, output_api): pylint_checks = input_api.canned_checks.GetPylint(input_api, output_api, extra_paths_list=_GetPathsToPrepend(input_api), pylintrc='pylintrc', @@ -84,10 +81,7 @@ return input_api.canned_checks.RunUnitTestsInDirectory( input_api, output_api, '.', - [ r'^tools_unittest\.py$'], - run_on_python3=USE_PYTHON3, - run_on_python2=False, - skip_shebang_check = True) + [ r'^tools_unittest\.py$']) def _ChangeAffectsCronetTools(change):
diff --git a/components/device_signals/core/browser/settings_signals_collector_unittest.cc b/components/device_signals/core/browser/settings_signals_collector_unittest.cc index 0064983..018e7511 100644 --- a/components/device_signals/core/browser/settings_signals_collector_unittest.cc +++ b/components/device_signals/core/browser/settings_signals_collector_unittest.cc
@@ -57,17 +57,16 @@ class SettingsSignalsCollectorTest : public testing::Test { protected: - SettingsSignalsCollectorTest() - : signal_collector_(std::move(settings_client)) {} + SettingsSignalsCollectorTest() { + auto settings_client = std::make_unique<StrictMock<MockSettingsClient>>(); + settings_client_ = settings_client.get(); + signal_collector_ = + std::make_unique<SettingsSignalsCollector>(std::move(settings_client)); + } base::test::TaskEnvironment task_environment_; - - std::unique_ptr<StrictMock<MockSettingsClient>> settings_client = - std::make_unique<StrictMock<MockSettingsClient>>(); - raw_ptr<StrictMock<MockSettingsClient>> settings_client_ = - settings_client.get(); - - SettingsSignalsCollector signal_collector_; + std::unique_ptr<SettingsSignalsCollector> signal_collector_; + raw_ptr<StrictMock<MockSettingsClient>> settings_client_; }; // Test that runs a sanity check on the set of signals supported by this @@ -76,7 +75,7 @@ const std::array<SignalName, 1> supported_signals{ {SignalName::kSystemSettings}}; - const auto names_set = signal_collector_.GetSupportedSignalNames(); + const auto names_set = signal_collector_->GetSupportedSignalNames(); EXPECT_EQ(names_set.size(), supported_signals.size()); for (const auto& signal_name : supported_signals) { @@ -89,8 +88,8 @@ SignalName signal_name = SignalName::kAntiVirus; SignalsAggregationResponse response; base::RunLoop run_loop; - signal_collector_.GetSignal(signal_name, CreateRequest(signal_name), response, - run_loop.QuitClosure()); + signal_collector_->GetSignal(signal_name, CreateRequest(signal_name), + response, run_loop.QuitClosure()); run_loop.Run(); @@ -105,7 +104,7 @@ SignalName signal_name = SignalName::kSystemSettings; SignalsAggregationResponse response; base::RunLoop run_loop; - signal_collector_.GetSignal( + signal_collector_->GetSignal( signal_name, CreateRequest(signal_name, /*with_settings_parameter=*/false), response, run_loop.QuitClosure()); @@ -146,8 +145,8 @@ SignalsAggregationResponse response; base::RunLoop run_loop; - signal_collector_.GetSignal(signal_name, request, response, - run_loop.QuitClosure()); + signal_collector_->GetSignal(signal_name, request, response, + run_loop.QuitClosure()); run_loop.Run();
diff --git a/components/feature_engagement/public/feature_configurations.cc b/components/feature_engagement/public/feature_configurations.cc index 28bccdf..91672a1 100644 --- a/components/feature_engagement/public/feature_configurations.cc +++ b/components/feature_engagement/public/feature_configurations.cc
@@ -298,17 +298,16 @@ absl::optional<FeatureConfig> config = FeatureConfig(); config->valid = true; config->availability = Comparator(ANY, 0); - // Don't show if user has already seen an IPH this session. - config->session_rate = Comparator(EQUAL, 0); + config->session_rate = Comparator(ANY, 0); + SessionRateImpact session_rate_impact; + session_rate_impact.type = SessionRateImpact::Type::NONE; + config->session_rate_impact = session_rate_impact; // Show the promo max once a year if the user hasn't interacted with the // download bubble within the last 21 days. config->trigger = EventConfig("download_bubble_iph_trigger", Comparator(EQUAL, 0), 360, 360); config->used = EventConfig("download_bubble_interaction", Comparator(EQUAL, 0), 21, 360); - // Allow snoozing for 7 days, up to 3 times. - config->snooze_params.snooze_interval = 7; - config->snooze_params.max_limit = 3; return config; }
diff --git a/components/guest_view/browser/PRESUBMIT.py b/components/guest_view/browser/PRESUBMIT.py index 5718f41..4980b7c2 100644 --- a/components/guest_view/browser/PRESUBMIT.py +++ b/components/guest_view/browser/PRESUBMIT.py
@@ -6,8 +6,6 @@ match the corresponding bad_message.h file. """ -USE_PYTHON3 = True - def _RunHistogramChecks(input_api, output_api, histogram_name): try: # Setup sys.path so that we can call histograms code.
diff --git a/components/headless/select_file_dialog/BUILD.gn b/components/headless/select_file_dialog/BUILD.gn new file mode 100644 index 0000000..bc8b3ec --- /dev/null +++ b/components/headless/select_file_dialog/BUILD.gn
@@ -0,0 +1,18 @@ +# 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. + +component("select_file_dialog") { + defines = [ "IS_HEADLESS_IMPL" ] + + sources = [ + "headless_select_file_dialog.cc", + "headless_select_file_dialog.h", + ] + + deps = [ + "//base", + "//ui/gfx:native_widget_types", + "//ui/shell_dialogs", + ] +}
diff --git a/components/headless/select_file_dialog/DEPS b/components/headless/select_file_dialog/DEPS new file mode 100644 index 0000000..3ca67282a --- /dev/null +++ b/components/headless/select_file_dialog/DEPS
@@ -0,0 +1,4 @@ +include_rules = [ + "+ui/gfx/native_widget_types.h", + "+ui/shell_dialogs", +]
diff --git a/headless/lib/browser/headless_select_file_dialog_factory.cc b/components/headless/select_file_dialog/headless_select_file_dialog.cc similarity index 80% rename from headless/lib/browser/headless_select_file_dialog_factory.cc rename to components/headless/select_file_dialog/headless_select_file_dialog.cc index 137d1f0..caf94e4 100644 --- a/headless/lib/browser/headless_select_file_dialog_factory.cc +++ b/components/headless/select_file_dialog/headless_select_file_dialog.cc
@@ -2,17 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "headless/lib/browser/headless_select_file_dialog_factory.h" +#include "components/headless/select_file_dialog/headless_select_file_dialog.h" -#include "url/gurl.h" +#include "ui/gfx/native_widget_types.h" namespace headless { -namespace { -// SelectFileDialogFactory is a destructable singleton, see -// SelectFileDialog::SetFactory(), so we must make it disposable. -HeadlessSelectFileDialogFactory* g_factory_instance = nullptr; -} // namespace +// static +HeadlessSelectFileDialogFactory* HeadlessSelectFileDialogFactory::instance_ = + nullptr; // HeadlessSelectFileDialog implements a stub select file dialog // that cancels itself as soon as it gets open, optionally calling @@ -46,11 +44,13 @@ gfx::NativeWindow owning_window, void* params, const GURL* caller) override { - if (callback_) + if (callback_) { std::move(callback_).Run(type); + } - if (listener_) + if (listener_) { listener_->FileSelectionCanceled(/*params=*/nullptr); + } } private: @@ -70,8 +70,8 @@ // static void HeadlessSelectFileDialogFactory::SetSelectFileDialogOnceCallbackForTests( SelectFileDialogCallback callback) { - DCHECK(g_factory_instance); - g_factory_instance->callback_ = std::move(callback); + DCHECK(instance_); + instance_->callback_ = std::move(callback); } ui::SelectFileDialog* HeadlessSelectFileDialogFactory::Create( @@ -82,13 +82,13 @@ } HeadlessSelectFileDialogFactory::HeadlessSelectFileDialogFactory() { - DCHECK(!g_factory_instance); - g_factory_instance = this; + DCHECK(!instance_); + instance_ = this; } HeadlessSelectFileDialogFactory::~HeadlessSelectFileDialogFactory() { - DCHECK_EQ(g_factory_instance, this); - g_factory_instance = nullptr; + DCHECK_EQ(instance_, this); + instance_ = nullptr; } } // namespace headless
diff --git a/headless/lib/browser/headless_select_file_dialog_factory.h b/components/headless/select_file_dialog/headless_select_file_dialog.h similarity index 78% rename from headless/lib/browser/headless_select_file_dialog_factory.h rename to components/headless/select_file_dialog/headless_select_file_dialog.h index 01c810b..244ec82 100644 --- a/headless/lib/browser/headless_select_file_dialog_factory.h +++ b/components/headless/select_file_dialog/headless_select_file_dialog.h
@@ -2,14 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef HEADLESS_LIB_BROWSER_HEADLESS_SELECT_FILE_DIALOG_FACTORY_H_ -#define HEADLESS_LIB_BROWSER_HEADLESS_SELECT_FILE_DIALOG_FACTORY_H_ +#ifndef COMPONENTS_HEADLESS_SELECT_FILE_DIALOG_HEADLESS_SELECT_FILE_DIALOG_H_ +#define COMPONENTS_HEADLESS_SELECT_FILE_DIALOG_HEADLESS_SELECT_FILE_DIALOG_H_ #include <memory> +#include "base/component_export.h" #include "base/files/file_path.h" #include "base/functional/callback.h" -#include "headless/public/headless_export.h" #include "ui/shell_dialogs/select_file_dialog.h" #include "ui/shell_dialogs/select_file_dialog_factory.h" #include "ui/shell_dialogs/select_file_policy.h" @@ -19,7 +19,7 @@ using SelectFileDialogCallback = base::OnceCallback<void(ui::SelectFileDialog::Type type)>; -class HEADLESS_EXPORT HeadlessSelectFileDialogFactory +class COMPONENT_EXPORT(HEADLESS) HeadlessSelectFileDialogFactory : public ui::SelectFileDialogFactory { public: HeadlessSelectFileDialogFactory(const HeadlessSelectFileDialogFactory&) = @@ -46,9 +46,10 @@ HeadlessSelectFileDialogFactory(); ~HeadlessSelectFileDialogFactory() override; + static HeadlessSelectFileDialogFactory* instance_; SelectFileDialogCallback callback_; }; } // namespace headless -#endif // HEADLESS_LIB_BROWSER_HEADLESS_SELECT_FILE_DIALOG_FACTORY_H_ +#endif // COMPONENTS_HEADLESS_SELECT_FILE_DIALOG_HEADLESS_SELECT_FILE_DIALOG_H_
diff --git a/components/history/core/browser/BUILD.gn b/components/history/core/browser/BUILD.gn index 8db9ac9..6a8274d0 100644 --- a/components/history/core/browser/BUILD.gn +++ b/components/history/core/browser/BUILD.gn
@@ -155,6 +155,10 @@ "android/visit_sql_handler.h", ] } + + if (is_ios) { + deps += [ "//base/ios" ] + } } source_set("unit_tests") {
diff --git a/components/history_clusters/core/config.cc b/components/history_clusters/core/config.cc index 90dbf6c1..80337a5 100644 --- a/components/history_clusters/core/config.cc +++ b/components/history_clusters/core/config.cc
@@ -168,30 +168,6 @@ "omnibox_history_cluster_provider_score", omnibox_history_cluster_provider_score); - omnibox_history_cluster_provider_inherit_search_match_score = - base::GetFieldTrialParamByFeatureAsBool( - internal::kOmniboxHistoryClusterProvider, - "omnibox_history_cluster_provider_inherit_search_match_score", - omnibox_history_cluster_provider_inherit_search_match_score); - - omnibox_history_cluster_provider_rank_above_searches = - base::GetFieldTrialParamByFeatureAsBool( - internal::kOmniboxHistoryClusterProvider, - "omnibox_history_cluster_provider_rank_above_searches", - omnibox_history_cluster_provider_rank_above_searches); - - omnibox_history_cluster_provider_shortcuts = - base::GetFieldTrialParamByFeatureAsBool( - internal::kOmniboxHistoryClusterProvider, - "omnibox_history_cluster_provider_shortcuts", - omnibox_history_cluster_provider_shortcuts); - - omnibox_history_cluster_provider_allow_default = - base::GetFieldTrialParamByFeatureAsBool( - internal::kOmniboxHistoryClusterProvider, - "omnibox_history_cluster_provider_allow_default", - omnibox_history_cluster_provider_allow_default); - omnibox_history_cluster_provider_navigation_intent_score_threshold = base::GetFieldTrialParamByFeatureAsInt( internal::kOmniboxHistoryClusterProvider, @@ -372,11 +348,6 @@ // WebUI features and params. { - hide_visits = base::FeatureList::IsEnabled(internal::kHideVisits); - - hide_visits_icon = GetFieldTrialParamByFeatureAsBool( - internal::kHideVisits, "hide_visits_icon", hide_visits_icon); - named_new_tab_groups = base::FeatureList::IsEnabled(internal::kJourneysNamedNewTabGroups); }
diff --git a/components/history_clusters/core/config.h b/components/history_clusters/core/config.h index 674d0df..645c681 100644 --- a/components/history_clusters/core/config.h +++ b/components/history_clusters/core/config.h
@@ -174,37 +174,6 @@ // aren't too many strong navigation matches. int omnibox_history_cluster_provider_score = 900; - // If enabled, will inherit the score from the matched search suggestion. This - // tries to emulate the ranking of chips, though remains slightly more - // conservative in that chips will be shown if the match query is at least the - // 8th top scored suggestion, while rows will be shown if the matched query is - // at least the 7th top scored suggestion. If enabled, - // `omnibox_history_cluster_provider_score` becomes a no-op. - bool omnibox_history_cluster_provider_inherit_search_match_score = false; - - // If enabled, ranks the suggestion row below the default suggestion, but - // above the searches. Though whether it appears or not will depend on scores. - // Otherwise, ranks the suggestion among the search group; the exact position - // will depend on scores. - bool omnibox_history_cluster_provider_rank_above_searches = false; - - // Whether Journey suggestions from the `HistoryClusterProvider` can be - // surfaced from the shortcuts' provider. They will be scored according to the - // shortcuts' provider's scoring, which is more aggressive than the default - // 900 score the `HistoryClusterProvider` assigns. Journey suggestions will - // still be limited to 1, and will still be locked to the last suggestion - // slot. More aggressive scoring won't affect ranking, but visibility. If - // disabled, journey suggestions will still be added to the table, but - // filtered out when retrieving suggesting; this is so that users in an - // experiment group with `omnibox_history_cluster_provider_shortcuts` enabled - // don't have lingering effects when they leave the group. Meaningless if - // `omnibox_history_cluster_provider` is disabled. - bool omnibox_history_cluster_provider_shortcuts = true; - - // Whether journey suggestions from the `ShortcutsProvider` can be default. - // Journey suggestions from the `HistoryClusterProvider` can never be default. - bool omnibox_history_cluster_provider_allow_default = false; - // If `omnibox_history_cluster_provider_on_navigation_intents` is false, this // threshold helps determine when the user is intending to perform a // navigation. Meaningless if either `omnibox_history_cluster_provider` is @@ -345,13 +314,6 @@ // WebUI features and params. - // Whether show either the hide visits thumbs-down or menu item on individual - // visits of persisted clusters. Which is shown depends on `hide_visits_icon`. - bool hide_visits = false; - - // Whether to the icon or menu item. - bool hide_visits_icon = true; - // Whether new tab groups created by "Open all in new tab group" should be // named after the cluster title. If false, the new tab group is anonymous, // which is the pre-M115 behavior.
diff --git a/components/history_clusters/core/features.cc b/components/history_clusters/core/features.cc index fc86dd54da..eb9dd042 100644 --- a/components/history_clusters/core/features.cc +++ b/components/history_clusters/core/features.cc
@@ -92,12 +92,6 @@ "HistoryClustersNavigationContextClustering", base::FEATURE_ENABLED_BY_DEFAULT); -// TODO(manukh): Launched with chromium roll out in m114 3/29/23. Clean feature -// code when m114 reaches stable 5/30. -BASE_FEATURE(kHideVisits, - "HistoryClustersHideVisits", - base::FEATURE_ENABLED_BY_DEFAULT); - // Killswitch only. BASE_FEATURE(kJourneysNamedNewTabGroups, "JourneysNamedNewTabGroups",
diff --git a/components/history_clusters/core/features.h b/components/history_clusters/core/features.h index fd9d374..fe483d7 100644 --- a/components/history_clusters/core/features.h +++ b/components/history_clusters/core/features.h
@@ -75,10 +75,6 @@ // batches. BASE_DECLARE_FEATURE(kHistoryClustersNavigationContextClustering); -// Enables either the hide visits thumbs-down or menu item on individual visits -// of persisted clusters. -BASE_DECLARE_FEATURE(kHideVisits); - // Enables Journeys creating new tab groups that have names derived from the // cluster title. If disabled, new tab groups are anonymous. BASE_DECLARE_FEATURE(kJourneysNamedNewTabGroups);
diff --git a/components/memory_system/BUILD.gn b/components/memory_system/BUILD.gn index 3f14593c..38e8729 100644 --- a/components/memory_system/BUILD.gn +++ b/components/memory_system/BUILD.gn
@@ -57,4 +57,8 @@ if (build_allocation_stack_trace_recorder) { deps += [ "//components/allocation_recorder/crash_client" ] } + + if (is_ios) { + deps += [ "//base/ios" ] + } }
diff --git a/components/metrics/metrics_log_store.cc b/components/metrics/metrics_log_store.cc index a18824d..d88e247 100644 --- a/components/metrics/metrics_log_store.cc +++ b/components/metrics/metrics_log_store.cc
@@ -25,22 +25,23 @@ MetricsLogsEventManager* logs_event_manager) : unsent_logs_loaded_(false), logs_event_manager_(logs_event_manager), - initial_log_queue_(std::make_unique<UnsentLogStoreMetricsImpl>(), - local_state, - prefs::kMetricsInitialLogs, - prefs::kMetricsInitialLogsMetadata, - storage_limits.min_initial_log_queue_count, - storage_limits.min_initial_log_queue_size, - 0, // Each individual initial log can be any size. - signing_key, - logs_event_manager), + initial_log_queue_( + std::make_unique<UnsentLogStoreMetricsImpl>(), + local_state, + prefs::kMetricsInitialLogs, + prefs::kMetricsInitialLogsMetadata, + UnsentLogStore::UnsentLogStoreLimits{ + storage_limits.initial_log_queue_limits.min_log_count, + storage_limits.initial_log_queue_limits.min_queue_size_bytes, + // Each individual initial log can be any size. + /*max_log_size_bytes=*/0}, + signing_key, + logs_event_manager), ongoing_log_queue_(std::make_unique<UnsentLogStoreMetricsImpl>(), local_state, prefs::kMetricsOngoingLogs, prefs::kMetricsOngoingLogsMetadata, - storage_limits.min_ongoing_log_queue_count, - storage_limits.min_ongoing_log_queue_size, - storage_limits.max_ongoing_log_size, + storage_limits.ongoing_log_queue_limits, signing_key, logs_event_manager) {}
diff --git a/components/metrics/metrics_log_store.h b/components/metrics/metrics_log_store.h index 8565a0cf..a3a12f9 100644 --- a/components/metrics/metrics_log_store.h +++ b/components/metrics/metrics_log_store.h
@@ -39,25 +39,14 @@ class MetricsLogStore : public LogStore { public: // Configurable limits for ensuring and restricting local log storage. - // - // |min_{initial,ongoing}_log_queue_count| are the minimum numbers of unsent - // logs that UnsentLogStore must persist before deleting old logs. - // - // |min_{initial,ongoing}_log_queue_size| are the minimum numbers of bytes in - // total across all logs within the initial or ongoing log queue that - // UnsentLogStore must persist before deleting old logs. - // - // If both |min_..._log_queue_count| and |min_..._log_queue_size| are 0, then - // this LogStore won't persist unsent logs to local storage. - // - // |max_ongoing_log_size| is the maximum size of any individual ongoing log. - // When set to 0, no limits are imposed, i.e. individual logs can be any size. struct StorageLimits { - size_t min_initial_log_queue_count = 0; - size_t min_initial_log_queue_size = 0; - size_t min_ongoing_log_queue_count = 0; - size_t min_ongoing_log_queue_size = 0; - size_t max_ongoing_log_size = 0; + // Log store limits for |initial_log_queue_|. See + // comments at //components/metrics/unsent_log_store.h for more details. + UnsentLogStore::UnsentLogStoreLimits initial_log_queue_limits; + + // Log store limits for |ongoing_log_queue_|.See + // comments at //components/metrics/unsent_log_store.h for more details. + UnsentLogStore::UnsentLogStoreLimits ongoing_log_queue_limits; }; // Constructs a MetricsLogStore that persists data into |local_state|.
diff --git a/components/metrics/metrics_log_store_unittest.cc b/components/metrics/metrics_log_store_unittest.cc index a1a808e..aeb51a9 100644 --- a/components/metrics/metrics_log_store_unittest.cc +++ b/components/metrics/metrics_log_store_unittest.cc
@@ -24,9 +24,10 @@ service, kTestPrefName, nullptr, - /*min_log_count=*/3, - /*min_log_bytes=*/1, - /*max_log_size=*/0, + // Set to 3 so logs are not dropped in the test. + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 3, + }, /*signing_key=*/std::string(), /*logs_event_manager=*/nullptr) {} ~TestUnsentLogStore() override = default; @@ -203,7 +204,7 @@ TEST_F(MetricsLogStoreTest, LargeLogDiscarding) { // Set the size threshold very low, to verify that it's honored. - client_.set_max_ongoing_log_size(1); + client_.set_max_ongoing_log_size_bytes(1); MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(), /*signing_key=*/std::string(), /*logs_event_manager=*/nullptr);
diff --git a/components/metrics/metrics_reporting_service.cc b/components/metrics/metrics_reporting_service.cc index 4b1bb037..7f41729 100644 --- a/components/metrics/metrics_reporting_service.cc +++ b/components/metrics/metrics_reporting_service.cc
@@ -31,7 +31,8 @@ MetricsLogsEventManager* logs_event_manager_) : ReportingService(client, local_state, - client->GetStorageLimits().max_ongoing_log_size, + client->GetStorageLimits() + .ongoing_log_queue_limits.max_log_size_bytes, logs_event_manager_), metrics_log_store_(local_state, client->GetStorageLimits(),
diff --git a/components/metrics/metrics_service_client.cc b/components/metrics/metrics_service_client.cc index 8c239e0..b6471fc5 100644 --- a/components/metrics/metrics_service_client.cc +++ b/components/metrics/metrics_service_client.cc
@@ -19,12 +19,14 @@ namespace metrics { -const base::FeatureParam<int> kMaxLogQueueBytes{ +// TODO(b/282078734): Names "max_*" are the original names when the experiment +// first started. These should be renamed after the experiment is over. +const base::FeatureParam<int> kMinLogQueueBytes{ &features::kStructuredMetrics, "max_log_queue_bytes", 300 * 1024 // 300 KiB }; -const base::FeatureParam<int> kMaxOngoingLogQueueCount{ +const base::FeatureParam<int> kMinOngoingLogQueueCount{ &features::kStructuredMetrics, "max_ongoing_log_queue_count", 8}; namespace { @@ -32,6 +34,9 @@ // The minimum time in seconds between consecutive metrics report uploads. constexpr int kMetricsUploadIntervalSecMinimum = 20; +// Initial logs can be of any size. +constexpr size_t kMaxInitialLogSize = 0; + // If a metrics log upload fails, and the transmission is over this byte count, // then we will discard the log, and not try to retransmit it. We also don't // persist the log to the prefs for transmission during the next chrome session @@ -43,9 +48,8 @@ constexpr size_t kMaxOngoingLogSize = 100 * 1024; // 100 KiB #endif // BUILDFLAG(IS_CHROMEOS) -// The minimum number of "initial" logs to save, and hope to send during a -// future Chrome session. Initial logs contain crash stats, and are pretty -// small. +// The minimum number of "initial" logs to save before logs are dropped. Initial +// logs contain crash stats, and are pretty small. constexpr size_t kMinInitialLogQueueCount = 20; } // namespace @@ -150,17 +154,22 @@ } MetricsLogStore::StorageLimits MetricsServiceClient::GetStorageLimits() const { - // TODO(b/283126298): Rename min_* variable names to max_* to more accurately - // reflect what the variable names represent. return { - /*min_initial_log_queue_count=*/kMinInitialLogQueueCount, - /*min_initial_log_queue_size=*/ - static_cast<size_t>(kMaxLogQueueBytes.Get()), - /*min_ongoing_log_queue_count=*/ - static_cast<size_t>(kMaxOngoingLogQueueCount.Get()), - /*min_ongoing_log_queue_size=*/ - static_cast<size_t>(kMaxLogQueueBytes.Get()), - /*max_ongoing_log_size=*/kMaxOngoingLogSize, + .initial_log_queue_limits = + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = kMinInitialLogQueueCount, + .min_queue_size_bytes = + static_cast<size_t>(kMinLogQueueBytes.Get()), + .max_log_size_bytes = static_cast<size_t>(kMaxInitialLogSize), + }, + .ongoing_log_queue_limits = + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = + static_cast<size_t>(kMinOngoingLogQueueCount.Get()), + .min_queue_size_bytes = + static_cast<size_t>(kMinLogQueueBytes.Get()), + .max_log_size_bytes = static_cast<size_t>(kMaxOngoingLogSize), + }, }; }
diff --git a/components/metrics/metrics_service_client.h b/components/metrics/metrics_service_client.h index 919c70e5..8c0e4d7 100644 --- a/components/metrics/metrics_service_client.h +++ b/components/metrics/metrics_service_client.h
@@ -40,14 +40,17 @@ class StructuredMetricsService; } -// The maximum capacity (bytes) of the queue for logs to be persisted. This -// will be applied to both log queues (initial/ongoing). This ensures that a -// reasonable amount of history will be stored even if there is a long series of -// very small logs. -extern const base::FeatureParam<int> kMaxLogQueueBytes; +// The minimum number bytes of the queue to be persisted before logs are +// dropped. This will be applied to both log queues (initial/ongoing). This +// ensures that a reasonable amount of history will be stored even if there is a +// long series of very small logs. +// +// Refer to //components/metrics/unsent_log_store.h for more details on when +// logs are dropped. +extern const base::FeatureParam<int> kMinLogQueueBytes; -// The maximum number of ongoing logs to persist in the queue to send during -// this or future sessions. +// The minimum number of ongoing logs to persist in the queue before logs are +// dropped. // // Note that each ongoing log may be pretty large, since "initial" logs must // first be sent before any ongoing logs are transmitted. "Initial" logs will @@ -58,7 +61,10 @@ // A "standard shutdown" will create a small log, including just the data that // was not yet been transmitted, and that is normal (to have exactly one // ongoing_log_ at startup). -extern const base::FeatureParam<int> kMaxOngoingLogQueueCount; +// +// Refer to //components/metrics/unsent_log_store.h for more details on when +// logs are dropped. +extern const base::FeatureParam<int> kMinOngoingLogQueueCount; // An abstraction of operations that depend on the embedder's (e.g. Chrome) // environment.
diff --git a/components/metrics/metrics_service_observer_unittest.cc b/components/metrics/metrics_service_observer_unittest.cc index 70e2725..89d55eb 100644 --- a/components/metrics/metrics_service_observer_unittest.cc +++ b/components/metrics/metrics_service_observer_unittest.cc
@@ -229,7 +229,7 @@ // Set the max log size to be 1 byte so that pretty much all logs will be // trimmed. We don't set it to 0 bytes because that is a special value that // represents no max size. - client.set_max_ongoing_log_size(1); + client.set_max_ongoing_log_size_bytes(1); MetricsService service(GetMetricsStateManager(), &client, local_state()); @@ -272,11 +272,11 @@ TEST_F(MetricsServiceObserverTest, TrimLongLogList) { TestMetricsServiceClient client; - // Set the mininimum log count to 1 and minimum log size to 1 byte. This + // Set the minimum log count to 1 and minimum log size to 1 byte. This // essentially means that the log store, when trimming logs, will only keep // the most recent one. I.e., after storing one log, it will trim the rest // due to having stored enough logs. - client.set_min_ongoing_log_queue_size(1); + client.set_min_ongoing_log_queue_size_bytes(1); client.set_min_ongoing_log_queue_count(1); MetricsService service(GetMetricsStateManager(), &client, local_state()); @@ -444,9 +444,7 @@ auto alternate_ongoing_log_store = std::make_unique<UnsentLogStore>( std::make_unique<UnsentLogStoreMetricsImpl>(), local_state(), prefs::kMetricsOngoingLogs, prefs::kMetricsOngoingLogsMetadata, - storage_limits.min_ongoing_log_queue_count, - storage_limits.min_ongoing_log_queue_size, - storage_limits.max_ongoing_log_size, client.GetUploadSigningKey(), + storage_limits.ongoing_log_queue_limits, client.GetUploadSigningKey(), // |logs_event_manager| will be set by |test_log_store| directly in // MetricsLogStore::SetAlternateOngoingLogStore(). /*logs_event_manager=*/nullptr);
diff --git a/components/metrics/metrics_service_unittest.cc b/components/metrics/metrics_service_unittest.cc index 4b5964e..ccb10da 100644 --- a/components/metrics/metrics_service_unittest.cc +++ b/components/metrics/metrics_service_unittest.cc
@@ -64,9 +64,10 @@ service, kTestPrefName, nullptr, - /*min_log_count=*/3, - /*min_log_bytes=*/1, - /*max_log_size=*/0, + // Set to 3 so logs are not dropped in the test. + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 3, + }, /*signing_key=*/std::string(), /*logs_event_manager=*/nullptr) {} ~TestUnsentLogStore() override = default;
diff --git a/components/metrics/structured/reporting/structured_metrics_reporting_service.cc b/components/metrics/structured/reporting/structured_metrics_reporting_service.cc index 671c127e..ebd0adc 100644 --- a/components/metrics/structured/reporting/structured_metrics_reporting_service.cc +++ b/components/metrics/structured/reporting/structured_metrics_reporting_service.cc
@@ -14,18 +14,16 @@ StructuredMetricsReportingService::StructuredMetricsReportingService( MetricsServiceClient* client, PrefService* local_state, - const StorageLimits& storage_limits) + const UnsentLogStore::UnsentLogStoreLimits& storage_limits) : ReportingService(client, local_state, - storage_limits.max_log_size, + storage_limits.max_log_size_bytes, /*logs_event_manager=*/nullptr), log_store_(std::make_unique<StructuredMetricsLogMetrics>(), local_state, prefs::kLogStoreName, /* metadata_pref_name=*/nullptr, - storage_limits.min_log_queue_count, - storage_limits.min_log_queue_size, - storage_limits.max_log_size, + storage_limits, client->GetUploadSigningKey(), /* logs_event_manager=*/nullptr) {}
diff --git a/components/metrics/structured/reporting/structured_metrics_reporting_service.h b/components/metrics/structured/reporting/structured_metrics_reporting_service.h index 3e5633f..8d05465 100644 --- a/components/metrics/structured/reporting/structured_metrics_reporting_service.h +++ b/components/metrics/structured/reporting/structured_metrics_reporting_service.h
@@ -17,19 +17,13 @@ namespace metrics::structured::reporting { -// The limiting parameters of the log store and reporting service. -struct StorageLimits { - size_t min_log_queue_count = 0; - size_t min_log_queue_size = 0; - size_t max_log_size = 0; -}; - // A service that uploads Structured Metrics logs to the UMA server. class StructuredMetricsReportingService : public metrics::ReportingService { public: - StructuredMetricsReportingService(MetricsServiceClient* client, - PrefService* local_state, - const StorageLimits& storage_limits); + StructuredMetricsReportingService( + MetricsServiceClient* client, + PrefService* local_state, + const UnsentLogStore::UnsentLogStoreLimits& storage_limits); void StoreLog(const std::string& serialized_log, metrics::MetricsLogsEventManager::CreateReason reason);
diff --git a/components/metrics/structured/structured_metrics_provider_unittest.cc b/components/metrics/structured/structured_metrics_provider_unittest.cc index 6146478..434b47b 100644 --- a/components/metrics/structured/structured_metrics_provider_unittest.cc +++ b/components/metrics/structured/structured_metrics_provider_unittest.cc
@@ -75,6 +75,8 @@ task_environment_.AdvanceClock(base::Days(1000)); } + void TearDown() override { StructuredMetricsClient::Get()->UnsetDelegate(); } + base::FilePath TempDirPath() { return temp_dir_.GetPath(); } base::FilePath ProfileKeyFilePath() {
diff --git a/components/metrics/structured/structured_metrics_recorder_unittest.cc b/components/metrics/structured/structured_metrics_recorder_unittest.cc index bd9ae8c..3ac5a86 100644 --- a/components/metrics/structured/structured_metrics_recorder_unittest.cc +++ b/components/metrics/structured/structured_metrics_recorder_unittest.cc
@@ -173,6 +173,8 @@ .Append("device_keys"); } + void TearDown() override { StructuredMetricsClient::Get()->UnsetDelegate(); } + void Wait() { task_environment_.RunUntilIdle(); } void WriteTestingProfileKeys() {
diff --git a/components/metrics/structured/structured_metrics_service.cc b/components/metrics/structured/structured_metrics_service.cc index c5d3080..8159124 100644 --- a/components/metrics/structured/structured_metrics_service.cc +++ b/components/metrics/structured/structured_metrics_service.cc
@@ -97,7 +97,8 @@ } // Setup the reporting service. - const reporting::StorageLimits storage_limits = GetLogStoreLimits(); + const UnsentLogStore::UnsentLogStoreLimits storage_limits = + GetLogStoreLimits(); reporting_service_ = std::make_unique<reporting::StructuredMetricsReportingService>( @@ -175,11 +176,12 @@ reporting::StructuredMetricsReportingService::RegisterPrefs(registry); } -reporting::StorageLimits StructuredMetricsService::GetLogStoreLimits() { - return reporting::StorageLimits{ - .min_log_queue_count = static_cast<size_t>(kMinLogQueueCount.Get()), - .min_log_queue_size = static_cast<size_t>(kMinLogQueueSizeBytes.Get()), - .max_log_size = static_cast<size_t>(kMaxLogSizeBytes.Get()), +UnsentLogStore::UnsentLogStoreLimits +StructuredMetricsService::GetLogStoreLimits() { + return UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = static_cast<size_t>(kMinLogQueueCount.Get()), + .min_queue_size_bytes = static_cast<size_t>(kMinLogQueueSizeBytes.Get()), + .max_log_size_bytes = static_cast<size_t>(kMaxLogSizeBytes.Get()), }; }
diff --git a/components/metrics/structured/structured_metrics_service.h b/components/metrics/structured/structured_metrics_service.h index f6021d28..c330995 100644 --- a/components/metrics/structured/structured_metrics_service.h +++ b/components/metrics/structured/structured_metrics_service.h
@@ -11,6 +11,7 @@ #include "components/metrics/structured/reporting/structured_metrics_reporting_service.h" #include "components/metrics/structured/structured_metrics_recorder.h" #include "components/metrics/structured/structured_metrics_scheduler.h" +#include "components/metrics/unsent_log_store.h" FORWARD_DECLARE_TEST(StructuredMetricsServiceTest, RotateLogs); @@ -92,7 +93,7 @@ static std::string SerializeLog(const ChromeUserMetricsExtension& uma_proto); // Retrieves the storage parameters to control the reporting service. - static reporting::StorageLimits GetLogStoreLimits(); + static UnsentLogStore::UnsentLogStoreLimits GetLogStoreLimits(); // Manages on-device recording of events. std::unique_ptr<StructuredMetricsRecorder> recorder_;
diff --git a/components/metrics/structured/structured_metrics_service_unittest.cc b/components/metrics/structured/structured_metrics_service_unittest.cc index 0ebe17b..529af7d9 100644 --- a/components/metrics/structured/structured_metrics_service_unittest.cc +++ b/components/metrics/structured/structured_metrics_service_unittest.cc
@@ -69,15 +69,15 @@ StructuredMetricsServiceTest() { reporting::StructuredMetricsReportingService::RegisterPrefs( prefs_.registry()); - - Recorder::GetInstance()->SetUiTaskRunner( - task_environment_.GetMainThreadTaskRunner()); - StructuredMetricsClient::Get()->SetDelegate(&test_recorder_); } void SetUp() override { feature_list_.InitWithFeatures({kEnabledStructuredMetricsService}, {}); + Recorder::GetInstance()->SetUiTaskRunner( + task_environment_.GetMainThreadTaskRunner()); + StructuredMetricsClient::Get()->SetDelegate(&test_recorder_); + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); WriteTestingDeviceKeys(); @@ -87,6 +87,8 @@ WriteTestingProfileKeys(); } + void TearDown() override { StructuredMetricsClient::Get()->UnsetDelegate(); } + void Init() { auto recorder = std::unique_ptr<StructuredMetricsRecorder>( new StructuredMetricsRecorder(DeviceKeyFilePath(), base::Seconds(0), @@ -149,8 +151,10 @@ metrics::UnsentLogStore result_unsent_log_store( std::make_unique<UnsentLogStoreMetricsImpl>(), &prefs_, prefs::kLogStoreName, /*metadata_pref_name=*/nullptr, - /*min_log_count=*/3, /*min_log_bytes=*/1000, - /*max_log_size=*/0, + // Set to 3 so logs are not dropped in the test. + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 3, + }, /*signing_key=*/std::string(), /*logs_event_manager=*/nullptr);
diff --git a/components/metrics/test/test_metrics_service_client.h b/components/metrics/test/test_metrics_service_client.h index e6d03df..d3b39c9 100644 --- a/components/metrics/test/test_metrics_service_client.h +++ b/components/metrics/test/test_metrics_service_client.h
@@ -81,14 +81,14 @@ void set_should_reset_client_ids_on_cloned_install(bool state) { should_reset_client_ids_on_cloned_install_ = state; } - void set_max_ongoing_log_size(size_t bytes) { - storage_limits_.max_ongoing_log_size = bytes; + void set_max_ongoing_log_size_bytes(size_t bytes) { + storage_limits_.ongoing_log_queue_limits.max_log_size_bytes = bytes; } void set_min_ongoing_log_queue_count(size_t log_count) { - storage_limits_.min_ongoing_log_queue_count = log_count; + storage_limits_.ongoing_log_queue_limits.min_log_count = log_count; } - void set_min_ongoing_log_queue_size(size_t bytes) { - storage_limits_.min_ongoing_log_queue_size = bytes; + void set_min_ongoing_log_queue_size_bytes(size_t bytes) { + storage_limits_.ongoing_log_queue_limits.min_queue_size_bytes = bytes; } void set_synthetic_trial_registry( variations::SyntheticTrialRegistry* registry) {
diff --git a/components/metrics/unsent_log_store.cc b/components/metrics/unsent_log_store.cc index 7d6a2c2..a024a8e 100644 --- a/components/metrics/unsent_log_store.cc +++ b/components/metrics/unsent_log_store.cc
@@ -170,24 +170,21 @@ PrefService* local_state, const char* log_data_pref_name, const char* metadata_pref_name, - size_t min_log_count, - size_t min_log_bytes, - size_t max_log_size, + UnsentLogStoreLimits log_store_limits, const std::string& signing_key, MetricsLogsEventManager* logs_event_manager) : metrics_(std::move(metrics)), local_state_(local_state), log_data_pref_name_(log_data_pref_name), metadata_pref_name_(metadata_pref_name), - min_log_count_(min_log_count), - min_log_bytes_(min_log_bytes), - max_log_size_(max_log_size != 0 ? max_log_size : static_cast<size_t>(-1)), + log_store_limits_(log_store_limits), signing_key_(signing_key), logs_event_manager_(logs_event_manager), staged_log_index_(-1) { DCHECK(local_state_); // One of the limit arguments must be non-zero. - DCHECK(min_log_count_ > 0 || min_log_bytes_ > 0); + DCHECK(log_store_limits_.min_log_count > 0 || + log_store_limits_.min_queue_size_bytes > 0); } UnsentLogStore::~UnsentLogStore() = default; @@ -291,8 +288,8 @@ for (int i = list_.size() - 1; i >= 0; --i) { size_t log_size = list_[i]->compressed_log_data.length(); // Hit the caps, we can stop moving the logs. - if (bytes_used >= min_log_bytes_ && - writer.unsent_logs_count() >= min_log_count_) { + if (bytes_used >= log_store_limits_.min_queue_size_bytes && + writer.unsent_logs_count() >= log_store_limits_.min_log_count) { // The rest of the logs (including the current one) are trimmed. if (overwrite_in_memory_store) { NotifyLogsEvent(base::span<std::unique_ptr<LogInfo>>( @@ -301,8 +298,9 @@ } break; } - // Omit overly large individual logs. - if (log_size > max_log_size_) { + // Omit overly large individual logs if the value is non-zero. + if (log_store_limits_.max_log_size_bytes != 0 && + log_size > log_store_limits_.max_log_size_bytes) { metrics_->RecordDroppedLogSize(log_size); if (overwrite_in_memory_store) { NotifyLogEvent(MetricsLogsEventManager::LogEvent::kLogTrimmed,
diff --git a/components/metrics/unsent_log_store.h b/components/metrics/unsent_log_store.h index 40fc531..6f223b51 100644 --- a/components/metrics/unsent_log_store.h +++ b/components/metrics/unsent_log_store.h
@@ -31,6 +31,37 @@ // Maintains a list of unsent logs that are written and restored from disk. class UnsentLogStore : public LogStore { public: + // Configurable capacities for unsent log store. + // + // When saving logs to disk, stores either the first |min_log_count| logs, or + // at least |min_queue_size_bytes| bytes of logs. If |this| contains more than + // |min_log_count| logs AND a total bytes larger than |min_queue_size_bytes|, + // older logs will be dropped for newer logs. + // + // Either |min_queue_size_bytes| or |min_log_count| must be greater than 0. + // + // Individual logs greater than |max_log_size_bytes| will not be written to + // disk. If |max_log_size_bytes| is zero, logs of any size will be written to + // disk. + struct UnsentLogStoreLimits { + // Minimum number of unsent logs persisted before older logs are trimmed. + // + // log_count >= |min_log_count| AND total_queue_bytes >= + // |min_queue_size_bytes| for logs to be dropped. See comments for + // UnsentLogStoreLimits for more details. + size_t min_log_count = 0; + + // Minimum bytes that the queue can hold before older logs are trimmed. + // + // Number of logs >= |min_log_count| AND total_queue_size >= + // |min_queue_size_bytes| for logs to be dropped. See comments for + // UnsentLogStoreLimits for more details. + size_t min_queue_size_bytes = 0; + + // Logs greater than this size will not be written to disk. + size_t max_log_size_bytes = 0; + }; + // Constructs an UnsentLogStore that stores data in |local_state| under the // preference |log_data_pref_name|. // Calling code is responsible for ensuring that the lifetime of |local_state| @@ -40,12 +71,6 @@ // the unsent logs info while the unset logs are persisted. That info will be // recorded as UMA metrics in next browser startup. // - // When saving logs to disk, stores either the first |min_log_count| logs, or - // at least |min_log_bytes| bytes of logs, whichever is greater. - // - // If the optional |max_log_size| parameter is non-zero, all logs larger than - // that limit will be skipped when writing to disk. - // // |signing_key| is used to produce an HMAC-SHA256 signature of the logged // data, which will be uploaded with the log and used to validate data // integrity. @@ -56,9 +81,7 @@ PrefService* local_state, const char* log_data_pref_name, const char* metadata_pref_name, - size_t min_log_count, - size_t min_log_bytes, - size_t max_log_size, + UnsentLogStoreLimits log_store_limits, const std::string& signing_key, MetricsLogsEventManager* logs_event_manager); @@ -222,14 +245,7 @@ // nullptr if the metadata isn't desired. const char* metadata_pref_name_; - // We will keep at least this |min_log_count_| logs or |min_log_bytes_| bytes - // of logs, whichever is greater, when trimming logs. These apply after - // skipping logs greater than |max_log_size_|. - const size_t min_log_count_; - const size_t min_log_bytes_; - - // Logs greater than this size will not be written to disk. - const size_t max_log_size_; + const UnsentLogStoreLimits log_store_limits_; // Used to create a signature of log data, in order to verify reported data is // authentic.
diff --git a/components/metrics/unsent_log_store_unittest.cc b/components/metrics/unsent_log_store_unittest.cc index 58fecc60..9634b52 100644 --- a/components/metrics/unsent_log_store_unittest.cc +++ b/components/metrics/unsent_log_store_unittest.cc
@@ -93,9 +93,10 @@ service, kTestPrefName, /*metadata_pref_name=*/nullptr, - kLogCountLimit, - min_log_bytes, - /*max_log_size=*/0, + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = kLogCountLimit, + .min_queue_size_bytes = min_log_bytes, + }, /*signing_key=*/std::string(), /*logs_event_manager=*/nullptr) {} TestUnsentLogStore(PrefService* service, @@ -105,9 +106,10 @@ service, kTestPrefName, /*metadata_pref_name=*/nullptr, - kLogCountLimit, - min_log_bytes, - /*max_log_size=*/0, + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = kLogCountLimit, + .min_queue_size_bytes = min_log_bytes, + }, signing_key, /*logs_event_manager=*/nullptr) {} TestUnsentLogStore(std::unique_ptr<UnsentLogStoreMetrics> metrics, @@ -117,9 +119,11 @@ service, kTestPrefName, kTestMetaDataPrefName, - kLogCountLimit, - /*min_log_bytes=*/1, - max_log_size, + UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = kLogCountLimit, + .min_queue_size_bytes = 1, + .max_log_size_bytes = max_log_size, + }, /*signing_key=*/std::string(), /*logs_event_manager=*/nullptr) {}
diff --git a/components/nacl/browser/PRESUBMIT.py b/components/nacl/browser/PRESUBMIT.py index 16d806c..ac4e5c9e 100644 --- a/components/nacl/browser/PRESUBMIT.py +++ b/components/nacl/browser/PRESUBMIT.py
@@ -6,8 +6,6 @@ match the corresponding bad_message.h file. """ -USE_PYTHON3 = True - def _RunHistogramChecks(input_api, output_api, histogram_name): try: # Setup sys.path so that we can call histograms code.
diff --git a/components/omnibox/PRESUBMIT.py b/components/omnibox/PRESUBMIT.py index b8875d4..546537e4 100644 --- a/components/omnibox/PRESUBMIT.py +++ b/components/omnibox/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - import os def _CheckPedalsHistograms(input_api, output_api):
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index 6186dc9c4..564eb1f 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -386,6 +386,10 @@ deps += [ "//components/keep_alive_registry" ] } + if (is_ios) { + deps += [ "//base/ios" ] + } + if (use_blink) { sources += [ "actions/history_clusters_action.cc",
diff --git a/components/omnibox/browser/actions/history_clusters_action.cc b/components/omnibox/browser/actions/history_clusters_action.cc index 5d858c3..9c91b5f5 100644 --- a/components/omnibox/browser/actions/history_clusters_action.cc +++ b/components/omnibox/browser/actions/history_clusters_action.cc
@@ -176,7 +176,8 @@ HistoryClustersAction::GetOrCreateJavaObject(JNIEnv* env) const { if (!j_omnibox_action_) { j_omnibox_action_.Reset(BuildHistoryClustersAction( - env, reinterpret_cast<intptr_t>(this), strings_.hint, query_)); + env, reinterpret_cast<intptr_t>(this), strings_.hint, + strings_.accessibility_hint, query_)); } return base::android::ScopedJavaLocalRef<jobject>(j_omnibox_action_); }
diff --git a/components/omnibox/browser/actions/omnibox_action_factory_android.cc b/components/omnibox/browser/actions/omnibox_action_factory_android.cc index a2165d5..3dc9260 100644 --- a/components/omnibox/browser/actions/omnibox_action_factory_android.cc +++ b/components/omnibox/browser/actions/omnibox_action_factory_android.cc
@@ -44,11 +44,13 @@ JNIEnv* env, intptr_t instance, const std::u16string& hint, + const std::u16string& accessibility_hint, OmniboxPedalId pedal_id) { return base::android::ScopedJavaGlobalRef( Java_OmniboxActionFactory_buildOmniboxPedal( env, g_java_factory.Get(), instance, base::android::ConvertUTF16ToJavaString(env, hint), + base::android::ConvertUTF16ToJavaString(env, accessibility_hint), static_cast<int32_t>(pedal_id))); } @@ -56,11 +58,13 @@ JNIEnv* env, intptr_t instance, const std::u16string& hint, + const std::u16string& accessibility_hint, const std::string& query) { return base::android::ScopedJavaGlobalRef( Java_OmniboxActionFactory_buildHistoryClustersAction( env, g_java_factory.Get(), instance, base::android::ConvertUTF16ToJavaString(env, hint), + base::android::ConvertUTF16ToJavaString(env, accessibility_hint), base::android::ConvertUTF8ToJavaString(env, query))); } @@ -68,12 +72,15 @@ JNIEnv* env, intptr_t instance, const std::u16string& hint, + const std::u16string& accessibility_hint, int action_type, const std::string& action_uri) { return base::android::ScopedJavaGlobalRef( Java_OmniboxActionFactory_buildActionInSuggest( env, g_java_factory.Get(), instance, - base::android::ConvertUTF16ToJavaString(env, hint), action_type, + base::android::ConvertUTF16ToJavaString(env, hint), + base::android::ConvertUTF16ToJavaString(env, accessibility_hint), + action_type, base::android::ConvertUTF8ToJavaString(env, action_uri))); }
diff --git a/components/omnibox/browser/actions/omnibox_action_factory_android.h b/components/omnibox/browser/actions/omnibox_action_factory_android.h index 5ae79dd..eb97fc4d 100644 --- a/components/omnibox/browser/actions/omnibox_action_factory_android.h +++ b/components/omnibox/browser/actions/omnibox_action_factory_android.h
@@ -16,18 +16,21 @@ JNIEnv* env, intptr_t instance, const std::u16string& hint, + const std::u16string& accessibility_hint, OmniboxPedalId pedal_id); base::android::ScopedJavaGlobalRef<jobject> BuildHistoryClustersAction( JNIEnv* env, intptr_t instance, const std::u16string& hint, + const std::u16string& accessibility_hint, const std::string& query); base::android::ScopedJavaGlobalRef<jobject> BuildOmniboxActionInSuggest( JNIEnv* env, intptr_t instance, const std::u16string& hint, + const std::u16string& accessibility_hint, int action_type, const std::string& action_uri);
diff --git a/components/omnibox/browser/actions/omnibox_action_in_suggest.cc b/components/omnibox/browser/actions/omnibox_action_in_suggest.cc index 6144726..c64d689 100644 --- a/components/omnibox/browser/actions/omnibox_action_in_suggest.cc +++ b/components/omnibox/browser/actions/omnibox_action_in_suggest.cc
@@ -85,7 +85,7 @@ ToActionHint(action_info.action_type()), ToActionContents(action_info.action_type()), IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST_SUFFIX, - IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST), + ToActionContents(action_info.action_type())), {}), action_info{std::move(action_info)}, search_terms_args{std::move(search_terms_args)} {} @@ -98,7 +98,8 @@ if (!j_omnibox_action_) { j_omnibox_action_.Reset(BuildOmniboxActionInSuggest( env, reinterpret_cast<intptr_t>(this), strings_.hint, - action_info.action_type(), action_info.action_uri())); + strings_.accessibility_hint, action_info.action_type(), + action_info.action_uri())); } return base::android::ScopedJavaLocalRef<jobject>(j_omnibox_action_); }
diff --git a/components/omnibox/browser/actions/omnibox_action_in_suggest_unittest.cc b/components/omnibox/browser/actions/omnibox_action_in_suggest_unittest.cc index 7129215..3278d31 100644 --- a/components/omnibox/browser/actions/omnibox_action_in_suggest_unittest.cc +++ b/components/omnibox/browser/actions/omnibox_action_in_suggest_unittest.cc
@@ -74,21 +74,21 @@ IDS_OMNIBOX_ACTION_IN_SUGGEST_CALL_HINT, IDS_OMNIBOX_ACTION_IN_SUGGEST_CALL_CONTENTS, IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST_SUFFIX, - IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST, + IDS_OMNIBOX_ACTION_IN_SUGGEST_CALL_CONTENTS, }, { omnibox::ActionInfo_ActionType_DIRECTIONS, IDS_OMNIBOX_ACTION_IN_SUGGEST_DIRECTIONS_HINT, IDS_OMNIBOX_ACTION_IN_SUGGEST_DIRECTIONS_CONTENTS, IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST_SUFFIX, - IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST, + IDS_OMNIBOX_ACTION_IN_SUGGEST_DIRECTIONS_CONTENTS, }, { omnibox::ActionInfo_ActionType_REVIEWS, IDS_OMNIBOX_ACTION_IN_SUGGEST_REVIEWS_HINT, IDS_OMNIBOX_ACTION_IN_SUGGEST_REVIEWS_CONTENTS, IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST_SUFFIX, - IDS_ACC_OMNIBOX_ACTION_IN_SUGGEST, + IDS_OMNIBOX_ACTION_IN_SUGGEST_REVIEWS_CONTENTS, }}; for (const auto& test_case : test_cases) {
diff --git a/components/omnibox/browser/actions/omnibox_pedal.cc b/components/omnibox/browser/actions/omnibox_pedal.cc index 5b2f229..897cb78 100644 --- a/components/omnibox/browser/actions/omnibox_pedal.cc +++ b/components/omnibox/browser/actions/omnibox_pedal.cc
@@ -321,8 +321,9 @@ base::android::ScopedJavaLocalRef<jobject> OmniboxPedal::GetOrCreateJavaObject( JNIEnv* env) const { if (!j_omnibox_action_) { - j_omnibox_action_.Reset(BuildOmniboxPedal( - env, reinterpret_cast<intptr_t>(this), strings_.hint, PedalId())); + j_omnibox_action_.Reset( + BuildOmniboxPedal(env, reinterpret_cast<intptr_t>(this), strings_.hint, + strings_.accessibility_hint, PedalId())); } return base::android::ScopedJavaLocalRef<jobject>(j_omnibox_action_); }
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxAction.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxAction.java index 7c909f6..df44eed 100644 --- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxAction.java +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxAction.java
@@ -42,16 +42,19 @@ public final @OmniboxActionId int actionId; /** The string to present/announce to the user when the action is shown. */ public final @NonNull String hint; + /** The text to announce when the action chip is focused. */ + public final @NonNull String accessibilityHint; /** The icon to use to decorate the Action chip. */ public final @NonNull ChipIcon icon; /** The corresponding native instance, or 0 if the native instance is not available. */ private long mNativeInstance; public OmniboxAction(@OmniboxActionId int actionId, long nativeInstance, @NonNull String hint, - @Nullable ChipIcon icon) { + @NonNull String accessibilityHint, @Nullable ChipIcon icon) { assert !TextUtils.isEmpty(hint); this.actionId = actionId; this.hint = hint; + this.accessibilityHint = accessibilityHint; this.icon = icon != null ? icon : DEFAULT_ICON; mNativeInstance = nativeInstance; }
diff --git a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxActionFactory.java b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxActionFactory.java index 34856b63..9dfb821 100644 --- a/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxActionFactory.java +++ b/components/omnibox/browser/android/java/src/org/chromium/components/omnibox/action/OmniboxActionFactory.java
@@ -17,18 +17,20 @@ * Create a new OmniboxPedal. * * @param hint the title displayed on the chip + * @param accessibilityHint the text to be announced to the accessibility-enabled users * @param pedalId the specific kind of pedal to create * @return new instance of an OmniboxPedal */ @CalledByNative @NonNull - OmniboxAction buildOmniboxPedal( - long instance, @NonNull String hint, @OmniboxPedalId int pedalId); + OmniboxAction buildOmniboxPedal(long instance, @NonNull String hint, + @NonNull String accessibilityHint, @OmniboxPedalId int pedalId); /** * Create a new OmniboxActionInSuggest. * * @param hint the title displayed on the chip + * @param accessibilityHint the text to be announced to the accessibility-enabled users * @param actionType the specific type of an action matching the * {@link EntityInfoProto.ActionInfo.ActionType} * @param actionUri the corresponding action URI/URL (serialized intent) @@ -37,19 +39,21 @@ @CalledByNative @NonNull OmniboxAction buildActionInSuggest(long instance, @NonNull String hint, + @NonNull String accessibilityHint, /* EntityInfoProto.ActionInfo.ActionType */ int actionType, @NonNull String actionUri); /** * Create a new HistoryClustersAction. * * @param hint the title displayed on the chip + * @param accessibilityHint the text to be announced to the accessibility-enabled users * @param query the user-specific query associated with History Clusters * @return new instance of an HistoryClustersAction */ @CalledByNative @NonNull - OmniboxAction buildHistoryClustersAction( - long instance, @NonNull String hint, @NonNull String query); + OmniboxAction buildHistoryClustersAction(long instance, @NonNull String hint, + @NonNull String accessibilityHint, @NonNull String query); @NativeMethods public interface Natives {
diff --git a/components/omnibox/browser/autocomplete_result.cc b/components/omnibox/browser/autocomplete_result.cc index 1fd89221..68ec6f7 100644 --- a/components/omnibox/browser/autocomplete_result.cc +++ b/components/omnibox/browser/autocomplete_result.cc
@@ -542,7 +542,9 @@ // - In every case, HISTORY_CLUSTERS is preferred over PEDALs. // - TAB_SWITCH actions are not considered because they're never attached. if constexpr (is_android) { - static constexpr size_t ACTIONS_IN_SUGGEST_CUTOFF_THRESHOLD = 2; + const size_t ACTIONS_IN_SUGGEST_CUTOFF_THRESHOLD = + OmniboxFieldTrial::kActionsInSuggestPromoteEntitySuggestion.Get() ? 1 + : 2; static constexpr size_t PEDALS_CUTOFF_THRESHOLD = 3; std::vector<OmniboxActionId> include_all{OmniboxActionId::ACTION_IN_SUGGEST, OmniboxActionId::HISTORY_CLUSTERS, @@ -1394,13 +1396,9 @@ if (AutocompleteMatch::IsStarterPackType(m.type)) return 0; #if !BUILDFLAG(IS_IOS) - // Group history cluster suggestions above or with searches. - if (m.type == AutocompleteMatchType::HISTORY_CLUSTER) { - return history_clusters::GetConfig() - .omnibox_history_cluster_provider_rank_above_searches - ? 0 - : 1; - } + // Group history cluster suggestions with searches. + if (m.type == AutocompleteMatchType::HISTORY_CLUSTER) + return 1; #endif // !BUILDFLAG(IS_IOS) if (AutocompleteMatch::IsSearchType(m.type)) return 1;
diff --git a/components/omnibox/browser/autocomplete_result_unittest.cc b/components/omnibox/browser/autocomplete_result_unittest.cc index e7d42abf..63f834c6 100644 --- a/components/omnibox/browser/autocomplete_result_unittest.cc +++ b/components/omnibox/browser/autocomplete_result_unittest.cc
@@ -2117,6 +2117,8 @@ {"url_3", AutocompleteMatchType::HISTORY_CLUSTER}, }; PopulateAutocompleteMatchesFromTestData(data, std::size(data), &matches); + for (auto& m : matches) + m.allowed_to_be_default_match = false; AutocompleteInput input(u"a", metrics::OmniboxEventProto::OTHER, TestSchemeClassifier()); @@ -2564,19 +2566,11 @@ EXPECT_THAT(test({n, n, td, td}), testing::ElementsAre(td, td)); EXPECT_THAT(test({n, n, td, t}), testing::ElementsAre(td, t)); + // When there are both history cluster and tail suggestions, history cluster + // suggestions should be hidden. // A history cluster suggestion. CullTailTestMatch h{u"H", AutocompleteMatchType::HISTORY_CLUSTER, false}; - // When there are both history cluster and tail suggestions, tail suggestions - // should be hidden. - EXPECT_THAT(test({nd, td, t, h}), testing::ElementsAre(nd, h)); - - { - // When there are both history cluster and tail suggestions, history cluster - // suggestions should be hidden. - base::test::ScopedFeatureList feature_list{ - omnibox::kPreferTailOverHistoryClusterSuggestions}; - EXPECT_THAT(test({nd, td, t, h}), testing::ElementsAre(nd, tdp, t)); - } + EXPECT_THAT(test({nd, td, t, h}), testing::ElementsAre(nd, tdp, t)); } #if !(BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_IOS))
diff --git a/components/omnibox/browser/bookmark_provider.cc b/components/omnibox/browser/bookmark_provider.cc index 47a1231..5ff8b09 100644 --- a/components/omnibox/browser/bookmark_provider.cc +++ b/components/omnibox/browser/bookmark_provider.cc
@@ -110,12 +110,6 @@ const std::u16string fixed_up_input(FixupUserInput(adjusted_input).second); for (auto& bookmark_match : matches) { - if (OmniboxFieldTrial::ShouldDisableCGIParamMatching()) { - RemoveQueryParamKeyMatches(bookmark_match); - if (bookmark_match.title_match_positions.empty() && - bookmark_match.url_match_positions.empty()) - continue; - } // Score the TitledUrlMatch. If its score is greater than 0 then the // AutocompleteMatch is created and added to matches_. auto [relevance, bookmark_count] = @@ -288,21 +282,3 @@ relevance = std::min(kMaxBookmarkScore, relevance); return {relevance, url_node_count}; } - -void BookmarkProvider::RemoveQueryParamKeyMatches(TitledUrlMatch& match) { - const GURL& url = match.node->GetTitledUrlNodeUrl(); - if (!url.has_query()) - return; - - // Remove any matches that are for query param keys. Since bookmark provider - // match positions are always at the beginning of words, we can just look at - // the preceding character for a '?' or '&' character. - base::EraseIf(match.url_match_positions, - [url](TitledUrlMatch::MatchPosition& position) { - size_t query_begin = - url.parsed_for_possibly_invalid_spec().query.begin; - return ((query_begin <= position.first) && - (url.spec().at(position.first - 1) == '?' || - url.spec().at(position.first - 1) == '&')); - }); -}
diff --git a/components/omnibox/browser/bookmark_provider.h b/components/omnibox/browser/bookmark_provider.h index 91e5d02..2b96545 100644 --- a/components/omnibox/browser/bookmark_provider.h +++ b/components/omnibox/browser/bookmark_provider.h
@@ -60,10 +60,6 @@ std::pair<int, int> CalculateBookmarkMatchRelevance( const bookmarks::TitledUrlMatch& match) const; - // Removes any URL matches for query parameter keys (if the matching word - // starts immediately after a '?' or '&'). - void RemoveQueryParamKeyMatches(bookmarks::TitledUrlMatch& match); - const raw_ptr<AutocompleteProviderClient> client_; const raw_ptr<bookmarks::BookmarkModel> local_or_syncable_bookmark_model_; const raw_ptr<bookmarks::BookmarkModel, DanglingUntriaged>
diff --git a/components/omnibox/browser/history_cluster_provider.cc b/components/omnibox/browser/history_cluster_provider.cc index 8e395db..be469216 100644 --- a/components/omnibox/browser/history_cluster_provider.cc +++ b/components/omnibox/browser/history_cluster_provider.cc
@@ -159,11 +159,7 @@ // Ideally, relevance would depend on how many keywords matched, how // significant the keywords were, how significant their clusters were etc. match.relevance = - history_clusters::GetConfig() - .omnibox_history_cluster_provider_inherit_search_match_score - ? search_match.relevance - 1 - : history_clusters::GetConfig() - .omnibox_history_cluster_provider_score; + history_clusters::GetConfig().omnibox_history_cluster_provider_score; const auto& text = search_match.contents;
diff --git a/components/omnibox/browser/omnibox_field_trial.cc b/components/omnibox/browser/omnibox_field_trial.cc index 932f3fe..b8e7838 100644 --- a/components/omnibox/browser/omnibox_field_trial.cc +++ b/components/omnibox/browser/omnibox_field_trial.cc
@@ -661,10 +661,6 @@ return constraint; } -bool OmniboxFieldTrial::ShouldDisableCGIParamMatching() { - return base::FeatureList::IsEnabled(omnibox::kDisableCGIParamMatching); -} - bool OmniboxFieldTrial::IsSiteSearchStarterPackEnabled() { return base::FeatureList::IsEnabled(omnibox::kSiteSearchStarterPack); } @@ -712,9 +708,7 @@ } bool OmniboxFieldTrial::IsGM3TextStyleEnabled() { - return features::GetChromeRefresh2023Level() == - features::ChromeRefresh2023Level::kLevel2 || - base::FeatureList::IsEnabled(omnibox::kOmniboxSteadyStateTextStyle); + return base::FeatureList::IsEnabled(omnibox::kOmniboxSteadyStateTextStyle); } // In order to control the value of this "font size" param via Finch, the
diff --git a/components/omnibox/browser/omnibox_field_trial.h b/components/omnibox/browser/omnibox_field_trial.h index 80335cc..403f298 100644 --- a/components/omnibox/browser/omnibox_field_trial.h +++ b/components/omnibox/browser/omnibox_field_trial.h
@@ -349,10 +349,6 @@ // Functions can be used in both non-incognito and incognito. std::string OnDeviceHeadModelLocaleConstraint(bool is_incognito); -// Returns true if CGI parameter names should not be considered when scoring -// suggestions. -bool ShouldDisableCGIParamMatching(); - // If true, enables a "starter pack" of @history, @bookmarks, and @settings // scopes for Site Search. bool IsSiteSearchStarterPackEnabled();
diff --git a/components/omnibox/browser/omnibox_view.cc b/components/omnibox/browser/omnibox_view.cc index 6af17529..5929229 100644 --- a/components/omnibox/browser/omnibox_view.cc +++ b/components/omnibox/browser/omnibox_view.cc
@@ -170,8 +170,7 @@ OmniboxView::~OmniboxView() = default; bool OmniboxView::IsEditingOrEmpty() const { - return (model() && model()->user_input_in_progress()) || - (GetOmniboxTextLength() == 0); + return model()->user_input_in_progress() || GetOmniboxTextLength() == 0; } // TODO (manukh) OmniboxView::GetIcon is very similar to @@ -192,14 +191,6 @@ return ui::ImageModel(); #else - if (!model()) { - AutocompleteMatch fake_match; - fake_match.type = AutocompleteMatchType::URL_WHAT_YOU_TYPED; - const gfx::VectorIcon& vector_icon = fake_match.GetVectorIcon(false); - return ui::ImageModel::FromVectorIcon(vector_icon, color_current_page_icon, - dip_size); - } - if (model()->ShouldShowCurrentPageIcon()) { LocationBarModel* location_bar_model = edit_model_delegate_->GetLocationBarModel(); @@ -259,9 +250,7 @@ } void OmniboxView::SetUserText(const std::u16string& text, bool update_popup) { - if (model()) { - model()->SetUserText(text); - } + model()->SetUserText(text); SetWindowTextAndCaretPos(text, text.length(), update_popup, true); } @@ -272,9 +261,7 @@ if (base::FeatureList::IsEnabled(omnibox::kRevertModelBeforeClosingPopup)) { // This will clear the model's `user_input_in_progress_`. - if (model()) { - model()->Revert(); - } + model()->Revert(); // This will stop the `AutocompleteController`. This should happen after // `user_input_in_progress_` is cleared above; otherwise, closing the popup @@ -285,18 +272,14 @@ } else { // Same as above, but in reverse order. CloseOmniboxPopup(); - if (model()) { - model()->Revert(); - } + model()->Revert(); } TextChanged(); } void OmniboxView::CloseOmniboxPopup() { - if (model()) { - model()->StopAutocomplete(); - } + model()->StopAutocomplete(); } bool OmniboxView::IsImeShowingPopup() const { @@ -367,15 +350,11 @@ OmniboxView::OmniboxView(OmniboxEditModelDelegate* edit_model_delegate, std::unique_ptr<OmniboxClient> client) - : edit_model_delegate_(edit_model_delegate) { - // `client` can be nullptr in tests. - // TODO(crbug.com/1404748): Verify if this can actually happen and prevent it - // such that checking `model()` before use is no longer necessary. - if (client) { - controller_ = std::make_unique<OmniboxController>( - /*view=*/this, edit_model_delegate, std::move(client)); - } -} + : edit_model_delegate_(edit_model_delegate), + controller_(std::make_unique<OmniboxController>( + /*view=*/this, + edit_model_delegate, + std::move(client))) {} OmniboxEditModel* OmniboxView::model() { return const_cast<OmniboxEditModel*>( @@ -383,15 +362,12 @@ } const OmniboxEditModel* OmniboxView::model() const { - // `controller_` can be nullptr in tests. - return controller_ ? controller_->edit_model() : nullptr; + return controller_->edit_model(); } void OmniboxView::TextChanged() { EmphasizeURLComponents(); - if (model()) { - model()->OnChanged(); - } + model()->OnChanged(); } void OmniboxView::UpdateTextStyle(
diff --git a/components/omnibox/browser/scored_history_match.cc b/components/omnibox/browser/scored_history_match.cc index cf3d908c..7a1aa88 100644 --- a/components/omnibox/browser/scored_history_match.cc +++ b/components/omnibox/browser/scored_history_match.cc
@@ -801,10 +801,6 @@ base::OffsetAdjuster::AdjustOffset(adjustments, &query_pos); base::OffsetAdjuster::AdjustOffset(adjustments, &last_part_of_host_pos); - // Loop through all URL matches and score them appropriately. - url::Component query = parsed.query; - url::Component key, value; - for (const auto& url_match : url_matches) { // Calculate the offset in the URL string where the meaningful (word) part // of the term starts. This takes into account times when a term starts @@ -821,23 +817,7 @@ (*next_word_starts == term_word_offset); if (term_word_offset >= query_pos) { // The match is in the query or ref component. - if (OmniboxFieldTrial::ShouldDisableCGIParamMatching()) { - // Only match cgi param values, NOT the param keys. - while (url::ExtractQueryKeyValue(url.spec().c_str(), &query, &key, - &value)) { - size_t value_begin = value.begin; - size_t value_end = value.end(); - base::OffsetAdjuster::AdjustOffset(adjustments, &value_begin); - base::OffsetAdjuster::AdjustOffset(adjustments, &value_end); - if (term_word_offset >= value_begin && - term_word_offset <= value_end) { - if (term_scores) { - (*term_scores)[url_match.term_num] += 5; - } - break; - } - } - } else if (term_scores) { + if (term_scores) { (*term_scores)[url_match.term_num] += 5; } } else if (term_word_offset >= path_pos) {
diff --git a/components/omnibox/browser/shortcuts_provider.cc b/components/omnibox/browser/shortcuts_provider.cc index 2c1fc7f..14e8b59 100644 --- a/components/omnibox/browser/shortcuts_provider.cc +++ b/components/omnibox/browser/shortcuts_provider.cc
@@ -264,16 +264,6 @@ ++it) { const ShortcutsDatabase::Shortcut& shortcut = it->second; - // Allow `HISTORY_CLUSTER` suggestions only if the appropriate feature is - // enabled. -#if !BUILDFLAG(IS_IOS) - if (!history_clusters::GetConfig() - .omnibox_history_cluster_provider_shortcuts && - shortcut.match_core.type == AutocompleteMatch::Type::HISTORY_CLUSTER) { - continue; - } -#endif // !BUILDFLAG(IS_IOS) - const GURL stripped_destination_url(AutocompleteMatch::GURLToStrippedGURL( shortcut.match_core.destination_url, input, template_url_service, shortcut.match_core.keyword, @@ -514,11 +504,8 @@ match.inline_autocompletion.empty(); } #if !BUILDFLAG(IS_IOS) - } else if (match.type != AutocompleteMatch::Type::HISTORY_CLUSTER || - history_clusters::GetConfig() - .omnibox_history_cluster_provider_allow_default) { - // Don't try to default history cluster suggestions unless - // `omnibox_history_cluster_provider_allow_default` is enabled. + } else if (match.type != AutocompleteMatch::Type::HISTORY_CLUSTER) { + // Don't default history cluster suggestions. #else } else { #endif
diff --git a/components/omnibox/browser/shortcuts_provider_unittest.cc b/components/omnibox/browser/shortcuts_provider_unittest.cc index 7533407..a5a0a6e 100644 --- a/components/omnibox/browser/shortcuts_provider_unittest.cc +++ b/components/omnibox/browser/shortcuts_provider_unittest.cc
@@ -1002,10 +1002,6 @@ #if !BUILDFLAG(IS_IOS) TEST_F(ShortcutsProviderTest, HistoryClusterSuggestions) { - history_clusters::Config config; - config.omnibox_history_cluster_provider_shortcuts = true; - history_clusters::SetConfigForTesting(config); - const auto create_test_data = [](std::string text, bool is_history_cluster) -> TestShortcutData { return {GetGuid(), text, "fill_into_edit", @@ -1074,15 +1070,5 @@ EXPECT_EQ(matches[4].suggestion_group_id, absl::nullopt); EXPECT_EQ(matches[5].suggestion_group_id, absl::nullopt); EXPECT_EQ(matches[6].suggestion_group_id, absl::nullopt); - - // With `omnibox_history_cluster_provider_allow_default`, should be allowed - // default. - config.omnibox_history_cluster_provider_allow_default = true; - history_clusters::SetConfigForTesting(config); - provider_->Start(input, false); - const auto matches_with_allow_default = provider_->matches(); - ASSERT_EQ(matches.size(), matches.size()); - for (const auto& m : matches_with_allow_default) - EXPECT_TRUE(m.allowed_to_be_default_match); } #endif // !BUILDFLAG(IS_IOS)
diff --git a/components/omnibox/common/omnibox_features.cc b/components/omnibox/common/omnibox_features.cc index c53a0540..a1d2925 100644 --- a/components/omnibox/common/omnibox_features.cc +++ b/components/omnibox/common/omnibox_features.cc
@@ -93,9 +93,11 @@ // Determines which are culled when both tail and history cluster suggestions // are available. See `MaybeCullTailSuggestions()`. +// TODO(manukh): Enabled by default 6/1/23 m116. Clean up feature code 8/15 when +// m116 reaches stable. BASE_FEATURE(kPreferTailOverHistoryClusterSuggestions, "OmniboxPreferTailOverHistoryClusterSuggestions", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // When disabled, when providers update their matches, the new set of matches // are sorted and culled, then merged with the old matches, then sorted and @@ -261,11 +263,6 @@ "OmniboxOnDeviceTailModel", base::FEATURE_DISABLED_BY_DEFAULT); -// If enabled, suggestions from a cgi param name match are scored to 0. -BASE_FEATURE(kDisableCGIParamMatching, - "OmniboxDisableCGIParamMatching", - base::FEATURE_DISABLED_BY_DEFAULT); - // If enabled, the shortcut provider is more aggressive in scoring. The exact // details will change over time; but ATM, the shortcut provider will chose 1 // candidate to compete with HUP's URL-what-you-typed suggestion for the default
diff --git a/components/omnibox/common/omnibox_features.h b/components/omnibox/common/omnibox_features.h index f988cfa..d8d00a2a 100644 --- a/components/omnibox/common/omnibox_features.h +++ b/components/omnibox/common/omnibox_features.h
@@ -70,7 +70,6 @@ BASE_DECLARE_FEATURE(kOnDeviceTailModel); // Provider-specific - These features change the behavior of specific providers. -BASE_DECLARE_FEATURE(kDisableCGIParamMatching); BASE_DECLARE_FEATURE(kShortcutBoost); // TODO(crbug.com/1202964): Clean up feature flag used in staged roll-out of // various CLs related to the contents/description clean-up work.
diff --git a/components/openscreen_platform/tls_client_connection_unittest.cc b/components/openscreen_platform/tls_client_connection_unittest.cc index b203a0c..da87907 100644 --- a/components/openscreen_platform/tls_client_connection_unittest.cc +++ b/components/openscreen_platform/tls_client_connection_unittest.cc
@@ -145,6 +145,7 @@ void SetUp() override { task_runner_ = std::make_unique<openscreen_platform::TaskRunner>( task_environment_.GetMainThreadTaskRunner()); + client_ = std::make_unique<StrictMock<MockTlsConnectionClient>>(); socket_streams_ = std::make_unique<FakeSocketStreams>(); connection_ = std::make_unique<TlsClientConnection>( task_runner_.get(), kValidEndpointOne, kValidEndpointTwo, @@ -156,16 +157,18 @@ void TearDown() override { connection_.reset(); socket_streams_.reset(); + client_.reset(); base::RunLoop().RunUntilIdle(); } + StrictMock<MockTlsConnectionClient>* client() const { return client_.get(); } FakeSocketStreams* socket_streams() const { return socket_streams_.get(); } TlsClientConnection* connection() const { return connection_.get(); } private: base::test::TaskEnvironment task_environment_; std::unique_ptr<openscreen_platform::TaskRunner> task_runner_; - + std::unique_ptr<StrictMock<MockTlsConnectionClient>> client_; std::unique_ptr<FakeSocketStreams> socket_streams_; std::unique_ptr<TlsClientConnection> connection_; }; @@ -175,8 +178,7 @@ // correctly after each read. constexpr int kNumReads = 3; - StrictMock<MockTlsConnectionClient> client; - connection()->SetClient(&client); + connection()->SetClient(client()); for (int i = 0; i < kNumReads; ++i) { // Send a different message in each iteration. @@ -185,29 +187,27 @@ for (uint8_t& byte : expected_data) { byte ^= i; } - EXPECT_CALL(client, OnRead(connection(), expected_data)).Times(1); + EXPECT_CALL(*client(), OnRead(connection(), expected_data)).Times(1); socket_streams()->SimulateSocketReceive(expected_data.data(), expected_data.size()); base::RunLoop().RunUntilIdle(); - Mock::VerifyAndClearExpectations(&client); + Mock::VerifyAndClearExpectations(client()); } } TEST_F(TlsClientConnectionTest, CallsClientOnErrorWhenSocketInboundCloses) { - StrictMock<MockTlsConnectionClient> client; - EXPECT_CALL(client, OnError(connection(), _)).Times(1); - connection()->SetClient(&client); + EXPECT_CALL(*client(), OnError(connection(), _)).Times(1); + connection()->SetClient(client()); socket_streams()->SimulateInboundClose(); base::RunLoop().RunUntilIdle(); } TEST_F(TlsClientConnectionTest, SendsUntilBlocked) { - StrictMock<MockTlsConnectionClient> client; // Note: Client::OnError() should not be called during this test since an // outbound-blocked socket is not a fatal error. - EXPECT_CALL(client, OnError(connection(), _)).Times(0); - connection()->SetClient(&client); + EXPECT_CALL(*client(), OnError(connection(), _)).Times(0); + connection()->SetClient(client()); std::vector<uint8_t> message(kDataPipeCapacity / 2); for (int i = 0; i < kDataPipeCapacity / 2; ++i) { @@ -249,9 +249,8 @@ TEST_F(TlsClientConnectionTest, CallsClientOnErrorWhenSendingToClosedOutboundStream) { - StrictMock<MockTlsConnectionClient> client; - EXPECT_CALL(client, OnError(connection(), _)).Times(0); - connection()->SetClient(&client); + EXPECT_CALL(*client(), OnError(connection(), _)).Times(0); + connection()->SetClient(client()); // Send a message and immediately close the outbound stream. EXPECT_TRUE(connection()->Send(kTestMessage, sizeof(kTestMessage))); @@ -259,10 +258,10 @@ base::RunLoop().RunUntilIdle(); // The Client should not have encountered any fatal errors yet. - Mock::VerifyAndClearExpectations(&client); + Mock::VerifyAndClearExpectations(client()); // Now, call Send() again and this should trigger a fatal error. - EXPECT_CALL(client, OnError(connection(), _)).Times(1); + EXPECT_CALL(*client(), OnError(connection(), _)).Times(1); EXPECT_FALSE(connection()->Send(kTestMessage, sizeof(kTestMessage))); }
diff --git a/components/optimization_guide/core/model_util.cc b/components/optimization_guide/core/model_util.cc index 7d6a63dc..a5489bc 100644 --- a/components/optimization_guide/core/model_util.cc +++ b/components/optimization_guide/core/model_util.cc
@@ -103,6 +103,8 @@ return "WebAppInstallationPromo"; case proto::OPTIMIZATION_TARGET_TEXT_EMBEDDER: return "TextEmbedder"; + case proto::OPTIMIZATION_TARGET_VISUAL_SEARCH_CLASSIFICATION: + return "VisualSearchClassification"; // Whenever a new value is added, make sure to add it to the OptTarget // variant list in // //tools/metrics/histograms/metadata/optimization/histograms.xml.
diff --git a/components/optimization_guide/proto/models.proto b/components/optimization_guide/proto/models.proto index 245720e..0036d8e2 100644 --- a/components/optimization_guide/proto/models.proto +++ b/components/optimization_guide/proto/models.proto
@@ -190,6 +190,8 @@ OPTIMIZATION_TARGET_WEB_APP_INSTALLATION_PROMO = 32; // Target for generic text embedder model. OPTIMIZATION_TARGET_TEXT_EMBEDDER = 33; + // Target for classifying and extracting search images on web page. + OPTIMIZATION_TARGET_VISUAL_SEARCH_CLASSIFICATION = 34; } // The model engine versions that can be used to do model inference.
diff --git a/components/page_image_service/image_service.cc b/components/page_image_service/image_service.cc index ef540d4..614ca5e8 100644 --- a/components/page_image_service/image_service.cc +++ b/components/page_image_service/image_service.cc
@@ -9,6 +9,7 @@ #include "base/functional/callback.h" #include "base/i18n/case_conversion.h" #include "base/memory/raw_ptr.h" +#include "base/memory/raw_ref.h" #include "base/memory/weak_ptr.h" #include "base/metrics/histogram_functions.h" #include "components/omnibox/browser/autocomplete_scheme_classifier.h" @@ -111,10 +112,10 @@ } AutocompleteInput input(search_query_, metrics::OmniboxEventProto::JOURNEYS, - autocomplete_scheme_classifier_); + *autocomplete_scheme_classifier_); SearchSuggestionParser::Results results; if (!SearchSuggestionParser::ParseSuggestResults( - *response_data, input, autocomplete_scheme_classifier_, + *response_data, input, *autocomplete_scheme_classifier_, /*default_result_relevance=*/100, /*is_keyword_result=*/false, &results)) { UmaHistogramEnumerationForClient( @@ -146,7 +147,8 @@ } // Embedder-specific logic on how to classify schemes. - const AutocompleteSchemeClassifier& autocomplete_scheme_classifier_; + const raw_ref<const AutocompleteSchemeClassifier> + autocomplete_scheme_classifier_; // The id of the UI requesting the image. mojom::ClientId client_id_;
diff --git a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc index d822524..29f25ad 100644 --- a/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc +++ b/components/page_load_metrics/browser/metrics_web_contents_observer_unittest.cc
@@ -97,6 +97,7 @@ } void TearDown() override { + embedder_interface_ = nullptr; content::SetBrowserClientForTesting(original_browser_client_); RenderViewHostTestHarness::TearDown(); } @@ -249,8 +250,7 @@ } base::HistogramTester histogram_tester_; - raw_ptr<TestMetricsWebContentsObserverEmbedder, DanglingUntriaged> - embedder_interface_; + raw_ptr<TestMetricsWebContentsObserverEmbedder> embedder_interface_; private: int num_errors_ = 0;
diff --git a/components/password_manager/content/browser/BUILD.gn b/components/password_manager/content/browser/BUILD.gn index eac17cc..fbbfc6b 100644 --- a/components/password_manager/content/browser/BUILD.gn +++ b/components/password_manager/content/browser/BUILD.gn
@@ -39,10 +39,6 @@ "//mojo/public/cpp/system", "//net", ] - - if (is_android) { - public_deps += [ "//components/webauthn/android" ] - } } source_set("test_support") {
diff --git a/components/password_manager/content/browser/DEPS b/components/password_manager/content/browser/DEPS index ab8a230..3268664 100644 --- a/components/password_manager/content/browser/DEPS +++ b/components/password_manager/content/browser/DEPS
@@ -7,7 +7,6 @@ "+components/safe_browsing/buildflags.h", "+components/ukm", "+components/user_prefs", - "+components/webauthn/android", "+content/public/browser", "+content/test", "+net",
diff --git a/components/password_manager/content/browser/PRESUBMIT.py b/components/password_manager/content/browser/PRESUBMIT.py index 290257b..bdc43b74 100644 --- a/components/password_manager/content/browser/PRESUBMIT.py +++ b/components/password_manager/content/browser/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - """Chromium presubmit script to check that BadMessage enums in histograms.xml match the corresponding bad_message.h file. """
diff --git a/components/password_manager/content/browser/content_password_manager_driver.cc b/components/password_manager/content/browser/content_password_manager_driver.cc index e668711..15f1932 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.cc +++ b/components/password_manager/content/browser/content_password_manager_driver.cc
@@ -35,10 +35,6 @@ #include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h" #include "ui/base/page_transition_types.h" -#if BUILDFLAG(IS_ANDROID) -#include "components/webauthn/android/webauthn_cred_man_delegate.h" -#endif // BUILDFLAG(IS_ANDROID) - using autofill::mojom::FocusedFieldType; namespace password_manager { @@ -197,7 +193,7 @@ #if BUILDFLAG(IS_ANDROID) void ContentPasswordManagerDriver::KeyboardReplacingSurfaceClosed( - ShowVirtualKeyboard show_virtual_keyboard) { + ToShowVirtualKeyboard show_virtual_keyboard) { GetPasswordAutofillAgent()->KeyboardReplacingSurfaceClosed( show_virtual_keyboard.value()); } @@ -447,8 +443,9 @@ // TODO (crbug.com/1448579): Make ShowTouchToFill to return bool (whether it // was shown or not) and do not call the OnShowPasswordSuggestions on the // password autofill manager if TTF was shown. - client_->ShowTouchToFill( - this, autofill::mojom::SubmissionReadinessState::kNoInformation); + client_->ShowKeyboardReplacingSurface( + this, autofill::mojom::SubmissionReadinessState::kNoInformation, + options & autofill::ACCEPTS_WEBAUTHN_CREDENTIALS); } #endif // BUILDFLAG(IS_ANDROID) @@ -465,26 +462,8 @@ render_frame_host_)) { return; } - if (is_webauthn_form && WebAuthnCredManDelegate::IsCredManEnabled()) { - WebAuthnCredManDelegate* cred_man_delegate = - WebAuthnCredManDelegate::GetRequestDelegate( - content::WebContents::FromRenderFrameHost(render_frame_host_)); - // webauthn forms without passkeys should show TouchToFill bottom sheet. - if (cred_man_delegate->HasResults()) { - auto cred_man_request_completion_cb = - base::BindRepeating( - [](bool success) { return ShowVirtualKeyboard(!success); }) - .Then(base::BindRepeating( - &ContentPasswordManagerDriver::KeyboardReplacingSurfaceClosed, - weak_factory_.GetWeakPtr())); - - cred_man_delegate->SetRequestCompletionCallback( - std::move(cred_man_request_completion_cb)); - cred_man_delegate->TriggerFullRequest(); - return; - } - } - client_->ShowTouchToFill(this, submission_readiness); + client_->ShowKeyboardReplacingSurface(this, submission_readiness, + is_webauthn_form); } #endif
diff --git a/components/password_manager/content/browser/content_password_manager_driver.h b/components/password_manager/content/browser/content_password_manager_driver.h index 7da0fcb..baf2ae8 100644 --- a/components/password_manager/content/browser/content_password_manager_driver.h +++ b/components/password_manager/content/browser/content_password_manager_driver.h
@@ -75,7 +75,7 @@ const std::u16string& credential) override; #if BUILDFLAG(IS_ANDROID) void KeyboardReplacingSurfaceClosed( - ShowVirtualKeyboard show_virtual_keyboard) override; + ToShowVirtualKeyboard show_virtual_keyboard) override; void TriggerFormSubmission() override; #endif void PreviewSuggestion(const std::u16string& username,
diff --git a/components/password_manager/core/browser/form_saver_impl.cc b/components/password_manager/core/browser/form_saver_impl.cc index 69ac595..e2b18d0 100644 --- a/components/password_manager/core/browser/form_saver_impl.cc +++ b/components/password_manager/core/browser/form_saver_impl.cc
@@ -10,6 +10,7 @@ #include "base/strings/utf_string_conversions.h" #include "base/time/time.h" +#include "components/password_manager/core/browser/affiliation/affiliation_utils.h" #include "components/password_manager/core/browser/password_manager_util.h" #include "components/password_manager/core/browser/password_store_interface.h" #include "url/gurl.h" @@ -54,9 +55,16 @@ const bool same_password = match->password_value == pending.password_value; const bool username_was_added = match->username_value.empty() && !pending.username_value.empty(); + const password_manager_util::GetLoginMatchType match_type = + password_manager_util::GetMatchType(*match); + const bool is_affiliated_android_match = + match_type == password_manager_util::GetLoginMatchType::kAffiliated && + password_manager::IsValidAndroidFacetURI(match->signon_realm); + // TODO(crbug.com/1428539): include affiliated website matches when Android + // supports them. if (same_password && username_was_added && - password_manager_util::GetMatchType(*match) == - password_manager_util::GetLoginMatchType::kExact) { + (match_type == password_manager_util::GetLoginMatchType::kExact || + is_affiliated_android_match)) { store->RemoveLogin(*match); continue; }
diff --git a/components/password_manager/core/browser/password_manager_client.cc b/components/password_manager/core/browser/password_manager_client.cc index 2801d09..66268388 100644 --- a/components/password_manager/core/browser/password_manager_client.cc +++ b/components/password_manager/core/browser/password_manager_client.cc
@@ -33,9 +33,10 @@ ErrorMessageFlowType flow_type, password_manager::PasswordStoreBackendErrorType error_type) {} -void PasswordManagerClient::ShowTouchToFill( +void PasswordManagerClient::ShowKeyboardReplacingSurface( PasswordManagerDriver* driver, - autofill::mojom::SubmissionReadinessState submission_readiness) {} + autofill::mojom::SubmissionReadinessState submission_readiness, + bool is_webauthn_form) {} #endif scoped_refptr<device_reauth::DeviceAuthenticator>
diff --git a/components/password_manager/core/browser/password_manager_client.h b/components/password_manager/core/browser/password_manager_client.h index 7d75c8f5..8ad51e0 100644 --- a/components/password_manager/core/browser/password_manager_client.h +++ b/components/password_manager/core/browser/password_manager_client.h
@@ -201,10 +201,12 @@ ErrorMessageFlowType flow_type, password_manager::PasswordStoreBackendErrorType error_type); - // Instructs the client to show the Touch To Fill UI. - virtual void ShowTouchToFill( + // Instructs the client to show a keyboard replacing surface UI (e.g. + // TouchToFill). + virtual void ShowKeyboardReplacingSurface( PasswordManagerDriver* driver, - autofill::mojom::SubmissionReadinessState submission_readiness); + autofill::mojom::SubmissionReadinessState submission_readiness, + bool is_webauthn_form); #endif // Returns a pointer to a DeviceAuthenticator. Might be null if
diff --git a/components/password_manager/core/browser/password_manager_driver.h b/components/password_manager/core/browser/password_manager_driver.h index a3e65ae3..c499610c 100644 --- a/components/password_manager/core/browser/password_manager_driver.h +++ b/components/password_manager/core/browser/password_manager_driver.h
@@ -36,8 +36,8 @@ : public base::SupportsWeakPtr<PasswordManagerDriver> { public: #if BUILDFLAG(IS_ANDROID) - using ShowVirtualKeyboard = - base::StrongAlias<class ShowVirtualKeyboardTag, bool>; + using ToShowVirtualKeyboard = + base::StrongAlias<class ToShowVirtualKeyboardTag, bool>; #endif PasswordManagerDriver() = default; @@ -96,7 +96,7 @@ // Fill sheet) has been closed. Indicates whether the virtual keyboard should // be shown instead. virtual void KeyboardReplacingSurfaceClosed( - ShowVirtualKeyboard show_virtual_keyboard) {} + ToShowVirtualKeyboard show_virtual_keyboard) {} // Triggers form submission on the last interacted web input element. virtual void TriggerFormSubmission() {}
diff --git a/components/password_manager/core/browser/password_manager_util.cc b/components/password_manager/core/browser/password_manager_util.cc index 13b4fdf..275dfbe 100644 --- a/components/password_manager/core/browser/password_manager_util.cc +++ b/components/password_manager/core/browser/password_manager_util.cc
@@ -56,8 +56,13 @@ std::tuple<int, base::Time, int> GetPriorityProperties( const PasswordForm* form) { - return std::make_tuple(-static_cast<int>(GetMatchType(*form)), - form->date_last_used, + GetLoginMatchType match_type = GetMatchType(*form); + // Treat affiliated android apps the same way as exact matches. + if (match_type == GetLoginMatchType::kAffiliated && + password_manager::IsValidAndroidFacetURI(form->signon_realm)) { + match_type = GetLoginMatchType::kExact; + } + return std::make_tuple(-static_cast<int>(match_type), form->date_last_used, static_cast<int>(form->in_store)); } @@ -252,11 +257,6 @@ } GetLoginMatchType GetMatchType(const password_manager::PasswordForm& form) { - if (password_manager::IsValidAndroidFacetURI(form.signon_realm)) { - DCHECK(form.is_affiliation_based_match); - DCHECK(!form.is_public_suffix_match); - return GetLoginMatchType::kExact; - } if (form.is_affiliation_based_match) return GetLoginMatchType::kAffiliated;
diff --git a/components/password_manager/core/browser/password_manager_util_unittest.cc b/components/password_manager/core/browser/password_manager_util_unittest.cc index 4532979..b66ac8b 100644 --- a/components/password_manager/core/browser/password_manager_util_unittest.cc +++ b/components/password_manager/core/browser/password_manager_util_unittest.cc
@@ -439,7 +439,7 @@ PasswordForm form = GetTestAndroidCredential(); form.is_affiliation_based_match = true; - EXPECT_EQ(GetLoginMatchType::kExact, GetMatchType(form)); + EXPECT_EQ(GetLoginMatchType::kAffiliated, GetMatchType(form)); } TEST(PasswordManagerUtil, GetMatchType_Web) {
diff --git a/components/password_manager/core/common/password_manager_features.cc b/components/password_manager/core/common/password_manager_features.cc index 842737c..efaefd85 100644 --- a/components/password_manager/core/common/password_manager_features.cc +++ b/components/password_manager/core/common/password_manager_features.cc
@@ -258,7 +258,7 @@ // Enables use of Google Mobile Services for password storage. Chrome's local // database will be unused but kept in sync for local passwords. BASE_FEATURE(kUnifiedPasswordManagerAndroid, - "UnifiedPasswordManagerAndroid", + "UnifiedPasswordManagerAndroid_LAUNCHED", base::FEATURE_ENABLED_BY_DEFAULT); // Enables use of Google Mobile services for non-sycned password storage.
diff --git a/components/password_manager/ios/password_form_helper.mm b/components/password_manager/ios/password_form_helper.mm index 0c04a48..472d46ec 100644 --- a/components/password_manager/ios/password_form_helper.mm +++ b/components/password_manager/ios/password_form_helper.mm
@@ -46,13 +46,15 @@ namespace password_manager { bool GetPageURLAndCheckTrustLevel(web::WebState* web_state, GURL* __nullable page_url) { - auto trustLevel = web::URLVerificationTrustLevel::kNone; - GURL dummy; - if (!page_url) { - page_url = &dummy; + absl::optional<GURL> last_committed_url = + web_state->GetLastCommittedURLIfTrusted(); + if (last_committed_url) { + if (page_url) { + *page_url = std::move(*last_committed_url); + } + return true; } - *page_url = web_state->GetCurrentURL(&trustLevel); - return trustLevel == web::URLVerificationTrustLevel::kAbsolute; + return false; } // The frame id associated with the frame which sent to form message.
diff --git a/components/payments/core/native_error_strings.cc b/components/payments/core/native_error_strings.cc index fde0641..06c8a3a 100644 --- a/components/payments/core/native_error_strings.cc +++ b/components/payments/core/native_error_strings.cc
@@ -97,6 +97,12 @@ const char kPaymentManifestDownloadFailed[] = "Unable to download payment manifest \"$1\"."; +const char kPaymentManifestDownloadFailedWithNetworkError[] = + "Unable to download payment manifest \"$1\". $2 ($3)"; + +const char kPaymentManifestDownloadFailedWithHttpStatusCode[] = + "Unable to download payment manifest \"$1\". HTTP $2 $3."; + const char kPaymentManifestCSPDenied[] = "Content Security Policy denied the download of payment manifest \"$1\".";
diff --git a/components/payments/core/native_error_strings.h b/components/payments/core/native_error_strings.h index 2f164bf3..0403376 100644 --- a/components/payments/core/native_error_strings.h +++ b/components/payments/core/native_error_strings.h
@@ -125,6 +125,18 @@ // be used with base::ReplaceStringPlaceholders(fmt, {A}, nullptr). extern const char kPaymentManifestDownloadFailed[]; +// Used when downloading payment manifest URL A has failed because of network +// error B. This format should be used with +// base::ReplaceStringPlaceholders( +// fmt, {A, net::ErrorToShortString(B), base::NumberToString(B)}, nullptr). +extern const char kPaymentManifestDownloadFailedWithNetworkError[]; + +// Used when downloading payment manifest URL A has failed because of HTTP +// status code B. This format should be used with +// base::ReplaceStringPlaceholders( +// fmt, {A, base::NumberToString(B), net::GetHttpReasonPhrase(B)}, nullptr). +extern const char kPaymentManifestDownloadFailedWithHttpStatusCode[]; + // Used when Content Security Policy (CSP) denied downloading payment manifest // URL A. This format should be used with base::ReplaceStringPlaceholders(fmt, // {A}, nullptr).
diff --git a/components/payments/core/payment_manifest_downloader.cc b/components/payments/core/payment_manifest_downloader.cc index e8c5036..3d2321a 100644 --- a/components/payments/core/payment_manifest_downloader.cc +++ b/components/payments/core/payment_manifest_downloader.cc
@@ -42,6 +42,19 @@ network::SimpleURLLoader::kMaxBoundedStringDownloadSize, "Max manifest size bigger than largest allowed download size"); +void RespondWithHttpStatusCodeError(const GURL& final_url, + net::HttpStatusCode http_status_code, + const ErrorLogger& log, + PaymentManifestDownloadCallback callback) { + std::string error_message = base::ReplaceStringPlaceholders( + errors::kPaymentManifestDownloadFailedWithHttpStatusCode, + {final_url.spec(), base::NumberToString(http_status_code), + net::GetHttpReasonPhrase(http_status_code)}, + nullptr); + log.Error(error_message); + std::move(callback).Run(final_url, std::string(), error_message); +} + // Invokes |callback| with |error_format|. void RespondWithError(const base::StringPiece& error_format, const GURL& final_url, @@ -99,8 +112,9 @@ return GURL(); } - if (!IsValidManifestUrl(redirect_info.new_url, log, out_error_message)) + if (!IsValidManifestUrl(redirect_info.new_url, log, out_error_message)) { return GURL(); + } return redirect_info.new_url; } @@ -205,12 +219,14 @@ network::SimpleURLLoader* url_loader, std::unique_ptr<std::string> response_body) { scoped_refptr<net::HttpResponseHeaders> headers; - if (url_loader->ResponseInfo()) + if (url_loader->ResponseInfo()) { headers = url_loader->ResponseInfo()->headers; + } std::string response_body_str; - if (response_body.get()) + if (response_body.get()) { response_body_str = std::move(*response_body); + } OnURLLoaderCompleteInternal(url_loader, url_loader->GetFinalURL(), response_body_str, headers, @@ -229,17 +245,27 @@ std::unique_ptr<Download> download = std::move(download_it->second); downloads_.erase(download_it); - if (net_error != net::OK) { - RespondWithError(errors::kPaymentManifestDownloadFailed, final_url, *log_, - std::move(download->callback)); + if (net_error != net::OK && + net_error != net::ERR_HTTP_RESPONSE_CODE_FAILURE) { + std::string error_message = base::ReplaceStringPlaceholders( + errors::kPaymentManifestDownloadFailedWithNetworkError, + {final_url.spec(), net::ErrorToShortString(net_error), + base::NumberToString(net_error)}, + nullptr); + log_->Error(error_message); + std::move(download->callback).Run(final_url, std::string(), error_message); return; } std::string error_message; if (download->type == Download::Type::RESPONSE_BODY) { - if (!headers || headers->response_code() != net::HTTP_OK) { + if (!headers) { RespondWithError(errors::kPaymentManifestDownloadFailed, final_url, *log_, std::move(download->callback)); + } else if (headers->response_code() != net::HTTP_OK) { + RespondWithHttpStatusCodeError( + final_url, static_cast<net::HttpStatusCode>(headers->response_code()), + *log_, std::move(download->callback)); } else { RespondWithContent(response_body, errors::kNoContentInPaymentManifest, final_url, *log_, std::move(download->callback)); @@ -257,8 +283,9 @@ if (headers->response_code() != net::HTTP_OK && headers->response_code() != net::HTTP_NO_CONTENT) { - RespondWithError(errors::kPaymentManifestDownloadFailed, final_url, *log_, - std::move(download->callback)); + RespondWithHttpStatusCodeError( + final_url, static_cast<net::HttpStatusCode>(headers->response_code()), + *log_, std::move(download->callback)); return; } @@ -279,8 +306,9 @@ } auto rel = params.find("rel"); - if (rel == params.end()) + if (rel == params.end()) { continue; + } std::vector<std::string> rel_parts = base::SplitString(rel->second.value_or(""), HTTP_LWS,
diff --git a/components/payments/core/payment_manifest_downloader_unittest.cc b/components/payments/core/payment_manifest_downloader_unittest.cc index 8cab806..991644f 100644 --- a/components/payments/core/payment_manifest_downloader_unittest.cc +++ b/components/payments/core/payment_manifest_downloader_unittest.cc
@@ -73,8 +73,9 @@ net::GetHttpReasonPhrase( static_cast<net::HttpStatusCode>(response_code)))); - if (link_header.has_value()) + if (link_header.has_value()) { headers->SetHeader("Link", *link_header); + } } downloader_->OnURLLoaderCompleteInternal( @@ -129,11 +130,10 @@ }; TEST_F(PaymentMethodManifestDownloaderTest, FirstHttpResponse404IsFailure) { - EXPECT_CALL( - *this, - OnManifestDownload( - _, kNoContent, - "Unable to download payment manifest \"https://bobpay.test/\".")); + EXPECT_CALL(*this, OnManifestDownload( + _, kNoContent, + "Unable to download payment manifest " + "\"https://bobpay.test/\". HTTP 404 Not Found.")); ServerResponse(404, Headers::kSend, kNoLinkHeader, kNoResponseBody, net::OK); } @@ -260,10 +260,11 @@ "<manifest.json>; rel=payment-method-manifest", kNoResponseBody, net::OK); - EXPECT_CALL(*this, - OnManifestDownload(_, kNoContent, - "Unable to download payment manifest " - "\"https://bobpay.test/manifest.json\".")); + EXPECT_CALL( + *this, OnManifestDownload( + _, kNoContent, + "Unable to download payment manifest " + "\"https://bobpay.test/manifest.json\". HTTP 404 Not Found.")); ServerResponse(404, Headers::kSend, kNoLinkHeader, kNoResponseBody, net::OK); } @@ -309,10 +310,10 @@ TEST_F(PaymentMethodManifestDownloaderTest, InsufficientResourcesInHttpLinkFailure) { EXPECT_CALL( - *this, - OnManifestDownload( - _, kNoContent, - "Unable to download payment manifest \"https://bobpay.test/\".")); + *this, OnManifestDownload( + _, kNoContent, + "Unable to download payment manifest " + "\"https://bobpay.test/\". ERR_INSUFFICIENT_RESOURCES (-12)")); ServerResponse(200, Headers::kSend, "<manifest.json>; rel=payment-method-manifest", @@ -328,7 +329,8 @@ EXPECT_CALL(*this, OnManifestDownload(_, kNoContent, "Unable to download payment manifest " - "\"https://bobpay.test/manifest.json\".")); + "\"https://bobpay.test/manifest.json\". " + "ERR_INSUFFICIENT_RESOURCES (-12)")); ServerResponse(200, Headers::kSend, kNoLinkHeader, "manifest content", net::ERR_INSUFFICIENT_RESOURCES); @@ -350,10 +352,12 @@ "<manifest.json>; rel=payment-method-manifest", kNoResponseBody, net::OK); - EXPECT_CALL(*this, - OnManifestDownload(_, kNoContent, - "Unable to download payment manifest " - "\"https://bobpay.test/manifest.json\".")); + EXPECT_CALL( + *this, + OnManifestDownload( + _, kNoContent, + "Unable to download payment manifest " + "\"https://bobpay.test/manifest.json\". HTTP 204 No Content.")); ServerResponse(204, Headers::kSend, kNoLinkHeader, "manifest content", net::OK); @@ -572,11 +576,10 @@ }; TEST_F(WebAppManifestDownloaderTest, HttpGetResponse404IsFailure) { - EXPECT_CALL( - *this, - OnManifestDownload( - _, kNoContent, - "Unable to download payment manifest \"https://bobpay.test/\".")); + EXPECT_CALL(*this, OnManifestDownload( + _, kNoContent, + "Unable to download payment manifest " + "\"https://bobpay.test/\". HTTP 404 Not Found.")); ServerResponse(404, kNoResponseBody, net::OK); } @@ -599,10 +602,10 @@ TEST_F(WebAppManifestDownloaderTest, InsufficientResourcesFailure) { EXPECT_CALL( - *this, - OnManifestDownload( - _, kNoContent, - "Unable to download payment manifest \"https://bobpay.test/\".")); + *this, OnManifestDownload( + _, kNoContent, + "Unable to download payment manifest " + "\"https://bobpay.test/\". ERR_INSUFFICIENT_RESOURCES (-12)")); ServerResponse(200, "manifest content", net::ERR_INSUFFICIENT_RESOURCES); }
diff --git a/components/policy/PRESUBMIT.py b/components/policy/PRESUBMIT.py index 2928891..552f435f 100644 --- a/components/policy/PRESUBMIT.py +++ b/components/policy/PRESUBMIT.py
@@ -6,7 +6,6 @@ # chromium-policy-owners@google.com. PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True import glob import os
diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index e4e80b5..a408bc5 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn
@@ -58,6 +58,9 @@ if (is_chromeos_ash) { deps += [ "//chromeos/ash/components/system" ] } + if (is_ios) { + deps += [ "//base/ios" ] + } } source_set("internal") {
diff --git a/components/policy/core/common/policy_pref_names.cc b/components/policy/core/common/policy_pref_names.cc index 7d8096d..de02f4b 100644 --- a/components/policy/core/common/policy_pref_names.cc +++ b/components/policy/core/common/policy_pref_names.cc
@@ -107,11 +107,6 @@ "policy.user_policy_notification_was_shown"; #endif -// A boolean indicating whether the deprecated API Event.path is enabled. It -// should eventually be disabled and removed. -// https://chromestatus.com/feature/5726124632965120 -const char kEventPathEnabled[] = "policy.event_path_enabled"; - // A boolean indicating whether the newly specified behavior for // Element.offsetParent is in effect. const char kOffsetParentNewSpecBehaviorEnabled[] = @@ -144,5 +139,10 @@ const char kBeforeunloadEventCancelByPreventDefaultEnabled[] = "policy.beforeunload_event_cancel_by_prevent_default_enabled"; +// Boolean indicating whether Policy Test Page is Enabled. +// The value is controlled by the PolicyTestPageEnabled policy. +// If this is set to True, the page will be accessible. +const char kPolicyTestPageEnabled[] = "policy_test_page_enabled"; + } // namespace policy_prefs } // namespace policy
diff --git a/components/policy/core/common/policy_pref_names.h b/components/policy/core/common/policy_pref_names.h index cb4e7998..bdd5a03 100644 --- a/components/policy/core/common/policy_pref_names.h +++ b/components/policy/core/common/policy_pref_names.h
@@ -60,7 +60,6 @@ #if BUILDFLAG(IS_IOS) extern const char kUserPolicyNotificationWasShown[]; #endif -extern const char kEventPathEnabled[]; extern const char kOffsetParentNewSpecBehaviorEnabled[]; extern const char kSendMouseEventsDisabledFormControlsEnabled[]; extern const char kForceGoogleSafeSearch[]; @@ -68,6 +67,7 @@ extern const char kHideWebStoreIcon[]; extern const char kIncognitoModeAvailability[]; extern const char kBeforeunloadEventCancelByPreventDefaultEnabled[]; +extern const char kPolicyTestPageEnabled[]; } // namespace policy_prefs } // namespace policy
diff --git a/components/policy/core/common/schema.h b/components/policy/core/common/schema.h index 3f54325..d407948 100644 --- a/components/policy/core/common/schema.h +++ b/components/policy/core/common/schema.h
@@ -198,7 +198,7 @@ private: scoped_refptr<const InternalStorage> storage_; raw_ptr<const internal::PropertyNode, AllowPtrArithmetic> it_; - raw_ptr<const internal::PropertyNode> end_; + raw_ptr<const internal::PropertyNode, AllowPtrArithmetic> end_; }; // These methods should be called only if type() == Type::DICT,
diff --git a/components/policy/resources/templates/policies.yaml b/components/policy/resources/templates/policies.yaml index e147e1f..2dd878d 100644 --- a/components/policy/resources/templates/policies.yaml +++ b/components/policy/resources/templates/policies.yaml
@@ -1110,6 +1110,7 @@ 1109: DataUrlInSvgUseEnabled 1110: RSAKeyUsageForLocalAnchorsEnabled 1111: BeforeunloadEventCancelByPreventDefaultEnabled + 1112: PolicyTestPageEnabled atomic_groups: 1: Homepage 2: RemoteAccess
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/PolicyTestPageEnabled.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/PolicyTestPageEnabled.yaml new file mode 100644 index 0000000..856cf4a4 --- /dev/null +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/PolicyTestPageEnabled.yaml
@@ -0,0 +1,37 @@ +owners: +- jayee@google.com +- ydago@google.com +- file://components/policy/OWNERS +caption: Allow access to the policy test page +desc: |- + This policy will provide access to the policy test page, + while policies are tested on this page, all other policies will be ignored. + Feature will only be available on Canary channel. + + If policy is Enabled or not set, the page will be accessible. + If policy is Disabled, the page will be blocked. +future_on: +- ios +- android +- chrome.* +- chrome_os +- fuchsia +features: + dynamic_refresh: true + per_profile: true +type: main +schema: + type: boolean +items: +- caption: Policy test page is accessible + value: true +- caption: Policy test page is blocked + value: false +default: true +example_value: true +tags: [] + + + + +
diff --git a/components/policy/test/data/policy_test_cases.json b/components/policy/test/data/policy_test_cases.json index b78426c..920f26a 100644 --- a/components/policy/test/data/policy_test_cases.json +++ b/components/policy/test/data/policy_test_cases.json
@@ -21098,6 +21098,46 @@ } ] }, + "PolicyTestPageEnabled":{ + "os": [ + "win", + "linux", + "mac", + "chromeos_ash", + "chromeos_lacros", + "fuchsia", + "android" + ], + "policy_pref_mapping_tests": [ + { + "policies": {}, + "prefs": { + "policy_test_page_enabled": { + "default_value": true, + "location": "user_profile" + } + } + }, + { + "policies": { "PolicyTestPageEnabled": true}, + "prefs": { + "policy_test_page_enabled": { + "value": true, + "location": "user_profile" + } + } + }, + { + "policies": { "PolicyTestPageEnabled": false}, + "prefs": { + "policy_test_page_enabled": { + "value": false, + "location": "user_profile" + } + } + } + ] + }, "CalendarIntegrationEnabled": { "os": ["chromeos_ash"], "policy_pref_mapping_tests": [ @@ -21192,45 +21232,7 @@ ] }, "EventPathEnabled": { - "os": [ - "win", - "linux", - "mac", - "chromeos_ash", - "chromeos_lacros", - "android", - "fuchsia" - ], - "policy_pref_mapping_tests": [ - { - "policies": { - "EventPathEnabled": true - }, - "prefs": { - "policy.event_path_enabled": { - "value": true - } - } - }, - { - "policies": { - "EventPathEnabled": false - }, - "prefs": { - "policy.event_path_enabled": { - "value": false - } - } - }, - { - "policies": {}, - "prefs": { - "policy.event_path_enabled": { - "default_value": false - } - } - } - ] + "reason_for_missing_test": "Policy is not supported as of M116" }, "OffsetParentNewSpecBehaviorEnabled": { "os": [
diff --git a/components/policy/tools/PRESUBMIT.py b/components/policy/tools/PRESUBMIT.py index 2966e44c6..566a111 100644 --- a/components/policy/tools/PRESUBMIT.py +++ b/components/policy/tools/PRESUBMIT.py
@@ -5,15 +5,12 @@ import os import sys -USE_PYTHON3 = True - def _RunPythonUnitTests(input_api, output_api): tests = input_api.canned_checks.GetUnitTestsInDirectory( input_api, output_api, directory='.', - files_to_check=[r'^.+test\.py$'], - run_on_python2=False) + files_to_check=[r'^.+test\.py$']) return input_api.RunTests(tests)
diff --git a/components/policy/tools/template_writers/PRESUBMIT.py b/components/policy/tools/template_writers/PRESUBMIT.py index d41b94f..8f54e52 100755 --- a/components/policy/tools/template_writers/PRESUBMIT.py +++ b/components/policy/tools/template_writers/PRESUBMIT.py
@@ -8,10 +8,6 @@ details on the presubmit API built into gcl. """ - -USE_PYTHON3 = True - - def RunUnittests(input_api, output_api): return input_api.canned_checks.RunPythonUnitTests(input_api, output_api,
diff --git a/components/power_metrics/BUILD.gn b/components/power_metrics/BUILD.gn index 1e9aa75..a945438 100644 --- a/components/power_metrics/BUILD.gn +++ b/components/power_metrics/BUILD.gn
@@ -42,14 +42,14 @@ ldflags = [ "/DELAYLOAD:setupapi.dll" ] } - if (is_linux) { + if (is_linux || is_chromeos) { sources += [ "energy_metrics_provider_linux.cc", "energy_metrics_provider_linux.h", ] } - if (is_win || is_linux) { + if (is_win || is_linux || is_chromeos) { sources += [ "system_power_monitor.cc", "system_power_monitor.h", @@ -78,7 +78,7 @@ data = [ "test/data/" ] } - if (is_win || is_linux) { + if (is_win || is_linux || is_chromeos) { sources += [ "system_power_monitor_unittest.cc" ] deps += [ "//base/test:test_support" ]
diff --git a/components/power_metrics/energy_metrics_provider.cc b/components/power_metrics/energy_metrics_provider.cc index e9d9029..29683e05 100644 --- a/components/power_metrics/energy_metrics_provider.cc +++ b/components/power_metrics/energy_metrics_provider.cc
@@ -7,7 +7,7 @@ #include "build/build_config.h" #if BUILDFLAG(IS_WIN) #include "components/power_metrics/energy_metrics_provider_win.h" -#elif BUILDFLAG(IS_LINUX) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) #include "components/power_metrics/energy_metrics_provider_linux.h" #endif // BUILDFLAG(IS_WIN) @@ -20,7 +20,7 @@ std::unique_ptr<EnergyMetricsProvider> EnergyMetricsProvider::Create() { #if BUILDFLAG(IS_WIN) return EnergyMetricsProviderWin::Create(); -#elif BUILDFLAG(IS_LINUX) +#elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) return EnergyMetricsProviderLinux::Create(); #else return nullptr;
diff --git a/components/power_metrics/energy_metrics_provider_linux.cc b/components/power_metrics/energy_metrics_provider_linux.cc index 804f130..0c0b097 100644 --- a/components/power_metrics/energy_metrics_provider_linux.cc +++ b/components/power_metrics/energy_metrics_provider_linux.cc
@@ -14,6 +14,7 @@ #include "base/files/scoped_file.h" #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -21,6 +22,8 @@ namespace { +constexpr const char* kPowerEventPath = "/sys/bus/event_source/devices/power"; + // Existing metrics that can be read via perf event. constexpr std::array<const char*, 5> kMetrics{ "energy-pkg", "energy-cores", "energy-gpu", "energy-ram", "energy-psys"}; @@ -134,6 +137,12 @@ is_initialized_ = true; + // Check if there are available power-related events on local platform. + if (!base::PathExists(base::FilePath(kPowerEventPath))) { + LOG(WARNING) << "No available power event"; + return false; + } + // Check if perf_event_paranoid is set to 0 as required. uint64_t perf_event_paranoid; if (!ReadUint64FromFile( @@ -151,7 +160,7 @@ // type for perf_event_attr from /sys/bus/event_source/devices/power/type. uint64_t attr_type; if (!ReadUint64FromFile( - base::FilePath("/sys/bus/event_source/devices/power/type"), + base::FilePath(base::StrCat({kPowerEventPath, "/type"})), &attr_type)) { LOG(WARNING) << "Failed to get perf event type"; return false; @@ -160,11 +169,9 @@ // For each metric, get their file descriptors. for (auto* const metric : kMetrics) { base::FilePath config_path = - base::FilePath("/sys/bus/event_source/devices/power/events") - .Append(FILE_PATH_LITERAL(metric)); - base::FilePath scale_path = - base::FilePath("/sys/bus/event_source/devices/power/events") - .Append(FILE_PATH_LITERAL(metric + std::string(".scale"))); + base::FilePath(base::StrCat({kPowerEventPath, "/events/", metric})); + base::FilePath scale_path = base::FilePath( + base::StrCat({kPowerEventPath, "/events/", metric, ".scale"})); // Some energy metrics may be unavailable on different platforms, so the // corresponding file path does not exist, which is normal. if (!base::PathExists(config_path) || !base::PathExists(scale_path)) {
diff --git a/components/query_tiles/internal/image_prefetcher_unittest.cc b/components/query_tiles/internal/image_prefetcher_unittest.cc index f2884d3..18d4b08 100644 --- a/components/query_tiles/internal/image_prefetcher_unittest.cc +++ b/components/query_tiles/internal/image_prefetcher_unittest.cc
@@ -102,8 +102,8 @@ private: base::test::TaskEnvironment task_environment_; - raw_ptr<MockImageLoader, DanglingUntriaged> image_loader_; std::unique_ptr<ImagePrefetcher> image_prefetcher_; + raw_ptr<MockImageLoader> image_loader_; }; // All images should be fetched for ImagePrefetchMode::kAll.
diff --git a/components/reporting/client/filtered_report_queue.h b/components/reporting/client/filtered_report_queue.h index 353bd77..71fe7a9f 100644 --- a/components/reporting/client/filtered_report_queue.h +++ b/components/reporting/client/filtered_report_queue.h
@@ -11,6 +11,7 @@ #include <type_traits> #include <utility> +#include "base/metrics/histogram_functions.h" #include "base/values.h" #include "components/reporting/client/report_queue.h" #include "components/reporting/proto/synced/record_constants.pb.h" @@ -84,6 +85,10 @@ Filter() = default; }; + // Events filtering UMA metric name. + static constexpr char kFilteredOutEventsUma[] = + "Browser.ERP.FilteredOutEvents"; + FilteredReportQueue<T>(std::unique_ptr<Filter> filter, std::unique_ptr<ReportQueue> report_queue) : filter_(std::move(filter)), report_queue_(std::move(report_queue)) {} @@ -100,9 +105,11 @@ ReportQueue::EnqueueCallback callback) const { const auto status = filter_->is_accepted(record); if (!status.ok()) { + base::UmaHistogramBoolean(kFilteredOutEventsUma, true); std::move(callback).Run(status); return; } + base::UmaHistogramBoolean(kFilteredOutEventsUma, false); report_queue_->Enqueue(std::move(record), priority, std::move(callback)); } @@ -118,9 +125,11 @@ ReportQueue::EnqueueCallback callback) const { const auto status = filter_->is_accepted(record); if (!status.ok()) { + base::UmaHistogramBoolean(kFilteredOutEventsUma, true); std::move(callback).Run(status); return; } + base::UmaHistogramBoolean(kFilteredOutEventsUma, false); report_queue_->Enqueue(std::make_unique<U>(std::move(record)), priority, std::move(callback)); }
diff --git a/components/reporting/client/filtered_report_queue_unittest.cc b/components/reporting/client/filtered_report_queue_unittest.cc index e7a584b..8284360 100644 --- a/components/reporting/client/filtered_report_queue_unittest.cc +++ b/components/reporting/client/filtered_report_queue_unittest.cc
@@ -7,6 +7,7 @@ #include <memory> #include <string> +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "components/reporting/client/mock_report_queue.h" #include "components/reporting/client/report_queue.h" @@ -24,6 +25,7 @@ using ::testing::Property; using ::testing::Return; using ::testing::StrEq; +using ::testing::UnorderedElementsAre; namespace reporting { namespace { @@ -39,6 +41,7 @@ class FilteredReportQueueTest : public ::testing::Test { protected: base::test::TaskEnvironment task_environment_; + base::HistogramTester histogram_tester_; }; TEST_F(FilteredReportQueueTest, StringAcceptedTest) { @@ -61,6 +64,8 @@ test::TestEvent<Status> enqueued; queue->Enqueue(kTestMessage, Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } TEST_F(FilteredReportQueueTest, StringRejectedTest) { @@ -81,6 +86,8 @@ enqueued.result(), AllOf(Property(&Status::error_code, Eq(error::CANCELLED)), Property(&Status::error_message, StrEq("Rejected in test")))); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(true, 1))); } TEST_F(FilteredReportQueueTest, MixedStringsTest) { @@ -104,6 +111,8 @@ test::TestEvent<Status> enqueued; queue->Enqueue(kTestMessage, Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } { @@ -116,6 +125,9 @@ enqueued.result(), AllOf(Property(&Status::error_code, Eq(error::ALREADY_EXISTS)), Property(&Status::error_message, StrEq("Duplicated in test")))); + EXPECT_THAT( + histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1), base::Bucket(true, 1))); } { @@ -130,6 +142,9 @@ test::TestEvent<Status> enqueued; queue->Enqueue(kTestMessage, Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT( + histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 2), base::Bucket(true, 1))); } } @@ -158,6 +173,8 @@ test::TestEvent<Status> enqueued; queue->Enqueue(std::move(test_dict), Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } TEST_F(FilteredReportQueueTest, JsonRejectedTest) { @@ -183,6 +200,8 @@ enqueued.result(), AllOf(Property(&Status::error_code, Eq(error::CANCELLED)), Property(&Status::error_message, StrEq("Rejected in test")))); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(true, 1))); } TEST_F(FilteredReportQueueTest, MixedJsonTest) { @@ -211,6 +230,8 @@ test::TestEvent<Status> enqueued; queue->Enqueue(test_dict.Clone(), Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } { @@ -223,6 +244,9 @@ enqueued.result(), AllOf(Property(&Status::error_code, Eq(error::ALREADY_EXISTS)), Property(&Status::error_message, StrEq("Duplicated in test")))); + EXPECT_THAT( + histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1), base::Bucket(true, 1))); } { @@ -237,6 +261,9 @@ test::TestEvent<Status> enqueued; queue->Enqueue(test_dict.Clone(), Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT( + histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 2), base::Bucket(true, 1))); } } @@ -263,6 +290,8 @@ test::TestEvent<Status> enqueued; queue->Enqueue(std::move(test_message), Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } TEST_F(FilteredReportQueueTest, ProtoRejectedTest) { @@ -286,6 +315,8 @@ enqueued.result(), AllOf(Property(&Status::error_code, Eq(error::CANCELLED)), Property(&Status::error_message, StrEq("Rejected in test")))); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(true, 1))); } TEST_F(FilteredReportQueueTest, MixedProtoTest) { @@ -312,6 +343,8 @@ test::TestEvent<Status> enqueued; queue->Enqueue(test_message, Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } { @@ -324,6 +357,9 @@ enqueued.result(), AllOf(Property(&Status::error_code, Eq(error::ALREADY_EXISTS)), Property(&Status::error_message, StrEq("Duplicated in test")))); + EXPECT_THAT( + histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 1), base::Bucket(true, 1))); } { @@ -338,6 +374,9 @@ test::TestEvent<Status> enqueued; queue->Enqueue(test_message, Priority::IMMEDIATE, enqueued.cb()); EXPECT_OK(enqueued.result()); + EXPECT_THAT( + histogram_tester_.GetAllSamples(queue->kFilteredOutEventsUma), + UnorderedElementsAre(base::Bucket(false, 2), base::Bucket(true, 1))); } } } // namespace
diff --git a/components/reporting/util/wrapped_rate_limiter.cc b/components/reporting/util/wrapped_rate_limiter.cc index b2fd973..16b3b1a 100644 --- a/components/reporting/util/wrapped_rate_limiter.cc +++ b/components/reporting/util/wrapped_rate_limiter.cc
@@ -6,6 +6,7 @@ #include "base/memory/ptr_util.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_functions.h" #include "base/sequence_checker.h" #include "base/task/bind_post_task.h" #include "base/task/sequenced_task_runner.h" @@ -34,20 +35,22 @@ bool WrappedRateLimiter::Acquire(base::WeakPtr<WrappedRateLimiter> self, size_t event_size) { if (!self) { + base::UmaHistogramBoolean(kRateLimitedEventsUma, false); return false; } DCHECK_CALLED_ON_VALID_SEQUENCE(self->sequence_checker_); - return self->rate_limiter_->Acquire(event_size); + if (!self->rate_limiter_->Acquire(event_size)) { + base::UmaHistogramBoolean(kRateLimitedEventsUma, false); + return false; + } + base::UmaHistogramBoolean(kRateLimitedEventsUma, true); + return true; } // static void WrappedRateLimiter::AsyncAcquire(base::WeakPtr<WrappedRateLimiter> self, size_t event_size, base::OnceCallback<void(bool)> cb) { - if (!self) { - std::move(cb).Run(false); - return; - } base::BindOnce(&WrappedRateLimiter::Acquire, self) .Then(std::move(cb)) .Run(event_size);
diff --git a/components/reporting/util/wrapped_rate_limiter.h b/components/reporting/util/wrapped_rate_limiter.h index 23e9737..2b4b6ca 100644 --- a/components/reporting/util/wrapped_rate_limiter.h +++ b/components/reporting/util/wrapped_rate_limiter.h
@@ -53,6 +53,10 @@ base::RepeatingCallback<void(size_t /*event_size*/, base::OnceCallback<void(bool)> /*cb*/)>; + // Events rate limiting UMA metric name. + static constexpr char kRateLimitedEventsUma[] = + "Browser.ERP.RateLimitedEvents"; + // Creates wrapped rate limiter that ensures sequenced access to `Acquire`. static SmartPtr Create(std::unique_ptr<RateLimiterInterface> rate_limiter);
diff --git a/components/reporting/util/wrapped_rate_limiter_unittest.cc b/components/reporting/util/wrapped_rate_limiter_unittest.cc index 6740500..dbf50c7 100644 --- a/components/reporting/util/wrapped_rate_limiter_unittest.cc +++ b/components/reporting/util/wrapped_rate_limiter_unittest.cc
@@ -7,6 +7,7 @@ #include "base/memory/raw_ptr.h" #include "base/task/sequenced_task_runner.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "components/reporting/util/rate_limiter_interface.h" #include "components/reporting/util/test_support_callbacks.h" @@ -14,7 +15,9 @@ #include "testing/gtest/include/gtest/gtest.h" using ::testing::_; +using ::testing::Eq; using ::testing::Return; +using ::testing::UnorderedElementsAre; namespace reporting { namespace { @@ -34,6 +37,7 @@ } base::test::TaskEnvironment task_environment_; + base::HistogramTester histogram_tester_; WrappedRateLimiter::SmartPtr wrapped_rate_limiter_{ nullptr, base::OnTaskRunnerDeleter(nullptr)}; @@ -46,6 +50,9 @@ test::TestEvent<bool> acuire_event; async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_TRUE(acuire_event.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(true, 1))); } TEST_F(WrappedRateLimiterTest, RejectedAcquire) { @@ -53,6 +60,9 @@ test::TestEvent<bool> acuire_event; async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_FALSE(acuire_event.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } TEST_F(WrappedRateLimiterTest, MultipleCalls) { @@ -66,26 +76,45 @@ test::TestEvent<bool> acuire_event; async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_TRUE(acuire_event.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(true, 1))); } { test::TestEvent<bool> acuire_event; async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_FALSE(acuire_event.result()); + EXPECT_THAT( + histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(true, 1), base::Bucket(false, 1))); } { test::TestEvent<bool> acuire_event; async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_TRUE(acuire_event.result()); + EXPECT_THAT( + histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(true, 2), base::Bucket(false, 1))); } { test::TestEvent<bool> acuire_event; async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_FALSE(acuire_event.result()); + EXPECT_THAT( + histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(true, 2), base::Bucket(false, 2))); } { test::TestEvent<bool> acuire_event; async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_TRUE(acuire_event.result()); + EXPECT_THAT( + histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(true, 3), base::Bucket(false, 2))); } } @@ -95,6 +124,9 @@ wrapped_rate_limiter_.reset(); async_acquire_cb_.Run(123U, acuire_event.cb()); EXPECT_FALSE(acuire_event.result()); + EXPECT_THAT(histogram_tester_.GetAllSamples( + WrappedRateLimiter::kRateLimitedEventsUma), + UnorderedElementsAre(base::Bucket(false, 1))); } } // namespace } // namespace reporting
diff --git a/components/resources/PRESUBMIT.py b/components/resources/PRESUBMIT.py index b086e5b6..297f4095 100644 --- a/components/resources/PRESUBMIT.py +++ b/components/resources/PRESUBMIT.py
@@ -9,9 +9,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - - def CheckChange(input_api, output_api): import sys old_sys_path = sys.path[:]
diff --git a/components/resources/ssl/ssl_error_assistant/PRESUBMIT.py b/components/resources/ssl/ssl_error_assistant/PRESUBMIT.py index cb9d6fc96..9280b94 100644 --- a/components/resources/ssl/ssl_error_assistant/PRESUBMIT.py +++ b/components/resources/ssl/ssl_error_assistant/PRESUBMIT.py
@@ -7,8 +7,6 @@ This is taken from chrome/browser/resources/safe_browsing/PRESUBMIT.py. """ -USE_PYTHON3 = True - # TODO(meacer): Refactor and reuse shared code with # chrome/browser/resources/safe_browsing/PRESUBMIT.py def CheckVersionUpdatedInSSLErrorAssistantProto(input_api, output_api):
diff --git a/components/safe_browsing/content/common/proto/PRESUBMIT.py b/components/safe_browsing/content/common/proto/PRESUBMIT.py index b1110e4a..87062f8 100644 --- a/components/safe_browsing/content/common/proto/PRESUBMIT.py +++ b/components/safe_browsing/content/common/proto/PRESUBMIT.py
@@ -2,9 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): results = []
diff --git a/components/safe_browsing/content/resources/PRESUBMIT.py b/components/safe_browsing/content/resources/PRESUBMIT.py index 8f69f8d5..55ea960 100644 --- a/components/safe_browsing/content/resources/PRESUBMIT.py +++ b/components/safe_browsing/content/resources/PRESUBMIT.py
@@ -5,8 +5,6 @@ """Presubmit checks for SafeBrowsing download_file_types. """ -USE_PYTHON3 = True - def CheckVersionUpdatedInDownloadFileTypeList(input_api, output_api): # Don't report errors for "git cl presubmit --all/--files" if input_api.no_diffs:
diff --git a/components/safe_browsing/content/resources/real_time_url_checks_allowlist/PRESUBMIT.py b/components/safe_browsing/content/resources/real_time_url_checks_allowlist/PRESUBMIT.py index 9ac288a..0303e5d 100644 --- a/components/safe_browsing/content/resources/real_time_url_checks_allowlist/PRESUBMIT.py +++ b/components/safe_browsing/content/resources/real_time_url_checks_allowlist/PRESUBMIT.py
@@ -6,8 +6,6 @@ Presubmit checks for SafeBrowsing real_time_url_checks_allowlist. """ -USE_PYTHON3 = True - def _CheckIdHelper(contents, id_type): """Return the version or scheme id from the provided file contents.
diff --git a/components/safe_browsing/core/common/proto/PRESUBMIT.py b/components/safe_browsing/core/common/proto/PRESUBMIT.py index fad36e48..75f1e78 100644 --- a/components/safe_browsing/core/common/proto/PRESUBMIT.py +++ b/components/safe_browsing/core/common/proto/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def CheckChangeOnUpload(input_api, output_api): results = []
diff --git a/components/search_engines/PRESUBMIT.py b/components/search_engines/PRESUBMIT.py index 053f944..2e4cfae 100644 --- a/components/search_engines/PRESUBMIT.py +++ b/components/search_engines/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - import os def _CheckPrepopulatedEnginesVersion(input_api, output_api):
diff --git a/components/search_engines/android/template_url_service_android.cc b/components/search_engines/android/template_url_service_android.cc index 1cc492a..6017a7f 100644 --- a/components/search_engines/android/template_url_service_android.cc +++ b/components/search_engines/android/template_url_service_android.cc
@@ -327,8 +327,6 @@ // TODO(tommycli): Delete this once the below metric approaches zero. TemplateURL* turl = *existing_play_api_turl; if (turl->safe_for_autoreplace()) { - TemplateURLService::LogSearchTemplateURLEvent( - TemplateURLService::MIGRATE_SAFE_FOR_AUTOREPLACE_PLAY_API_ENGINE); template_url_service_->ResetTemplateURL(turl, turl->short_name(), turl->keyword(), turl->url()); }
diff --git a/components/search_engines/template_url_service.cc b/components/search_engines/template_url_service.cc index cfb55a4a..faab9daf 100644 --- a/components/search_engines/template_url_service.cc +++ b/components/search_engines/template_url_service.cc
@@ -316,13 +316,6 @@ } // static -void TemplateURLService::LogSearchTemplateURLEvent( - SearchTemplateURLEvent event) { - UMA_HISTOGRAM_ENUMERATION("Search.TemplateURL.Events", event, - SEARCH_TEMPLATE_URL_EVENT_MAX); -} - -// static void TemplateURLService::RegisterProfilePrefs( user_prefs::PrefRegistrySyncable* registry) { #if BUILDFLAG(IS_IOS) || BUILDFLAG(IS_ANDROID) @@ -1213,8 +1206,7 @@ syncer::SyncChange::ChangeTypeToString(iter->change_type()); if (iter->change_type() == syncer::SyncChange::ACTION_DELETE) { if (!existing_turl) { - // Can't DELETE a non-existent engine, although we log it. - LogSearchTemplateURLEvent(SYNC_DELETE_FAIL_NONEXISTENT_ENGINE); + // Can't DELETE a non-existent engine. error = syncer::ModelError(FROM_HERE, error_msg); continue; } @@ -1232,9 +1224,6 @@ // likely a source of duplicate search engine entries. crbug.com/1022775 if (existing_turl != GetDefaultSearchProvider()) { Remove(existing_turl); - LogSearchTemplateURLEvent(SYNC_DELETE_SUCCESS); - } else { - LogSearchTemplateURLEvent(SYNC_DELETE_FAIL_DEFAULT_SEARCH_PROVIDER); } continue; } @@ -1247,12 +1236,6 @@ iter->change_type() == syncer::SyncChange::ACTION_UPDATE); if (!existing_turl) { - if (iter->change_type() == syncer::SyncChange::ACTION_UPDATE) { - // This can happen if we have silently deleted a replaceable engine due - // to keyword conflict, and Sync server sends us an UPDATE to it. - LogSearchTemplateURLEvent(SYNC_UPDATE_CONVERTED_TO_ADD); - } - base::AutoReset<DefaultSearchChangeOrigin> change_origin_add( &dsp_change_origin_, DSP_CHANGE_SYNC_ADD); // Force the local ID to kInvalidTemplateURLID so we can add it. @@ -1262,22 +1245,8 @@ TemplateURL* added = Add(std::make_unique<TemplateURL>(data)); if (added) { MaybeUpdateDSEViaPrefs(added); - - LogSearchTemplateURLEvent(SYNC_ADD_SUCCESS); - } else { - // Currently, in practice, this means that we tried to add a replaceable - // duplicate that was worse than our existing entry, but the API doesn't - // promise that, so we just log a generic SYNC_ADD_FAIL_OTHER_ERROR. - LogSearchTemplateURLEvent(SYNC_ADD_FAIL_OTHER_ERROR); } } else { - if (iter->change_type() == syncer::SyncChange::ACTION_ADD) { - // This can happen if we have ignored a DELETE request in the past to - // avoid deleting the default search provider, and later on, Sync tries - // to re-ADD something it thinks it has deleted. - LogSearchTemplateURLEvent(SYNC_ADD_CONVERTED_TO_UPDATE); - } - // Since we've already found |existing_turl| by GUID, this Update() should // always return true, but we still don't want to crash if it fails. DCHECK(existing_turl); @@ -1285,7 +1254,6 @@ DCHECK(update_success); MaybeUpdateDSEViaPrefs(existing_turl); - LogSearchTemplateURLEvent(SYNC_UPDATE_SUCCESS); } }
diff --git a/components/search_engines/template_url_service.h b/components/search_engines/template_url_service.h index 63e684f..111f1ef1 100644 --- a/components/search_engines/template_url_service.h +++ b/components/search_engines/template_url_service.h
@@ -113,21 +113,6 @@ std::u16string search_terms; }; - // Values for an enumerated histogram used to track TemplateURL edge cases. - // These are persisted. Do not re-number. - enum SearchTemplateURLEvent { - SYNC_DELETE_SUCCESS = 0, - SYNC_DELETE_FAIL_NONEXISTENT_ENGINE = 1, - SYNC_DELETE_FAIL_DEFAULT_SEARCH_PROVIDER = 2, - SYNC_ADD_SUCCESS = 3, - SYNC_ADD_CONVERTED_TO_UPDATE = 4, - SYNC_ADD_FAIL_OTHER_ERROR = 5, - SYNC_UPDATE_SUCCESS = 6, - SYNC_UPDATE_CONVERTED_TO_ADD = 7, - MIGRATE_SAFE_FOR_AUTOREPLACE_PLAY_API_ENGINE = 8, - SEARCH_TEMPLATE_URL_EVENT_MAX, - }; - TemplateURLService( PrefService* prefs, std::unique_ptr<SearchTermsData> search_terms_data, @@ -142,9 +127,6 @@ ~TemplateURLService() override; - // Log a SearchTemplateURLEvent. - static void LogSearchTemplateURLEvent(SearchTemplateURLEvent event); - // Register Profile preferences in |registry|. static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
diff --git a/components/segmentation_platform/PRESUBMIT.py b/components/segmentation_platform/PRESUBMIT.py index e199446..b3d7666 100644 --- a/components/segmentation_platform/PRESUBMIT.py +++ b/components/segmentation_platform/PRESUBMIT.py
@@ -6,8 +6,6 @@ from typing import Dict, List -USE_PYTHON3 = True - TOOL_PATH = 'tools/testing/launcher_filter_file.py'
diff --git a/components/segmentation_platform/internal/proto/PRESUBMIT.py b/components/segmentation_platform/internal/proto/PRESUBMIT.py index 12eed6c..62fe9f14 100644 --- a/components/segmentation_platform/internal/proto/PRESUBMIT.py +++ b/components/segmentation_platform/internal/proto/PRESUBMIT.py
@@ -7,8 +7,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def CheckChange(input_api, output_api): cwd = input_api.PresubmitLocalPath() for f in input_api.AffectedFiles():
diff --git a/components/segmentation_platform/internal/selection/request_handler_unittest.cc b/components/segmentation_platform/internal/selection/request_handler_unittest.cc index e46fb7d..c2bfbe17 100644 --- a/components/segmentation_platform/internal/selection/request_handler_unittest.cc +++ b/components/segmentation_platform/internal/selection/request_handler_unittest.cc
@@ -74,8 +74,8 @@ base::test::TaskEnvironment task_environment_{ base::test::TaskEnvironment::TimeSource::MOCK_TIME}; std::unique_ptr<Config> config_; - raw_ptr<MockResultProvider, DanglingUntriaged> result_provider_ = nullptr; std::unique_ptr<RequestHandler> request_handler_; + raw_ptr<MockResultProvider> result_provider_ = nullptr; ExecutionService execution_service_; };
diff --git a/components/segmentation_platform/tools/testing/launcher_filter_file.py b/components/segmentation_platform/tools/testing/launcher_filter_file.py index f19bc40..e7674da 100755 --- a/components/segmentation_platform/tools/testing/launcher_filter_file.py +++ b/components/segmentation_platform/tools/testing/launcher_filter_file.py
@@ -18,8 +18,6 @@ import os import re -USE_PYTHON3 = True - OUTPUT_FILENAME = 'components_unittests.filter'
diff --git a/components/services/app_service/BUILD.gn b/components/services/app_service/BUILD.gn new file mode 100644 index 0000000..b924385c --- /dev/null +++ b/components/services/app_service/BUILD.gn
@@ -0,0 +1,35 @@ +# 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. + +import("//build/config/chromeos/ui_mode.gni") + +# The primary public target for the App Service component. Prefer to use this instead of depending on individual targets inside the component. +source_set("app_service") { + public_deps = [ + "//components/services/app_service/public/cpp:app_file_handling", + "//components/services/app_service/public/cpp:app_share_target", + "//components/services/app_service/public/cpp:app_types", + "//components/services/app_service/public/cpp:app_update", + "//components/services/app_service/public/cpp:app_url_handling", + "//components/services/app_service/public/cpp:crosapi_utils", + "//components/services/app_service/public/cpp:icon_loader", + "//components/services/app_service/public/cpp:icon_types", + "//components/services/app_service/public/cpp:intents", + "//components/services/app_service/public/cpp:macros", + "//components/services/app_service/public/cpp:preferred_app", + "//components/services/app_service/public/cpp:preferred_apps", + "//components/services/app_service/public/cpp:protocol_handling", + "//components/services/app_service/public/cpp:run_on_os_login", + "//components/services/app_service/public/cpp:types", + ] + + if (is_chromeos) { + public_deps += [ "//components/services/app_service/public/cpp:browser_app_instance_registry_update" ] + } + + if (is_chromeos_ash) { + public_deps += + [ "//components/services/app_service/public/cpp:instance_update" ] + } +}
diff --git a/components/services/app_service/public/cpp/BUILD.gn b/components/services/app_service/public/cpp/BUILD.gn index 32961aa..5ecda1f 100644 --- a/components/services/app_service/public/cpp/BUILD.gn +++ b/components/services/app_service/public/cpp/BUILD.gn
@@ -4,6 +4,10 @@ import("//build/config/chromeos/ui_mode.gni") +# Prefer to depend on the component's public target +# "//components/services/app_service" instead of several individual targets in +# this directory. + source_set("app_file_handling") { sources = [ "file_handler.cc",
diff --git a/components/sessions/core/command_storage_backend.cc b/components/sessions/core/command_storage_backend.cc index 10796a8..7acf35d0 100644 --- a/components/sessions/core/command_storage_backend.cc +++ b/components/sessions/core/command_storage_backend.cc
@@ -174,6 +174,9 @@ // The file. std::unique_ptr<base::File> file_; + // The number of bytes successfully read from `file_`. + int bytes_read_ = 0; + // Position in buffer_ of the data. size_t buffer_position_ = 0; @@ -205,7 +208,8 @@ LOG_IF(ERROR, result.error_reading) << "Commands successfully read before error: " - << commands_result.commands.size(); + << commands_result.commands.size() + << ", bytes successfully read from file before error: " << bytes_read_; // `error_reading` is only set if `command` is null. commands_result.error_reading = result.error_reading; @@ -220,10 +224,23 @@ if (!file_->IsValid()) return false; FileHeader header; - const int read_count = + CHECK_EQ(0, bytes_read_); + bytes_read_ = file_->ReadAtCurrentPos(reinterpret_cast<char*>(&header), sizeof(header)); - if (read_count != sizeof(header) || header.signature != kFileSignature) + if (bytes_read_ < 0) { + VLOG(1) << "SessionFileReader::ReadHeader, failed to read header. " + "Attempted to read " + << sizeof(header) + << " bytes into buffer but encountered file read error: " + << base::File::ErrorToString(base::File::GetLastFileError()); + } + if (bytes_read_ != sizeof(header) || header.signature != kFileSignature) { + VLOG(1) << "SessionFileReader::ReadHeader, failed to read header. " + "Attempted to read " + << sizeof(header) << " bytes into buffer but got " << bytes_read_ + << " bytes instead."; return false; + } version_ = header.version; const bool encrypt = aead_.get() != nullptr; return (encrypt && (version_ == kEncryptedFileVersion || @@ -345,15 +362,21 @@ } buffer_position_ = 0; DCHECK(buffer_position_ + available_count_ < buffer_.size()); - int to_read = static_cast<int>(buffer_.size() - available_count_); - int read_count = + const int to_read = static_cast<int>(buffer_.size() - available_count_); + const int read_count = file_->ReadAtCurrentPos(&(buffer_[available_count_]), to_read); if (read_count < 0) { - // TODO(sky): communicate/log an error here. + VLOG(1) << "SessionFileReader::FillBuffer, failed to read header. " + "Attempted to read " + << to_read << " bytes into buffer but encountered file read error: " + << base::File::ErrorToString(base::File::GetLastFileError()) + << "\nRead " << bytes_read_ + << " bytes successfully from file before error."; return false; } if (read_count == 0) return false; + bytes_read_ += read_count; available_count_ += read_count; return true; } @@ -564,15 +587,22 @@ CommandStorageBackend::ReadLastSessionCommands() { InitIfNecessary(); - if (last_session_info_) + if (last_session_info_) { + VLOG(1) << "CommandStorageBackend::ReadLastSessionCommands, reading " + "commands from: " + << last_session_info_->path; return ReadCommandsFromFile(last_session_info_->path, initial_decryption_key_); + } return {}; } void CommandStorageBackend::DeleteLastSession() { InitIfNecessary(); if (last_session_info_) { + VLOG(1) + << "CommandStorageBackend::DeleteLastSession, deleting session file: " + << last_session_info_->path; base::DeleteFile(last_session_info_->path); last_session_info_.reset(); } @@ -594,6 +624,9 @@ last_or_current_path_with_valid_marker_.reset(); } last_session_info_ = new_last_session_info; + VLOG(1) << "CommandStorageBackend::MoveCurrentSessionToLastSession, moved " + "current session to: " + << (last_session_info_ ? last_session_info_->path : base::FilePath()); TruncateOrOpenFile(); }
diff --git a/components/sessions/core/tab_restore_service_impl.cc b/components/sessions/core/tab_restore_service_impl.cc index 837fbd22..28fe077 100644 --- a/components/sessions/core/tab_restore_service_impl.cc +++ b/components/sessions/core/tab_restore_service_impl.cc
@@ -34,6 +34,12 @@ #include "components/tab_groups/tab_group_id.h" #include "components/tab_groups/tab_group_visual_data.h" +// TODO(crbug.com/1424800): Remove once the restore issue has been resolved. +#if BUILDFLAG(IS_CHROMEOS_LACROS) +#undef ENABLED_VLOG_LEVEL +#define ENABLED_VLOG_LEVEL 1 +#endif + #undef LoadBitmap namespace sessions { @@ -754,6 +760,8 @@ // Request the tabs closed in the last session. If the last session crashed, // this won't contain the tabs/window that were open at the point of the // crash (the call to GetLastSession above requests those). + VLOG(1) << "PersistenceDelegate::LoadTabsFromLastSession, getting tab " + "restore commands."; command_storage_manager_->GetLastSessionCommands( base::BindOnce(&PersistenceDelegate::OnGotLastSessionCommands, weak_factory_.GetWeakPtr()));
diff --git a/components/subresource_filter/core/common/PRESUBMIT.py b/components/subresource_filter/core/common/PRESUBMIT.py index bb9cf0b2..b0c9716 100644 --- a/components/subresource_filter/core/common/PRESUBMIT.py +++ b/components/subresource_filter/core/common/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def CheckIndexedRulesetVersion(input_api, output_api): """ Checks that IndexedRuleset format version is modified when necessary.
diff --git a/components/sync/PRESUBMIT.py b/components/sync/PRESUBMIT.py index e7595242..29a7de1 100644 --- a/components/sync/PRESUBMIT.py +++ b/components/sync/PRESUBMIT.py
@@ -11,8 +11,6 @@ import os import re -USE_PYTHON3 = True - # Some definitions don't follow all the conventions we want to enforce. # It's either difficult or impossible to fix this, so we ignore the problem(s). EXCEPTION_MODEL_TYPES = [
diff --git a/components/sync/nigori/nigori_model_type_processor_unittest.cc b/components/sync/nigori/nigori_model_type_processor_unittest.cc index 7716ea0..37cdb3f 100644 --- a/components/sync/nigori/nigori_model_type_processor_unittest.cc +++ b/components/sync/nigori/nigori_model_type_processor_unittest.cc
@@ -138,6 +138,12 @@ processor_.ConnectSync(std::move(mock_commit_queue_)); } + void SimulateSyncStopping(SyncStopMetadataFate fate) { + // Drop unowned reference before stopping processor which will destroy it. + mock_commit_queue_ptr_ = nullptr; + processor_.OnSyncStopping(fate); + } + MockNigoriSyncBridge* mock_nigori_sync_bridge() { return &mock_nigori_sync_bridge_; } @@ -167,7 +173,7 @@ private: testing::NiceMock<MockNigoriSyncBridge> mock_nigori_sync_bridge_; std::unique_ptr<testing::NiceMock<MockCommitQueue>> mock_commit_queue_; - raw_ptr<MockCommitQueue, DanglingUntriaged> mock_commit_queue_ptr_; + raw_ptr<MockCommitQueue> mock_commit_queue_ptr_; NigoriModelTypeProcessor processor_; }; @@ -503,7 +509,7 @@ ASSERT_TRUE(processor()->IsConnectedForTest()); EXPECT_CALL(*mock_nigori_sync_bridge(), ApplyDisableSyncChanges()).Times(0); - processor()->OnSyncStopping(syncer::KEEP_METADATA); + SimulateSyncStopping(syncer::KEEP_METADATA); EXPECT_FALSE(processor()->IsConnectedForTest()); } @@ -517,7 +523,7 @@ ASSERT_TRUE(processor()->IsConnectedForTest()); EXPECT_CALL(*mock_nigori_sync_bridge(), ApplyDisableSyncChanges()); - processor()->OnSyncStopping(syncer::CLEAR_METADATA); + SimulateSyncStopping(syncer::CLEAR_METADATA); EXPECT_FALSE(processor()->IsConnectedForTest()); }
diff --git a/components/sync/service/resources/PRESUBMIT.py b/components/sync/service/resources/PRESUBMIT.py index 53687cb..d32ad24 100644 --- a/components/sync/service/resources/PRESUBMIT.py +++ b/components/sync/service/resources/PRESUBMIT.py
@@ -2,9 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): return _CommonChecks(input_api, output_api)
diff --git a/components/sync_bookmarks/PRESUBMIT.py b/components/sync_bookmarks/PRESUBMIT.py index 3fe15da..c2c2f8a 100644 --- a/components/sync_bookmarks/PRESUBMIT.py +++ b/components/sync_bookmarks/PRESUBMIT.py
@@ -10,8 +10,6 @@ import re -USE_PYTHON3 = True - SYNC_BOOKMARKS_SOURCE_FILES = ( r'^components[\\/]sync_bookmarks[\\/].*\.(cc|h)$',)
diff --git a/components/sync_sessions/PRESUBMIT.py b/components/sync_sessions/PRESUBMIT.py index 1d8a143..13cb751 100644 --- a/components/sync_sessions/PRESUBMIT.py +++ b/components/sync_sessions/PRESUBMIT.py
@@ -10,8 +10,6 @@ import re -USE_PYTHON3 = True - SYNC_SESSIONS_SOURCE_FILES = (r'^components[\\/]sync_sessions[\\/].*\.(cc|h)$',) def CheckChangeLintsClean(input_api, output_api):
diff --git a/components/test/PRESUBMIT.py b/components/test/PRESUBMIT.py index d2e5ec2..40c8c1d 100644 --- a/components/test/PRESUBMIT.py +++ b/components/test/PRESUBMIT.py
@@ -10,9 +10,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - - def CheckChange(input_api, output_api): old_sys_path = sys.path[:] results = []
diff --git a/components/test/components_test_suite.cc b/components/test/components_test_suite.cc index fb4e09d..496cd86 100644 --- a/components/test/components_test_suite.cc +++ b/components/test/components_test_suite.cc
@@ -66,7 +66,7 @@ #if BUILDFLAG(USE_BLINK) gl::GLSurfaceTestSupport::InitializeOneOff(); - content::ForceInProcessNetworkService(true); + content::ForceInProcessNetworkService(); // Setup content scheme statics. {
diff --git a/components/test/data/visual_model.tflite b/components/test/data/visual_model.tflite new file mode 100644 index 0000000..ebf0532 --- /dev/null +++ b/components/test/data/visual_model.tflite
@@ -0,0 +1 @@ +empty file used by chrome/browser/companion/visual_search/visual_search_suggestions_service_unittest.cc \ No newline at end of file
diff --git a/components/translate/core/browser/translate_ui_delegate.cc b/components/translate/core/browser/translate_ui_delegate.cc index 2ccf1db..fe2eb64 100644 --- a/components/translate/core/browser/translate_ui_delegate.cc +++ b/components/translate/core/browser/translate_ui_delegate.cc
@@ -20,26 +20,11 @@ namespace { -const char kPerformTranslateAmpCacheUrl[] = "Translate.Translate.AMPCacheURL"; const char kNeverTranslateLang[] = "Translate.NeverTranslateLang"; const char kNeverTranslateSite[] = "Translate.NeverTranslateSite"; const char kAlwaysTranslateLang[] = "Translate.AlwaysTranslateLang"; -const char kModifySourceLang[] = "Translate.ModifyOriginalLang"; const char kShowErrorUI[] = "Translate.ShowErrorUI"; -// Returns whether |url| fits pattern of an AMP cache url. -// Note this is a copy of logic in amp_page_load_metrics_observer.cc -// TODO(crbug.com/1064974) Factor out into shared utility. -bool IsLikelyAmpCacheUrl(const GURL& url) { - // Our heuristic to identify AMP cache URLs is to check for the presence of - // the amp_js_v query param. - for (net::QueryIterator it(url); !it.IsAtEnd(); it.Advance()) { - if (it.GetKey() == "amp_js_v") - return true; - } - return false; -} - } // namespace namespace translate { @@ -95,8 +80,6 @@ return; } - UMA_HISTOGRAM_BOOLEAN(kModifySourceLang, true); - if (translate_manager_) { translate_manager_->GetActiveTranslateMetricsLogger()->LogSourceLanguage( translate_ui_languages_manager_->GetLanguageCodeAt(language_index)); @@ -192,8 +175,6 @@ translate_manager_->GetActiveTranslateMetricsLogger() ->GetNextManualTranslationType( /*is_context_menu_initiated_translation=*/false)); - if (IsLikelyAmpCacheUrl(translate_driver_->GetLastCommittedURL())) - UMA_HISTOGRAM_BOOLEAN(kPerformTranslateAmpCacheUrl, true); } }
diff --git a/components/ukm/debug/PRESUBMIT.py b/components/ukm/debug/PRESUBMIT.py index 6c5dd50..79374e1 100644 --- a/components/ukm/debug/PRESUBMIT.py +++ b/components/ukm/debug/PRESUBMIT.py
@@ -2,9 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - - def _CommonChecks(input_api, output_api): results = [] try:
diff --git a/components/ukm/ukm_reporting_service.cc b/components/ukm/ukm_reporting_service.cc index e3824ff..1463d364 100644 --- a/components/ukm/ukm_reporting_service.cc +++ b/components/ukm/ukm_reporting_service.cc
@@ -15,6 +15,7 @@ #include "build/build_config.h" #include "components/metrics/metrics_service_client.h" #include "components/metrics/metrics_switches.h" +#include "components/metrics/unsent_log_store.h" #include "components/metrics/url_constants.h" #include "components/prefs/pref_registry_simple.h" #include "components/ukm/ukm_pref_names.h" @@ -79,9 +80,11 @@ local_state, prefs::kUkmUnsentLogStore, nullptr, - kMinUnsentLogCount, - kMinUnsentLogBytes, - kMaxLogRetransmitSize, + metrics::UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = kMinUnsentLogCount, + .min_queue_size_bytes = kMinUnsentLogBytes, + .max_log_size_bytes = kMaxLogRetransmitSize, + }, client->GetUploadSigningKey(), /*logs_event_manager=*/nullptr) {}
diff --git a/components/ukm/ukm_service_unittest.cc b/components/ukm/ukm_service_unittest.cc index 6715103..8e9a6f3e 100644 --- a/components/ukm/ukm_service_unittest.cc +++ b/components/ukm/ukm_service_unittest.cc
@@ -143,8 +143,10 @@ metrics::UnsentLogStore result_unsent_log_store( std::make_unique<UnsentLogStoreMetricsImpl>(), &prefs, prefs::kUkmUnsentLogStore, /*metadata_pref_name=*/nullptr, - /*min_log_count=*/3, /*min_log_bytes=*/1000, - /*max_log_size=*/0, + // Set to 3 so logs are not dropped in the test. + metrics::UnsentLogStore::UnsentLogStoreLimits{ + .min_log_count = 3, + }, /*signing_key=*/std::string(), /*logs_event_manager=*/nullptr);
diff --git a/components/update_client/update_query_params.cc b/components/update_client/update_query_params.cc index 2389612..a522312 100644 --- a/components/update_client/update_query_params.cc +++ b/components/update_client/update_query_params.cc
@@ -61,10 +61,10 @@ "mipsel"; #elif defined(__powerpc64__) "ppc64"; -#elif defined(ARCH_CPU_LOONG32) - "loong32"; -#elif defined(ARCH_CPU_LOONG64) - "loong64"; +#elif defined(ARCH_CPU_LOONGARCH32) + "loongarch32"; +#elif defined(ARCH_CPU_LOONGARCH64) + "loongarch64"; #elif defined(ARCH_CPU_RISCV64) "riscv64"; #else @@ -136,10 +136,10 @@ return "mips64"; #elif defined(ARCH_CPU_PPC64) return "ppc64"; -#elif defined(ARCH_CPU_LOONG32) - return "loong32"; -#elif defined(ARCH_CPU_LOONG64) - return "loong64"; +#elif defined(ARCH_CPU_LOONGARCH32) + return "loongarch32"; +#elif defined(ARCH_CPU_LOONGARCH64) + return "loongarch64"; #elif defined(ARCH_CPU_RISCV64) return "riscv64"; #else
diff --git a/components/url_pattern_index/PRESUBMIT.py b/components/url_pattern_index/PRESUBMIT.py index 9dca24bd7..f78f416 100644 --- a/components/url_pattern_index/PRESUBMIT.py +++ b/components/url_pattern_index/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def CheckUrlPatternIndexFormatVersion(input_api, output_api): """ Checks the kUrlPatternIndexFormatVersion is modified when necessary.
diff --git a/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java b/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java index b618ad1..aa3e5691 100644 --- a/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java +++ b/components/variations/android/java/src/org/chromium/components/variations/firstrun/VariationsSeedFetcher.java
@@ -42,6 +42,7 @@ import java.util.Arrays; import java.util.Date; import java.util.List; +import java.util.Objects; /** Fetches the variations seed before the actual first run of Chrome. */ public class VariationsSeedFetcher { @@ -252,10 +253,30 @@ private String mRestrictMode; private String mMilestone; private String mChannel; - private Boolean mIsFastFetchMode; + private boolean mIsFastFetchMode; + + // This is added as a convenience for using Mockito. + @Override + public boolean equals(final Object obj) { + if (obj == null) return false; + if (obj.getClass() != this.getClass()) return false; + if (!(obj instanceof SeedFetchParameters)) return false; + SeedFetchParameters castObj = (SeedFetchParameters) obj; + + return getPlatform() == castObj.getPlatform() + && getIsFastFetchMode() == castObj.getIsFastFetchMode() + && Objects.equals(getMilestone(), castObj.getMilestone()) + && Objects.equals(getRestrictMode(), castObj.getRestrictMode()) + && Objects.equals(getChannel(), castObj.getChannel()); + } + + @Override + public int hashCode() { + return Objects.hash(mPlatform, mRestrictMode, mMilestone, mChannel, mIsFastFetchMode); + } private SeedFetchParameters(@VariationsPlatform int platform, String restrictMode, - String milestone, String channel, Boolean isFastFetchMode) { + String milestone, String channel, boolean isFastFetchMode) { this.mPlatform = platform; this.mRestrictMode = restrictMode; this.mMilestone = milestone; @@ -269,7 +290,7 @@ private String mRestrictMode; private String mMilestone; private String mChannel; - private Boolean mIsFastFetchMode; + private boolean mIsFastFetchMode; private Builder() { this.mPlatform = VariationsPlatform.ANDROID; @@ -328,7 +349,7 @@ return mChannel; } - public Boolean getIsFastFetchMode() { + public boolean getIsFastFetchMode() { return mIsFastFetchMode; } }
diff --git a/components/variations/android/junit/src/org/chromium/components/variations/firstrun/VariationsSeedFetcherTest.java b/components/variations/android/junit/src/org/chromium/components/variations/firstrun/VariationsSeedFetcherTest.java index 3e8f751c..17ba75ae 100644 --- a/components/variations/android/junit/src/org/chromium/components/variations/firstrun/VariationsSeedFetcherTest.java +++ b/components/variations/android/junit/src/org/chromium/components/variations/firstrun/VariationsSeedFetcherTest.java
@@ -11,7 +11,6 @@ import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; -import static org.mockito.Mockito.any; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -74,7 +73,13 @@ mConnection = mock(HttpURLConnection.class); doReturn(mConnection) .when(mFetcher) - .getServerConnection(any(VariationsSeedFetcher.SeedFetchParameters.class)); + .getServerConnection( + VariationsSeedFetcher.SeedFetchParameters.Builder.newBuilder() + .setPlatform(VariationsSeedFetcher.VariationsPlatform.ANDROID) + .setRestrictMode(sRestrict) + .setMilestone(sMilestone) + .setChannel(sChannel) + .build()); mPrefs = ContextUtils.getAppSharedPreferences(); UmaRecorderHolder.resetForTesting(); } @@ -95,6 +100,16 @@ when(mConnection.getHeaderField("IM")).thenReturn("gzip"); when(mConnection.getInputStream()) .thenReturn(new ByteArrayInputStream(ApiCompatibilityUtils.getBytesUtf8("1234"))); + doReturn(mConnection) + .when(mFetcher) + .getServerConnection( + VariationsSeedFetcher.SeedFetchParameters.Builder.newBuilder() + .setPlatform(VariationsSeedFetcher.VariationsPlatform.ANDROID) + .setMilestone(sMilestone) + .setChannel(sChannel) + // Restrict mode is null because fetchSeed sets this to null. + .setRestrictMode(null) + .build()); long startTime = new Date().getTime(); mFetcher.fetchSeed(sRestrict, sMilestone, sChannel); @@ -472,6 +487,14 @@ @Test public void testFetchSeed_badResponse() throws IOException { when(mConnection.getResponseCode()).thenReturn(HttpURLConnection.HTTP_NOT_FOUND); + doReturn(mConnection) + .when(mFetcher) + .getServerConnection( + VariationsSeedFetcher.SeedFetchParameters.Builder.newBuilder() + .setPlatform(VariationsSeedFetcher.VariationsPlatform.ANDROID) + .setMilestone(sMilestone) + .setChannel(sChannel) + .build()); mFetcher.fetchSeed(sRestrict, sMilestone, sChannel); @@ -492,6 +515,14 @@ @Test public void testFetchSeed_IOException() throws IOException { doThrow(new IOException()).when(mConnection).connect(); + doReturn(mConnection) + .when(mFetcher) + .getServerConnection( + VariationsSeedFetcher.SeedFetchParameters.Builder.newBuilder() + .setPlatform(VariationsSeedFetcher.VariationsPlatform.ANDROID) + .setMilestone(sMilestone) + .setChannel(sChannel) + .build()); mFetcher.fetchSeed(sRestrict, sMilestone, sChannel);
diff --git a/components/variations/proto/PRESUBMIT.py b/components/variations/proto/PRESUBMIT.py index 86d1265..bb8fe8a 100644 --- a/components/variations/proto/PRESUBMIT.py +++ b/components/variations/proto/PRESUBMIT.py
@@ -6,7 +6,6 @@ See https://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True def CheckChange(input_api, output_api): """Checks that changes to client_variations.proto are mirrored."""
diff --git a/components/vector_icons/BUILD.gn b/components/vector_icons/BUILD.gn index f35bcec..dfa62918 100644 --- a/components/vector_icons/BUILD.gn +++ b/components/vector_icons/BUILD.gn
@@ -48,7 +48,8 @@ "close_rounded.icon", "cloud_download.icon", "code.icon", - "code_off.icon", + "code_chrome_refresh.icon", + "code_off_chrome_refresh.icon", "content_copy.icon", "content_paste.icon", "content_paste_chrome_refresh.icon", @@ -169,7 +170,8 @@ "select_window_chrome_refresh.icon", "select_window_off_chrome_refresh.icon", "sensors.icon", - "sensors_off.icon", + "sensors_chrome_refresh.icon", + "sensors_off_chrome_refresh.icon", "serial_port.icon", "serial_port_chrome_refresh.icon", "serial_port_off_chrome_refresh.icon", @@ -195,8 +197,8 @@ "videogame_asset.icon", "videogame_asset_chrome_refresh.icon", "videogame_asset_off_chrome_refresh.icon", - "view_in_ar.icon", - "view_in_ar_off.icon", + "view_in_ar_chrome_refresh.icon", + "view_in_ar_off_chrome_refresh.icon", "volume_off.icon", "volume_off_chrome_refresh.icon", "volume_up.icon",
diff --git a/components/vector_icons/account_circle_chrome_refresh.icon b/components/vector_icons/account_circle_chrome_refresh.icon index 2562897..32fa3ff7 100644 --- a/components/vector_icons/account_circle_chrome_refresh.icon +++ b/components/vector_icons/account_circle_chrome_refresh.icon
@@ -64,8 +64,132 @@ R_CUBIC_TO, -0.28f, 0.28f, -0.41f, 0.63f, -0.41f, 1.04f, R_CUBIC_TO, 0, 0.42f, 0.14f, 0.77f, 0.41f, 1.04f, R_CUBIC_TO, 0.27f, 0.28f, 0.62f, 0.41f, 1.04f, 0.41f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.96f, 13.99f, +R_ARC_TO, 8.24f, 8.24f, 0, 0, 1, 2.4f, -1.16f, +R_ARC_TO, 9.28f, 9.28f, 0, 0, 1, 2.64f, -0.37f, +R_CUBIC_TO, 0.91f, 0, 1.8f, 0.13f, 2.65f, 0.38f, +R_ARC_TO, 8.34f, 8.34f, 0, 0, 1, 2.39f, 1.15f, +R_ARC_TO, 5.84f, 5.84f, 0, 0, 0, 1.06f, -1.87f, +R_CUBIC_TO, 0.23f, -0.68f, 0.34f, -1.38f, 0.34f, -2.12f, +R_CUBIC_TO, 0, -1.78f, -0.63f, -3.3f, -1.89f, -4.55f, +R_CUBIC_TO, -1.26f, -1.26f, -2.78f, -1.89f, -4.56f, -1.89f, +R_CUBIC_TO, -1.78f, 0, -3.3f, 0.63f, -4.55f, 1.89f, +CUBIC_TO, 4.19f, 6.7f, 3.56f, 8.22f, 3.56f, 10, +R_CUBIC_TO, 0, 0.73f, 0.11f, 1.44f, 0.34f, 2.11f, +R_CUBIC_TO, 0.23f, 0.68f, 0.58f, 1.3f, 1.06f, 1.88f, CLOSE, -R_MOVE_TO, 0, -1.45f, +MOVE_TO, 10, 11.54f, +R_CUBIC_TO, -0.85f, 0, -1.57f, -0.29f, -2.16f, -0.88f, +R_CUBIC_TO, -0.59f, -0.59f, -0.88f, -1.31f, -0.88f, -2.15f, +R_CUBIC_TO, 0, -0.85f, 0.29f, -1.57f, 0.88f, -2.16f, +ARC_TO, 2.94f, 2.94f, 0, 0, 1, 10, 5.47f, +R_CUBIC_TO, 0.85f, 0, 1.57f, 0.3f, 2.16f, 0.89f, +R_CUBIC_TO, 0.59f, 0.59f, 0.88f, 1.31f, 0.88f, 2.16f, +R_CUBIC_TO, 0, 0.84f, -0.29f, 1.56f, -0.88f, 2.15f, +R_CUBIC_TO, -0.59f, 0.59f, -1.31f, 0.88f, -2.16f, 0.88f, CLOSE, -R_MOVE_TO, 0.01f, 8.97f, +R_MOVE_TO, 0, 6.63f, +R_ARC_TO, 7.96f, 7.96f, 0, 0, 1, -3.17f, -0.64f, +R_ARC_TO, 8.25f, 8.25f, 0, 0, 1, -2.61f, -1.75f, +R_ARC_TO, 8.25f, 8.25f, 0, 0, 1, -1.75f, -2.61f, +R_ARC_TO, 7.97f, 7.97f, 0, 0, 1, -0.64f, -3.18f, +R_CUBIC_TO, 0, -1.12f, 0.21f, -2.18f, 0.64f, -3.17f, +R_ARC_TO, 8.29f, 8.29f, 0, 0, 1, 1.75f, -2.6f, +R_ARC_TO, 8.25f, 8.25f, 0, 0, 1, 2.61f, -1.75f, +R_ARC_TO, 7.97f, 7.97f, 0, 0, 1, 3.18f, -0.64f, +R_CUBIC_TO, 1.13f, 0, 2.18f, 0.21f, 3.17f, 0.64f, +R_ARC_TO, 8.29f, 8.29f, 0, 0, 1, 2.6f, 1.75f, +R_ARC_TO, 8.26f, 8.26f, 0, 0, 1, 1.75f, 2.6f, +R_CUBIC_TO, 0.43f, 0.99f, 0.64f, 2.05f, 0.64f, 3.17f, +R_ARC_TO, 7.96f, 7.96f, 0, 0, 1, -0.64f, 3.17f, +R_ARC_TO, 8.25f, 8.25f, 0, 0, 1, -1.75f, 2.61f, +R_ARC_TO, 8.26f, 8.26f, 0, 0, 1, -2.6f, 1.75f, +R_ARC_TO, 7.93f, 7.93f, 0, 0, 1, -3.17f, 0.64f, +CLOSE, +MOVE_TO, 10, 16.44f, +R_CUBIC_TO, 0.71f, 0, 1.38f, -0.11f, 2.03f, -0.33f, +R_ARC_TO, 6.9f, 6.9f, 0, 0, 0, 1.85f, -0.98f, +R_ARC_TO, 7.87f, 7.87f, 0, 0, 0, -1.86f, -0.83f, +ARC_TO, 7.25f, 7.25f, 0, 0, 0, 10, 14.03f, +R_CUBIC_TO, -0.7f, 0, -1.37f, 0.09f, -2.02f, 0.27f, +R_ARC_TO, 6.69f, 6.69f, 0, 0, 0, -1.85f, 0.84f, +R_CUBIC_TO, 0.58f, 0.43f, 1.2f, 0.75f, 1.84f, 0.98f, +R_CUBIC_TO, 0.64f, 0.22f, 1.32f, 0.33f, 2.03f, 0.33f, +CLOSE, +R_MOVE_TO, 0, -6.47f, +R_CUBIC_TO, 0.4f, 0, 0.75f, -0.14f, 1.03f, -0.43f, +R_CUBIC_TO, 0.28f, -0.28f, 0.43f, -0.63f, 0.43f, -1.03f, +R_CUBIC_TO, 0, -0.41f, -0.14f, -0.75f, -0.43f, -1.03f, +ARC_TO, 1.4f, 1.4f, 0, 0, 0, 10, 7.04f, +R_CUBIC_TO, -0.4f, 0, -0.75f, 0.14f, -1.03f, 0.43f, +R_ARC_TO, 1.41f, 1.41f, 0, 0, 0, -0.43f, 1.03f, +R_CUBIC_TO, 0, 0.4f, 0.14f, 0.75f, 0.43f, 1.03f, +R_CUBIC_TO, 0.28f, 0.28f, 0.63f, 0.43f, 1.03f, 0.43f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 4, 11.11f, +R_ARC_TO, 6.71f, 6.71f, 0, 0, 1, 1.91f, -0.91f, +R_ARC_TO, 7.63f, 7.63f, 0, 0, 1, 2.1f, -0.29f, +R_CUBIC_TO, 0.73f, 0, 1.43f, 0.1f, 2.11f, 0.31f, +R_ARC_TO, 6.84f, 6.84f, 0, 0, 1, 1.89f, 0.9f, +R_CUBIC_TO, 0.37f, -0.46f, 0.64f, -0.95f, 0.82f, -1.47f, +R_CUBIC_TO, 0.18f, -0.52f, 0.26f, -1.07f, 0.26f, -1.64f, +R_CUBIC_TO, 0, -1.4f, -0.5f, -2.6f, -1.49f, -3.6f, +R_CUBIC_TO, -0.99f, -0.99f, -2.2f, -1.49f, -3.6f, -1.49f, +R_CUBIC_TO, -1.4f, 0, -2.6f, 0.5f, -3.59f, 1.49f, +CUBIC_TO, 3.41f, 5.4f, 2.91f, 6.6f, 2.91f, 8, +R_CUBIC_TO, 0, 0.57f, 0.09f, 1.11f, 0.26f, 1.63f, +R_ARC_TO, 4.7f, 4.7f, 0, 0, 0, 0.82f, 1.48f, +CLOSE, +MOVE_TO, 8, 9.28f, +R_ARC_TO, 2.4f, 2.4f, 0, 0, 1, -1.76f, -0.71f, +R_ARC_TO, 2.38f, 2.38f, 0, 0, 1, -0.72f, -1.75f, +R_CUBIC_TO, 0, -0.69f, 0.24f, -1.28f, 0.72f, -1.76f, +ARC_TO, 2.39f, 2.39f, 0, 0, 1, 8, 4.35f, +R_ARC_TO, 2.39f, 2.39f, 0, 0, 1, 1.76f, 0.72f, +R_CUBIC_TO, 0.48f, 0.48f, 0.72f, 1.07f, 0.72f, 1.76f, +R_CUBIC_TO, 0, 0.69f, -0.24f, 1.27f, -0.72f, 1.75f, +ARC_TO, 2.4f, 2.4f, 0, 0, 1, 8, 9.29f, +CLOSE, +R_MOVE_TO, 0, 5.43f, +R_ARC_TO, 6.52f, 6.52f, 0, 0, 1, -2.61f, -0.52f, +ARC_TO, 6.68f, 6.68f, 0, 0, 1, 3.25f, 12.75f, +R_ARC_TO, 6.68f, 6.68f, 0, 0, 1, -1.44f, -2.14f, +R_ARC_TO, 6.53f, 6.53f, 0, 0, 1, -0.52f, -2.61f, +R_CUBIC_TO, 0, -0.93f, 0.17f, -1.8f, 0.52f, -2.6f, +ARC_TO, 6.69f, 6.69f, 0, 0, 1, 3.25f, 3.25f, +R_ARC_TO, 6.68f, 6.68f, 0, 0, 1, 2.15f, -1.44f, +R_ARC_TO, 6.53f, 6.53f, 0, 0, 1, 2.61f, -0.52f, +R_CUBIC_TO, 0.93f, 0, 1.8f, 0.17f, 2.61f, 0.52f, +ARC_TO, 6.69f, 6.69f, 0, 0, 1, 12.75f, 3.25f, +R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, 1.45f, 2.14f, +R_CUBIC_TO, 0.35f, 0.81f, 0.52f, 1.68f, 0.52f, 2.61f, +R_CUBIC_TO, 0, 0.93f, -0.17f, 1.79f, -0.52f, 2.61f, +R_ARC_TO, 6.68f, 6.68f, 0, 0, 1, -1.44f, 2.14f, +R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -2.14f, 1.45f, +R_ARC_TO, 6.48f, 6.48f, 0, 0, 1, -2.61f, 0.52f, +CLOSE, +MOVE_TO, 8, 13.09f, +R_CUBIC_TO, 0.55f, 0, 1.07f, -0.08f, 1.56f, -0.25f, +R_ARC_TO, 5.72f, 5.72f, 0, 0, 0, 1.45f, -0.75f, +R_ARC_TO, 6.57f, 6.57f, 0, 0, 0, -1.46f, -0.63f, +ARC_TO, 5.64f, 5.64f, 0, 0, 0, 8, 11.26f, +R_CUBIC_TO, -0.56f, 0, -1.07f, 0.06f, -1.55f, 0.2f, +R_CUBIC_TO, -0.48f, 0.13f, -0.96f, 0.34f, -1.44f, 0.64f, +R_CUBIC_TO, 0.47f, 0.33f, 0.95f, 0.58f, 1.44f, 0.75f, +R_CUBIC_TO, 0.49f, 0.17f, 1.01f, 0.25f, 1.56f, 0.25f, +CLOSE, +R_MOVE_TO, 0, -5.14f, +R_CUBIC_TO, 0.31f, 0, 0.57f, -0.11f, 0.79f, -0.33f, +R_CUBIC_TO, 0.22f, -0.22f, 0.33f, -0.48f, 0.33f, -0.79f, +R_ARC_TO, 1.1f, 1.1f, 0, 0, 0, -0.33f, -0.8f, +ARC_TO, 1.08f, 1.08f, 0, 0, 0, 8, 5.68f, +R_CUBIC_TO, -0.31f, 0, -0.57f, 0.11f, -0.79f, 0.34f, +R_ARC_TO, 1.1f, 1.1f, 0, 0, 0, -0.33f, 0.8f, +R_CUBIC_TO, 0, 0.31f, 0.11f, 0.57f, 0.33f, 0.79f, +R_CUBIC_TO, 0.22f, 0.22f, 0.48f, 0.33f, 0.79f, 0.33f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/account_circle_off_chrome_refresh.icon b/components/vector_icons/account_circle_off_chrome_refresh.icon index c985f1d..1f81772 100644 --- a/components/vector_icons/account_circle_off_chrome_refresh.icon +++ b/components/vector_icons/account_circle_off_chrome_refresh.icon
@@ -72,4 +72,146 @@ R_CUBIC_TO, 0.64f, 0.14f, 1.26f, 0.33f, 1.87f, 0.57f, R_LINE_TO, 3.45f, 3.45f, ARC_TO, 10.15f, 10.15f, 0, 0, 1, 12, 22.2f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 11.06f, 8.77f, +CLOSE, +R_MOVE_TO, -2.33f, 2.5f, +CLOSE, +MOVE_TO, 10, 16.44f, +R_CUBIC_TO, 0.7f, 0, 1.38f, -0.11f, 2.04f, -0.34f, +R_ARC_TO, 6.72f, 6.72f, 0, 0, 0, 1.84f, -0.97f, +R_ARC_TO, 7.35f, 7.35f, 0, 0, 0, -1.86f, -0.82f, +ARC_TO, 7.4f, 7.4f, 0, 0, 0, 10, 14.03f, +R_CUBIC_TO, -0.69f, 0, -1.36f, 0.09f, -2.02f, 0.27f, +R_CUBIC_TO, -0.66f, 0.18f, -1.28f, 0.46f, -1.85f, 0.83f, +R_CUBIC_TO, 0.57f, 0.43f, 1.18f, 0.75f, 1.84f, 0.97f, +R_ARC_TO, 6.24f, 6.24f, 0, 0, 0, 2.03f, 0.34f, +CLOSE, +R_MOVE_TO, 2.5f, -6.22f, +R_LINE_TO, -1.17f, -1.18f, +R_ARC_TO, 0.84f, 0.84f, 0, 0, 0, 0.11f, -0.26f, +R_CUBIC_TO, 0.02f, -0.09f, 0.03f, -0.18f, 0.03f, -0.27f, +R_CUBIC_TO, 0, -0.41f, -0.14f, -0.75f, -0.43f, -1.04f, +R_ARC_TO, 1.41f, 1.41f, 0, 0, 0, -1.31f, -0.4f, +R_ARC_TO, 0.72f, 0.72f, 0, 0, 0, -0.26f, 0.11f, +LINE_TO, 8.29f, 6.01f, +R_CUBIC_TO, 0.26f, -0.17f, 0.53f, -0.3f, 0.82f, -0.4f, +R_CUBIC_TO, 0.29f, -0.09f, 0.59f, -0.14f, 0.89f, -0.14f, +R_CUBIC_TO, 0.84f, 0, 1.56f, 0.3f, 2.15f, 0.89f, +R_CUBIC_TO, 0.59f, 0.59f, 0.89f, 1.31f, 0.89f, 2.15f, +R_ARC_TO, 3.02f, 3.02f, 0, 0, 1, -0.54f, 1.71f, +CLOSE, +R_MOVE_TO, 4.29f, 4.29f, +R_LINE_TO, -1.26f, -1.26f, +R_ARC_TO, 6.37f, 6.37f, 0, 0, 0, 0.68f, -1.56f, +ARC_TO, 6.16f, 6.16f, 0, 0, 0, 16.44f, 10, +R_CUBIC_TO, 0, -1.78f, -0.63f, -3.3f, -1.88f, -4.56f, +CUBIC_TO, 13.31f, 4.19f, 11.79f, 3.56f, 10, 3.56f, +R_ARC_TO, 6.16f, 6.16f, 0, 0, 0, -1.69f, 0.23f, +R_ARC_TO, 6.51f, 6.51f, 0, 0, 0, -1.56f, 0.67f, +LINE_TO, 5.48f, 3.21f, +ARC_TO, 8.01f, 8.01f, 0, 0, 1, 10, 1.83f, +R_ARC_TO, 7.93f, 7.93f, 0, 0, 1, 3.18f, 0.64f, +R_ARC_TO, 8.29f, 8.29f, 0, 0, 1, 2.6f, 1.75f, +R_ARC_TO, 8.29f, 8.29f, 0, 0, 1, 1.75f, 2.6f, +R_ARC_TO, 7.93f, 7.93f, 0, 0, 1, 0.64f, 3.18f, +R_ARC_TO, 8.01f, 8.01f, 0, 0, 1, -1.37f, 4.52f, +CLOSE, +MOVE_TO, 10, 18.17f, +R_ARC_TO, 7.93f, 7.93f, 0, 0, 1, -3.17f, -0.64f, +R_ARC_TO, 8.23f, 8.23f, 0, 0, 1, -2.6f, -1.75f, +R_ARC_TO, 8.23f, 8.23f, 0, 0, 1, -1.75f, -2.6f, +ARC_TO, 7.93f, 7.93f, 0, 0, 1, 1.83f, 10, +R_CUBIC_TO, 0, -0.82f, 0.12f, -1.62f, 0.36f, -2.39f, +ARC_TO, 8.48f, 8.48f, 0, 0, 1, 3.25f, 5.42f, +LINE_TO, 1.85f, 4, +LINE_TO, 2.96f, 2.89f, +R_LINE_TO, 14.23f, 14.23f, +R_LINE_TO, -1.11f, 1.11f, +LINE_TO, 4.49f, 6.66f, +R_ARC_TO, 6.37f, 6.37f, 0, 0, 0, -0.7f, 1.6f, +ARC_TO, 6.42f, 6.42f, 0, 0, 0, 3.56f, 10, +R_CUBIC_TO, 0, 0.73f, 0.12f, 1.44f, 0.35f, 2.12f, +R_CUBIC_TO, 0.23f, 0.68f, 0.58f, 1.31f, 1.06f, 1.87f, +R_ARC_TO, 8.37f, 8.37f, 0, 0, 1, 2.39f, -1.16f, +R_ARC_TO, 9.27f, 9.27f, 0, 0, 1, 2.64f, -0.37f, +R_CUBIC_TO, 0.53f, 0, 1.05f, 0.04f, 1.56f, 0.14f, +R_CUBIC_TO, 0.51f, 0.09f, 1.01f, 0.23f, 1.5f, 0.4f, +R_LINE_TO, 2.75f, 2.75f, +R_ARC_TO, 8.05f, 8.05f, 0, 0, 1, -2.65f, 1.79f, +R_CUBIC_TO, -1, 0.42f, -2.05f, 0.63f, -3.15f, 0.63f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 8.95f, 6.92f, +CLOSE, +MOVE_TO, 6.97f, 9.03f, +CLOSE, +MOVE_TO, 8, 13.09f, +R_CUBIC_TO, 0.54f, 0, 1.06f, -0.09f, 1.57f, -0.25f, +R_ARC_TO, 5.39f, 5.39f, 0, 0, 0, 1.43f, -0.74f, +ARC_TO, 5.86f, 5.86f, 0, 0, 0, 8, 11.26f, +R_ARC_TO, 6.01f, 6.01f, 0, 0, 0, -1.56f, 0.2f, +R_CUBIC_TO, -0.51f, 0.14f, -0.99f, 0.35f, -1.44f, 0.63f, +R_CUBIC_TO, 0.45f, 0.32f, 0.92f, 0.57f, 1.43f, 0.74f, +R_ARC_TO, 4.95f, 4.95f, 0, 0, 0, 1.57f, 0.25f, +CLOSE, +R_MOVE_TO, 2.11f, -4.98f, +LINE_TO, 9.08f, 7.06f, +R_ARC_TO, 0.29f, 0.29f, 0, 0, 0, 0.04f, -0.12f, +R_CUBIC_TO, 0, -0.04f, 0, -0.08f, 0, -0.12f, +R_CUBIC_TO, 0, -0.32f, -0.11f, -0.59f, -0.33f, -0.8f, +R_ARC_TO, 1.09f, 1.09f, 0, 0, 0, -0.93f, -0.32f, +R_ARC_TO, 0.31f, 0.31f, 0, 0, 0, -0.12f, 0.05f, +LINE_TO, 6.72f, 4.7f, +R_CUBIC_TO, 0.2f, -0.12f, 0.41f, -0.21f, 0.63f, -0.27f, +ARC_TO, 2.53f, 2.53f, 0, 0, 1, 8, 4.34f, +R_CUBIC_TO, 0.69f, 0, 1.27f, 0.24f, 1.75f, 0.72f, +R_CUBIC_TO, 0.48f, 0.48f, 0.72f, 1.06f, 0.72f, 1.75f, +R_CUBIC_TO, 0, 0.22f, -0.03f, 0.43f, -0.09f, 0.66f, +R_ARC_TO, 2.68f, 2.68f, 0, 0, 1, -0.27f, 0.63f, +CLOSE, +R_MOVE_TO, 3.53f, 3.53f, +R_LINE_TO, -1.21f, -1.21f, +R_CUBIC_TO, 0.21f, -0.36f, 0.38f, -0.75f, 0.48f, -1.16f, +R_CUBIC_TO, 0.11f, -0.41f, 0.17f, -0.83f, 0.17f, -1.26f, +R_CUBIC_TO, 0, -1.41f, -0.5f, -2.6f, -1.49f, -3.6f, +CUBIC_TO, 10.61f, 3.41f, 9.41f, 2.91f, 8, 2.91f, +R_CUBIC_TO, -0.43f, 0, -0.85f, 0.06f, -1.26f, 0.17f, +R_CUBIC_TO, -0.41f, 0.11f, -0.8f, 0.27f, -1.16f, 0.47f, +LINE_TO, 4.37f, 2.36f, +R_ARC_TO, 6.56f, 6.56f, 0, 0, 1, 1.74f, -0.8f, +ARC_TO, 6.53f, 6.53f, 0, 0, 1, 8, 1.28f, +R_ARC_TO, 6.48f, 6.48f, 0, 0, 1, 2.61f, 0.52f, +ARC_TO, 6.69f, 6.69f, 0, 0, 1, 12.75f, 3.25f, +R_ARC_TO, 6.69f, 6.69f, 0, 0, 1, 1.45f, 2.14f, +ARC_TO, 6.48f, 6.48f, 0, 0, 1, 14.72f, 8, +R_ARC_TO, 6.53f, 6.53f, 0, 0, 1, -0.27f, 1.89f, +R_ARC_TO, 6.56f, 6.56f, 0, 0, 1, -0.8f, 1.74f, +CLOSE, +MOVE_TO, 8, 14.72f, +R_ARC_TO, 6.52f, 6.52f, 0, 0, 1, -2.61f, -0.52f, +R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -2.14f, -1.44f, +R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -1.44f, -2.14f, +ARC_TO, 6.52f, 6.52f, 0, 0, 1, 1.28f, 8, +R_CUBIC_TO, 0, -0.68f, 0.1f, -1.33f, 0.31f, -1.97f, +R_CUBIC_TO, 0.21f, -0.64f, 0.5f, -1.24f, 0.88f, -1.8f, +LINE_TO, 1.45f, 3.2f, +R_LINE_TO, 0.95f, -0.94f, +R_LINE_TO, 11.5f, 11.5f, +R_LINE_TO, -0.95f, 0.95f, +R_LINE_TO, -9.32f, -9.3f, +R_ARC_TO, 5.17f, 5.17f, 0, 0, 0, -0.54f, 1.25f, +R_CUBIC_TO, -0.12f, 0.43f, -0.18f, 0.89f, -0.18f, 1.35f, +R_CUBIC_TO, 0, 0.57f, 0.09f, 1.12f, 0.27f, 1.65f, +R_CUBIC_TO, 0.18f, 0.53f, 0.45f, 1.02f, 0.81f, 1.46f, +R_ARC_TO, 6.58f, 6.58f, 0, 0, 1, 1.9f, -0.9f, +R_ARC_TO, 7.36f, 7.36f, 0, 0, 1, 2.1f, -0.3f, +R_CUBIC_TO, 0.44f, 0, 0.86f, 0.04f, 1.28f, 0.11f, +R_CUBIC_TO, 0.42f, 0.08f, 0.82f, 0.19f, 1.22f, 0.34f, +R_LINE_TO, 2.31f, 2.31f, +R_ARC_TO, 6.71f, 6.71f, 0, 0, 1, -2.19f, 1.51f, +R_CUBIC_TO, -0.83f, 0.35f, -1.7f, 0.53f, -2.62f, 0.53f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/ads_chrome_refresh.icon b/components/vector_icons/ads_chrome_refresh.icon index eea9da7c..8261fea 100644 --- a/components/vector_icons/ads_chrome_refresh.icon +++ b/components/vector_icons/ads_chrome_refresh.icon
@@ -2,22 +2,62 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 16, -MOVE_TO, 3.65f, 13.73f, -R_CUBIC_TO, -0.38f, 0, -0.71f, -0.14f, -0.98f, -0.41f, -R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.97f, -V_LINE_TO, 3.65f, -R_CUBIC_TO, 0, -0.37f, 0.13f, -0.7f, 0.4f, -0.97f, -R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.41f, 0.98f, -0.41f, -R_H_LINE_TO, 8.7f, -R_CUBIC_TO, 0.38f, 0, 0.71f, 0.14f, 0.98f, 0.41f, -R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.6f, 0.4f, 0.97f, -R_V_LINE_TO, 8.7f, -R_CUBIC_TO, 0, 0.38f, -0.13f, 0.7f, -0.4f, 0.97f, -R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.41f, -0.98f, 0.41f, +CANVAS_DIMENSIONS, 24, +MOVE_TO, 5.07f, 21.2f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 5.07f, +R_CUBIC_TO, 0, -0.63f, 0.22f, -1.16f, 0.66f, -1.61f, +R_CUBIC_TO, 0.45f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f, +H_LINE_TO, 18.93f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +V_LINE_TO, 18.93f, +R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, +R_CUBIC_TO, -0.44f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, CLOSE, -R_MOVE_TO, -0.05f, -1.34f, +MOVE_TO, 5, 19, +R_H_LINE_TO, 14, +V_LINE_TO, 7.97f, +H_LINE_TO, 5, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.56f, 17.17f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.22f, +V_LINE_TO, 4.56f, +R_CUBIC_TO, 0, -0.47f, 0.17f, -0.87f, 0.5f, -1.22f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, 1.22f, -0.51f, +H_LINE_TO, 15.44f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.5f, 0.75f, 0.5f, 1.22f, +V_LINE_TO, 15.44f, +R_CUBIC_TO, 0, 0.47f, -0.17f, 0.88f, -0.5f, 1.22f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, -1.22f, 0.51f, +CLOSE, +MOVE_TO, 4.5f, 15.5f, +R_H_LINE_TO, 11, +V_LINE_TO, 6.97f, +R_H_LINE_TO, -11, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3.72f, 13.92f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.48f, +R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, -0.48f, -1.16f, +R_V_LINE_TO, -8.57f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.83f, 0.48f, -1.16f, +R_CUBIC_TO, 0.32f, -0.32f, 0.7f, -0.48f, 1.16f, -0.48f, +R_H_LINE_TO, 8.57f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +R_V_LINE_TO, 8.57f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.16f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f, +CLOSE, +R_MOVE_TO, -0.11f, -1.52f, R_H_LINE_TO, 8.8f, -V_LINE_TO, 5.57f, +V_LINE_TO, 5.54f, H_LINE_TO, 3.6f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/ads_off_chrome_refresh.icon b/components/vector_icons/ads_off_chrome_refresh.icon index 9d9f45f..3b75bfc9 100644 --- a/components/vector_icons/ads_off_chrome_refresh.icon +++ b/components/vector_icons/ads_off_chrome_refresh.icon
@@ -2,28 +2,82 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 19.87f, 22.73f, +R_LINE_TO, -1.53f, -1.52f, +H_LINE_TO, 5.07f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -1.6f, -0.67f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -0.67f, -1.6f, +V_LINE_TO, 5.75f, +R_CUBIC_TO, 0, -0.02f, 0, -0.03f, 0, -0.05f, +R_V_LINE_TO, -0.04f, +LINE_TO, 1.27f, 4.11f, +R_LINE_TO, 1.46f, -1.46f, +R_LINE_TO, 18.62f, 18.62f, +CLOSE, +R_MOVE_TO, -14.8f, -3.8f, +R_H_LINE_TO, 11, +LINE_TO, 5.07f, 7.93f, +CLOSE, +R_MOVE_TO, 16.13f, -0.65f, +LINE_TO, 19, 16.08f, +V_LINE_TO, 7.97f, +R_H_LINE_TO, -8.11f, +LINE_TO, 5.72f, 2.8f, +R_H_LINE_TO, 13.21f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.67f, +R_CUBIC_TO, 0.45f, 0.45f, 0.67f, 0.98f, 0.67f, 1.61f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.1f, 18.23f, +R_LINE_TO, -1.09f, -1.06f, +H_LINE_TO, 4.56f, +R_CUBIC_TO, -0.47f, 0, -0.88f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 5.02f, +R_CUBIC_TO, 0, -0.01f, 0, -0.03f, 0, -0.04f, +LINE_TO, 1.77f, 3.93f, +R_LINE_TO, 1.11f, -1.12f, +LINE_TO, 17.19f, 17.14f, +CLOSE, +MOVE_TO, 4.56f, 15.44f, +R_H_LINE_TO, 8.73f, +LINE_TO, 4.56f, 6.72f, +CLOSE, +R_MOVE_TO, 12.61f, -0.48f, +LINE_TO, 15.5f, 13.3f, +V_LINE_TO, 6.97f, +H_LINE_TO, 9.18f, +R_LINE_TO, -4.14f, -4.14f, +H_LINE_TO, 15.44f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +CLOSE + CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 12.88f, 14.58f, -R_LINE_TO, -0.87f, -0.85f, -H_LINE_TO, 3.65f, -R_CUBIC_TO, -0.38f, 0, -0.71f, -0.13f, -0.98f, -0.41f, -R_ARC_TO, 1.32f, 1.32f, 0, 0, 1, -0.41f, -0.98f, -V_LINE_TO, 4.02f, -R_CUBIC_TO, 0, -0.01f, 0, -0.02f, 0, -0.03f, -R_LINE_TO, -0.85f, -0.85f, -R_LINE_TO, 0.89f, -0.89f, -R_LINE_TO, 11.45f, 11.47f, +R_MOVE_TO, 12.97f, 14.7f, +R_LINE_TO, -0.8f, -0.78f, +R_H_LINE_TO, -8.45f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.15f, -0.48f, +R_CUBIC_TO, -0.32f, -0.32f, -0.48f, -0.71f, -0.48f, -1.16f, +V_LINE_TO, 3.98f, +R_CUBIC_TO, 0, -0.02f, 0, -0.05f, 0.01f, -0.08f, +R_CUBIC_TO, 0, -0.03f, 0, -0.05f, 0, -0.06f, +R_LINE_TO, -0.79f, -0.78f, +R_LINE_TO, 0.95f, -0.95f, +LINE_TO, 13.9f, 13.77f, CLOSE, -R_MOVE_TO, -9.23f, -2.23f, -R_H_LINE_TO, 6.98f, -R_LINE_TO, -6.98f, -6.98f, +R_MOVE_TO, -9.25f, -2.41f, +R_H_LINE_TO, 6.82f, +LINE_TO, 3.72f, 5.47f, CLOSE, -R_MOVE_TO, 10.09f, -0.38f, -R_LINE_TO, -1.34f, -1.33f, -V_LINE_TO, 5.57f, -H_LINE_TO, 7.34f, -LINE_TO, 4.03f, 2.27f, -R_H_LINE_TO, 8.32f, -R_CUBIC_TO, 0.38f, 0, 0.71f, 0.13f, 0.98f, 0.41f, -R_CUBIC_TO, 0.27f, 0.27f, 0.41f, 0.59f, 0.41f, 0.98f, +R_MOVE_TO, 10.21f, -0.21f, +R_LINE_TO, -1.52f, -1.52f, +V_LINE_TO, 5.54f, +H_LINE_TO, 7.4f, +LINE_TO, 3.93f, 2.08f, +R_H_LINE_TO, 8.36f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/bluetooth_chrome_refresh.icon b/components/vector_icons/bluetooth_chrome_refresh.icon index 31640d8..e5447969 100644 --- a/components/vector_icons/bluetooth_chrome_refresh.icon +++ b/components/vector_icons/bluetooth_chrome_refresh.icon
@@ -25,4 +25,54 @@ R_MOVE_TO, 0, 8.55f, R_LINE_TO, 1.79f, -1.74f, R_LINE_TO, -1.79f, -1.79f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 8.96f, 18.06f, +R_V_LINE_TO, -5.84f, +R_LINE_TO, -3.52f, 3.53f, +R_LINE_TO, -1.12f, -1.12f, +LINE_TO, 8.95f, 10, +LINE_TO, 4.32f, 5.38f, +R_LINE_TO, 1.12f, -1.12f, +R_LINE_TO, 3.52f, 3.53f, +R_V_LINE_TO, -5.84f, +R_H_LINE_TO, 1.16f, +LINE_TO, 14.68f, 6.5f, +R_LINE_TO, -3.5f, 3.5f, +R_LINE_TO, 3.5f, 3.5f, +R_LINE_TO, -4.55f, 4.56f, +CLOSE, +R_MOVE_TO, 1.58f, -9.64f, +R_LINE_TO, 1.91f, -1.91f, +R_LINE_TO, -1.91f, -1.91f, +CLOSE, +R_MOVE_TO, 0, 7, +R_LINE_TO, 1.91f, -1.91f, +R_LINE_TO, -1.91f, -1.91f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 7.13f, 14.5f, +V_LINE_TO, 9.87f, +R_LINE_TO, -2.77f, 2.78f, +R_LINE_TO, -0.96f, -0.95f, +LINE_TO, 7.1f, 8, +LINE_TO, 3.4f, 4.3f, +R_LINE_TO, 0.96f, -0.95f, +R_LINE_TO, 2.77f, 2.78f, +V_LINE_TO, 1.5f, +R_H_LINE_TO, 0.98f, +LINE_TO, 11.81f, 5.2f, +LINE_TO, 9, 8, +R_LINE_TO, 2.8f, 2.8f, +R_LINE_TO, -3.7f, 3.7f, +CLOSE, +R_MOVE_TO, 1.35f, -7.87f, +R_LINE_TO, 1.42f, -1.43f, +R_LINE_TO, -1.42f, -1.43f, +CLOSE, +R_MOVE_TO, 0, 5.6f, +R_LINE_TO, 1.42f, -1.43f, +R_LINE_TO, -1.42f, -1.43f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/bluetooth_off_chrome_refresh.icon b/components/vector_icons/bluetooth_off_chrome_refresh.icon index 3a9dd92..8c24e8c2 100644 --- a/components/vector_icons/bluetooth_off_chrome_refresh.icon +++ b/components/vector_icons/bluetooth_off_chrome_refresh.icon
@@ -28,4 +28,60 @@ R_V_LINE_TO, -6.21f, H_LINE_TO, 12, R_LINE_TO, 5.77f, 5.77f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.06f, 18.18f, +R_LINE_TO, -3.03f, -3.03f, +R_LINE_TO, -2.91f, 2.91f, +H_LINE_TO, 8.96f, +R_V_LINE_TO, -5.84f, +R_LINE_TO, -3.52f, 3.53f, +R_LINE_TO, -1.12f, -1.12f, +R_LINE_TO, 4.09f, -4.09f, +R_LINE_TO, -6.53f, -6.55f, +R_LINE_TO, 1.06f, -1.06f, +R_LINE_TO, 14.17f, 14.2f, +CLOSE, +R_MOVE_TO, -5.52f, -2.77f, +R_LINE_TO, 1.38f, -1.37f, +R_LINE_TO, -1.37f, -1.38f, +CLOSE, +R_MOVE_TO, 1.12f, -5.89f, +R_LINE_TO, -1.18f, -1.18f, +R_LINE_TO, 1.97f, -1.84f, +R_LINE_TO, -1.91f, -1.91f, +R_V_LINE_TO, 3.82f, +LINE_TO, 8.96f, 6.83f, +V_LINE_TO, 1.95f, +R_H_LINE_TO, 1.16f, +LINE_TO, 14.68f, 6.5f, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 12.91f, 14.61f, +R_LINE_TO, -2.46f, -2.46f, +R_LINE_TO, -2.35f, 2.36f, +R_H_LINE_TO, -0.98f, +V_LINE_TO, 9.87f, +R_LINE_TO, -2.77f, 2.78f, +R_LINE_TO, -0.96f, -0.95f, +R_LINE_TO, 3.31f, -3.3f, +LINE_TO, 1.52f, 3.18f, +R_LINE_TO, 0.85f, -0.85f, +R_LINE_TO, 11.4f, 11.42f, +CLOSE, +MOVE_TO, 8.48f, 12.23f, +R_LINE_TO, 1.03f, -1.03f, +R_LINE_TO, -1.03f, -1.03f, +CLOSE, +R_MOVE_TO, 0.88f, -4.58f, +LINE_TO, 8.35f, 6.65f, +R_LINE_TO, 1.54f, -1.45f, +R_LINE_TO, -1.42f, -1.43f, +R_V_LINE_TO, 2.99f, +LINE_TO, 7.13f, 5.41f, +V_LINE_TO, 1.5f, +R_H_LINE_TO, 0.98f, +LINE_TO, 11.81f, 5.2f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/bluetooth_scanning_chrome_refresh.icon b/components/vector_icons/bluetooth_scanning_chrome_refresh.icon index 8e11f458..68730ec 100644 --- a/components/vector_icons/bluetooth_scanning_chrome_refresh.icon +++ b/components/vector_icons/bluetooth_scanning_chrome_refresh.icon
@@ -43,4 +43,89 @@ R_CUBIC_TO, 0.27f, 0.9f, 0.4f, 1.81f, 0.4f, 2.76f, R_CUBIC_TO, 0, 0.95f, -0.13f, 1.87f, -0.4f, 2.76f, R_CUBIC_TO, -0.26f, 0.89f, -0.65f, 1.74f, -1.15f, 2.54f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 7.44f, 18.06f, +R_LINE_TO, 0, -5.84f, +R_LINE_TO, -3.53f, 3.53f, +R_LINE_TO, -1.12f, -1.12f, +LINE_TO, 7.43f, 10, +LINE_TO, 2.8f, 5.38f, +R_LINE_TO, 1.12f, -1.12f, +R_LINE_TO, 3.53f, 3.53f, +R_LINE_TO, 0, -5.84f, +R_H_LINE_TO, 1.16f, +LINE_TO, 13.16f, 6.5f, +LINE_TO, 9.66f, 10, +R_LINE_TO, 3.5f, 3.5f, +R_LINE_TO, -4.55f, 4.56f, +CLOSE, +MOVE_TO, 9.02f, 8.41f, +R_LINE_TO, 1.91f, -1.91f, +LINE_TO, 9.02f, 4.59f, +CLOSE, +R_MOVE_TO, 0, 7, +R_LINE_TO, 1.91f, -1.91f, +R_LINE_TO, -1.91f, -1.91f, +CLOSE, +R_MOVE_TO, 4.72f, -3.65f, +LINE_TO, 11.98f, 10, +R_LINE_TO, 1.76f, -1.76f, +R_CUBIC_TO, 0.12f, 0.29f, 0.2f, 0.58f, 0.25f, 0.87f, +R_ARC_TO, 5.14f, 5.14f, 0, 0, 1, 0, 1.78f, +R_CUBIC_TO, -0.05f, 0.29f, -0.13f, 0.58f, -0.25f, 0.87f, +CLOSE, +R_MOVE_TO, 2.25f, 2.26f, +R_LINE_TO, -1.17f, -1.18f, +R_CUBIC_TO, 0.24f, -0.45f, 0.41f, -0.91f, 0.51f, -1.39f, +R_ARC_TO, 6.82f, 6.82f, 0, 0, 0, 0, -2.91f, +R_ARC_TO, 5.37f, 5.37f, 0, 0, 0, -0.51f, -1.39f, +LINE_TO, 16, 5.97f, +R_CUBIC_TO, 0.37f, 0.6f, 0.64f, 1.24f, 0.81f, 1.92f, +R_CUBIC_TO, 0.18f, 0.68f, 0.26f, 1.37f, 0.26f, 2.09f, +R_CUBIC_TO, 0, 0.72f, -0.09f, 1.42f, -0.26f, 2.1f, +R_ARC_TO, 7.13f, 7.13f, 0, 0, 1, -0.82f, 1.93f, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 5.89f, 14.5f, +R_LINE_TO, 0.01f, -4.63f, +R_LINE_TO, -2.78f, 2.78f, +R_LINE_TO, -0.95f, -0.95f, +LINE_TO, 5.86f, 8, +R_LINE_TO, -3.7f, -3.7f, +R_LINE_TO, 0.95f, -0.95f, +R_LINE_TO, 2.78f, 2.78f, +R_LINE_TO, -0.01f, -4.63f, +R_H_LINE_TO, 0.98f, +LINE_TO, 10.57f, 5.2f, +LINE_TO, 7.77f, 8, +R_LINE_TO, 2.8f, 2.8f, +R_LINE_TO, -3.7f, 3.7f, +CLOSE, +R_MOVE_TO, 1.35f, -7.87f, +R_LINE_TO, 1.42f, -1.43f, +R_LINE_TO, -1.42f, -1.43f, +CLOSE, +R_MOVE_TO, 0, 5.6f, +LINE_TO, 8.66f, 10.8f, +LINE_TO, 7.24f, 9.37f, +CLOSE, +R_MOVE_TO, 3.81f, -2.75f, +LINE_TO, 9.56f, 8, +R_LINE_TO, 1.48f, -1.48f, +R_CUBIC_TO, 0.1f, 0.25f, 0.18f, 0.49f, 0.22f, 0.73f, +R_ARC_TO, 4.29f, 4.29f, 0, 0, 1, 0, 1.5f, +R_ARC_TO, 3.09f, 3.09f, 0, 0, 1, -0.21f, 0.73f, +CLOSE, +R_MOVE_TO, 1.79f, 1.8f, +R_LINE_TO, -0.98f, -1, +R_CUBIC_TO, 0.19f, -0.36f, 0.32f, -0.73f, 0.41f, -1.12f, +R_ARC_TO, 5.57f, 5.57f, 0, 0, 0, 0, -2.34f, +R_ARC_TO, 4.64f, 4.64f, 0, 0, 0, -0.41f, -1.12f, +R_LINE_TO, 1, -1, +R_CUBIC_TO, 0.3f, 0.49f, 0.52f, 1.01f, 0.68f, 1.56f, +R_ARC_TO, 6.8f, 6.8f, 0, 0, 1, 0, 3.43f, +R_ARC_TO, 5.78f, 5.78f, 0, 0, 1, -0.69f, 1.59f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/business_chrome_refresh.icon b/components/vector_icons/business_chrome_refresh.icon index 2588f08..735cb35 100644 --- a/components/vector_icons/business_chrome_refresh.icon +++ b/components/vector_icons/business_chrome_refresh.icon
@@ -87,9 +87,6 @@ H_LINE_TO, 16, CLOSE - - - CANVAS_DIMENSIONS, 20, MOVE_TO, 2, 17, V_LINE_TO, 3, @@ -172,11 +169,7 @@ H_LINE_TO, 15, V_LINE_TO, 13.83f, H_LINE_TO, 13.5f, -CLOSE, -NEW_PATH - - - +CLOSE CANVAS_DIMENSIONS, 16, @@ -263,6 +256,4 @@ V_LINE_TO, 5.52f, H_LINE_TO, 13.5f, V_LINE_TO, 12.52f, -CLOSE, -NEW_PATH - +CLOSE
diff --git a/components/vector_icons/certificate_chrome_refresh.icon b/components/vector_icons/certificate_chrome_refresh.icon index 5b8e8d0..b0f4c65 100644 --- a/components/vector_icons/certificate_chrome_refresh.icon +++ b/components/vector_icons/certificate_chrome_refresh.icon
@@ -2,30 +2,92 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 4.07f, 20.2f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 6.07f, +R_CUBIC_TO, 0, -0.63f, 0.22f, -1.16f, 0.66f, -1.61f, +R_CUBIC_TO, 0.45f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f, +H_LINE_TO, 19.93f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +V_LINE_TO, 17.93f, +R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, +R_CUBIC_TO, -0.44f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, +CLOSE, +R_MOVE_TO, 0, -2.27f, +R_H_LINE_TO, 15.86f, +V_LINE_TO, 8.07f, +H_LINE_TO, 4.07f, +CLOSE, +R_MOVE_TO, 6.88f, -1.33f, +LINE_TO, 7.34f, 12.98f, +R_LINE_TO, 1.51f, -1.51f, +R_LINE_TO, 2.11f, 2.11f, +R_LINE_TO, 4.21f, -4.21f, +R_LINE_TO, 1.51f, 1.51f, +CLOSE, +MOVE_TO, 4.07f, 17.93f, +V_LINE_TO, 6.07f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 3.56f, 16.17f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.5f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.23f, +V_LINE_TO, 5.56f, +R_CUBIC_TO, 0, -0.48f, 0.17f, -0.89f, 0.5f, -1.22f, +R_CUBIC_TO, 0.34f, -0.34f, 0.75f, -0.5f, 1.22f, -0.5f, +H_LINE_TO, 16.44f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.5f, +R_CUBIC_TO, 0.34f, 0.34f, 0.5f, 0.75f, 0.5f, 1.23f, +R_V_LINE_TO, 8.88f, +R_CUBIC_TO, 0, 0.48f, -0.17f, 0.89f, -0.5f, 1.22f, +R_CUBIC_TO, -0.34f, 0.34f, -0.75f, 0.5f, -1.22f, 0.5f, +CLOSE, +R_MOVE_TO, 0, -1.73f, +H_LINE_TO, 16.44f, +V_LINE_TO, 7.06f, +H_LINE_TO, 3.56f, +CLOSE, +R_MOVE_TO, 5.57f, -0.73f, +LINE_TO, 6.24f, 10.82f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 1.78f, 1.77f, +R_LINE_TO, 3.53f, -3.55f, +R_LINE_TO, 1.11f, 1.11f, +CLOSE, +R_MOVE_TO, -5.57f, 0.73f, +V_LINE_TO, 5.56f, +CLOSE + CANVAS_DIMENSIONS, 16, -MOVE_TO, 14, 2.5f, -H_LINE_TO, 2, -R_CUBIC_TO, -0.55f, 0, -1, 0.45f, -1, 1, -R_V_LINE_TO, 9, -R_CUBIC_TO, 0, 0.55f, 0.45f, 1, 1, 1, -R_H_LINE_TO, 12, -R_CUBIC_TO, 0.55f, 0, 1, -0.45f, 1, -1, -R_V_LINE_TO, -9, -R_CUBIC_TO, 0, -0.55f, -0.45f, -1, -1, -1, +MOVE_TO, 2.91f, 13.12f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, -0.48f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +V_LINE_TO, 4.51f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.47f, -1.16f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, 1.16f, -0.47f, +R_H_LINE_TO, 10.17f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f, +R_V_LINE_TO, 6.98f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.47f, 1.16f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -1.16f, 0.47f, CLOSE, -MOVE_TO, 2.5f, 12, -V_LINE_TO, 5.5f, -R_H_LINE_TO, 11, -V_LINE_TO, 12, -R_H_LINE_TO, -11, +R_MOVE_TO, 0, -1.63f, +R_H_LINE_TO, 10.17f, +V_LINE_TO, 5.72f, +H_LINE_TO, 2.91f, CLOSE, -NEW_PATH, -MOVE_TO, 7.5f, 8.88f, -LINE_TO, 6.31f, 7.69f, -LINE_TO, 5.25f, 8.75f, -LINE_TO, 7.5f, 11, -LINE_TO, 11, 7.5f, -LINE_TO, 9.94f, 6.44f, -LINE_TO, 7.5f, 8.88f, +R_MOVE_TO, 4.39f, -0.48f, +LINE_TO, 4.93f, 8.64f, +R_LINE_TO, 0.95f, -0.94f, +R_LINE_TO, 1.43f, 1.43f, +R_LINE_TO, 2.82f, -2.84f, +R_LINE_TO, 0.95f, 0.95f, CLOSE, -NEW_PATH \ No newline at end of file +R_MOVE_TO, -4.39f, 0.48f, +V_LINE_TO, 4.51f, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/certificate_off_chrome_refresh.icon b/components/vector_icons/certificate_off_chrome_refresh.icon index 6c5a0a6e..8cd2517 100644 --- a/components/vector_icons/certificate_off_chrome_refresh.icon +++ b/components/vector_icons/certificate_off_chrome_refresh.icon
@@ -2,47 +2,136 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 20.55f, 23.43f, +R_LINE_TO, -3.23f, -3.22f, +H_LINE_TO, 4.07f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 6.07f, +R_CUBIC_TO, 0, -0.6f, 0.2f, -1.11f, 0.61f, -1.55f, +R_CUBIC_TO, 0.41f, -0.43f, 0.91f, -0.67f, 1.5f, -0.71f, +R_V_LINE_TO, 2.97f, +LINE_TO, 0.62f, 3.5f, +R_LINE_TO, 1.48f, -1.48f, +R_LINE_TO, 19.93f, 19.93f, +CLOSE, +MOVE_TO, 4.07f, 17.93f, +R_H_LINE_TO, 10.98f, +LINE_TO, 5.32f, 8.2f, +H_LINE_TO, 4.07f, +CLOSE, +R_MOVE_TO, 17.91f, 0.98f, +R_LINE_TO, -2.05f, -2.05f, +R_V_LINE_TO, -8.66f, +R_H_LINE_TO, -8.66f, +LINE_TO, 6.86f, 3.8f, +H_LINE_TO, 19.93f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +V_LINE_TO, 17.93f, +R_CUBIC_TO, 0, 0.18f, -0.01f, 0.35f, -0.05f, 0.52f, +R_CUBIC_TO, -0.03f, 0.17f, -0.09f, 0.33f, -0.18f, 0.47f, +CLOSE, +R_MOVE_TO, -6.67f, -6.67f, +R_LINE_TO, -1.51f, -1.51f, +R_LINE_TO, 1.36f, -1.36f, +R_LINE_TO, 1.51f, 1.51f, +CLOSE, +R_MOVE_TO, -1.48f, 1.49f, +R_LINE_TO, -2.87f, 2.87f, +R_LINE_TO, -3.61f, -3.62f, +R_LINE_TO, 1.51f, -1.51f, +R_LINE_TO, 2.11f, 2.11f, +R_LINE_TO, 1.36f, -1.36f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.81f, 18.94f, +R_LINE_TO, -2.79f, -2.77f, +H_LINE_TO, 3.56f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.16f, -1.23f, -0.5f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.23f, +V_LINE_TO, 5.56f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.85f, 0.48f, -1.17f, +R_CUBIC_TO, 0.32f, -0.33f, 0.71f, -0.51f, 1.18f, -0.54f, +R_H_LINE_TO, 0.23f, +V_LINE_TO, 5.84f, +LINE_TO, 1.14f, 3.27f, +R_LINE_TO, 1.11f, -1.09f, +R_LINE_TO, 15.65f, 15.64f, +CLOSE, +MOVE_TO, 3.56f, 14.44f, +R_H_LINE_TO, 8.73f, +LINE_TO, 5.02f, 7.17f, +H_LINE_TO, 3.56f, +CLOSE, +R_MOVE_TO, 14.23f, 1.05f, +R_LINE_TO, -1.35f, -1.35f, +V_LINE_TO, 7.17f, +H_LINE_TO, 9.47f, +LINE_TO, 6.14f, 3.83f, +H_LINE_TO, 16.44f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.16f, 1.23f, 0.5f, +R_CUBIC_TO, 0.34f, 0.34f, 0.5f, 0.75f, 0.5f, 1.23f, +R_V_LINE_TO, 8.88f, +R_CUBIC_TO, 0, 0.2f, -0.04f, 0.4f, -0.1f, 0.59f, +R_CUBIC_TO, -0.07f, 0.19f, -0.16f, 0.34f, -0.27f, 0.46f, +CLOSE, +R_MOVE_TO, -5.23f, -5.23f, +R_LINE_TO, -1.11f, -1.11f, +R_LINE_TO, 1.2f, -1.22f, +R_LINE_TO, 1.11f, 1.11f, +CLOSE, +R_MOVE_TO, -1.11f, 1.11f, +R_LINE_TO, -2.33f, 2.33f, +R_LINE_TO, -2.89f, -2.89f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 1.78f, 1.77f, +R_LINE_TO, 1.22f, -1.22f, +CLOSE + CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 13.45f, 15.15f, -R_LINE_TO, -2.23f, -2.21f, -H_LINE_TO, 2.85f, -R_CUBIC_TO, -0.39f, 0, -0.71f, -0.13f, -0.98f, -0.4f, -R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.98f, -V_LINE_TO, 4.45f, -R_CUBIC_TO, 0, -0.37f, 0.13f, -0.68f, 0.38f, -0.94f, -R_CUBIC_TO, 0.25f, -0.26f, 0.57f, -0.41f, 0.94f, -0.43f, +R_MOVE_TO, 13.54f, 15.27f, +R_LINE_TO, -2.17f, -2.14f, +R_H_LINE_TO, -8.46f, +R_CUBIC_TO, -0.46f, 0, -0.85f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +V_LINE_TO, 4.51f, +R_CUBIC_TO, 0, -0.41f, 0.13f, -0.76f, 0.4f, -1.06f, +R_CUBIC_TO, 0.27f, -0.3f, 0.61f, -0.48f, 1.01f, -0.54f, R_H_LINE_TO, 0.18f, -R_V_LINE_TO, 1.59f, -LINE_TO, 0.91f, 2.62f, -R_LINE_TO, 0.89f, -0.87f, -R_LINE_TO, 12.52f, 12.52f, +R_V_LINE_TO, 1.71f, +LINE_TO, 0.89f, 2.62f, +R_LINE_TO, 0.95f, -0.93f, +R_LINE_TO, 12.64f, 12.63f, CLOSE, -MOVE_TO, 2.85f, 11.55f, -R_H_LINE_TO, 6.98f, -LINE_TO, 4.02f, 5.73f, -H_LINE_TO, 2.85f, +MOVE_TO, 2.91f, 11.49f, +R_H_LINE_TO, 6.82f, +LINE_TO, 4.17f, 5.92f, +H_LINE_TO, 2.91f, CLOSE, -R_MOVE_TO, 11.39f, 0.84f, -R_LINE_TO, -1.08f, -1.08f, -V_LINE_TO, 5.73f, -H_LINE_TO, 7.58f, -LINE_TO, 4.91f, 3.07f, -R_H_LINE_TO, 8.25f, -R_CUBIC_TO, 0.39f, 0, 0.72f, 0.13f, 0.98f, 0.4f, -R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.6f, 0.4f, 0.98f, -R_V_LINE_TO, 7.1f, -R_CUBIC_TO, 0, 0.16f, -0.03f, 0.32f, -0.08f, 0.47f, -R_ARC_TO, 1.06f, 1.06f, 0, 0, 1, -0.22f, 0.37f, +R_MOVE_TO, 11.51f, 0.9f, +R_LINE_TO, -1.34f, -1.34f, +V_LINE_TO, 5.92f, +H_LINE_TO, 7.96f, +LINE_TO, 4.92f, 2.88f, +R_H_LINE_TO, 8.17f, +R_CUBIC_TO, 0.46f, 0, 0.85f, 0.16f, 1.16f, 0.47f, +R_CUBIC_TO, 0.32f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f, +R_V_LINE_TO, 6.98f, +R_CUBIC_TO, 0, 0.17f, -0.03f, 0.34f, -0.08f, 0.5f, +R_ARC_TO, 1.38f, 1.38f, 0, 0, 1, -0.21f, 0.4f, CLOSE, -R_MOVE_TO, -4.18f, -4.18f, -R_LINE_TO, -0.89f, -0.89f, -R_LINE_TO, 0.96f, -0.97f, -R_LINE_TO, 0.89f, 0.89f, +R_MOVE_TO, -4.25f, -4.25f, +LINE_TO, 9.23f, 7.19f, +R_LINE_TO, 0.9f, -0.91f, +R_LINE_TO, 0.95f, 0.95f, CLOSE, -R_MOVE_TO, -0.89f, 0.89f, -R_LINE_TO, -1.86f, 1.86f, -R_LINE_TO, -2.31f, -2.31f, -R_LINE_TO, 0.89f, -0.89f, -R_LINE_TO, 1.42f, 1.42f, -R_LINE_TO, 0.97f, -0.97f, +R_MOVE_TO, -0.95f, 0.94f, +R_LINE_TO, -1.93f, 1.93f, +R_LINE_TO, -2.37f, -2.37f, +R_LINE_TO, 0.95f, -0.94f, +R_LINE_TO, 1.43f, 1.43f, +R_LINE_TO, 0.98f, -0.98f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/code_chrome_refresh.icon b/components/vector_icons/code_chrome_refresh.icon new file mode 100644 index 0000000..85d8476a --- /dev/null +++ b/components/vector_icons/code_chrome_refresh.icon
@@ -0,0 +1,51 @@ +// 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. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 7.91f, 18.19f, +LINE_TO, 1.72f, 12, +LINE_TO, 7.91f, 5.8f, +R_LINE_TO, 1.62f, 1.62f, +R_LINE_TO, -4.6f, 4.6f, +R_LINE_TO, 4.57f, 4.57f, +CLOSE, +R_MOVE_TO, 8.18f, 0.01f, +R_LINE_TO, -1.62f, -1.62f, +R_LINE_TO, 4.6f, -4.6f, +R_LINE_TO, -4.57f, -4.57f, +LINE_TO, 16.09f, 5.81f, +LINE_TO, 22.29f, 12, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 6.93f, 15.16f, +LINE_TO, 1.76f, 10, +R_LINE_TO, 5.16f, -5.16f, +R_LINE_TO, 1.23f, 1.22f, +R_LINE_TO, -3.94f, 3.94f, +R_LINE_TO, 3.94f, 3.94f, +CLOSE, +R_MOVE_TO, 6.15f, 0, +R_LINE_TO, -1.23f, -1.22f, +R_LINE_TO, 3.94f, -3.94f, +R_LINE_TO, -3.94f, -3.94f, +R_LINE_TO, 1.23f, -1.23f, +LINE_TO, 18.24f, 10, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 5.46f, 12.3f, +LINE_TO, 1.15f, 8, +R_LINE_TO, 4.31f, -4.31f, +LINE_TO, 6.62f, 4.84f, +LINE_TO, 3.47f, 7.99f, +R_LINE_TO, 3.15f, 3.15f, +CLOSE, +R_MOVE_TO, 5.09f, 0.01f, +LINE_TO, 9.38f, 11.16f, +R_LINE_TO, 3.15f, -3.15f, +LINE_TO, 9.38f, 4.86f, +R_LINE_TO, 1.16f, -1.16f, +LINE_TO, 14.85f, 8, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/code_off.icon b/components/vector_icons/code_off.icon deleted file mode 100644 index bb303ec..0000000 --- a/components/vector_icons/code_off.icon +++ /dev/null
@@ -1,23 +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. - -CANVAS_DIMENSIONS, 16, -MOVE_TO, 12.95f, 14.67f, -LINE_TO, 4.82f, 6.54f, -LINE_TO, 3.37f, 8, -R_LINE_TO, 3.15f, 3.15f, -R_LINE_TO, -0.98f, 0.98f, -LINE_TO, 1.41f, 8, -R_LINE_TO, 2.44f, -2.43f, -R_LINE_TO, -2.52f, -2.52f, -R_LINE_TO, 0.89f, -0.89f, -LINE_TO, 13.84f, 13.78f, -CLOSE, -R_MOVE_TO, -0.74f, -4.29f, -R_LINE_TO, -0.98f, -0.98f, -R_LINE_TO, 1.39f, -1.39f, -R_LINE_TO, -3.15f, -3.15f, -R_LINE_TO, 0.98f, -0.98f, -LINE_TO, 14.59f, 8, -CLOSE \ No newline at end of file
diff --git a/components/vector_icons/code_off_chrome_refresh.icon b/components/vector_icons/code_off_chrome_refresh.icon new file mode 100644 index 0000000..fcd82bdf --- /dev/null +++ b/components/vector_icons/code_off_chrome_refresh.icon
@@ -0,0 +1,63 @@ +// 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. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 20, 22.88f, +LINE_TO, 7.04f, 9.91f, +LINE_TO, 4.93f, 12.02f, +R_LINE_TO, 4.57f, 4.57f, +LINE_TO, 7.91f, 18.19f, +LINE_TO, 1.72f, 12, +R_LINE_TO, 3.7f, -3.7f, +R_LINE_TO, -4.29f, -4.3f, +R_LINE_TO, 1.48f, -1.48f, +LINE_TO, 21.49f, 21.39f, +CLOSE, +R_MOVE_TO, -1.33f, -7.27f, +R_LINE_TO, -1.62f, -1.61f, +R_LINE_TO, 2.01f, -2.02f, +R_LINE_TO, -4.57f, -4.57f, +LINE_TO, 16.09f, 5.81f, +LINE_TO, 22.29f, 12, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 16.19f, 18.34f, +LINE_TO, 6.03f, 8.18f, +LINE_TO, 4.22f, 10, +R_LINE_TO, 3.94f, 3.94f, +R_LINE_TO, -1.23f, 1.23f, +LINE_TO, 1.76f, 10, +R_LINE_TO, 3.05f, -3.04f, +R_LINE_TO, -3.14f, -3.14f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 14.52f, 14.52f, +CLOSE, +R_MOVE_TO, -0.92f, -5.37f, +R_LINE_TO, -1.22f, -1.22f, +R_LINE_TO, 1.74f, -1.74f, +R_LINE_TO, -3.94f, -3.94f, +R_LINE_TO, 1.23f, -1.23f, +LINE_TO, 18.24f, 10, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 13.16f, 14.9f, +R_LINE_TO, -8.3f, -8.29f, +R_LINE_TO, -1.39f, 1.39f, +R_LINE_TO, 3.15f, 3.15f, +R_LINE_TO, -1.16f, 1.16f, +LINE_TO, 1.15f, 8, +R_LINE_TO, 2.56f, -2.55f, +R_LINE_TO, -2.6f, -2.61f, +R_LINE_TO, 0.94f, -0.94f, +R_LINE_TO, 12.06f, 12.06f, +CLOSE, +R_MOVE_TO, -0.72f, -4.49f, +R_LINE_TO, -1.15f, -1.15f, +R_LINE_TO, 1.25f, -1.25f, +LINE_TO, 9.38f, 4.86f, +R_LINE_TO, 1.16f, -1.16f, +LINE_TO, 14.85f, 8, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/cookie_chrome_refresh.icon b/components/vector_icons/cookie_chrome_refresh.icon index 79c4865..21027ee4 100644 --- a/components/vector_icons/cookie_chrome_refresh.icon +++ b/components/vector_icons/cookie_chrome_refresh.icon
@@ -2,6 +2,72 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 10.5f, 10, +R_CUBIC_TO, 0.42f, 0, 0.77f, -0.14f, 1.06f, -0.44f, +R_CUBIC_TO, 0.29f, -0.29f, 0.44f, -0.64f, 0.44f, -1.06f, +R_CUBIC_TO, 0, -0.42f, -0.14f, -0.77f, -0.44f, -1.06f, +ARC_TO, 1.44f, 1.44f, 0, 0, 0, 10.5f, 7, +R_CUBIC_TO, -0.42f, 0, -0.77f, 0.14f, -1.06f, 0.44f, +ARC_TO, 1.44f, 1.44f, 0, 0, 0, 9, 8.5f, +R_CUBIC_TO, 0, 0.42f, 0.14f, 0.77f, 0.44f, 1.06f, +R_CUBIC_TO, 0.29f, 0.29f, 0.64f, 0.44f, 1.06f, 0.44f, +CLOSE, +R_MOVE_TO, -2, 5, +R_CUBIC_TO, 0.42f, 0, 0.77f, -0.14f, 1.06f, -0.44f, +R_CUBIC_TO, 0.29f, -0.29f, 0.44f, -0.64f, 0.44f, -1.06f, +R_CUBIC_TO, 0, -0.42f, -0.14f, -0.77f, -0.44f, -1.06f, +ARC_TO, 1.44f, 1.44f, 0, 0, 0, 8.5f, 12, +R_CUBIC_TO, -0.42f, 0, -0.77f, 0.14f, -1.06f, 0.44f, +ARC_TO, 1.44f, 1.44f, 0, 0, 0, 7, 13.5f, +R_CUBIC_TO, 0, 0.42f, 0.14f, 0.77f, 0.44f, 1.06f, +R_CUBIC_TO, 0.29f, 0.29f, 0.64f, 0.44f, 1.06f, 0.44f, +CLOSE, +R_MOVE_TO, 6.5f, 1, +R_CUBIC_TO, 0.28f, 0, 0.52f, -0.1f, 0.71f, -0.29f, +ARC_TO, 0.96f, 0.96f, 0, 0, 0, 16, 15, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.29f, -0.71f, +ARC_TO, 0.96f, 0.96f, 0, 0, 0, 15, 14, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.71f, 0.29f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.29f, 0.71f, +R_CUBIC_TO, 0, 0.28f, 0.1f, 0.52f, 0.29f, 0.71f, +R_CUBIC_TO, 0.19f, 0.19f, 0.43f, 0.29f, 0.71f, 0.29f, +CLOSE, +R_MOVE_TO, -3, 6.14f, +R_ARC_TO, 9.89f, 9.89f, 0, 0, 1, -3.95f, -0.8f, +R_ARC_TO, 10.2f, 10.2f, 0, 0, 1, -3.22f, -2.17f, +R_ARC_TO, 10.2f, 10.2f, 0, 0, 1, -2.17f, -3.22f, +ARC_TO, 9.89f, 9.89f, 0, 0, 1, 1.86f, 12, +R_CUBIC_TO, 0, -1.48f, 0.32f, -2.89f, 0.95f, -4.25f, +R_ARC_TO, 10.3f, 10.3f, 0, 0, 1, 2.62f, -3.48f, +R_CUBIC_TO, 1.11f, -0.96f, 2.42f, -1.66f, 3.93f, -2.1f, +R_CUBIC_TO, 1.5f, -0.43f, 3.13f, -0.46f, 4.88f, -0.08f, +R_CUBIC_TO, -0.16f, 0.76f, -0.12f, 1.47f, 0.11f, 2.13f, +R_CUBIC_TO, 0.23f, 0.66f, 0.59f, 1.21f, 1.07f, 1.65f, +R_CUBIC_TO, 0.49f, 0.45f, 1.07f, 0.75f, 1.76f, 0.91f, +R_CUBIC_TO, 0.68f, 0.16f, 1.41f, 0.13f, 2.18f, -0.12f, +R_CUBIC_TO, -0.48f, 1.15f, -0.38f, 2.14f, 0.28f, 2.95f, +R_CUBIC_TO, 0.67f, 0.82f, 1.48f, 1.23f, 2.43f, 1.24f, +R_CUBIC_TO, 0.16f, 1.51f, 0.01f, 2.95f, -0.45f, 4.32f, +R_CUBIC_TO, -0.46f, 1.36f, -1.15f, 2.56f, -2.07f, 3.59f, +R_ARC_TO, 10.28f, 10.28f, 0, 0, 1, -3.32f, 2.45f, +R_CUBIC_TO, -1.3f, 0.61f, -2.71f, 0.91f, -4.23f, 0.91f, +CLOSE, +R_MOVE_TO, 0, -2.27f, +R_CUBIC_TO, 1.98f, 0, 3.75f, -0.68f, 5.29f, -2.03f, +R_CUBIC_TO, 1.54f, -1.35f, 2.39f, -3.09f, 2.56f, -5.19f, +R_CUBIC_TO, -0.81f, -0.37f, -1.45f, -0.87f, -1.92f, -1.5f, +R_ARC_TO, 5.38f, 5.38f, 0, 0, 1, -0.96f, -2.09f, +R_ARC_TO, 5.84f, 5.84f, 0, 0, 1, -3.28f, -1.65f, +R_ARC_TO, 5.97f, 5.97f, 0, 0, 1, -1.73f, -3.27f, +R_CUBIC_TO, -1.26f, -0.02f, -2.38f, 0.23f, -3.35f, 0.72f, +R_ARC_TO, 7.97f, 7.97f, 0, 0, 0, -2.45f, 1.91f, +R_ARC_TO, 8.47f, 8.47f, 0, 0, 0, -1.5f, 2.56f, +R_CUBIC_TO, -0.34f, 0.93f, -0.51f, 1.82f, -0.51f, 2.68f, +R_CUBIC_TO, 0, 2.18f, 0.77f, 4.04f, 2.3f, 5.57f, +R_CUBIC_TO, 1.53f, 1.53f, 3.39f, 2.3f, 5.57f, 2.3f, +CLOSE + CANVAS_DIMENSIONS, 20, MOVE_TO, 8.75f, 8.5f, R_CUBIC_TO, 0.35f, 0, 0.64f, -0.12f, 0.89f, -0.36f, @@ -65,43 +131,70 @@ ARC_TO, 6.23f, 6.23f, 0, 0, 0, 3.61f, 10, R_CUBIC_TO, 0, 1.77f, 0.63f, 3.28f, 1.87f, 4.52f, R_CUBIC_TO, 1.24f, 1.24f, 2.75f, 1.87f, 4.52f, 1.87f, -CLOSE, -R_MOVE_TO, -0.01f, -6.35f, CLOSE CANVAS_DIMENSIONS, 16, -MOVE_TO, 14.97f, 7.48f, -R_CUBIC_TO, -0.07f, 0, -0.15f, 0.02f, -0.22f, 0.02f, -R_CUBIC_TO, -1.24f, 0, -2.25f, -1.01f, -2.25f, -2.25f, -R_CUBIC_TO, 0, -0.1f, 0.02f, -0.19f, 0.03f, -0.28f, -R_CUBIC_TO, -0.09f, 0, -0.18f, 0.03f, -0.28f, 0.03f, -CUBIC_TO, 10.46f, 5, 9, 3.54f, 9, 1.75f, -R_CUBIC_TO, 0, -0.23f, 0.02f, -0.45f, 0.07f, -0.66f, -CUBIC_TO, 8.72f, 1.04f, 8.37f, 1, 8, 1, -CUBIC_TO, 4.13f, 1, 1, 4.13f, 1, 8, -R_CUBIC_TO, 0, 3.87f, 3.13f, 7, 7, 7, -R_CUBIC_TO, 3.87f, 0, 7, -3.13f, 7, -7, -R_CUBIC_TO, 0, -0.18f, -0.01f, -0.35f, -0.03f, -0.52f, +MOVE_TO, 7, 6.8f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, 0.71f, -0.29f, +ARC_TO, 0.96f, 0.96f, 0, 0, 0, 8, 5.8f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, -0.29f, -0.71f, +ARC_TO, 0.97f, 0.97f, 0, 0, 0, 7, 4.8f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, -0.71f, 0.29f, +ARC_TO, 0.97f, 0.97f, 0, 0, 0, 6, 5.8f, +R_CUBIC_TO, 0, 0.28f, 0.1f, 0.51f, 0.29f, 0.71f, +R_CUBIC_TO, 0.19f, 0.2f, 0.43f, 0.29f, 0.71f, 0.29f, CLOSE, -MOVE_TO, 8, 13.5f, -ARC_TO, 5.51f, 5.51f, 0, 0, 1, 2.5f, 8, -R_CUBIC_TO, 0, -3.03f, 2.23f, -5.26f, 5.06f, -5.48f, -R_ARC_TO, 4.76f, 4.76f, 0, 0, 0, 3.61f, 3.86f, -R_ARC_TO, 3.77f, 3.77f, 0, 0, 0, 2.27f, 2.39f, -R_ARC_TO, 5.5f, 5.5f, 0, 0, 1, -5.45f, 4.73f, -H_LINE_TO, 8, +MOVE_TO, 5.4f, 10, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, 0.71f, -0.29f, +ARC_TO, 0.95f, 0.95f, 0, 0, 0, 6.4f, 9, +R_ARC_TO, 0.95f, 0.95f, 0, 0, 0, -0.29f, -0.71f, +ARC_TO, 0.96f, 0.96f, 0, 0, 0, 5.4f, 8, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.71f, 0.29f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.29f, 0.71f, +R_CUBIC_TO, 0, 0.28f, 0.1f, 0.52f, 0.29f, 0.71f, +R_CUBIC_TO, 0.2f, 0.2f, 0.43f, 0.29f, 0.71f, 0.29f, CLOSE, -NEW_PATH, -MOVE_TO, 7, 7, -R_ARC_TO, 1, 1, 0, 1, 0, 0, -2, -R_ARC_TO, 1, 1, 0, 0, 0, 0, 2, +R_MOVE_TO, 4.6f, 0.6f, +R_ARC_TO, 0.6f, 0.6f, 0, 0, 0, 0.43f, -0.17f, +R_ARC_TO, 0.58f, 0.58f, 0, 0, 0, 0.18f, -0.43f, +R_ARC_TO, 0.6f, 0.6f, 0, 0, 0, -0.17f, -0.43f, +R_ARC_TO, 0.58f, 0.58f, 0, 0, 0, -0.43f, -0.18f, +R_ARC_TO, 0.6f, 0.6f, 0, 0, 0, -0.43f, 0.17f, +R_ARC_TO, 0.58f, 0.58f, 0, 0, 0, -0.18f, 0.43f, +R_CUBIC_TO, 0, 0.17f, 0.06f, 0.31f, 0.17f, 0.43f, +R_ARC_TO, 0.58f, 0.58f, 0, 0, 0, 0.43f, 0.18f, CLOSE, -MOVE_TO, 5.5f, 10.5f, -R_ARC_TO, 1, 1, 0, 1, 0, 0, -2, -R_ARC_TO, 1, 1, 0, 0, 0, 0, 2, +MOVE_TO, 8, 14.62f, +R_CUBIC_TO, -0.91f, 0, -1.77f, -0.17f, -2.57f, -0.51f, +R_ARC_TO, 6.61f, 6.61f, 0, 0, 1, -2.11f, -1.42f, +R_ARC_TO, 6.61f, 6.61f, 0, 0, 1, -1.42f, -2.11f, +ARC_TO, 6.46f, 6.46f, 0, 0, 1, 1.38f, 8, +R_CUBIC_TO, 0, -1.15f, 0.25f, -2.19f, 0.75f, -3.11f, +ARC_TO, 6.85f, 6.85f, 0, 0, 1, 4.08f, 2.63f, +ARC_TO, 6.79f, 6.79f, 0, 0, 1, 6.73f, 1.44f, +R_ARC_TO, 5.67f, 5.67f, 0, 0, 1, 2.86f, 0.12f, +R_CUBIC_TO, -0.09f, 0.51f, -0.09f, 0.97f, 0.03f, 1.38f, +R_CUBIC_TO, 0.11f, 0.41f, 0.32f, 0.75f, 0.61f, 1.01f, +R_CUBIC_TO, 0.29f, 0.26f, 0.66f, 0.45f, 1.1f, 0.55f, +R_CUBIC_TO, 0.44f, 0.1f, 0.93f, 0.1f, 1.47f, -0.01f, +R_CUBIC_TO, -0.22f, 0.64f, -0.18f, 1.24f, 0.14f, 1.82f, +R_CUBIC_TO, 0.32f, 0.57f, 0.86f, 0.86f, 1.64f, 0.84f, +R_ARC_TO, 6.49f, 6.49f, 0, 0, 1, -0.26f, 2.83f, +R_ARC_TO, 6.79f, 6.79f, 0, 0, 1, -1.34f, 2.38f, +ARC_TO, 6.68f, 6.68f, 0, 0, 1, 10.79f, 14, +R_CUBIC_TO, -0.85f, 0.41f, -1.78f, 0.62f, -2.79f, 0.62f, CLOSE, -MOVE_TO, 10, 10.75f, -R_ARC_TO, 0.75f, 0.75f, 0, 1, 0, 0, -1.5f, -R_ARC_TO, 0.75f, 0.75f, 0, 0, 0, 0, 1.5f, -CLOSE, -NEW_PATH \ No newline at end of file +R_MOVE_TO, 0, -1.63f, +R_CUBIC_TO, 1.31f, 0, 2.44f, -0.44f, 3.37f, -1.3f, +R_CUBIC_TO, 0.94f, -0.87f, 1.47f, -1.95f, 1.58f, -3.25f, +R_ARC_TO, 3.13f, 3.13f, 0, 0, 1, -1.18f, -0.92f, +R_ARC_TO, 3.05f, 3.05f, 0, 0, 1, -0.63f, -1.37f, +ARC_TO, 4.05f, 4.05f, 0, 0, 1, 9.03f, 5.09f, +ARC_TO, 3.55f, 3.55f, 0, 0, 1, 7.93f, 3.04f, +R_ARC_TO, 4.47f, 4.47f, 0, 0, 0, -1.75f, 0.32f, +R_CUBIC_TO, -0.58f, 0.23f, -1.11f, 0.56f, -1.58f, 0.99f, +R_CUBIC_TO, -0.47f, 0.43f, -0.86f, 0.95f, -1.14f, 1.57f, +R_CUBIC_TO, -0.29f, 0.62f, -0.43f, 1.31f, -0.43f, 2.07f, +R_CUBIC_TO, 0, 1.38f, 0.49f, 2.56f, 1.46f, 3.53f, +R_CUBIC_TO, 0.97f, 0.97f, 2.15f, 1.46f, 3.53f, 1.46f, +CLOSE
diff --git a/components/vector_icons/cookie_off_chrome_refresh.icon b/components/vector_icons/cookie_off_chrome_refresh.icon index 50fb441..9094a26 100644 --- a/components/vector_icons/cookie_off_chrome_refresh.icon +++ b/components/vector_icons/cookie_off_chrome_refresh.icon
@@ -2,27 +2,141 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 20.55f, 17.47f, +R_LINE_TO, -1.66f, -1.66f, +R_CUBIC_TO, 0.26f, -0.47f, 0.48f, -0.98f, 0.64f, -1.51f, +R_CUBIC_TO, 0.16f, -0.53f, 0.27f, -1.09f, 0.32f, -1.66f, +R_CUBIC_TO, -0.81f, -0.37f, -1.45f, -0.87f, -1.92f, -1.5f, +R_ARC_TO, 5.38f, 5.38f, 0, 0, 1, -0.96f, -2.09f, +R_ARC_TO, 5.84f, 5.84f, 0, 0, 1, -3.28f, -1.65f, +R_ARC_TO, 5.97f, 5.97f, 0, 0, 1, -1.73f, -3.27f, +R_ARC_TO, 6.8f, 6.8f, 0, 0, 0, -2.04f, 0.24f, +R_ARC_TO, 7.57f, 7.57f, 0, 0, 0, -1.74f, 0.73f, +R_LINE_TO, -1.64f, -1.64f, +R_CUBIC_TO, 1.05f, -0.7f, 2.22f, -1.18f, 3.52f, -1.44f, +R_CUBIC_TO, 1.3f, -0.26f, 2.7f, -0.23f, 4.18f, 0.08f, +R_CUBIC_TO, -0.16f, 0.76f, -0.12f, 1.47f, 0.11f, 2.13f, +R_CUBIC_TO, 0.23f, 0.66f, 0.59f, 1.21f, 1.07f, 1.65f, +R_CUBIC_TO, 0.49f, 0.45f, 1.07f, 0.75f, 1.76f, 0.91f, +R_CUBIC_TO, 0.68f, 0.16f, 1.41f, 0.13f, 2.18f, -0.12f, +R_CUBIC_TO, -0.48f, 1.15f, -0.38f, 2.14f, 0.28f, 2.95f, +R_CUBIC_TO, 0.67f, 0.82f, 1.48f, 1.23f, 2.43f, 1.24f, +R_ARC_TO, 9.48f, 9.48f, 0, 0, 1, -0.21f, 3.5f, +R_ARC_TO, 10.67f, 10.67f, 0, 0, 1, -1.32f, 3.1f, +CLOSE, +MOVE_TO, 8.5f, 15, +R_CUBIC_TO, -0.42f, 0, -0.77f, -0.14f, -1.06f, -0.44f, +ARC_TO, 1.44f, 1.44f, 0, 0, 1, 7, 13.5f, +R_CUBIC_TO, 0, -0.42f, 0.14f, -0.77f, 0.44f, -1.06f, +ARC_TO, 1.44f, 1.44f, 0, 0, 1, 8.5f, 12, +R_CUBIC_TO, 0.42f, 0, 0.77f, 0.14f, 1.06f, 0.44f, +R_CUBIC_TO, 0.29f, 0.29f, 0.44f, 0.64f, 0.44f, 1.06f, +R_CUBIC_TO, 0, 0.42f, -0.14f, 0.77f, -0.44f, 1.06f, +ARC_TO, 1.44f, 1.44f, 0, 0, 1, 8.5f, 15, +CLOSE, +R_MOVE_TO, 12.07f, 8.43f, +R_LINE_TO, -2.92f, -2.91f, +R_CUBIC_TO, -0.82f, 0.55f, -1.7f, 0.97f, -2.64f, 1.25f, +R_CUBIC_TO, -0.95f, 0.29f, -1.95f, 0.44f, -3.01f, 0.44f, +R_CUBIC_TO, -1.41f, 0, -2.74f, -0.26f, -3.98f, -0.8f, +R_ARC_TO, 10.38f, 10.38f, 0, 0, 1, -3.24f, -2.17f, +R_CUBIC_TO, -0.91f, -0.92f, -1.64f, -2, -2.17f, -3.24f, +R_CUBIC_TO, -0.54f, -1.24f, -0.8f, -2.57f, -0.8f, -3.98f, +R_CUBIC_TO, 0, -1.06f, 0.14f, -2.06f, 0.44f, -3.01f, +R_ARC_TO, 9.96f, 9.96f, 0, 0, 1, 1.25f, -2.64f, +LINE_TO, 0.65f, 3.5f, +R_LINE_TO, 1.48f, -1.48f, +LINE_TO, 22.06f, 21.94f, +CLOSE, +MOVE_TO, 12, 19.93f, +R_CUBIC_TO, 0.73f, 0, 1.43f, -0.1f, 2.1f, -0.29f, +R_ARC_TO, 8.27f, 8.27f, 0, 0, 0, 1.88f, -0.8f, +LINE_TO, 5.16f, 8.02f, +R_CUBIC_TO, -0.34f, 0.59f, -0.61f, 1.21f, -0.8f, 1.88f, +ARC_TO, 7.57f, 7.57f, 0, 0, 0, 4.07f, 12, +R_CUBIC_TO, 0, 2.2f, 0.77f, 4.07f, 2.32f, 5.61f, +CUBIC_TO, 7.93f, 19.16f, 9.81f, 19.93f, 12, 19.93f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.77f, 14.47f, +R_LINE_TO, -1.28f, -1.28f, +R_CUBIC_TO, 0.24f, -0.41f, 0.44f, -0.84f, 0.59f, -1.3f, +R_ARC_TO, 6.24f, 6.24f, 0, 0, 0, 0.29f, -1.45f, +R_ARC_TO, 3.8f, 3.8f, 0, 0, 1, -1.53f, -1.16f, +R_ARC_TO, 3.86f, 3.86f, 0, 0, 1, -0.79f, -1.75f, +R_ARC_TO, 4.86f, 4.86f, 0, 0, 1, -2.67f, -1.31f, +R_ARC_TO, 4.42f, 4.42f, 0, 0, 1, -1.34f, -2.6f, +R_ARC_TO, 5.69f, 5.69f, 0, 0, 0, -1.71f, 0.18f, +R_ARC_TO, 5.89f, 5.89f, 0, 0, 0, -1.56f, 0.67f, +LINE_TO, 5.49f, 3.19f, +R_ARC_TO, 8, 8, 0, 0, 1, 3.02f, -1.28f, +R_ARC_TO, 6.69f, 6.69f, 0, 0, 1, 3.29f, 0.17f, +R_CUBIC_TO, -0.11f, 0.62f, -0.09f, 1.19f, 0.07f, 1.7f, +R_CUBIC_TO, 0.16f, 0.51f, 0.44f, 0.94f, 0.82f, 1.27f, +R_CUBIC_TO, 0.38f, 0.33f, 0.84f, 0.57f, 1.4f, 0.7f, +R_CUBIC_TO, 0.56f, 0.13f, 1.15f, 0.13f, 1.8f, -0.02f, +R_CUBIC_TO, -0.32f, 0.79f, -0.26f, 1.55f, 0.16f, 2.27f, +R_CUBIC_TO, 0.43f, 0.72f, 1.1f, 1.08f, 2.01f, 1.09f, +R_ARC_TO, 7.82f, 7.82f, 0, 0, 1, -0.18f, 2.87f, +R_ARC_TO, 8.05f, 8.05f, 0, 0, 1, -1.12f, 2.52f, +CLOSE, +MOVE_TO, 6.75f, 12.5f, +R_CUBIC_TO, -0.35f, 0, -0.64f, -0.12f, -0.89f, -0.36f, +R_ARC_TO, 1.22f, 1.22f, 0, 0, 1, -0.36f, -0.89f, +R_CUBIC_TO, 0, -0.35f, 0.12f, -0.64f, 0.36f, -0.89f, +R_CUBIC_TO, 0.25f, -0.24f, 0.54f, -0.36f, 0.89f, -0.36f, +R_CUBIC_TO, 0.35f, 0, 0.64f, 0.12f, 0.89f, 0.36f, +R_CUBIC_TO, 0.24f, 0.25f, 0.36f, 0.54f, 0.36f, 0.89f, +R_CUBIC_TO, 0, 0.35f, -0.12f, 0.64f, -0.36f, 0.89f, +R_CUBIC_TO, -0.25f, 0.24f, -0.54f, 0.36f, -0.89f, 0.36f, +CLOSE, +R_MOVE_TO, 9.2f, 5.61f, +R_LINE_TO, -1.35f, -1.35f, +R_ARC_TO, 8.76f, 8.76f, 0, 0, 1, -2.2f, 1.05f, +R_ARC_TO, 8.01f, 8.01f, 0, 0, 1, -2.4f, 0.36f, +R_ARC_TO, 7.97f, 7.97f, 0, 0, 1, -3.18f, -0.64f, +R_ARC_TO, 8.2f, 8.2f, 0, 0, 1, -2.6f, -1.75f, +R_ARC_TO, 8.2f, 8.2f, 0, 0, 1, -1.75f, -2.6f, +ARC_TO, 7.97f, 7.97f, 0, 0, 1, 1.83f, 10, +R_CUBIC_TO, 0, -0.83f, 0.12f, -1.62f, 0.36f, -2.4f, +R_ARC_TO, 8.76f, 8.76f, 0, 0, 1, 1.05f, -2.2f, +R_LINE_TO, -1.26f, -1.27f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 13.98f, 13.98f, +CLOSE, +R_MOVE_TO, -5.95f, -1.66f, +R_CUBIC_TO, 0.6f, 0, 1.17f, -0.09f, 1.74f, -0.26f, +R_ARC_TO, 8.67f, 8.67f, 0, 0, 0, 1.62f, -0.69f, +LINE_TO, 4.51f, 6.64f, +R_ARC_TO, 8.82f, 8.82f, 0, 0, 0, -0.69f, 1.62f, +R_ARC_TO, 5.89f, 5.89f, 0, 0, 0, -0.26f, 1.74f, +R_CUBIC_TO, 0, 1.79f, 0.63f, 3.31f, 1.88f, 4.56f, +R_CUBIC_TO, 1.25f, 1.25f, 2.78f, 1.88f, 4.56f, 1.88f, +CLOSE + CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 13.41f, 11.57f, -R_LINE_TO, -1.02f, -1.02f, -R_CUBIC_TO, 0.2f, -0.33f, 0.35f, -0.67f, 0.47f, -1.04f, -R_CUBIC_TO, 0.12f, -0.37f, 0.2f, -0.75f, 0.23f, -1.16f, -R_ARC_TO, 3.09f, 3.09f, 0, 0, 1, -1.85f, -2.33f, -R_ARC_TO, 3.89f, 3.89f, 0, 0, 1, -2.14f, -1.05f, -R_ARC_TO, 3.56f, 3.56f, 0, 0, 1, -1.07f, -2.08f, -R_ARC_TO, 4.42f, 4.42f, 0, 0, 0, -1.36f, 0.14f, -R_ARC_TO, 4.57f, 4.57f, 0, 0, 0, -1.25f, 0.54f, -LINE_TO, 4.39f, 2.55f, -R_ARC_TO, 6.4f, 6.4f, 0, 0, 1, 2.42f, -1.03f, -R_ARC_TO, 5.39f, 5.39f, 0, 0, 1, 2.63f, 0.14f, -R_CUBIC_TO, -0.09f, 0.5f, -0.07f, 0.95f, 0.06f, 1.36f, -R_CUBIC_TO, 0.13f, 0.41f, 0.35f, 0.75f, 0.65f, 1.02f, -R_CUBIC_TO, 0.3f, 0.27f, 0.68f, 0.45f, 1.12f, 0.56f, -R_CUBIC_TO, 0.45f, 0.11f, 0.93f, 0.1f, 1.44f, -0.02f, -R_CUBIC_TO, -0.25f, 0.63f, -0.21f, 1.24f, 0.13f, 1.81f, -R_CUBIC_TO, 0.34f, 0.57f, 0.88f, 0.87f, 1.61f, 0.87f, -R_ARC_TO, 6.26f, 6.26f, 0, 0, 1, -0.14f, 2.3f, -R_ARC_TO, 6.42f, 6.42f, 0, 0, 1, -0.89f, 2.02f, +R_MOVE_TO, 13.57f, 11.54f, +R_LINE_TO, -1.22f, -1.21f, +R_ARC_TO, 4.42f, 4.42f, 0, 0, 0, 0.4f, -0.9f, +R_CUBIC_TO, 0.1f, -0.32f, 0.17f, -0.65f, 0.2f, -1, +R_ARC_TO, 3.13f, 3.13f, 0, 0, 1, -1.18f, -0.92f, +R_ARC_TO, 3.05f, 3.05f, 0, 0, 1, -0.63f, -1.37f, +ARC_TO, 4.05f, 4.05f, 0, 0, 1, 9.03f, 5.09f, +ARC_TO, 3.55f, 3.55f, 0, 0, 1, 7.93f, 3.04f, +R_ARC_TO, 4.42f, 4.42f, 0, 0, 0, -2.28f, 0.58f, +LINE_TO, 4.42f, 2.4f, +ARC_TO, 6.57f, 6.57f, 0, 0, 1, 6.92f, 1.39f, +R_ARC_TO, 5.42f, 5.42f, 0, 0, 1, 2.67f, 0.17f, +R_CUBIC_TO, -0.09f, 0.51f, -0.09f, 0.97f, 0.03f, 1.38f, +R_CUBIC_TO, 0.11f, 0.41f, 0.32f, 0.75f, 0.61f, 1.01f, +R_CUBIC_TO, 0.29f, 0.26f, 0.66f, 0.45f, 1.1f, 0.55f, +R_CUBIC_TO, 0.44f, 0.1f, 0.93f, 0.1f, 1.47f, -0.01f, +R_CUBIC_TO, -0.22f, 0.64f, -0.18f, 1.24f, 0.14f, 1.82f, +R_CUBIC_TO, 0.32f, 0.57f, 0.86f, 0.85f, 1.64f, 0.84f, +R_ARC_TO, 6.59f, 6.59f, 0, 0, 1, -0.12f, 2.34f, +R_ARC_TO, 6.64f, 6.64f, 0, 0, 1, -0.87f, 2.06f, CLOSE, MOVE_TO, 5.4f, 10, R_ARC_TO, 0.96f, 0.96f, 0, 0, 1, -0.71f, -0.29f, @@ -34,30 +148,26 @@ R_ARC_TO, 0.95f, 0.95f, 0, 0, 1, -0.29f, 0.71f, R_ARC_TO, 0.96f, 0.96f, 0, 0, 1, -0.71f, 0.29f, CLOSE, -R_MOVE_TO, 7.37f, 4.48f, -R_LINE_TO, -1.08f, -1.08f, -R_ARC_TO, 7.08f, 7.08f, 0, 0, 1, -1.76f, 0.84f, -R_ARC_TO, 6.49f, 6.49f, 0, 0, 1, -1.92f, 0.29f, -R_CUBIC_TO, -0.9f, 0, -1.75f, -0.17f, -2.54f, -0.51f, -R_ARC_TO, 6.55f, 6.55f, 0, 0, 1, -2.08f, -1.4f, -R_ARC_TO, 6.55f, 6.55f, 0, 0, 1, -1.4f, -2.08f, -ARC_TO, 6.32f, 6.32f, 0, 0, 1, 1.47f, 8, -R_CUBIC_TO, 0, -0.66f, 0.1f, -1.3f, 0.29f, -1.92f, -R_ARC_TO, 7.08f, 7.08f, 0, 0, 1, 0.84f, -1.76f, -LINE_TO, 1.58f, 3.3f, -R_LINE_TO, 0.89f, -0.89f, -R_LINE_TO, 11.18f, 11.18f, +R_MOVE_TO, 7.45f, 4.6f, +R_LINE_TO, -1.05f, -1.04f, +R_ARC_TO, 7.28f, 7.28f, 0, 0, 1, -1.81f, 0.86f, +R_CUBIC_TO, -0.64f, 0.2f, -1.3f, 0.3f, -1.98f, 0.3f, +R_ARC_TO, 6.51f, 6.51f, 0, 0, 1, -2.62f, -0.52f, +R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -2.14f, -1.44f, +R_ARC_TO, 6.7f, 6.7f, 0, 0, 1, -1.44f, -2.14f, +ARC_TO, 6.51f, 6.51f, 0, 0, 1, 1.28f, 8, +R_CUBIC_TO, 0, -0.68f, 0.1f, -1.34f, 0.3f, -1.98f, +R_ARC_TO, 7.28f, 7.28f, 0, 0, 1, 0.86f, -1.81f, +R_LINE_TO, -0.89f, -0.9f, +R_LINE_TO, 0.94f, -0.95f, +R_LINE_TO, 11.3f, 11.3f, CLOSE, -MOVE_TO, 8, 13.15f, -R_CUBIC_TO, 0.48f, 0, 0.94f, -0.07f, 1.39f, -0.21f, -R_CUBIC_TO, 0.45f, -0.14f, 0.88f, -0.32f, 1.29f, -0.55f, -LINE_TO, 3.61f, 5.31f, -R_CUBIC_TO, -0.23f, 0.42f, -0.41f, 0.85f, -0.55f, 1.3f, -R_CUBIC_TO, -0.14f, 0.45f, -0.21f, 0.92f, -0.21f, 1.4f, -R_CUBIC_TO, 0, 1.43f, 0.5f, 2.65f, 1.51f, 3.65f, -CUBIC_TO, 5.36f, 12.65f, 6.58f, 13.15f, 8, 13.15f, -CLOSE, -R_MOVE_TO, -1.01f, -4.14f, -CLOSE, -R_MOVE_TO, 1.92f, -1.95f, +MOVE_TO, 8, 13.09f, +R_ARC_TO, 4.8f, 4.8f, 0, 0, 0, 1.36f, -0.19f, +R_ARC_TO, 6.43f, 6.43f, 0, 0, 0, 1.27f, -0.53f, +R_LINE_TO, -6.98f, -6.99f, +R_ARC_TO, 6.5f, 6.5f, 0, 0, 0, -0.53f, 1.26f, +ARC_TO, 4.84f, 4.84f, 0, 0, 0, 2.91f, 8, +R_CUBIC_TO, 0, 1.41f, 0.5f, 2.62f, 1.48f, 3.61f, +R_CUBIC_TO, 0.99f, 0.99f, 2.2f, 1.48f, 3.6f, 1.48f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/devices_chrome_refresh.icon b/components/vector_icons/devices_chrome_refresh.icon index 13c0027..d211de4 100644 --- a/components/vector_icons/devices_chrome_refresh.icon +++ b/components/vector_icons/devices_chrome_refresh.icon
@@ -67,3 +67,36 @@ V_LINE_TO, 8.5f, R_H_LINE_TO, -3.07f, CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 1.46f, 13.23f, +V_LINE_TO, 11.2f, +R_H_LINE_TO, 1.6f, +V_LINE_TO, 4.4f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.84f, 0.48f, -1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.48f, +R_H_LINE_TO, 8.91f, +R_V_LINE_TO, 1.63f, +R_H_LINE_TO, -8.91f, +V_LINE_TO, 11.2f, +H_LINE_TO, 7.86f, +R_V_LINE_TO, 2.04f, +CLOSE, +R_MOVE_TO, 8.73f, 0, +R_ARC_TO, 0.85f, 0.85f, 0, 0, 1, -0.62f, -0.25f, +R_ARC_TO, 0.84f, 0.84f, 0, 0, 1, -0.25f, -0.62f, +V_LINE_TO, 6.32f, +R_CUBIC_TO, 0, -0.25f, 0.08f, -0.45f, 0.25f, -0.62f, +R_ARC_TO, 0.86f, 0.86f, 0, 0, 1, 0.63f, -0.25f, +R_H_LINE_TO, 3.49f, +R_CUBIC_TO, 0.25f, 0, 0.45f, 0.09f, 0.62f, 0.25f, +R_CUBIC_TO, 0.16f, 0.17f, 0.25f, 0.37f, 0.25f, 0.62f, +R_V_LINE_TO, 6.04f, +R_ARC_TO, 0.86f, 0.86f, 0, 0, 1, -0.25f, 0.62f, +R_ARC_TO, 0.84f, 0.84f, 0, 0, 1, -0.62f, 0.25f, +CLOSE, +R_MOVE_TO, 0.48f, -2.03f, +R_H_LINE_TO, 2.54f, +V_LINE_TO, 6.8f, +R_H_LINE_TO, -2.54f, +CLOSE
diff --git a/components/vector_icons/devices_off_chrome_refresh.icon b/components/vector_icons/devices_off_chrome_refresh.icon index fd63c3c..bc8d406 100644 --- a/components/vector_icons/devices_off_chrome_refresh.icon +++ b/components/vector_icons/devices_off_chrome_refresh.icon
@@ -75,3 +75,41 @@ R_LINE_TO, 1.12f, -1.11f, R_LINE_TO, 14.43f, 14.43f, CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 6.29f, 4.4f, +LINE_TO, 4.66f, 2.77f, +R_H_LINE_TO, 9.07f, +R_V_LINE_TO, 1.63f, +CLOSE, +R_MOVE_TO, 8.38f, 8.37f, +R_LINE_TO, -1.34f, -1.32f, +V_LINE_TO, 6.8f, +R_H_LINE_TO, -2.55f, +R_V_LINE_TO, 2.1f, +R_LINE_TO, -1.34f, -1.35f, +V_LINE_TO, 6.32f, +R_CUBIC_TO, 0, -0.24f, 0.09f, -0.44f, 0.25f, -0.61f, +R_ARC_TO, 0.86f, 0.86f, 0, 0, 1, 0.62f, -0.25f, +R_H_LINE_TO, 3.48f, +R_CUBIC_TO, 0.24f, 0, 0.45f, 0.09f, 0.62f, 0.25f, +R_ARC_TO, 0.83f, 0.83f, 0, 0, 1, 0.25f, 0.61f, +CLOSE, +R_MOVE_TO, -1.57f, 2.27f, +R_LINE_TO, -1.79f, -1.8f, +R_H_LINE_TO, -1, +ARC_TO, 0.78f, 0.78f, 0, 0, 1, 9.68f, 13, +R_ARC_TO, 0.75f, 0.75f, 0, 0, 1, -0.24f, -0.64f, +R_V_LINE_TO, -0.98f, +LINE_TO, 4.82f, 6.75f, +R_V_LINE_TO, 4.45f, +H_LINE_TO, 7.98f, +R_V_LINE_TO, 2.03f, +H_LINE_TO, 1.58f, +V_LINE_TO, 11.2f, +H_LINE_TO, 3.18f, +V_LINE_TO, 5.12f, +LINE_TO, 1.23f, 3.15f, +R_LINE_TO, 0.95f, -0.94f, +R_LINE_TO, 11.88f, 11.88f, +CLOSE
diff --git a/components/vector_icons/file_download_chrome_refresh.icon b/components/vector_icons/file_download_chrome_refresh.icon index b837da24..0faf6b85 100644 --- a/components/vector_icons/file_download_chrome_refresh.icon +++ b/components/vector_icons/file_download_chrome_refresh.icon
@@ -2,6 +2,31 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 5.88f, 20.38f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +R_V_LINE_TO, -3.37f, +H_LINE_TO, 5.88f, +R_V_LINE_TO, 3.37f, +R_H_LINE_TO, 12.23f, +R_V_LINE_TO, -3.37f, +R_H_LINE_TO, 2.27f, +R_V_LINE_TO, 3.37f, +R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, +R_CUBIC_TO, -0.45f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, +CLOSE, +MOVE_TO, 12, 15.83f, +R_LINE_TO, -5.28f, -5.28f, +R_LINE_TO, 1.59f, -1.63f, +R_LINE_TO, 2.55f, 2.56f, +V_LINE_TO, 3.44f, +R_H_LINE_TO, 2.27f, +R_V_LINE_TO, 8.04f, +R_LINE_TO, 2.55f, -2.56f, +R_LINE_TO, 1.59f, 1.63f, +CLOSE + CANVAS_DIMENSIONS, 20, MOVE_TO, 5.4f, 16.32f, R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.51f, @@ -28,26 +53,26 @@ CLOSE CANVAS_DIMENSIONS, 16, -MOVE_TO, 4.32f, 13.06f, -R_ARC_TO, 1.32f, 1.32f, 0, 0, 1, -0.98f, -0.4f, -R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.98f, -V_LINE_TO, 10.23f, -H_LINE_TO, 4.32f, -R_V_LINE_TO, 1.44f, -R_H_LINE_TO, 7.35f, -V_LINE_TO, 10.23f, -R_H_LINE_TO, 1.38f, -R_V_LINE_TO, 1.44f, -R_CUBIC_TO, 0, 0.38f, -0.13f, 0.71f, -0.4f, 0.98f, -R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.4f, -0.98f, 0.4f, +MOVE_TO, 4.21f, 13.4f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +V_LINE_TO, 10, +R_H_LINE_TO, 1.63f, +R_V_LINE_TO, 1.77f, +R_H_LINE_TO, 7.56f, +V_LINE_TO, 10, +R_H_LINE_TO, 1.63f, +R_V_LINE_TO, 1.77f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.47f, 1.16f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.47f, -1.16f, 0.47f, CLOSE, -MOVE_TO, 8, 10.29f, -LINE_TO, 4.61f, 6.9f, -R_LINE_TO, 0.98f, -0.98f, -R_LINE_TO, 1.72f, 1.72f, -V_LINE_TO, 2.02f, -H_LINE_TO, 8.69f, -R_V_LINE_TO, 5.63f, -R_LINE_TO, 1.72f, -1.72f, -R_LINE_TO, 0.98f, 0.98f, -CLOSE \ No newline at end of file +MOVE_TO, 8, 10.14f, +LINE_TO, 4.35f, 6.49f, +R_LINE_TO, 1.16f, -1.14f, +R_LINE_TO, 1.68f, 1.68f, +R_V_LINE_TO, -5.52f, +R_H_LINE_TO, 1.63f, +R_V_LINE_TO, 5.52f, +R_LINE_TO, 1.68f, -1.68f, +R_LINE_TO, 1.16f, 1.14f, +CLOSE
diff --git a/components/vector_icons/file_download_off_chrome_refresh.icon b/components/vector_icons/file_download_off_chrome_refresh.icon index 8a8a3be..e3be41b 100644 --- a/components/vector_icons/file_download_off_chrome_refresh.icon +++ b/components/vector_icons/file_download_off_chrome_refresh.icon
@@ -62,3 +62,34 @@ R_LINE_TO, -1.73f, -1.73f, V_LINE_TO, 2.53f, CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 2.05f, 1.9f, +R_LINE_TO, 12.06f, 12.06f, +R_LINE_TO, -0.95f, 0.94f, +R_LINE_TO, -1.5f, -1.49f, +R_ARC_TO, 0.15f, 0.15f, 0, 0, 1, -0.07f, 0, +R_CUBIC_TO, -0.02f, 0, -0.05f, 0, -0.07f, 0, +H_LINE_TO, 4.22f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.48f, -1.16f, +V_LINE_TO, 10, +R_H_LINE_TO, 1.63f, +R_V_LINE_TO, 1.77f, +R_H_LINE_TO, 5.82f, +R_LINE_TO, -1.64f, -1.64f, +R_LINE_TO, -0.39f, 0.4f, +R_LINE_TO, -3.65f, -3.65f, +R_LINE_TO, 0.4f, -0.39f, +R_LINE_TO, -3.64f, -3.64f, +CLOSE, +R_MOVE_TO, 8.45f, 3.84f, +R_LINE_TO, 1.16f, 1.13f, +R_LINE_TO, -1.37f, 1.37f, +R_LINE_TO, -1.15f, -1.14f, +CLOSE, +MOVE_TO, 8.82f, 1.52f, +R_V_LINE_TO, 5.27f, +LINE_TO, 7.18f, 5.15f, +V_LINE_TO, 1.52f, +CLOSE
diff --git a/components/vector_icons/font_download_chrome_refresh.icon b/components/vector_icons/font_download_chrome_refresh.icon index ee40938..dfc1253 100644 --- a/components/vector_icons/font_download_chrome_refresh.icon +++ b/components/vector_icons/font_download_chrome_refresh.icon
@@ -75,3 +75,40 @@ R_MOVE_TO, 0, -12.88f, V_LINE_TO, 16.44f, CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 4.14f, 12, +R_H_LINE_TO, 1.55f, +R_LINE_TO, 0.71f, -1.96f, +R_H_LINE_TO, 3.2f, +LINE_TO, 10.28f, 12, +R_H_LINE_TO, 1.58f, +LINE_TO, 8.83f, 4, +H_LINE_TO, 7.17f, +CLOSE, +R_MOVE_TO, 2.68f, -3.23f, +R_LINE_TO, 1.15f, -3.26f, +R_H_LINE_TO, 0.03f, +R_LINE_TO, 1.14f, 3.26f, +CLOSE, +MOVE_TO, 2.91f, 14.72f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +V_LINE_TO, 2.91f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.47f, -1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.47f, +R_H_LINE_TO, 10.17f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.47f, +R_CUBIC_TO, 0.32f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f, +R_V_LINE_TO, 10.17f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.47f, 1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.47f, +CLOSE, +R_MOVE_TO, 0, -1.63f, +R_H_LINE_TO, 10.17f, +V_LINE_TO, 2.91f, +H_LINE_TO, 2.91f, +CLOSE, +R_MOVE_TO, 0, -10.17f, +R_V_LINE_TO, 10.17f, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/font_download_off_chrome_refresh.icon b/components/vector_icons/font_download_off_chrome_refresh.icon index 40a46a0..c2e8cee 100644 --- a/components/vector_icons/font_download_off_chrome_refresh.icon +++ b/components/vector_icons/font_download_off_chrome_refresh.icon
@@ -54,4 +54,112 @@ R_LINE_TO, 1.82f, 1.82f, H_LINE_TO, 9.6f, LINE_TO, 8.51f, 18, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.81f, 18.94f, +R_LINE_TO, -0.79f, -0.77f, +R_CUBIC_TO, -0.02f, 0, -0.03f, 0, -0.04f, 0, +H_LINE_TO, 3.56f, +R_CUBIC_TO, -0.47f, 0, -0.88f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 4.02f, +R_CUBIC_TO, 0, -0.01f, 0, -0.02f, 0, -0.04f, +R_LINE_TO, -0.77f, -0.79f, +R_LINE_TO, 1.11f, -1.09f, +R_LINE_TO, 15.72f, 15.72f, +CLOSE, +MOVE_TO, 3.56f, 16.44f, +R_H_LINE_TO, 10.73f, +LINE_TO, 3.56f, 5.72f, +CLOSE, +R_MOVE_TO, 14.61f, -0.57f, +R_LINE_TO, -1.73f, -1.73f, +V_LINE_TO, 3.56f, +H_LINE_TO, 5.86f, +LINE_TO, 4.13f, 1.83f, +H_LINE_TO, 16.44f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +CLOSE, +R_MOVE_TO, -5, -5, +LINE_TO, 10.5f, 8.2f, +R_LINE_TO, -0.49f, -1.41f, +R_H_LINE_TO, -0.07f, +R_LINE_TO, -0.22f, 0.64f, +R_LINE_TO, -1.16f, -1.15f, +LINE_TO, 9.04f, 5, +R_H_LINE_TO, 1.91f, +CLOSE, +R_MOVE_TO, -4.29f, 0.23f, +CLOSE, +R_MOVE_TO, 1.81f, -2.68f, +CLOSE, +R_MOVE_TO, 2.07f, 6.36f, +R_LINE_TO, -1.11f, -3.19f, +R_LINE_TO, 2.86f, 2.86f, +R_LINE_TO, 0.13f, 0.33f, +CLOSE, +MOVE_TO, 5.26f, 15, +R_LINE_TO, 2.7f, -7.12f, +R_LINE_TO, 1.23f, 1.24f, +R_LINE_TO, -0.66f, 1.87f, +R_H_LINE_TO, 2.53f, +R_LINE_TO, 1.5f, 1.5f, +H_LINE_TO, 8.06f, +LINE_TO, 7.18f, 15, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 13.54f, 15.27f, +R_LINE_TO, -0.57f, -0.56f, +R_CUBIC_TO, -0.03f, 0.01f, -0.05f, 0.01f, -0.07f, 0.01f, +R_H_LINE_TO, -9.98f, +R_CUBIC_TO, -0.45f, 0, -0.84f, -0.16f, -1.16f, -0.48f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.48f, -1.16f, +R_V_LINE_TO, -9.98f, +R_CUBIC_TO, 0, -0.02f, 0, -0.04f, 0.01f, -0.07f, +R_LINE_TO, -0.56f, -0.56f, +R_LINE_TO, 0.95f, -0.93f, +LINE_TO, 14.46f, 14.32f, +CLOSE, +R_MOVE_TO, -10.62f, -2.18f, +R_H_LINE_TO, 8.42f, +LINE_TO, 2.91f, 4.67f, +CLOSE, +R_MOVE_TO, 11.8f, -0.39f, +R_LINE_TO, -1.63f, -1.63f, +V_LINE_TO, 2.91f, +H_LINE_TO, 4.94f, +LINE_TO, 3.31f, 1.28f, +R_H_LINE_TO, 9.78f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +CLOSE, +R_MOVE_TO, -4.18f, -4.18f, +LINE_TO, 8.29f, 6.25f, +R_LINE_TO, -0.31f, -0.89f, +R_H_LINE_TO, -0.04f, +R_LINE_TO, -0.13f, 0.41f, +R_LINE_TO, -0.95f, -0.94f, +LINE_TO, 7.17f, 4, +R_H_LINE_TO, 1.66f, +CLOSE, +R_MOVE_TO, -3.45f, 0.38f, +CLOSE, +MOVE_TO, 8.65f, 6.64f, +CLOSE, +R_MOVE_TO, 1.53f, 5.18f, +R_LINE_TO, -0.94f, -2.71f, +R_LINE_TO, 2.45f, 2.45f, +R_LINE_TO, 0.11f, 0.27f, +CLOSE, +MOVE_TO, 4.13f, 12, +R_LINE_TO, 2.21f, -5.8f, +R_LINE_TO, 1.04f, 1.04f, +R_LINE_TO, -0.53f, 1.54f, +R_H_LINE_TO, 2.08f, +R_LINE_TO, 1.26f, 1.26f, +H_LINE_TO, 6.45f, +LINE_TO, 5.75f, 12, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/https_valid_chrome_refresh.icon b/components/vector_icons/https_valid_chrome_refresh.icon index c52531f..9a8a132d 100644 --- a/components/vector_icons/https_valid_chrome_refresh.icon +++ b/components/vector_icons/https_valid_chrome_refresh.icon
@@ -2,52 +2,146 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 6.07f, 22.18f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -1.6f, -0.67f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -0.67f, -1.61f, +R_V_LINE_TO, -9.85f, +R_CUBIC_TO, 0, -0.62f, 0.22f, -1.16f, 0.67f, -1.61f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, 1.61f, -0.67f, +R_H_LINE_TO, 0.84f, +V_LINE_TO, 5.95f, +R_CUBIC_TO, 0, -1.42f, 0.5f, -2.62f, 1.49f, -3.62f, +CUBIC_TO, 9.39f, 1.34f, 10.59f, 0.84f, 12, 0.84f, +R_CUBIC_TO, 1.41f, 0, 2.61f, 0.5f, 3.6f, 1.49f, +R_CUBIC_TO, 0.99f, 1, 1.49f, 2.2f, 1.49f, 3.62f, +R_V_LINE_TO, 1.82f, +R_H_LINE_TO, 0.84f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.67f, +R_CUBIC_TO, 0.45f, 0.45f, 0.67f, 0.99f, 0.67f, 1.61f, +R_V_LINE_TO, 9.86f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -0.67f, 1.61f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -1.6f, 0.67f, +CLOSE, +R_MOVE_TO, 0, -2.27f, +R_H_LINE_TO, 11.86f, +R_V_LINE_TO, -9.85f, +H_LINE_TO, 6.07f, +CLOSE, +MOVE_TO, 12, 16.98f, +R_CUBIC_TO, 0.55f, 0, 1.02f, -0.19f, 1.41f, -0.58f, +R_CUBIC_TO, 0.39f, -0.39f, 0.59f, -0.86f, 0.59f, -1.41f, +R_CUBIC_TO, 0, -0.55f, -0.19f, -1.02f, -0.59f, -1.41f, +ARC_TO, 1.94f, 1.94f, 0, 0, 0, 12, 12.98f, +R_CUBIC_TO, -0.55f, 0, -1.02f, 0.2f, -1.41f, 0.59f, +R_CUBIC_TO, -0.39f, 0.39f, -0.59f, 0.86f, -0.59f, 1.41f, +R_CUBIC_TO, 0, 0.55f, 0.2f, 1.02f, 0.59f, 1.42f, +R_CUBIC_TO, 0.39f, 0.39f, 0.86f, 0.59f, 1.41f, 0.59f, +CLOSE, +MOVE_TO, 9.18f, 7.78f, +R_H_LINE_TO, 5.63f, +V_LINE_TO, 5.95f, +R_CUBIC_TO, 0, -0.79f, -0.27f, -1.46f, -0.82f, -2.01f, +ARC_TO, 2.7f, 2.7f, 0, 0, 0, 12, 3.12f, +R_CUBIC_TO, -0.78f, 0, -1.45f, 0.27f, -2, 0.82f, +R_ARC_TO, 2.74f, 2.74f, 0, 0, 0, -0.82f, 2.01f, +CLOSE, +MOVE_TO, 6.07f, 19.91f, +R_V_LINE_TO, -9.85f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 5.56f, 18.16f, +R_CUBIC_TO, -0.48f, 0, -0.88f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.68f, 1.68f, 0, 0, 1, -0.5f, -1.22f, +V_LINE_TO, 8.54f, +R_CUBIC_TO, 0, -0.47f, 0.17f, -0.88f, 0.51f, -1.22f, +R_CUBIC_TO, 0.34f, -0.34f, 0.75f, -0.51f, 1.22f, -0.51f, +R_H_LINE_TO, 0.37f, +V_LINE_TO, 4.96f, +R_CUBIC_TO, 0, -1.13f, 0.4f, -2.1f, 1.19f, -2.89f, +CUBIC_TO, 7.91f, 1.27f, 8.88f, 0.87f, 10, 0.87f, +R_CUBIC_TO, 1.13f, 0, 2.09f, 0.4f, 2.88f, 1.2f, +R_CUBIC_TO, 0.79f, 0.8f, 1.19f, 1.76f, 1.19f, 2.9f, +R_V_LINE_TO, 1.86f, +R_H_LINE_TO, 0.37f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +R_V_LINE_TO, 7.88f, +R_CUBIC_TO, 0, 0.48f, -0.17f, 0.88f, -0.51f, 1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -1.22f, 0.51f, +CLOSE, +R_MOVE_TO, 0, -1.73f, +R_H_LINE_TO, 8.88f, +V_LINE_TO, 8.54f, +H_LINE_TO, 5.56f, +CLOSE, +R_MOVE_TO, 4.45f, -2.44f, +R_CUBIC_TO, 0.41f, 0, 0.77f, -0.15f, 1.06f, -0.44f, +R_CUBIC_TO, 0.29f, -0.29f, 0.44f, -0.65f, 0.44f, -1.06f, +R_CUBIC_TO, 0, -0.41f, -0.15f, -0.76f, -0.44f, -1.06f, +R_ARC_TO, 1.47f, 1.47f, 0, 0, 0, -1.06f, -0.44f, +R_CUBIC_TO, -0.41f, 0, -0.77f, 0.15f, -1.06f, 0.44f, +R_ARC_TO, 1.45f, 1.45f, 0, 0, 0, -0.44f, 1.06f, +R_CUBIC_TO, 0, 0.41f, 0.15f, 0.77f, 0.44f, 1.06f, +R_CUBIC_TO, 0.3f, 0.29f, 0.65f, 0.44f, 1.06f, 0.44f, +CLOSE, +MOVE_TO, 7.66f, 6.82f, +R_H_LINE_TO, 4.69f, +V_LINE_TO, 4.96f, +R_CUBIC_TO, 0, -0.66f, -0.23f, -1.22f, -0.68f, -1.67f, +R_CUBIC_TO, -0.45f, -0.46f, -1.01f, -0.69f, -1.66f, -0.69f, +R_CUBIC_TO, -0.66f, 0, -1.21f, 0.23f, -1.66f, 0.69f, +R_ARC_TO, 2.29f, 2.29f, 0, 0, 0, -0.68f, 1.67f, +CLOSE, +R_MOVE_TO, -2.1f, 9.61f, +V_LINE_TO, 8.54f, +CLOSE + CANVAS_DIMENSIONS, 16, -MOVE_TO, 4.4f, 14.4f, -CUBIC_TO, 4.07f, 14.4f, 3.79f, 14.28f, 3.55f, 14.05f, -CUBIC_TO, 3.32f, 13.83f, 3.2f, 13.52f, 3.2f, 13.2f, -LINE_TO, 3.2f, 6.8f, -CUBIC_TO, 3.2f, 6.46f, 3.32f, 6.18f, 3.55f, 5.95f, -CUBIC_TO, 3.77f, 5.72f, 4.08f, 5.59f, 4.4f, 5.6f, -LINE_TO, 4.8f, 5.6f, -LINE_TO, 4.8f, 4, -CUBIC_TO, 4.8f, 3.11f, 5.11f, 2.36f, 5.73f, 1.73f, -CUBIC_TO, 6.36f, 1.11f, 7.11f, 0.8f, 8, 0.8f, -CUBIC_TO, 8.89f, 0.8f, 9.64f, 1.11f, 10.27f, 1.73f, -CUBIC_TO, 10.89f, 2.36f, 11.2f, 3.11f, 11.2f, 4, -LINE_TO, 11.2f, 5.6f, -LINE_TO, 11.6f, 5.6f, -CUBIC_TO, 11.93f, 5.6f, 12.21f, 5.72f, 12.45f, 5.95f, -CUBIC_TO, 12.68f, 6.18f, 12.8f, 6.46f, 12.8f, 6.8f, -LINE_TO, 12.8f, 13.2f, -CUBIC_TO, 12.8f, 13.54f, 12.68f, 13.82f, 12.45f, 14.05f, -CUBIC_TO, 12.23f, 14.28f, 11.92f, 14.41f, 11.6f, 14.4f, +MOVE_TO, 4.51f, 14.69f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.15f, -0.48f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.15f, +V_LINE_TO, 6.89f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.84f, 0.48f, -1.16f, +R_CUBIC_TO, 0.32f, -0.32f, 0.7f, -0.48f, 1.15f, -0.48f, +R_H_LINE_TO, 0.15f, +V_LINE_TO, 3.93f, +R_CUBIC_TO, 0, -0.94f, 0.32f, -1.73f, 0.97f, -2.39f, +R_ARC_TO, 3.22f, 3.22f, 0, 0, 1, 2.37f, -0.98f, +R_CUBIC_TO, 0.93f, 0, 1.72f, 0.33f, 2.37f, 0.98f, +R_CUBIC_TO, 0.65f, 0.66f, 0.97f, 1.45f, 0.97f, 2.39f, +V_LINE_TO, 5.25f, +R_H_LINE_TO, 0.15f, +R_CUBIC_TO, 0.45f, 0, 0.83f, 0.16f, 1.15f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +R_V_LINE_TO, 6.17f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.15f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f, CLOSE, -MOVE_TO, 4.4f, 13.2f, -LINE_TO, 11.6f, 13.2f, -LINE_TO, 11.6f, 6.8f, -LINE_TO, 4.4f, 6.8f, +R_MOVE_TO, 0, -1.63f, +R_H_LINE_TO, 6.98f, +V_LINE_TO, 6.89f, +H_LINE_TO, 4.51f, CLOSE, -MOVE_TO, 8, 11.2f, -CUBIC_TO, 8.33f, 11.2f, 8.62f, 11.08f, 8.85f, 10.85f, -CUBIC_TO, 9.08f, 10.62f, 9.2f, 10.33f, 9.2f, 10, -CUBIC_TO, 9.2f, 9.67f, 9.08f, 9.38f, 8.85f, 9.15f, -CUBIC_TO, 8.63f, 8.92f, 8.32f, 8.79f, 8, 8.8f, -CUBIC_TO, 7.67f, 8.8f, 7.38f, 8.92f, 7.15f, 9.15f, -CUBIC_TO, 6.92f, 9.38f, 6.79f, 9.68f, 6.8f, 10, -CUBIC_TO, 6.8f, 10.33f, 6.92f, 10.62f, 7.15f, 10.85f, -CUBIC_TO, 7.38f, 11.08f, 7.67f, 11.2f, 8, 11.2f, +R_MOVE_TO, 3.49f, -1.89f, +R_CUBIC_TO, 0.33f, 0, 0.61f, -0.12f, 0.85f, -0.36f, +R_CUBIC_TO, 0.23f, -0.23f, 0.35f, -0.51f, 0.35f, -0.85f, +R_CUBIC_TO, 0, -0.33f, -0.12f, -0.61f, -0.35f, -0.85f, +R_ARC_TO, 1.17f, 1.17f, 0, 0, 0, -0.85f, -0.35f, +R_CUBIC_TO, -0.33f, 0, -0.61f, 0.12f, -0.85f, 0.35f, +R_CUBIC_TO, -0.23f, 0.23f, -0.35f, 0.52f, -0.35f, 0.85f, +R_CUBIC_TO, 0, 0.33f, 0.12f, 0.61f, 0.35f, 0.84f, +R_CUBIC_TO, 0.24f, 0.24f, 0.52f, 0.35f, 0.85f, 0.35f, CLOSE, -MOVE_TO, 6, 5.6f, -LINE_TO, 10, 5.6f, -LINE_TO, 10, 4, -CUBIC_TO, 10, 3.45f, 9.8f, 2.97f, 9.41f, 2.59f, -CUBIC_TO, 9.04f, 2.2f, 8.53f, 1.99f, 8, 2, -CUBIC_TO, 7.47f, 1.99f, 6.96f, 2.2f, 6.59f, 2.59f, -CUBIC_TO, 6.2f, 2.96f, 5.99f, 3.47f, 6, 4, +MOVE_TO, 6.29f, 5.25f, +R_H_LINE_TO, 3.41f, +V_LINE_TO, 3.93f, +R_CUBIC_TO, 0, -0.48f, -0.16f, -0.89f, -0.49f, -1.23f, +ARC_TO, 1.62f, 1.62f, 0, 0, 0, 8, 2.19f, +R_CUBIC_TO, -0.48f, 0, -0.89f, 0.17f, -1.22f, 0.51f, +R_ARC_TO, 1.7f, 1.7f, 0, 0, 0, -0.49f, 1.23f, CLOSE, -MOVE_TO, 4.4f, 13.2f, -LINE_TO, 4.4f, 6.8f, -CLOSE, -MOVE_TO, 4.4f, 13.2f, +R_MOVE_TO, -1.78f, 7.81f, +V_LINE_TO, 6.89f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/launch_chrome_refresh.icon b/components/vector_icons/launch_chrome_refresh.icon index 8cb73052..8d00eb0 100644 --- a/components/vector_icons/launch_chrome_refresh.icon +++ b/components/vector_icons/launch_chrome_refresh.icon
@@ -2,7 +2,38 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +FLIPS_IN_RTL, +MOVE_TO, 5.07f, 21.2f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 5.07f, +R_CUBIC_TO, 0, -0.63f, 0.22f, -1.16f, 0.66f, -1.61f, +R_CUBIC_TO, 0.45f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f, +H_LINE_TO, 12, +V_LINE_TO, 5.07f, +H_LINE_TO, 5.07f, +R_V_LINE_TO, 13.86f, +R_H_LINE_TO, 13.86f, +V_LINE_TO, 12, +R_H_LINE_TO, 2.27f, +R_V_LINE_TO, 6.93f, +R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, +R_CUBIC_TO, -0.44f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, +CLOSE, +MOVE_TO, 9.89f, 15.7f, +LINE_TO, 8.3f, 14.11f, +R_LINE_TO, 9.04f, -9.04f, +H_LINE_TO, 14, +V_LINE_TO, 2.8f, +R_H_LINE_TO, 7.2f, +V_LINE_TO, 10, +H_LINE_TO, 18.93f, +V_LINE_TO, 6.66f, +CLOSE + CANVAS_DIMENSIONS, 20, +FLIPS_IN_RTL, MOVE_TO, 4.56f, 17.17f, R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.5f, R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.22f, @@ -33,31 +64,30 @@ CANVAS_DIMENSIONS, 16, FLIPS_IN_RTL, -MOVE_TO, 12.5f, 12.5f, -R_H_LINE_TO, -9, -R_V_LINE_TO, -9, +MOVE_TO, 3.72f, 13.92f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, -0.48f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.16f, +R_V_LINE_TO, -8.57f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.48f, H_LINE_TO, 8, -V_LINE_TO, 2, -H_LINE_TO, 3, -R_CUBIC_TO, -0.55f, 0, -1, 0.45f, -1, 1, -R_V_LINE_TO, 10, -R_CUBIC_TO, 0, 0.55f, 0.45f, 1, 1, 1, -R_H_LINE_TO, 10, -R_CUBIC_TO, 0.55f, 0, 1, -0.45f, 1, -1, +R_V_LINE_TO, 1.64f, +H_LINE_TO, 3.72f, +R_V_LINE_TO, 8.57f, +R_H_LINE_TO, 8.57f, V_LINE_TO, 8, -R_H_LINE_TO, -1.5f, -R_V_LINE_TO, 4.5f, +R_H_LINE_TO, 1.64f, +R_V_LINE_TO, 4.29f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.48f, 1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.48f, CLOSE, -NEW_PATH, -MOVE_TO, 9.5f, 2, -R_V_LINE_TO, 1.5f, -R_H_LINE_TO, 1.94f, -LINE_TO, 6, 8.94f, -LINE_TO, 7.06f, 10, -R_LINE_TO, 5.44f, -5.44f, -V_LINE_TO, 6.5f, -H_LINE_TO, 14, -V_LINE_TO, 2, -H_LINE_TO, 9.5f, -CLOSE, -NEW_PATH +R_MOVE_TO, 3.03f, -3.52f, +R_LINE_TO, -1.14f, -1.14f, +R_LINE_TO, 5.54f, -5.54f, +H_LINE_TO, 9.6f, +V_LINE_TO, 2.08f, +R_H_LINE_TO, 4.32f, +R_V_LINE_TO, 4.32f, +R_H_LINE_TO, -1.64f, +V_LINE_TO, 4.86f, +CLOSE
diff --git a/components/vector_icons/launch_off_chrome_refresh.icon b/components/vector_icons/launch_off_chrome_refresh.icon index 03b3e52..c2b93ae1 100644 --- a/components/vector_icons/launch_off_chrome_refresh.icon +++ b/components/vector_icons/launch_off_chrome_refresh.icon
@@ -2,45 +2,131 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +FLIPS_IN_RTL, +R_MOVE_TO, 20, 22.88f, +R_LINE_TO, -1.69f, -1.68f, +R_CUBIC_TO, -0.01f, 0, -0.03f, 0, -0.04f, 0, +H_LINE_TO, 5.07f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 5.72f, +R_CUBIC_TO, 0, -0.01f, 0, -0.02f, 0, -0.04f, +LINE_TO, 1.13f, 4, +R_LINE_TO, 1.48f, -1.48f, +LINE_TO, 21.49f, 21.39f, +CLOSE, +MOVE_TO, 5.07f, 18.93f, +R_H_LINE_TO, 10.98f, +R_LINE_TO, -4.69f, -4.7f, +LINE_TO, 9.89f, 15.7f, +LINE_TO, 8.3f, 14.11f, +R_LINE_TO, 1.47f, -1.46f, +LINE_TO, 5.07f, 7.95f, +CLOSE, +MOVE_TO, 8.14f, 5.07f, +LINE_TO, 5.86f, 2.8f, +H_LINE_TO, 12, +V_LINE_TO, 5.07f, +CLOSE, +R_MOVE_TO, 6.19f, 6.19f, +R_LINE_TO, -1.59f, -1.59f, +R_LINE_TO, 4.61f, -4.61f, +H_LINE_TO, 14, +V_LINE_TO, 2.8f, +R_H_LINE_TO, 7.2f, +V_LINE_TO, 10, +H_LINE_TO, 18.93f, +V_LINE_TO, 6.66f, +CLOSE, +R_MOVE_TO, 6.88f, 6.88f, +R_LINE_TO, -2.27f, -2.27f, +V_LINE_TO, 12, +R_H_LINE_TO, 2.27f, +CLOSE + +CANVAS_DIMENSIONS, 20, +FLIPS_IN_RTL, +R_MOVE_TO, 16.19f, 18.34f, +R_LINE_TO, -1.17f, -1.17f, +R_CUBIC_TO, -0.02f, 0, -0.03f, 0, -0.04f, 0, +H_LINE_TO, 4.56f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.5f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.22f, +V_LINE_TO, 5.02f, +R_CUBIC_TO, 0, -0.01f, 0, -0.02f, 0, -0.04f, +LINE_TO, 1.66f, 3.81f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 14.52f, 14.52f, +CLOSE, +MOVE_TO, 4.56f, 15.44f, +R_H_LINE_TO, 8.73f, +R_LINE_TO, -3.75f, -3.77f, +LINE_TO, 8.22f, 13, +LINE_TO, 7, 11.78f, +R_LINE_TO, 1.33f, -1.32f, +R_LINE_TO, -3.77f, -3.75f, +CLOSE, +MOVE_TO, 6.86f, 4.56f, +LINE_TO, 5.14f, 2.83f, +H_LINE_TO, 10, +R_V_LINE_TO, 1.73f, +CLOSE, +R_MOVE_TO, 4.88f, 4.91f, +R_LINE_TO, -1.22f, -1.22f, +R_LINE_TO, 3.69f, -3.69f, +H_LINE_TO, 12, +V_LINE_TO, 2.83f, +R_H_LINE_TO, 5.17f, +V_LINE_TO, 8, +R_H_LINE_TO, -1.73f, +V_LINE_TO, 5.78f, +CLOSE, +R_MOVE_TO, 5.42f, 5.39f, +R_LINE_TO, -1.73f, -1.73f, +V_LINE_TO, 10, +R_H_LINE_TO, 1.73f, +CLOSE + CANVAS_DIMENSIONS, 16, FLIPS_IN_RTL, -R_MOVE_TO, 12.95f, 14.67f, -R_LINE_TO, -0.94f, -0.94f, -R_CUBIC_TO, -0.01f, 0, -0.02f, 0, -0.03f, 0, -H_LINE_TO, 3.65f, -R_CUBIC_TO, -0.38f, 0, -0.71f, -0.13f, -0.98f, -0.4f, -R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.98f, -V_LINE_TO, 4.02f, -R_CUBIC_TO, 0, -0.01f, 0, -0.02f, 0, -0.03f, -R_LINE_TO, -0.94f, -0.94f, -R_LINE_TO, 0.89f, -0.89f, -LINE_TO, 13.84f, 13.78f, +R_MOVE_TO, 13.16f, 14.9f, +R_LINE_TO, -0.99f, -0.98f, +R_ARC_TO, 0.24f, 0.24f, 0, 0, 1, -0.07f, 0.01f, +H_LINE_TO, 3.72f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, -0.48f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.16f, +V_LINE_TO, 3.9f, +R_CUBIC_TO, 0, -0.02f, 0, -0.04f, 0.01f, -0.07f, +R_LINE_TO, -0.98f, -0.99f, +R_LINE_TO, 0.94f, -0.95f, +R_LINE_TO, 12.06f, 12.06f, CLOSE, -R_MOVE_TO, -9.3f, -2.32f, -R_H_LINE_TO, 6.99f, -LINE_TO, 7.64f, 9.34f, -R_LINE_TO, -1.06f, 1.06f, -R_LINE_TO, -0.97f, -0.97f, -LINE_TO, 6.66f, 8.36f, -LINE_TO, 3.65f, 5.37f, +R_MOVE_TO, -9.44f, -2.61f, +R_H_LINE_TO, 6.82f, +LINE_TO, 7.71f, 9.44f, +R_LINE_TO, -0.96f, 0.96f, +R_LINE_TO, -1.14f, -1.14f, +R_LINE_TO, 0.96f, -0.96f, +R_LINE_TO, -2.85f, -2.83f, CLOSE, -R_MOVE_TO, 1.84f, -8.7f, -LINE_TO, 4.11f, 2.27f, +R_MOVE_TO, 2.04f, -8.57f, +LINE_TO, 4.12f, 2.08f, H_LINE_TO, 8, -R_V_LINE_TO, 1.38f, +R_V_LINE_TO, 1.64f, CLOSE, -R_MOVE_TO, 3.91f, 3.93f, -R_LINE_TO, -0.97f, -0.97f, -R_LINE_TO, 2.95f, -2.95f, +R_MOVE_TO, 3.82f, 3.85f, +LINE_TO, 8.43f, 6.42f, +R_LINE_TO, 2.71f, -2.71f, H_LINE_TO, 9.6f, -V_LINE_TO, 2.27f, -R_H_LINE_TO, 4.13f, -R_V_LINE_TO, 4.13f, -R_H_LINE_TO, -1.38f, -V_LINE_TO, 4.62f, +V_LINE_TO, 2.08f, +R_H_LINE_TO, 4.32f, +R_V_LINE_TO, 4.32f, +R_H_LINE_TO, -1.64f, +V_LINE_TO, 4.86f, CLOSE, R_MOVE_TO, 4.34f, 4.32f, -R_LINE_TO, -1.38f, -1.38f, +R_LINE_TO, -1.64f, -1.64f, V_LINE_TO, 8, -R_H_LINE_TO, 1.38f, -CLOSE \ No newline at end of file +R_H_LINE_TO, 1.64f, +CLOSE
diff --git a/components/vector_icons/location_off_chrome_refresh.icon b/components/vector_icons/location_off_chrome_refresh.icon index f0b65d6e..1e95b43 100644 --- a/components/vector_icons/location_off_chrome_refresh.icon +++ b/components/vector_icons/location_off_chrome_refresh.icon
@@ -2,6 +2,58 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 17.39f, 14.41f, +R_LINE_TO, -1.65f, -1.65f, +R_ARC_TO, 7.9f, 7.9f, 0, 0, 0, 0.87f, -1.8f, +R_CUBIC_TO, 0.21f, -0.63f, 0.32f, -1.29f, 0.32f, -1.96f, +R_CUBIC_TO, 0, -1.36f, -0.48f, -2.53f, -1.44f, -3.49f, +CUBIC_TO, 14.53f, 4.55f, 13.36f, 4.07f, 12, 4.07f, +R_ARC_TO, 4.93f, 4.93f, 0, 0, 0, -1.9f, 0.38f, +R_ARC_TO, 4.75f, 4.75f, 0, 0, 0, -1.59f, 1.09f, +LINE_TO, 6.88f, 3.94f, +R_ARC_TO, 7.19f, 7.19f, 0, 0, 1, 2.36f, -1.59f, +ARC_TO, 7.07f, 7.07f, 0, 0, 1, 12, 1.8f, +R_CUBIC_TO, 2.01f, 0, 3.71f, 0.7f, 5.11f, 2.1f, +CUBIC_TO, 18.5f, 5.29f, 19.2f, 6.99f, 19.2f, 9, +R_ARC_TO, 8.21f, 8.21f, 0, 0, 1, -0.5f, 2.84f, +R_CUBIC_TO, -0.33f, 0.91f, -0.77f, 1.77f, -1.32f, 2.58f, +CLOSE, +R_MOVE_TO, -3.52f, -3.48f, +R_ARC_TO, 2.4f, 2.4f, 0, 0, 0, 0.47f, -0.77f, +R_CUBIC_TO, 0.11f, -0.28f, 0.16f, -0.59f, 0.16f, -0.91f, +R_CUBIC_TO, 0, -0.7f, -0.24f, -1.29f, -0.73f, -1.77f, +R_CUBIC_TO, -0.48f, -0.48f, -1.07f, -0.73f, -1.77f, -0.73f, +R_CUBIC_TO, -0.31f, 0, -0.61f, 0.05f, -0.89f, 0.16f, +R_ARC_TO, 2.14f, 2.14f, 0, 0, 0, -0.74f, 0.48f, +CLOSE, +R_MOVE_TO, 6, 11.86f, +R_LINE_TO, -4.94f, -4.94f, +R_ARC_TO, 9.99f, 9.99f, 0, 0, 0, -0.87f, 1.54f, +R_CUBIC_TO, -0.24f, 0.54f, -0.48f, 1.09f, -0.71f, 1.65f, +R_ARC_TO, 2.73f, 2.73f, 0, 0, 1, -0.54f, 0.81f, +R_ARC_TO, 1.08f, 1.08f, 0, 0, 1, -0.8f, 0.35f, +R_CUBIC_TO, -0.32f, 0, -0.6f, -0.12f, -0.82f, -0.35f, +R_ARC_TO, 2.47f, 2.47f, 0, 0, 1, -0.52f, -0.81f, +R_ARC_TO, 14.01f, 14.01f, 0, 0, 0, -1.41f, -2.69f, +R_ARC_TO, 51.84f, 51.84f, 0, 0, 0, -1.77f, -2.5f, +R_ARC_TO, 23.44f, 23.44f, 0, 0, 1, -1.87f, -3.25f, +R_ARC_TO, 8.29f, 8.29f, 0, 0, 1, -0.78f, -4.18f, +R_CUBIC_TO, 0.02f, -0.19f, 0.05f, -0.39f, 0.09f, -0.58f, +LINE_TO, 1.21f, 4.13f, +R_LINE_TO, 1.47f, -1.46f, +R_LINE_TO, 18.65f, 18.65f, +CLOSE, +MOVE_TO, 12, 18.46f, +R_CUBIC_TO, 0.17f, -0.39f, 0.36f, -0.78f, 0.57f, -1.15f, +R_CUBIC_TO, 0.21f, -0.37f, 0.44f, -0.73f, 0.68f, -1.08f, +R_LINE_TO, -6.03f, -6.04f, +R_CUBIC_TO, 0.14f, 0.82f, 0.43f, 1.58f, 0.87f, 2.28f, +R_CUBIC_TO, 0.43f, 0.7f, 0.91f, 1.38f, 1.42f, 2.03f, +R_CUBIC_TO, 0.47f, 0.61f, 0.92f, 1.25f, 1.34f, 1.91f, +R_CUBIC_TO, 0.42f, 0.66f, 0.8f, 1.34f, 1.15f, 2.05f, +CLOSE + CANVAS_DIMENSIONS, 20, R_MOVE_TO, 14.22f, 11.97f, R_LINE_TO, -1.25f, -1.25f, @@ -53,47 +105,57 @@ R_CUBIC_TO, 0.37f, 0.62f, 0.76f, 1.23f, 1.17f, 1.82f, R_CUBIC_TO, 0.37f, 0.49f, 0.72f, 0.97f, 1.05f, 1.46f, R_CUBIC_TO, 0.33f, 0.49f, 0.64f, 1, 0.91f, 1.55f, -CLOSE, -R_MOVE_TO, -1.32f, -4.11f, -CLOSE, -R_MOVE_TO, 1.4f, -3.27f, CLOSE CANVAS_DIMENSIONS, 16, -MOVE_TO, 8, 2.5f, -R_CUBIC_TO, 1.93f, 0, 3.5f, 1.57f, 3.5f, 3.5f, -R_CUBIC_TO, 0, 0.88f, -0.36f, 1.65f, -0.91f, 2.47f, -R_LINE_TO, 1.08f, 1.08f, -CUBIC_TO, 12.42f, 8.46f, 13, 7.36f, 13, 6, -R_CUBIC_TO, 0, -2.76f, -2.24f, -5, -5, -5, -R_CUBIC_TO, -1.35f, 0, -2.57f, 0.54f, -3.47f, 1.41f, -R_LINE_TO, 1.06f, 1.06f, -R_CUBIC_TO, 0.63f, -0.6f, 1.47f, -0.97f, 2.41f, -0.97f, +R_MOVE_TO, 11.55f, 9.64f, +R_LINE_TO, -1.19f, -1.19f, +R_CUBIC_TO, 0.23f, -0.37f, 0.4f, -0.76f, 0.53f, -1.17f, +R_CUBIC_TO, 0.13f, -0.42f, 0.19f, -0.84f, 0.19f, -1.28f, +R_CUBIC_TO, 0, -0.85f, -0.3f, -1.58f, -0.9f, -2.18f, +ARC_TO, 2.97f, 2.97f, 0, 0, 0, 8, 2.91f, +R_CUBIC_TO, -0.43f, 0, -0.84f, 0.09f, -1.22f, 0.26f, +R_CUBIC_TO, -0.38f, 0.17f, -0.72f, 0.41f, -1.01f, 0.71f, +LINE_TO, 4.64f, 2.72f, +ARC_TO, 5.06f, 5.06f, 0, 0, 1, 6.18f, 1.66f, +ARC_TO, 4.43f, 4.43f, 0, 0, 1, 8, 1.28f, +R_CUBIC_TO, 1.32f, 0, 2.43f, 0.46f, 3.35f, 1.37f, +R_CUBIC_TO, 0.91f, 0.92f, 1.37f, 2.03f, 1.37f, 3.35f, +R_CUBIC_TO, 0, 0.66f, -0.1f, 1.29f, -0.3f, 1.9f, +R_ARC_TO, 6.93f, 6.93f, 0, 0, 1, -0.87f, 1.74f, CLOSE, -NEW_PATH, -MOVE_TO, 8, 4, -R_CUBIC_TO, -0.52f, 0, -0.98f, 0.23f, -1.3f, 0.58f, -R_LINE_TO, 2.46f, 2.46f, -R_CUBIC_TO, 0.36f, -0.32f, 0.58f, -0.78f, 0.58f, -1.3f, -R_CUBIC_TO, 0, -0.97f, -0.78f, -1.75f, -1.75f, -1.75f, -LINE_TO, 8, 4, +MOVE_TO, 9.21f, 7.29f, +R_CUBIC_TO, 0.11f, -0.15f, 0.21f, -0.31f, 0.28f, -0.49f, +R_CUBIC_TO, 0.08f, -0.18f, 0.11f, -0.37f, 0.11f, -0.56f, +R_CUBIC_TO, 0, -0.45f, -0.16f, -0.83f, -0.46f, -1.14f, +ARC_TO, 1.55f, 1.55f, 0, 0, 0, 8, 4.63f, +R_CUBIC_TO, -0.19f, 0, -0.38f, 0.03f, -0.57f, 0.09f, +R_CUBIC_TO, -0.19f, 0.06f, -0.35f, 0.16f, -0.5f, 0.31f, CLOSE, -MOVE_TO, 0.75f, 2.87f, -LINE_TO, 3.08f, 5.2f, -R_CUBIC_TO, -0.04f, 0.26f, -0.08f, 0.52f, -0.08f, 0.8f, -R_CUBIC_TO, 0, 3.22f, 3.22f, 5, 4.32f, 8.5f, -R_CUBIC_TO, 0.08f, 0.25f, 0.33f, 0.5f, 0.68f, 0.5f, -R_CUBIC_TO, 0.35f, 0, 0.6f, -0.25f, 0.68f, -0.5f, -R_CUBIC_TO, 0.29f, -0.93f, 0.73f, -1.73f, 1.22f, -2.47f, -R_LINE_TO, 3.22f, 3.22f, -R_LINE_TO, 1.06f, -1.06f, -LINE_TO, 1.81f, 1.81f, -LINE_TO, 0.75f, 2.87f, +R_MOVE_TO, 3.69f, 7.52f, +LINE_TO, 10, 11.88f, +R_CUBIC_TO, -0.16f, 0.28f, -0.33f, 0.58f, -0.5f, 0.88f, +R_ARC_TO, 18.35f, 18.35f, 0, 0, 0, -0.49f, 0.91f, +R_ARC_TO, 4.51f, 4.51f, 0, 0, 1, -0.39f, 0.72f, +R_ARC_TO, 0.69f, 0.69f, 0, 0, 1, -0.62f, 0.33f, +R_ARC_TO, 0.69f, 0.69f, 0, 0, 1, -0.61f, -0.33f, +R_ARC_TO, 5.26f, 5.26f, 0, 0, 1, -0.4f, -0.72f, +R_ARC_TO, 8.57f, 8.57f, 0, 0, 0, -1.02f, -1.62f, +R_ARC_TO, 24.63f, 24.63f, 0, 0, 1, -1.13f, -1.53f, +R_ARC_TO, 12.17f, 12.17f, 0, 0, 1, -1.11f, -2.15f, +R_ARC_TO, 6.37f, 6.37f, 0, 0, 1, -0.45f, -2.35f, +R_CUBIC_TO, 0, -0.13f, 0, -0.26f, 0.01f, -0.38f, +R_CUBIC_TO, 0, -0.12f, 0.02f, -0.25f, 0.06f, -0.37f, +LINE_TO, 1.2f, 3.08f, +R_LINE_TO, 0.95f, -0.94f, +R_LINE_TO, 11.7f, 11.71f, CLOSE, -R_MOVE_TO, 8.07f, 8.07f, -R_CUBIC_TO, -0.29f, 0.42f, -0.57f, 0.86f, -0.82f, 1.33f, -R_CUBIC_TO, -0.52f, -0.97f, -1.14f, -1.81f, -1.71f, -2.57f, -R_CUBIC_TO, -0.81f, -1.09f, -1.48f, -1.99f, -1.7f, -2.99f, -R_LINE_TO, 4.23f, 4.23f, -CLOSE, -NEW_PATH \ No newline at end of file +MOVE_TO, 8, 12.02f, +R_CUBIC_TO, 0.11f, -0.23f, 0.25f, -0.45f, 0.4f, -0.66f, +R_CUBIC_TO, 0.15f, -0.21f, 0.3f, -0.41f, 0.44f, -0.63f, +LINE_TO, 5.1f, 6.98f, +R_CUBIC_TO, 0.09f, 0.52f, 0.27f, 1, 0.54f, 1.45f, +R_CUBIC_TO, 0.27f, 0.44f, 0.55f, 0.88f, 0.85f, 1.32f, +R_CUBIC_TO, 0.28f, 0.37f, 0.55f, 0.74f, 0.81f, 1.1f, +R_CUBIC_TO, 0.25f, 0.37f, 0.49f, 0.76f, 0.71f, 1.17f, +CLOSE
diff --git a/components/vector_icons/location_on_chrome_refresh.icon b/components/vector_icons/location_on_chrome_refresh.icon index 94f8c58..749ea94 100644 --- a/components/vector_icons/location_on_chrome_refresh.icon +++ b/components/vector_icons/location_on_chrome_refresh.icon
@@ -2,69 +2,134 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 12, 22.18f, +R_CUBIC_TO, -0.27f, 0, -0.5f, -0.07f, -0.7f, -0.23f, +R_ARC_TO, 1.61f, 1.61f, 0, 0, 1, -0.46f, -0.63f, +R_CUBIC_TO, -0.38f, -1.01f, -0.8f, -1.91f, -1.26f, -2.7f, +R_CUBIC_TO, -0.46f, -0.79f, -1.09f, -1.69f, -1.87f, -2.72f, +R_CUBIC_TO, -0.86f, -1.11f, -1.56f, -2.18f, -2.1f, -3.19f, +R_CUBIC_TO, -0.53f, -1.02f, -0.8f, -2.25f, -0.8f, -3.71f, +R_CUBIC_TO, 0, -2.01f, 0.7f, -3.71f, 2.1f, -5.11f, +CUBIC_TO, 8.29f, 2.5f, 9.99f, 1.8f, 12, 1.8f, +R_CUBIC_TO, 2, 0, 3.71f, 0.7f, 5.11f, 2.1f, +CUBIC_TO, 18.5f, 5.29f, 19.2f, 6.99f, 19.2f, 9, +R_CUBIC_TO, 0, 1.55f, -0.29f, 2.84f, -0.88f, 3.86f, +R_ARC_TO, 26.27f, 26.27f, 0, 0, 1, -2.02f, 3.04f, +R_CUBIC_TO, -0.83f, 1.1f, -1.47f, 2.04f, -1.92f, 2.81f, +R_CUBIC_TO, -0.44f, 0.77f, -0.85f, 1.64f, -1.22f, 2.61f, +R_CUBIC_TO, -0.11f, 0.28f, -0.27f, 0.49f, -0.47f, 0.64f, +R_ARC_TO, 1.16f, 1.16f, 0, 0, 1, -0.69f, 0.22f, +CLOSE, +R_MOVE_TO, 0, -3.87f, +R_ARC_TO, 16.62f, 16.62f, 0, 0, 1, 0.95f, -1.67f, +R_CUBIC_TO, 0.36f, -0.55f, 0.87f, -1.26f, 1.54f, -2.14f, +R_CUBIC_TO, 0.72f, -0.93f, 1.3f, -1.78f, 1.75f, -2.57f, +R_CUBIC_TO, 0.46f, -0.79f, 0.69f, -1.77f, 0.69f, -2.94f, +R_CUBIC_TO, 0, -1.36f, -0.48f, -2.53f, -1.44f, -3.49f, +CUBIC_TO, 14.53f, 4.55f, 13.36f, 4.07f, 12, 4.07f, +R_CUBIC_TO, -1.36f, 0, -2.53f, 0.48f, -3.49f, 1.44f, +CUBIC_TO, 7.55f, 6.47f, 7.07f, 7.64f, 7.07f, 9, +R_CUBIC_TO, 0, 1.17f, 0.23f, 2.15f, 0.69f, 2.94f, +R_CUBIC_TO, 0.45f, 0.79f, 1.04f, 1.64f, 1.75f, 2.57f, +R_CUBIC_TO, 0.67f, 0.88f, 1.18f, 1.59f, 1.54f, 2.14f, +R_CUBIC_TO, 0.36f, 0.55f, 0.67f, 1.11f, 0.95f, 1.67f, +CLOSE, +R_MOVE_TO, 0, -6.79f, +R_CUBIC_TO, 0.7f, 0, 1.3f, -0.25f, 1.79f, -0.73f, +ARC_TO, 2.43f, 2.43f, 0, 0, 0, 14.52f, 9, +R_CUBIC_TO, 0, -0.7f, -0.25f, -1.3f, -0.73f, -1.78f, +ARC_TO, 2.43f, 2.43f, 0, 0, 0, 12, 6.48f, +R_CUBIC_TO, -0.7f, 0, -1.3f, 0.25f, -1.78f, 0.73f, +ARC_TO, 2.43f, 2.43f, 0, 0, 0, 9.48f, 9, +R_CUBIC_TO, 0, 0.7f, 0.25f, 1.3f, 0.73f, 1.79f, +R_ARC_TO, 2.43f, 2.43f, 0, 0, 0, 1.79f, 0.74f, +CLOSE + CANVAS_DIMENSIONS, 20, -MOVE_TO, 10.01f, 18.15f, -R_CUBIC_TO, -0.22f, 0, -0.41f, -0.06f, -0.57f, -0.18f, -R_CUBIC_TO, -0.16f, -0.12f, -0.28f, -0.29f, -0.36f, -0.49f, -R_CUBIC_TO, -0.32f, -0.8f, -0.65f, -1.52f, -1.01f, -2.15f, +MOVE_TO, 10, 18.16f, +R_ARC_TO, 0.92f, 0.92f, 0, 0, 1, -0.57f, -0.18f, +R_ARC_TO, 1.09f, 1.09f, 0, 0, 1, -0.36f, -0.5f, +R_ARC_TO, 18.21f, 18.21f, 0, 0, 0, -1.01f, -2.15f, R_CUBIC_TO, -0.36f, -0.64f, -0.86f, -1.37f, -1.5f, -2.2f, -R_CUBIC_TO, -0.69f, -0.88f, -1.25f, -1.74f, -1.68f, -2.56f, -R_CUBIC_TO, -0.43f, -0.82f, -0.65f, -1.81f, -0.65f, -2.97f, -R_CUBIC_TO, 0, -1.6f, 0.56f, -2.96f, 1.68f, -4.08f, -CUBIC_TO, 7.04f, 2.4f, 8.4f, 1.84f, 10.01f, 1.84f, +R_ARC_TO, 16.96f, 16.96f, 0, 0, 1, -1.68f, -2.56f, +R_CUBIC_TO, -0.43f, -0.82f, -0.65f, -1.81f, -0.65f, -2.96f, +R_CUBIC_TO, 0, -1.6f, 0.56f, -2.96f, 1.68f, -4.09f, +CUBIC_TO, 7.03f, 2.39f, 8.39f, 1.83f, 10, 1.83f, R_CUBIC_TO, 1.61f, 0, 2.97f, 0.56f, 4.09f, 1.68f, R_CUBIC_TO, 1.12f, 1.12f, 1.68f, 2.49f, 1.68f, 4.1f, R_CUBIC_TO, 0, 1.24f, -0.24f, 2.27f, -0.71f, 3.09f, -R_CUBIC_TO, -0.47f, 0.82f, -1.01f, 1.62f, -1.62f, 2.43f, -R_CUBIC_TO, -0.67f, 0.86f, -1.18f, 1.61f, -1.54f, 2.24f, -R_CUBIC_TO, -0.36f, 0.63f, -0.68f, 1.33f, -0.97f, 2.11f, +R_ARC_TO, 23.21f, 23.21f, 0, 0, 1, -1.62f, 2.43f, +R_CUBIC_TO, -0.66f, 0.86f, -1.18f, 1.61f, -1.54f, 2.24f, +R_ARC_TO, 14.28f, 14.28f, 0, 0, 0, -0.97f, 2.11f, R_CUBIC_TO, -0.09f, 0.2f, -0.21f, 0.37f, -0.37f, 0.49f, -R_CUBIC_TO, -0.16f, 0.12f, -0.34f, 0.19f, -0.55f, 0.19f, +R_ARC_TO, 0.87f, 0.87f, 0, 0, 1, -0.56f, 0.19f, CLOSE, -R_MOVE_TO, 0, -2.89f, +MOVE_TO, 10, 15.26f, R_CUBIC_TO, 0.23f, -0.47f, 0.5f, -0.94f, 0.79f, -1.4f, -R_CUBIC_TO, 0.3f, -0.46f, 0.72f, -1.06f, 1.28f, -1.8f, -R_CUBIC_TO, 0.58f, -0.74f, 1.05f, -1.43f, 1.42f, -2.07f, -R_CUBIC_TO, 0.37f, -0.64f, 0.55f, -1.43f, 0.55f, -2.39f, -R_CUBIC_TO, 0, -1.11f, -0.4f, -2.06f, -1.19f, -2.85f, -R_CUBIC_TO, -0.79f, -0.79f, -1.75f, -1.19f, -2.86f, -1.19f, +R_CUBIC_TO, 0.29f, -0.46f, 0.72f, -1.06f, 1.28f, -1.8f, +R_ARC_TO, 17.86f, 17.86f, 0, 0, 0, 1.42f, -2.07f, +R_CUBIC_TO, 0.36f, -0.64f, 0.55f, -1.43f, 0.55f, -2.39f, +R_CUBIC_TO, 0, -1.11f, -0.39f, -2.06f, -1.19f, -2.85f, +R_CUBIC_TO, -0.8f, -0.79f, -1.75f, -1.19f, -2.87f, -1.19f, R_CUBIC_TO, -1.11f, 0, -2.07f, 0.4f, -2.85f, 1.19f, -R_CUBIC_TO, -0.79f, 0.79f, -1.18f, 1.75f, -1.18f, 2.85f, -R_CUBIC_TO, 0, 0.95f, 0.19f, 1.75f, 0.56f, 2.39f, +R_CUBIC_TO, -0.79f, 0.79f, -1.18f, 1.75f, -1.18f, 2.86f, +R_CUBIC_TO, 0, 0.95f, 0.18f, 1.75f, 0.56f, 2.39f, R_CUBIC_TO, 0.37f, 0.64f, 0.84f, 1.33f, 1.41f, 2.07f, R_CUBIC_TO, 0.56f, 0.74f, 0.99f, 1.34f, 1.28f, 1.8f, -R_CUBIC_TO, 0.29f, 0.46f, 0.56f, 0.93f, 0.79f, 1.4f, +R_CUBIC_TO, 0.3f, 0.46f, 0.56f, 0.93f, 0.79f, 1.4f, CLOSE, R_MOVE_TO, 0, -5.64f, R_CUBIC_TO, 0.56f, 0, 1.04f, -0.19f, 1.43f, -0.58f, R_CUBIC_TO, 0.39f, -0.39f, 0.59f, -0.86f, 0.59f, -1.43f, -R_CUBIC_TO, 0, -0.57f, -0.19f, -1.04f, -0.58f, -1.43f, -R_CUBIC_TO, -0.39f, -0.39f, -0.86f, -0.59f, -1.43f, -0.59f, -R_CUBIC_TO, -0.57f, 0, -1.04f, 0.19f, -1.43f, 0.58f, -CUBIC_TO, 8.2f, 6.56f, 8, 7.03f, 8, 7.6f, -R_CUBIC_TO, 0, 0.57f, 0.19f, 1.04f, 0.58f, 1.43f, -R_CUBIC_TO, 0.39f, 0.39f, 0.86f, 0.59f, 1.43f, 0.59f, +R_CUBIC_TO, 0, -0.56f, -0.2f, -1.04f, -0.58f, -1.43f, +R_ARC_TO, 1.95f, 1.95f, 0, 0, 0, -1.43f, -0.59f, +R_CUBIC_TO, -0.56f, 0, -1.04f, 0.2f, -1.43f, 0.58f, +R_CUBIC_TO, -0.39f, 0.39f, -0.59f, 0.86f, -0.59f, 1.43f, +R_CUBIC_TO, 0, 0.56f, 0.2f, 1.04f, 0.58f, 1.43f, +R_CUBIC_TO, 0.39f, 0.39f, 0.87f, 0.59f, 1.43f, 0.59f, CLOSE CANVAS_DIMENSIONS, 16, -MOVE_TO, 8, 2.5f, -R_CUBIC_TO, 1.93f, 0, 3.5f, 1.57f, 3.5f, 3.5f, -R_CUBIC_TO, 0, 1.3f, -0.79f, 2.36f, -1.79f, 3.7f, -R_CUBIC_TO, -0.57f, 0.77f, -1.19f, 1.6f, -1.71f, 2.57f, -R_CUBIC_TO, -0.52f, -0.97f, -1.14f, -1.81f, -1.71f, -2.57f, -CUBIC_TO, 5.29f, 8.36f, 4.5f, 7.3f, 4.5f, 6, -R_CUBIC_TO, 0, -1.93f, 1.57f, -3.5f, 3.5f, -3.5f, -MOVE_TO, 8, 1, -CUBIC_TO, 5.24f, 1, 3, 3.24f, 3, 6, -R_CUBIC_TO, 0, 3.22f, 3.22f, 5, 4.32f, 8.5f, -R_CUBIC_TO, 0.08f, 0.25f, 0.33f, 0.5f, 0.68f, 0.5f, -R_CUBIC_TO, 0.35f, 0, 0.6f, -0.25f, 0.68f, -0.5f, -CUBIC_TO, 9.78f, 11, 13, 9.22f, 13, 6, -R_CUBIC_TO, 0, -2.76f, -2.24f, -5, -5, -5, +MOVE_TO, 8, 14.69f, +R_ARC_TO, 0.91f, 0.91f, 0, 0, 1, -0.55f, -0.17f, +R_ARC_TO, 1.14f, 1.14f, 0, 0, 1, -0.37f, -0.49f, +R_CUBIC_TO, -0.31f, -0.71f, -0.6f, -1.3f, -0.87f, -1.78f, +R_ARC_TO, 13.96f, 13.96f, 0, 0, 0, -1.1f, -1.62f, +R_ARC_TO, 14.19f, 14.19f, 0, 0, 1, -1.38f, -2.09f, +R_CUBIC_TO, -0.35f, -0.67f, -0.53f, -1.49f, -0.53f, -2.45f, +R_CUBIC_TO, 0, -1.33f, 0.47f, -2.46f, 1.4f, -3.4f, +CUBIC_TO, 5.53f, 1.75f, 6.66f, 1.28f, 8, 1.28f, +R_CUBIC_TO, 1.34f, 0, 2.47f, 0.47f, 3.41f, 1.4f, +R_CUBIC_TO, 0.93f, 0.93f, 1.4f, 2.07f, 1.4f, 3.41f, +R_CUBIC_TO, 0, 1.02f, -0.2f, 1.87f, -0.58f, 2.54f, +R_CUBIC_TO, -0.39f, 0.67f, -0.83f, 1.33f, -1.33f, 1.98f, +ARC_TO, 15.23f, 15.23f, 0, 0, 0, 9.77f, 12.25f, +R_ARC_TO, 15.91f, 15.91f, 0, 0, 0, -0.85f, 1.77f, +R_ARC_TO, 1.29f, 1.29f, 0, 0, 1, -0.37f, 0.49f, +R_ARC_TO, 0.85f, 0.85f, 0, 0, 1, -0.54f, 0.18f, CLOSE, -NEW_PATH, -MOVE_TO, 8, 7.5f, -ARC_TO, 1.75f, 1.75f, 0, 1, 0, 8, 4, -R_ARC_TO, 1.75f, 1.75f, 0, 0, 0, 0, 3.5f, +MOVE_TO, 8, 12.11f, +R_CUBIC_TO, 0.18f, -0.38f, 0.39f, -0.75f, 0.62f, -1.12f, +R_CUBIC_TO, 0.23f, -0.37f, 0.56f, -0.83f, 0.98f, -1.38f, +R_CUBIC_TO, 0.46f, -0.59f, 0.84f, -1.13f, 1.13f, -1.64f, +R_CUBIC_TO, 0.29f, -0.5f, 0.44f, -1.13f, 0.44f, -1.89f, +R_CUBIC_TO, 0, -0.87f, -0.31f, -1.61f, -0.93f, -2.23f, +R_ARC_TO, 3.06f, 3.06f, 0, 0, 0, -2.25f, -0.93f, +R_CUBIC_TO, -0.87f, 0, -1.62f, 0.31f, -2.24f, 0.93f, +R_ARC_TO, 3.06f, 3.06f, 0, 0, 0, -0.93f, 2.23f, +R_CUBIC_TO, 0, 0.75f, 0.15f, 1.38f, 0.45f, 1.89f, +R_CUBIC_TO, 0.3f, 0.51f, 0.67f, 1.05f, 1.12f, 1.64f, +R_CUBIC_TO, 0.42f, 0.55f, 0.75f, 1.01f, 0.98f, 1.38f, +R_CUBIC_TO, 0.23f, 0.37f, 0.44f, 0.74f, 0.63f, 1.12f, CLOSE, -NEW_PATH \ No newline at end of file +R_MOVE_TO, 0, -4.39f, +R_CUBIC_TO, 0.45f, 0, 0.84f, -0.16f, 1.16f, -0.47f, +R_CUBIC_TO, 0.32f, -0.32f, 0.48f, -0.7f, 0.48f, -1.15f, +R_CUBIC_TO, 0, -0.46f, -0.16f, -0.84f, -0.47f, -1.16f, +R_ARC_TO, 1.56f, 1.56f, 0, 0, 0, -1.15f, -0.48f, +R_CUBIC_TO, -0.45f, 0, -0.84f, 0.16f, -1.16f, 0.47f, +R_CUBIC_TO, -0.32f, 0.31f, -0.48f, 0.7f, -0.48f, 1.15f, +R_CUBIC_TO, 0, 0.45f, 0.16f, 0.84f, 0.47f, 1.16f, +R_CUBIC_TO, 0.31f, 0.32f, 0.7f, 0.48f, 1.15f, 0.48f, +CLOSE
diff --git a/components/vector_icons/media_router_active_chrome_refresh.icon b/components/vector_icons/media_router_active_chrome_refresh.icon index dfbfcb0b..d0cb562 100644 --- a/components/vector_icons/media_router_active_chrome_refresh.icon +++ b/components/vector_icons/media_router_active_chrome_refresh.icon
@@ -53,5 +53,4 @@ R_ARC_TO, 7.86f, 7.86f, 0, 0, 0, -1.73f, -2.54f, R_ARC_TO, 7.86f, 7.86f, 0, 0, 0, -2.54f, -1.73f, ARC_TO, 7.7f, 7.7f, 0, 0, 0, 2, 8, -CLOSE, -NEW_PATH \ No newline at end of file +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/media_router_idle_chrome_refresh.icon b/components/vector_icons/media_router_idle_chrome_refresh.icon index fc0fa54..c377e31 100644 --- a/components/vector_icons/media_router_idle_chrome_refresh.icon +++ b/components/vector_icons/media_router_idle_chrome_refresh.icon
@@ -46,6 +46,5 @@ R_ARC_TO, 7.86f, 7.86f, 0, 0, 0, -1.73f, -2.54f, R_ARC_TO, 7.86f, 7.86f, 0, 0, 0, -2.54f, -1.73f, ARC_TO, 7.7f, 7.7f, 0, 0, 0, 2, 8, -CLOSE, -NEW_PATH +CLOSE
diff --git a/components/vector_icons/mic_chrome_refresh.icon b/components/vector_icons/mic_chrome_refresh.icon index 3c61761..c1b12a85 100644 --- a/components/vector_icons/mic_chrome_refresh.icon +++ b/components/vector_icons/mic_chrome_refresh.icon
@@ -122,4 +122,4 @@ R_V_LINE_TO, 3.97f, R_CUBIC_TO, 0, 0.22f, 0.08f, 0.4f, 0.22f, 0.55f, ARC_TO, 0.74f, 0.74f, 0, 0, 0, 8, 8.4f, -CLOSE \ No newline at end of file +CLOSE
diff --git a/components/vector_icons/mic_off_chrome_refresh.icon b/components/vector_icons/mic_off_chrome_refresh.icon index aca30b9..c4397abd 100644 --- a/components/vector_icons/mic_off_chrome_refresh.icon +++ b/components/vector_icons/mic_off_chrome_refresh.icon
@@ -145,4 +145,4 @@ LINE_TO, 1.48f, 3.15f, R_LINE_TO, 0.89f, -0.89f, R_LINE_TO, 11.3f, 11.32f, -CLOSE \ No newline at end of file +CLOSE
diff --git a/components/vector_icons/midi_chrome_refresh.icon b/components/vector_icons/midi_chrome_refresh.icon index 9b51ff25..8f94e6b 100644 --- a/components/vector_icons/midi_chrome_refresh.icon +++ b/components/vector_icons/midi_chrome_refresh.icon
@@ -90,3 +90,47 @@ R_ARC_TO, 0.52f, 0.52f, 0, 0, 1, -0.38f, 0.15f, R_H_LINE_TO, -0.46f, CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3.72f, 13.92f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.16f, -0.48f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.48f, -1.16f, +R_V_LINE_TO, -8.57f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f, +R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, 1.16f, -0.48f, +R_H_LINE_TO, 8.57f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.16f, +R_V_LINE_TO, 8.57f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.16f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f, +CLOSE, +R_MOVE_TO, 0, -1.64f, +R_H_LINE_TO, 1.73f, +R_V_LINE_TO, -2.61f, +R_H_LINE_TO, -0.32f, +R_ARC_TO, 0.47f, 0.47f, 0, 0, 1, -0.48f, -0.48f, +V_LINE_TO, 3.72f, +R_H_LINE_TO, -0.93f, +CLOSE, +R_MOVE_TO, 6.84f, 0, +R_H_LINE_TO, 1.73f, +R_V_LINE_TO, -8.57f, +R_H_LINE_TO, -0.93f, +R_V_LINE_TO, 5.48f, +R_ARC_TO, 0.47f, 0.47f, 0, 0, 1, -0.48f, 0.48f, +R_H_LINE_TO, -0.32f, +CLOSE, +R_MOVE_TO, -4.01f, 0, +R_H_LINE_TO, 2.91f, +R_V_LINE_TO, -2.61f, +R_H_LINE_TO, -0.32f, +R_ARC_TO, 0.46f, 0.46f, 0, 0, 1, -0.34f, -0.14f, +R_ARC_TO, 0.45f, 0.45f, 0, 0, 1, -0.14f, -0.34f, +V_LINE_TO, 3.72f, +H_LINE_TO, 7.34f, +V_LINE_TO, 9.21f, +R_ARC_TO, 0.44f, 0.44f, 0, 0, 1, -0.14f, 0.33f, +R_ARC_TO, 0.47f, 0.47f, 0, 0, 1, -0.34f, 0.13f, +R_H_LINE_TO, -0.32f, +CLOSE
diff --git a/components/vector_icons/midi_off_chrome_refresh.icon b/components/vector_icons/midi_off_chrome_refresh.icon index d84adec..74cd14fe1 100644 --- a/components/vector_icons/midi_off_chrome_refresh.icon +++ b/components/vector_icons/midi_off_chrome_refresh.icon
@@ -103,3 +103,55 @@ R_H_LINE_TO, 0.12f, R_LINE_TO, -0.12f, -0.13f, CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 13.16f, 14.9f, +R_LINE_TO, -0.99f, -0.98f, +R_ARC_TO, 0.24f, 0.24f, 0, 0, 1, -0.07f, 0.01f, +H_LINE_TO, 3.72f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, -0.48f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.48f, -1.16f, +V_LINE_TO, 3.9f, +R_CUBIC_TO, 0, -0.02f, 0, -0.04f, 0.01f, -0.07f, +R_LINE_TO, -0.98f, -0.99f, +R_LINE_TO, 0.94f, -0.95f, +R_LINE_TO, 12.06f, 12.06f, +CLOSE, +R_MOVE_TO, 0.77f, -3.01f, +R_LINE_TO, -1.64f, -1.64f, +V_LINE_TO, 3.72f, +R_H_LINE_TO, -0.93f, +V_LINE_TO, 9.21f, +R_ARC_TO, 0.1f, 0.1f, 0, 0, 1, -0.01f, 0.04f, +R_CUBIC_TO, -0.01f, 0.02f, -0.02f, 0.02f, -0.02f, 0.02f, +LINE_TO, 8.66f, 6.63f, +V_LINE_TO, 3.72f, +H_LINE_TO, 7.34f, +V_LINE_TO, 5.3f, +LINE_TO, 4.12f, 2.08f, +R_H_LINE_TO, 8.17f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.16f, +CLOSE, +R_MOVE_TO, -10.21f, 0.4f, +R_H_LINE_TO, 1.73f, +R_V_LINE_TO, -2.61f, +R_H_LINE_TO, -0.32f, +R_ARC_TO, 0.45f, 0.45f, 0, 0, 1, -0.34f, -0.14f, +R_ARC_TO, 0.45f, 0.45f, 0, 0, 1, -0.14f, -0.34f, +V_LINE_TO, 6.4f, +R_LINE_TO, -0.93f, -0.93f, +CLOSE, +R_MOVE_TO, 2.83f, 0, +R_H_LINE_TO, 2.91f, +R_V_LINE_TO, -1.08f, +LINE_TO, 7.27f, 9.02f, +R_V_LINE_TO, 0.3f, +R_ARC_TO, 0.37f, 0.37f, 0, 0, 1, -0.14f, 0.25f, +R_ARC_TO, 0.41f, 0.41f, 0, 0, 1, -0.27f, 0.1f, +R_H_LINE_TO, -0.32f, +CLOSE, +R_MOVE_TO, 3.81f, -0.03f, +R_H_LINE_TO, 0.03f, +R_LINE_TO, -0.03f, -0.04f, +CLOSE
diff --git a/components/vector_icons/not_secure_warning_chrome_refresh.icon b/components/vector_icons/not_secure_warning_chrome_refresh.icon index ec374c5..7cfc460 100644 --- a/components/vector_icons/not_secure_warning_chrome_refresh.icon +++ b/components/vector_icons/not_secure_warning_chrome_refresh.icon
@@ -28,8 +28,7 @@ V_LINE_TO, 13.2f, H_LINE_TO, 14.83f, V_LINE_TO, 20.13f, -CLOSE, -NEW_PATH +CLOSE CANVAS_DIMENSIONS, 20, MOVE_TO, 0.86f, 17.09f, @@ -80,5 +79,4 @@ CUBIC_TO, 8.75f, 10.84f, 8.41f, 10.5f, 8, 10.5f, CUBIC_TO, 7.59f, 10.5f, 7.25f, 10.84f, 7.25f, 11.25f, CUBIC_TO, 7.25f, 11.66f, 7.59f, 12, 8, 12, -CLOSE, -NEW_PATH +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/notifications_chrome_refresh.icon b/components/vector_icons/notifications_chrome_refresh.icon index 02f0a93..409cd42 100644 --- a/components/vector_icons/notifications_chrome_refresh.icon +++ b/components/vector_icons/notifications_chrome_refresh.icon
@@ -2,6 +2,43 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 3.66f, 19.17f, +R_V_LINE_TO, -2.27f, +R_H_LINE_TO, 2.07f, +R_V_LINE_TO, -6.78f, +R_CUBIC_TO, 0, -1.44f, 0.43f, -2.71f, 1.28f, -3.84f, +R_ARC_TO, 5.88f, 5.88f, 0, 0, 1, 3.36f, -2.21f, +V_LINE_TO, 3.41f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.84f, 0.48f, -1.16f, +R_CUBIC_TO, 0.32f, -0.32f, 0.71f, -0.48f, 1.16f, -0.48f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +R_V_LINE_TO, 0.66f, +R_CUBIC_TO, 1.39f, 0.34f, 2.5f, 1.08f, 3.36f, 2.2f, +R_CUBIC_TO, 0.85f, 1.12f, 1.28f, 2.4f, 1.28f, 3.84f, +R_V_LINE_TO, 6.78f, +R_H_LINE_TO, 2.08f, +R_V_LINE_TO, 2.27f, +CLOSE, +R_MOVE_TO, 8.34f, -7.66f, +CLOSE, +R_MOVE_TO, 0.01f, 10.69f, +R_CUBIC_TO, -0.57f, 0, -1.06f, -0.2f, -1.46f, -0.6f, +R_ARC_TO, 1.99f, 1.99f, 0, 0, 1, -0.61f, -1.46f, +R_H_LINE_TO, 4.14f, +R_CUBIC_TO, 0, 0.57f, -0.2f, 1.06f, -0.6f, 1.46f, +R_CUBIC_TO, -0.41f, 0.4f, -0.89f, 0.61f, -1.46f, 0.61f, +CLOSE, +MOVE_TO, 8, 16.9f, +R_H_LINE_TO, 8, +R_V_LINE_TO, -6.78f, +R_CUBIC_TO, 0, -1.1f, -0.39f, -2.04f, -1.18f, -2.83f, +R_CUBIC_TO, -0.78f, -0.78f, -1.72f, -1.17f, -2.82f, -1.17f, +R_CUBIC_TO, -1.1f, 0, -2.04f, 0.39f, -2.82f, 1.17f, +CUBIC_TO, 8.39f, 8.08f, 8, 9.02f, 8, 10.12f, +CLOSE + CANVAS_DIMENSIONS, 20, MOVE_TO, 3.72f, 15.65f, R_V_LINE_TO, -1.73f, @@ -40,29 +77,38 @@ CLOSE CANVAS_DIMENSIONS, 16, -MOVE_TO, 12, 11, -V_LINE_TO, 7, -R_CUBIC_TO, 0, -1.95f, -1.4f, -3.57f, -3.25f, -3.92f, +MOVE_TO, 2.66f, 12.67f, +R_V_LINE_TO, -1.63f, +R_H_LINE_TO, 0.9f, +V_LINE_TO, 7.39f, +R_CUBIC_TO, 0, -1.03f, 0.32f, -1.96f, 0.95f, -2.78f, +R_ARC_TO, 3.95f, 3.95f, 0, 0, 1, 2.47f, -1.52f, R_V_LINE_TO, -0.83f, -R_CUBIC_TO, 0, -0.41f, -0.34f, -0.75f, -0.75f, -0.75f, -R_CUBIC_TO, -0.41f, 0, -0.75f, 0.34f, -0.75f, 0.75f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 1, 0.3f, -0.72f, +ARC_TO, 0.97f, 0.97f, 0, 0, 1, 8, 1.24f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 1, 0.72f, 0.3f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 1, 0.3f, 0.72f, R_V_LINE_TO, 0.83f, -ARC_TO, 4, 4, 0, 0, 0, 4, 7, -R_V_LINE_TO, 4, -H_LINE_TO, 3, -R_V_LINE_TO, 1.5f, -R_H_LINE_TO, 10, -V_LINE_TO, 11, -R_H_LINE_TO, -1, +R_CUBIC_TO, 1.03f, 0.2f, 1.85f, 0.7f, 2.48f, 1.51f, +R_CUBIC_TO, 0.63f, 0.81f, 0.94f, 1.74f, 0.94f, 2.79f, +R_V_LINE_TO, 3.65f, +R_H_LINE_TO, 0.91f, +R_V_LINE_TO, 1.63f, CLOSE, -R_MOVE_TO, -1.5f, 0, -R_H_LINE_TO, -5, -V_LINE_TO, 7, -R_ARC_TO, 2.5f, 2.5f, 0, 0, 1, 5, 0, -R_V_LINE_TO, 4, +MOVE_TO, 8, 7.72f, CLOSE, -MOVE_TO, 8, 14.5f, -R_CUBIC_TO, 0.69f, 0, 1.25f, -0.56f, 1.25f, -1.25f, -R_H_LINE_TO, -2.5f, -R_CUBIC_TO, 0, 0.69f, 0.56f, 1.25f, 1.25f, 1.25f, -CLOSE \ No newline at end of file +R_MOVE_TO, 0.01f, 7, +R_CUBIC_TO, -0.36f, 0, -0.67f, -0.12f, -0.93f, -0.38f, +R_ARC_TO, 1.26f, 1.26f, 0, 0, 1, -0.38f, -0.92f, +R_H_LINE_TO, 2.62f, +R_CUBIC_TO, 0, 0.36f, -0.13f, 0.67f, -0.38f, 0.93f, +R_CUBIC_TO, -0.26f, 0.25f, -0.56f, 0.38f, -0.92f, 0.38f, +CLOSE, +R_MOVE_TO, -2.81f, -3.68f, +R_H_LINE_TO, 5.6f, +V_LINE_TO, 7.39f, +R_CUBIC_TO, 0, -0.78f, -0.27f, -1.44f, -0.82f, -1.98f, +ARC_TO, 2.7f, 2.7f, 0, 0, 0, 8, 4.59f, +R_CUBIC_TO, -0.78f, 0, -1.44f, 0.27f, -1.98f, 0.82f, +R_ARC_TO, 2.7f, 2.7f, 0, 0, 0, -0.82f, 1.98f, +CLOSE
diff --git a/components/vector_icons/notifications_off_chrome_refresh.icon b/components/vector_icons/notifications_off_chrome_refresh.icon index 9e9eaff..7182124 100644 --- a/components/vector_icons/notifications_off_chrome_refresh.icon +++ b/components/vector_icons/notifications_off_chrome_refresh.icon
@@ -2,6 +2,52 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 3.66f, 19.17f, +R_V_LINE_TO, -2.27f, +R_H_LINE_TO, 2.07f, +R_V_LINE_TO, -6.78f, +R_ARC_TO, 6.5f, 6.5f, 0, 0, 1, 0.97f, -3.43f, +R_LINE_TO, 1.7f, 1.7f, +R_ARC_TO, 4, 4, 0, 0, 0, -0.3f, 0.84f, +R_ARC_TO, 3.92f, 3.92f, 0, 0, 0, -0.1f, 0.88f, +R_V_LINE_TO, 6.78f, +R_H_LINE_TO, 5.97f, +LINE_TO, 1.25f, 4.17f, +LINE_TO, 2.71f, 2.71f, +R_LINE_TO, 18.68f, 18.68f, +R_LINE_TO, -1.46f, 1.46f, +R_LINE_TO, -3.72f, -3.68f, +CLOSE, +MOVE_TO, 18.27f, 15.3f, +LINE_TO, 16, 13.02f, +R_V_LINE_TO, -2.9f, +R_CUBIC_TO, 0, -1.1f, -0.39f, -2.04f, -1.18f, -2.83f, +R_CUBIC_TO, -0.78f, -0.78f, -1.72f, -1.17f, -2.82f, -1.17f, +R_CUBIC_TO, -0.42f, 0, -0.81f, 0.06f, -1.18f, 0.19f, +R_ARC_TO, 4.09f, 4.09f, 0, 0, 0, -1.01f, 0.52f, +LINE_TO, 8.13f, 5.16f, +R_ARC_TO, 9.33f, 9.33f, 0, 0, 1, 1.04f, -0.64f, +R_CUBIC_TO, 0.37f, -0.2f, 0.77f, -0.34f, 1.19f, -0.44f, +V_LINE_TO, 3.41f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.84f, 0.48f, -1.16f, +R_CUBIC_TO, 0.32f, -0.32f, 0.71f, -0.48f, 1.16f, -0.48f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +R_V_LINE_TO, 0.66f, +R_CUBIC_TO, 1.33f, 0.33f, 2.43f, 1.06f, 3.32f, 2.17f, +R_CUBIC_TO, 0.88f, 1.11f, 1.32f, 2.41f, 1.32f, 3.88f, +CLOSE, +R_MOVE_TO, -7.3f, -1.39f, +CLOSE, +R_MOVE_TO, 1.04f, 8.29f, +R_CUBIC_TO, -0.57f, 0, -1.06f, -0.2f, -1.46f, -0.6f, +R_ARC_TO, 1.99f, 1.99f, 0, 0, 1, -0.61f, -1.46f, +R_H_LINE_TO, 4.14f, +R_CUBIC_TO, 0, 0.57f, -0.2f, 1.06f, -0.6f, 1.46f, +R_CUBIC_TO, -0.41f, 0.4f, -0.89f, 0.61f, -1.46f, 0.61f, +CLOSE + CANVAS_DIMENSIONS, 20, MOVE_TO, 3.72f, 15.65f, R_V_LINE_TO, -1.73f, @@ -47,8 +93,6 @@ R_H_LINE_TO, 3.11f, R_CUBIC_TO, 0, 0.43f, -0.15f, 0.8f, -0.46f, 1.11f, R_CUBIC_TO, -0.3f, 0.3f, -0.67f, 0.45f, -1.1f, 0.45f, -CLOSE, -R_MOVE_TO, 0.67f, -9.73f, CLOSE CANVAS_DIMENSIONS, 16,
diff --git a/components/vector_icons/page_info_content_paste_chrome_refresh.icon b/components/vector_icons/page_info_content_paste_chrome_refresh.icon index ca8d9a2..dbfb2897 100644 --- a/components/vector_icons/page_info_content_paste_chrome_refresh.icon +++ b/components/vector_icons/page_info_content_paste_chrome_refresh.icon
@@ -39,4 +39,80 @@ ARC_TO, 0.96f, 0.96f, 0, 0, 0, 11, 4, R_CUBIC_TO, 0, 0.28f, 0.1f, 0.52f, 0.29f, 0.71f, R_CUBIC_TO, 0.19f, 0.19f, 0.43f, 0.29f, 0.71f, 0.29f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.56f, 17.18f, +R_CUBIC_TO, -0.47f, 0, -0.88f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 4.57f, +R_CUBIC_TO, 0, -0.48f, 0.17f, -0.88f, 0.51f, -1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, 1.22f, -0.51f, +R_H_LINE_TO, 3.38f, +R_CUBIC_TO, 0.13f, -0.44f, 0.38f, -0.8f, 0.76f, -1.09f, +R_CUBIC_TO, 0.38f, -0.29f, 0.81f, -0.43f, 1.31f, -0.43f, +R_CUBIC_TO, 0.49f, 0, 0.92f, 0.14f, 1.3f, 0.43f, +R_CUBIC_TO, 0.38f, 0.28f, 0.63f, 0.65f, 0.77f, 1.09f, +R_H_LINE_TO, 3.38f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +R_V_LINE_TO, 10.88f, +R_CUBIC_TO, 0, 0.47f, -0.17f, 0.88f, -0.51f, 1.22f, +R_CUBIC_TO, -0.34f, 0.34f, -0.75f, 0.51f, -1.22f, 0.51f, +CLOSE, +R_MOVE_TO, 0, -1.73f, +H_LINE_TO, 15.44f, +V_LINE_TO, 4.57f, +R_H_LINE_TO, -1.46f, +R_V_LINE_TO, 2.58f, +H_LINE_TO, 6.02f, +V_LINE_TO, 4.57f, +H_LINE_TO, 4.56f, +CLOSE, +MOVE_TO, 10, 4.5f, +R_CUBIC_TO, 0.21f, 0, 0.39f, -0.07f, 0.54f, -0.21f, +R_ARC_TO, 0.72f, 0.72f, 0, 0, 0, 0.22f, -0.53f, +R_CUBIC_TO, 0, -0.21f, -0.07f, -0.39f, -0.21f, -0.53f, +ARC_TO, 0.72f, 0.72f, 0, 0, 0, 10, 3, +R_CUBIC_TO, -0.21f, 0, -0.39f, 0.07f, -0.53f, 0.22f, +R_ARC_TO, 0.72f, 0.72f, 0, 0, 0, -0.22f, 0.53f, +R_CUBIC_TO, 0, 0.21f, 0.07f, 0.39f, 0.22f, 0.54f, +R_CUBIC_TO, 0.14f, 0.14f, 0.32f, 0.22f, 0.53f, 0.22f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3.72f, 13.92f, +R_CUBIC_TO, -0.45f, 0, -0.84f, -0.16f, -1.16f, -0.48f, +R_CUBIC_TO, -0.32f, -0.32f, -0.48f, -0.71f, -0.48f, -1.16f, +R_V_LINE_TO, -8.57f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.84f, 0.48f, -1.16f, +R_CUBIC_TO, 0.32f, -0.32f, 0.71f, -0.48f, 1.16f, -0.48f, +R_H_LINE_TO, 2.49f, +R_CUBIC_TO, 0.13f, -0.36f, 0.35f, -0.66f, 0.68f, -0.89f, +ARC_TO, 1.86f, 1.86f, 0, 0, 1, 8, 0.83f, +R_CUBIC_TO, 0.41f, 0, 0.78f, 0.12f, 1.11f, 0.35f, +R_CUBIC_TO, 0.33f, 0.23f, 0.56f, 0.53f, 0.69f, 0.89f, +R_H_LINE_TO, 2.49f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +R_V_LINE_TO, 8.57f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.84f, -0.48f, 1.16f, +R_CUBIC_TO, -0.32f, 0.32f, -0.71f, 0.48f, -1.16f, 0.48f, +CLOSE, +R_MOVE_TO, 0, -1.64f, +R_H_LINE_TO, 8.57f, +R_V_LINE_TO, -8.57f, +R_H_LINE_TO, -1.13f, +R_V_LINE_TO, 2.15f, +H_LINE_TO, 4.85f, +V_LINE_TO, 3.72f, +H_LINE_TO, 3.72f, +CLOSE, +MOVE_TO, 8, 3.57f, +R_ARC_TO, 0.58f, 0.58f, 0, 0, 0, 0.43f, -0.17f, +R_ARC_TO, 0.56f, 0.56f, 0, 0, 0, 0.18f, -0.42f, +R_ARC_TO, 0.59f, 0.59f, 0, 0, 0, -0.6f, -0.61f, +R_ARC_TO, 0.6f, 0.6f, 0, 0, 0, -0.43f, 0.17f, +R_ARC_TO, 0.57f, 0.57f, 0, 0, 0, -0.18f, 0.43f, +R_ARC_TO, 0.59f, 0.59f, 0, 0, 0, 0.6f, 0.6f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/page_info_content_paste_off_chrome_refresh.icon b/components/vector_icons/page_info_content_paste_off_chrome_refresh.icon index 9b4b3cb..90704ea2 100644 --- a/components/vector_icons/page_info_content_paste_off_chrome_refresh.icon +++ b/components/vector_icons/page_info_content_paste_off_chrome_refresh.icon
@@ -42,4 +42,86 @@ LINE_TO, 21.49f, 21.39f, R_LINE_TO, -1.48f, 1.48f, R_LINE_TO, -1.66f, -1.65f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 17.17f, 14.86f, +R_LINE_TO, -1.73f, -1.73f, +V_LINE_TO, 4.57f, +R_H_LINE_TO, -1.46f, +R_V_LINE_TO, 2.58f, +H_LINE_TO, 9.45f, +LINE_TO, 5.15f, 2.84f, +R_LINE_TO, 2.79f, 0.02f, +R_CUBIC_TO, 0.17f, -0.47f, 0.43f, -0.84f, 0.78f, -1.12f, +R_CUBIC_TO, 0.35f, -0.28f, 0.78f, -0.42f, 1.29f, -0.42f, +R_CUBIC_TO, 0.5f, 0, 0.93f, 0.14f, 1.29f, 0.41f, +R_CUBIC_TO, 0.36f, 0.28f, 0.62f, 0.65f, 0.78f, 1.11f, +R_H_LINE_TO, 3.38f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +CLOSE, +MOVE_TO, 10, 4.5f, +R_CUBIC_TO, 0.21f, 0, 0.39f, -0.07f, 0.54f, -0.21f, +R_ARC_TO, 0.72f, 0.72f, 0, 0, 0, 0.22f, -0.53f, +R_CUBIC_TO, 0, -0.21f, -0.07f, -0.39f, -0.21f, -0.53f, +ARC_TO, 0.72f, 0.72f, 0, 0, 0, 10, 3, +R_CUBIC_TO, -0.21f, 0, -0.39f, 0.07f, -0.53f, 0.22f, +R_ARC_TO, 0.72f, 0.72f, 0, 0, 0, -0.22f, 0.53f, +R_CUBIC_TO, 0, 0.21f, 0.07f, 0.39f, 0.22f, 0.54f, +R_CUBIC_TO, 0.14f, 0.14f, 0.32f, 0.22f, 0.53f, 0.22f, +CLOSE, +R_MOVE_TO, 3.31f, 10.96f, +R_LINE_TO, -8.75f, -8.75f, +R_V_LINE_TO, 8.75f, +CLOSE, +R_MOVE_TO, -8.75f, 1.73f, +R_CUBIC_TO, -0.47f, 0, -0.88f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 4.98f, +LINE_TO, 1.66f, 3.81f, +LINE_TO, 2.78f, 2.7f, +R_LINE_TO, 14.52f, 14.52f, +R_LINE_TO, -1.11f, 1.11f, +R_LINE_TO, -1.15f, -1.15f, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 13.92f, 11.85f, +R_LINE_TO, -1.64f, -1.63f, +V_LINE_TO, 3.72f, +R_H_LINE_TO, -1.13f, +R_V_LINE_TO, 2.15f, +R_H_LINE_TO, -3.23f, +LINE_TO, 4.15f, 2.08f, +R_LINE_TO, 2.06f, 0.02f, +R_CUBIC_TO, 0.16f, -0.39f, 0.39f, -0.7f, 0.69f, -0.92f, +R_CUBIC_TO, 0.3f, -0.23f, 0.67f, -0.34f, 1.11f, -0.34f, +R_CUBIC_TO, 0.42f, 0, 0.79f, 0.11f, 1.1f, 0.34f, +R_CUBIC_TO, 0.31f, 0.22f, 0.54f, 0.53f, 0.7f, 0.91f, +R_H_LINE_TO, 2.49f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +CLOSE, +MOVE_TO, 8, 3.57f, +R_ARC_TO, 0.58f, 0.58f, 0, 0, 0, 0.43f, -0.17f, +R_ARC_TO, 0.56f, 0.56f, 0, 0, 0, 0.18f, -0.42f, +R_ARC_TO, 0.59f, 0.59f, 0, 0, 0, -0.6f, -0.61f, +R_ARC_TO, 0.6f, 0.6f, 0, 0, 0, -0.43f, 0.17f, +R_ARC_TO, 0.57f, 0.57f, 0, 0, 0, -0.18f, 0.43f, +R_ARC_TO, 0.59f, 0.59f, 0, 0, 0, 0.6f, 0.6f, +CLOSE, +R_MOVE_TO, 2.58f, 8.72f, +LINE_TO, 3.72f, 5.42f, +R_V_LINE_TO, 6.86f, +CLOSE, +R_MOVE_TO, -6.86f, 1.64f, +R_CUBIC_TO, -0.45f, 0, -0.84f, -0.16f, -1.16f, -0.48f, +R_CUBIC_TO, -0.32f, -0.32f, -0.48f, -0.71f, -0.48f, -1.16f, +V_LINE_TO, 3.79f, +R_LINE_TO, -0.97f, -0.98f, +R_LINE_TO, 0.94f, -0.94f, +R_LINE_TO, 12.06f, 12.05f, +R_LINE_TO, -0.95f, 0.95f, +R_LINE_TO, -0.94f, -0.94f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/photo_chrome_refresh.icon b/components/vector_icons/photo_chrome_refresh.icon index 694a26c..d9fa5e0 100644 --- a/components/vector_icons/photo_chrome_refresh.icon +++ b/components/vector_icons/photo_chrome_refresh.icon
@@ -2,31 +2,89 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 5.07f, 21.2f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 5.07f, +R_CUBIC_TO, 0, -0.63f, 0.22f, -1.16f, 0.66f, -1.61f, +R_CUBIC_TO, 0.45f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f, +H_LINE_TO, 18.93f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +V_LINE_TO, 18.93f, +R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, +R_CUBIC_TO, -0.44f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, +CLOSE, +R_MOVE_TO, 0, -2.27f, +R_H_LINE_TO, 13.86f, +V_LINE_TO, 5.07f, +H_LINE_TO, 5.07f, +CLOSE, +R_MOVE_TO, 0.83f, -1.86f, +R_H_LINE_TO, 12.2f, +LINE_TO, 14.25f, 11.88f, +R_LINE_TO, -3, 4, +R_LINE_TO, -2.25f, -3, +CLOSE, +R_MOVE_TO, -0.83f, 1.86f, +V_LINE_TO, 5.07f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.56f, 17.17f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.22f, +V_LINE_TO, 4.56f, +R_CUBIC_TO, 0, -0.47f, 0.17f, -0.87f, 0.5f, -1.22f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, 1.22f, -0.51f, +H_LINE_TO, 15.44f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.5f, 0.75f, 0.5f, 1.22f, +V_LINE_TO, 15.44f, +R_CUBIC_TO, 0, 0.47f, -0.17f, 0.88f, -0.5f, 1.22f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, -1.22f, 0.51f, +CLOSE, +R_MOVE_TO, 0, -1.73f, +H_LINE_TO, 15.44f, +V_LINE_TO, 4.56f, +H_LINE_TO, 4.56f, +CLOSE, +R_MOVE_TO, 0.86f, -1.38f, +R_H_LINE_TO, 9.17f, +LINE_TO, 11.5f, 9.9f, +R_LINE_TO, -2.25f, 3, +R_LINE_TO, -1.5f, -2, +CLOSE, +MOVE_TO, 4.56f, 15.44f, +V_LINE_TO, 4.56f, +CLOSE + CANVAS_DIMENSIONS, 16, -MOVE_TO, 3.65f, 13.73f, -R_CUBIC_TO, -0.38f, 0, -0.71f, -0.14f, -0.98f, -0.41f, -R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.4f, -0.97f, -V_LINE_TO, 3.65f, -R_CUBIC_TO, 0, -0.37f, 0.13f, -0.7f, 0.4f, -0.97f, -R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.41f, 0.98f, -0.41f, -R_H_LINE_TO, 8.7f, -R_CUBIC_TO, 0.38f, 0, 0.71f, 0.14f, 0.98f, 0.41f, -R_CUBIC_TO, 0.27f, 0.27f, 0.4f, 0.6f, 0.4f, 0.97f, -R_V_LINE_TO, 8.7f, -R_CUBIC_TO, 0, 0.38f, -0.13f, 0.7f, -0.4f, 0.97f, -R_CUBIC_TO, -0.27f, 0.27f, -0.6f, 0.41f, -0.98f, 0.41f, +MOVE_TO, 3.72f, 13.92f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.48f, +R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, -0.48f, -1.16f, +R_V_LINE_TO, -8.57f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.83f, 0.48f, -1.16f, +R_CUBIC_TO, 0.32f, -0.32f, 0.7f, -0.48f, 1.16f, -0.48f, +R_H_LINE_TO, 8.57f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, +R_V_LINE_TO, 8.57f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.16f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f, CLOSE, -R_MOVE_TO, 0, -1.38f, -R_H_LINE_TO, 8.7f, -V_LINE_TO, 3.65f, -H_LINE_TO, 3.65f, +R_MOVE_TO, 0, -1.64f, +R_H_LINE_TO, 8.57f, +R_V_LINE_TO, -8.57f, +R_H_LINE_TO, -8.57f, CLOSE, -R_MOVE_TO, 0.68f, -1.11f, -R_H_LINE_TO, 7.34f, -LINE_TO, 9.2f, 7.92f, -LINE_TO, 7.4f, 10.32f, +R_MOVE_TO, 0.52f, -0.97f, +R_H_LINE_TO, 7.52f, +R_LINE_TO, -2.56f, -3.5f, +R_LINE_TO, -1.8f, 2.4f, R_LINE_TO, -1.2f, -1.6f, CLOSE, -R_MOVE_TO, -0.68f, 1.11f, -V_LINE_TO, 3.65f, +R_MOVE_TO, -0.52f, 0.97f, +R_V_LINE_TO, -8.57f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/photo_off_chrome_refresh.icon b/components/vector_icons/photo_off_chrome_refresh.icon index 5f7a0a0..281dc8d 100644 --- a/components/vector_icons/photo_off_chrome_refresh.icon +++ b/components/vector_icons/photo_off_chrome_refresh.icon
@@ -2,37 +2,97 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 13.45f, 15.15f, -R_LINE_TO, -1.43f, -1.41f, -H_LINE_TO, 3.65f, -R_CUBIC_TO, -0.38f, 0, -0.71f, -0.13f, -0.98f, -0.41f, -R_ARC_TO, 1.32f, 1.32f, 0, 0, 1, -0.41f, -0.98f, -R_V_LINE_TO, -8.34f, -R_CUBIC_TO, 0, -0.01f, 0, -0.02f, 0, -0.02f, -LINE_TO, 0.85f, 2.57f, -R_LINE_TO, 0.89f, -0.89f, -LINE_TO, 14.32f, 14.28f, +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 20.57f, 23.43f, +R_LINE_TO, -2.23f, -2.22f, +H_LINE_TO, 5.07f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -1.6f, -0.67f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -0.67f, -1.6f, +V_LINE_TO, 5.75f, +R_CUBIC_TO, 0, -0.02f, 0, -0.03f, 0, -0.05f, +R_V_LINE_TO, -0.04f, +LINE_TO, 0.57f, 3.41f, +R_LINE_TO, 1.46f, -1.46f, +R_LINE_TO, 20.02f, 20.02f, CLOSE, -R_MOVE_TO, -9.8f, -2.8f, -R_H_LINE_TO, 6.98f, -R_LINE_TO, -1.07f, -1.07f, +MOVE_TO, 5.07f, 18.93f, +R_H_LINE_TO, 11, +LINE_TO, 14.15f, 17, +H_LINE_TO, 6, +R_LINE_TO, 3, -4, +R_LINE_TO, 2, 2.73f, +R_LINE_TO, 0.84f, -1.04f, +R_LINE_TO, -6.77f, -6.76f, +CLOSE, +R_MOVE_TO, 16.13f, -0.65f, +R_LINE_TO, -2.27f, -2.27f, +V_LINE_TO, 5.07f, +H_LINE_TO, 7.99f, +LINE_TO, 5.72f, 2.8f, +R_H_LINE_TO, 13.21f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.67f, +R_CUBIC_TO, 0.45f, 0.45f, 0.67f, 0.98f, 0.67f, 1.61f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.81f, 18.94f, +R_LINE_TO, -1.79f, -1.77f, +H_LINE_TO, 4.56f, +R_CUBIC_TO, -0.47f, 0, -0.88f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 5.02f, +R_CUBIC_TO, 0, -0.02f, 0, -0.03f, 0, -0.03f, +LINE_TO, 1.06f, 3.22f, +R_LINE_TO, 1.11f, -1.12f, +R_LINE_TO, 15.72f, 15.75f, +CLOSE, +MOVE_TO, 4.56f, 15.44f, +R_H_LINE_TO, 8.73f, +R_LINE_TO, -1.33f, -1.34f, +H_LINE_TO, 5.08f, +R_LINE_TO, 2.46f, -3.29f, +R_LINE_TO, 1.85f, 2.48f, +R_LINE_TO, 0.74f, -1.01f, +R_LINE_TO, -5.58f, -5.57f, +CLOSE, +R_MOVE_TO, 12.61f, -0.48f, +R_LINE_TO, -1.73f, -1.73f, +V_LINE_TO, 4.56f, +H_LINE_TO, 6.77f, +R_LINE_TO, -1.73f, -1.73f, +H_LINE_TO, 15.44f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 13.54f, 15.27f, +R_LINE_TO, -1.37f, -1.34f, +R_H_LINE_TO, -8.45f, +R_CUBIC_TO, -0.45f, 0, -0.84f, -0.16f, -1.16f, -0.48f, +R_CUBIC_TO, -0.32f, -0.32f, -0.48f, -0.71f, -0.48f, -1.16f, +V_LINE_TO, 3.98f, +R_CUBIC_TO, 0, -0.03f, 0, -0.05f, 0.01f, -0.08f, +R_CUBIC_TO, 0, -0.03f, 0, -0.05f, 0, -0.06f, +LINE_TO, 0.73f, 2.49f, +R_LINE_TO, 0.95f, -0.95f, +R_LINE_TO, 12.78f, 12.8f, +CLOSE, +R_MOVE_TO, -9.82f, -2.98f, +R_H_LINE_TO, 6.82f, +R_LINE_TO, -1, -1, H_LINE_TO, 4.07f, R_LINE_TO, 1.97f, -2.64f, R_LINE_TO, 1.48f, 1.99f, -R_LINE_TO, 0.59f, -0.8f, -R_LINE_TO, -4.46f, -4.46f, +R_LINE_TO, 0.58f, -0.79f, +LINE_TO, 3.72f, 5.47f, CLOSE, -R_MOVE_TO, 10.09f, -0.38f, -R_LINE_TO, -1.38f, -1.38f, -V_LINE_TO, 3.65f, -H_LINE_TO, 5.41f, -LINE_TO, 4.03f, 2.27f, -R_H_LINE_TO, 8.32f, -R_CUBIC_TO, 0.38f, 0, 0.71f, 0.13f, 0.98f, 0.41f, -R_CUBIC_TO, 0.27f, 0.27f, 0.41f, 0.59f, 0.41f, 0.98f, -CLOSE, -R_MOVE_TO, -4.87f, -4.77f, -CLOSE, -MOVE_TO, 7.11f, 8.9f, +R_MOVE_TO, 10.21f, -0.22f, +R_LINE_TO, -1.64f, -1.63f, +V_LINE_TO, 3.72f, +H_LINE_TO, 5.56f, +LINE_TO, 3.93f, 2.08f, +R_H_LINE_TO, 8.36f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.16f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/search_chrome_refresh.icon b/components/vector_icons/search_chrome_refresh.icon index 508b567..b0a7c9b 100644 --- a/components/vector_icons/search_chrome_refresh.icon +++ b/components/vector_icons/search_chrome_refresh.icon
@@ -27,8 +27,7 @@ CUBIC_TO, 7.03f, 9.43f, 6.43f, 10.89f, 6.43f, 12.6f, CUBIC_TO, 6.43f, 14.31f, 7.03f, 15.78f, 8.23f, 17, CUBIC_TO, 9.46f, 18.2f, 10.92f, 18.8f, 12.63f, 18.8f, -CLOSE, -NEW_PATH +CLOSE CANVAS_DIMENSIONS, 20, MOVE_TO, 15.94f, 17, @@ -55,5 +54,4 @@ CUBIC_TO, 4.84f, 6.2f, 4.5f, 7.03f, 4.5f, 8, CUBIC_TO, 4.5f, 8.97f, 4.84f, 9.8f, 5.52f, 10.48f, CUBIC_TO, 6.2f, 11.16f, 7.03f, 11.5f, 8, 11.5f, -CLOSE, -NEW_PATH +CLOSE
diff --git a/components/vector_icons/select_window_chrome_refresh.icon b/components/vector_icons/select_window_chrome_refresh.icon index 9eecaabd..bfec440 100644 --- a/components/vector_icons/select_window_chrome_refresh.icon +++ b/components/vector_icons/select_window_chrome_refresh.icon
@@ -75,3 +75,40 @@ R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.17f, 0.49f, R_CUBIC_TO, 0.32f, 0.32f, 0.49f, 0.72f, 0.49f, 1.17f, CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 2.8f, 14.69f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +V_LINE_TO, 7.74f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.47f, -1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.47f, +R_H_LINE_TO, 0.91f, +V_LINE_TO, 2.94f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f, +ARC_TO, 1.57f, 1.57f, 0, 0, 1, 5.34f, 1.31f, +R_H_LINE_TO, 7.86f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.47f, +R_CUBIC_TO, 0.32f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f, +R_V_LINE_TO, 5.32f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.47f, 1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.47f, +R_H_LINE_TO, -0.91f, +R_V_LINE_TO, 3.17f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.48f, 1.16f, +R_ARC_TO, 1.57f, 1.57f, 0, 0, 1, -1.16f, 0.47f, +CLOSE, +R_MOVE_TO, 0, -1.63f, +R_H_LINE_TO, 7.86f, +V_LINE_TO, 8.8f, +H_LINE_TO, 2.8f, +CLOSE, +R_MOVE_TO, 9.49f, -4.8f, +R_H_LINE_TO, 0.91f, +V_LINE_TO, 4, +H_LINE_TO, 5.34f, +R_V_LINE_TO, 2.11f, +R_H_LINE_TO, 5.46f, +R_CUBIC_TO, 0.41f, 0, 0.76f, 0.14f, 1.05f, 0.44f, +R_CUBIC_TO, 0.29f, 0.29f, 0.44f, 0.64f, 0.44f, 1.06f, +CLOSE
diff --git a/components/vector_icons/select_window_off_chrome_refresh.icon b/components/vector_icons/select_window_off_chrome_refresh.icon index b8ee205..becf418 100644 --- a/components/vector_icons/select_window_off_chrome_refresh.icon +++ b/components/vector_icons/select_window_off_chrome_refresh.icon
@@ -45,4 +45,94 @@ R_CUBIC_TO, 0, 0.63f, -0.22f, 1.17f, -0.66f, 1.61f, R_CUBIC_TO, -0.44f, 0.45f, -0.98f, 0.66f, -1.61f, 0.66f, R_H_LINE_TO, -1.64f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 16.81f, 18.94f, +LINE_TO, 8.87f, 11, +H_LINE_TO, 3.5f, +R_V_LINE_TO, 5.43f, +R_H_LINE_TO, 9.93f, +R_V_LINE_TO, -3.07f, +R_LINE_TO, 1.73f, 1.72f, +R_V_LINE_TO, 1.36f, +R_CUBIC_TO, 0, 0.48f, -0.17f, 0.88f, -0.51f, 1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -1.22f, 0.5f, +H_LINE_TO, 3.5f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 9.57f, +R_CUBIC_TO, 0, -0.49f, 0.17f, -0.91f, 0.5f, -1.25f, +R_CUBIC_TO, 0.34f, -0.34f, 0.74f, -0.5f, 1.23f, -0.47f, +R_H_LINE_TO, 1.34f, +V_LINE_TO, 7, +LINE_TO, 1.14f, 3.27f, +R_LINE_TO, 1.11f, -1.09f, +R_LINE_TO, 15.64f, 15.64f, +CLOSE, +R_MOVE_TO, -1.5f, -5.93f, +R_LINE_TO, -2.27f, -2.27f, +R_LINE_TO, -2.89f, -2.89f, +H_LINE_TO, 13.5f, +R_CUBIC_TO, 0.47f, 0, 0.87f, 0.16f, 1.18f, 0.47f, +R_CUBIC_TO, 0.31f, 0.32f, 0.47f, 0.71f, 0.47f, 1.18f, +R_V_LINE_TO, 0.93f, +H_LINE_TO, 16.5f, +V_LINE_TO, 5, +H_LINE_TO, 7.3f, +LINE_TO, 5.09f, 2.79f, +R_CUBIC_TO, 0.13f, -0.3f, 0.32f, -0.53f, 0.6f, -0.7f, +R_CUBIC_TO, 0.27f, -0.16f, 0.57f, -0.25f, 0.89f, -0.25f, +H_LINE_TO, 16.5f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.51f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +R_V_LINE_TO, 6.85f, +R_CUBIC_TO, 0, 0.48f, -0.17f, 0.89f, -0.51f, 1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -1.22f, 0.51f, +R_H_LINE_TO, -1.19f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 13.54f, 15.27f, +LINE_TO, 7.07f, 8.8f, +H_LINE_TO, 2.8f, +R_V_LINE_TO, 4.26f, +R_H_LINE_TO, 7.86f, +R_V_LINE_TO, -2.54f, +R_LINE_TO, 1.63f, 1.63f, +R_V_LINE_TO, 0.92f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.84f, -0.48f, 1.15f, +R_ARC_TO, 1.57f, 1.57f, 0, 0, 1, -1.16f, 0.47f, +H_LINE_TO, 2.8f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +R_V_LINE_TO, -5.32f, +R_CUBIC_TO, 0, -0.47f, 0.16f, -0.86f, 0.47f, -1.18f, +R_CUBIC_TO, 0.31f, -0.32f, 0.7f, -0.47f, 1.16f, -0.45f, +R_H_LINE_TO, 0.91f, +R_V_LINE_TO, -0.64f, +LINE_TO, 0.89f, 2.62f, +R_LINE_TO, 0.95f, -0.93f, +LINE_TO, 14.46f, 14.32f, +CLOSE, +R_MOVE_TO, -0.96f, -4.71f, +R_LINE_TO, -2.07f, -2.08f, +R_LINE_TO, -2.37f, -2.37f, +H_LINE_TO, 10.8f, +R_CUBIC_TO, 0.43f, 0, 0.78f, 0.14f, 1.07f, 0.43f, +R_CUBIC_TO, 0.28f, 0.28f, 0.43f, 0.64f, 0.43f, 1.07f, +R_V_LINE_TO, 0.66f, +R_H_LINE_TO, 0.91f, +V_LINE_TO, 4, +H_LINE_TO, 6.03f, +LINE_TO, 4.05f, 2.02f, +R_CUBIC_TO, 0.13f, -0.23f, 0.32f, -0.41f, 0.55f, -0.53f, +R_CUBIC_TO, 0.23f, -0.12f, 0.48f, -0.18f, 0.75f, -0.18f, +R_H_LINE_TO, 7.86f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.47f, +R_CUBIC_TO, 0.32f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f, +R_V_LINE_TO, 5.32f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.47f, 1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.47f, +R_H_LINE_TO, -0.62f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/sensors_chrome_refresh.icon b/components/vector_icons/sensors_chrome_refresh.icon new file mode 100644 index 0000000..8ea6d73 --- /dev/null +++ b/components/vector_icons/sensors_chrome_refresh.icon
@@ -0,0 +1,172 @@ +// 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. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 4.67f, 19.33f, +R_ARC_TO, 10.74f, 10.74f, 0, 0, 1, -2.22f, -3.3f, +R_CUBIC_TO, -0.54f, -1.25f, -0.81f, -2.6f, -0.81f, -4.03f, +R_CUBIC_TO, 0, -1.45f, 0.27f, -2.8f, 0.81f, -4.05f, +R_ARC_TO, 10.5f, 10.5f, 0, 0, 1, 2.22f, -3.28f, +R_LINE_TO, 1.55f, 1.55f, +R_ARC_TO, 8.31f, 8.31f, 0, 0, 0, -1.76f, 2.61f, +R_ARC_TO, 7.92f, 7.92f, 0, 0, 0, -0.64f, 3.17f, +R_CUBIC_TO, 0, 1.15f, 0.21f, 2.21f, 0.64f, 3.2f, +ARC_TO, 8.09f, 8.09f, 0, 0, 0, 6.22f, 17.78f, +CLOSE, +R_MOVE_TO, 2.89f, -2.89f, +R_ARC_TO, 6.53f, 6.53f, 0, 0, 1, -1.33f, -2, +R_ARC_TO, 6.01f, 6.01f, 0, 0, 1, -0.5f, -2.44f, +R_CUBIC_TO, 0, -0.89f, 0.16f, -1.71f, 0.5f, -2.47f, +ARC_TO, 6.35f, 6.35f, 0, 0, 1, 7.56f, 7.56f, +R_LINE_TO, 1.55f, 1.55f, +R_ARC_TO, 4.03f, 4.03f, 0, 0, 0, -0.88f, 1.3f, +ARC_TO, 3.96f, 3.96f, 0, 0, 0, 7.91f, 12, +R_CUBIC_TO, 0, 0.56f, 0.11f, 1.09f, 0.32f, 1.59f, +R_CUBIC_TO, 0.21f, 0.5f, 0.5f, 0.93f, 0.88f, 1.3f, +CLOSE, +MOVE_TO, 12, 14.18f, +R_CUBIC_TO, -0.6f, 0, -1.12f, -0.21f, -1.54f, -0.64f, +R_CUBIC_TO, -0.43f, -0.43f, -0.64f, -0.94f, -0.64f, -1.54f, +R_CUBIC_TO, 0, -0.6f, 0.21f, -1.12f, 0.64f, -1.54f, +R_CUBIC_TO, 0.43f, -0.43f, 0.94f, -0.64f, 1.54f, -0.64f, +R_CUBIC_TO, 0.6f, 0, 1.12f, 0.21f, 1.54f, 0.64f, +R_CUBIC_TO, 0.43f, 0.43f, 0.64f, 0.94f, 0.64f, 1.54f, +R_CUBIC_TO, 0, 0.6f, -0.21f, 1.12f, -0.64f, 1.54f, +R_CUBIC_TO, -0.43f, 0.43f, -0.94f, 0.64f, -1.54f, 0.64f, +CLOSE, +R_MOVE_TO, 4.44f, 2.26f, +R_LINE_TO, -1.55f, -1.55f, +R_CUBIC_TO, 0.38f, -0.37f, 0.67f, -0.81f, 0.88f, -1.3f, +R_CUBIC_TO, 0.21f, -0.49f, 0.32f, -1.02f, 0.32f, -1.59f, +R_ARC_TO, 4.09f, 4.09f, 0, 0, 0, -1.2f, -2.89f, +R_LINE_TO, 1.55f, -1.55f, +R_ARC_TO, 6.24f, 6.24f, 0, 0, 1, 1.34f, 1.97f, +R_CUBIC_TO, 0.33f, 0.76f, 0.5f, 1.58f, 0.5f, 2.47f, +R_ARC_TO, 6.01f, 6.01f, 0, 0, 1, -0.5f, 2.44f, +R_ARC_TO, 6.53f, 6.53f, 0, 0, 1, -1.34f, 2, +CLOSE, +R_MOVE_TO, 2.89f, 2.89f, +R_LINE_TO, -1.55f, -1.55f, +R_ARC_TO, 8.31f, 8.31f, 0, 0, 0, 1.77f, -2.61f, +ARC_TO, 7.93f, 7.93f, 0, 0, 0, 20.18f, 12, +R_CUBIC_TO, 0, -1.14f, -0.21f, -2.21f, -0.64f, -3.19f, +R_ARC_TO, 8.09f, 8.09f, 0, 0, 0, -1.77f, -2.59f, +R_LINE_TO, 1.55f, -1.55f, +R_ARC_TO, 10.51f, 10.51f, 0, 0, 1, 2.22f, 3.28f, +R_CUBIC_TO, 0.54f, 1.25f, 0.81f, 2.6f, 0.81f, 4.06f, +R_CUBIC_TO, 0, 1.43f, -0.27f, 2.77f, -0.81f, 4.03f, +R_ARC_TO, 10.74f, 10.74f, 0, 0, 1, -2.22f, 3.3f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.14f, 15.86f, +R_ARC_TO, 8.14f, 8.14f, 0, 0, 1, -1.8f, -2.63f, +R_ARC_TO, 8.04f, 8.04f, 0, 0, 1, -0.65f, -3.22f, +R_CUBIC_TO, 0, -1.16f, 0.22f, -2.24f, 0.65f, -3.24f, +R_CUBIC_TO, 0.43f, -1, 1.02f, -1.88f, 1.77f, -2.65f, +R_LINE_TO, 1.17f, 1.17f, +ARC_TO, 6.98f, 6.98f, 0, 0, 0, 3.87f, 7.41f, +R_ARC_TO, 6.43f, 6.43f, 0, 0, 0, -0.52f, 2.58f, +R_ARC_TO, 6.49f, 6.49f, 0, 0, 0, 1.97f, 4.7f, +CLOSE, +MOVE_TO, 6.3f, 13.7f, +R_ARC_TO, 5.49f, 5.49f, 0, 0, 1, -1.12f, -1.66f, +R_ARC_TO, 5.03f, 5.03f, 0, 0, 1, -0.41f, -2.03f, +R_CUBIC_TO, 0, -0.73f, 0.14f, -1.42f, 0.42f, -2.05f, +ARC_TO, 5.44f, 5.44f, 0, 0, 1, 6.3f, 6.3f, +R_LINE_TO, 1.16f, 1.16f, +R_ARC_TO, 3.58f, 3.58f, 0, 0, 0, -0.76f, 1.14f, +R_ARC_TO, 3.47f, 3.47f, 0, 0, 0, -0.28f, 1.4f, +R_CUBIC_TO, 0, 0.5f, 0.09f, 0.96f, 0.28f, 1.39f, +R_CUBIC_TO, 0.18f, 0.43f, 0.44f, 0.81f, 0.76f, 1.14f, +CLOSE, +R_MOVE_TO, 3.69f, -1.79f, +R_CUBIC_TO, -0.52f, 0, -0.97f, -0.19f, -1.34f, -0.56f, +R_ARC_TO, 1.85f, 1.85f, 0, 0, 1, -0.56f, -1.35f, +R_CUBIC_TO, 0, -0.52f, 0.19f, -0.97f, 0.56f, -1.34f, +R_ARC_TO, 1.85f, 1.85f, 0, 0, 1, 1.35f, -0.56f, +R_CUBIC_TO, 0.52f, 0, 0.97f, 0.19f, 1.34f, 0.56f, +R_CUBIC_TO, 0.37f, 0.38f, 0.56f, 0.82f, 0.56f, 1.35f, +R_CUBIC_TO, 0, 0.52f, -0.19f, 0.97f, -0.56f, 1.34f, +R_ARC_TO, 1.85f, 1.85f, 0, 0, 1, -1.35f, 0.56f, +CLOSE, +R_MOVE_TO, 3.69f, 1.77f, +R_LINE_TO, -1.14f, -1.14f, +R_CUBIC_TO, 0.32f, -0.33f, 0.58f, -0.71f, 0.76f, -1.14f, +R_CUBIC_TO, 0.19f, -0.44f, 0.28f, -0.9f, 0.28f, -1.39f, +R_CUBIC_TO, 0, -0.49f, -0.09f, -0.96f, -0.28f, -1.39f, +R_ARC_TO, 3.65f, 3.65f, 0, 0, 0, -0.76f, -1.14f, +LINE_TO, 13.7f, 6.3f, +R_CUBIC_TO, 0.47f, 0.48f, 0.84f, 1.03f, 1.12f, 1.66f, +R_ARC_TO, 5.09f, 5.09f, 0, 0, 1, 0.41f, 2.05f, +R_CUBIC_TO, 0, 0.72f, -0.14f, 1.4f, -0.41f, 2.03f, +R_ARC_TO, 5.15f, 5.15f, 0, 0, 1, -1.14f, 1.64f, +CLOSE, +R_MOVE_TO, 2.18f, 2.18f, +LINE_TO, 14.69f, 14.69f, +R_ARC_TO, 6.5f, 6.5f, 0, 0, 0, 1.97f, -4.68f, +R_ARC_TO, 6.47f, 6.47f, 0, 0, 0, -0.52f, -2.6f, +R_ARC_TO, 7.18f, 7.18f, 0, 0, 0, -1.42f, -2.12f, +R_LINE_TO, 1.17f, -1.17f, +R_ARC_TO, 8.68f, 8.68f, 0, 0, 1, 1.77f, 2.65f, +R_CUBIC_TO, 0.43f, 1, 0.65f, 2.08f, 0.65f, 3.24f, +R_ARC_TO, 8.03f, 8.03f, 0, 0, 1, -0.65f, 3.22f, +R_ARC_TO, 8.14f, 8.14f, 0, 0, 1, -1.8f, 2.63f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3.08f, 12.92f, +R_ARC_TO, 6.81f, 6.81f, 0, 0, 1, -2.06f, -4.91f, +R_CUBIC_TO, 0, -0.98f, 0.18f, -1.88f, 0.54f, -2.72f, +R_ARC_TO, 7.23f, 7.23f, 0, 0, 1, 1.5f, -2.22f, +LINE_TO, 4.11f, 4.11f, +R_ARC_TO, 5.83f, 5.83f, 0, 0, 0, -1.17f, 1.75f, +R_ARC_TO, 5.34f, 5.34f, 0, 0, 0, -0.43f, 2.13f, +R_CUBIC_TO, 0, 0.77f, 0.14f, 1.48f, 0.43f, 2.14f, +R_ARC_TO, 5.54f, 5.54f, 0, 0, 0, 1.19f, 1.74f, +CLOSE, +R_MOVE_TO, 1.79f, -1.78f, +R_ARC_TO, 4.59f, 4.59f, 0, 0, 1, -0.94f, -1.41f, +R_ARC_TO, 4.23f, 4.23f, 0, 0, 1, -0.35f, -1.72f, +R_CUBIC_TO, 0, -0.62f, 0.12f, -1.2f, 0.35f, -1.73f, +R_CUBIC_TO, 0.23f, -0.53f, 0.55f, -1, 0.95f, -1.41f, +R_LINE_TO, 1.05f, 1.05f, +R_CUBIC_TO, -0.27f, 0.26f, -0.48f, 0.57f, -0.63f, 0.93f, +R_CUBIC_TO, -0.15f, 0.36f, -0.23f, 0.75f, -0.23f, 1.16f, +R_CUBIC_TO, 0, 0.41f, 0.07f, 0.79f, 0.23f, 1.15f, +R_CUBIC_TO, 0.15f, 0.36f, 0.36f, 0.67f, 0.63f, 0.93f, +CLOSE, +MOVE_TO, 8, 9.69f, +R_CUBIC_TO, -0.47f, 0, -0.87f, -0.16f, -1.19f, -0.5f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -0.49f, -1.2f, +R_CUBIC_TO, 0, -0.47f, 0.16f, -0.87f, 0.5f, -1.19f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, 1.2f, -0.49f, +R_CUBIC_TO, 0.47f, 0, 0.87f, 0.16f, 1.2f, 0.5f, +R_CUBIC_TO, 0.33f, 0.34f, 0.49f, 0.73f, 0.49f, 1.2f, +R_CUBIC_TO, 0, 0.47f, -0.16f, 0.87f, -0.5f, 1.2f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -1.2f, 0.49f, +CLOSE, +R_MOVE_TO, 3.12f, 1.43f, +R_LINE_TO, -1.03f, -1.03f, +R_CUBIC_TO, 0.27f, -0.27f, 0.48f, -0.59f, 0.63f, -0.94f, +R_CUBIC_TO, 0.15f, -0.36f, 0.23f, -0.74f, 0.23f, -1.14f, +R_ARC_TO, 2.93f, 2.93f, 0, 0, 0, -0.85f, -2.09f, +R_LINE_TO, 1.05f, -1.05f, +R_CUBIC_TO, 0.4f, 0.41f, 0.72f, 0.87f, 0.95f, 1.41f, +R_CUBIC_TO, 0.23f, 0.53f, 0.35f, 1.11f, 0.35f, 1.74f, +R_CUBIC_TO, 0, 0.61f, -0.12f, 1.19f, -0.35f, 1.72f, +R_CUBIC_TO, -0.23f, 0.53f, -0.56f, 1, -0.96f, 1.39f, +CLOSE, +R_MOVE_TO, 1.81f, 1.81f, +R_LINE_TO, -1.05f, -1.05f, +R_ARC_TO, 5.48f, 5.48f, 0, 0, 0, 1.19f, -1.74f, +R_CUBIC_TO, 0.28f, -0.66f, 0.43f, -1.37f, 0.43f, -2.13f, +R_CUBIC_TO, 0, -0.76f, -0.14f, -1.48f, -0.43f, -2.14f, +ARC_TO, 5.78f, 5.78f, 0, 0, 0, 11.89f, 4.11f, +R_LINE_TO, 1.05f, -1.05f, +R_ARC_TO, 7.2f, 7.2f, 0, 0, 1, 1.5f, 2.23f, +R_CUBIC_TO, 0.36f, 0.84f, 0.54f, 1.75f, 0.54f, 2.72f, +R_CUBIC_TO, 0, 0.97f, -0.18f, 1.86f, -0.54f, 2.71f, +R_ARC_TO, 6.84f, 6.84f, 0, 0, 1, -1.51f, 2.2f, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/sensors_off.icon b/components/vector_icons/sensors_off.icon deleted file mode 100644 index 428c9d1..0000000 --- a/components/vector_icons/sensors_off.icon +++ /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. - -CANVAS_DIMENSIONS, 16, -MOVE_TO, 12.95f, 14.67f, -LINE_TO, 5.32f, 7.04f, -ARC_TO, 2.62f, 2.62f, 0, 0, 0, 5.14f, 8, -R_CUBIC_TO, 0, 0.4f, 0.08f, 0.77f, 0.22f, 1.12f, -R_CUBIC_TO, 0.15f, 0.34f, 0.35f, 0.65f, 0.61f, 0.91f, -R_LINE_TO, -0.92f, 0.92f, -R_ARC_TO, 4.09f, 4.09f, 0, 0, 1, -0.91f, -1.32f, -ARC_TO, 3.98f, 3.98f, 0, 0, 1, 3.82f, 8, -R_CUBIC_TO, 0, -0.35f, 0.05f, -0.69f, 0.14f, -1.02f, -R_CUBIC_TO, 0.09f, -0.32f, 0.22f, -0.64f, 0.38f, -0.93f, -R_LINE_TO, -0.84f, -0.86f, -R_ARC_TO, 5.58f, 5.58f, 0, 0, 0, -0.59f, 1.33f, -ARC_TO, 5.05f, 5.05f, 0, 0, 0, 2.68f, 8, -R_CUBIC_TO, 0, 0.74f, 0.14f, 1.43f, 0.42f, 2.07f, -R_ARC_TO, 5.31f, 5.31f, 0, 0, 0, 1.15f, 1.68f, -R_LINE_TO, -0.93f, 0.93f, -ARC_TO, 6.49f, 6.49f, 0, 0, 1, 1.36f, 8, -R_CUBIC_TO, 0, -0.69f, 0.1f, -1.36f, 0.3f, -2, -R_ARC_TO, 6.55f, 6.55f, 0, 0, 1, 0.86f, -1.77f, -LINE_TO, 1.33f, 3.05f, -R_LINE_TO, 0.89f, -0.89f, -LINE_TO, 13.84f, 13.78f, -CLOSE, -R_MOVE_TO, 0.58f, -2.98f, -R_LINE_TO, -0.98f, -0.96f, -R_ARC_TO, 5.58f, 5.58f, 0, 0, 0, 0.57f, -1.3f, -R_CUBIC_TO, 0.13f, -0.46f, 0.2f, -0.94f, 0.2f, -1.44f, -R_CUBIC_TO, 0, -0.74f, -0.14f, -1.43f, -0.42f, -2.07f, -R_ARC_TO, 5.31f, 5.31f, 0, 0, 0, -1.15f, -1.68f, -R_LINE_TO, 0.93f, -0.93f, -R_ARC_TO, 6.49f, 6.49f, 0, 0, 1, 1.44f, 2.11f, -R_CUBIC_TO, 0.34f, 0.8f, 0.52f, 1.66f, 0.52f, 2.58f, -R_CUBIC_TO, 0, 0.68f, -0.1f, 1.34f, -0.29f, 1.96f, -R_ARC_TO, 6.31f, 6.31f, 0, 0, 1, -0.82f, 1.73f, -CLOSE, -R_MOVE_TO, -1.8f, -1.8f, -R_LINE_TO, -1.03f, -1.03f, -ARC_TO, 2.41f, 2.41f, 0, 0, 0, 10.86f, 8, -R_CUBIC_TO, 0, -0.4f, -0.07f, -0.77f, -0.22f, -1.12f, -R_ARC_TO, 2.9f, 2.9f, 0, 0, 0, -0.61f, -0.91f, -R_LINE_TO, 0.92f, -0.92f, -ARC_TO, 4.09f, 4.09f, 0, 0, 1, 12.18f, 8, -R_CUBIC_TO, 0, 0.34f, -0.04f, 0.67f, -0.11f, 0.99f, -R_CUBIC_TO, -0.07f, 0.32f, -0.18f, 0.62f, -0.34f, 0.91f, -CLOSE \ No newline at end of file
diff --git a/components/vector_icons/sensors_off_chrome_refresh.icon b/components/vector_icons/sensors_off_chrome_refresh.icon new file mode 100644 index 0000000..bc738f1 --- /dev/null +++ b/components/vector_icons/sensors_off_chrome_refresh.icon
@@ -0,0 +1,148 @@ +// 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. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 20, 22.88f, +LINE_TO, 8.05f, 10.93f, +R_CUBIC_TO, -0.04f, 0.18f, -0.07f, 0.35f, -0.1f, 0.52f, +R_CUBIC_TO, -0.03f, 0.18f, -0.04f, 0.36f, -0.04f, 0.55f, +R_ARC_TO, 4.05f, 4.05f, 0, 0, 0, 1.2f, 2.89f, +R_LINE_TO, -1.55f, 1.55f, +R_ARC_TO, 6.53f, 6.53f, 0, 0, 1, -1.34f, -2, +ARC_TO, 6.02f, 6.02f, 0, 0, 1, 5.73f, 12, +R_ARC_TO, 6.21f, 6.21f, 0, 0, 1, 0.64f, -2.76f, +LINE_TO, 4.95f, 7.83f, +R_CUBIC_TO, -0.36f, 0.61f, -0.64f, 1.27f, -0.84f, 1.97f, +ARC_TO, 8.11f, 8.11f, 0, 0, 0, 3.82f, 12, +R_CUBIC_TO, 0, 1.14f, 0.21f, 2.21f, 0.64f, 3.2f, +R_ARC_TO, 8.09f, 8.09f, 0, 0, 0, 1.77f, 2.59f, +R_LINE_TO, -1.55f, 1.55f, +R_ARC_TO, 10.74f, 10.74f, 0, 0, 1, -2.22f, -3.3f, +R_CUBIC_TO, -0.54f, -1.25f, -0.81f, -2.6f, -0.81f, -4.03f, +R_ARC_TO, 9.9f, 9.9f, 0, 0, 1, 0.46f, -3.05f, +R_CUBIC_TO, 0.31f, -0.96f, 0.74f, -1.86f, 1.28f, -2.69f, +R_LINE_TO, -2.25f, -2.26f, +R_LINE_TO, 1.48f, -1.48f, +LINE_TO, 21.49f, 21.39f, +CLOSE, +R_MOVE_TO, 0.69f, -5.24f, +LINE_TO, 19.11f, 16.05f, +R_ARC_TO, 8.49f, 8.49f, 0, 0, 0, 0.79f, -1.92f, +ARC_TO, 7.94f, 7.94f, 0, 0, 0, 20.18f, 12, +R_CUBIC_TO, 0, -1.14f, -0.21f, -2.21f, -0.64f, -3.19f, +R_ARC_TO, 8.09f, 8.09f, 0, 0, 0, -1.77f, -2.59f, +R_LINE_TO, 1.55f, -1.55f, +R_ARC_TO, 10.51f, 10.51f, 0, 0, 1, 2.22f, 3.28f, +R_CUBIC_TO, 0.54f, 1.25f, 0.81f, 2.6f, 0.81f, 4.05f, +R_ARC_TO, 9.9f, 9.9f, 0, 0, 1, -0.44f, 2.98f, +R_CUBIC_TO, -0.3f, 0.95f, -0.7f, 1.83f, -1.23f, 2.66f, +CLOSE, +MOVE_TO, 17.7f, 14.64f, +R_LINE_TO, -1.71f, -1.72f, +R_CUBIC_TO, 0.03f, -0.15f, 0.06f, -0.3f, 0.08f, -0.45f, +R_ARC_TO, 3.94f, 3.94f, 0, 0, 0, -0.29f, -2.06f, +R_ARC_TO, 4.09f, 4.09f, 0, 0, 0, -0.88f, -1.3f, +R_LINE_TO, 1.55f, -1.55f, +R_ARC_TO, 6.24f, 6.24f, 0, 0, 1, 1.34f, 1.97f, +ARC_TO, 6.1f, 6.1f, 0, 0, 1, 18.27f, 12, +R_CUBIC_TO, 0, 0.48f, -0.05f, 0.94f, -0.15f, 1.38f, +R_ARC_TO, 6.27f, 6.27f, 0, 0, 1, -0.43f, 1.26f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 16.19f, 18.34f, +LINE_TO, 6.65f, 8.79f, +R_ARC_TO, 2.76f, 2.76f, 0, 0, 0, -0.17f, 0.58f, +R_CUBIC_TO, -0.04f, 0.2f, -0.05f, 0.41f, -0.05f, 0.63f, +R_CUBIC_TO, 0, 0.5f, 0.09f, 0.97f, 0.27f, 1.4f, +R_CUBIC_TO, 0.19f, 0.43f, 0.44f, 0.81f, 0.77f, 1.14f, +LINE_TO, 6.32f, 13.68f, +R_ARC_TO, 5.15f, 5.15f, 0, 0, 1, -1.14f, -1.64f, +R_ARC_TO, 5.09f, 5.09f, 0, 0, 1, -0.24f, -3.32f, +R_CUBIC_TO, 0.11f, -0.41f, 0.27f, -0.8f, 0.47f, -1.17f, +R_LINE_TO, -1.06f, -1.07f, +R_ARC_TO, 6.99f, 6.99f, 0, 0, 0, -0.74f, 1.66f, +R_CUBIC_TO, -0.18f, 0.59f, -0.27f, 1.21f, -0.27f, 1.86f, +R_CUBIC_TO, 0, 0.92f, 0.18f, 1.79f, 0.52f, 2.59f, +R_CUBIC_TO, 0.35f, 0.8f, 0.83f, 1.5f, 1.44f, 2.1f, +LINE_TO, 4.14f, 15.86f, +R_ARC_TO, 8.14f, 8.14f, 0, 0, 1, -1.8f, -2.62f, +ARC_TO, 8.07f, 8.07f, 0, 0, 1, 1.7f, 10, +R_CUBIC_TO, 0, -0.87f, 0.13f, -1.7f, 0.38f, -2.5f, +R_CUBIC_TO, 0.25f, -0.79f, 0.61f, -1.53f, 1.08f, -2.21f, +R_LINE_TO, -1.48f, -1.48f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 14.52f, 14.52f, +CLOSE, +R_MOVE_TO, 0.73f, -3.72f, +R_LINE_TO, -1.22f, -1.19f, +R_ARC_TO, 7.07f, 7.07f, 0, 0, 0, 0.7f, -1.62f, +ARC_TO, 6.25f, 6.25f, 0, 0, 0, 16.66f, 10, +R_ARC_TO, 6.46f, 6.46f, 0, 0, 0, -0.52f, -2.59f, +ARC_TO, 6.61f, 6.61f, 0, 0, 0, 14.69f, 5.31f, +LINE_TO, 15.86f, 4.14f, +R_ARC_TO, 8.16f, 8.16f, 0, 0, 1, 1.8f, 2.63f, +R_ARC_TO, 8.05f, 8.05f, 0, 0, 1, 0.65f, 3.23f, +R_CUBIC_TO, 0, 0.85f, -0.12f, 1.67f, -0.36f, 2.45f, +R_ARC_TO, 7.87f, 7.87f, 0, 0, 1, -1.03f, 2.16f, +CLOSE, +R_MOVE_TO, -2.25f, -2.25f, +R_LINE_TO, -1.28f, -1.28f, +ARC_TO, 3.08f, 3.08f, 0, 0, 0, 13.57f, 10, +R_CUBIC_TO, 0, -0.5f, -0.09f, -0.96f, -0.27f, -1.39f, +R_ARC_TO, 3.68f, 3.68f, 0, 0, 0, -0.77f, -1.14f, +LINE_TO, 13.68f, 6.32f, +ARC_TO, 5.08f, 5.08f, 0, 0, 1, 15.23f, 10, +R_CUBIC_TO, 0, 0.43f, -0.05f, 0.84f, -0.14f, 1.23f, +R_CUBIC_TO, -0.09f, 0.4f, -0.23f, 0.78f, -0.43f, 1.13f, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 13.16f, 14.9f, +R_LINE_TO, -7.91f, -7.9f, +R_ARC_TO, 1.95f, 1.95f, 0, 0, 0, -0.14f, 0.49f, +R_CUBIC_TO, -0.03f, 0.17f, -0.04f, 0.34f, -0.04f, 0.52f, +R_CUBIC_TO, 0, 0.41f, 0.07f, 0.8f, 0.23f, 1.16f, +R_CUBIC_TO, 0.15f, 0.36f, 0.36f, 0.67f, 0.63f, 0.93f, +R_LINE_TO, -1.03f, 1.03f, +R_ARC_TO, 4.19f, 4.19f, 0, 0, 1, -0.96f, -1.39f, +ARC_TO, 4.24f, 4.24f, 0, 0, 1, 3.57f, 8, +R_CUBIC_TO, 0, -0.38f, 0.05f, -0.75f, 0.15f, -1.11f, +R_CUBIC_TO, 0.1f, -0.35f, 0.24f, -0.69f, 0.42f, -1.01f, +R_LINE_TO, -0.79f, -0.8f, +R_ARC_TO, 5.83f, 5.83f, 0, 0, 0, -0.62f, 1.38f, +ARC_TO, 5.33f, 5.33f, 0, 0, 0, 2.51f, 8, +R_CUBIC_TO, 0, 0.76f, 0.14f, 1.47f, 0.43f, 2.13f, +R_ARC_TO, 5.53f, 5.53f, 0, 0, 0, 1.18f, 1.74f, +R_LINE_TO, -1.05f, 1.05f, +R_ARC_TO, 6.84f, 6.84f, 0, 0, 1, -1.51f, -2.2f, +ARC_TO, 6.87f, 6.87f, 0, 0, 1, 1.02f, 8, +R_ARC_TO, 6.95f, 6.95f, 0, 0, 1, 1.24f, -3.98f, +R_LINE_TO, -1.16f, -1.17f, +R_LINE_TO, 0.94f, -0.95f, +R_LINE_TO, 12.06f, 12.06f, +CLOSE, +R_MOVE_TO, 0.69f, -3.08f, +R_LINE_TO, -1.1f, -1.08f, +R_CUBIC_TO, 0.23f, -0.41f, 0.41f, -0.84f, 0.55f, -1.3f, +R_CUBIC_TO, 0.13f, -0.46f, 0.2f, -0.94f, 0.2f, -1.43f, +R_CUBIC_TO, 0, -0.76f, -0.14f, -1.47f, -0.43f, -2.13f, +R_ARC_TO, 5.53f, 5.53f, 0, 0, 0, -1.18f, -1.74f, +R_LINE_TO, 1.05f, -1.05f, +R_ARC_TO, 6.89f, 6.89f, 0, 0, 1, 1.51f, 2.22f, +R_CUBIC_TO, 0.36f, 0.84f, 0.54f, 1.74f, 0.54f, 2.71f, +R_CUBIC_TO, 0, 0.7f, -0.1f, 1.38f, -0.29f, 2.02f, +R_ARC_TO, 6.84f, 6.84f, 0, 0, 1, -0.84f, 1.79f, +CLOSE, +R_MOVE_TO, -1.86f, -1.86f, +R_LINE_TO, -1.18f, -1.18f, +R_ARC_TO, 2.52f, 2.52f, 0, 0, 0, 0.11f, -0.38f, +R_ARC_TO, 2.91f, 2.91f, 0, 0, 0, -0.19f, -1.54f, +R_ARC_TO, 2.81f, 2.81f, 0, 0, 0, -0.63f, -0.94f, +R_LINE_TO, 1.03f, -1.03f, +R_CUBIC_TO, 0.41f, 0.39f, 0.74f, 0.86f, 0.97f, 1.39f, +R_CUBIC_TO, 0.23f, 0.54f, 0.35f, 1.11f, 0.35f, 1.72f, +R_CUBIC_TO, 0, 0.35f, -0.04f, 0.69f, -0.11f, 1.02f, +R_CUBIC_TO, -0.07f, 0.32f, -0.18f, 0.64f, -0.34f, 0.93f, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/serial_port_chrome_refresh.icon b/components/vector_icons/serial_port_chrome_refresh.icon index 1b9b4801..241ec37 100644 --- a/components/vector_icons/serial_port_chrome_refresh.icon +++ b/components/vector_icons/serial_port_chrome_refresh.icon
@@ -55,4 +55,114 @@ CLOSE, MOVE_TO, 4.03f, 5.07f, R_V_LINE_TO, 13.86f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 3.52f, 17.17f, +R_CUBIC_TO, -0.47f, 0, -0.87f, -0.17f, -1.21f, -0.51f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 4.56f, +R_CUBIC_TO, 0, -0.48f, 0.17f, -0.89f, 0.51f, -1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, 1.21f, -0.5f, +R_H_LINE_TO, 10.88f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.5f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +V_LINE_TO, 6, +R_H_LINE_TO, 2.08f, +R_V_LINE_TO, 1.57f, +H_LINE_TO, 16.13f, +R_V_LINE_TO, 1.64f, +R_H_LINE_TO, 2.07f, +R_V_LINE_TO, 1.58f, +H_LINE_TO, 16.13f, +R_V_LINE_TO, 1.64f, +R_H_LINE_TO, 2.07f, +V_LINE_TO, 14, +H_LINE_TO, 16.13f, +R_V_LINE_TO, 1.43f, +R_CUBIC_TO, 0, 0.48f, -0.17f, 0.89f, -0.51f, 1.23f, +R_ARC_TO, 1.66f, 1.66f, 0, 0, 1, -1.22f, 0.51f, +CLOSE, +R_MOVE_TO, 0, -1.73f, +R_H_LINE_TO, 10.88f, +V_LINE_TO, 4.56f, +H_LINE_TO, 3.52f, +CLOSE, +MOVE_TO, 4.96f, 14, +R_H_LINE_TO, 4, +R_V_LINE_TO, -3, +R_H_LINE_TO, -4, +CLOSE, +R_MOVE_TO, 5, -6, +R_H_LINE_TO, 3, +V_LINE_TO, 6, +R_H_LINE_TO, -3, +CLOSE, +R_MOVE_TO, -5, 2, +R_H_LINE_TO, 4, +V_LINE_TO, 6, +R_H_LINE_TO, -4, +CLOSE, +R_MOVE_TO, 5, 4, +R_H_LINE_TO, 3, +V_LINE_TO, 9, +R_H_LINE_TO, -3, +CLOSE, +MOVE_TO, 3.52f, 4.56f, +V_LINE_TO, 15.44f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 2.85f, 13.92f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.15f, -0.48f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.48f, -1.16f, +R_V_LINE_TO, -8.57f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.48f, -1.16f, +R_CUBIC_TO, 0.32f, -0.32f, 0.7f, -0.48f, 1.15f, -0.48f, +R_H_LINE_TO, 8.56f, +R_CUBIC_TO, 0.45f, 0, 0.83f, 0.16f, 1.15f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.49f, 0.7f, 0.49f, 1.16f, +V_LINE_TO, 4.8f, +R_H_LINE_TO, 1.74f, +R_V_LINE_TO, 1.34f, +R_H_LINE_TO, -1.74f, +R_V_LINE_TO, 1.18f, +R_H_LINE_TO, 1.74f, +R_V_LINE_TO, 1.35f, +R_H_LINE_TO, -1.74f, +R_V_LINE_TO, 1.18f, +R_H_LINE_TO, 1.74f, +R_V_LINE_TO, 1.34f, +R_H_LINE_TO, -1.74f, +R_V_LINE_TO, 1.08f, +R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, -0.48f, 1.16f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.15f, 0.48f, +CLOSE, +R_MOVE_TO, 0, -1.64f, +R_H_LINE_TO, 8.56f, +R_V_LINE_TO, -8.57f, +H_LINE_TO, 2.85f, +CLOSE, +MOVE_TO, 3.93f, 11.2f, +R_H_LINE_TO, 3.2f, +V_LINE_TO, 8.8f, +R_H_LINE_TO, -3.2f, +CLOSE, +R_MOVE_TO, 4, -4.8f, +R_H_LINE_TO, 2.4f, +V_LINE_TO, 4.8f, +H_LINE_TO, 7.93f, +CLOSE, +MOVE_TO, 3.93f, 8, +R_H_LINE_TO, 3.2f, +V_LINE_TO, 4.8f, +R_H_LINE_TO, -3.2f, +CLOSE, +R_MOVE_TO, 4, 3.2f, +R_H_LINE_TO, 2.4f, +R_V_LINE_TO, -4, +H_LINE_TO, 7.93f, +CLOSE, +MOVE_TO, 2.85f, 3.71f, +R_V_LINE_TO, 8.57f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/serial_port_off_chrome_refresh.icon b/components/vector_icons/serial_port_off_chrome_refresh.icon index b312d02..ffcf609 100644 --- a/components/vector_icons/serial_port_off_chrome_refresh.icon +++ b/components/vector_icons/serial_port_off_chrome_refresh.icon
@@ -77,4 +77,158 @@ V_LINE_TO, 12, R_H_LINE_TO, -5, V_LINE_TO, 7, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 16.71f, 18.84f, +LINE_TO, 1.04f, 3.17f, +R_LINE_TO, 1.11f, -1.09f, +R_LINE_TO, 15.65f, 15.65f, +CLOSE, +MOVE_TO, 5.14f, 2.83f, +R_H_LINE_TO, 9.25f, +R_CUBIC_TO, 0.49f, 0, 0.9f, 0.17f, 1.24f, 0.51f, +R_CUBIC_TO, 0.33f, 0.34f, 0.5f, 0.75f, 0.5f, 1.23f, +V_LINE_TO, 6, +R_H_LINE_TO, 2.07f, +R_V_LINE_TO, 1.57f, +H_LINE_TO, 16.13f, +R_V_LINE_TO, 1.64f, +R_H_LINE_TO, 2.07f, +R_V_LINE_TO, 1.58f, +H_LINE_TO, 16.13f, +R_V_LINE_TO, 1.64f, +R_H_LINE_TO, 2.07f, +V_LINE_TO, 14, +R_H_LINE_TO, -1.9f, +R_LINE_TO, -1.91f, -1.9f, +R_V_LINE_TO, -7.54f, +H_LINE_TO, 6.86f, +CLOSE, +MOVE_TO, 8.96f, 6.7f, +LINE_TO, 8.27f, 6, +R_H_LINE_TO, 0.7f, +CLOSE, +MOVE_TO, 10.31f, 8, +R_LINE_TO, -0.34f, -0.34f, +V_LINE_TO, 6, +R_H_LINE_TO, 3, +R_V_LINE_TO, 2, +CLOSE, +R_MOVE_TO, 2.66f, 2.66f, +LINE_TO, 11.3f, 9, +R_H_LINE_TO, 1.66f, +CLOSE, +R_MOVE_TO, -3.98f, 0.47f, +CLOSE, +R_MOVE_TO, 1.78f, -2.64f, +CLOSE, +MOVE_TO, 4.96f, 14, +R_V_LINE_TO, -3, +R_H_LINE_TO, 4, +R_V_LINE_TO, 3, +CLOSE, +MOVE_TO, 3.05f, 2.98f, +R_LINE_TO, 1.58f, 1.58f, +R_H_LINE_TO, -1.11f, +V_LINE_TO, 15.44f, +R_H_LINE_TO, 10.9f, +R_V_LINE_TO, -1.09f, +LINE_TO, 16.07f, 16, +R_ARC_TO, 1.95f, 1.95f, 0, 0, 1, -0.67f, 0.82f, +R_CUBIC_TO, -0.32f, 0.24f, -0.65f, 0.35f, -1.01f, 0.35f, +H_LINE_TO, 3.52f, +R_CUBIC_TO, -0.47f, 0, -0.87f, -0.17f, -1.21f, -0.51f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 4.56f, +R_CUBIC_TO, 0, -0.36f, 0.13f, -0.68f, 0.38f, -0.96f, +R_CUBIC_TO, 0.25f, -0.28f, 0.54f, -0.49f, 0.88f, -0.62f, +CLOSE, +R_MOVE_TO, 6.91f, 6.91f, +R_LINE_TO, 3.33f, 3.33f, +V_LINE_TO, 14, +H_LINE_TO, 9.96f, +CLOSE, +MOVE_TO, 6.07f, 6, +LINE_TO, 9.25f, 9.18f, +V_LINE_TO, 10, +H_LINE_TO, 4.96f, +V_LINE_TO, 6, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 13.34f, 15.07f, +LINE_TO, 0.7f, 2.43f, +R_LINE_TO, 0.94f, -0.93f, +R_LINE_TO, 12.63f, 12.63f, +CLOSE, +MOVE_TO, 4.12f, 2.08f, +R_H_LINE_TO, 7.29f, +R_CUBIC_TO, 0.47f, 0, 0.86f, 0.16f, 1.17f, 0.48f, +R_CUBIC_TO, 0.31f, 0.33f, 0.47f, 0.71f, 0.47f, 1.17f, +V_LINE_TO, 4.8f, +R_H_LINE_TO, 1.74f, +R_V_LINE_TO, 1.34f, +R_H_LINE_TO, -1.74f, +R_V_LINE_TO, 1.18f, +R_H_LINE_TO, 1.74f, +R_V_LINE_TO, 1.35f, +R_H_LINE_TO, -1.74f, +R_V_LINE_TO, 1.18f, +R_H_LINE_TO, 1.74f, +R_V_LINE_TO, 1.34f, +R_H_LINE_TO, -1.55f, +LINE_TO, 11.41f, 9.37f, +V_LINE_TO, 3.72f, +H_LINE_TO, 5.75f, +CLOSE, +MOVE_TO, 7.13f, 5.16f, +R_LINE_TO, -0.36f, -0.36f, +R_H_LINE_TO, 0.36f, +CLOSE, +R_MOVE_TO, 1.31f, 1.24f, +R_LINE_TO, -0.51f, -0.51f, +V_LINE_TO, 4.8f, +R_H_LINE_TO, 2.4f, +R_V_LINE_TO, 1.6f, +CLOSE, +R_MOVE_TO, 1.89f, 1.9f, +LINE_TO, 9.23f, 7.2f, +R_H_LINE_TO, 1.09f, +CLOSE, +R_MOVE_TO, -3.17f, 0.61f, +CLOSE, +R_MOVE_TO, 1.53f, -2.23f, +CLOSE, +R_MOVE_TO, -4.76f, 4.53f, +V_LINE_TO, 8.8f, +R_H_LINE_TO, 3.2f, +R_V_LINE_TO, 2.4f, +CLOSE, +MOVE_TO, 2.36f, 2.22f, +R_LINE_TO, 1.5f, 1.5f, +H_LINE_TO, 2.85f, +R_V_LINE_TO, 8.57f, +R_H_LINE_TO, 8.58f, +R_V_LINE_TO, -1, +R_LINE_TO, 1.51f, 1.52f, +R_ARC_TO, 1.69f, 1.69f, 0, 0, 1, -0.59f, 0.79f, +R_ARC_TO, 1.54f, 1.54f, 0, 0, 1, -0.94f, 0.33f, +H_LINE_TO, 2.85f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.15f, -0.48f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.48f, -1.16f, +R_V_LINE_TO, -8.57f, +R_CUBIC_TO, 0, -0.34f, 0.11f, -0.64f, 0.34f, -0.91f, +R_ARC_TO, 2.08f, 2.08f, 0, 0, 1, 0.8f, -0.59f, +CLOSE, +R_MOVE_TO, 5.57f, 5.57f, +R_LINE_TO, 2.66f, 2.66f, +R_V_LINE_TO, 0.75f, +H_LINE_TO, 7.93f, +CLOSE, +MOVE_TO, 4.94f, 4.8f, +LINE_TO, 7.36f, 7.22f, +V_LINE_TO, 8, +H_LINE_TO, 3.93f, +V_LINE_TO, 4.8f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/settings_chrome_refresh.icon b/components/vector_icons/settings_chrome_refresh.icon index 9611f12570..6d5e443 100644 --- a/components/vector_icons/settings_chrome_refresh.icon +++ b/components/vector_icons/settings_chrome_refresh.icon
@@ -2,62 +2,243 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 9.08f, 22.2f, +R_LINE_TO, -0.41f, -3.26f, +R_ARC_TO, 3.1f, 3.1f, 0, 0, 1, -0.52f, -0.26f, +R_ARC_TO, 7.01f, 7.01f, 0, 0, 1, -0.49f, -0.32f, +R_LINE_TO, -3.03f, 1.28f, +R_LINE_TO, -2.93f, -5.07f, +R_LINE_TO, 2.62f, -1.99f, +R_ARC_TO, 2.45f, 2.45f, 0, 0, 1, -0.02f, -0.29f, +R_V_LINE_TO, -0.58f, +R_CUBIC_TO, 0, -0.09f, 0.01f, -0.19f, 0.02f, -0.29f, +LINE_TO, 1.69f, 9.44f, +R_LINE_TO, 2.93f, -5.06f, +R_LINE_TO, 3.05f, 1.27f, +R_CUBIC_TO, 0.16f, -0.11f, 0.32f, -0.22f, 0.49f, -0.32f, +R_CUBIC_TO, 0.17f, -0.1f, 0.34f, -0.18f, 0.51f, -0.25f, +R_LINE_TO, 0.41f, -3.28f, +R_H_LINE_TO, 5.84f, +R_LINE_TO, 0.41f, 3.28f, +R_CUBIC_TO, 0.18f, 0.07f, 0.36f, 0.16f, 0.52f, 0.25f, +R_CUBIC_TO, 0.17f, 0.1f, 0.33f, 0.21f, 0.49f, 0.32f, +R_LINE_TO, 3.04f, -1.27f, +R_LINE_TO, 2.93f, 5.06f, +R_LINE_TO, -2.63f, 1.99f, +R_CUBIC_TO, 0.01f, 0.1f, 0.02f, 0.2f, 0.02f, 0.29f, +V_LINE_TO, 12, +R_CUBIC_TO, 0, 0.1f, 0, 0.2f, 0, 0.29f, +R_CUBIC_TO, 0, 0.09f, -0.01f, 0.19f, -0.04f, 0.29f, +R_LINE_TO, 2.63f, 1.99f, +R_LINE_TO, -2.94f, 5.07f, +R_LINE_TO, -3.02f, -1.28f, +R_CUBIC_TO, -0.16f, 0.11f, -0.32f, 0.22f, -0.49f, 0.32f, +R_ARC_TO, 3.65f, 3.65f, 0, 0, 1, -0.51f, 0.26f, +R_LINE_TO, -0.41f, 3.27f, +CLOSE, +R_MOVE_TO, 1.99f, -2.27f, +R_H_LINE_TO, 1.84f, +R_LINE_TO, 0.36f, -2.64f, +R_ARC_TO, 5.7f, 5.7f, 0, 0, 0, 1.46f, -0.59f, +R_CUBIC_TO, 0.45f, -0.26f, 0.86f, -0.58f, 1.23f, -0.97f, +R_LINE_TO, 2.47f, 1.03f, +R_LINE_TO, 0.9f, -1.59f, +R_LINE_TO, -2.13f, -1.61f, +R_ARC_TO, 4.01f, 4.01f, 0, 0, 0, 0.18f, -0.75f, +R_CUBIC_TO, 0.04f, -0.26f, 0.06f, -0.53f, 0.06f, -0.8f, +R_CUBIC_TO, 0, -0.27f, -0.02f, -0.54f, -0.05f, -0.8f, +R_ARC_TO, 4.01f, 4.01f, 0, 0, 0, -0.18f, -0.75f, +R_LINE_TO, 2.14f, -1.61f, +R_LINE_TO, -0.91f, -1.59f, +LINE_TO, 15.95f, 8.29f, +R_ARC_TO, 5.36f, 5.36f, 0, 0, 0, -2.69f, -1.58f, +R_LINE_TO, -0.32f, -2.64f, +R_H_LINE_TO, -1.85f, +R_LINE_TO, -0.34f, 2.63f, +R_ARC_TO, 5.59f, 5.59f, 0, 0, 0, -1.47f, 0.59f, +R_CUBIC_TO, -0.45f, 0.27f, -0.87f, 0.59f, -1.24f, 0.97f, +LINE_TO, 5.58f, 7.24f, +R_LINE_TO, -0.91f, 1.59f, +R_LINE_TO, 2.13f, 1.58f, +R_ARC_TO, 4.66f, 4.66f, 0, 0, 0, -0.18f, 0.77f, +R_CUBIC_TO, -0.04f, 0.26f, -0.06f, 0.53f, -0.06f, 0.82f, +R_CUBIC_TO, 0, 0.27f, 0.02f, 0.54f, 0.06f, 0.79f, +R_CUBIC_TO, 0.04f, 0.26f, 0.1f, 0.52f, 0.18f, 0.77f, +R_LINE_TO, -2.12f, 1.6f, +R_LINE_TO, 0.91f, 1.59f, +R_LINE_TO, 2.46f, -1.05f, +R_ARC_TO, 5.63f, 5.63f, 0, 0, 0, 2.71f, 1.58f, +CLOSE, +R_MOVE_TO, 0.97f, -4.43f, +R_ARC_TO, 3.37f, 3.37f, 0, 0, 0, 2.48f, -1.02f, +ARC_TO, 3.38f, 3.38f, 0, 0, 0, 15.53f, 12, +R_CUBIC_TO, 0, -0.96f, -0.34f, -1.79f, -1.02f, -2.48f, +ARC_TO, 3.37f, 3.37f, 0, 0, 0, 12.03f, 8.5f, +R_CUBIC_TO, -0.98f, 0, -1.81f, 0.34f, -2.48f, 1.02f, +ARC_TO, 3.4f, 3.4f, 0, 0, 0, 8.53f, 12, +R_ARC_TO, 3.4f, 3.4f, 0, 0, 0, 1.02f, 2.48f, +R_CUBIC_TO, 0.68f, 0.68f, 1.5f, 1.02f, 2.48f, 1.02f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 8.25f, 18.17f, +R_LINE_TO, -0.47f, -2.43f, +R_ARC_TO, 6.5f, 6.5f, 0, 0, 1, -0.85f, -0.4f, +R_ARC_TO, 4.63f, 4.63f, 0, 0, 1, -0.78f, -0.54f, +R_LINE_TO, -2.34f, 0.8f, +R_LINE_TO, -1.75f, -3.04f, +R_LINE_TO, 1.85f, -1.61f, +R_ARC_TO, 6.17f, 6.17f, 0, 0, 1, -0.05f, -0.46f, +R_ARC_TO, 4.71f, 4.71f, 0, 0, 1, 0, -0.96f, +R_CUBIC_TO, 0.01f, -0.15f, 0.03f, -0.31f, 0.05f, -0.46f, +LINE_TO, 2.05f, 7.45f, +R_LINE_TO, 1.75f, -3.03f, +R_LINE_TO, 2.35f, 0.79f, +R_CUBIC_TO, 0.25f, -0.21f, 0.5f, -0.39f, 0.77f, -0.53f, +R_CUBIC_TO, 0.27f, -0.15f, 0.56f, -0.28f, 0.85f, -0.4f, +R_LINE_TO, 0.47f, -2.44f, +R_H_LINE_TO, 3.5f, +R_LINE_TO, 0.47f, 2.44f, +R_CUBIC_TO, 0.29f, 0.12f, 0.57f, 0.25f, 0.85f, 0.4f, +R_CUBIC_TO, 0.28f, 0.15f, 0.54f, 0.33f, 0.78f, 0.54f, +R_LINE_TO, 2.34f, -0.79f, +R_LINE_TO, 1.75f, 3.03f, +R_LINE_TO, -1.86f, 1.61f, +R_CUBIC_TO, 0.03f, 0.15f, 0.04f, 0.31f, 0.06f, 0.46f, +R_CUBIC_TO, 0.02f, 0.15f, 0.02f, 0.31f, 0.02f, 0.48f, +R_CUBIC_TO, 0, 0.17f, -0.01f, 0.33f, -0.02f, 0.48f, +R_CUBIC_TO, -0.02f, 0.15f, -0.03f, 0.31f, -0.05f, 0.46f, +R_LINE_TO, 1.86f, 1.61f, +R_LINE_TO, -1.76f, 3.04f, +R_LINE_TO, -2.35f, -0.8f, +R_ARC_TO, 5.1f, 5.1f, 0, 0, 1, -0.77f, 0.54f, +R_CUBIC_TO, -0.27f, 0.16f, -0.56f, 0.29f, -0.85f, 0.4f, +R_LINE_TO, -0.47f, 2.43f, +CLOSE, +R_MOVE_TO, 1.43f, -1.73f, +R_H_LINE_TO, 0.64f, +R_LINE_TO, 0.4f, -2.05f, +R_ARC_TO, 4.71f, 4.71f, 0, 0, 0, 1.5f, -0.54f, +R_ARC_TO, 4.15f, 4.15f, 0, 0, 0, 1.2f, -1.02f, +R_LINE_TO, 1.99f, 0.67f, +R_LINE_TO, 0.32f, -0.53f, +R_LINE_TO, -1.57f, -1.39f, +R_CUBIC_TO, 0.08f, -0.24f, 0.15f, -0.49f, 0.2f, -0.75f, +R_CUBIC_TO, 0.05f, -0.26f, 0.08f, -0.53f, 0.08f, -0.81f, +R_CUBIC_TO, 0, -0.28f, -0.02f, -0.55f, -0.08f, -0.81f, +R_ARC_TO, 5.76f, 5.76f, 0, 0, 0, -0.2f, -0.75f, +R_LINE_TO, 1.58f, -1.39f, +R_LINE_TO, -0.33f, -0.53f, +R_LINE_TO, -1.99f, 0.67f, +R_ARC_TO, 4.26f, 4.26f, 0, 0, 0, -1.2f, -1.02f, +R_ARC_TO, 4.57f, 4.57f, 0, 0, 0, -1.5f, -0.54f, +LINE_TO, 10.32f, 3.56f, +R_H_LINE_TO, -0.64f, +R_LINE_TO, -0.39f, 2.05f, +R_CUBIC_TO, -0.54f, 0.1f, -1.04f, 0.28f, -1.51f, 0.55f, +R_CUBIC_TO, -0.47f, 0.27f, -0.87f, 0.61f, -1.21f, 1.03f, +R_LINE_TO, -1.99f, -0.67f, +R_LINE_TO, -0.32f, 0.54f, +LINE_TO, 5.83f, 8.43f, +R_ARC_TO, 5.21f, 5.21f, 0, 0, 0, -0.2f, 0.75f, +ARC_TO, 4.02f, 4.02f, 0, 0, 0, 5.55f, 10, +R_CUBIC_TO, 0, 0.28f, 0.02f, 0.56f, 0.08f, 0.82f, +R_CUBIC_TO, 0.05f, 0.27f, 0.12f, 0.52f, 0.2f, 0.76f, +R_LINE_TO, -1.57f, 1.38f, +R_LINE_TO, 0.32f, 0.54f, +R_LINE_TO, 1.99f, -0.66f, +R_CUBIC_TO, 0.34f, 0.41f, 0.74f, 0.75f, 1.21f, 1.02f, +R_CUBIC_TO, 0.47f, 0.27f, 0.97f, 0.45f, 1.51f, 0.55f, +CLOSE, +MOVE_TO, 9.98f, 13, +R_CUBIC_TO, 0.84f, 0, 1.54f, -0.29f, 2.13f, -0.87f, +R_CUBIC_TO, 0.59f, -0.58f, 0.88f, -1.29f, 0.88f, -2.12f, +R_CUBIC_TO, 0, -0.83f, -0.29f, -1.54f, -0.87f, -2.12f, +ARC_TO, 2.89f, 2.89f, 0, 0, 0, 9.98f, 7, +R_CUBIC_TO, -0.83f, 0, -1.53f, 0.29f, -2.12f, 0.88f, +ARC_TO, 2.89f, 2.89f, 0, 0, 0, 6.98f, 10, +R_CUBIC_TO, 0, 0.83f, 0.29f, 1.54f, 0.88f, 2.13f, +R_ARC_TO, 2.9f, 2.9f, 0, 0, 0, 2.12f, 0.88f, +CLOSE + CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 12.97f, 7.7f, -R_LINE_TO, 1.84f, -1.9f, -R_LINE_TO, -1.5f, -2.6f, -R_LINE_TO, -2.55f, 0.64f, -R_CUBIC_TO, -0.17f, -0.11f, -0.36f, -0.2f, -0.54f, -0.29f, -LINE_TO, 9.49f, 1, -R_H_LINE_TO, -3, -R_LINE_TO, -0.73f, 2.55f, -R_CUBIC_TO, -0.18f, 0.09f, -0.37f, 0.18f, -0.54f, 0.29f, -LINE_TO, 2.67f, 3.2f, -R_LINE_TO, -1.5f, 2.6f, -R_LINE_TO, 1.84f, 1.9f, -R_V_LINE_TO, 0.59f, -R_LINE_TO, -1.84f, 1.9f, -R_LINE_TO, 1.5f, 2.6f, -R_LINE_TO, 2.55f, -0.64f, -R_CUBIC_TO, 0.17f, 0.11f, 0.36f, 0.2f, 0.54f, 0.29f, -R_LINE_TO, 0.73f, 2.55f, -R_H_LINE_TO, 3, -R_LINE_TO, 0.73f, -2.55f, -R_CUBIC_TO, 0.18f, -0.09f, 0.37f, -0.18f, 0.54f, -0.29f, -R_LINE_TO, 2.55f, 0.64f, -R_LINE_TO, 1.5f, -2.6f, -R_LINE_TO, -1.84f, -1.9f, -V_LINE_TO, 7.7f, +R_MOVE_TO, 6.45f, 14.72f, +R_LINE_TO, -0.39f, -2, +R_ARC_TO, 5.29f, 5.29f, 0, 0, 1, -0.61f, -0.28f, +R_CUBIC_TO, -0.2f, -0.11f, -0.38f, -0.24f, -0.56f, -0.38f, +R_LINE_TO, -1.93f, 0.66f, +R_LINE_TO, -1.57f, -2.73f, +R_LINE_TO, 1.52f, -1.32f, +R_CUBIC_TO, -0.02f, -0.1f, -0.03f, -0.21f, -0.04f, -0.32f, +ARC_TO, 3.1f, 3.1f, 0, 0, 1, 2.87f, 8, +R_CUBIC_TO, 0, -0.12f, 0, -0.23f, 0.02f, -0.34f, +R_CUBIC_TO, 0.01f, -0.11f, 0.02f, -0.22f, 0.04f, -0.32f, +LINE_TO, 1.4f, 6.01f, +LINE_TO, 2.97f, 3.31f, +R_LINE_TO, 1.95f, 0.65f, +R_CUBIC_TO, 0.18f, -0.14f, 0.36f, -0.27f, 0.54f, -0.37f, +R_CUBIC_TO, 0.19f, -0.1f, 0.39f, -0.2f, 0.6f, -0.28f, +R_LINE_TO, 0.39f, -2.02f, +R_H_LINE_TO, 3.11f, +R_LINE_TO, 0.39f, 2.02f, +R_CUBIC_TO, 0.21f, 0.08f, 0.41f, 0.18f, 0.61f, 0.28f, +R_CUBIC_TO, 0.2f, 0.11f, 0.38f, 0.23f, 0.56f, 0.38f, +R_LINE_TO, 1.93f, -0.65f, +R_LINE_TO, 1.57f, 2.71f, +R_LINE_TO, -1.54f, 1.32f, +R_CUBIC_TO, 0.02f, 0.11f, 0.03f, 0.22f, 0.04f, 0.32f, +R_CUBIC_TO, 0.01f, 0.11f, 0.02f, 0.22f, 0.02f, 0.34f, +R_CUBIC_TO, 0, 0.12f, -0.01f, 0.23f, -0.02f, 0.34f, +R_LINE_TO, -0.04f, 0.32f, +R_LINE_TO, 1.54f, 1.32f, +R_LINE_TO, -1.57f, 2.73f, +R_LINE_TO, -1.94f, -0.66f, +R_ARC_TO, 4.15f, 4.15f, 0, 0, 1, -0.54f, 0.38f, +R_CUBIC_TO, -0.19f, 0.11f, -0.39f, 0.2f, -0.6f, 0.28f, +R_LINE_TO, -0.39f, 2.01f, CLOSE, -R_MOVE_TO, -1.54f, 1.16f, -R_LINE_TO, 1.51f, 1.56f, -R_LINE_TO, -0.37f, 0.64f, -R_LINE_TO, -2.09f, -0.52f, -R_CUBIC_TO, -0.74f, 0.49f, -0.4f, 0.3f, -1.52f, 0.86f, -R_LINE_TO, -0.6f, 2.09f, -R_H_LINE_TO, -0.74f, -R_LINE_TO, -0.6f, -2.09f, -R_CUBIC_TO, -1.12f, -0.56f, -0.78f, -0.37f, -1.52f, -0.86f, -R_LINE_TO, -2.09f, 0.52f, -R_LINE_TO, -0.37f, -0.64f, -R_LINE_TO, 1.5f, -1.57f, -R_CUBIC_TO, -0.04f, -1.02f, -0.04f, -0.81f, 0.01f, -1.73f, -LINE_TO, 3.04f, 5.56f, -R_LINE_TO, 0.37f, -0.64f, -R_LINE_TO, 2.09f, 0.52f, -R_CUBIC_TO, 0.74f, -0.49f, 0.4f, -0.3f, 1.52f, -0.86f, -R_LINE_TO, 0.6f, -2.09f, -R_H_LINE_TO, 0.74f, -R_LINE_TO, 0.6f, 2.09f, -R_CUBIC_TO, 1.12f, 0.56f, 0.78f, 0.37f, 1.52f, 0.86f, -R_LINE_TO, 2.09f, -0.52f, -R_LINE_TO, 0.37f, 0.64f, -R_LINE_TO, -1.5f, 1.57f, -R_CUBIC_TO, 0.04f, 1.02f, 0.04f, 0.81f, -0.01f, 1.73f, +R_MOVE_TO, 1.36f, -1.63f, +R_H_LINE_TO, 0.38f, +R_LINE_TO, 0.32f, -1.63f, +R_CUBIC_TO, 0.43f, -0.08f, 0.84f, -0.23f, 1.22f, -0.44f, +R_CUBIC_TO, 0.38f, -0.21f, 0.71f, -0.5f, 0.97f, -0.84f, +R_LINE_TO, 1.59f, 0.53f, +R_LINE_TO, 0.19f, -0.33f, +R_LINE_TO, -1.24f, -1.1f, +R_CUBIC_TO, 0.07f, -0.2f, 0.12f, -0.41f, 0.17f, -0.62f, +R_ARC_TO, 3.32f, 3.32f, 0, 0, 0, 0, -1.32f, +R_ARC_TO, 6.61f, 6.61f, 0, 0, 0, -0.17f, -0.62f, +LINE_TO, 12.5f, 5.62f, +R_LINE_TO, -0.21f, -0.33f, +R_LINE_TO, -1.58f, 0.53f, +R_ARC_TO, 3.37f, 3.37f, 0, 0, 0, -0.97f, -0.84f, +R_ARC_TO, 3.69f, 3.69f, 0, 0, 0, -1.23f, -0.44f, +R_LINE_TO, -0.32f, -1.63f, +R_H_LINE_TO, -0.4f, +R_LINE_TO, -0.3f, 1.62f, +R_CUBIC_TO, -0.44f, 0.07f, -0.85f, 0.22f, -1.24f, 0.44f, +R_ARC_TO, 3.4f, 3.4f, 0, 0, 0, -0.99f, 0.85f, +R_LINE_TO, -1.57f, -0.53f, +R_LINE_TO, -0.19f, 0.33f, +R_LINE_TO, 1.23f, 1.09f, +R_CUBIC_TO, -0.07f, 0.2f, -0.12f, 0.41f, -0.17f, 0.63f, +ARC_TO, 3.11f, 3.11f, 0, 0, 0, 4.5f, 8, +R_CUBIC_TO, 0, 0.23f, 0.02f, 0.45f, 0.07f, 0.67f, +R_CUBIC_TO, 0.04f, 0.22f, 0.1f, 0.43f, 0.17f, 0.63f, +LINE_TO, 3.5f, 10.38f, +R_LINE_TO, 0.2f, 0.33f, +R_LINE_TO, 1.58f, -0.52f, +R_CUBIC_TO, 0.27f, 0.34f, 0.6f, 0.61f, 0.99f, 0.84f, +R_CUBIC_TO, 0.39f, 0.22f, 0.8f, 0.37f, 1.23f, 0.45f, CLOSE, -NEW_PATH, -MOVE_TO, 8, 10.5f, -R_ARC_TO, 2.5f, 2.5f, 0, 1, 0, 0, -5, -R_ARC_TO, 2.5f, 2.5f, 0, 0, 0, 0, 5, -CLOSE, -NEW_PATH \ No newline at end of file +R_MOVE_TO, 0.17f, -2.69f, +R_CUBIC_TO, 0.66f, 0, 1.23f, -0.23f, 1.7f, -0.7f, +R_CUBIC_TO, 0.47f, -0.46f, 0.7f, -1.03f, 0.7f, -1.7f, +R_CUBIC_TO, 0, -0.67f, -0.23f, -1.23f, -0.7f, -1.7f, +R_ARC_TO, 2.31f, 2.31f, 0, 0, 0, -1.7f, -0.7f, +R_CUBIC_TO, -0.66f, 0, -1.23f, 0.23f, -1.69f, 0.7f, +ARC_TO, 2.29f, 2.29f, 0, 0, 0, 5.57f, 8, +R_CUBIC_TO, 0, 0.67f, 0.24f, 1.23f, 0.71f, 1.7f, +R_CUBIC_TO, 0.47f, 0.47f, 1.03f, 0.7f, 1.7f, 0.7f, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/sync_chrome_refresh.icon b/components/vector_icons/sync_chrome_refresh.icon index edd1538..36297ae 100644 --- a/components/vector_icons/sync_chrome_refresh.icon +++ b/components/vector_icons/sync_chrome_refresh.icon
@@ -2,41 +2,119 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 16, -MOVE_TO, 3.61f, 12.88f, -V_LINE_TO, 11.62f, -R_H_LINE_TO, 1.1f, -R_LINE_TO, 0.05f, 0.04f, -R_ARC_TO, 5.3f, 5.3f, 0, 0, 1, -1.21f, -1.63f, -ARC_TO, 4.57f, 4.57f, 0, 0, 1, 3.1f, 8, -R_CUBIC_TO, 0, -1.16f, 0.36f, -2.18f, 1.08f, -3.06f, -R_ARC_TO, 4.88f, 4.88f, 0, 0, 1, 2.72f, -1.7f, -R_V_LINE_TO, 1.43f, -R_ARC_TO, 3.49f, 3.49f, 0, 0, 0, -1.73f, 1.25f, -R_CUBIC_TO, -0.45f, 0.6f, -0.68f, 1.29f, -0.68f, 2.07f, -R_CUBIC_TO, 0, 0.52f, 0.11f, 1, 0.32f, 1.44f, -R_CUBIC_TO, 0.22f, 0.45f, 0.5f, 0.83f, 0.86f, 1.14f, -R_LINE_TO, -0.03f, -0.03f, -V_LINE_TO, 9.6f, -R_H_LINE_TO, 1.26f, -R_V_LINE_TO, 3.28f, +CANVAS_DIMENSIONS, 24, +MOVE_TO, 4.01f, 20.12f, +R_V_LINE_TO, -2.09f, +R_H_LINE_TO, 2.55f, +R_LINE_TO, -0.32f, -0.29f, +R_CUBIC_TO, -0.87f, -0.79f, -1.49f, -1.68f, -1.85f, -2.67f, +R_ARC_TO, 8.73f, 8.73f, 0, 0, 1, -0.54f, -3.01f, +R_CUBIC_TO, 0, -1.91f, 0.59f, -3.61f, 1.75f, -5.09f, +R_CUBIC_TO, 1.17f, -1.48f, 2.68f, -2.44f, 4.54f, -2.89f, +R_V_LINE_TO, 2.38f, +R_ARC_TO, 5.66f, 5.66f, 0, 0, 0, -2.91f, 2.15f, +R_ARC_TO, 5.82f, 5.82f, 0, 0, 0, -1.11f, 3.47f, +R_CUBIC_TO, 0, 0.73f, 0.14f, 1.43f, 0.42f, 2.13f, +R_ARC_TO, 5.86f, 5.86f, 0, 0, 0, 1.29f, 1.92f, +R_LINE_TO, 0.2f, 0.2f, +V_LINE_TO, 14, +R_H_LINE_TO, 2.09f, +R_V_LINE_TO, 6.12f, CLOSE, -R_MOVE_TO, 5.49f, -0.12f, -R_V_LINE_TO, -1.43f, -R_ARC_TO, 3.49f, 3.49f, 0, 0, 0, 1.73f, -1.25f, -R_CUBIC_TO, 0.45f, -0.6f, 0.68f, -1.29f, 0.68f, -2.07f, -R_CUBIC_TO, 0, -0.52f, -0.11f, -1, -0.32f, -1.44f, -R_ARC_TO, 3.61f, 3.61f, 0, 0, 0, -0.85f, -1.14f, -R_LINE_TO, 0.03f, 0.03f, -R_V_LINE_TO, 0.95f, -H_LINE_TO, 9.12f, -V_LINE_TO, 3.12f, -R_H_LINE_TO, 3.27f, -V_LINE_TO, 4.38f, -R_H_LINE_TO, -1.1f, -R_LINE_TO, -0.05f, -0.04f, -R_CUBIC_TO, 0.51f, 0.46f, 0.91f, 1, 1.21f, 1.63f, -R_CUBIC_TO, 0.3f, 0.63f, 0.45f, 1.31f, 0.45f, 2.04f, -R_CUBIC_TO, 0, 1.16f, -0.36f, 2.18f, -1.08f, 3.06f, -R_ARC_TO, 4.88f, 4.88f, 0, 0, 1, -2.72f, 1.7f, +R_MOVE_TO, 9.84f, -0.19f, +R_V_LINE_TO, -2.37f, +R_ARC_TO, 5.66f, 5.66f, 0, 0, 0, 2.91f, -2.14f, +R_ARC_TO, 5.82f, 5.82f, 0, 0, 0, 1.11f, -3.46f, +R_CUBIC_TO, 0, -0.73f, -0.14f, -1.43f, -0.42f, -2.12f, +R_ARC_TO, 5.86f, 5.86f, 0, 0, 0, -1.29f, -1.92f, +R_LINE_TO, -0.2f, -0.2f, +V_LINE_TO, 10, +R_H_LINE_TO, -2.09f, +V_LINE_TO, 3.88f, +R_H_LINE_TO, 6.11f, +R_V_LINE_TO, 2.09f, +R_H_LINE_TO, -2.55f, +R_LINE_TO, 0.32f, 0.29f, +R_CUBIC_TO, 0.83f, 0.83f, 1.43f, 1.73f, 1.82f, 2.71f, +R_CUBIC_TO, 0.38f, 0.98f, 0.57f, 1.97f, 0.57f, 2.98f, +R_CUBIC_TO, 0, 1.91f, -0.58f, 3.61f, -1.75f, 5.09f, +R_CUBIC_TO, -1.17f, 1.48f, -2.68f, 2.44f, -4.54f, 2.9f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.51f, 16.1f, +R_V_LINE_TO, -1.58f, +R_H_LINE_TO, 1.38f, +R_LINE_TO, 0.07f, 0.05f, +R_ARC_TO, 6.67f, 6.67f, 0, 0, 1, -1.51f, -2.03f, +ARC_TO, 5.79f, 5.79f, 0, 0, 1, 3.88f, 10, +R_CUBIC_TO, 0, -1.46f, 0.45f, -2.73f, 1.35f, -3.82f, +R_ARC_TO, 6.1f, 6.1f, 0, 0, 1, 3.4f, -2.12f, +R_V_LINE_TO, 1.79f, +R_ARC_TO, 4.41f, 4.41f, 0, 0, 0, -2.17f, 1.56f, +R_CUBIC_TO, -0.57f, 0.75f, -0.85f, 1.61f, -0.85f, 2.59f, +R_CUBIC_TO, 0, 0.65f, 0.13f, 1.25f, 0.4f, 1.8f, +R_ARC_TO, 4.45f, 4.45f, 0, 0, 0, 1.07f, 1.43f, +R_LINE_TO, -0.04f, -0.04f, +V_LINE_TO, 12, +R_H_LINE_TO, 1.57f, +R_V_LINE_TO, 4.1f, +CLOSE, +R_MOVE_TO, 6.86f, -0.16f, +R_V_LINE_TO, -1.79f, +R_ARC_TO, 4.41f, 4.41f, 0, 0, 0, 2.17f, -1.56f, +R_CUBIC_TO, 0.57f, -0.75f, 0.85f, -1.61f, 0.85f, -2.59f, +R_CUBIC_TO, 0, -0.65f, -0.13f, -1.25f, -0.4f, -1.8f, +R_ARC_TO, 4.45f, 4.45f, 0, 0, 0, -1.07f, -1.43f, +R_LINE_TO, 0.04f, 0.04f, +V_LINE_TO, 8, +R_H_LINE_TO, -1.57f, +V_LINE_TO, 3.9f, +R_H_LINE_TO, 4.09f, +R_V_LINE_TO, 1.58f, +R_H_LINE_TO, -1.37f, +R_LINE_TO, -0.07f, -0.05f, +R_ARC_TO, 6.38f, 6.38f, 0, 0, 1, 1.52f, 2.03f, +R_CUBIC_TO, 0.38f, 0.79f, 0.56f, 1.63f, 0.56f, 2.55f, +R_CUBIC_TO, 0, 1.46f, -0.45f, 2.73f, -1.35f, 3.82f, +R_ARC_TO, 6.1f, 6.1f, 0, 0, 1, -3.4f, 2.12f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3.62f, 12.99f, +R_V_LINE_TO, -1.34f, +R_H_LINE_TO, 0.93f, +R_LINE_TO, 0.12f, 0.09f, +R_ARC_TO, 5.92f, 5.92f, 0, 0, 1, -1.23f, -1.68f, +ARC_TO, 4.62f, 4.62f, 0, 0, 1, 2.96f, 8, +R_CUBIC_TO, 0, -1.22f, 0.39f, -2.29f, 1.17f, -3.2f, +R_ARC_TO, 5.07f, 5.07f, 0, 0, 1, 2.91f, -1.73f, +R_V_LINE_TO, 1.68f, +R_CUBIC_TO, -0.71f, 0.2f, -1.29f, 0.59f, -1.75f, 1.19f, +ARC_TO, 3.28f, 3.28f, 0, 0, 0, 4.6f, 8, +R_CUBIC_TO, 0, 0.5f, 0.11f, 0.96f, 0.31f, 1.38f, +R_CUBIC_TO, 0.21f, 0.43f, 0.48f, 0.8f, 0.82f, 1.11f, +R_LINE_TO, -0.07f, -0.07f, +R_V_LINE_TO, -0.81f, +R_H_LINE_TO, 1.34f, +R_V_LINE_TO, 3.39f, +CLOSE, +R_MOVE_TO, 5.35f, -0.06f, +R_V_LINE_TO, -1.68f, +R_CUBIC_TO, 0.71f, -0.2f, 1.29f, -0.59f, 1.75f, -1.19f, +ARC_TO, 3.28f, 3.28f, 0, 0, 0, 11.4f, 8, +R_CUBIC_TO, 0, -0.5f, -0.1f, -0.96f, -0.31f, -1.38f, +R_ARC_TO, 3.57f, 3.57f, 0, 0, 0, -0.82f, -1.1f, +R_LINE_TO, 0.07f, 0.07f, +R_V_LINE_TO, 0.81f, +R_H_LINE_TO, -1.34f, +V_LINE_TO, 3.01f, +R_H_LINE_TO, 3.38f, +R_V_LINE_TO, 1.34f, +R_H_LINE_TO, -0.93f, +R_LINE_TO, -0.12f, -0.09f, +R_CUBIC_TO, 0.52f, 0.47f, 0.93f, 1.03f, 1.24f, 1.67f, +R_CUBIC_TO, 0.31f, 0.64f, 0.46f, 1.33f, 0.46f, 2.07f, +R_CUBIC_TO, 0, 1.22f, -0.39f, 2.29f, -1.16f, 3.2f, +R_ARC_TO, 5.07f, 5.07f, 0, 0, 1, -2.91f, 1.73f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/sync_off_chrome_refresh.icon b/components/vector_icons/sync_off_chrome_refresh.icon index 2fbd9e2..10c15e0df 100644 --- a/components/vector_icons/sync_off_chrome_refresh.icon +++ b/components/vector_icons/sync_off_chrome_refresh.icon
@@ -2,58 +2,164 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 19.76f, 22.66f, +LINE_TO, 16.1f, 19, +R_CUBIC_TO, -0.35f, 0.2f, -0.71f, 0.39f, -1.09f, 0.55f, +R_CUBIC_TO, -0.38f, 0.16f, -0.78f, 0.29f, -1.2f, 0.39f, +R_V_LINE_TO, -2.37f, +R_CUBIC_TO, 0.11f, -0.03f, 0.21f, -0.07f, 0.31f, -0.11f, +R_CUBIC_TO, 0.1f, -0.04f, 0.2f, -0.08f, 0.31f, -0.12f, +LINE_TO, 6.64f, 9.54f, +R_CUBIC_TO, -0.17f, 0.4f, -0.31f, 0.8f, -0.41f, 1.22f, +R_ARC_TO, 5.66f, 5.66f, 0, 0, 0, 0.27f, 3.41f, +R_ARC_TO, 5.83f, 5.83f, 0, 0, 0, 1.29f, 1.93f, +R_LINE_TO, 0.2f, 0.2f, +V_LINE_TO, 14, +R_H_LINE_TO, 2.09f, +R_V_LINE_TO, 6.12f, +H_LINE_TO, 3.97f, +R_V_LINE_TO, -2.09f, +R_H_LINE_TO, 2.56f, +R_LINE_TO, -0.33f, -0.29f, +R_CUBIC_TO, -0.83f, -0.83f, -1.43f, -1.73f, -1.82f, -2.71f, +R_ARC_TO, 8.17f, 8.17f, 0, 0, 1, 0.58f, -7.18f, +R_LINE_TO, -3.6f, -3.59f, +LINE_TO, 2.85f, 2.77f, +LINE_TO, 21.25f, 21.17f, +CLOSE, +R_MOVE_TO, -0.75f, -6.57f, +LINE_TO, 17.3f, 14.38f, +R_CUBIC_TO, 0.17f, -0.37f, 0.3f, -0.77f, 0.39f, -1.18f, +R_ARC_TO, 5.73f, 5.73f, 0, 0, 0, -0.28f, -3.37f, +R_ARC_TO, 5.86f, 5.86f, 0, 0, 0, -1.29f, -1.92f, +R_LINE_TO, -0.21f, -0.2f, +V_LINE_TO, 10, +R_H_LINE_TO, -2.09f, +V_LINE_TO, 3.88f, +R_H_LINE_TO, 6.12f, +R_V_LINE_TO, 2.09f, +R_H_LINE_TO, -2.56f, +R_LINE_TO, 0.33f, 0.29f, +R_CUBIC_TO, 0.83f, 0.83f, 1.43f, 1.73f, 1.82f, 2.71f, +R_ARC_TO, 8.17f, 8.17f, 0, 0, 1, 0.28f, 5.16f, +R_ARC_TO, 9.33f, 9.33f, 0, 0, 1, -0.8f, 1.96f, +CLOSE, +R_MOVE_TO, -9.43f, -9.43f, +LINE_TO, 7.88f, 4.95f, +R_CUBIC_TO, 0.34f, -0.2f, 0.7f, -0.37f, 1.07f, -0.51f, +R_CUBIC_TO, 0.37f, -0.14f, 0.75f, -0.27f, 1.16f, -0.37f, +R_V_LINE_TO, 2.38f, +R_ARC_TO, 9.77f, 9.77f, 0, 0, 1, -0.26f, 0.09f, +R_CUBIC_TO, -0.09f, 0.03f, -0.18f, 0.07f, -0.26f, 0.12f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 15.97f, 17.11f, +R_LINE_TO, -2.93f, -2.92f, +R_ARC_TO, 7.31f, 7.31f, 0, 0, 1, -0.82f, 0.42f, +R_ARC_TO, 4.51f, 4.51f, 0, 0, 1, -0.88f, 0.3f, +R_V_LINE_TO, -1.81f, +R_CUBIC_TO, 0.07f, -0.03f, 0.14f, -0.06f, 0.22f, -0.09f, +R_CUBIC_TO, 0.07f, -0.03f, 0.14f, -0.06f, 0.21f, -0.09f, +R_LINE_TO, -5.78f, -5.8f, +R_CUBIC_TO, -0.13f, 0.28f, -0.23f, 0.57f, -0.3f, 0.87f, +R_ARC_TO, 3.81f, 3.81f, 0, 0, 0, -0.11f, 0.95f, +R_CUBIC_TO, 0, 0.64f, 0.13f, 1.24f, 0.4f, 1.8f, +R_ARC_TO, 4.45f, 4.45f, 0, 0, 0, 1.07f, 1.43f, +R_LINE_TO, -0.04f, -0.04f, +R_V_LINE_TO, -1.19f, +H_LINE_TO, 8.57f, +R_V_LINE_TO, 4.1f, +H_LINE_TO, 4.47f, +R_V_LINE_TO, -1.58f, +R_H_LINE_TO, 1.38f, +R_LINE_TO, 0.06f, 0.05f, +R_ARC_TO, 6.38f, 6.38f, 0, 0, 1, -1.52f, -2.03f, +R_ARC_TO, 5.88f, 5.88f, 0, 0, 1, -0.56f, -2.55f, +R_CUBIC_TO, 0, -0.57f, 0.07f, -1.11f, 0.23f, -1.64f, +R_ARC_TO, 6.28f, 6.28f, 0, 0, 1, 0.63f, -1.46f, +LINE_TO, 1.84f, 2.97f, +R_LINE_TO, 1.12f, -1.12f, +R_LINE_TO, 14.13f, 14.15f, +CLOSE, +R_MOVE_TO, -0.73f, -5.09f, +R_LINE_TO, -1.3f, -1.3f, +R_ARC_TO, 4.64f, 4.64f, 0, 0, 0, 0.3f, -0.85f, +R_ARC_TO, 4.24f, 4.24f, 0, 0, 0, -0.28f, -2.75f, +R_ARC_TO, 4.46f, 4.46f, 0, 0, 0, -1.07f, -1.44f, +R_LINE_TO, 0.04f, 0.04f, +R_V_LINE_TO, 1.21f, +R_H_LINE_TO, -1.57f, +V_LINE_TO, 2.84f, +R_H_LINE_TO, 4.1f, +R_V_LINE_TO, 1.58f, +R_H_LINE_TO, -1.38f, +R_LINE_TO, -0.06f, -0.05f, +R_ARC_TO, 6.31f, 6.31f, 0, 0, 1, 1.51f, 2.03f, +R_CUBIC_TO, 0.38f, 0.79f, 0.56f, 1.63f, 0.56f, 2.55f, +R_CUBIC_TO, 0, 0.57f, -0.07f, 1.11f, -0.22f, 1.63f, +R_ARC_TO, 5.92f, 5.92f, 0, 0, 1, -0.62f, 1.46f, +CLOSE, +R_MOVE_TO, -7.07f, -7.07f, +LINE_TO, 6.9f, 3.67f, +R_ARC_TO, 7.13f, 7.13f, 0, 0, 1, 0.81f, -0.41f, +R_CUBIC_TO, 0.28f, -0.12f, 0.57f, -0.22f, 0.88f, -0.29f, +R_V_LINE_TO, 1.81f, +R_CUBIC_TO, -0.07f, 0.03f, -0.14f, 0.06f, -0.21f, 0.09f, +R_ARC_TO, 1.92f, 1.92f, 0, 0, 1, -0.21f, 0.09f, +CLOSE + CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 12.77f, 13.69f, -R_LINE_TO, -2.34f, -2.34f, -R_CUBIC_TO, -0.21f, 0.13f, -0.43f, 0.24f, -0.65f, 0.34f, -R_CUBIC_TO, -0.23f, 0.1f, -0.46f, 0.18f, -0.71f, 0.24f, -R_V_LINE_TO, -1.45f, -R_CUBIC_TO, 0.06f, -0.02f, 0.11f, -0.05f, 0.17f, -0.07f, -R_CUBIC_TO, 0.06f, -0.03f, 0.11f, -0.05f, 0.17f, -0.07f, -LINE_TO, 4.79f, 5.69f, -R_ARC_TO, 3.69f, 3.69f, 0, 0, 0, -0.24f, 0.7f, -R_CUBIC_TO, -0.06f, 0.24f, -0.09f, 0.5f, -0.09f, 0.76f, -R_CUBIC_TO, 0, 0.52f, 0.11f, 1, 0.32f, 1.44f, -R_CUBIC_TO, 0.21f, 0.45f, 0.5f, 0.82f, 0.85f, 1.14f, -R_LINE_TO, -0.03f, -0.03f, -R_V_LINE_TO, -0.95f, -R_H_LINE_TO, 1.26f, -R_V_LINE_TO, 3.28f, -R_H_LINE_TO, -3.28f, -V_LINE_TO, 10.77f, -R_H_LINE_TO, 1.11f, -R_LINE_TO, 0.05f, 0.04f, -R_ARC_TO, 5.13f, 5.13f, 0, 0, 1, -1.21f, -1.62f, -R_ARC_TO, 4.72f, 4.72f, 0, 0, 1, -0.45f, -2.04f, -R_CUBIC_TO, 0, -0.45f, 0.06f, -0.89f, 0.18f, -1.31f, -R_CUBIC_TO, 0.12f, -0.42f, 0.29f, -0.81f, 0.5f, -1.17f, -LINE_TO, 1.47f, 2.38f, -R_LINE_TO, 0.89f, -0.89f, +R_MOVE_TO, 12.73f, 13.75f, +R_LINE_TO, -2.28f, -2.28f, +R_CUBIC_TO, -0.24f, 0.14f, -0.49f, 0.27f, -0.75f, 0.38f, +R_CUBIC_TO, -0.26f, 0.11f, -0.53f, 0.19f, -0.81f, 0.25f, +V_LINE_TO, 10.39f, +R_CUBIC_TO, 0.06f, -0.02f, 0.12f, -0.04f, 0.18f, -0.07f, +R_ARC_TO, 1.16f, 1.16f, 0, 0, 1, 0.18f, -0.06f, +LINE_TO, 4.82f, 5.82f, +R_ARC_TO, 3.21f, 3.21f, 0, 0, 0, 0.02f, 2.72f, +R_CUBIC_TO, 0.2f, 0.43f, 0.48f, 0.8f, 0.82f, 1.11f, +R_LINE_TO, -0.07f, -0.07f, +V_LINE_TO, 8.75f, +R_H_LINE_TO, 1.35f, +R_V_LINE_TO, 3.39f, +H_LINE_TO, 3.54f, +R_V_LINE_TO, -1.34f, +R_H_LINE_TO, 0.93f, +R_LINE_TO, 0.11f, 0.09f, +R_ARC_TO, 5.17f, 5.17f, 0, 0, 1, -1.24f, -1.67f, +R_ARC_TO, 4.77f, 4.77f, 0, 0, 1, -0.46f, -2.08f, +R_CUBIC_TO, 0, -0.46f, 0.06f, -0.91f, 0.19f, -1.34f, +R_CUBIC_TO, 0.13f, -0.43f, 0.3f, -0.83f, 0.52f, -1.2f, +R_LINE_TO, -2.17f, -2.18f, +R_LINE_TO, 0.95f, -0.95f, R_LINE_TO, 11.3f, 11.32f, CLOSE, -R_MOVE_TO, -0.58f, -4.07f, -R_LINE_TO, -1.04f, -1.04f, -R_ARC_TO, 3.39f, 3.39f, 0, 0, 0, 0.25f, -0.68f, -R_ARC_TO, 3.37f, 3.37f, 0, 0, 0, -0.23f, -2.2f, -R_ARC_TO, 3.53f, 3.53f, 0, 0, 0, -0.85f, -1.15f, -R_LINE_TO, 0.03f, 0.03f, -R_V_LINE_TO, 0.97f, -H_LINE_TO, 9.09f, -V_LINE_TO, 2.27f, -R_H_LINE_TO, 3.28f, -V_LINE_TO, 3.53f, -R_H_LINE_TO, -1.1f, -R_LINE_TO, -0.05f, -0.04f, -R_CUBIC_TO, 0.51f, 0.46f, 0.91f, 1, 1.21f, 1.63f, -R_CUBIC_TO, 0.3f, 0.63f, 0.45f, 1.31f, 0.45f, 2.04f, -R_CUBIC_TO, 0, 0.45f, -0.06f, 0.89f, -0.18f, 1.31f, -R_ARC_TO, 4.65f, 4.65f, 0, 0, 1, -0.5f, 1.17f, +R_MOVE_TO, -0.47f, -4.07f, +R_LINE_TO, -1.23f, -1.23f, +R_ARC_TO, 3.04f, 3.04f, 0, 0, 0, 0.29f, -1.3f, +R_CUBIC_TO, 0, -0.49f, -0.1f, -0.96f, -0.31f, -1.39f, +R_ARC_TO, 3.48f, 3.48f, 0, 0, 0, -0.82f, -1.11f, +R_LINE_TO, 0.07f, 0.07f, +R_V_LINE_TO, 0.83f, +H_LINE_TO, 8.93f, +V_LINE_TO, 2.16f, +R_H_LINE_TO, 3.39f, +R_V_LINE_TO, 1.34f, +R_H_LINE_TO, -0.93f, +R_LINE_TO, -0.11f, -0.09f, +R_CUBIC_TO, 0.52f, 0.47f, 0.93f, 1.02f, 1.23f, 1.66f, +R_CUBIC_TO, 0.31f, 0.65f, 0.46f, 1.34f, 0.46f, 2.07f, +R_CUBIC_TO, 0, 0.47f, -0.06f, 0.91f, -0.18f, 1.34f, +R_CUBIC_TO, -0.12f, 0.43f, -0.29f, 0.83f, -0.51f, 1.19f, CLOSE, -MOVE_TO, 6.54f, 3.97f, -R_LINE_TO, -1.02f, -1.03f, -R_CUBIC_TO, 0.21f, -0.12f, 0.42f, -0.23f, 0.65f, -0.33f, -R_CUBIC_TO, 0.22f, -0.1f, 0.46f, -0.17f, 0.7f, -0.23f, -R_V_LINE_TO, 1.45f, -R_CUBIC_TO, -0.05f, 0.02f, -0.11f, 0.04f, -0.17f, 0.07f, -R_ARC_TO, 1.48f, 1.48f, 0, 0, 1, -0.16f, 0.07f, +MOVE_TO, 6.63f, 4.04f, +LINE_TO, 5.42f, 2.82f, +R_CUBIC_TO, 0.23f, -0.14f, 0.48f, -0.26f, 0.73f, -0.37f, +R_CUBIC_TO, 0.26f, -0.11f, 0.52f, -0.19f, 0.81f, -0.25f, +R_V_LINE_TO, 1.7f, +R_LINE_TO, -0.17f, 0.07f, +R_ARC_TO, 0.87f, 0.87f, 0, 0, 1, -0.17f, 0.06f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/usb_chrome_refresh.icon b/components/vector_icons/usb_chrome_refresh.icon index 8de9aa47..daafc91 100644 --- a/components/vector_icons/usb_chrome_refresh.icon +++ b/components/vector_icons/usb_chrome_refresh.icon
@@ -2,46 +2,135 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 16, -MOVE_TO, 8, 14.52f, -R_ARC_TO, 1.2f, 1.2f, 0, 0, 1, -0.89f, -0.37f, -R_ARC_TO, 1.23f, 1.23f, 0, 0, 1, -0.37f, -0.89f, -R_CUBIC_TO, 0, -0.22f, 0.05f, -0.43f, 0.16f, -0.62f, -R_CUBIC_TO, 0.1f, -0.19f, 0.25f, -0.34f, 0.44f, -0.45f, -R_V_LINE_TO, -1.68f, -H_LINE_TO, 5.4f, -R_CUBIC_TO, -0.36f, 0, -0.68f, -0.13f, -0.93f, -0.39f, -R_ARC_TO, 1.27f, 1.27f, 0, 0, 1, -0.39f, -0.93f, -V_LINE_TO, 7.87f, -R_ARC_TO, 1.23f, 1.23f, 0, 0, 1, -0.6f, -1.07f, -R_CUBIC_TO, 0, -0.35f, 0.13f, -0.65f, 0.38f, -0.89f, -R_CUBIC_TO, 0.25f, -0.25f, 0.55f, -0.37f, 0.89f, -0.37f, -R_CUBIC_TO, 0.35f, 0, 0.65f, 0.13f, 0.89f, 0.37f, -R_CUBIC_TO, 0.25f, 0.24f, 0.37f, 0.54f, 0.37f, 0.89f, -R_CUBIC_TO, 0, 0.23f, -0.05f, 0.43f, -0.16f, 0.63f, -R_CUBIC_TO, -0.11f, 0.19f, -0.25f, 0.34f, -0.44f, 0.44f, -V_LINE_TO, 9.2f, +CANVAS_DIMENSIONS, 24, +MOVE_TO, 12, 22.18f, +R_ARC_TO, 2, 2, 0, 0, 1, -1.48f, -0.62f, +R_ARC_TO, 2.01f, 2.01f, 0, 0, 1, -0.61f, -1.48f, +R_CUBIC_TO, 0, -0.36f, 0.09f, -0.69f, 0.27f, -0.99f, +R_CUBIC_TO, 0.18f, -0.3f, 0.42f, -0.56f, 0.73f, -0.75f, +R_V_LINE_TO, -2.16f, +H_LINE_TO, 8, +R_CUBIC_TO, -0.6f, 0, -1.12f, -0.21f, -1.54f, -0.64f, +ARC_TO, 2.09f, 2.09f, 0, 0, 1, 5.82f, 14, +R_V_LINE_TO, -2.25f, +R_ARC_TO, 1.92f, 1.92f, 0, 0, 1, -0.73f, -0.71f, +ARC_TO, 2, 2, 0, 0, 1, 4.82f, 10, +R_CUBIC_TO, 0, -0.58f, 0.2f, -1.07f, 0.62f, -1.48f, +R_CUBIC_TO, 0.41f, -0.41f, 0.9f, -0.61f, 1.48f, -0.61f, +R_ARC_TO, 2, 2, 0, 0, 1, 1.48f, 0.61f, +ARC_TO, 2, 2, 0, 0, 1, 9, 10, +R_CUBIC_TO, 0, 0.39f, -0.09f, 0.73f, -0.27f, 1.02f, +R_ARC_TO, 2.29f, 2.29f, 0, 0, 1, -0.73f, 0.72f, +V_LINE_TO, 14, +R_H_LINE_TO, 2.91f, +V_LINE_TO, 6, +H_LINE_TO, 8.82f, +LINE_TO, 12, 1.75f, +LINE_TO, 15.18f, 6, +H_LINE_TO, 13.09f, +R_V_LINE_TO, 8, +H_LINE_TO, 16, +R_V_LINE_TO, -1.91f, +R_H_LINE_TO, -1, +V_LINE_TO, 7.91f, +R_H_LINE_TO, 4.18f, +R_V_LINE_TO, 4.18f, +R_H_LINE_TO, -1, +V_LINE_TO, 14, +R_CUBIC_TO, 0, 0.6f, -0.21f, 1.12f, -0.64f, 1.54f, +R_CUBIC_TO, -0.43f, 0.43f, -0.94f, 0.64f, -1.54f, 0.64f, +R_H_LINE_TO, -2.91f, +R_V_LINE_TO, 2.15f, +R_CUBIC_TO, 0.32f, 0.18f, 0.56f, 0.43f, 0.74f, 0.73f, +R_CUBIC_TO, 0.18f, 0.31f, 0.26f, 0.65f, 0.26f, 1.02f, +R_CUBIC_TO, 0, 0.57f, -0.2f, 1.07f, -0.61f, 1.48f, +R_ARC_TO, 2, 2, 0, 0, 1, -1.48f, 0.62f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 10, 18.16f, +R_CUBIC_TO, -0.43f, 0, -0.8f, -0.16f, -1.11f, -0.47f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 1, -0.46f, -1.11f, +R_CUBIC_TO, 0, -0.28f, 0.07f, -0.53f, 0.2f, -0.77f, +R_CUBIC_TO, 0.13f, -0.23f, 0.32f, -0.42f, 0.56f, -0.55f, +R_V_LINE_TO, -2.09f, +H_LINE_TO, 6.75f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.17f, -0.48f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.49f, -1.16f, +V_LINE_TO, 9.84f, +R_ARC_TO, 1.54f, 1.54f, 0, 0, 1, -0.75f, -1.34f, +R_CUBIC_TO, 0, -0.44f, 0.16f, -0.81f, 0.47f, -1.11f, +R_CUBIC_TO, 0.31f, -0.31f, 0.68f, -0.46f, 1.12f, -0.46f, +R_CUBIC_TO, 0.44f, 0, 0.81f, 0.15f, 1.11f, 0.46f, +R_CUBIC_TO, 0.31f, 0.31f, 0.46f, 0.68f, 0.46f, 1.11f, +R_CUBIC_TO, 0, 0.28f, -0.07f, 0.54f, -0.2f, 0.78f, +R_ARC_TO, 1.41f, 1.41f, 0, 0, 1, -0.55f, 0.55f, +V_LINE_TO, 11.5f, +R_H_LINE_TO, 2.43f, +V_LINE_TO, 5, H_LINE_TO, 7.34f, +LINE_TO, 10, 1.8f, +LINE_TO, 12.66f, 5, +R_H_LINE_TO, -1.83f, +R_V_LINE_TO, 6.5f, +R_H_LINE_TO, 2.43f, +R_V_LINE_TO, -1.43f, +R_H_LINE_TO, -0.75f, +V_LINE_TO, 6.93f, +R_H_LINE_TO, 3.16f, +R_V_LINE_TO, 3.15f, +R_H_LINE_TO, -0.75f, +V_LINE_TO, 11.5f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.49f, 1.17f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -1.17f, 0.49f, +R_H_LINE_TO, -2.43f, +R_V_LINE_TO, 2.08f, +R_CUBIC_TO, 0.24f, 0.14f, 0.42f, 0.33f, 0.56f, 0.56f, +R_CUBIC_TO, 0.13f, 0.23f, 0.2f, 0.49f, 0.2f, 0.77f, +R_CUBIC_TO, 0, 0.44f, -0.15f, 0.81f, -0.46f, 1.12f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 1, -1.11f, 0.47f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 8, 14.69f, +R_CUBIC_TO, -0.37f, 0, -0.68f, -0.13f, -0.94f, -0.4f, +R_ARC_TO, 1.31f, 1.31f, 0, 0, 1, -0.39f, -0.95f, +R_CUBIC_TO, 0, -0.23f, 0.05f, -0.44f, 0.15f, -0.63f, +R_CUBIC_TO, 0.1f, -0.19f, 0.25f, -0.35f, 0.45f, -0.46f, +R_V_LINE_TO, -1.55f, +R_H_LINE_TO, -1.86f, +R_CUBIC_TO, -0.41f, 0, -0.76f, -0.14f, -1.05f, -0.43f, +R_ARC_TO, 1.44f, 1.44f, 0, 0, 1, -0.44f, -1.05f, +V_LINE_TO, 7.92f, +R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.6f, -1.12f, +R_CUBIC_TO, 0, -0.37f, 0.13f, -0.69f, 0.4f, -0.95f, +R_CUBIC_TO, 0.27f, -0.26f, 0.59f, -0.39f, 0.96f, -0.39f, +R_CUBIC_TO, 0.38f, 0, 0.69f, 0.13f, 0.95f, 0.39f, +R_CUBIC_TO, 0.26f, 0.26f, 0.39f, 0.58f, 0.39f, 0.95f, +R_CUBIC_TO, 0, 0.23f, -0.05f, 0.45f, -0.16f, 0.64f, +R_CUBIC_TO, -0.11f, 0.2f, -0.25f, 0.35f, -0.44f, 0.47f, +V_LINE_TO, 9.2f, +R_H_LINE_TO, 1.86f, V_LINE_TO, 4, -H_LINE_TO, 5.88f, -LINE_TO, 8, 1.44f, -LINE_TO, 10.13f, 4, -H_LINE_TO, 8.66f, +H_LINE_TO, 5.71f, +LINE_TO, 8, 1.22f, +LINE_TO, 10.29f, 4, +R_H_LINE_TO, -1.55f, R_V_LINE_TO, 5.2f, -R_H_LINE_TO, 1.94f, -V_LINE_TO, 8.06f, +R_H_LINE_TO, 1.86f, +V_LINE_TO, 8.14f, H_LINE_TO, 10, -R_V_LINE_TO, -2.52f, -R_H_LINE_TO, 2.52f, -R_V_LINE_TO, 2.52f, +V_LINE_TO, 5.46f, +R_H_LINE_TO, 2.69f, +R_V_LINE_TO, 2.68f, R_H_LINE_TO, -0.6f, -R_V_LINE_TO, 1.14f, -R_CUBIC_TO, 0, 0.37f, -0.13f, 0.68f, -0.39f, 0.94f, -R_CUBIC_TO, -0.26f, 0.26f, -0.57f, 0.39f, -0.93f, 0.39f, -H_LINE_TO, 8.66f, -R_V_LINE_TO, 1.67f, -R_CUBIC_TO, 0.19f, 0.11f, 0.34f, 0.26f, 0.44f, 0.45f, -R_CUBIC_TO, 0.11f, 0.19f, 0.16f, 0.39f, 0.16f, 0.62f, -R_CUBIC_TO, 0, 0.35f, -0.12f, 0.65f, -0.37f, 0.89f, -R_ARC_TO, 1.22f, 1.22f, 0, 0, 1, -0.89f, 0.37f, +R_V_LINE_TO, 1.06f, +R_CUBIC_TO, 0, 0.41f, -0.15f, 0.77f, -0.44f, 1.06f, +R_ARC_TO, 1.44f, 1.44f, 0, 0, 1, -1.05f, 0.44f, +R_H_LINE_TO, -1.86f, +R_V_LINE_TO, 1.53f, +R_CUBIC_TO, 0.19f, 0.13f, 0.34f, 0.29f, 0.44f, 0.48f, +R_CUBIC_TO, 0.11f, 0.2f, 0.16f, 0.41f, 0.16f, 0.64f, +R_CUBIC_TO, 0, 0.37f, -0.13f, 0.69f, -0.39f, 0.96f, +R_ARC_TO, 1.31f, 1.31f, 0, 0, 1, -0.95f, 0.39f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/usb_off_chrome_refresh.icon b/components/vector_icons/usb_off_chrome_refresh.icon index 3e6ac3c9a..59eb373 100644 --- a/components/vector_icons/usb_off_chrome_refresh.icon +++ b/components/vector_icons/usb_off_chrome_refresh.icon
@@ -2,57 +2,167 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 20, 22.88f, +R_LINE_TO, -6.7f, -6.69f, +R_H_LINE_TO, -0.21f, +R_V_LINE_TO, 2.15f, +R_CUBIC_TO, 0.32f, 0.18f, 0.56f, 0.43f, 0.74f, 0.75f, +R_CUBIC_TO, 0.18f, 0.31f, 0.26f, 0.65f, 0.26f, 1.01f, +R_CUBIC_TO, 0, 0.58f, -0.2f, 1.07f, -0.61f, 1.48f, +R_ARC_TO, 2, 2, 0, 0, 1, -1.48f, 0.61f, +R_ARC_TO, 2, 2, 0, 0, 1, -1.48f, -0.61f, +R_ARC_TO, 2.01f, 2.01f, 0, 0, 1, -0.61f, -1.48f, +R_CUBIC_TO, 0, -0.36f, 0.09f, -0.69f, 0.27f, -0.99f, +R_CUBIC_TO, 0.18f, -0.3f, 0.43f, -0.56f, 0.73f, -0.75f, +R_V_LINE_TO, -2.16f, +H_LINE_TO, 8, +R_CUBIC_TO, -0.6f, 0, -1.12f, -0.21f, -1.54f, -0.64f, +ARC_TO, 2.09f, 2.09f, 0, 0, 1, 5.82f, 14, +R_V_LINE_TO, -2.25f, +R_ARC_TO, 1.91f, 1.91f, 0, 0, 1, -0.74f, -0.75f, +ARC_TO, 2.02f, 2.02f, 0, 0, 1, 4.82f, 10, +R_CUBIC_TO, 0, -0.3f, 0.06f, -0.59f, 0.18f, -0.87f, +R_CUBIC_TO, 0.12f, -0.27f, 0.31f, -0.51f, 0.55f, -0.7f, +LINE_TO, 1.13f, 4, +R_LINE_TO, 1.48f, -1.48f, +LINE_TO, 21.49f, 21.39f, +CLOSE, +R_MOVE_TO, -2.03f, -7.96f, +R_LINE_TO, -2.16f, -2.16f, +R_V_LINE_TO, -0.94f, +H_LINE_TO, 15, +V_LINE_TO, 7.91f, +R_H_LINE_TO, 4.18f, +R_V_LINE_TO, 4.18f, +R_H_LINE_TO, -1, +V_LINE_TO, 14, +R_CUBIC_TO, 0, 0.16f, -0.02f, 0.32f, -0.05f, 0.48f, +R_CUBIC_TO, -0.03f, 0.16f, -0.08f, 0.3f, -0.16f, 0.43f, +CLOSE, +MOVE_TO, 8, 14, +R_H_LINE_TO, 2.91f, +R_V_LINE_TO, -0.21f, +R_LINE_TO, -2.43f, -2.43f, +R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.23f, 0.22f, +R_ARC_TO, 3.18f, 3.18f, 0, 0, 1, -0.25f, 0.17f, +CLOSE, +R_MOVE_TO, 5.09f, -3.97f, +R_LINE_TO, -2.18f, -2.19f, +V_LINE_TO, 6, +H_LINE_TO, 9.18f, +R_LINE_TO, -0.21f, -0.21f, +LINE_TO, 12, 1.75f, +LINE_TO, 15.18f, 6, +H_LINE_TO, 13.09f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.19f, 18.34f, +R_LINE_TO, -5.19f, -5.18f, +R_H_LINE_TO, -0.17f, +R_V_LINE_TO, 2.08f, +R_CUBIC_TO, 0.24f, 0.14f, 0.42f, 0.33f, 0.56f, 0.56f, +R_CUBIC_TO, 0.13f, 0.23f, 0.2f, 0.49f, 0.2f, 0.78f, +R_CUBIC_TO, 0, 0.44f, -0.15f, 0.81f, -0.46f, 1.12f, +R_CUBIC_TO, -0.31f, 0.31f, -0.68f, 0.47f, -1.12f, 0.47f, +R_CUBIC_TO, -0.44f, 0, -0.81f, -0.16f, -1.11f, -0.46f, +R_ARC_TO, 1.53f, 1.53f, 0, 0, 1, -0.46f, -1.12f, +R_CUBIC_TO, 0, -0.28f, 0.07f, -0.54f, 0.2f, -0.76f, +R_CUBIC_TO, 0.13f, -0.22f, 0.31f, -0.41f, 0.55f, -0.56f, +R_V_LINE_TO, -2.09f, +H_LINE_TO, 6.75f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.17f, -0.48f, +R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, -0.49f, -1.16f, +V_LINE_TO, 9.84f, +R_ARC_TO, 1.34f, 1.34f, 0, 0, 1, -0.55f, -0.55f, +R_ARC_TO, 1.63f, 1.63f, 0, 0, 1, -0.2f, -0.79f, +R_CUBIC_TO, 0, -0.25f, 0.07f, -0.49f, 0.2f, -0.72f, +R_ARC_TO, 2.01f, 2.01f, 0, 0, 1, 0.5f, -0.59f, +LINE_TO, 1.66f, 3.81f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 14.52f, 14.52f, +CLOSE, +R_MOVE_TO, -1.54f, -5.99f, +R_LINE_TO, -1.55f, -1.55f, +R_V_LINE_TO, -0.95f, +H_LINE_TO, 12.5f, +V_LINE_TO, 6.93f, +R_H_LINE_TO, 3.16f, +R_V_LINE_TO, 3.15f, +R_H_LINE_TO, -0.75f, +V_LINE_TO, 11.5f, +R_CUBIC_TO, 0, 0.15f, -0.02f, 0.3f, -0.06f, 0.44f, +R_CUBIC_TO, -0.04f, 0.14f, -0.11f, 0.28f, -0.2f, 0.4f, +CLOSE, +MOVE_TO, 6.75f, 11.5f, +R_H_LINE_TO, 2.43f, +R_V_LINE_TO, -0.18f, +LINE_TO, 7.23f, 9.38f, +R_CUBIC_TO, -0.07f, 0.1f, -0.14f, 0.18f, -0.22f, 0.25f, +R_ARC_TO, 6.19f, 6.19f, 0, 0, 1, -0.26f, 0.21f, +CLOSE, +R_MOVE_TO, 4.07f, -2.98f, +LINE_TO, 9.18f, 6.87f, +V_LINE_TO, 5, +R_H_LINE_TO, -1.52f, +R_LINE_TO, -0.18f, -0.18f, +LINE_TO, 10, 1.8f, +LINE_TO, 12.66f, 5, +R_H_LINE_TO, -1.83f, +CLOSE + CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 12.95f, 14.67f, -R_LINE_TO, -4.16f, -4.14f, -H_LINE_TO, 8.66f, -R_V_LINE_TO, 1.67f, -R_CUBIC_TO, 0.19f, 0.11f, 0.34f, 0.26f, 0.44f, 0.45f, -R_CUBIC_TO, 0.11f, 0.19f, 0.16f, 0.39f, 0.16f, 0.63f, -R_CUBIC_TO, 0, 0.35f, -0.12f, 0.64f, -0.37f, 0.89f, -R_ARC_TO, 1.22f, 1.22f, 0, 0, 1, -0.89f, 0.37f, -R_CUBIC_TO, -0.35f, 0, -0.64f, -0.12f, -0.89f, -0.37f, -R_ARC_TO, 1.23f, 1.23f, 0, 0, 1, -0.37f, -0.89f, -R_CUBIC_TO, 0, -0.23f, 0.06f, -0.43f, 0.16f, -0.61f, -R_CUBIC_TO, 0.11f, -0.18f, 0.25f, -0.33f, 0.44f, -0.45f, -R_V_LINE_TO, -1.68f, -H_LINE_TO, 5.4f, -R_CUBIC_TO, -0.36f, 0, -0.67f, -0.13f, -0.93f, -0.39f, -R_ARC_TO, 1.27f, 1.27f, 0, 0, 1, -0.39f, -0.93f, -V_LINE_TO, 7.87f, -R_ARC_TO, 1.06f, 1.06f, 0, 0, 1, -0.44f, -0.44f, -R_ARC_TO, 1.25f, 1.25f, 0, 0, 1, -0.16f, -0.62f, -R_CUBIC_TO, 0, -0.2f, 0.05f, -0.39f, 0.16f, -0.58f, -R_ARC_TO, 1.59f, 1.59f, 0, 0, 1, 0.4f, -0.47f, -LINE_TO, 1.33f, 3.05f, -R_LINE_TO, 0.89f, -0.89f, -LINE_TO, 13.84f, 13.78f, +MOVE_TO, 13.16f, 14.9f, +LINE_TO, 8.94f, 10.69f, +R_H_LINE_TO, -0.19f, +R_V_LINE_TO, 1.53f, +R_CUBIC_TO, 0.19f, 0.13f, 0.34f, 0.28f, 0.44f, 0.48f, +R_CUBIC_TO, 0.11f, 0.19f, 0.16f, 0.41f, 0.16f, 0.64f, +R_CUBIC_TO, 0, 0.38f, -0.13f, 0.7f, -0.39f, 0.96f, +R_ARC_TO, 1.3f, 1.3f, 0, 0, 1, -0.95f, 0.39f, +R_CUBIC_TO, -0.37f, 0, -0.69f, -0.13f, -0.95f, -0.39f, +R_ARC_TO, 1.31f, 1.31f, 0, 0, 1, -0.39f, -0.96f, +R_CUBIC_TO, 0, -0.23f, 0.05f, -0.44f, 0.16f, -0.62f, +R_CUBIC_TO, 0.11f, -0.19f, 0.25f, -0.34f, 0.44f, -0.47f, +R_V_LINE_TO, -1.55f, +R_H_LINE_TO, -1.86f, +R_CUBIC_TO, -0.41f, 0, -0.76f, -0.14f, -1.05f, -0.43f, +R_ARC_TO, 1.44f, 1.44f, 0, 0, 1, -0.44f, -1.05f, +V_LINE_TO, 7.92f, +R_ARC_TO, 1.17f, 1.17f, 0, 0, 1, -0.44f, -0.47f, +R_ARC_TO, 1.36f, 1.36f, 0, 0, 1, -0.16f, -0.64f, +R_CUBIC_TO, 0, -0.22f, 0.06f, -0.43f, 0.18f, -0.63f, +R_CUBIC_TO, 0.11f, -0.19f, 0.26f, -0.36f, 0.43f, -0.51f, +R_LINE_TO, -2.81f, -2.82f, +R_LINE_TO, 0.94f, -0.95f, +R_LINE_TO, 12.06f, 12.06f, CLOSE, -MOVE_TO, 11.72f, 9.88f, -R_LINE_TO, -1.24f, -1.24f, -R_V_LINE_TO, -0.76f, +R_MOVE_TO, -1.25f, -5.03f, +LINE_TO, 10.31f, 8.28f, +R_V_LINE_TO, -0.57f, H_LINE_TO, 10, -V_LINE_TO, 5.54f, -R_H_LINE_TO, 2.52f, -R_V_LINE_TO, 2.52f, +R_V_LINE_TO, -2.25f, +R_H_LINE_TO, 2.69f, +R_V_LINE_TO, 2.68f, R_H_LINE_TO, -0.6f, -R_V_LINE_TO, 1.14f, -R_CUBIC_TO, 0, 0.12f, -0.02f, 0.24f, -0.04f, 0.36f, -R_ARC_TO, 0.95f, 0.95f, 0, 0, 1, -0.16f, 0.32f, +R_V_LINE_TO, 1.06f, +R_CUBIC_TO, 0, 0.12f, -0.02f, 0.24f, -0.05f, 0.35f, +R_ARC_TO, 0.89f, 0.89f, 0, 0, 1, -0.14f, 0.32f, CLOSE, -R_MOVE_TO, -6.32f, -0.68f, -R_H_LINE_TO, 1.94f, -R_V_LINE_TO, -0.14f, -LINE_TO, 5.79f, 7.5f, -R_CUBIC_TO, -0.06f, 0.08f, -0.12f, 0.14f, -0.18f, 0.2f, -R_CUBIC_TO, -0.06f, 0.05f, -0.13f, 0.11f, -0.21f, 0.16f, +MOVE_TO, 5.4f, 9.2f, +R_H_LINE_TO, 1.86f, +R_V_LINE_TO, -0.2f, +LINE_TO, 5.79f, 7.53f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 1, -0.18f, 0.2f, +R_ARC_TO, 3.57f, 3.57f, 0, 0, 1, -0.21f, 0.18f, CLOSE, -MOVE_TO, 8.66f, 6.82f, -LINE_TO, 7.34f, 5.5f, +R_MOVE_TO, 3.34f, -2.49f, +LINE_TO, 7.26f, 5.22f, V_LINE_TO, 4, -H_LINE_TO, 6.13f, -R_LINE_TO, -0.14f, -0.14f, -LINE_TO, 8, 1.44f, -LINE_TO, 10.13f, 4, -H_LINE_TO, 8.66f, +R_H_LINE_TO, -0.96f, +R_LINE_TO, -0.34f, -0.33f, +LINE_TO, 8, 1.22f, +LINE_TO, 10.29f, 4, +R_H_LINE_TO, -1.55f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/videocam_chrome_refresh.icon b/components/vector_icons/videocam_chrome_refresh.icon index 91d7d24..36d8233 100644 --- a/components/vector_icons/videocam_chrome_refresh.icon +++ b/components/vector_icons/videocam_chrome_refresh.icon
@@ -2,29 +2,83 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -CANVAS_DIMENSIONS, 16, -MOVE_TO, 3.65f, 12.93f, -R_CUBIC_TO, -0.37f, 0, -0.7f, -0.14f, -0.97f, -0.41f, -R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.41f, -0.97f, -V_LINE_TO, 4.45f, -R_CUBIC_TO, 0, -0.38f, 0.14f, -0.71f, 0.41f, -0.98f, -R_CUBIC_TO, 0.27f, -0.27f, 0.6f, -0.4f, 0.97f, -0.4f, -R_H_LINE_TO, 7.11f, -R_CUBIC_TO, 0.38f, 0, 0.71f, 0.13f, 0.98f, 0.4f, -R_CUBIC_TO, 0.27f, 0.27f, 0.41f, 0.6f, 0.41f, 0.98f, -V_LINE_TO, 7.2f, -R_LINE_TO, 2.4f, -2.4f, -R_V_LINE_TO, 6.4f, -R_LINE_TO, -2.4f, -2.4f, -R_V_LINE_TO, 2.75f, -R_CUBIC_TO, 0, 0.38f, -0.14f, 0.7f, -0.41f, 0.97f, -R_CUBIC_TO, -0.27f, 0.27f, -0.59f, 0.41f, -0.98f, 0.41f, +CANVAS_DIMENSIONS, 24, +MOVE_TO, 4.07f, 20.2f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 6.07f, +R_CUBIC_TO, 0, -0.63f, 0.22f, -1.16f, 0.66f, -1.61f, +R_CUBIC_TO, 0.45f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f, +H_LINE_TO, 15.93f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +V_LINE_TO, 10.5f, +R_LINE_TO, 4, -4, +R_V_LINE_TO, 11, +R_LINE_TO, -4, -4, +R_V_LINE_TO, 4.43f, +R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, +R_CUBIC_TO, -0.44f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, CLOSE, -R_MOVE_TO, 0, -1.38f, -R_H_LINE_TO, 7.11f, -V_LINE_TO, 4.45f, -H_LINE_TO, 3.65f, +R_MOVE_TO, 0, -2.27f, +R_H_LINE_TO, 11.86f, +V_LINE_TO, 6.07f, +H_LINE_TO, 4.07f, CLOSE, R_MOVE_TO, 0, 0, -V_LINE_TO, 4.45f, +V_LINE_TO, 6.07f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.56f, 16.17f, +R_CUBIC_TO, -0.47f, 0, -0.87f, -0.17f, -1.22f, -0.51f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, -0.51f, -1.22f, +V_LINE_TO, 5.56f, +R_CUBIC_TO, 0, -0.48f, 0.17f, -0.89f, 0.51f, -1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, 1.22f, -0.5f, +R_H_LINE_TO, 8.88f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.5f, +R_CUBIC_TO, 0.34f, 0.34f, 0.5f, 0.75f, 0.5f, 1.22f, +V_LINE_TO, 9, +R_LINE_TO, 3, -3, +R_V_LINE_TO, 8, +R_LINE_TO, -3, -3, +R_V_LINE_TO, 3.44f, +R_CUBIC_TO, 0, 0.47f, -0.17f, 0.88f, -0.5f, 1.22f, +R_ARC_TO, 1.65f, 1.65f, 0, 0, 1, -1.22f, 0.51f, +CLOSE, +R_MOVE_TO, 0, -1.73f, +R_H_LINE_TO, 8.88f, +V_LINE_TO, 5.56f, +H_LINE_TO, 4.56f, +CLOSE, +R_MOVE_TO, 0, 0, +V_LINE_TO, 5.56f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3.72f, 13.12f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.16f, -0.48f, +R_CUBIC_TO, -0.32f, -0.32f, -0.48f, -0.71f, -0.48f, -1.15f, +V_LINE_TO, 4.51f, +R_CUBIC_TO, 0, -0.45f, 0.16f, -0.84f, 0.48f, -1.16f, +R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, 1.16f, -0.48f, +R_H_LINE_TO, 6.97f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.16f, +R_V_LINE_TO, 2.69f, +R_LINE_TO, 2.4f, -2.4f, +R_V_LINE_TO, 6.4f, +LINE_TO, 12.32f, 8.8f, +R_V_LINE_TO, 2.69f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.15f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f, +CLOSE, +R_MOVE_TO, 0, -1.63f, +R_H_LINE_TO, 6.97f, +V_LINE_TO, 4.51f, +H_LINE_TO, 3.72f, +CLOSE, +R_MOVE_TO, 0, 0, +V_LINE_TO, 4.51f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/videocam_off_chrome_refresh.icon b/components/vector_icons/videocam_off_chrome_refresh.icon index 77e6d39..4401758e 100644 --- a/components/vector_icons/videocam_off_chrome_refresh.icon +++ b/components/vector_icons/videocam_off_chrome_refresh.icon
@@ -2,6 +2,46 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 22.2f, 17.5f, +R_LINE_TO, -4, -4, +R_V_LINE_TO, 1.77f, +R_LINE_TO, -2.27f, -2.28f, +V_LINE_TO, 6.07f, +H_LINE_TO, 9.01f, +LINE_TO, 6.73f, 3.8f, +R_H_LINE_TO, 9.2f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +V_LINE_TO, 10.5f, +R_LINE_TO, 4, -4, +CLOSE, +R_MOVE_TO, -1.56f, 5.97f, +LINE_TO, 0.53f, 3.35f, +R_LINE_TO, 1.47f, -1.46f, +R_LINE_TO, 20.12f, 20.12f, +CLOSE, +MOVE_TO, 12.5f, 9.57f, +CLOSE, +R_MOVE_TO, -2.96f, 2.84f, +CLOSE, +MOVE_TO, 3.91f, 3.8f, +LINE_TO, 6.18f, 6.07f, +H_LINE_TO, 4.07f, +R_V_LINE_TO, 11.86f, +R_H_LINE_TO, 11.86f, +R_V_LINE_TO, -2.11f, +R_LINE_TO, 2.26f, 2.26f, +R_ARC_TO, 2.15f, 2.15f, 0, 0, 1, -0.7f, 1.51f, +R_ARC_TO, 2.19f, 2.19f, 0, 0, 1, -1.56f, 0.62f, +H_LINE_TO, 4.07f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +V_LINE_TO, 6.07f, +R_CUBIC_TO, 0, -0.6f, 0.21f, -1.12f, 0.62f, -1.56f, +R_CUBIC_TO, 0.41f, -0.44f, 0.91f, -0.67f, 1.51f, -0.7f, +CLOSE + CANVAS_DIMENSIONS, 20, R_MOVE_TO, 18.17f, 13.98f, R_LINE_TO, -3, -3, @@ -43,41 +83,41 @@ CLOSE CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 14.54f, 11.18f, -R_LINE_TO, -2.4f, -2.4f, -R_V_LINE_TO, 1.56f, -LINE_TO, 10.75f, 8.96f, -V_LINE_TO, 4.45f, -H_LINE_TO, 6.22f, -LINE_TO, 4.84f, 3.07f, -R_H_LINE_TO, 5.91f, -R_CUBIC_TO, 0.38f, 0, 0.71f, 0.13f, 0.98f, 0.4f, -R_CUBIC_TO, 0.27f, 0.27f, 0.41f, 0.6f, 0.41f, 0.98f, -R_V_LINE_TO, 2.74f, +MOVE_TO, 14.72f, 11.18f, +LINE_TO, 12.32f, 8.79f, +R_V_LINE_TO, 1.64f, +R_LINE_TO, -1.63f, -1.63f, +V_LINE_TO, 4.51f, +H_LINE_TO, 6.39f, +LINE_TO, 4.76f, 2.88f, +R_H_LINE_TO, 5.93f, +R_CUBIC_TO, 0.45f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.7f, 0.48f, 1.16f, +R_V_LINE_TO, 2.67f, R_LINE_TO, 2.4f, -2.4f, CLOSE, -R_MOVE_TO, -1.09f, 3.95f, -LINE_TO, 0.86f, 2.55f, -R_LINE_TO, 0.89f, -0.89f, -R_LINE_TO, 12.6f, 12.58f, +R_MOVE_TO, -1.2f, 4.05f, +LINE_TO, 0.75f, 2.46f, +R_LINE_TO, 0.95f, -0.95f, +R_LINE_TO, 12.8f, 12.78f, CLOSE, -R_MOVE_TO, -4.96f, -8.43f, +R_MOVE_TO, -4.99f, -8.59f, CLOSE, -MOVE_TO, 6.76f, 8.43f, +MOVE_TO, 6.75f, 8.43f, CLOSE, -MOVE_TO, 3.17f, 3.1f, -LINE_TO, 4.52f, 4.43f, -R_H_LINE_TO, -0.87f, -R_V_LINE_TO, 7.12f, -R_H_LINE_TO, 7.11f, -R_V_LINE_TO, -0.9f, -R_LINE_TO, 1.38f, 1.38f, -R_ARC_TO, 1.8f, 1.8f, 0, 0, 1, -0.49f, 0.64f, -R_CUBIC_TO, -0.22f, 0.18f, -0.51f, 0.27f, -0.88f, 0.27f, -H_LINE_TO, 3.65f, -R_CUBIC_TO, -0.37f, 0, -0.7f, -0.13f, -0.97f, -0.4f, -R_ARC_TO, 1.33f, 1.33f, 0, 0, 1, -0.41f, -0.98f, -V_LINE_TO, 4.43f, -R_CUBIC_TO, 0, -0.32f, 0.09f, -0.59f, 0.26f, -0.82f, -R_ARC_TO, 1.41f, 1.41f, 0, 0, 1, 0.65f, -0.5f, -CLOSE \ No newline at end of file +R_MOVE_TO, -3.65f, -5.52f, +LINE_TO, 4.69f, 4.5f, +R_H_LINE_TO, -0.98f, +R_V_LINE_TO, 6.99f, +R_H_LINE_TO, 6.97f, +R_V_LINE_TO, -1.01f, +LINE_TO, 12.3f, 12.09f, +R_CUBIC_TO, -0.14f, 0.29f, -0.34f, 0.54f, -0.59f, 0.73f, +R_CUBIC_TO, -0.26f, 0.2f, -0.6f, 0.3f, -1.02f, 0.3f, +H_LINE_TO, 3.72f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.16f, -0.48f, +R_ARC_TO, 1.57f, 1.57f, 0, 0, 1, -0.48f, -1.16f, +V_LINE_TO, 4.5f, +R_CUBIC_TO, 0, -0.37f, 0.1f, -0.69f, 0.29f, -0.96f, +R_CUBIC_TO, 0.2f, -0.27f, 0.44f, -0.48f, 0.74f, -0.6f, +CLOSE
diff --git a/components/vector_icons/videogame_asset_chrome_refresh.icon b/components/vector_icons/videogame_asset_chrome_refresh.icon index eb0c74c7..ba9a52718 100644 --- a/components/vector_icons/videogame_asset_chrome_refresh.icon +++ b/components/vector_icons/videogame_asset_chrome_refresh.icon
@@ -56,4 +56,116 @@ CLOSE, MOVE_TO, 3.95f, 16, V_LINE_TO, 8, -CLOSE \ No newline at end of file +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 3.46f, 15.23f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.51f, +ARC_TO, 1.66f, 1.66f, 0, 0, 1, 1.73f, 13.5f, +R_V_LINE_TO, -7, +R_CUBIC_TO, 0, -0.47f, 0.17f, -0.87f, 0.51f, -1.22f, +R_ARC_TO, 1.64f, 1.64f, 0, 0, 1, 1.22f, -0.51f, +R_H_LINE_TO, 13.08f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.52f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, +R_V_LINE_TO, 7, +R_CUBIC_TO, 0, 0.47f, -0.17f, 0.88f, -0.51f, 1.22f, +R_ARC_TO, 1.64f, 1.64f, 0, 0, 1, -1.22f, 0.52f, +CLOSE, +R_MOVE_TO, 0, -1.73f, +R_H_LINE_TO, 13.08f, +R_V_LINE_TO, -7, +H_LINE_TO, 3.46f, +CLOSE, +R_MOVE_TO, 2.54f, -1, +R_H_LINE_TO, 1.5f, +R_V_LINE_TO, -1.75f, +R_H_LINE_TO, 1.75f, +R_V_LINE_TO, -1.5f, +H_LINE_TO, 7.5f, +V_LINE_TO, 7.5f, +H_LINE_TO, 6, +R_V_LINE_TO, 1.75f, +H_LINE_TO, 4.25f, +R_V_LINE_TO, 1.5f, +H_LINE_TO, 6, +CLOSE, +R_MOVE_TO, 6.04f, -0.25f, +R_CUBIC_TO, 0.35f, 0, 0.64f, -0.12f, 0.89f, -0.36f, +R_CUBIC_TO, 0.24f, -0.25f, 0.36f, -0.54f, 0.36f, -0.89f, +R_CUBIC_TO, 0, -0.35f, -0.12f, -0.64f, -0.36f, -0.89f, +R_ARC_TO, 1.21f, 1.21f, 0, 0, 0, -0.89f, -0.36f, +R_ARC_TO, 1.2f, 1.2f, 0, 0, 0, -0.88f, 0.36f, +R_CUBIC_TO, -0.25f, 0.25f, -0.37f, 0.54f, -0.37f, 0.89f, +R_CUBIC_TO, 0, 0.35f, 0.12f, 0.64f, 0.37f, 0.89f, +R_ARC_TO, 1.2f, 1.2f, 0, 0, 0, 0.88f, 0.36f, +CLOSE, +R_MOVE_TO, 2.5f, -2, +R_CUBIC_TO, 0.35f, 0, 0.64f, -0.12f, 0.89f, -0.36f, +R_CUBIC_TO, 0.24f, -0.25f, 0.36f, -0.54f, 0.36f, -0.89f, +R_CUBIC_TO, 0, -0.35f, -0.12f, -0.64f, -0.36f, -0.89f, +R_ARC_TO, 1.21f, 1.21f, 0, 0, 0, -0.89f, -0.36f, +R_ARC_TO, 1.2f, 1.2f, 0, 0, 0, -0.88f, 0.36f, +R_CUBIC_TO, -0.25f, 0.25f, -0.37f, 0.54f, -0.37f, 0.89f, +R_CUBIC_TO, 0, 0.35f, 0.12f, 0.64f, 0.37f, 0.89f, +R_ARC_TO, 1.2f, 1.2f, 0, 0, 0, 0.88f, 0.36f, +CLOSE, +MOVE_TO, 3.46f, 13.5f, +R_V_LINE_TO, -7, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 2.73f, 12.43f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.48f, +ARC_TO, 1.59f, 1.59f, 0, 0, 1, 1.09f, 10.8f, +V_LINE_TO, 5.2f, +R_CUBIC_TO, 0, -0.44f, 0.16f, -0.83f, 0.48f, -1.15f, +R_CUBIC_TO, 0.32f, -0.32f, 0.7f, -0.48f, 1.16f, -0.48f, +R_H_LINE_TO, 10.55f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.15f, +R_V_LINE_TO, 5.6f, +R_CUBIC_TO, 0, 0.45f, -0.16f, 0.83f, -0.48f, 1.15f, +R_CUBIC_TO, -0.32f, 0.32f, -0.7f, 0.48f, -1.16f, 0.48f, +CLOSE, +R_MOVE_TO, 0, -1.63f, +R_H_LINE_TO, 10.55f, +V_LINE_TO, 5.2f, +H_LINE_TO, 2.73f, +CLOSE, +MOVE_TO, 4.76f, 10, +R_H_LINE_TO, 1.2f, +V_LINE_TO, 8.6f, +R_H_LINE_TO, 1.4f, +V_LINE_TO, 7.4f, +H_LINE_TO, 5.96f, +V_LINE_TO, 6, +R_H_LINE_TO, -1.2f, +R_V_LINE_TO, 1.4f, +H_LINE_TO, 3.36f, +R_V_LINE_TO, 1.2f, +R_H_LINE_TO, 1.4f, +CLOSE, +R_MOVE_TO, 4.92f, -0.2f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, 0.71f, -0.29f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, 0.29f, -0.71f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, -0.29f, -0.71f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, -0.71f, -0.29f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, -0.71f, 0.29f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, -0.29f, 0.71f, +R_CUBIC_TO, 0, 0.28f, 0.1f, 0.51f, 0.29f, 0.71f, +R_CUBIC_TO, 0.19f, 0.2f, 0.43f, 0.29f, 0.71f, 0.29f, +CLOSE, +R_MOVE_TO, 2, -1.6f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, 0.71f, -0.29f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, 0.29f, -0.71f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.29f, -0.71f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.71f, -0.29f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.71f, 0.29f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 0, -0.29f, 0.71f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 0, 0.29f, 0.71f, +R_CUBIC_TO, 0.19f, 0.19f, 0.43f, 0.29f, 0.71f, 0.29f, +CLOSE, +R_MOVE_TO, -8.95f, 2.6f, +V_LINE_TO, 5.2f, +CLOSE
diff --git a/components/vector_icons/videogame_asset_off_chrome_refresh.icon b/components/vector_icons/videogame_asset_off_chrome_refresh.icon index af47fb2a..c5226b26 100644 --- a/components/vector_icons/videogame_asset_off_chrome_refresh.icon +++ b/components/vector_icons/videogame_asset_off_chrome_refresh.icon
@@ -60,8 +60,120 @@ R_ARC_TO, 1.99f, 1.99f, 0, 0, 0, -1.46f, -0.61f, R_CUBIC_TO, -0.42f, 0, -0.8f, 0.11f, -1.14f, 0.35f, R_CUBIC_TO, -0.34f, 0.23f, -0.6f, 0.55f, -0.78f, 0.94f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 18.27f, 13.5f, +R_CUBIC_TO, 0, 0.34f, -0.08f, 0.64f, -0.25f, 0.9f, +R_ARC_TO, 1.53f, 1.53f, 0, 0, 1, -0.71f, 0.6f, +LINE_TO, 15.8f, 13.5f, +R_H_LINE_TO, 0.74f, +R_V_LINE_TO, -7, +H_LINE_TO, 8.8f, +LINE_TO, 7.07f, 4.77f, +R_H_LINE_TO, 9.47f, +R_CUBIC_TO, 0.47f, 0, 0.88f, 0.17f, 1.22f, 0.52f, +R_CUBIC_TO, 0.34f, 0.34f, 0.51f, 0.75f, 0.51f, 1.22f, CLOSE, -R_MOVE_TO, -1.91f, -3, +R_MOVE_TO, -3.73f, -3.25f, +R_ARC_TO, 1.2f, 1.2f, 0, 0, 1, -0.88f, -0.36f, +ARC_TO, 1.2f, 1.2f, 0, 0, 1, 13.29f, 9, +R_CUBIC_TO, 0, -0.35f, 0.12f, -0.64f, 0.37f, -0.89f, +R_ARC_TO, 1.2f, 1.2f, 0, 0, 1, 0.88f, -0.36f, +R_CUBIC_TO, 0.35f, 0, 0.65f, 0.12f, 0.89f, 0.36f, +R_CUBIC_TO, 0.24f, 0.25f, 0.36f, 0.54f, 0.36f, 0.89f, +R_CUBIC_TO, 0, 0.35f, -0.12f, 0.64f, -0.36f, 0.89f, +R_CUBIC_TO, -0.24f, 0.24f, -0.54f, 0.36f, -0.89f, 0.36f, CLOSE, -R_MOVE_TO, -6.66f, 0.41f, +R_MOVE_TO, -6.71f, -0.17f, +CLOSE, +R_MOVE_TO, 4.47f, 0, +CLOSE, +MOVE_TO, 5.96f, 12.5f, +R_V_LINE_TO, -1.75f, +H_LINE_TO, 4.21f, +R_V_LINE_TO, -1.5f, +R_H_LINE_TO, 1.75f, +V_LINE_TO, 7.5f, +R_H_LINE_TO, 1.5f, +R_V_LINE_TO, 1.75f, +R_H_LINE_TO, 1.75f, +R_V_LINE_TO, 1.5f, +H_LINE_TO, 7.46f, +R_V_LINE_TO, 1.75f, +CLOSE, +R_MOVE_TO, -2.5f, 2.73f, +R_CUBIC_TO, -0.47f, 0, -0.87f, -0.17f, -1.22f, -0.51f, +ARC_TO, 1.66f, 1.66f, 0, 0, 1, 1.73f, 13.5f, +R_V_LINE_TO, -7, +R_CUBIC_TO, 0, -0.46f, 0.17f, -0.87f, 0.49f, -1.21f, +R_ARC_TO, 1.55f, 1.55f, 0, 0, 1, 1.17f, -0.51f, +R_H_LINE_TO, 1.47f, +LINE_TO, 6.58f, 6.5f, +H_LINE_TO, 3.46f, +R_V_LINE_TO, 7, +R_H_LINE_TO, 7.89f, +LINE_TO, 1.67f, 3.81f, +LINE_TO, 2.78f, 2.7f, +R_LINE_TO, 14.52f, 14.52f, +R_LINE_TO, -1.11f, 1.11f, +R_LINE_TO, -3.11f, -3.11f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 14.91f, 10.8f, +R_CUBIC_TO, 0, 0.28f, -0.07f, 0.54f, -0.19f, 0.77f, +R_CUBIC_TO, -0.13f, 0.23f, -0.31f, 0.41f, -0.56f, 0.56f, +R_LINE_TO, -1.34f, -1.32f, +R_H_LINE_TO, 0.45f, +V_LINE_TO, 5.2f, +H_LINE_TO, 7.23f, +LINE_TO, 5.6f, 3.57f, +R_H_LINE_TO, 7.68f, +R_CUBIC_TO, 0.45f, 0, 0.83f, 0.16f, 1.16f, 0.48f, +R_CUBIC_TO, 0.32f, 0.32f, 0.48f, 0.71f, 0.48f, 1.15f, +CLOSE, +R_MOVE_TO, -3.23f, -2.6f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 1, -0.71f, -0.29f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 1, -0.29f, -0.71f, +R_CUBIC_TO, 0, -0.28f, 0.1f, -0.51f, 0.29f, -0.71f, +R_ARC_TO, 0.96f, 0.96f, 0, 0, 1, 0.71f, -0.29f, +R_CUBIC_TO, 0.28f, 0, 0.51f, 0.1f, 0.71f, 0.29f, +R_CUBIC_TO, 0.2f, 0.2f, 0.29f, 0.43f, 0.29f, 0.71f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 1, -0.29f, 0.71f, +R_ARC_TO, 0.97f, 0.97f, 0, 0, 1, -0.71f, 0.29f, +CLOSE, +R_MOVE_TO, -5.44f, -0.13f, +CLOSE, +R_MOVE_TO, 3.8f, 0, +CLOSE, +MOVE_TO, 4.73f, 10, +V_LINE_TO, 8.6f, +H_LINE_TO, 3.32f, +V_LINE_TO, 7.4f, +R_H_LINE_TO, 1.4f, +V_LINE_TO, 6, +R_H_LINE_TO, 1.2f, +R_V_LINE_TO, 1.4f, +R_H_LINE_TO, 1.4f, +R_V_LINE_TO, 1.2f, +H_LINE_TO, 5.93f, +V_LINE_TO, 10, +CLOSE, +R_MOVE_TO, -2, 2.43f, +R_CUBIC_TO, -0.45f, 0, -0.83f, -0.16f, -1.16f, -0.48f, +R_CUBIC_TO, -0.32f, -0.32f, -0.48f, -0.71f, -0.48f, -1.15f, +V_LINE_TO, 5.2f, +R_CUBIC_TO, 0, -0.44f, 0.16f, -0.82f, 0.46f, -1.14f, +R_CUBIC_TO, 0.31f, -0.32f, 0.67f, -0.48f, 1.1f, -0.48f, +R_H_LINE_TO, 1.08f, +LINE_TO, 5.35f, 5.2f, +H_LINE_TO, 2.73f, +R_V_LINE_TO, 5.6f, +R_H_LINE_TO, 6.33f, +R_LINE_TO, -7.95f, -7.96f, +R_LINE_TO, 0.94f, -0.95f, +R_LINE_TO, 12.06f, 12.06f, +R_LINE_TO, -0.95f, 0.94f, +R_LINE_TO, -2.47f, -2.46f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/view_in_ar.icon b/components/vector_icons/view_in_ar.icon deleted file mode 100644 index 14168466..0000000 --- a/components/vector_icons/view_in_ar.icon +++ /dev/null
@@ -1,84 +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. - -CANVAS_DIMENSIONS, 24, -R_MOVE_TO, 10.86f, 19.54f, -R_LINE_TO, -4.82f, -2.77f, -R_ARC_TO, 2.3f, 2.3f, 0, 0, 1, -0.84f, -0.83f, -R_CUBIC_TO, -0.2f, -0.34f, -0.3f, -0.72f, -0.3f, -1.14f, -V_LINE_TO, 9.25f, -R_CUBIC_TO, 0, -0.41f, 0.1f, -0.79f, 0.3f, -1.14f, -R_CUBIC_TO, 0.2f, -0.34f, 0.48f, -0.62f, 0.84f, -0.83f, -R_LINE_TO, 4.82f, -2.77f, -ARC_TO, 2.22f, 2.22f, 0, 0, 1, 12, 4.2f, -R_CUBIC_TO, 0.4f, 0, 0.78f, 0.1f, 1.14f, 0.31f, -R_LINE_TO, 4.82f, 2.77f, -R_CUBIC_TO, 0.36f, 0.21f, 0.63f, 0.49f, 0.84f, 0.83f, -R_CUBIC_TO, 0.2f, 0.34f, 0.3f, 0.72f, 0.3f, 1.14f, -R_V_LINE_TO, 5.55f, -R_CUBIC_TO, 0, 0.41f, -0.1f, 0.79f, -0.3f, 1.14f, -R_CUBIC_TO, -0.2f, 0.34f, -0.48f, 0.62f, -0.84f, 0.83f, -R_LINE_TO, -4.82f, 2.77f, -R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, 0.31f, -R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, -0.31f, -CLOSE, -MOVE_TO, 11, 16.99f, -R_V_LINE_TO, -4.38f, -R_LINE_TO, -3.82f, -2.22f, -R_V_LINE_TO, 4.41f, -CLOSE, -R_MOVE_TO, 2, 0, -R_LINE_TO, 3.82f, -2.19f, -R_V_LINE_TO, -4.41f, -LINE_TO, 13, 12.61f, -CLOSE, -MOVE_TO, 1.8f, 6.98f, -V_LINE_TO, 4.07f, -R_CUBIC_TO, 0, -0.63f, 0.22f, -1.16f, 0.66f, -1.61f, -R_CUBIC_TO, 0.45f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f, -R_H_LINE_TO, 2.91f, -V_LINE_TO, 3.98f, -R_H_LINE_TO, -3, -R_V_LINE_TO, 3, -CLOSE, -MOVE_TO, 6.98f, 22.2f, -H_LINE_TO, 4.07f, -R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, -R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, -R_V_LINE_TO, -2.91f, -H_LINE_TO, 3.98f, -R_V_LINE_TO, 3, -R_H_LINE_TO, 3, -CLOSE, -R_MOVE_TO, 10.04f, 0, -V_LINE_TO, 20.02f, -R_H_LINE_TO, 3, -R_V_LINE_TO, -3, -R_H_LINE_TO, 2.18f, -R_V_LINE_TO, 2.91f, -R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, -R_CUBIC_TO, -0.44f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, -CLOSE, -R_MOVE_TO, 3, -15.22f, -R_V_LINE_TO, -3, -R_H_LINE_TO, -3, -V_LINE_TO, 1.8f, -R_H_LINE_TO, 2.91f, -R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, -R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, -R_V_LINE_TO, 2.91f, -CLOSE, -MOVE_TO, 12, 10.88f, -R_LINE_TO, 3.78f, -2.22f, -LINE_TO, 12, 6.47f, -R_LINE_TO, -3.78f, 2.18f, -CLOSE, -R_MOVE_TO, 0, 1.11f, -CLOSE, -R_MOVE_TO, 0, -1.11f, -CLOSE, -R_MOVE_TO, 1, 1.73f, -CLOSE, -R_MOVE_TO, -2, 0, -CLOSE \ No newline at end of file
diff --git a/components/vector_icons/view_in_ar_chrome_refresh.icon b/components/vector_icons/view_in_ar_chrome_refresh.icon new file mode 100644 index 0000000..6dc8076 --- /dev/null +++ b/components/vector_icons/view_in_ar_chrome_refresh.icon
@@ -0,0 +1,218 @@ +// 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. + +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 10.86f, 19.54f, +R_LINE_TO, -4.82f, -2.77f, +R_ARC_TO, 2.3f, 2.3f, 0, 0, 1, -0.84f, -0.83f, +R_CUBIC_TO, -0.2f, -0.34f, -0.3f, -0.72f, -0.3f, -1.14f, +V_LINE_TO, 9.25f, +R_CUBIC_TO, 0, -0.41f, 0.1f, -0.79f, 0.3f, -1.14f, +R_CUBIC_TO, 0.2f, -0.34f, 0.48f, -0.62f, 0.84f, -0.83f, +R_LINE_TO, 4.82f, -2.77f, +ARC_TO, 2.22f, 2.22f, 0, 0, 1, 12, 4.2f, +R_CUBIC_TO, 0.4f, 0, 0.78f, 0.1f, 1.14f, 0.31f, +R_LINE_TO, 4.82f, 2.77f, +R_CUBIC_TO, 0.36f, 0.21f, 0.63f, 0.49f, 0.84f, 0.83f, +R_CUBIC_TO, 0.2f, 0.34f, 0.3f, 0.72f, 0.3f, 1.14f, +R_V_LINE_TO, 5.55f, +R_CUBIC_TO, 0, 0.41f, -0.1f, 0.79f, -0.3f, 1.14f, +R_CUBIC_TO, -0.2f, 0.34f, -0.48f, 0.62f, -0.84f, 0.83f, +R_LINE_TO, -4.82f, 2.77f, +R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, 0.31f, +R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, -0.31f, +CLOSE, +MOVE_TO, 11, 16.99f, +R_V_LINE_TO, -4.38f, +R_LINE_TO, -3.82f, -2.22f, +R_V_LINE_TO, 4.41f, +CLOSE, +R_MOVE_TO, 2, 0, +R_LINE_TO, 3.82f, -2.19f, +R_V_LINE_TO, -4.41f, +LINE_TO, 13, 12.61f, +CLOSE, +MOVE_TO, 1.8f, 6.98f, +V_LINE_TO, 4.07f, +R_CUBIC_TO, 0, -0.63f, 0.22f, -1.16f, 0.66f, -1.61f, +R_CUBIC_TO, 0.45f, -0.44f, 0.98f, -0.66f, 1.61f, -0.66f, +R_H_LINE_TO, 2.91f, +V_LINE_TO, 3.98f, +R_H_LINE_TO, -3, +R_V_LINE_TO, 3, +CLOSE, +MOVE_TO, 6.98f, 22.2f, +H_LINE_TO, 4.07f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +R_V_LINE_TO, -2.91f, +H_LINE_TO, 3.98f, +R_V_LINE_TO, 3, +R_H_LINE_TO, 3, +CLOSE, +R_MOVE_TO, 10.04f, 0, +V_LINE_TO, 20.02f, +R_H_LINE_TO, 3, +R_V_LINE_TO, -3, +R_H_LINE_TO, 2.18f, +R_V_LINE_TO, 2.91f, +R_CUBIC_TO, 0, 0.63f, -0.22f, 1.16f, -0.66f, 1.61f, +R_CUBIC_TO, -0.44f, 0.44f, -0.98f, 0.66f, -1.61f, 0.66f, +CLOSE, +R_MOVE_TO, 3, -15.22f, +R_V_LINE_TO, -3, +R_H_LINE_TO, -3, +V_LINE_TO, 1.8f, +R_H_LINE_TO, 2.91f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +R_V_LINE_TO, 2.91f, +CLOSE, +MOVE_TO, 12, 10.88f, +R_LINE_TO, 3.78f, -2.22f, +LINE_TO, 12, 6.47f, +R_LINE_TO, -3.78f, 2.18f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 9.14f, 16.47f, +R_LINE_TO, -4.35f, -2.48f, +R_CUBIC_TO, -0.27f, -0.17f, -0.48f, -0.39f, -0.63f, -0.65f, +R_ARC_TO, 1.69f, 1.69f, 0, 0, 1, -0.23f, -0.86f, +V_LINE_TO, 7.54f, +R_ARC_TO, 1.72f, 1.72f, 0, 0, 1, 0.86f, -1.49f, +R_LINE_TO, 4.35f, -2.5f, +R_CUBIC_TO, 0.27f, -0.16f, 0.56f, -0.24f, 0.86f, -0.24f, +R_CUBIC_TO, 0.31f, 0, 0.59f, 0.08f, 0.86f, 0.24f, +R_LINE_TO, 4.35f, 2.5f, +R_ARC_TO, 1.72f, 1.72f, 0, 0, 1, 0.86f, 1.49f, +R_V_LINE_TO, 4.95f, +R_CUBIC_TO, 0, 0.31f, -0.08f, 0.59f, -0.23f, 0.85f, +R_ARC_TO, 1.92f, 1.92f, 0, 0, 1, -0.63f, 0.64f, +R_LINE_TO, -4.35f, 2.48f, +R_CUBIC_TO, -0.27f, 0.16f, -0.56f, 0.24f, -0.86f, 0.24f, +R_CUBIC_TO, -0.31f, 0, -0.59f, -0.08f, -0.86f, -0.24f, +CLOSE, +R_MOVE_TO, 0.11f, -1.91f, +V_LINE_TO, 10.44f, +LINE_TO, 5.66f, 8.28f, +R_V_LINE_TO, 4.22f, +CLOSE, +R_MOVE_TO, 1.5f, 0, +R_LINE_TO, 3.59f, -2.06f, +V_LINE_TO, 8.3f, +LINE_TO, 10.75f, 10.46f, +CLOSE, +R_MOVE_TO, -8.92f, -8.57f, +V_LINE_TO, 3.56f, +R_CUBIC_TO, 0, -0.48f, 0.17f, -0.89f, 0.5f, -1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, 1.22f, -0.5f, +R_H_LINE_TO, 2.42f, +R_V_LINE_TO, 1.65f, +R_H_LINE_TO, -2.5f, +R_V_LINE_TO, 2.5f, +CLOSE, +R_MOVE_TO, 4.15f, 12.18f, +H_LINE_TO, 3.56f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.5f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.22f, +R_V_LINE_TO, -2.42f, +R_H_LINE_TO, 1.65f, +R_V_LINE_TO, 2.5f, +R_H_LINE_TO, 2.5f, +CLOSE, +R_MOVE_TO, 8.03f, 0, +R_V_LINE_TO, -1.65f, +R_H_LINE_TO, 2.5f, +R_V_LINE_TO, -2.5f, +R_H_LINE_TO, 1.65f, +R_V_LINE_TO, 2.42f, +R_CUBIC_TO, 0, 0.48f, -0.17f, 0.89f, -0.5f, 1.22f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -1.22f, 0.5f, +CLOSE, +R_MOVE_TO, 2.5f, -12.18f, +R_V_LINE_TO, -2.5f, +R_H_LINE_TO, -2.5f, +V_LINE_TO, 1.83f, +R_H_LINE_TO, 2.42f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.5f, +R_CUBIC_TO, 0.34f, 0.34f, 0.5f, 0.75f, 0.5f, 1.22f, +R_V_LINE_TO, 2.42f, +CLOSE, +MOVE_TO, 10, 9.14f, +R_LINE_TO, 3.48f, -2.08f, +LINE_TO, 10, 5.06f, +LINE_TO, 6.52f, 7.06f, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 7.18f, 13.23f, +R_LINE_TO, -3.31f, -1.89f, +R_ARC_TO, 1.82f, 1.82f, 0, 0, 1, -0.6f, -0.61f, +R_ARC_TO, 1.6f, 1.6f, 0, 0, 1, -0.22f, -0.82f, +V_LINE_TO, 6.15f, +R_ARC_TO, 1.61f, 1.61f, 0, 0, 1, 0.82f, -1.41f, +R_LINE_TO, 3.31f, -1.91f, +R_CUBIC_TO, 0.25f, -0.15f, 0.53f, -0.22f, 0.82f, -0.22f, +R_CUBIC_TO, 0.29f, 0, 0.57f, 0.08f, 0.82f, 0.22f, +R_LINE_TO, 3.31f, 1.91f, +R_ARC_TO, 1.61f, 1.61f, 0, 0, 1, 0.82f, 1.41f, +R_V_LINE_TO, 3.78f, +R_CUBIC_TO, 0, 0.29f, -0.07f, 0.56f, -0.22f, 0.8f, +R_CUBIC_TO, -0.15f, 0.25f, -0.35f, 0.45f, -0.6f, 0.61f, +R_LINE_TO, -3.31f, 1.89f, +ARC_TO, 1.59f, 1.59f, 0, 0, 1, 8, 13.45f, +R_CUBIC_TO, -0.29f, 0, -0.57f, -0.07f, -0.82f, -0.22f, +CLOSE, +R_MOVE_TO, 0.21f, -1.75f, +V_LINE_TO, 8.38f, +LINE_TO, 4.69f, 6.74f, +R_V_LINE_TO, 3.18f, +CLOSE, +R_MOVE_TO, 1.2f, 0, +R_LINE_TO, 2.71f, -1.56f, +R_V_LINE_TO, -3.16f, +R_LINE_TO, -2.71f, 1.64f, +CLOSE, +R_MOVE_TO, -7.32f, -6.7f, +V_LINE_TO, 2.91f, +R_CUBIC_TO, 0, -0.46f, 0.16f, -0.84f, 0.47f, -1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, 1.16f, -0.47f, +R_H_LINE_TO, 1.86f, +R_V_LINE_TO, 1.49f, +R_H_LINE_TO, -2, +R_V_LINE_TO, 2, +CLOSE, +R_MOVE_TO, 3.49f, 9.95f, +H_LINE_TO, 2.91f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +R_V_LINE_TO, -1.86f, +R_H_LINE_TO, 1.49f, +R_V_LINE_TO, 2, +R_H_LINE_TO, 2, +CLOSE, +R_MOVE_TO, 6.45f, 0, +R_V_LINE_TO, -1.49f, +R_H_LINE_TO, 2, +R_V_LINE_TO, -2, +R_H_LINE_TO, 1.49f, +R_V_LINE_TO, 1.86f, +R_CUBIC_TO, 0, 0.46f, -0.16f, 0.84f, -0.47f, 1.16f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -1.16f, 0.47f, +CLOSE, +R_MOVE_TO, 2, -9.95f, +R_V_LINE_TO, -2, +R_H_LINE_TO, -2, +V_LINE_TO, 1.28f, +R_H_LINE_TO, 1.86f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.47f, +R_CUBIC_TO, 0.32f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f, +R_V_LINE_TO, 1.86f, +CLOSE, +MOVE_TO, 8, 7.34f, +R_LINE_TO, 2.63f, -1.57f, +LINE_TO, 8, 4.25f, +LINE_TO, 5.38f, 5.77f, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/view_in_ar_off.icon b/components/vector_icons/view_in_ar_off.icon deleted file mode 100644 index 1e36988..0000000 --- a/components/vector_icons/view_in_ar_off.icon +++ /dev/null
@@ -1,102 +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. - -CANVAS_DIMENSIONS, 24, -MOVE_TO, 13.95f, 10.88f, -CLOSE, -R_MOVE_TO, -1.88f, 1.1f, -CLOSE, -R_MOVE_TO, 6.77f, 3.8f, -LINE_TO, 8.78f, 5.71f, -R_LINE_TO, 2.09f, -1.2f, -ARC_TO, 2.22f, 2.22f, 0, 0, 1, 12, 4.2f, -R_CUBIC_TO, 0.4f, 0, 0.78f, 0.1f, 1.14f, 0.31f, -R_LINE_TO, 4.82f, 2.77f, -R_CUBIC_TO, 0.36f, 0.21f, 0.63f, 0.49f, 0.84f, 0.84f, -R_CUBIC_TO, 0.2f, 0.35f, 0.3f, 0.73f, 0.3f, 1.13f, -R_V_LINE_TO, 5.55f, -R_CUBIC_TO, 0, 0.18f, -0.02f, 0.35f, -0.07f, 0.51f, -R_CUBIC_TO, -0.04f, 0.16f, -0.1f, 0.32f, -0.18f, 0.47f, -CLOSE, -R_MOVE_TO, -7.98f, 3.75f, -R_LINE_TO, -4.82f, -2.77f, -R_ARC_TO, 2.26f, 2.26f, 0, 0, 1, -1.14f, -1.96f, -V_LINE_TO, 9.25f, -R_CUBIC_TO, 0, -0.4f, 0.1f, -0.78f, 0.3f, -1.13f, -R_CUBIC_TO, 0.2f, -0.35f, 0.48f, -0.63f, 0.84f, -0.84f, -R_LINE_TO, 0.85f, -0.48f, -LINE_TO, 17.25f, 17.15f, -R_LINE_TO, -4.11f, 2.38f, -R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, 0.31f, -R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, -0.31f, -CLOSE, -R_MOVE_TO, 2.36f, -9.37f, -CLOSE, -MOVE_TO, 11, 12.61f, -CLOSE, -R_MOVE_TO, 3.68f, -0.99f, -CLOSE, -MOVE_TO, 13, 12.91f, -CLOSE, -R_MOVE_TO, -2.57f, -5.54f, -R_LINE_TO, 2.79f, 2.79f, -R_LINE_TO, 2.55f, -1.51f, -LINE_TO, 12, 6.47f, -CLOSE, -R_MOVE_TO, 0.57f, 9.62f, -R_V_LINE_TO, -4.38f, -R_LINE_TO, -3.82f, -2.22f, -R_V_LINE_TO, 4.41f, -CLOSE, -R_MOVE_TO, 5.82f, -3.24f, -R_V_LINE_TO, -3.37f, -R_LINE_TO, -2.14f, 1.23f, -CLOSE, -MOVE_TO, 13, 16.99f, -R_LINE_TO, 2.59f, -1.49f, -R_LINE_TO, -2.59f, -2.59f, -CLOSE, -R_MOVE_TO, 7.55f, 6.44f, -R_LINE_TO, -1.22f, -1.22f, -H_LINE_TO, 17.02f, -R_V_LINE_TO, -2.19f, -R_H_LINE_TO, 0.31f, -R_V_LINE_TO, 0.2f, -LINE_TO, 3.64f, 6.52f, -R_H_LINE_TO, 0.35f, -R_V_LINE_TO, 0.46f, -H_LINE_TO, 1.8f, -V_LINE_TO, 4.68f, -LINE_TO, 0.62f, 3.5f, -R_LINE_TO, 1.48f, -1.48f, -R_LINE_TO, 19.93f, 19.93f, -CLOSE, -R_MOVE_TO, 1.65f, -6.41f, -R_V_LINE_TO, 2.12f, -R_LINE_TO, -2, -2, -R_V_LINE_TO, -0.11f, -CLOSE, -MOVE_TO, 6.98f, 1.8f, -R_V_LINE_TO, 2, -R_H_LINE_TO, -0.11f, -R_LINE_TO, -2, -2, -CLOSE, -R_MOVE_TO, 0, 20.41f, -H_LINE_TO, 4.07f, -R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, -R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, -R_V_LINE_TO, -2.91f, -H_LINE_TO, 3.98f, -R_V_LINE_TO, 3, -R_H_LINE_TO, 3, -CLOSE, -MOVE_TO, 20.02f, 6.98f, -R_V_LINE_TO, -3, -R_H_LINE_TO, -3, -V_LINE_TO, 1.8f, -R_H_LINE_TO, 2.91f, -R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, -R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, -R_V_LINE_TO, 2.91f, -CLOSE \ No newline at end of file
diff --git a/components/vector_icons/view_in_ar_off_chrome_refresh.icon b/components/vector_icons/view_in_ar_off_chrome_refresh.icon new file mode 100644 index 0000000..5631599 --- /dev/null +++ b/components/vector_icons/view_in_ar_off_chrome_refresh.icon
@@ -0,0 +1,301 @@ +// 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. + +CANVAS_DIMENSIONS, 24, +MOVE_TO, 13.95f, 10.88f, +CLOSE, +R_MOVE_TO, -1.88f, 1.1f, +CLOSE, +R_MOVE_TO, 6.77f, 3.8f, +LINE_TO, 8.78f, 5.71f, +R_LINE_TO, 2.09f, -1.2f, +ARC_TO, 2.22f, 2.22f, 0, 0, 1, 12, 4.2f, +R_CUBIC_TO, 0.4f, 0, 0.78f, 0.1f, 1.14f, 0.31f, +R_LINE_TO, 4.82f, 2.77f, +R_CUBIC_TO, 0.36f, 0.21f, 0.63f, 0.49f, 0.84f, 0.84f, +R_CUBIC_TO, 0.2f, 0.35f, 0.3f, 0.73f, 0.3f, 1.13f, +R_V_LINE_TO, 5.55f, +R_CUBIC_TO, 0, 0.18f, -0.02f, 0.35f, -0.07f, 0.51f, +R_CUBIC_TO, -0.04f, 0.16f, -0.1f, 0.32f, -0.18f, 0.47f, +CLOSE, +R_MOVE_TO, -7.98f, 3.75f, +R_LINE_TO, -4.82f, -2.77f, +R_ARC_TO, 2.26f, 2.26f, 0, 0, 1, -1.14f, -1.96f, +V_LINE_TO, 9.25f, +R_CUBIC_TO, 0, -0.4f, 0.1f, -0.78f, 0.3f, -1.13f, +R_CUBIC_TO, 0.2f, -0.35f, 0.48f, -0.63f, 0.84f, -0.84f, +R_LINE_TO, 0.85f, -0.48f, +LINE_TO, 17.25f, 17.15f, +R_LINE_TO, -4.11f, 2.38f, +R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, 0.31f, +R_ARC_TO, 2.22f, 2.22f, 0, 0, 1, -1.14f, -0.31f, +CLOSE, +R_MOVE_TO, 2.36f, -9.37f, +CLOSE, +MOVE_TO, 11, 12.61f, +CLOSE, +R_MOVE_TO, 3.68f, -0.99f, +CLOSE, +MOVE_TO, 13, 12.91f, +CLOSE, +R_MOVE_TO, -2.57f, -5.54f, +R_LINE_TO, 2.79f, 2.79f, +R_LINE_TO, 2.55f, -1.51f, +LINE_TO, 12, 6.47f, +CLOSE, +R_MOVE_TO, 0.57f, 9.62f, +R_V_LINE_TO, -4.38f, +R_LINE_TO, -3.82f, -2.22f, +R_V_LINE_TO, 4.41f, +CLOSE, +R_MOVE_TO, 5.82f, -3.24f, +R_V_LINE_TO, -3.37f, +R_LINE_TO, -2.14f, 1.23f, +CLOSE, +MOVE_TO, 13, 16.99f, +R_LINE_TO, 2.59f, -1.49f, +R_LINE_TO, -2.59f, -2.59f, +CLOSE, +R_MOVE_TO, 7.55f, 6.44f, +R_LINE_TO, -1.22f, -1.22f, +H_LINE_TO, 17.02f, +R_V_LINE_TO, -2.19f, +R_H_LINE_TO, 0.31f, +R_V_LINE_TO, 0.2f, +LINE_TO, 3.64f, 6.52f, +R_H_LINE_TO, 0.35f, +R_V_LINE_TO, 0.46f, +H_LINE_TO, 1.8f, +V_LINE_TO, 4.68f, +LINE_TO, 0.62f, 3.5f, +R_LINE_TO, 1.48f, -1.48f, +R_LINE_TO, 19.93f, 19.93f, +CLOSE, +R_MOVE_TO, 1.65f, -6.41f, +R_V_LINE_TO, 2.12f, +R_LINE_TO, -2, -2, +R_V_LINE_TO, -0.11f, +CLOSE, +MOVE_TO, 6.98f, 1.8f, +R_V_LINE_TO, 2, +R_H_LINE_TO, -0.11f, +R_LINE_TO, -2, -2, +CLOSE, +R_MOVE_TO, 0, 20.41f, +H_LINE_TO, 4.07f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -1.61f, -0.66f, +R_ARC_TO, 2.2f, 2.2f, 0, 0, 1, -0.66f, -1.61f, +R_V_LINE_TO, -2.91f, +H_LINE_TO, 3.98f, +R_V_LINE_TO, 3, +R_H_LINE_TO, 3, +CLOSE, +MOVE_TO, 20.02f, 6.98f, +R_V_LINE_TO, -3, +R_H_LINE_TO, -3, +V_LINE_TO, 1.8f, +R_H_LINE_TO, 2.91f, +R_CUBIC_TO, 0.63f, 0, 1.16f, 0.22f, 1.61f, 0.66f, +R_CUBIC_TO, 0.44f, 0.45f, 0.66f, 0.98f, 0.66f, 1.61f, +R_V_LINE_TO, 2.91f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 11.46f, 9.15f, +CLOSE, +R_MOVE_TO, -1.4f, 0.83f, +CLOSE, +R_MOVE_TO, 5.69f, 3.46f, +LINE_TO, 7.04f, 4.74f, +R_LINE_TO, 2.09f, -1.19f, +R_CUBIC_TO, 0.27f, -0.16f, 0.56f, -0.24f, 0.86f, -0.24f, +R_CUBIC_TO, 0.31f, 0, 0.59f, 0.08f, 0.86f, 0.24f, +R_LINE_TO, 4.35f, 2.5f, +R_CUBIC_TO, 0.27f, 0.16f, 0.48f, 0.37f, 0.63f, 0.64f, +R_CUBIC_TO, 0.16f, 0.27f, 0.23f, 0.55f, 0.23f, 0.86f, +R_V_LINE_TO, 4.95f, +R_CUBIC_TO, 0, 0.17f, -0.03f, 0.34f, -0.09f, 0.5f, +R_ARC_TO, 1.99f, 1.99f, 0, 0, 1, -0.24f, 0.45f, +CLOSE, +R_MOVE_TO, -6.61f, 3.02f, +LINE_TO, 4.79f, 13.99f, +R_ARC_TO, 1.92f, 1.92f, 0, 0, 1, -0.63f, -0.64f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.23f, -0.87f, +V_LINE_TO, 7.54f, +R_CUBIC_TO, 0, -0.3f, 0.07f, -0.59f, 0.23f, -0.86f, +R_CUBIC_TO, 0.15f, -0.27f, 0.36f, -0.48f, 0.63f, -0.64f, +R_LINE_TO, 0.86f, -0.48f, +R_LINE_TO, 8.84f, 8.83f, +R_LINE_TO, -3.62f, 2.07f, +R_CUBIC_TO, -0.27f, 0.16f, -0.56f, 0.24f, -0.86f, 0.24f, +R_CUBIC_TO, -0.31f, 0, -0.59f, -0.08f, -0.86f, -0.24f, +CLOSE, +R_MOVE_TO, 1.78f, -7.85f, +CLOSE, +MOVE_TO, 9.25f, 10.44f, +CLOSE, +R_MOVE_TO, 2.75f, -0.74f, +CLOSE, +R_MOVE_TO, -1.25f, 0.97f, +CLOSE, +MOVE_TO, 8.34f, 6.04f, +R_LINE_TO, 2.58f, 2.58f, +R_LINE_TO, 2.56f, -1.55f, +LINE_TO, 10, 5.06f, +CLOSE, +R_MOVE_TO, 0.91f, 8.52f, +V_LINE_TO, 10.44f, +LINE_TO, 5.66f, 8.28f, +R_V_LINE_TO, 4.22f, +CLOSE, +R_MOVE_TO, 5.09f, -2.51f, +V_LINE_TO, 8.3f, +R_LINE_TO, -2.34f, 1.4f, +CLOSE, +R_MOVE_TO, -3.59f, 2.51f, +R_LINE_TO, 2.47f, -1.41f, +R_LINE_TO, -2.47f, -2.47f, +CLOSE, +R_MOVE_TO, 6.06f, 4.38f, +R_LINE_TO, -0.77f, -0.77f, +R_H_LINE_TO, -2.03f, +R_V_LINE_TO, -1.66f, +R_H_LINE_TO, 0.53f, +R_V_LINE_TO, 0.17f, +LINE_TO, 3.2f, 5.33f, +R_H_LINE_TO, 0.29f, +R_V_LINE_TO, 0.66f, +H_LINE_TO, 1.83f, +V_LINE_TO, 3.96f, +R_LINE_TO, -0.69f, -0.69f, +R_LINE_TO, 1.11f, -1.09f, +R_LINE_TO, 15.65f, 15.64f, +CLOSE, +R_MOVE_TO, 1.36f, -4.92f, +R_V_LINE_TO, 1.85f, +R_LINE_TO, -1.5f, -1.5f, +R_V_LINE_TO, -0.34f, +CLOSE, +MOVE_TO, 5.98f, 1.83f, +R_V_LINE_TO, 1.5f, +R_H_LINE_TO, -0.34f, +R_LINE_TO, -1.5f, -1.5f, +CLOSE, +R_MOVE_TO, 0, 16.34f, +H_LINE_TO, 3.56f, +R_CUBIC_TO, -0.48f, 0, -0.89f, -0.17f, -1.22f, -0.5f, +R_ARC_TO, 1.67f, 1.67f, 0, 0, 1, -0.5f, -1.22f, +R_V_LINE_TO, -2.42f, +R_H_LINE_TO, 1.65f, +R_V_LINE_TO, 2.5f, +R_H_LINE_TO, 2.5f, +CLOSE, +MOVE_TO, 16.52f, 5.98f, +R_V_LINE_TO, -2.5f, +R_H_LINE_TO, -2.5f, +V_LINE_TO, 1.83f, +R_H_LINE_TO, 2.42f, +R_CUBIC_TO, 0.48f, 0, 0.89f, 0.17f, 1.22f, 0.5f, +R_CUBIC_TO, 0.34f, 0.34f, 0.5f, 0.75f, 0.5f, 1.22f, +R_V_LINE_TO, 2.42f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 9.3f, 7.26f, +CLOSE, +R_MOVE_TO, -1.19f, 0.71f, +CLOSE, +R_MOVE_TO, 4.59f, 2.69f, +R_LINE_TO, -7, -7, +R_LINE_TO, 1.48f, -0.84f, +R_CUBIC_TO, 0.25f, -0.15f, 0.53f, -0.22f, 0.82f, -0.22f, +R_CUBIC_TO, 0.29f, 0, 0.57f, 0.08f, 0.82f, 0.22f, +R_LINE_TO, 3.31f, 1.91f, +R_ARC_TO, 1.62f, 1.62f, 0, 0, 1, 0.82f, 1.41f, +R_V_LINE_TO, 3.78f, +R_CUBIC_TO, 0, 0.14f, -0.02f, 0.26f, -0.06f, 0.39f, +R_ARC_TO, 1.83f, 1.83f, 0, 0, 1, -0.17f, 0.35f, +CLOSE, +R_MOVE_TO, -5.52f, 2.56f, +R_LINE_TO, -3.31f, -1.89f, +R_CUBIC_TO, -0.25f, -0.16f, -0.45f, -0.36f, -0.6f, -0.61f, +R_ARC_TO, 1.57f, 1.57f, 0, 0, 1, -0.22f, -0.82f, +V_LINE_TO, 6.15f, +R_ARC_TO, 1.62f, 1.62f, 0, 0, 1, 0.82f, -1.41f, +R_LINE_TO, 0.64f, -0.36f, +R_LINE_TO, 3.6f, 3.6f, +R_LINE_TO, 3.6f, 3.59f, +R_LINE_TO, -2.9f, 1.66f, +ARC_TO, 1.59f, 1.59f, 0, 0, 1, 8, 13.45f, +R_CUBIC_TO, -0.29f, 0, -0.57f, -0.07f, -0.82f, -0.22f, +CLOSE, +R_MOVE_TO, 1.68f, -6.4f, +CLOSE, +R_MOVE_TO, -1.47f, 1.55f, +CLOSE, +R_MOVE_TO, 2.35f, -0.67f, +CLOSE, +R_MOVE_TO, -1.14f, 0.74f, +CLOSE, +MOVE_TO, 6.93f, 4.89f, +R_LINE_TO, 1.94f, 1.94f, +R_LINE_TO, 1.76f, -1.06f, +LINE_TO, 8, 4.25f, +CLOSE, +R_MOVE_TO, 0.47f, 6.59f, +V_LINE_TO, 8.38f, +LINE_TO, 4.69f, 6.74f, +R_V_LINE_TO, 3.18f, +CLOSE, +R_MOVE_TO, 3.91f, -2.21f, +V_LINE_TO, 6.76f, +R_LINE_TO, -1.56f, 0.95f, +CLOSE, +R_MOVE_TO, -2.71f, 2.21f, +R_LINE_TO, 1.92f, -1.11f, +LINE_TO, 8.6f, 8.45f, +CLOSE, +R_MOVE_TO, 4.94f, 3.79f, +LINE_TO, 13, 14.72f, +R_H_LINE_TO, -1.77f, +V_LINE_TO, 13.21f, +R_H_LINE_TO, 0.39f, +R_V_LINE_TO, 0.13f, +LINE_TO, 2.55f, 4.28f, +R_H_LINE_TO, 0.23f, +R_V_LINE_TO, 0.5f, +R_H_LINE_TO, -1.5f, +V_LINE_TO, 3.01f, +R_LINE_TO, -0.39f, -0.39f, +R_LINE_TO, 0.95f, -0.93f, +R_LINE_TO, 12.64f, 12.63f, +CLOSE, +R_MOVE_TO, 1.18f, -4.04f, +R_V_LINE_TO, 1.45f, +R_LINE_TO, -1.2f, -1.21f, +R_V_LINE_TO, -0.25f, +CLOSE, +MOVE_TO, 4.77f, 1.28f, +R_V_LINE_TO, 1.2f, +R_H_LINE_TO, -0.25f, +LINE_TO, 3.32f, 1.28f, +CLOSE, +R_MOVE_TO, 0, 13.44f, +H_LINE_TO, 2.91f, +R_CUBIC_TO, -0.46f, 0, -0.84f, -0.16f, -1.16f, -0.47f, +R_ARC_TO, 1.58f, 1.58f, 0, 0, 1, -0.47f, -1.16f, +R_V_LINE_TO, -1.86f, +R_H_LINE_TO, 1.49f, +R_V_LINE_TO, 2, +R_H_LINE_TO, 2, +CLOSE, +R_MOVE_TO, 8.45f, -9.95f, +R_V_LINE_TO, -2, +R_H_LINE_TO, -2, +V_LINE_TO, 1.28f, +R_H_LINE_TO, 1.86f, +R_CUBIC_TO, 0.46f, 0, 0.84f, 0.16f, 1.16f, 0.47f, +R_CUBIC_TO, 0.32f, 0.32f, 0.47f, 0.7f, 0.47f, 1.16f, +R_V_LINE_TO, 1.86f, +CLOSE \ No newline at end of file
diff --git a/components/vector_icons/volume_off_chrome_refresh.icon b/components/vector_icons/volume_off_chrome_refresh.icon index 3bb510092..89a3bde 100644 --- a/components/vector_icons/volume_off_chrome_refresh.icon +++ b/components/vector_icons/volume_off_chrome_refresh.icon
@@ -2,54 +2,152 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +R_MOVE_TO, 19.86f, 22.79f, +R_LINE_TO, -3.04f, -3.05f, +R_ARC_TO, 8.69f, 8.69f, 0, 0, 1, -2.68f, 1.09f, +R_V_LINE_TO, -2.15f, +R_CUBIC_TO, 0.2f, -0.07f, 0.4f, -0.14f, 0.6f, -0.21f, +R_CUBIC_TO, 0.19f, -0.07f, 0.38f, -0.16f, 0.56f, -0.26f, +R_LINE_TO, -3.15f, -3.16f, +R_V_LINE_TO, 5.45f, +R_LINE_TO, -5.28f, -5.28f, +H_LINE_TO, 2.75f, +V_LINE_TO, 8.8f, +R_H_LINE_TO, 3.21f, +R_LINE_TO, -4.76f, -4.8f, +R_LINE_TO, 1.46f, -1.46f, +R_LINE_TO, 18.67f, 18.79f, +CLOSE, +R_MOVE_TO, -0.04f, -5.93f, +R_LINE_TO, -1.51f, -1.53f, +R_ARC_TO, 6.83f, 6.83f, 0, 0, 0, 0.64f, -1.62f, +R_ARC_TO, 7.22f, 7.22f, 0, 0, 0, 0.21f, -1.75f, +R_CUBIC_TO, 0, -1.56f, -0.46f, -2.96f, -1.38f, -4.19f, +R_CUBIC_TO, -0.92f, -1.23f, -2.13f, -2.07f, -3.62f, -2.51f, +V_LINE_TO, 3.13f, +R_CUBIC_TO, 2.09f, 0.47f, 3.8f, 1.53f, 5.12f, 3.17f, +R_CUBIC_TO, 1.32f, 1.64f, 1.98f, 3.54f, 1.98f, 5.68f, +R_CUBIC_TO, 0, 0.9f, -0.12f, 1.76f, -0.37f, 2.59f, +R_ARC_TO, 9.22f, 9.22f, 0, 0, 1, -1.06f, 2.31f, +CLOSE, +R_MOVE_TO, -3.34f, -3.36f, +R_LINE_TO, -2.33f, -2.33f, +V_LINE_TO, 7.88f, +R_CUBIC_TO, 0.8f, 0.38f, 1.43f, 0.93f, 1.9f, 1.68f, +R_ARC_TO, 4.52f, 4.52f, 0, 0, 1, 0.63f, 3.22f, +R_ARC_TO, 3.93f, 3.93f, 0, 0, 1, -0.2f, 0.73f, +CLOSE, +R_MOVE_TO, -4.32f, -4.35f, +R_LINE_TO, -2.8f, -2.83f, +R_LINE_TO, 2.8f, -2.8f, +CLOSE, +R_MOVE_TO, -2.27f, 5.83f, +R_V_LINE_TO, -2.24f, +LINE_TO, 8.22f, 11.07f, +H_LINE_TO, 5.02f, +R_V_LINE_TO, 1.86f, +R_H_LINE_TO, 2.8f, +CLOSE + +CANVAS_DIMENSIONS, 20, +R_MOVE_TO, 16.05f, 18.29f, +R_LINE_TO, -2.24f, -2.25f, +R_CUBIC_TO, -0.29f, 0.18f, -0.64f, 0.36f, -1.05f, 0.52f, +R_ARC_TO, 7.37f, 7.37f, 0, 0, 1, -1.13f, 0.36f, +R_V_LINE_TO, -1.62f, +R_CUBIC_TO, 0.14f, -0.06f, 0.31f, -0.13f, 0.52f, -0.21f, +R_CUBIC_TO, 0.2f, -0.08f, 0.38f, -0.16f, 0.51f, -0.23f, +R_LINE_TO, -2.52f, -2.53f, +R_V_LINE_TO, 4.1f, +R_LINE_TO, -4.23f, -4.23f, +H_LINE_TO, 2.79f, +R_V_LINE_TO, -4.34f, +R_H_LINE_TO, 2.89f, +LINE_TO, 1.71f, 3.83f, +R_LINE_TO, 1.11f, -1.11f, +R_LINE_TO, 14.35f, 14.45f, +CLOSE, +R_MOVE_TO, 0.01f, -4.46f, +R_LINE_TO, -1.14f, -1.15f, +R_CUBIC_TO, 0.22f, -0.4f, 0.4f, -0.82f, 0.52f, -1.27f, +R_CUBIC_TO, 0.12f, -0.45f, 0.19f, -0.91f, 0.19f, -1.38f, +R_CUBIC_TO, 0, -1.23f, -0.37f, -2.33f, -1.12f, -3.29f, +R_ARC_TO, 5.71f, 5.71f, 0, 0, 0, -2.88f, -2, +V_LINE_TO, 3.1f, +R_CUBIC_TO, 1.65f, 0.32f, 2.98f, 1.14f, 4.02f, 2.45f, +R_CUBIC_TO, 1.04f, 1.31f, 1.56f, 2.8f, 1.56f, 4.47f, +R_CUBIC_TO, 0, 0.68f, -0.1f, 1.34f, -0.3f, 1.98f, +R_ARC_TO, 7.67f, 7.67f, 0, 0, 1, -0.85f, 1.82f, +CLOSE, +R_MOVE_TO, -2.58f, -2.59f, +R_LINE_TO, -1.85f, -1.86f, +V_LINE_TO, 6.79f, +R_ARC_TO, 3.43f, 3.43f, 0, 0, 1, 1.52f, 1.31f, +R_CUBIC_TO, 0.37f, 0.59f, 0.56f, 1.23f, 0.56f, 1.92f, +R_CUBIC_TO, 0, 0.21f, -0.01f, 0.41f, -0.05f, 0.61f, +R_CUBIC_TO, -0.03f, 0.2f, -0.09f, 0.4f, -0.18f, 0.6f, +CLOSE, +R_MOVE_TO, -3.35f, -3.37f, +LINE_TO, 8.02f, 5.72f, +R_LINE_TO, 2.11f, -2.11f, +CLOSE, +R_MOVE_TO, -1.73f, 4.39f, +R_V_LINE_TO, -1.68f, +R_LINE_TO, -1.38f, -1.39f, +R_LINE_TO, -0.37f, 0.4f, +H_LINE_TO, 4.52f, +R_V_LINE_TO, 0.88f, +R_H_LINE_TO, 2.09f, +CLOSE + CANVAS_DIMENSIONS, 16, -R_MOVE_TO, 12.84f, 14.63f, -R_LINE_TO, -1.79f, -1.8f, -R_ARC_TO, 5.1f, 5.1f, 0, 0, 1, -0.84f, 0.41f, -R_CUBIC_TO, -0.33f, 0.13f, -0.63f, 0.23f, -0.91f, 0.29f, -R_V_LINE_TO, -1.3f, -R_CUBIC_TO, 0.11f, -0.05f, 0.25f, -0.11f, 0.41f, -0.17f, -R_CUBIC_TO, 0.16f, -0.07f, 0.3f, -0.12f, 0.41f, -0.18f, -LINE_TO, 8.1f, 9.86f, -R_V_LINE_TO, 3.28f, -LINE_TO, 4.71f, 9.75f, -H_LINE_TO, 2.23f, -V_LINE_TO, 6.28f, -H_LINE_TO, 4.54f, -LINE_TO, 1.36f, 3.07f, -R_LINE_TO, 0.89f, -0.89f, -R_LINE_TO, 11.48f, 11.56f, +R_MOVE_TO, 12.9f, 14.8f, +R_LINE_TO, -1.8f, -1.82f, +R_ARC_TO, 5.67f, 5.67f, 0, 0, 1, -0.8f, 0.38f, +R_ARC_TO, 4.66f, 4.66f, 0, 0, 1, -0.86f, 0.27f, +R_V_LINE_TO, -1.39f, +R_CUBIC_TO, 0.09f, -0.04f, 0.2f, -0.08f, 0.33f, -0.14f, +R_CUBIC_TO, 0.14f, -0.05f, 0.25f, -0.1f, 0.33f, -0.14f, +R_LINE_TO, -1.86f, -1.88f, +R_V_LINE_TO, 3.5f, +R_LINE_TO, -3.64f, -3.64f, +R_H_LINE_TO, -2.59f, +R_V_LINE_TO, -3.84f, +R_H_LINE_TO, 2.32f, +LINE_TO, 1.18f, 2.88f, +R_LINE_TO, 0.95f, -0.94f, +R_LINE_TO, 11.72f, 11.91f, CLOSE, -R_MOVE_TO, 0, -3.57f, -R_LINE_TO, -0.91f, -0.92f, -R_CUBIC_TO, 0.18f, -0.32f, 0.32f, -0.66f, 0.42f, -1.02f, +R_MOVE_TO, 0.14f, -3.68f, +R_LINE_TO, -0.97f, -0.99f, +R_ARC_TO, 4.59f, 4.59f, 0, 0, 0, 0.41f, -1.01f, R_CUBIC_TO, 0.1f, -0.36f, 0.15f, -0.73f, 0.15f, -1.1f, -R_ARC_TO, 4.2f, 4.2f, 0, 0, 0, -0.89f, -2.63f, -R_ARC_TO, 4.57f, 4.57f, 0, 0, 0, -2.3f, -1.6f, -V_LINE_TO, 2.48f, -R_ARC_TO, 5.31f, 5.31f, 0, 0, 1, 3.22f, 1.96f, -R_ARC_TO, 5.6f, 5.6f, 0, 0, 1, 1.24f, 3.58f, -R_CUBIC_TO, 0, 0.55f, -0.08f, 1.07f, -0.24f, 1.58f, -R_CUBIC_TO, -0.16f, 0.51f, -0.39f, 1, -0.68f, 1.46f, +R_CUBIC_TO, 0, -0.98f, -0.3f, -1.86f, -0.9f, -2.62f, +R_ARC_TO, 4.68f, 4.68f, 0, 0, 0, -2.3f, -1.61f, +V_LINE_TO, 2.39f, +R_ARC_TO, 5.4f, 5.4f, 0, 0, 1, 3.28f, 1.99f, +R_ARC_TO, 5.68f, 5.68f, 0, 0, 1, 1.27f, 3.64f, +R_CUBIC_TO, 0, 0.56f, -0.08f, 1.1f, -0.25f, 1.62f, +R_ARC_TO, 6.45f, 6.45f, 0, 0, 1, -0.7f, 1.49f, CLOSE, -MOVE_TO, 10.78f, 8.98f, -R_LINE_TO, -1.48f, -1.49f, -V_LINE_TO, 5.43f, -R_ARC_TO, 2.82f, 2.82f, 0, 0, 1, 1.66f, 2.58f, -R_CUBIC_TO, 0, 0.16f, -0.02f, 0.33f, -0.04f, 0.49f, -R_ARC_TO, 1.79f, 1.79f, 0, 0, 1, -0.14f, 0.48f, +MOVE_TO, 10.98f, 9.04f, +LINE_TO, 9.43f, 7.47f, +V_LINE_TO, 5.37f, +R_CUBIC_TO, 0.53f, 0.23f, 0.95f, 0.59f, 1.27f, 1.07f, +R_CUBIC_TO, 0.32f, 0.48f, 0.48f, 1, 0.48f, 1.58f, +R_CUBIC_TO, 0, 0.18f, -0.01f, 0.35f, -0.04f, 0.52f, +R_ARC_TO, 1.83f, 1.83f, 0, 0, 1, -0.16f, 0.5f, CLOSE, -R_MOVE_TO, -2.68f, -2.7f, -LINE_TO, 6.42f, 4.58f, -R_LINE_TO, 1.69f, -1.68f, +MOVE_TO, 8.23f, 6.24f, +R_LINE_TO, -1.87f, -1.92f, +R_LINE_TO, 1.87f, -1.87f, CLOSE, -MOVE_TO, 6.72f, 9.8f, -V_LINE_TO, 8.46f, -LINE_TO, 5.61f, 7.35f, +MOVE_TO, 6.6f, 9.65f, +V_LINE_TO, 8.41f, +R_LINE_TO, -0.97f, -0.99f, R_LINE_TO, -0.3f, 0.32f, -H_LINE_TO, 3.62f, -R_V_LINE_TO, 0.7f, -R_H_LINE_TO, 1.67f, -CLOSE, -R_MOVE_TO, -0.55f, -1.9f, +H_LINE_TO, 3.64f, +R_V_LINE_TO, 0.57f, +R_H_LINE_TO, 1.63f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/volume_up_chrome_refresh.icon b/components/vector_icons/volume_up_chrome_refresh.icon index 51a315e..4e030f5 100644 --- a/components/vector_icons/volume_up_chrome_refresh.icon +++ b/components/vector_icons/volume_up_chrome_refresh.icon
@@ -2,39 +2,107 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +CANVAS_DIMENSIONS, 24, +MOVE_TO, 14.16f, 20.83f, +R_V_LINE_TO, -2.15f, +R_CUBIC_TO, 1.5f, -0.44f, 2.7f, -1.28f, 3.62f, -2.51f, +R_CUBIC_TO, 0.92f, -1.23f, 1.38f, -2.63f, 1.38f, -4.19f, +R_CUBIC_TO, 0, -1.56f, -0.46f, -2.96f, -1.38f, -4.19f, +R_CUBIC_TO, -0.92f, -1.23f, -2.12f, -2.07f, -3.62f, -2.51f, +V_LINE_TO, 3.13f, +R_CUBIC_TO, 2.09f, 0.47f, 3.79f, 1.53f, 5.11f, 3.17f, +R_CUBIC_TO, 1.32f, 1.64f, 1.98f, 3.54f, 1.98f, 5.68f, +R_CUBIC_TO, 0, 2.14f, -0.66f, 4.03f, -1.98f, 5.68f, +R_CUBIC_TO, -1.32f, 1.65f, -3.02f, 2.7f, -5.11f, 3.18f, +CLOSE, +MOVE_TO, 2.75f, 15.2f, +V_LINE_TO, 8.8f, +R_H_LINE_TO, 4.12f, +R_LINE_TO, 5.28f, -5.28f, +R_V_LINE_TO, 16.97f, +R_LINE_TO, -5.28f, -5.28f, +CLOSE, +R_MOVE_TO, 11.4f, 0.87f, +V_LINE_TO, 7.88f, +R_CUBIC_TO, 0.8f, 0.38f, 1.43f, 0.94f, 1.9f, 1.68f, +R_CUBIC_TO, 0.46f, 0.74f, 0.7f, 1.55f, 0.7f, 2.44f, +R_ARC_TO, 4.44f, 4.44f, 0, 0, 1, -0.69f, 2.41f, +R_ARC_TO, 4.43f, 4.43f, 0, 0, 1, -1.89f, 1.66f, +CLOSE, +MOVE_TO, 9.88f, 9.02f, +LINE_TO, 7.83f, 11.07f, +R_H_LINE_TO, -2.8f, +R_V_LINE_TO, 1.86f, +R_H_LINE_TO, 2.8f, +R_LINE_TO, 2.05f, 2.05f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 11.63f, 16.92f, +V_LINE_TO, 15.27f, +R_ARC_TO, 5.28f, 5.28f, 0, 0, 0, 2.89f, -1.95f, +R_CUBIC_TO, 0.74f, -0.97f, 1.11f, -2.08f, 1.11f, -3.32f, +R_CUBIC_TO, 0, -1.23f, -0.37f, -2.34f, -1.12f, -3.3f, +R_ARC_TO, 5.68f, 5.68f, 0, 0, 0, -2.88f, -2, +V_LINE_TO, 3.06f, +R_ARC_TO, 6.84f, 6.84f, 0, 0, 1, 4.01f, 2.46f, +R_CUBIC_TO, 1.04f, 1.3f, 1.56f, 2.78f, 1.56f, 4.45f, +R_CUBIC_TO, 0, 1.67f, -0.51f, 3.16f, -1.55f, 4.46f, +R_CUBIC_TO, -1.04f, 1.3f, -2.38f, 2.13f, -4.02f, 2.48f, +CLOSE, +R_MOVE_TO, -8.83f, -4.77f, +R_V_LINE_TO, -4.34f, +R_H_LINE_TO, 3.1f, +R_LINE_TO, 4.23f, -4.23f, +R_V_LINE_TO, 12.81f, +R_LINE_TO, -4.23f, -4.24f, +CLOSE, +R_MOVE_TO, 8.83f, 1.04f, +R_V_LINE_TO, -6.41f, +R_CUBIC_TO, 0.64f, 0.29f, 1.14f, 0.73f, 1.52f, 1.3f, +R_CUBIC_TO, 0.37f, 0.57f, 0.55f, 1.21f, 0.55f, 1.91f, +R_CUBIC_TO, 0, 0.69f, -0.18f, 1.33f, -0.56f, 1.9f, +R_ARC_TO, 3.52f, 3.52f, 0, 0, 1, -1.52f, 1.3f, +CLOSE, +MOVE_TO, 8.4f, 7.75f, +R_LINE_TO, -1.79f, 1.79f, +H_LINE_TO, 4.52f, +R_V_LINE_TO, 0.88f, +H_LINE_TO, 6.61f, +R_LINE_TO, 1.79f, 1.79f, +CLOSE + CANVAS_DIMENSIONS, 16, -MOVE_TO, 9.31f, 13.54f, -R_V_LINE_TO, -1.32f, -R_ARC_TO, 4.19f, 4.19f, 0, 0, 0, 2.31f, -1.56f, -R_ARC_TO, 4.28f, 4.28f, 0, 0, 0, 0.89f, -2.65f, -R_ARC_TO, 4.2f, 4.2f, 0, 0, 0, -0.89f, -2.64f, -R_ARC_TO, 4.58f, 4.58f, 0, 0, 0, -2.3f, -1.6f, -V_LINE_TO, 2.45f, -R_CUBIC_TO, 1.3f, 0.28f, 2.38f, 0.94f, 3.21f, 1.97f, -R_CUBIC_TO, 0.84f, 1.03f, 1.25f, 2.22f, 1.25f, 3.56f, -R_ARC_TO, 5.57f, 5.57f, 0, 0, 1, -1.24f, 3.57f, -R_CUBIC_TO, -0.83f, 1.04f, -1.9f, 1.7f, -3.21f, 1.98f, +MOVE_TO, 9.45f, 13.63f, +R_V_LINE_TO, -1.41f, +R_ARC_TO, 4.29f, 4.29f, 0, 0, 0, 2.31f, -1.57f, +R_CUBIC_TO, 0.59f, -0.78f, 0.89f, -1.66f, 0.89f, -2.64f, +R_CUBIC_TO, 0, -0.98f, -0.3f, -1.86f, -0.89f, -2.63f, +R_ARC_TO, 4.65f, 4.65f, 0, 0, 0, -2.31f, -1.6f, +R_V_LINE_TO, -1.41f, +R_ARC_TO, 5.58f, 5.58f, 0, 0, 1, 3.27f, 2.01f, +R_CUBIC_TO, 0.85f, 1.06f, 1.27f, 2.26f, 1.27f, 3.62f, +R_CUBIC_TO, 0, 1.36f, -0.42f, 2.57f, -1.26f, 3.63f, +R_CUBIC_TO, -0.84f, 1.06f, -1.94f, 1.73f, -3.27f, 2.01f, CLOSE, -MOVE_TO, 2.24f, 9.72f, -V_LINE_TO, 6.25f, -R_H_LINE_TO, 2.48f, -R_LINE_TO, 3.39f, -3.39f, -R_V_LINE_TO, 10.25f, -LINE_TO, 4.72f, 9.72f, +R_MOVE_TO, -7.43f, -3.72f, +R_V_LINE_TO, -3.84f, +R_H_LINE_TO, 2.59f, +R_LINE_TO, 3.64f, -3.64f, +R_V_LINE_TO, 11.13f, +LINE_TO, 4.6f, 9.9f, CLOSE, -R_MOVE_TO, 7.07f, 0.83f, -V_LINE_TO, 5.42f, -R_CUBIC_TO, 0.51f, 0.23f, 0.91f, 0.58f, 1.21f, 1.04f, -R_CUBIC_TO, 0.3f, 0.46f, 0.45f, 0.97f, 0.45f, 1.54f, -R_CUBIC_TO, 0, 0.55f, -0.15f, 1.06f, -0.45f, 1.52f, -R_CUBIC_TO, -0.3f, 0.46f, -0.7f, 0.81f, -1.21f, 1.04f, +R_MOVE_TO, 7.43f, 0.71f, +V_LINE_TO, 5.36f, +R_CUBIC_TO, 0.53f, 0.24f, 0.95f, 0.6f, 1.27f, 1.07f, +R_CUBIC_TO, 0.32f, 0.47f, 0.48f, 0.99f, 0.48f, 1.57f, +R_CUBIC_TO, 0, 0.57f, -0.16f, 1.09f, -0.48f, 1.56f, +R_ARC_TO, 3.03f, 3.03f, 0, 0, 1, -1.27f, 1.06f, CLOSE, -MOVE_TO, 6.72f, 6.2f, -R_LINE_TO, -1.43f, 1.43f, -H_LINE_TO, 3.62f, -R_V_LINE_TO, 0.7f, -H_LINE_TO, 5.29f, -LINE_TO, 6.72f, 9.77f, -CLOSE, -MOVE_TO, 5.25f, 7.97f, +MOVE_TO, 6.61f, 6.36f, +R_LINE_TO, -1.34f, 1.34f, +H_LINE_TO, 3.65f, +R_V_LINE_TO, 0.57f, +R_H_LINE_TO, 1.63f, +R_LINE_TO, 1.34f, 1.34f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/vr_headset_chrome_refresh.icon b/components/vector_icons/vr_headset_chrome_refresh.icon index a69a5e4..484be93 100644 --- a/components/vector_icons/vr_headset_chrome_refresh.icon +++ b/components/vector_icons/vr_headset_chrome_refresh.icon
@@ -62,6 +62,123 @@ R_CUBIC_TO, -0.41f, 0.41f, -0.61f, 0.9f, -0.61f, 1.47f, R_CUBIC_TO, 0, 0.57f, 0.2f, 1.06f, 0.61f, 1.47f, R_CUBIC_TO, 0.41f, 0.4f, 0.89f, 0.61f, 1.47f, 0.61f, +CLOSE + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.29f, 13.12f, +R_H_LINE_TO, 3.3f, +R_V_LINE_TO, -0.01f, +R_LINE_TO, 0.66f, -1.26f, +R_CUBIC_TO, 0.18f, -0.33f, 0.42f, -0.6f, 0.73f, -0.79f, +ARC_TO, 1.91f, 1.91f, 0, 0, 1, 10, 10.77f, +R_CUBIC_TO, 0.38f, 0, 0.72f, 0.09f, 1.03f, 0.28f, +R_CUBIC_TO, 0.31f, 0.19f, 0.56f, 0.45f, 0.73f, 0.78f, +R_LINE_TO, 0.66f, 1.28f, +R_V_LINE_TO, 0.01f, +R_H_LINE_TO, 3.3f, +V_LINE_TO, 6.88f, +H_LINE_TO, 4.29f, CLOSE, -MOVE_TO, 12.02f, 12, +R_MOVE_TO, 2.1f, -1.56f, +R_CUBIC_TO, 0.43f, 0, 0.8f, -0.15f, 1.1f, -0.46f, +R_CUBIC_TO, 0.31f, -0.31f, 0.46f, -0.68f, 0.46f, -1.11f, +R_CUBIC_TO, 0, -0.43f, -0.16f, -0.8f, -0.46f, -1.1f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 0, -1.11f, -0.45f, +R_CUBIC_TO, -0.43f, 0, -0.8f, 0.15f, -1.1f, 0.46f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 0, -0.46f, 1.11f, +R_CUBIC_TO, 0, 0.43f, 0.15f, 0.8f, 0.46f, 1.1f, +R_CUBIC_TO, 0.31f, 0.3f, 0.68f, 0.45f, 1.11f, 0.45f, +CLOSE, +R_MOVE_TO, -2.1f, 3.13f, +R_ARC_TO, 1.51f, 1.51f, 0, 0, 1, -1.1f, -0.46f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 1, -0.46f, -1.1f, +V_LINE_TO, 6.88f, +R_CUBIC_TO, 0, -0.42f, 0.16f, -0.78f, 0.46f, -1.09f, +R_CUBIC_TO, 0.31f, -0.31f, 0.68f, -0.47f, 1.09f, -0.47f, +R_H_LINE_TO, 11.43f, +R_CUBIC_TO, 0.42f, 0, 0.79f, 0.16f, 1.09f, 0.47f, +R_CUBIC_TO, 0.31f, 0.31f, 0.46f, 0.68f, 0.46f, 1.1f, +R_V_LINE_TO, 6.24f, +R_CUBIC_TO, 0, 0.42f, -0.16f, 0.79f, -0.46f, 1.09f, +R_ARC_TO, 1.5f, 1.5f, 0, 0, 1, -1.1f, 0.47f, +R_H_LINE_TO, -3.29f, +R_CUBIC_TO, -0.3f, 0, -0.58f, -0.08f, -0.83f, -0.24f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 1, -0.57f, -0.61f, +R_LINE_TO, -0.66f, -1.26f, +R_ARC_TO, 0.54f, 0.54f, 0, 0, 0, -0.16f, -0.17f, +R_ARC_TO, 0.37f, 0.37f, 0, 0, 0, -0.21f, -0.07f, +R_ARC_TO, 0.46f, 0.46f, 0, 0, 0, -0.38f, 0.24f, +R_LINE_TO, -0.64f, 1.27f, +R_CUBIC_TO, -0.12f, 0.25f, -0.31f, 0.46f, -0.57f, 0.61f, +R_CUBIC_TO, -0.25f, 0.16f, -0.53f, 0.24f, -0.83f, 0.24f, +CLOSE, +R_MOVE_TO, 9.34f, -3.12f, +R_CUBIC_TO, 0.43f, 0, 0.8f, -0.15f, 1.1f, -0.46f, +R_CUBIC_TO, 0.3f, -0.31f, 0.46f, -0.68f, 0.46f, -1.11f, +R_CUBIC_TO, 0, -0.43f, -0.15f, -0.8f, -0.46f, -1.1f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 0, -1.11f, -0.45f, +R_CUBIC_TO, -0.43f, 0, -0.8f, 0.15f, -1.1f, 0.46f, +R_ARC_TO, 1.52f, 1.52f, 0, 0, 0, -0.46f, 1.11f, +R_CUBIC_TO, 0, 0.43f, 0.16f, 0.8f, 0.46f, 1.1f, +R_CUBIC_TO, 0.31f, 0.3f, 0.68f, 0.45f, 1.11f, 0.45f, +CLOSE + +CANVAS_DIMENSIONS, 16, +MOVE_TO, 3.2f, 10.63f, +R_H_LINE_TO, 2.76f, +R_CUBIC_TO, 0, 0, 0, 0, 0, 0, +R_V_LINE_TO, 0, +R_LINE_TO, 0.56f, -1.06f, +R_CUBIC_TO, 0.15f, -0.28f, 0.35f, -0.5f, 0.62f, -0.67f, +ARC_TO, 1.6f, 1.6f, 0, 0, 1, 8, 8.64f, +R_ARC_TO, 1.68f, 1.68f, 0, 0, 1, 1.48f, 0.9f, +R_LINE_TO, 0.56f, 1.08f, +R_V_LINE_TO, 0.01f, +R_H_LINE_TO, 2.77f, +R_V_LINE_TO, -5.25f, +R_H_LINE_TO, -9.61f, +CLOSE, +R_MOVE_TO, 1.78f, -1.31f, +R_CUBIC_TO, 0.36f, 0, 0.67f, -0.13f, 0.93f, -0.39f, +R_CUBIC_TO, 0.26f, -0.26f, 0.38f, -0.57f, 0.38f, -0.93f, +R_ARC_TO, 1.25f, 1.25f, 0, 0, 0, -0.39f, -0.93f, +R_ARC_TO, 1.28f, 1.28f, 0, 0, 0, -0.93f, -0.38f, +R_CUBIC_TO, -0.36f, 0, -0.67f, 0.13f, -0.93f, 0.39f, +R_ARC_TO, 1.27f, 1.27f, 0, 0, 0, -0.39f, 0.93f, +R_CUBIC_TO, 0, 0.36f, 0.13f, 0.67f, 0.39f, 0.93f, +R_CUBIC_TO, 0.26f, 0.25f, 0.57f, 0.38f, 0.94f, 0.38f, +CLOSE, +MOVE_TO, 3.2f, 11.95f, +R_CUBIC_TO, -0.35f, 0, -0.66f, -0.13f, -0.93f, -0.39f, +R_ARC_TO, 1.27f, 1.27f, 0, 0, 1, -0.39f, -0.93f, +R_V_LINE_TO, -5.25f, +R_CUBIC_TO, 0, -0.35f, 0.13f, -0.66f, 0.39f, -0.93f, +R_CUBIC_TO, 0.26f, -0.26f, 0.57f, -0.4f, 0.92f, -0.4f, +R_H_LINE_TO, 9.61f, +R_CUBIC_TO, 0.36f, 0, 0.66f, 0.13f, 0.92f, 0.39f, +R_CUBIC_TO, 0.26f, 0.26f, 0.39f, 0.57f, 0.39f, 0.93f, +R_V_LINE_TO, 5.25f, +R_CUBIC_TO, 0, 0.36f, -0.13f, 0.66f, -0.39f, 0.93f, +R_CUBIC_TO, -0.26f, 0.27f, -0.57f, 0.4f, -0.93f, 0.4f, +R_H_LINE_TO, -2.75f, +R_CUBIC_TO, -0.26f, 0, -0.5f, -0.07f, -0.71f, -0.21f, +R_ARC_TO, 1.36f, 1.36f, 0, 0, 1, -0.47f, -0.51f, +R_LINE_TO, -0.55f, -1.07f, +R_ARC_TO, 0.5f, 0.5f, 0, 0, 0, -0.14f, -0.15f, +ARC_TO, 0.32f, 0.32f, 0, 0, 0, 8, 9.95f, +R_ARC_TO, 0.35f, 0.35f, 0, 0, 0, -0.18f, 0.06f, +R_ARC_TO, 0.38f, 0.38f, 0, 0, 0, -0.14f, 0.15f, +R_LINE_TO, -0.55f, 1.07f, +R_ARC_TO, 1.37f, 1.37f, 0, 0, 1, -0.47f, 0.52f, +R_CUBIC_TO, -0.21f, 0.14f, -0.45f, 0.21f, -0.71f, 0.21f, +CLOSE, +R_MOVE_TO, 7.83f, -2.64f, +R_CUBIC_TO, 0.36f, 0, 0.67f, -0.13f, 0.93f, -0.39f, +R_CUBIC_TO, 0.26f, -0.26f, 0.39f, -0.57f, 0.39f, -0.93f, +R_ARC_TO, 1.25f, 1.25f, 0, 0, 0, -0.39f, -0.93f, +R_ARC_TO, 1.3f, 1.3f, 0, 0, 0, -0.94f, -0.38f, +R_ARC_TO, 1.25f, 1.25f, 0, 0, 0, -0.92f, 0.39f, +R_ARC_TO, 1.26f, 1.26f, 0, 0, 0, -0.38f, 0.93f, +R_CUBIC_TO, 0, 0.36f, 0.13f, 0.67f, 0.39f, 0.93f, +R_CUBIC_TO, 0.26f, 0.25f, 0.57f, 0.38f, 0.93f, 0.38f, CLOSE \ No newline at end of file
diff --git a/components/vector_icons/vr_headset_off_chrome_refresh.icon b/components/vector_icons/vr_headset_off_chrome_refresh.icon index a5277a79..ae458a2 100644 --- a/components/vector_icons/vr_headset_off_chrome_refresh.icon +++ b/components/vector_icons/vr_headset_off_chrome_refresh.icon
@@ -60,10 +60,6 @@ R_ARC_TO, 1.99f, 1.99f, 0, 0, 0, -1.46f, -0.61f, R_CUBIC_TO, -0.42f, 0, -0.8f, 0.11f, -1.14f, 0.35f, R_CUBIC_TO, -0.34f, 0.23f, -0.6f, 0.55f, -0.78f, 0.94f, -CLOSE, -R_MOVE_TO, -1.91f, -3, -CLOSE, -R_MOVE_TO, -6.66f, 0.41f, CLOSE CANVAS_DIMENSIONS, 20, @@ -124,8 +120,64 @@ R_ARC_TO, 1.5f, 1.5f, 0, 0, 0, -1.1f, -0.46f, R_CUBIC_TO, -0.38f, 0, -0.71f, 0.12f, -1, 0.35f, R_CUBIC_TO, -0.29f, 0.24f, -0.47f, 0.54f, -0.54f, 0.91f, +CLOSE + +CANVAS_DIMENSIONS, 16, +R_MOVE_TO, 3.23f, 10.6f, +R_LINE_TO, 2.77f, -0.01f, +R_H_LINE_TO, 0.01f, +R_CUBIC_TO, 0, 0, 0, 0, 0, -0.01f, +R_LINE_TO, 0.53f, -1.07f, +R_CUBIC_TO, 0.07f, -0.13f, 0.16f, -0.24f, 0.25f, -0.34f, +R_ARC_TO, 2.1f, 2.1f, 0, 0, 1, 0.33f, -0.27f, +R_LINE_TO, -0.82f, -0.81f, +R_ARC_TO, 1.32f, 1.32f, 0, 0, 1, -0.42f, 0.86f, +R_CUBIC_TO, -0.24f, 0.22f, -0.54f, 0.33f, -0.89f, 0.33f, +R_ARC_TO, 1.26f, 1.26f, 0, 0, 1, -0.93f, -0.38f, +R_ARC_TO, 1.27f, 1.27f, 0, 0, 1, -0.39f, -0.93f, +R_CUBIC_TO, 0, -0.35f, 0.11f, -0.64f, 0.34f, -0.89f, +R_CUBIC_TO, 0.22f, -0.25f, 0.51f, -0.39f, 0.86f, -0.42f, +LINE_TO, 3.56f, 5.34f, +R_H_LINE_TO, -0.32f, CLOSE, -R_MOVE_TO, -1.59f, -5.43f, +R_MOVE_TO, 10.05f, 4.48f, +R_LINE_TO, -3.16f, -3.17f, +R_ARC_TO, 1.46f, 1.46f, 0, 0, 1, -0.73f, -0.21f, +R_ARC_TO, 1.14f, 1.14f, 0, 0, 1, -0.48f, -0.51f, +LINE_TO, 8.36f, 10.16f, +R_ARC_TO, 0.41f, 0.41f, 0, 0, 0, -0.14f, -0.16f, +R_ARC_TO, 0.48f, 0.48f, 0, 0, 0, -0.19f, -0.08f, +R_ARC_TO, 0.34f, 0.34f, 0, 0, 0, -0.17f, 0.06f, +R_ARC_TO, 0.31f, 0.31f, 0, 0, 0, -0.12f, 0.14f, +R_LINE_TO, -0.55f, 1.07f, +R_ARC_TO, 1.35f, 1.35f, 0, 0, 1, -1.19f, 0.72f, +H_LINE_TO, 3.24f, +R_ARC_TO, 1.28f, 1.28f, 0, 0, 1, -0.93f, -0.39f, +R_ARC_TO, 1.27f, 1.27f, 0, 0, 1, -0.39f, -0.93f, +V_LINE_TO, 5.32f, +R_CUBIC_TO, 0, -0.22f, 0.06f, -0.42f, 0.16f, -0.6f, +R_CUBIC_TO, 0.11f, -0.19f, 0.24f, -0.34f, 0.41f, -0.46f, +LINE_TO, 0.93f, 2.72f, +R_LINE_TO, 0.93f, -0.93f, +R_LINE_TO, 12.36f, 12.36f, CLOSE, -MOVE_TO, 7.41f, 9.56f, +R_MOVE_TO, 0.48f, -3.57f, +R_LINE_TO, -0.93f, -0.92f, +R_V_LINE_TO, -5.25f, +H_LINE_TO, 7.32f, +LINE_TO, 5.95f, 4.02f, +R_LINE_TO, 6.9f, -0.01f, +R_CUBIC_TO, 0.36f, 0, 0.67f, 0.13f, 0.93f, 0.38f, +R_CUBIC_TO, 0.26f, 0.26f, 0.39f, 0.57f, 0.39f, 0.93f, +R_V_LINE_TO, 5.25f, +R_CUBIC_TO, 0, 0.18f, -0.04f, 0.34f, -0.1f, 0.5f, +R_CUBIC_TO, -0.07f, 0.16f, -0.16f, 0.3f, -0.29f, 0.43f, +CLOSE, +R_MOVE_TO, -2.37f, -2.27f, +R_ARC_TO, 1.42f, 1.42f, 0, 0, 0, 0.72f, -0.47f, +R_CUBIC_TO, 0.19f, -0.23f, 0.28f, -0.5f, 0.28f, -0.8f, +R_CUBIC_TO, 0, -0.36f, -0.13f, -0.67f, -0.39f, -0.93f, +R_ARC_TO, 1.26f, 1.26f, 0, 0, 0, -0.93f, -0.39f, +R_CUBIC_TO, -0.32f, 0, -0.6f, 0.1f, -0.84f, 0.29f, +R_CUBIC_TO, -0.24f, 0.2f, -0.39f, 0.45f, -0.46f, 0.76f, CLOSE
diff --git a/components/viz/OWNERS b/components/viz/OWNERS index 6dcc02a2..79ba367b 100644 --- a/components/viz/OWNERS +++ b/components/viz/OWNERS
@@ -29,6 +29,7 @@ # hit testing rjkroege@chromium.org +jonross@chromium.org # math / geometry dbaron@chromium.org
diff --git a/components/viz/PRESUBMIT.py b/components/viz/PRESUBMIT.py index 32effeb..730672c9 100644 --- a/components/viz/PRESUBMIT.py +++ b/components/viz/PRESUBMIT.py
@@ -4,8 +4,6 @@ """Top-level presubmit script for components/viz.""" -USE_PYTHON3 = True - def CheckChangeOnUpload(input_api, output_api): import sys original_sys_path = sys.path
diff --git a/components/viz/common/frame_sinks/copy_output_request.cc b/components/viz/common/frame_sinks/copy_output_request.cc index b7f74c0..ff4b1fc 100644 --- a/components/viz/common/frame_sinks/copy_output_request.cc +++ b/components/viz/common/frame_sinks/copy_output_request.cc
@@ -109,7 +109,8 @@ void CopyOutputRequest::set_blit_request(BlitRequest blit_request) { DCHECK(!blit_request_); DCHECK_EQ(result_destination(), ResultDestination::kNativeTextures); - DCHECK_EQ(result_format(), ResultFormat::NV12_PLANES); + DCHECK(result_format() == ResultFormat::NV12_PLANES || + result_format() == ResultFormat::NV12_MULTIPLANE); DCHECK(has_result_selection()); // Destination region must start at an even offset for NV12 results:
diff --git a/components/viz/common/frame_sinks/copy_output_result.cc b/components/viz/common/frame_sinks/copy_output_result.cc index 942c4d8..ccbbb43 100644 --- a/components/viz/common/frame_sinks/copy_output_result.cc +++ b/components/viz/common/frame_sinks/copy_output_result.cc
@@ -45,7 +45,7 @@ rect_(rect), needs_lock_for_bitmap_(needs_lock_for_bitmap) { DCHECK(format_ == Format::RGBA || format_ == Format::I420_PLANES || - format == Format::NV12_PLANES); + format == Format::NV12_PLANES || format == Format::NV12_MULTIPLANE); DCHECK(destination_ == Destination::kSystemMemory || destination_ == Destination::kNativeTextures); } @@ -232,6 +232,9 @@ if (format == Format::NV12_PLANES) { DCHECK_EQ(rect.IsEmpty(), texture_result_.mailbox_holders[1].mailbox.IsZero()); + } else if (format == Format::NV12_MULTIPLANE) { + // In NV12_MULTIPLANE, a single mailbox stores all the planes. + DCHECK(texture_result_.mailbox_holders[1].mailbox.IsZero()); } // If we're constructing empty result, the callbacks must be empty. // From definition of implication: p => q <=> !p || q.
diff --git a/components/viz/common/gpu/metal_context_provider.mm b/components/viz/common/gpu/metal_context_provider.mm index 15b0cfcb..c965354 100644 --- a/components/viz/common/gpu/metal_context_provider.mm +++ b/components/viz/common/gpu/metal_context_provider.mm
@@ -37,31 +37,27 @@ bool InitializeGraphiteContext( const skgpu::graphite::ContextOptions& options) override { CHECK(!graphite_context_); - - if (device_) { - skgpu::graphite::MtlBackendContext backend_context = {}; - backend_context.fDevice.reset(device_); - backend_context.fQueue.reset([device_ newCommandQueue]); - graphite_context_ = - skgpu::graphite::ContextFactory::MakeMetal(backend_context, options); - } - + CHECK(device_); + skgpu::graphite::MtlBackendContext backend_context = {}; + backend_context.fDevice.retain(device_); + backend_context.fQueue.reset([device_ newCommandQueue]); + graphite_context_ = + skgpu::graphite::ContextFactory::MakeMetal(backend_context, options); if (!graphite_context_) { DLOG(ERROR) << "Failed to create Graphite Context for Metal"; return false; } - return true; } skgpu::graphite::Context* GetGraphiteContext() override { return graphite_context_.get(); } + metal::MTLDevicePtr GetMTLDevice() override { return device_.get(); } private: base::scoped_nsprotocol<id<MTLDevice>> device_; - base::scoped_nsprotocol<id<MTLCommandQueue>> command_queue_; std::unique_ptr<skgpu::graphite::Context> graphite_context_; };
diff --git a/components/viz/common/hit_test/OWNERS b/components/viz/common/hit_test/OWNERS index 6a1dd96..e35fe26 100644 --- a/components/viz/common/hit_test/OWNERS +++ b/components/viz/common/hit_test/OWNERS
@@ -1,2 +1,3 @@ rjkroege@chromium.org sadrul@chromium.org +jonross@chromium.org
diff --git a/components/viz/common/resources/shared_image_format.cc b/components/viz/common/resources/shared_image_format.cc index 9b11dc43..12b6059e6 100644 --- a/components/viz/common/resources/shared_image_format.cc +++ b/components/viz/common/resources/shared_image_format.cc
@@ -402,10 +402,6 @@ case BGRA_1010102: case RG16_EXT: return 32; - case P010: - return 24; - case YUVA_420_TRIPLANAR: - return 20; case RGBA_4444: case RGB_565: case LUMINANCE_F16: @@ -413,15 +409,18 @@ case BGR_565: case RG_88: return 16; - case YVU_420: - case YUV_420_BIPLANAR: - return 12; case ALPHA_8: case LUMINANCE_8: case RED_8: return 8; case ETC1: return 4; + case P010: + case YUVA_420_TRIPLANAR: + case YVU_420: + case YUV_420_BIPLANAR: + // Legacy multiplanar formats are not supported. + CHECK(0); } NOTREACHED_NORETURN(); }
diff --git a/components/viz/common/resources/shared_image_format.h b/components/viz/common/resources/shared_image_format.h index 664b43b..7ef8608 100644 --- a/components/viz/common/resources/shared_image_format.h +++ b/components/viz/common/resources/shared_image_format.h
@@ -147,7 +147,8 @@ // YUV_420_BIPLANAR, YVU_420, YUVA_420_TRIPLANAR, P010. bool IsLegacyMultiplanar() const; - // NOTE: Supported only for single-plane formats. + // NOTE: Supported only for true single-plane formats (i.e., formats for + // which is_single_plane() is true and IsLegacyMultiplanar() is false). int BitsPerPixel() const; bool operator==(const SharedImageFormat& o) const;
diff --git a/components/viz/service/display/overlay_processor_delegated.cc b/components/viz/service/display/overlay_processor_delegated.cc index 2f0b9bc..ccef0c3 100644 --- a/components/viz/service/display/overlay_processor_delegated.cc +++ b/components/viz/service/display/overlay_processor_delegated.cc
@@ -138,6 +138,11 @@ constexpr bool is_delegated_context = true; delegated_status_ = DelegationStatus::kCompositedOther; + if (!features::IsDelegatedCompositingEnabled()) { + delegated_status_ = DelegationStatus::kCompositedFeatureDisabled; + return false; + } + if (disable_delegation()) return false;
diff --git a/components/viz/service/display/overlay_processor_delegated.h b/components/viz/service/display/overlay_processor_delegated.h index f9517e2..f27a0dc 100644 --- a/components/viz/service/display/overlay_processor_delegated.h +++ b/components/viz/service/display/overlay_processor_delegated.h
@@ -84,7 +84,8 @@ kCompositedHas3dTransform = 8, kCompositedHas2dShear = 9, kCompositedHas2dRotation = 10, - kMaxValue = kCompositedHas2dRotation + kCompositedFeatureDisabled = 11, + kMaxValue = kCompositedFeatureDisabled }; gfx::RectF GetPrimaryPlaneDisplayRect(
diff --git a/components/viz/service/display/overlay_processor_interface.cc b/components/viz/service/display/overlay_processor_interface.cc index c598a43..ddcf3d5 100644 --- a/components/viz/service/display/overlay_processor_interface.cc +++ b/components/viz/service/display/overlay_processor_interface.cc
@@ -138,16 +138,15 @@ } #if BUILDFLAG(IS_CHROMEOS_LACROS) - if (features::IsDelegatedCompositingEnabled()) { - return std::make_unique<OverlayProcessorDelegated>( - std::move(overlay_candidates), - std::move(renderer_settings.overlay_strategies), sii); - } -#endif - + return std::make_unique<OverlayProcessorDelegated>( + std::move(overlay_candidates), + std::move(renderer_settings.overlay_strategies), sii); +#else return std::make_unique<OverlayProcessorOzone>( std::move(overlay_candidates), std::move(renderer_settings.overlay_strategies), sii); +#endif // BUILDFLAG(IS_CHROMEOS_LACROS) + #elif BUILDFLAG(IS_ANDROID) DCHECK(display_controller);
diff --git a/components/viz/service/display/overlay_unittest.cc b/components/viz/service/display/overlay_unittest.cc index 302c740..0775633a 100644 --- a/components/viz/service/display/overlay_unittest.cc +++ b/components/viz/service/display/overlay_unittest.cc
@@ -5017,7 +5017,15 @@ OverlayProcessorInterface::OutputSurfaceOverlayPlane primary_plane_; }; -using DelegatedTest = OverlayTest<TestDelegatedOverlayProcessor>; +class DelegatedTest : public OverlayTest<TestDelegatedOverlayProcessor> { + public: + DelegatedTest() { + scoped_features.InitAndEnableFeature(features::kDelegatedCompositing); + } + + private: + base::test::ScopedFeatureList scoped_features; +}; gfx::Transform MakePerspectiveTransform() { gfx::Transform transform;
diff --git a/components/viz/service/display/resolved_frame_data.cc b/components/viz/service/display/resolved_frame_data.cc index eda9c28..ae9097bf 100644 --- a/components/viz/service/display/resolved_frame_data.cc +++ b/components/viz/service/display/resolved_frame_data.cc
@@ -46,6 +46,14 @@ *this = AggregationPassData(); } +ParentClipData::ParentClipData() = default; +ParentClipData::ParentClipData(ParentClipData&& other) = default; +ParentClipData& ParentClipData::operator=(ParentClipData& other) = default; +ParentClipData& ParentClipData::operator=(const ParentClipData& other) = + default; +ParentClipData& ParentClipData::operator=(ParentClipData&& other) = default; +ParentClipData::~ParentClipData() = default; + ResolvedPassData::ResolvedPassData(FixedPassData fixed_data) : fixed_(std::move(fixed_data)) {} ResolvedPassData::~ResolvedPassData() = default; @@ -53,6 +61,11 @@ ResolvedPassData& ResolvedPassData::operator=(ResolvedPassData&& other) = default; +void ResolvedPassData::CopyAndResetParentClipData() { + previous_parent_clip_data_ = current_parent_clip_data_; + current_parent_clip_data_ = ParentClipData(); +} + ResolvedFrameData::ResolvedFrameData(DisplayResourceProvider* resource_provider, Surface* surface, uint64_t previous_frame_index, @@ -106,7 +119,8 @@ // Will be repopulated based on active frame. render_pass_id_map_.clear(); - resolved_passes_.clear(); + std::vector<ResolvedPassData> previous_resolved_passes; + resolved_passes_.swap(previous_resolved_passes); render_pass_id_map_.reserve(num_render_pass); resolved_passes_.reserve(num_render_pass); @@ -133,6 +147,7 @@ } fixed.remapped_id = remapped_id; fixed.is_root = is_root; + fixed.render_pass_id = render_pass->id; // Loop through the quads, remapping resource ids and storing them. auto& draw_quads = fixed.draw_quads; @@ -197,6 +212,10 @@ frame_index_ = surface_->GetActiveFrameIndex(); DCHECK_NE(frame_index_, 0u); + // Get parent_clip_data from the previous frame to the current frame. + MoveParentClipDataFromPreviousFrame(previous_resolved_passes); + previous_resolved_passes.clear(); + // Clear id mappings that weren't used in this frame. base::EraseIf(aggregated_id_map_, [this](auto& entry) { return render_pass_id_map_.find(entry.first) == render_pass_id_map_.end(); @@ -228,8 +247,10 @@ void ResolvedFrameData::ResetAfterAggregation() { // Reset aggregation scoped data. - for (auto& resolved_pass : resolved_passes_) + for (auto& resolved_pass : resolved_passes_) { resolved_pass.aggregation().Reset(); + resolved_pass.CopyAndResetParentClipData(); + } previous_frame_index_ = frame_index_; used_in_aggregation_ = false; @@ -303,4 +324,18 @@ surface_id_); } +void ResolvedFrameData::MoveParentClipDataFromPreviousFrame( + const std::vector<ResolvedPassData>& previous_resolved_passes) { + for (const auto& previous_resolved_pass : previous_resolved_passes) { + auto render_pass_id = previous_resolved_pass.render_pass_id(); + // iter to |current_parent_clip_data_| + auto iter = render_pass_id_map_.find(render_pass_id); + + if (iter != render_pass_id_map_.end()) { + iter->second->previous_parent_clip_data() = + previous_resolved_pass.previous_parent_clip_data(); + } + } +} + } // namespace viz
diff --git a/components/viz/service/display/resolved_frame_data.h b/components/viz/service/display/resolved_frame_data.h index cf4e7b2..ca457476 100644 --- a/components/viz/service/display/resolved_frame_data.h +++ b/components/viz/service/display/resolved_frame_data.h
@@ -54,6 +54,7 @@ int embed_count = 0; AggregatedRenderPassId remapped_id; + CompositorRenderPassId render_pass_id; bool is_root = false; std::vector<ResolvedQuadData> draw_quads; }; @@ -109,6 +110,27 @@ bool will_draw = false; }; +struct ParentClipData { + ParentClipData(); + ParentClipData(ParentClipData&& other); + ParentClipData& operator=(ParentClipData& other); + ParentClipData& operator=(const ParentClipData& other); + ParentClipData& operator=(ParentClipData&& other); + ~ParentClipData(); + + enum MergeState { kInitState, kNotMerged, kAlwaysMerged, kSomeTimesMerged }; + + // The intersection of all render pass output rects, RenderPassDrawQuad rect, + // SurfaceDrawQuad rect, and clip rects from its ancestor render passes and + // surface. This is the max size this render pass can be rendered into the + // root surface. |parent_clip_rect| is in the dest root target space. + gfx::Rect parent_clip_rect; + + // Whether the render passes is merged with its parent render pass. The render + // mighe be embedded multiple times and has different status each time. + MergeState merge_state = kInitState; +}; + // Data associated with a CompositorRenderPass in a resolved frame. Has fixed // portion that does not change and an aggregation portion that does change. class VIZ_SERVICE_EXPORT ResolvedPassData { @@ -122,6 +144,9 @@ return *fixed_.render_pass; } AggregatedRenderPassId remapped_id() const { return fixed_.remapped_id; } + CompositorRenderPassId render_pass_id() const { + return fixed_.render_pass_id; + } bool is_root() const { return fixed_.is_root; } const std::vector<ResolvedQuadData>& draw_quads() const { return fixed_.draw_quads; @@ -139,6 +164,20 @@ AggregationPassData& aggregation() { return aggregation_; } const AggregationPassData& aggregation() const { return aggregation_; } + ParentClipData& current_parent_clip_data() { + return current_parent_clip_data_; + } + + ParentClipData& previous_parent_clip_data() { + return previous_parent_clip_data_; + } + + const ParentClipData& previous_parent_clip_data() const { + return previous_parent_clip_data_; + } + + void CopyAndResetParentClipData(); + private: friend class ResolvedFrameData; @@ -147,6 +186,9 @@ // Data that will change each aggregation. AggregationPassData aggregation_; + + ParentClipData current_parent_clip_data_; + ParentClipData previous_parent_clip_data_; }; enum FrameDamageType { @@ -252,6 +294,8 @@ private: void RegisterWithResourceProvider(); + void MoveParentClipDataFromPreviousFrame( + const std::vector<ResolvedPassData>& previoius_resolved_passes); const raw_ptr<DisplayResourceProvider> resource_provider_; const SurfaceId surface_id_;
diff --git a/components/viz/service/display/surface_aggregator.cc b/components/viz/service/display/surface_aggregator.cc index a7a873e..1466374 100644 --- a/components/viz/service/display/surface_aggregator.cc +++ b/components/viz/service/display/surface_aggregator.cc
@@ -211,17 +211,117 @@ dest_render_pass); } -// Returns true if |resolved_pass| needs full damage. This is because: -// 1. The render pass pixels will be saved, either by a copy request or into a -// cached render pass. This avoids a partially drawn render pass being saved. -// 2. The render pass pixels will have a pixel moving foreground filter applied -// to them. In this case pixels outside the damage_rect can be moved inside -// the damage_rect by the filter. -bool RenderPassNeedsFullDamage(const ResolvedPassData& resolved_pass) { +void UpdateParentClipDataMergeState(ResolvedPassData& resolved_pass, + AggregatedRenderPass* dest_pass, + bool is_merged_pass) { + auto& parent_clip_data = resolved_pass.current_parent_clip_data(); + + ParentClipData::MergeState merge_state = is_merged_pass + ? ParentClipData::kAlwaysMerged + : ParentClipData::kNotMerged; + + if (parent_clip_data.merge_state == ParentClipData::kInitState) { + // This is the first time it's embedded. + parent_clip_data.merge_state = merge_state; + } else if (parent_clip_data.merge_state != merge_state) { + parent_clip_data.merge_state = ParentClipData::kSomeTimesMerged; + } +} + +bool ChangeInMergeState(ResolvedPassData& resolved_pass) { + DCHECK(resolved_pass.current_parent_clip_data().merge_state != + ParentClipData::kInitState); + // If this is the first frame and previous_merge_state is empty, + // this function will returns false. + auto current_merge_state = + resolved_pass.current_parent_clip_data().merge_state; + auto previous_merge_state = + resolved_pass.previous_parent_clip_data().merge_state; + + // Check if this render pass is merged to its parent render pass in the + // previous frame but is not in the current frame. + bool change_in_merged_pass = + previous_merge_state == ParentClipData::kAlwaysMerged && + current_merge_state == ParentClipData::kNotMerged; + + // If it's embedded multiple times and some are merged while some are not, + // just redraw the render pass. It's complicated to track individual change. + change_in_merged_pass |= + resolved_pass.current_parent_clip_data().merge_state == + ParentClipData::kSomeTimesMerged || + resolved_pass.previous_parent_clip_data().merge_state == + ParentClipData::kSomeTimesMerged; + + return change_in_merged_pass; +} + +void UpdateNeedsRedraw( + ResolvedPassData& resolved_pass, + AggregatedRenderPass* dest_pass, + const absl::optional<gfx::Rect>& dest_root_target_clip_rect) { + // |dest_root_target_clip_rect| is the bounding box on the root surface where + // this render pass can be rendered into. It includes all ancestors' render + // pass output rects, RenderPassDrawQuad rect, SurfaceDrawQuad rect, and clip + // rects. + DCHECK(dest_root_target_clip_rect.has_value()); + + // Save the parent_clip_rect from the current frame. + auto& current_parent_clip_rect = + resolved_pass.current_parent_clip_data().parent_clip_rect; + current_parent_clip_rect.Union(dest_root_target_clip_rect.value()); + + // Get the parent_clip_rect from the preious frame; + auto& previous_parent_clip_rect = + resolved_pass.previous_parent_clip_data().parent_clip_rect; + + // If the parent clip rect expands, the new area of the render pass output + // buffer has never been updated. Redraw is needed. + bool parent_clip_rect_expands = + !previous_parent_clip_rect.Contains(current_parent_clip_rect); + + // Whether the render pass is merged with its parent render pass and changes. + bool change_in_merged_pass = ChangeInMergeState(resolved_pass); + + // 1. Needs redraw when the current parent clip rect expands from the + // previous frame. + // 2. Needs full damage and redraw when it switched from merged to + // non-merged. + // 3. Needs full damage and redraw when it is in_copy_request_pass. + if (parent_clip_rect_expands || + resolved_pass.aggregation().in_copy_request_pass || + change_in_merged_pass) { + dest_pass->has_damage_from_contributing_content = true; + } +} + +bool RenderPassNeedsFullDamage(ResolvedPassData& resolved_pass) { auto& aggregation = resolved_pass.aggregation(); - return aggregation.in_cached_render_pass || - aggregation.in_copy_request_pass || - aggregation.in_pixel_moving_filter_pass; + + const bool can_skip_render_pass = base::FeatureList::IsEnabled( + features::kAllowUndamagedNonrootRenderPassToSkip); + if (can_skip_render_pass) { + // Needs full damage when + // 1. The render pass pixels will be saved, either by a copy request or into + // a cached render pass. This avoids a partially drawn render pass being + // saved. + // 2. A render pass is merged to its parent render pass in the previous + // frame but it's not in this frame. + return aggregation.in_cached_render_pass || + aggregation.in_copy_request_pass || + ChangeInMergeState(resolved_pass); + } else { + // Returns true if |resolved_pass| needs full damage. This is because: + // 1. The render pass pixels will be saved, either by a copy request or into + // a cached render pass. This avoids a partially drawn render pass being + // saved. + // 2. The render pass pixels will have a pixel moving foreground filter + // applied to them. In this case pixels outside the damage_rect can be + // moved inside the damage_rect by the filter. + + return aggregation.in_cached_render_pass || + aggregation.in_copy_request_pass || + aggregation.in_pixel_moving_filter_pass; + } } // Computes an enclosing rect in target render pass coordinate space that bounds @@ -369,7 +469,7 @@ const gfx::Transform& parent_target_transform, const absl::optional<gfx::Rect>& dest_root_target_clip_rect, const gfx::Transform& dest_transform_to_root_target, - const ResolvedFrameData* resolved_frame) { + ResolvedFrameData* resolved_frame) { gfx::Rect damage_rect; if (!resolved_frame) { // When the surface is null, it's either the surface is lost or it comes @@ -597,7 +697,7 @@ DCHECK(target_transform.Preserves2dAxisAlignment()); SurfaceId primary_surface_id = surface_quad->surface_range.end(); - const ResolvedFrameData* resolved_frame = + ResolvedFrameData* resolved_frame = GetResolvedFrame(surface_quad->surface_range); // |added_clip_rect| should be bounded by the output_rect of the render pass @@ -609,31 +709,30 @@ // |surface_damage_rect_list_| for overlays. The whole quad is considered // damaged. absl::optional<gfx::Rect> combined_clip_rect; - if (needs_surface_damage_rect_list_) { - gfx::Rect surface_in_target_space = - ComputeDrawableRectForQuad(surface_quad); - surface_in_target_space.Intersect(source_pass.output_rect); - if (!resolved_frame || resolved_frame->surface_id() != primary_surface_id) { - // If using a fallback surface the surface content may be stretched or - // have gutter. If the surface is missing the content will be filled - // with a solid color. In both cases we no longer have frame-to-frame - // damage so treat the entire SurfaceDrawQuad visible_rect as damaged. - // |combined_clip_rect| is the transforming and clipping result of the - // entire SurfaceDrawQuad visible_rect on the root target space of the - // root surface. - AddSurfaceDamageToDamageList(surface_in_target_space, target_transform, - dest_root_target_clip_rect, - dest_pass->transform_to_root_target, - /*resolved_frame=*/nullptr); - } + gfx::Rect surface_in_target_space = ComputeDrawableRectForQuad(surface_quad); + surface_in_target_space.Intersect(source_pass.output_rect); + + if (needs_surface_damage_rect_list_ && + (!resolved_frame || resolved_frame->surface_id() != primary_surface_id)) { + // If using a fallback surface the surface content may be stretched or + // have gutter. If the surface is missing the content will be filled + // with a solid color. In both cases we no longer have frame-to-frame + // damage so treat the entire SurfaceDrawQuad visible_rect as damaged. + // |combined_clip_rect| is the transforming and clipping result of the + // entire SurfaceDrawQuad visible_rect on the root target space of the + // root surface. + AddSurfaceDamageToDamageList(surface_in_target_space, target_transform, + dest_root_target_clip_rect, + dest_pass->transform_to_root_target, + /*resolved_frame=*/nullptr); + } // combined_clip_rect is the result of |dest_root_target_clip_rect| // intersecting |surface_quad| on the root target space of the root surface. - combined_clip_rect = TransformRectToDestRootTargetSpace( - /*rect_in_target_space=*/surface_in_target_space, target_transform, - dest_pass->transform_to_root_target, dest_root_target_clip_rect); - } + combined_clip_rect = TransformRectToDestRootTargetSpace( + /*rect_in_target_space=*/surface_in_target_space, target_transform, + dest_pass->transform_to_root_target, dest_root_target_clip_rect); // If there's no fallback surface ID available, then simply emit a // SolidColorDrawQuad with the provided default background color. This @@ -676,7 +775,7 @@ } void SurfaceAggregator::EmitSurfaceContent( - const ResolvedFrameData& resolved_frame, + ResolvedFrameData& resolved_frame, float parent_device_scale_factor, const SurfaceDrawQuad* surface_quad, uint32_t embedder_client_namespace_id, @@ -785,6 +884,12 @@ added_clip_rect, ComputeDrawableRectForQuad(surface_quad), target_transform); } + // Update ParentClipData.merge_status of the root render pass of the current + // frame before making a call to AddSurfaceDamageToDamageList() where + // RenderPassNeedsFullDamage() is called and needs root pass |merge_state| + // info. + UpdateParentClipDataMergeState(resolved_frame.GetRootRenderPassData(), + dest_pass, merge_pass); if (needs_surface_damage_rect_list_ && resolved_frame.WillDraw()) { AddSurfaceDamageToDamageList( @@ -803,12 +908,12 @@ } // TODO(fsamuel): Move this to a separate helper function. - const auto& resolved_passes = resolved_frame.GetResolvedPasses(); + auto& resolved_passes = resolved_frame.GetResolvedPasses(); size_t num_render_passes = resolved_passes.size(); size_t passes_to_copy = merge_pass ? num_render_passes - 1 : num_render_passes; for (size_t j = 0; j < passes_to_copy; ++j) { - const ResolvedPassData& resolved_pass = resolved_passes[j]; + ResolvedPassData& resolved_pass = resolved_passes[j]; const CompositorRenderPass& source = resolved_pass.render_pass(); size_t sqs_size = source.shared_quad_state_list.size(); @@ -830,6 +935,9 @@ source.cache_render_pass, resolved_pass.aggregation().has_damage, source.generate_mipmap); + UpdateParentClipDataMergeState(resolved_pass, copy_pass.get(), + /*is_merged_pass=*/false); + MoveMatchingRequests(source.id, ©_requests, ©_pass->copy_requests); // Contributing passes aggregated in to the pass list need to take the @@ -849,9 +957,10 @@ } const auto& last_pass = *render_pass_list.back(); - const auto& resolved_root_pass = resolved_frame.GetRootRenderPassData(); + auto& resolved_root_pass = resolved_frame.GetRootRenderPassData(); if (merge_pass) { + // UpdateParentClipDataMergeState() has been called earlier. CopyQuadsToPass(resolved_frame, resolved_root_pass, dest_pass, frame.device_scale_factor(), combined_transform, surface_quad_clip, dest_root_target_clip_rect, surface, @@ -1167,8 +1276,8 @@ } void SurfaceAggregator::CopyQuadsToPass( - const ResolvedFrameData& resolved_frame, - const ResolvedPassData& resolved_pass, + ResolvedFrameData& resolved_frame, + ResolvedPassData& resolved_pass, AggregatedRenderPass* dest_pass, float parent_device_scale_factor, const gfx::Transform& target_transform, @@ -1234,6 +1343,16 @@ surface, &overlay_damage_index); } + gfx::Transform pass_to_dest_root_target_transform = + dest_pass->transform_to_root_target * target_transform; + + // Add render pass |output_rect| to |dest_root_target_clip_rect|. + auto new_dest_root_target_clip_rect = CalculateClipRect( + dest_root_target_clip_rect, resolved_pass.render_pass().output_rect, + pass_to_dest_root_target_transform); + + UpdateNeedsRedraw(resolved_pass, dest_pass, new_dest_root_target_clip_rect); + MaskFilterInfoExt new_mask_filter_info_ext = parent_mask_filter_info_ext; size_t quad_index = 0; @@ -1269,8 +1388,8 @@ HandleSurfaceQuad(source_pass, surface_quad, client_namespace_id, parent_device_scale_factor, target_transform, clip_rect, - dest_root_target_clip_rect, dest_pass, ignore_undamaged, - &damage_rect_in_quad_space, + new_dest_root_target_clip_rect, dest_pass, + ignore_undamaged, &damage_rect_in_quad_space, &damage_rect_in_quad_space_valid, new_mask_filter_info_ext); } else { @@ -1295,10 +1414,11 @@ GetOptionalDamageRectFromQuad(quad); dest_shared_quad_state->overlay_damage_index = surface_damage_rect_list_->size(); - AddSurfaceDamageToDamageList( - damage_rect_in_target_space.value(), target_transform, - dest_root_target_clip_rect, dest_pass->transform_to_root_target, - /*resolved_frame=*/nullptr); + AddSurfaceDamageToDamageList(damage_rect_in_target_space.value(), + target_transform, + new_dest_root_target_clip_rect, + dest_pass->transform_to_root_target, + /*resolved_frame=*/nullptr); } else if (quad == quad_with_overlay_damage_index) { dest_shared_quad_state->overlay_damage_index = overlay_damage_index; } @@ -1333,7 +1453,8 @@ resolved_pass.aggregation().will_draw) { AddRenderPassFilterDamageToDamageList( resolved_frame, pass_quad, target_transform, - dest_root_target_clip_rect, dest_pass->transform_to_root_target); + new_dest_root_target_clip_rect, + dest_pass->transform_to_root_target); } } else if (const auto* texture_quad = quad->DynamicCast<TextureDrawQuad>()) { @@ -1360,7 +1481,7 @@ } } -void SurfaceAggregator::CopyPasses(const ResolvedFrameData& resolved_frame) { +void SurfaceAggregator::CopyPasses(ResolvedFrameData& resolved_frame) { Surface* surface = resolved_frame.surface(); const CompositorFrame& frame = surface->GetActiveOrInterpolatedFrame(); @@ -1430,6 +1551,8 @@ source.has_transparent_background, source.cache_render_pass, resolved_pass.aggregation().has_damage, source.generate_mipmap); + UpdateParentClipDataMergeState(resolved_pass, copy_pass.get(), + /*is_merged_pass=*/false); if (needs_surface_damage_rect_list_ && resolved_pass.is_root()) { AddSurfaceDamageToDamageList( /*default_damage_rect=*/gfx::Rect(), @@ -1442,7 +1565,7 @@ frame.device_scale_factor(), apply_surface_transform_to_root_pass ? surface_transform : gfx::Transform(), - {}, /*dest_root_target_clip_rect=*/{}, surface, + {}, /*dest_root_target_clip_rect=*/output_rect, surface, MaskFilterInfoExt()); SetRenderPassDamageRect(copy_pass.get(), resolved_pass); @@ -1456,7 +1579,7 @@ void SurfaceAggregator::SetRenderPassDamageRect( AggregatedRenderPass* copy_pass, - const ResolvedPassData& resolved_pass) { + ResolvedPassData& resolved_pass) { // If the render pass has copy requests, or should be cached, or has // moving-pixel filters, or in a moving-pixel surface, we should damage the // whole output rect so that we always drawn the full content. Otherwise, we @@ -1934,7 +2057,7 @@ for (size_t i = 0; i < surfaces_to_copy.size(); i++) { SurfaceId surface_id = surfaces_to_copy[i]; - const ResolvedFrameData* resolved_frame = GetResolvedFrame(surface_id); + ResolvedFrameData* resolved_frame = GetResolvedFrame(surface_id); if (!resolved_frame) continue;
diff --git a/components/viz/service/display/surface_aggregator.h b/components/viz/service/display/surface_aggregator.h index 1abec0a1..3de36d0 100644 --- a/components/viz/service/display/surface_aggregator.h +++ b/components/viz/service/display/surface_aggregator.h
@@ -164,7 +164,7 @@ const MaskFilterInfoExt& mask_filter_info_pair); void EmitSurfaceContent( - const ResolvedFrameData& resolved_frame, + ResolvedFrameData& resolved_frame, float parent_device_scale_factor, const SurfaceDrawQuad* surface_quad, uint32_t embedder_client_namespace_id, @@ -197,8 +197,8 @@ const MaskFilterInfoExt& mask_filter_info_pair); void CopyQuadsToPass( - const ResolvedFrameData& resolved_frame, - const ResolvedPassData& resolved_pass, + ResolvedFrameData& resolved_frame, + ResolvedPassData& resolved_pass, AggregatedRenderPass* dest_pass, float parent_device_scale_factor, const gfx::Transform& target_transform, @@ -254,7 +254,7 @@ void ProcessResolvedFrame(ResolvedFrameData& resolved_frame); void CopyUndrawnSurfaces(PrewalkResult* prewalk); - void CopyPasses(const ResolvedFrameData& resolved_frame); + void CopyPasses(ResolvedFrameData& resolved_frame); void AddColorConversionPass(); void AddRootReadbackPass(); void AddDisplayTransformPass(); @@ -295,7 +295,7 @@ const gfx::Transform& parent_target_transform, const absl::optional<gfx::Rect>& dest_root_target_clip_rect, const gfx::Transform& dest_transform_to_root_target, - const ResolvedFrameData* resolved_frame); + ResolvedFrameData* resolved_frame); void AddRenderPassFilterDamageToDamageList( const ResolvedFrameData& resolved_frame, @@ -337,7 +337,7 @@ void ResetAfterAggregate(); void SetRenderPassDamageRect(AggregatedRenderPass* copy_pass, - const ResolvedPassData& resolved_pass); + ResolvedPassData& resolved_pass); const raw_ptr<SurfaceManager> manager_; const raw_ptr<DisplayResourceProvider> provider_;
diff --git a/components/viz/service/display/surface_aggregator_unittest.cc b/components/viz/service/display/surface_aggregator_unittest.cc index 711545f..3c60b0847 100644 --- a/components/viz/service/display/surface_aggregator_unittest.cc +++ b/components/viz/service/display/surface_aggregator_unittest.cc
@@ -18,9 +18,11 @@ #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" #include "base/time/time.h" #include "cc/base/math_util.h" #include "cc/test/render_pass_test_utils.h" +#include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "components/viz/common/quads/aggregated_render_pass.h" #include "components/viz/common/quads/aggregated_render_pass_draw_quad.h" @@ -5150,6 +5152,12 @@ // Tests that quads outside the damage rect are ignored. TEST_F(SurfaceAggregatorPartialSwapTest, IgnoreOutside) { + // The damage is different for the pixel-moving filter mode with + // kAllowUndamagedNonrootRenderPassToSkip enabled. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndDisableFeature( + features::kAllowUndamagedNonrootRenderPassToSkip); + TestSurfaceIdAllocator child_surface_id(child_sink_->frame_sink_id()); constexpr float device_scale_factor = 1.0f; @@ -5683,6 +5691,483 @@ } } +// Tests that quads outside the damage rect are ignored. +TEST_F(SurfaceAggregatorPartialSwapTest, AllowSkipAndIgnoreOutside) { + // The damage is different for the pixel-moving filter mode with + // kAllowUndamagedNonrootRenderPassToSkip enabled. + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitAndEnableFeature( + features::kAllowUndamagedNonrootRenderPassToSkip); + + TestSurfaceIdAllocator child_surface_id(child_sink_->frame_sink_id()); + constexpr float device_scale_factor = 1.0f; + + // The child surface has three quads, one with a visible rect of 13,13 4x4 and + // the other other with a visible rect of 10,10 2x2 (relative to root target + // space), and one with a non-invertible transform. + { + CompositorRenderPassId child_pass_ids[] = {CompositorRenderPassId{1}, + CompositorRenderPassId{2}, + CompositorRenderPassId{3}}; + std::vector<Quad> child_quads1 = { + Quad::SolidColorQuad(SkColors::kGreen, gfx::Rect(5, 5))}; + std::vector<Quad> child_quads2 = { + Quad::SolidColorQuad(SkColors::kGreen, gfx::Rect(5, 5))}; + std::vector<Quad> child_quads3 = { + Quad::SolidColorQuad(SkColors::kGreen, gfx::Rect(5, 5))}; + std::vector<Pass> child_passes = { + Pass(child_quads1, child_pass_ids[0], kSurfaceSize), + Pass(child_quads2, child_pass_ids[1], kSurfaceSize), + Pass(child_quads3, child_pass_ids[2], kSurfaceSize)}; + + CompositorRenderPassList child_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&child_pass_list, child_passes, &referenced_surfaces); + + child_pass_list[0]->quad_list.ElementAt(0)->visible_rect = + gfx::Rect(1, 1, 2, 2); + auto* child_sqs = child_pass_list[0]->shared_quad_state_list.ElementAt(0u); + child_sqs->quad_to_target_transform.Translate(1, 1); + child_sqs->quad_to_target_transform.Scale(2, 2); + + child_pass_list[1]->quad_list.ElementAt(0)->visible_rect = + gfx::Rect(0, 0, 2, 2); + + auto* child_noninvertible_sqs = + child_pass_list[2]->shared_quad_state_list.ElementAt(0u); + child_noninvertible_sqs->quad_to_target_transform.set_rc(0, 0, 0.0); + EXPECT_FALSE( + child_noninvertible_sqs->quad_to_target_transform.IsInvertible()); + child_pass_list[2]->quad_list.ElementAt(0)->visible_rect = + gfx::Rect(0, 0, 2, 2); + + // Check whether a nonroot render pass can be skipped or not. + child_pass_list[0]->has_damage_from_contributing_content = true; + child_pass_list[1]->has_damage_from_contributing_content = true; + child_pass_list[2]->has_damage_from_contributing_content = true; + + SubmitPassListAsFrame(child_sink_.get(), + child_surface_id.local_surface_id(), &child_pass_list, + std::move(referenced_surfaces), device_scale_factor); + } + + { + std::vector<Quad> root_quads = {Quad::SurfaceQuad( + SurfaceRange(absl::nullopt, child_surface_id), SkColors::kWhite, + gfx::Rect(5, 5), /*stretch_content_to_fill_bounds=*/false)}; + + std::vector<Pass> root_passes = {Pass(root_quads, kSurfaceSize)}; + + CompositorRenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + auto* root_pass = root_pass_list[0].get(); + root_pass->shared_quad_state_list.front() + ->quad_to_target_transform.Translate(10, 10); + root_pass->damage_rect = gfx::Rect(0, 0, 1, 1); + root_pass->has_damage_from_contributing_content = true; + + SubmitPassListAsFrame(root_sink_.get(), root_surface_id_.local_surface_id(), + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + } + + { + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(3u, aggregated_pass_list.size()); + + // Damage rect for first aggregation should contain entire root surface. + EXPECT_EQ(gfx::Rect(kSurfaceSize), aggregated_pass_list[2]->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + + EXPECT_TRUE(aggregated_pass_list[0]->has_damage_from_contributing_content); + EXPECT_TRUE(aggregated_pass_list[1]->has_damage_from_contributing_content); + } + + // Create a root surface with a smaller damage rect. + { + std::vector<Quad> root_quads = {Quad::SurfaceQuad( + SurfaceRange(absl::nullopt, child_surface_id), SkColors::kWhite, + gfx::Rect(5, 5), /*stretch_content_to_fill_bounds=*/false)}; + + std::vector<Pass> root_passes = {Pass(root_quads, kSurfaceSize)}; + + CompositorRenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + auto* root_pass = root_pass_list[0].get(); + root_pass->shared_quad_state_list.front() + ->quad_to_target_transform.Translate(10, 10); + root_pass->damage_rect = gfx::Rect(10, 10, 2, 2); + SubmitPassListAsFrame(root_sink_.get(), root_surface_id_.local_surface_id(), + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + } + + { + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(3u, aggregated_pass_list.size()); + + // Only first quad from surface is inside damage rect and should be + // included. + EXPECT_EQ(gfx::Rect(10, 10, 2, 2), aggregated_pass_list[2]->damage_rect); + EXPECT_EQ(0u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(gfx::Rect(0, 0, 2, 2), + aggregated_pass_list[1]->quad_list.back()->visible_rect); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + + EXPECT_FALSE(aggregated_pass_list[0]->has_damage_from_contributing_content); + EXPECT_FALSE(aggregated_pass_list[1]->has_damage_from_contributing_content); + } + + // New child frame has same content and no damage, but has a + // CopyOutputRequest. + { + CompositorRenderPassId child_pass_ids[] = {CompositorRenderPassId{1}, + CompositorRenderPassId{2}}; + std::vector<Quad> child_quads1 = { + Quad::SolidColorQuad({1.0, 0.0, 1.0, 1.0f / 255.0f}, gfx::Rect(5, 5))}; + std::vector<Quad> child_quads2 = { + Quad::RenderPassQuad(child_pass_ids[0], gfx::Transform(), true)}; + std::vector<Pass> child_passes = { + Pass(child_quads1, child_pass_ids[0], kSurfaceSize), + Pass(child_quads2, child_pass_ids[1], kSurfaceSize)}; + + CompositorRenderPassList child_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&child_pass_list, child_passes, &referenced_surfaces); + + child_pass_list[0]->quad_list.ElementAt(0)->visible_rect = + gfx::Rect(1, 1, 2, 2); + auto* child_sqs = child_pass_list[0]->shared_quad_state_list.ElementAt(0u); + child_sqs->quad_to_target_transform.Translate(1, 1); + child_sqs->quad_to_target_transform.Scale(2, 2); + + child_pass_list[1]->quad_list.ElementAt(0)->visible_rect = + gfx::Rect(0, 0, 2, 2); + + auto* child_root_pass = child_pass_list[1].get(); + + child_root_pass->copy_requests.push_back( + CopyOutputRequest::CreateStubForTesting()); + child_root_pass->damage_rect = gfx::Rect(); + + child_pass_list[0]->has_damage_from_contributing_content = false; + child_pass_list[1]->has_damage_from_contributing_content = false; + + SubmitPassListAsFrame(child_sink_.get(), + child_surface_id.local_surface_id(), &child_pass_list, + std::move(referenced_surfaces), device_scale_factor); + } + + { + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + // Output frame should have no damage, but all quads included. + ASSERT_EQ(3u, aggregated_pass_list.size()); + + EXPECT_EQ(gfx::Rect(kSurfaceSize), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(gfx::Rect(kSurfaceSize), aggregated_pass_list[1]->damage_rect); + EXPECT_TRUE(aggregated_pass_list[2]->damage_rect.IsEmpty()); + ASSERT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + ASSERT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(gfx::Rect(1, 1, 2, 2), + aggregated_pass_list[0]->quad_list.ElementAt(0)->visible_rect); + EXPECT_EQ(gfx::Rect(0, 0, 2, 2), + aggregated_pass_list[1]->quad_list.ElementAt(0)->visible_rect); + ASSERT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + + EXPECT_TRUE(aggregated_pass_list[1]->has_damage_from_contributing_content); + EXPECT_FALSE(aggregated_pass_list[2]->has_damage_from_contributing_content); + } + + { + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + // There were no changes since last aggregation, so output should be empty + // and have no damage. + ASSERT_EQ(1u, aggregated_pass_list.size()); + EXPECT_TRUE(aggregated_pass_list[0]->damage_rect.IsEmpty()); + ASSERT_EQ(0u, aggregated_pass_list[0]->quad_list.size()); + } + + // Reset and make full damage for all render passes. + { + CompositorRenderPassId root_pass_ids[] = {CompositorRenderPassId{1}, + CompositorRenderPassId{2}, + CompositorRenderPassId{3}}; + std::vector<Quad> root_quads1 = {Quad::SurfaceQuad( + SurfaceRange(absl::nullopt, child_surface_id), SkColors::kWhite, + gfx::Rect(5, 5), /*stretch_content_to_fill_bounds=*/false)}; + std::vector<Quad> root_quads2 = { + Quad::RenderPassQuad(root_pass_ids[0], gfx::Transform(), true)}; + std::vector<Quad> root_quads3 = { + Quad::RenderPassQuad(root_pass_ids[1], gfx::Transform(), true)}; + std::vector<Pass> root_passes = { + Pass(root_quads1, root_pass_ids[0], kSurfaceSize), + Pass(root_quads2, root_pass_ids[1], kSurfaceSize), + Pass(root_quads3, root_pass_ids[2], kSurfaceSize)}; + + CompositorRenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + root_pass_list[0]->has_damage_from_contributing_content = true; + root_pass_list[1]->has_damage_from_contributing_content = true; + root_pass_list[2]->has_damage_from_contributing_content = true; + root_pass_list[0]->damage_rect = gfx::Rect(kSurfaceSize); + root_pass_list[1]->damage_rect = gfx::Rect(kSurfaceSize); + root_pass_list[2]->damage_rect = gfx::Rect(kSurfaceSize); + + SubmitPassListAsFrame(root_sink_.get(), root_surface_id_.local_surface_id(), + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(4u, aggregated_pass_list.size()); + + EXPECT_EQ(gfx::Rect(kSurfaceSize), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(gfx::Rect(kSurfaceSize), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(gfx::Rect(kSurfaceSize), aggregated_pass_list[2]->damage_rect); + EXPECT_EQ(gfx::Rect(kSurfaceSize), aggregated_pass_list[3]->damage_rect); + + EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[3]->quad_list.size()); + + // parent_clip_rect expands from + EXPECT_TRUE(aggregated_pass_list[0]->has_damage_from_contributing_content); + EXPECT_TRUE(aggregated_pass_list[1]->has_damage_from_contributing_content); + EXPECT_TRUE(aggregated_pass_list[2]->has_damage_from_contributing_content); + } + + // Render passes with pixel-moving foreground filters will increase the damage + // only if the damage of the contents will overlap the expanded render pass + // draw quad. Since the root surface damage does not overlap, the render pass + // and its descendant passes should not be aggregated. + { + CompositorRenderPassId root_pass_ids[] = {CompositorRenderPassId{1}, + CompositorRenderPassId{2}, + CompositorRenderPassId{3}}; + std::vector<Quad> root_quads1 = {Quad::SurfaceQuad( + SurfaceRange(absl::nullopt, child_surface_id), SkColors::kWhite, + gfx::Rect(5, 5), /*stretch_content_to_fill_bounds=*/false)}; + std::vector<Quad> root_quads2 = { + Quad::RenderPassQuad(root_pass_ids[0], gfx::Transform(), true)}; + std::vector<Quad> root_quads3 = { + Quad::RenderPassQuad(root_pass_ids[1], gfx::Transform(), true)}; + std::vector<Pass> root_passes = { + Pass(root_quads1, root_pass_ids[0], kSurfaceSize), + Pass(root_quads2, root_pass_ids[1], kSurfaceSize), + Pass(root_quads3, root_pass_ids[2], kSurfaceSize)}; + + CompositorRenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + auto* filter_pass = root_pass_list[1].get(); + filter_pass->shared_quad_state_list.front() + ->quad_to_target_transform.Translate(10, 10); + // Create 3 pixel-moving filters with the same max pixel movement. + filter_pass->filters.Append(cc::FilterOperation::CreateBlurFilter(2)); + filter_pass->filters.Append(cc::FilterOperation::CreateDropShadowFilter( + gfx::Point(0, 0), 2, SkColors::kTransparent)); + filter_pass->filters.Append(cc::FilterOperation::CreateZoomFilter(2, 4)); + auto* root_pass = root_pass_list[2].get(); + // Set the root damage rect which doesn't intersect with the expanded + // filter_pass quad (-4, -4, 13, 13) (filter quad (0, 0, 5, 5) + blur filter + // pixel movement (2 * 3 = 6)), so we don't have to add more damage from the + // filter_pass and the first render pass draw quad will not be drawn. + root_pass->damage_rect = gfx::Rect(20, 20, 2, 2); + root_pass->has_damage_from_contributing_content = true; + root_pass_list[0]->has_damage_from_contributing_content = false; + root_pass_list[1]->has_damage_from_contributing_content = false; + root_pass_list[0]->damage_rect = gfx::Rect(); + root_pass_list[1]->damage_rect = gfx::Rect(); + + SubmitPassListAsFrame(root_sink_.get(), root_surface_id_.local_surface_id(), + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(4u, aggregated_pass_list.size()); + + EXPECT_EQ(gfx::Rect(20, 20, 2, 2), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(gfx::Rect(20, 20, 2, 2), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(gfx::Rect(20, 20, 2, 2), aggregated_pass_list[2]->damage_rect); + // The filter pass does not intersects with the other damages. The root + // damage should not increase. + EXPECT_EQ(gfx::Rect(20, 20, 2, 2), aggregated_pass_list[3]->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + // First render pass draw quad with filter is outside damage rect, so + // shouldn't be drawn. + EXPECT_EQ(0u, aggregated_pass_list[3]->quad_list.size()); + + EXPECT_FALSE(aggregated_pass_list[0]->has_damage_from_contributing_content); + EXPECT_FALSE(aggregated_pass_list[1]->has_damage_from_contributing_content); + EXPECT_FALSE(aggregated_pass_list[2]->has_damage_from_contributing_content); + } + + // Render passes with pixel-moving foreground filters will increase the damage + // if the damage of the contents will overlap the expanded render pass draw + // quad (quad rect + maximum pixel movement). Since the root surface damage + // overlaps, the render pass and its descendant passes should be aggregated. + { + CompositorRenderPassId root_pass_ids[] = {CompositorRenderPassId{1}, + CompositorRenderPassId{2}, + CompositorRenderPassId{3}}; + std::vector<Quad> root_quads1 = {Quad::SurfaceQuad( + SurfaceRange(absl::nullopt, child_surface_id), SkColors::kWhite, + gfx::Rect(5, 5), /*stretch_content_to_fill_bounds=*/false)}; + std::vector<Quad> root_quads2 = { + Quad::RenderPassQuad(root_pass_ids[0], gfx::Transform(), true)}; + std::vector<Quad> root_quads3 = { + Quad::RenderPassQuad(root_pass_ids[1], gfx::Transform(), true)}; + std::vector<Pass> root_passes = { + Pass(root_quads1, root_pass_ids[0], kSurfaceSize), + Pass(root_quads2, root_pass_ids[1], kSurfaceSize), + Pass(root_quads3, root_pass_ids[2], kSurfaceSize)}; + + CompositorRenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + auto* filter_pass = root_pass_list[1].get(); + filter_pass->shared_quad_state_list.front() + ->quad_to_target_transform.Translate(10, 10); + // Create 3 pixel-moving filters with the same max pixel movement. + filter_pass->filters.Append(cc::FilterOperation::CreateBlurFilter(10)); + filter_pass->filters.Append(cc::FilterOperation::CreateDropShadowFilter( + gfx::Point(0, 0), 10, SkColors::kTransparent)); + filter_pass->filters.Append(cc::FilterOperation::CreateZoomFilter(2, 20)); + auto* root_pass = root_pass_list[2].get(); + // Make the root damage rect intersect with the expanded filter_pass quad + // (filter quad (0, 0, 5, 5) + blur filter pixel movement (10 * 3) = (-30, + // -30, 65, 65)), but not with filter_pass quad itself (0, 0, 5, 5). The + // first render pass will be drawn. + root_pass->damage_rect = gfx::Rect(20, 20, 2, 2); + root_pass->has_damage_from_contributing_content = true; + root_pass_list[0]->has_damage_from_contributing_content = false; + root_pass_list[1]->has_damage_from_contributing_content = false; + + SubmitPassListAsFrame(root_sink_.get(), root_surface_id_.local_surface_id(), + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(4u, aggregated_pass_list.size()); + + EXPECT_EQ(gfx::Rect(0, 0, 35, 35), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(gfx::Rect(0, 0, 35, 35), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(gfx::Rect(0, 0, 35, 35), aggregated_pass_list[2]->damage_rect); + // The filter pass intersects with the root surface damage, the root damage + // should increase. + // damage_rect = original root damage (0, 0, 5, 5) + blur filter pixel + // movement (10 * 3) = (-30, -30, 65, 65). Then intersects with the root + // output_rect (0, 0, 100, 100) = (0, 0, 35, 35). + EXPECT_EQ(gfx::Rect(0, 0, 35, 35), aggregated_pass_list[3]->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + // First render pass draw quad is damaged. It should be drawn. + EXPECT_EQ(1u, aggregated_pass_list[3]->quad_list.size()); + + EXPECT_FALSE(aggregated_pass_list[0]->has_damage_from_contributing_content); + EXPECT_FALSE(aggregated_pass_list[1]->has_damage_from_contributing_content); + EXPECT_FALSE(aggregated_pass_list[2]->has_damage_from_contributing_content); + } + + // If child surface quad or child render pass output rect expands from the + // previous frame, the child render pass should redraw. + { + CompositorRenderPassId root_pass_ids[] = {CompositorRenderPassId{1}, + CompositorRenderPassId{2}, + CompositorRenderPassId{3}}; + // Increase surface quad size from 5x5 to 30x30. + std::vector<Quad> root_quads1 = {Quad::SurfaceQuad( + SurfaceRange(absl::nullopt, child_surface_id), SkColors::kWhite, + gfx::Rect(30, 30), /*stretch_content_to_fill_bounds=*/false)}; + std::vector<Quad> root_quads2 = { + Quad::RenderPassQuad(root_pass_ids[0], gfx::Transform(), true)}; + std::vector<Quad> root_quads3 = { + Quad::RenderPassQuad(root_pass_ids[1], gfx::Transform(), true)}; + + // Expand the render pass [1] output rect size from 100x100 to 150x150. + std::vector<Pass> root_passes = { + Pass(root_quads1, root_pass_ids[0], kSurfaceSize), + Pass(root_quads2, root_pass_ids[1], gfx::Size(150, 150)), + Pass(root_quads3, root_pass_ids[2], kSurfaceSize)}; + + CompositorRenderPassList root_pass_list; + std::vector<SurfaceRange> referenced_surfaces; + AddPasses(&root_pass_list, root_passes, &referenced_surfaces); + + // Make the root damage rect intersect with the child render passes. + auto* root_pass = root_pass_list[2].get(); + root_pass->damage_rect = gfx::Rect(0, 0, 40, 40); + root_pass->has_damage_from_contributing_content = true; + root_pass_list[0]->has_damage_from_contributing_content = false; + root_pass_list[1]->has_damage_from_contributing_content = false; + + SubmitPassListAsFrame(root_sink_.get(), root_surface_id_.local_surface_id(), + &root_pass_list, std::move(referenced_surfaces), + device_scale_factor); + + auto aggregated_frame = AggregateFrame(root_surface_id_); + + const auto& aggregated_pass_list = aggregated_frame.render_pass_list; + + ASSERT_EQ(4u, aggregated_pass_list.size()); + + EXPECT_EQ(gfx::Rect(0, 0, 40, 40), aggregated_pass_list[0]->damage_rect); + EXPECT_EQ(gfx::Rect(0, 0, 40, 40), aggregated_pass_list[1]->damage_rect); + EXPECT_EQ(gfx::Rect(0, 0, 40, 40), aggregated_pass_list[2]->damage_rect); + + EXPECT_EQ(gfx::Rect(0, 0, 40, 40), aggregated_pass_list[3]->damage_rect); + EXPECT_EQ(1u, aggregated_pass_list[0]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[1]->quad_list.size()); + EXPECT_EQ(1u, aggregated_pass_list[2]->quad_list.size()); + // First render pass draw quad is damaged. It should be drawn. + EXPECT_EQ(1u, aggregated_pass_list[3]->quad_list.size()); + + // SurfaceQuad |parent_clip_rect| expands from (0,0 5x5) to (0,0 30x30). It + // should redraw. |has_damage_from_contributing_content| should be true. + EXPECT_TRUE(aggregated_pass_list[0]->has_damage_from_contributing_content); + EXPECT_TRUE(aggregated_pass_list[1]->has_damage_from_contributing_content); + + // RenderPassDrawQuad |parent_clip_rect| expands from (0,0 100x100) to (0,0 + // 150x150). It should redraw. |has_damage_from_contributing_content| should + // be true. + EXPECT_TRUE(aggregated_pass_list[2]->has_damage_from_contributing_content); + } +} + TEST_F(SurfaceAggregatorPartialSwapTest, ExpandByTargetDamage) { TestSurfaceIdAllocator child_surface_id(child_sink_->frame_sink_id()); constexpr float device_scale_factor = 1.0f;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index c2e09c8..e5ae879 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -994,6 +994,25 @@ gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access, GrGpuFinishedProc finished_proc, GrGpuFinishedContext finished_context) { + return FlushInternal(surface, end_semaphores, scoped_write_access, + finished_proc, finished_context); +} + +bool SkiaOutputSurfaceImplOnGpu::FlushContext( + std::vector<GrBackendSemaphore>& end_semaphores, + gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access, + GrGpuFinishedProc finished_proc, + GrGpuFinishedContext finished_context) { + return FlushInternal(/*surface=*/nullptr, end_semaphores, scoped_write_access, + finished_proc, finished_context); +} + +bool SkiaOutputSurfaceImplOnGpu::FlushInternal( + SkSurface* surface, + std::vector<GrBackendSemaphore>& end_semaphores, + gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access, + GrGpuFinishedProc finished_proc, + GrGpuFinishedContext finished_context) { GrFlushInfo flush_info; flush_info.fNumSemaphores = end_semaphores.size(); flush_info.fSignalSemaphores = end_semaphores.data(); @@ -1004,7 +1023,8 @@ context_state_->progress_reporter()); GrSemaphoresSubmitted flush_result = GrSemaphoresSubmitted::kNo; if (GrDirectContext* direct_context = gr_context()) { - flush_result = direct_context->flush(surface, flush_info, nullptr); + flush_result = surface ? direct_context->flush(surface, flush_info) + : direct_context->flush(flush_info); } if (scoped_write_access) { scoped_write_access->ApplyBackendSurfaceEndState(); @@ -1066,8 +1086,10 @@ bool SkiaOutputSurfaceImplOnGpu::ImportSurfacesForNV12Planes( const BlitRequest& blit_request, std::array<MailboxAccessData, CopyOutputResult::kNV12MaxPlanes>& - mailbox_access_datas) { - for (size_t i = 0; i < CopyOutputResult::kNV12MaxPlanes; ++i) { + mailbox_access_datas, + bool is_multiplane) { + size_t num_mailboxes = is_multiplane ? 1 : CopyOutputResult::kNV12MaxPlanes; + for (size_t i = 0; i < num_mailboxes; ++i) { const gpu::MailboxHolder& mailbox_holder = blit_request.mailbox(i); // Should never happen, mailboxes are validated when setting blit request on @@ -1091,9 +1113,20 @@ &mailbox_access_data.begin_semaphores, &mailbox_access_data.end_semaphores, gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes); - SkSurface* dest_surface = scoped_write->surface(); - dest_surface->wait(mailbox_access_data.begin_semaphores.size(), - mailbox_access_data.begin_semaphores.data()); + + if (is_multiplane) { + // NOTE: For multiplanar SharedImage there is only one set of semaphores + // for all of the planes. Rather than waiting on one of the planes we wait + // on the context, which facilitates flushing later: we first flush the + // individual surfaces without signaling followed by flushing+signaling + // the context. + gr_context()->wait(mailbox_access_data.begin_semaphores.size(), + mailbox_access_data.begin_semaphores.data()); + } else { + SkSurface* dest_surface = scoped_write->surface(); + dest_surface->wait(mailbox_access_data.begin_semaphores.size(), + mailbox_access_data.begin_semaphores.data()); + } // Semaphores have already been populated in `mailbox_access_data`. // Set the remaining fields. @@ -1165,6 +1198,9 @@ // blitted to the destination textures. const gfx::Size intermediate_dst_size = geometry.result_selection.size(); + bool is_multiplane = request->result_format() == + CopyOutputRequest::ResultFormat::NV12_MULTIPLANE; + std::array<MailboxAccessData, CopyOutputResult::kNV12MaxPlanes> mailbox_access_datas; @@ -1186,7 +1222,7 @@ } destination_surfaces_ready = ImportSurfacesForNV12Planes( - request->blit_request(), mailbox_access_datas); + request->blit_request(), mailbox_access_datas, is_multiplane); // The entire destination image size is the same as the size of the luma // plane of the image that was just imported: @@ -1207,6 +1243,10 @@ return; } } else { + // NV12_MULTIPLANE is currently used only when there is a blit request. + // TODO(crbug.com/1429004): Add handling for this case and then enable it in + // FrameSinkVideoCapturerImpl. + CHECK(!is_multiplane); yuva_info = SkYUVAInfo(gfx::SizeToSkISize(intermediate_dst_size), SkYUVAInfo::PlaneConfig::kY_UV, SkYUVAInfo::Subsampling::k420, @@ -1264,9 +1304,20 @@ // `skia::BlitRGBAToYUVA()` requires a buffer with 4 SkSurface* elements, // let's allocate it and populate its first 2 entries with the surfaces // obtained from |mailbox_access_datas|. - std::array<SkSurface*, SkYUVAInfo::kMaxPlanes> plane_surfaces = { - mailbox_access_datas[0].scoped_write->surface(), - mailbox_access_datas[1].scoped_write->surface(), nullptr, nullptr}; + std::array<SkSurface*, SkYUVAInfo::kMaxPlanes> plane_surfaces; + + // When using multiplanar SharedImage, the information for both planes is + // contained within the single SharedImage. Otherwise, each plane is accessed + // via its own SharedImage. + if (is_multiplane) { + plane_surfaces = {mailbox_access_datas[0].scoped_write->surface(0), + mailbox_access_datas[0].scoped_write->surface(1), nullptr, + nullptr}; + } else { + plane_surfaces = {mailbox_access_datas[0].scoped_write->surface(), + mailbox_access_datas[1].scoped_write->surface(), nullptr, + nullptr}; + } // The region to be populated in caller's textures is derived from blit // request's |destination_region_offset()|, and from COR's @@ -1294,12 +1345,17 @@ // Collect mailbox holders for the destination textures. They will be needed // in case the result is kNativeTextures. It happens here in order to simplify // the code in case we are populating the GpuMemoryBuffer-backed textures. + // NOTE: When using multiplanar SharedImage, there is only one mailbox (rather + // than one for each plane). + auto second_mailbox_holder = + is_multiplane ? gpu::MailboxHolder() + : gpu::MailboxHolder(mailbox_access_datas[1].mailbox, + gpu::SyncToken(), GL_TEXTURE_2D); std::array<gpu::MailboxHolder, CopyOutputResult::kMaxPlanes> mailbox_holders = { gpu::MailboxHolder(mailbox_access_datas[0].mailbox, gpu::SyncToken(), GL_TEXTURE_2D), - gpu::MailboxHolder(mailbox_access_datas[1].mailbox, gpu::SyncToken(), - GL_TEXTURE_2D), + second_mailbox_holder, gpu::MailboxHolder(), }; @@ -1319,11 +1375,12 @@ // sending the CopyOutputResult: nv12_planes_ready = base::MakeRefCounted<NV12PlanesReadyContext>( weak_ptr_, std::move(request), geometry.result_selection, - mailbox_holders, color_space); + mailbox_holders, color_space, is_multiplane); } bool should_submit = false; - for (size_t i = 0; i < CopyOutputResult::kNV12MaxPlanes; ++i) { + size_t num_mailboxes = is_multiplane ? 1 : CopyOutputResult::kNV12MaxPlanes; + for (size_t i = 0; i < num_mailboxes; ++i) { mailbox_access_datas[i].representation->SetCleared(); should_submit |= !mailbox_access_datas[i].end_semaphores.empty(); @@ -1342,13 +1399,30 @@ ++num_readbacks_pending_; } - if (!FlushSurface( - plane_surfaces[i], mailbox_access_datas[i].end_semaphores, - mailbox_access_datas[i].scoped_write.get(), - should_wait_for_gpu_work - ? &NV12SingleMailboxReadyContext::OnMailboxReady - : nullptr, - should_wait_for_gpu_work ? nv12_plane_ready.release() : nullptr)) { + bool flush_succeeded = false; + if (is_multiplane) { + // Flush the individual surfaces followed by flushing the context and + // signaling. + gr_context()->flush(plane_surfaces[0], GrFlushInfo()); + gr_context()->flush(plane_surfaces[1], GrFlushInfo()); + flush_succeeded = FlushContext( + mailbox_access_datas[i].end_semaphores, + mailbox_access_datas[i].scoped_write.get(), + should_wait_for_gpu_work + ? &NV12SingleMailboxReadyContext::OnMailboxReady + : nullptr, + should_wait_for_gpu_work ? nv12_plane_ready.release() : nullptr); + } else { + flush_succeeded = FlushSurface( + plane_surfaces[i], mailbox_access_datas[i].end_semaphores, + mailbox_access_datas[i].scoped_write.get(), + should_wait_for_gpu_work + ? &NV12SingleMailboxReadyContext::OnMailboxReady + : nullptr, + should_wait_for_gpu_work ? nv12_plane_ready.release() : nullptr); + } + + if (!flush_succeeded) { // TODO(penghuang): handle vulkan device lost. FailedSkiaFlush("CopyOutputNV12 plane_surfaces[i]->flush()"); return; @@ -1366,6 +1440,13 @@ return; } + // NV12_MULTIPLANE is currently used only when there is a blit request that + // populates the GMB and sends the result to native textures, in which case + // `should_wait_for_gpu_work` will be true. + // TODO(crbug.com/1429004): Remove this CHECK when extending support to + // other cases. + CHECK(!is_multiplane); + // We conditionally move from request (if `should_wait_for_gpu_work` is true), // DCHECK that we don't accidentally enter this codepath after the request was // moved from. @@ -1601,17 +1682,13 @@ &CopyOutputResultSkiaYUV::OnReadbackDone, context.release()); break; } - case CopyOutputRequest::ResultFormat::NV12_PLANES: { + case CopyOutputRequest::ResultFormat::NV12_PLANES: + case CopyOutputRequest::ResultFormat::NV12_MULTIPLANE: { CopyOutputNV12(surface, geometry, color_space, src_rect, rescale_mode, is_downscale_or_identity_in_both_dimensions, std::move(request)); break; } - case CopyOutputRequest::ResultFormat::NV12_MULTIPLANE: { - // TODO(crbug.com/1429004): Implement. - NOTREACHED(); - break; - } case CopyOutputRequest::ResultFormat::RGBA: { CopyOutputRGBA(surface, geometry, color_space, src_rect, rescale_mode, is_downscale_or_identity_in_both_dimensions,
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index 15b8ffa1..c13f493 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -341,6 +341,16 @@ gpu::GrContextType::kGraphiteDawn; } + // Helper for `FlushSurface()` & `FlushContext()` methods, flushes writes + // to either the surface if it is non-null or to the context otherwise, using + // |end_semaphores| and |end_state|. + bool FlushInternal( + SkSurface* surface, + std::vector<GrBackendSemaphore>& end_semaphores, + gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access, + GrGpuFinishedProc finished_proc = nullptr, + GrGpuFinishedContext finished_context = nullptr); + // Helper for `CopyOutput()` method, handles the RGBA format. void CopyOutputRGBA(SkSurface* surface, copy_output::RenderPassGeometry geometry, @@ -392,6 +402,14 @@ GrGpuFinishedProc finished_proc = nullptr, GrGpuFinishedContext finished_context = nullptr); + // Helper for `CopyOutputNV12()` & `CopyOutputRGBA()` methods, flushes writes + // to the Skia context with |end_semaphores| and |end_state|. + bool FlushContext( + std::vector<GrBackendSemaphore>& end_semaphores, + gpu::SkiaImageRepresentation::ScopedWriteAccess* scoped_write_access, + GrGpuFinishedProc finished_proc = nullptr, + GrGpuFinishedContext finished_context = nullptr); + // Creates surfaces needed to store the data in NV12 format. // |mailbox_access_datas| will be populated with information needed to access // the NV12 planes. @@ -407,7 +425,8 @@ bool ImportSurfacesForNV12Planes( const BlitRequest& blit_request, std::array<MailboxAccessData, CopyOutputResult::kNV12MaxPlanes>& - mailbox_access_datas); + mailbox_access_datas, + bool is_multiplane); // Helper, blends `BlendBitmap`s set on the |blit_request| over the |canvas|. // Used to implement handling of `CopyOutputRequest`s that contain
diff --git a/components/viz/service/display_embedder/skia_render_copy_results.cc b/components/viz/service/display_embedder/skia_render_copy_results.cc index 6286818..5c3609c 100644 --- a/components/viz/service/display_embedder/skia_render_copy_results.cc +++ b/components/viz/service/display_embedder/skia_render_copy_results.cc
@@ -329,11 +329,15 @@ const gfx::Rect& result_rect, const std::array<gpu::MailboxHolder, CopyOutputResult::kMaxPlanes>& mailbox_holders, - const gfx::ColorSpace& color_space) + const gfx::ColorSpace& color_space, + bool is_multiplane) : request_(std::move(request)), result_rect_(result_rect), mailbox_holders_(mailbox_holders), - color_space_(color_space) {} + color_space_(color_space), + is_multiplane_(is_multiplane) { + outstanding_mailboxes_ = is_multiplane ? 1 : CopyOutputResult::kNV12MaxPlanes; +} NV12PlanesReadyContext::~NV12PlanesReadyContext() { DCHECK_EQ(outstanding_mailboxes_, 0); @@ -348,8 +352,10 @@ outstanding_mailboxes_--; if (outstanding_mailboxes_ == 0) { + auto format = is_multiplane_ ? CopyOutputResult::Format::NV12_MULTIPLANE + : CopyOutputResult::Format::NV12_PLANES; request_->SendResult(std::make_unique<CopyOutputTextureResult>( - CopyOutputResult::Format::NV12_PLANES, result_rect_, + format, result_rect_, CopyOutputResult::TextureResult(mailbox_holders_, color_space_), CopyOutputResult::ReleaseCallbacks())); }
diff --git a/components/viz/service/display_embedder/skia_render_copy_results.h b/components/viz/service/display_embedder/skia_render_copy_results.h index cfe63db..175ce7c4 100644 --- a/components/viz/service/display_embedder/skia_render_copy_results.h +++ b/components/viz/service/display_embedder/skia_render_copy_results.h
@@ -189,7 +189,8 @@ const gfx::Rect& result_rect, const std::array<gpu::MailboxHolder, CopyOutputResult::kMaxPlanes>& mailbox_holders, - const gfx::ColorSpace& color_space); + const gfx::ColorSpace& color_space, + bool is_multiplane); NV12PlanesReadyContext(const NV12PlanesReadyContext& other) = delete; NV12PlanesReadyContext& operator=(const NV12PlanesReadyContext& other) = @@ -213,8 +214,11 @@ std::array<gpu::MailboxHolder, CopyOutputResult::kMaxPlanes> mailbox_holders_; gfx::ColorSpace color_space_; - // Number of mailboxes that still need to report completion: - int outstanding_mailboxes_ = CopyOutputResult::kNV12MaxPlanes; + // Number of mailboxes that still need to report completion, initialized + // either to 1 for multiplanar or to the number of NV12 planes otherwise. + int outstanding_mailboxes_ = 0; + + bool is_multiplane_; THREAD_CHECKER(thread_checker_); };
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index e4e8d71..90310f0e 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -31,6 +31,7 @@ #include "gpu/command_buffer/service/gpu_switches.h" #include "gpu/command_buffer/service/scheduler.h" #include "gpu/command_buffer/service/shared_context_state.h" +#include "gpu/command_buffer/service/shared_image/shared_image_manager.h" #include "gpu/command_buffer/service/skia_utils.h" #include "gpu/command_buffer/service/sync_point_manager.h" #include "gpu/config/dx_diag_node.h" @@ -56,7 +57,6 @@ #include "media/gpu/buildflags.h" #include "media/gpu/gpu_video_accelerator_util.h" #include "media/gpu/gpu_video_encode_accelerator_factory.h" -#include "media/gpu/ipc/service/gpu_video_decode_accelerator.h" #include "media/gpu/ipc/service/media_gpu_channel_manager.h" #include "media/mojo/services/gpu_mojo_media_client.h" #include "media/mojo/services/mojo_video_encode_accelerator_provider.h"
diff --git a/components/webapps/browser/android/app_banner_manager_android.cc b/components/webapps/browser/android/app_banner_manager_android.cc index 5643064..a081e265 100644 --- a/components/webapps/browser/android/app_banner_manager_android.cc +++ b/components/webapps/browser/android/app_banner_manager_android.cc
@@ -185,12 +185,6 @@ manifest_id_); } -// TODO(eirage): Implement for Android. -bool AppBannerManagerAndroid::IsAppFullyInstalledForSiteUrl( - const GURL& site_url) const { - return false; -} - void AppBannerManagerAndroid::ResetCurrentPageData() { AppBannerManager::ResetCurrentPageData(); native_app_data_.Reset(); @@ -544,11 +538,35 @@ return Java_AppBannerManager_isRelatedNonWebAppInstalled(env, java_id); } +// TODO(eirage): Implement for Android. +bool AppBannerManagerAndroid::IsAppFullyInstalledForSiteUrl( + const GURL& site_url) const { + return false; +} + bool AppBannerManagerAndroid::IsAppPartiallyInstalledForSiteUrl( const GURL& site_url) const { return false; } +void AppBannerManagerAndroid::SaveInstallationDismissedForMl( + const GURL& manifest_id) { + // TODO(https://crbug.com/1449993): Implement. +} +void AppBannerManagerAndroid::SaveInstallationIgnoredForMl( + const GURL& manifest_id) { + // TODO(https://crbug.com/1449993): Implement. +} +void AppBannerManagerAndroid::SaveInstallationAcceptedForMl( + const GURL& manifest_id) { + // TODO(https://crbug.com/1449993): Implement. +} +bool AppBannerManagerAndroid::IsMlPromotionBlockedByHistoryGuardrail( + const GURL& manifest_id) { + // TODO(https://crbug.com/1449993): Implement. + return false; +} + void AppBannerManagerAndroid::RecordExtraMetricsForInstallEvent( AddToHomescreenInstaller::Event event, const AddToHomescreenParams& a2hs_params) {}
diff --git a/components/webapps/browser/android/app_banner_manager_android.h b/components/webapps/browser/android/app_banner_manager_android.h index 0a91003..91e1c80 100644 --- a/components/webapps/browser/android/app_banner_manager_android.h +++ b/components/webapps/browser/android/app_banner_manager_android.h
@@ -114,11 +114,6 @@ void PerformWorkerCheckForAmbientBadge(InstallableParams params, InstallableCallback callback); - bool IsAppFullyInstalledForSiteUrl(const GURL& site_url) const override; - - // Locally installed apps do not exist on Android. - bool IsAppPartiallyInstalledForSiteUrl(const GURL& site_url) const override; - protected: // AppBannerManager overrides. std::string GetAppIdentifier() override; @@ -135,6 +130,13 @@ bool IsRelatedNonWebAppInstalled( const blink::Manifest::RelatedApplication& related_app) const override; bool IsWebAppConsideredInstalled() const override; + bool IsAppFullyInstalledForSiteUrl(const GURL& site_url) const override; + // Locally installed apps do not exist on Android. + bool IsAppPartiallyInstalledForSiteUrl(const GURL& site_url) const override; + void SaveInstallationDismissedForMl(const GURL& manifest_id) override; + void SaveInstallationIgnoredForMl(const GURL& manifest_id) override; + void SaveInstallationAcceptedForMl(const GURL& manifest_id) override; + bool IsMlPromotionBlockedByHistoryGuardrail(const GURL& manifest_id) override; void CheckEngagementForAmbientBadge();
diff --git a/components/webapps/browser/banners/app_banner_manager.h b/components/webapps/browser/banners/app_banner_manager.h index 0810e87..a1ff6c53 100644 --- a/components/webapps/browser/banners/app_banner_manager.h +++ b/components/webapps/browser/banners/app_banner_manager.h
@@ -235,6 +235,15 @@ virtual bool IsAppPartiallyInstalledForSiteUrl( const GURL& site_url) const = 0; + // The user has ignored the installation dialog and it went away due to + // another interaction (e.g. the tab was changed, page navigated, etc). + virtual void SaveInstallationIgnoredForMl(const GURL& manifest_id) = 0; + // The user has taken active action on the dialog to make it go away. + virtual void SaveInstallationDismissedForMl(const GURL& manifest_id) = 0; + virtual void SaveInstallationAcceptedForMl(const GURL& manifest_id) = 0; + virtual bool IsMlPromotionBlockedByHistoryGuardrail( + const GURL& manifest_id) = 0; + protected: explicit AppBannerManager(content::WebContents* web_contents); ~AppBannerManager() override;
diff --git a/components/webapps/browser/installable/ml_installability_promoter.cc b/components/webapps/browser/installable/ml_installability_promoter.cc index 1e9cc89..716258f 100644 --- a/components/webapps/browser/installable/ml_installability_promoter.cc +++ b/components/webapps/browser/installable/ml_installability_promoter.cc
@@ -191,8 +191,9 @@ site_quality_metrics_.favicons_count = candidates.size(); } -void MLInstallabilityPromoter::OnRegistrationCompleted(const GURL& pattern) { - if (!content::ServiceWorkerContext::ScopeMatches(pattern, site_url_)) { +void MLInstallabilityPromoter::OnRegistrationStored(int64_t registration_id, + const GURL& scope) { + if (!content::ServiceWorkerContext::ScopeMatches(scope, site_url_)) { return; }
diff --git a/components/webapps/browser/installable/ml_installability_promoter.h b/components/webapps/browser/installable/ml_installability_promoter.h index 110a5f2..0d985712 100644 --- a/components/webapps/browser/installable/ml_installability_promoter.h +++ b/components/webapps/browser/installable/ml_installability_promoter.h
@@ -98,7 +98,8 @@ const std::vector<blink::mojom::FaviconURLPtr>& candidates) override; // content::ServiceWorkerContextObserver overrides - void OnRegistrationCompleted(const GURL& pattern) override; + void OnRegistrationStored(int64_t registration_id, + const GURL& scope) override; void OnDestruct(content::ServiceWorkerContext* context) override; // This proceeds the ML pipeline only if:
diff --git a/components/webauthn/android/BUILD.gn b/components/webauthn/android/BUILD.gn index 824de4b0..c049eb9 100644 --- a/components/webauthn/android/BUILD.gn +++ b/components/webauthn/android/BUILD.gn
@@ -39,6 +39,7 @@ "//base:jni_java", "//build/android:build_java", "//components/externalauth/android:java", + "//components/password_manager/core/common:features", "//components/payments/content/android:feature_list_java", "//components/version_info/android:version_constants_java", "//content/public/android:content_java",
diff --git a/components/webauthn/android/DEPS b/components/webauthn/android/DEPS index 06c84d0..39d51de 100644 --- a/components/webauthn/android/DEPS +++ b/components/webauthn/android/DEPS
@@ -1,6 +1,7 @@ include_rules = [ "+components/cbor", "+components/externalauth/android/java", + "+components/password_manager/core/common", "+content/public/android/java", "+content/public/browser", "+device/fido",
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java index f99178a..2a97b9c 100644 --- a/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java +++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/Fido2CredentialRequest.java
@@ -65,6 +65,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.Set; /** * Uses the Google Play Services Fido2 APIs. @@ -77,6 +78,7 @@ ComponentName.createRelative("com.google.android.gms", ".auth.api.credentials.credman.service.PasswordAndPasskeyService"); private static final String CHANNEL_KEY = "com.android.chrome.CHANNEL"; + private static final String TYPE_PASSKEY = CRED_MAN_PREFIX + "TYPE_PUBLIC_KEY_CREDENTIAL"; static final String NON_EMPTY_ALLOWLIST_ERROR_MSG = "Authentication request must have non-empty allowList"; static final String NON_VALID_ALLOWED_CREDENTIALS_ERROR_MSG = @@ -261,7 +263,7 @@ prefetchCredentialsViaCredMan( options, callerOrigin, callerOriginString, clientDataHash); } else { - getCredentialViaCredMan(options, callerOrigin); + getCredentialViaCredMan(options, callerOrigin, /*requestPasswords=*/false); } return; } @@ -887,11 +889,9 @@ try { final Class createCredentialRequestBuilder = credManCreateRequestBuilderClass(); - final Object builder = - createCredentialRequestBuilder - .getConstructor(String.class, Bundle.class, Bundle.class) - .newInstance(CRED_MAN_PREFIX + "TYPE_PUBLIC_KEY_CREDENTIAL", - requestBundle, requestBundle); + final Object builder = createCredentialRequestBuilder + .getConstructor(String.class, Bundle.class, Bundle.class) + .newInstance(TYPE_PASSKEY, requestBundle, requestBundle); final Class builderClass = builder.getClass(); builderClass.getMethod("setAlwaysSendAppInfoToProvider", boolean.class) .invoke(builder, true); @@ -936,7 +936,8 @@ * TODO: update the version code to U when Chromium builds with Android 14 SDK. */ @RequiresApi(Build.VERSION_CODES.TIRAMISU) - private void getCredentialViaCredMan(PublicKeyCredentialRequestOptions options, Origin origin) { + private void getCredentialViaCredMan( + PublicKeyCredentialRequestOptions options, Origin origin, boolean requestPasswords) { final Context context = ContextUtils.getApplicationContext(); // The Android 14 APIs have to be called via reflection until Chromium @@ -980,11 +981,13 @@ return; } Bundle data; + String type; try { Object credential = getCredentialResponse.getClass() .getMethod("getCredential") .invoke(getCredentialResponse); data = (Bundle) credential.getClass().getMethod("getData").invoke(credential); + type = (String) credential.getClass().getMethod("getType").invoke(credential); } catch (ReflectiveOperationException e) { Log.e(TAG, "Reflection failed; are you running on Android 14?", e); @@ -996,6 +999,12 @@ return; } + if (!TYPE_PASSKEY.equals(type)) { + // TODO(crbug/1434278): Implement password handling logic. + notifyBrowserOnCredManClosed(true); + return; + } + String json = data.getString(CRED_MAN_PREFIX + "BUNDLE_KEY_AUTHENTICATION_RESPONSE_JSON"); byte[] responseSerialized = @@ -1042,7 +1051,8 @@ mConditionalUiState = options.isConditional ? ConditionalUiState.REQUEST_SENT_TO_PLATFORM : ConditionalUiState.NONE; try { - final Object getCredentialRequest = buildGetCredentialRequest(options, origin); + final Object getCredentialRequest = + buildGetCredentialRequest(options, origin, requestPasswords); if (getCredentialRequest == null) { mConditionalUiState = options.isConditional ? ConditionalUiState.WAITING_FOR_SELECTION @@ -1123,51 +1133,34 @@ } assert mConditionalUiState == ConditionalUiState.WAITING_FOR_CREDENTIAL_LIST; boolean hasPublicKeyCredentials; - boolean hasPasswordCredentials; - boolean hasRemoteResults; - Object pendingGetCredentialHandle; try { Method hasCredentialResultsMethod = prepareGetCredentialResponse.getClass().getMethod( "hasCredentialResults", String.class); hasPublicKeyCredentials = (Boolean) hasCredentialResultsMethod.invoke( - prepareGetCredentialResponse, - "androidx.credentials.TYPE_PUBLIC_KEY_CREDENTIAL"); - hasPasswordCredentials = (Boolean) hasCredentialResultsMethod.invoke( - prepareGetCredentialResponse, - "android.credentials.TYPE_PASSWORD_CREDENTIAL"); - hasRemoteResults = (Boolean) prepareGetCredentialResponse.getClass() - .getMethod("hasRemoteResults") - .invoke(prepareGetCredentialResponse); - pendingGetCredentialHandle = prepareGetCredentialResponse.getClass() - .getMethod("getPendingGetCredentialHandle") - .invoke(prepareGetCredentialResponse); + prepareGetCredentialResponse, TYPE_PASSKEY); } catch (ReflectiveOperationException e) { Log.e(TAG, "Reflection failed; are you running on Android 14?", e); mConditionalUiState = ConditionalUiState.NONE; returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); return; } - if (pendingGetCredentialHandle == null) { - Log.e(TAG, "prepareGetCredentialResponse is null."); - mConditionalUiState = ConditionalUiState.NONE; - returnErrorAndResetCallback(AuthenticatorStatus.UNKNOWN_ERROR); - return; - } if (mBrowserBridge == null) { mBrowserBridge = new WebAuthnBrowserBridge(); }; mConditionalUiState = ConditionalUiState.WAITING_FOR_SELECTION; mBrowserBridge.onCredManConditionalRequestPending(mFrameHost, - hasPasswordCredentials || hasPublicKeyCredentials || hasRemoteResults, - () -> getCredentialViaCredMan(options, origin)); + hasPublicKeyCredentials, + (requestPasswords) + -> getCredentialViaCredMan(options, origin, requestPasswords)); } }; try { mConditionalUiState = ConditionalUiState.WAITING_FOR_CREDENTIAL_LIST; - final Object getCredentialRequest = buildGetCredentialRequest(options, origin); + final Object getCredentialRequest = + buildGetCredentialRequest(options, origin, /*requestPasswords=*/false); if (getCredentialRequest == null) { mConditionalUiState = ConditionalUiState.NONE; returnErrorAndResetCallback(AuthenticatorStatus.NOT_ALLOWED_ERROR); @@ -1190,7 +1183,7 @@ } private Object buildGetCredentialRequest(PublicKeyCredentialRequestOptions options, - Origin origin) throws ReflectiveOperationException { + Origin origin, boolean requestPasswords) throws ReflectiveOperationException { final String requestAsJson = Fido2CredentialRequestJni.get().getOptionsToJson(options.serialize()); @@ -1206,15 +1199,14 @@ Bundle publicKeyCredentialOptionBundle = buildPublicKeyCredentialOptionBundle(requestAsJson, clientDataHash); - // Build the CredentialOption: + // Build the CredentialOption for passkeys: Object credentialOption; try { final Class<?> credentialOptionBuilderClass = credManCredentialOptionBuilderClass(); final Object credentialOptionBuilder = credentialOptionBuilderClass .getConstructor(String.class, Bundle.class, Bundle.class) - .newInstance(CRED_MAN_PREFIX + "TYPE_PUBLIC_KEY_CREDENTIAL", - publicKeyCredentialOptionBundle, + .newInstance(TYPE_PASSKEY, publicKeyCredentialOptionBundle, publicKeyCredentialOptionBundle); credentialOption = credentialOptionBuilderClass.getMethod("build").invoke(credentialOptionBuilder); @@ -1224,8 +1216,7 @@ credentialOption = Class.forName("android.credentials.CredentialOption") .getConstructor(String.class, Bundle.class, Bundle.class, Boolean.TYPE) - .newInstance(CRED_MAN_PREFIX + "TYPE_PUBLIC_KEY_CREDENTIAL", - publicKeyCredentialOptionBundle, + .newInstance(TYPE_PASSKEY, publicKeyCredentialOptionBundle, publicKeyCredentialOptionBundle, false); } @@ -1241,6 +1232,14 @@ getCredentialRequestBuilderClass .getMethod("addCredentialOption", credentialOption.getClass()) .invoke(getCredentialRequestBuilderObject, credentialOption); + if (requestPasswords) { + Object passwordCredentialOption = buildPasswordOption(); + if (passwordCredentialOption != null) { + getCredentialRequestBuilderClass + .getMethod("addCredentialOption", passwordCredentialOption.getClass()) + .invoke(getCredentialRequestBuilderObject, passwordCredentialOption); + } + } getCredentialRequestBuilderClass.getMethod("setOrigin", String.class) .invoke(getCredentialRequestBuilderObject, convertOriginToString(origin)); return getCredentialRequestBuilderClass.getMethod("build").invoke( @@ -1313,6 +1312,35 @@ return null; } + private Object buildPasswordOption() throws ReflectiveOperationException { + Object passwordCredentialOption; + Bundle passwordOptionBundle = new Bundle(); + passwordOptionBundle.putString(CHANNEL_KEY, getChannel()); + + try { + final Class<?> credentialOptionBuilderClass = credManCredentialOptionBuilderClass(); + final Object credentialOptionBuilder = + credentialOptionBuilderClass + .getConstructor(String.class, Bundle.class, Bundle.class) + .newInstance("android.credentials.TYPE_PASSWORD_CREDENTIAL", + passwordOptionBundle, passwordOptionBundle); + credentialOptionBuilderClass.getMethod("setAllowedProviders", Set.class) + .invoke(credentialOptionBuilder, Set.of(GPM_COMPONENT_NAME)); + passwordCredentialOption = + credentialOptionBuilderClass.getMethod("build").invoke(credentialOptionBuilder); + + } catch (ClassNotFoundException e) { + // In order to be compatible with Android 14 Beta 1, the older + // form of the call is also tried. + passwordCredentialOption = + Class.forName("android.credentials.CredentialOption") + .getConstructor(String.class, Bundle.class, Bundle.class, Boolean.TYPE) + .newInstance("android.credentials.TYPE_PASSWORD_CREDENTIAL", + passwordOptionBundle, passwordOptionBundle, false); + } + return passwordCredentialOption; + } + @VisibleForTesting @NativeMethods public interface Natives {
diff --git a/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnBrowserBridge.java b/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnBrowserBridge.java index 56ce1fa..63bca6d8 100644 --- a/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnBrowserBridge.java +++ b/components/webauthn/android/java/src/org/chromium/components/webauthn/WebAuthnBrowserBridge.java
@@ -63,7 +63,7 @@ * completed conditional request. */ public void onCredManConditionalRequestPending( - RenderFrameHost frameHost, boolean hasResults, Runnable fullAssertion) { + RenderFrameHost frameHost, boolean hasResults, Callback<Boolean> fullAssertion) { if (mNativeWebAuthnBrowserBridge == 0) { mNativeWebAuthnBrowserBridge = WebAuthnBrowserBridgeJni.get().createNativeWebAuthnBrowserBridge( @@ -134,7 +134,7 @@ RenderFrameHost frameHost, boolean isConditionalRequest, Callback<byte[]> getAssertionCallback, Runnable hybridCallback); void onCredManConditionalRequestPending(long nativeWebAuthnBrowserBridge, - RenderFrameHost frameHost, boolean hasResults, Runnable fullAssertion); + RenderFrameHost frameHost, boolean hasResults, Callback<Boolean> fullAssertion); void onCredManUiClosed( long nativeWebAuthnBrowserBridge, RenderFrameHost frameHost, boolean success); void cleanupRequest(long nativeWebAuthnBrowserBridge, RenderFrameHost frameHost);
diff --git a/components/webauthn/android/webauthn_browser_bridge.cc b/components/webauthn/android/webauthn_browser_bridge.cc index a81577bc..ba4abf3 100644 --- a/components/webauthn/android/webauthn_browser_bridge.cc +++ b/components/webauthn/android/webauthn_browser_bridge.cc
@@ -132,8 +132,10 @@ } void TriggerFullRequest( - const base::android::JavaRef<jobject>& jfull_request_runnable) { - base::android::RunRunnableAndroid(jfull_request_runnable); + const base::android::JavaRef<jobject>& jfull_request_runnable, + bool request_passwords) { + base::android::RunBooleanCallbackAndroid(jfull_request_runnable, + request_passwords); } void WebAuthnBrowserBridge::OnCredManConditionalRequestPending(
diff --git a/components/webauthn/android/webauthn_client_android.cc b/components/webauthn/android/webauthn_client_android.cc index 125fd567..dee8922e 100644 --- a/components/webauthn/android/webauthn_client_android.cc +++ b/components/webauthn/android/webauthn_client_android.cc
@@ -34,7 +34,7 @@ void WebAuthnClientAndroid::OnCredManConditionalRequestPending( content::RenderFrameHost* render_frame_host, bool has_results, - base::RepeatingClosure full_assertion_request) { + base::RepeatingCallback<void(bool)> full_assertion_request) { auto* cred_man_delegate = WebAuthnCredManDelegate::GetRequestDelegate( content::WebContents::FromRenderFrameHost(render_frame_host)); cred_man_delegate->OnCredManConditionalRequestPending(
diff --git a/components/webauthn/android/webauthn_client_android.h b/components/webauthn/android/webauthn_client_android.h index a22bf83..e5d4b33 100644 --- a/components/webauthn/android/webauthn_client_android.h +++ b/components/webauthn/android/webauthn_client_android.h
@@ -49,7 +49,7 @@ void OnCredManConditionalRequestPending( content::RenderFrameHost* render_frame_host, bool has_results, - base::RepeatingClosure full_assertion_request); + base::RepeatingCallback<void(bool)> full_assertion_request); // Called when a CredMan sheet is closed. This can happen if the user // dismissed the UI, selected a credential, or if there are errors. Android U+
diff --git a/components/webauthn/android/webauthn_cred_man_delegate.cc b/components/webauthn/android/webauthn_cred_man_delegate.cc index 6b03cc1..aae900c 100644 --- a/components/webauthn/android/webauthn_cred_man_delegate.cc +++ b/components/webauthn/android/webauthn_cred_man_delegate.cc
@@ -12,6 +12,7 @@ #include "base/memory/raw_ptr.h" #include "base/notreached.h" #include "base/supports_user_data.h" +#include "components/password_manager/core/common/password_manager_features.h" #include "content/public/browser/web_contents.h" #include "device/fido/features.h" @@ -28,7 +29,7 @@ void WebAuthnCredManDelegate::OnCredManConditionalRequestPending( content::RenderFrameHost* render_frame_host, bool has_results, - base::RepeatingClosure full_assertion_request) { + base::RepeatingCallback<void(bool)> full_assertion_request) { has_results_ = has_results; full_assertion_request_ = std::move(full_assertion_request); } @@ -44,7 +45,9 @@ OnCredManUiClosed(false); return; } - full_assertion_request_.Run(); + + full_assertion_request_.Run(base::FeatureList::IsEnabled( + password_manager::features::kPasswordsInCredMan)); } bool WebAuthnCredManDelegate::HasResults() {
diff --git a/components/webauthn/android/webauthn_cred_man_delegate.h b/components/webauthn/android/webauthn_cred_man_delegate.h index 62a092a9..0777b1e 100644 --- a/components/webauthn/android/webauthn_cred_man_delegate.h +++ b/components/webauthn/android/webauthn_cred_man_delegate.h
@@ -31,7 +31,7 @@ void OnCredManConditionalRequestPending( content::RenderFrameHost* render_frame_host, bool has_results, - base::RepeatingClosure full_assertion_request); + base::RepeatingCallback<void(bool)> full_assertion_request); // Called when the CredMan UI is closed. void OnCredManUiClosed(bool success); @@ -61,7 +61,7 @@ private: bool has_results_ = false; - base::RepeatingClosure full_assertion_request_; + base::RepeatingCallback<void(bool)> full_assertion_request_; base::RepeatingCallback<void(bool)> request_completion_callback_; };
diff --git a/components/webauthn/android/webauthn_cred_man_delegate_unittest.cc b/components/webauthn/android/webauthn_cred_man_delegate_unittest.cc index 1770426..590e205 100644 --- a/components/webauthn/android/webauthn_cred_man_delegate_unittest.cc +++ b/components/webauthn/android/webauthn_cred_man_delegate_unittest.cc
@@ -23,24 +23,24 @@ }; TEST_F(WebAuthnCredManDelegateTest, FullRequestNotRunAfterCleanup) { - base::MockRepeatingClosure closure; - EXPECT_CALL(closure, Run()).Times(0); + base::MockCallback<base::RepeatingCallback<void(bool)>> closure; + EXPECT_CALL(closure, Run(testing::_)).Times(0); delegate()->OnCredManConditionalRequestPending(nullptr, true, closure.Get()); - EXPECT_CALL(closure, Run()).Times(1); + EXPECT_CALL(closure, Run(false)).Times(1); delegate()->TriggerFullRequest(); - EXPECT_CALL(closure, Run()).Times(0); + EXPECT_CALL(closure, Run(false)).Times(0); delegate()->CleanUpConditionalRequest(); - EXPECT_CALL(closure, Run()).Times(0); + EXPECT_CALL(closure, Run(false)).Times(0); delegate()->TriggerFullRequest(); } TEST_F(WebAuthnCredManDelegateTest, RequestCompletionCallbackRun) { base::MockCallback<base::RepeatingCallback<void(bool)>> mock_request_completion_callback; - base::MockRepeatingClosure mock_full_request; + base::MockCallback<base::RepeatingCallback<void(bool)>> mock_full_request; delegate()->SetRequestCompletionCallback( mock_request_completion_callback.Get());
diff --git a/components/webxr/mailbox_to_surface_bridge_impl.cc b/components/webxr/mailbox_to_surface_bridge_impl.cc index 3a70c35d..1a77219 100644 --- a/components/webxr/mailbox_to_surface_bridge_impl.cc +++ b/components/webxr/mailbox_to_surface_bridge_impl.cc
@@ -270,6 +270,9 @@ } void MailboxToSurfaceBridgeImpl::ResizeSurface(int width, int height) { + // Make sure we have the surface. + CHECK(surface_handle_); + surface_width_ = width; surface_height_ = height;
diff --git a/components/webxr/mailbox_to_surface_bridge_impl.h b/components/webxr/mailbox_to_surface_bridge_impl.h index 07023233..f6453da 100644 --- a/components/webxr/mailbox_to_surface_bridge_impl.h +++ b/components/webxr/mailbox_to_surface_bridge_impl.h
@@ -95,6 +95,7 @@ // in the same class like this. base::OnceClosure on_context_bound_; + // Only initialized if we have Surface (i.e surface_handle_ is not null). int surface_width_ = 0; int surface_height_ = 0;
diff --git a/content/app/content_main_runner_impl.cc b/content/app/content_main_runner_impl.cc index b2b8c2d..a068f7a 100644 --- a/content/app/content_main_runner_impl.cc +++ b/content/app/content_main_runner_impl.cc
@@ -1242,7 +1242,7 @@ #endif if (start_minimal_browser) - ForceInProcessNetworkService(true); + ForceInProcessNetworkService(); discardable_shared_memory_manager_ = std::make_unique<discardable_memory::DiscardableSharedMemoryManager>();
diff --git a/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h index df7044c..e2bb90c1 100644 --- a/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h +++ b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.h
@@ -31,6 +31,14 @@ + (instancetype)sharedInstance; +// Returns YES if the specified version is less than 13.0 or more than 13.2. +// Manual occlusion detection is not supported on macOS 13.0-13.2. ++ (BOOL)manualOcclusionDetectionSupportedForVersion:(int32_t)major + :(int32_t)minor; + +// Returns YES if manual occlusion detection is supported for the current macOS. ++ (BOOL)manualOcclusionDetectionSupportedForCurrentMacOSVersion; + // API exposed for testing. // Resets the state of `sharedInstance` during tests.
diff --git a/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm index 1ec68c9..9402e6c 100644 --- a/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm +++ b/content/app_shim_remote_cocoa/web_contents_occlusion_checker_mac.mm
@@ -15,6 +15,7 @@ #import "base/mac/scoped_objc_class_swizzler.h" #include "base/metrics/field_trial_params.h" #include "base/no_destructor.h" +#include "base/system/sys_info.h" #include "content/public/browser/content_browser_client.h" #include "content/public/common/content_client.h" #include "content/public/common/content_features.h" @@ -24,8 +25,6 @@ // Experiment features. const base::FeatureParam<bool> kEnhancedWindowOcclusionDetection{ &kMacWebContentsOcclusion, "EnhancedWindowOcclusionDetection", false}; -const base::FeatureParam<bool> kDisplaySleepAndAppHideDetection{ - &kMacWebContentsOcclusion, "DisplaySleepAndAppHideDetection", false}; namespace { @@ -82,6 +81,25 @@ return sharedInstance->get(); } ++ (BOOL)manualOcclusionDetectionSupportedForVersion:(int32_t)major + :(int32_t)minor { + if (major != 13) { + return YES; + } + + return minor >= 3; +} + ++ (BOOL)manualOcclusionDetectionSupportedForCurrentMacOSVersion { + int32_t major_version; + int32_t minor_version; + int32_t bugfix_version; + base::SysInfo::OperatingSystemVersionNumbers(&major_version, &minor_version, + &bugfix_version); + return [self manualOcclusionDetectionSupportedForVersion: + major_version:minor_version]; +} + + (void)resetSharedInstanceForTesting { [self sharedOcclusionChecker]->reset(); } @@ -125,6 +143,12 @@ return _windowClassSwizzler.get(); } +- (BOOL)isManualOcclusionDetectionEnabled { + return [WebContentsOcclusionCheckerMac + manualOcclusionDetectionSupportedForCurrentMacOSVersion] && + kEnhancedWindowOcclusionDetection.Get(); +} + // Alternative implementation of orderWindow:relativeTo:. Replaces // NSWindow's version, allowing the occlusion checker to learn about // window ordering events. @@ -135,8 +159,10 @@ ->InvokeOriginal<void, NSWindowOrderingMode, NSInteger>( self, _cmd, orderingMode, otherWindowNumber); - if (!kEnhancedWindowOcclusionDetection.Get()) + if (![[WebContentsOcclusionCheckerMac sharedInstance] + isManualOcclusionDetectionEnabled]) { return; + } [[NSNotificationCenter defaultCenter] postNotificationName:kWindowDidChangePositionInWindowList @@ -148,7 +174,7 @@ NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter]; - if (kEnhancedWindowOcclusionDetection.Get()) { + if ([self isManualOcclusionDetectionEnabled]) { [notificationCenter addObserver:self selector:@selector(windowWillMove:) name:NSWindowWillMoveNotification @@ -174,6 +200,17 @@ selector:@selector(windowDidChangePositionInWindowList:) name:kWindowDidChangePositionInWindowList object:nil]; + + [[[NSWorkspace sharedWorkspace] notificationCenter] + addObserver:self + selector:@selector(displaysDidSleep:) + name:NSWorkspaceScreensDidSleepNotification + object:nil]; + [[[NSWorkspace sharedWorkspace] notificationCenter] + addObserver:self + selector:@selector(displaysDidWake:) + name:NSWorkspaceScreensDidWakeNotification + object:nil]; } [notificationCenter addObserver:self @@ -197,19 +234,6 @@ selector:@selector(fullscreenTransitionComplete:) name:NSWindowDidExitFullScreenNotification object:nil]; - - if (kDisplaySleepAndAppHideDetection.Get()) { - [[[NSWorkspace sharedWorkspace] notificationCenter] - addObserver:self - selector:@selector(displaysDidSleep:) - name:NSWorkspaceScreensDidSleepNotification - object:nil]; - [[[NSWorkspace sharedWorkspace] notificationCenter] - addObserver:self - selector:@selector(displaysDidWake:) - name:NSWorkspaceScreensDidWakeNotification - object:nil]; - } } - (BOOL)windowCanTriggerOcclusionUpdates:(NSWindow*)window { @@ -400,9 +424,8 @@ return YES; } - // If manual occlusion detection is disabled in the experiement, return the - // answer from macOS. - if (!kEnhancedWindowOcclusionDetection.Get()) { + // If manual occlusion detection is disabled, return the answer from macOS. + if (![self isManualOcclusionDetectionEnabled]) { return NO; }
diff --git a/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm b/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm index fdf66fe1..147a590 100644 --- a/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm +++ b/content/app_shim_remote_cocoa/window_occlusion_browsertest_mac.mm
@@ -25,9 +25,13 @@ const int kNeverCalled = -100; struct FeatureState { - bool feature_enabled = false; bool enhanced_occlusion_detection_enabled = false; - bool display_sleep_detection_enabled = false; +}; + +struct Version { + int32_t major; + int32_t minor; + bool supported; }; } // namespace @@ -141,6 +145,8 @@ - (instancetype)init { self = [super init]; + // The tests should access WebContentsOcclusionCheckerMac directly, rather + // than through NSClassFromString(). See crbug.com/1450724 . [WebContentVisibilityUpdateWatcher performOcclusionStateUpdatesSwizzler] .reset(new base::mac::ScopedObjCClassSwizzler( NSClassFromString(@"WebContentsOcclusionCheckerMac"), @@ -329,12 +335,9 @@ public ContentBrowserTest { public: WindowOcclusionBrowserTestMac() { - if (GetParam().feature_enabled) { + if (GetParam().enhanced_occlusion_detection_enabled) { base::FieldTrialParams params; - if (GetParam().enhanced_occlusion_detection_enabled) - params["EnhancedWindowOcclusionDetection"] = "true"; - if (GetParam().display_sleep_detection_enabled) - params["DisplaySleepAndAppHideDetection"] = "true"; + params["EnhancedWindowOcclusionDetection"] = "true"; _features.InitAndEnableFeatureWithParameters( features::kMacWebContentsOcclusion, params); } else { @@ -343,9 +346,10 @@ } void SetUp() override { - if (base::mac::IsAtLeastOS13()) { + if (![NSClassFromString(@"WebContentsOcclusionCheckerMac") + manualOcclusionDetectionSupportedForCurrentMacOSVersion]) { GTEST_SKIP() - << "Manual window occlusion detection is broken on macOS Ventura."; + << "Manual window occlusion detection is broken on macOS 13.0-13.2."; } ContentBrowserTest::SetUp(); } @@ -467,8 +471,7 @@ void OrderWindowFront(NSWindow* window) { base::scoped_nsobject<WebContentVisibilityUpdateCounter> watcher; - if (!kEnhancedWindowOcclusionDetection.Get() && - !kDisplaySleepAndAppHideDetection.Get()) { + if (!kEnhancedWindowOcclusionDetection.Get()) { watcher.reset([[WebContentVisibilityUpdateCounter alloc] init]); } @@ -477,8 +480,6 @@ if (kEnhancedWindowOcclusionDetection.Get()) { WaitForOcclusionUpdate(); - } else if (!kDisplaySleepAndAppHideDetection.Get()) { - EXPECT_TRUE([WebContentVisibilityUpdateCounter methodNeverCalled]); } } @@ -569,55 +570,45 @@ WindowOcclusionBrowserTestMac; using WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature = WindowOcclusionBrowserTestMac; -using WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature = - WindowOcclusionBrowserTestMac; // Tests that should only work without the occlusion detection feature. -INSTANTIATE_TEST_SUITE_P( - NoFeature, - WindowOcclusionBrowserTestMacWithoutOcclusionFeature, - ::testing::Values(FeatureState{.feature_enabled = false}, - // Feature should be a no-op without parameters. - FeatureState{.feature_enabled = true})); +INSTANTIATE_TEST_SUITE_P(NoFeature, + WindowOcclusionBrowserTestMacWithoutOcclusionFeature, + ::testing::Values(FeatureState{ + .enhanced_occlusion_detection_enabled = false})); // Tests that should work with or without the occlusion detection feature. INSTANTIATE_TEST_SUITE_P( Common, WindowOcclusionBrowserTestMac, - ::testing::Values(FeatureState{.feature_enabled = false}, - FeatureState{.feature_enabled = true}, - FeatureState{ - .feature_enabled = true, - .enhanced_occlusion_detection_enabled = true}, - FeatureState{.feature_enabled = true, - .display_sleep_detection_enabled = true}, - FeatureState{.feature_enabled = true, - .enhanced_occlusion_detection_enabled = true, - .display_sleep_detection_enabled = true})); + ::testing::Values( + FeatureState{.enhanced_occlusion_detection_enabled = false}, + FeatureState{.enhanced_occlusion_detection_enabled = true})); // Tests that require enhanced window occlusion detection. INSTANTIATE_TEST_SUITE_P( EnhancedWindowOcclusionDetection, WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, - ::testing::Values( - FeatureState{.feature_enabled = true, - .enhanced_occlusion_detection_enabled = true}, - FeatureState{.feature_enabled = true, - .enhanced_occlusion_detection_enabled = true, - .display_sleep_detection_enabled = true})); + ::testing::Values(FeatureState{ + .enhanced_occlusion_detection_enabled = true})); -// Tests that require display sleep and app hide detection. -INSTANTIATE_TEST_SUITE_P( - DisplaySleepAndAppHideDetection, - WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature, - ::testing::Values(FeatureState{.feature_enabled = true, - .display_sleep_detection_enabled = true}, - FeatureState{.feature_enabled = true, - .enhanced_occlusion_detection_enabled = true, - .display_sleep_detection_enabled = true})); +// Tests that we correctly disallow unsupported macOS versions. +IN_PROC_BROWSER_TEST_P(WindowOcclusionBrowserTestMac, MacOSVersionChecking) { + Class WebContentsOcclusionCheckerMac = + NSClassFromString(@"WebContentsOcclusionCheckerMac"); + std::vector<Version> versions = { + {11, 0, true}, {12, 0, true}, {12, 9, true}, {13, 0, false}, + {13, 1, false}, {13, 2, false}, {13, 3, true}, {14, 0, true}}; -// Test that enhanced occlusion detection doesn't work if the feature's not -// enabled. + for (const auto& version : versions) { + bool supported = [WebContentsOcclusionCheckerMac manualOcclusionDetectionSupportedForVersion:version.major + :version.minor]; + EXPECT_EQ(supported, version.supported); + } +} + +// Tests that enhanced occlusion detection isn't triggered if the feature's +// not enabled. IN_PROC_BROWSER_TEST_P(WindowOcclusionBrowserTestMacWithoutOcclusionFeature, ManualOcclusionDetectionDisabled) { InitWindowA(); @@ -820,7 +811,7 @@ // Checks that web contents are marked kHidden on display sleep. IN_PROC_BROWSER_TEST_P( - WindowOcclusionBrowserTestMacWithDisplaySleepDetectionFeature, + WindowOcclusionBrowserTestMacWithOcclusionDetectionFeature, OcclusionDetectionOnDisplaySleep) { InitWindowA();
diff --git a/content/browser/BUILD.gn b/content/browser/BUILD.gn index 4209a49..5778ced 100644 --- a/content/browser/BUILD.gn +++ b/content/browser/BUILD.gn
@@ -375,8 +375,6 @@ "accessibility/one_shot_accessibility_tree_search.h", "accessibility/render_accessibility_host.cc", "accessibility/render_accessibility_host.h", - "accessibility/touch_passthrough_manager.cc", - "accessibility/touch_passthrough_manager.h", "accessibility/web_ax_platform_tree_manager_delegate.h", "accessibility/web_contents_accessibility.h", "after_startup_task_utils.cc", @@ -1371,6 +1369,8 @@ "network/network_errors_listing_ui.h", "network/network_quality_observer_impl.cc", "network/network_quality_observer_impl.h", + "network/network_service_util_internal.cc", + "network/network_service_util_internal.h", "network/reporting_service_proxy.cc", "network/reporting_service_proxy.h", "network/shared_dictionary_util.cc", @@ -2090,6 +2090,8 @@ "shared_storage/shared_storage_document_service_impl.h", "shared_storage/shared_storage_event_params.cc", "shared_storage/shared_storage_event_params.h", + "shared_storage/shared_storage_header_observer.cc", + "shared_storage/shared_storage_header_observer.h", "shared_storage/shared_storage_render_thread_worklet_driver.cc", "shared_storage/shared_storage_render_thread_worklet_driver.h", "shared_storage/shared_storage_url_loader_factory_proxy.cc",
diff --git a/content/browser/accessibility/browser_accessibility_cocoa.h b/content/browser/accessibility/browser_accessibility_cocoa.h index acdffba..7da79adb 100644 --- a/content/browser/accessibility/browser_accessibility_cocoa.h +++ b/content/browser/accessibility/browser_accessibility_cocoa.h
@@ -42,14 +42,6 @@ // Returns true if the given object is an NSRange instance. bool IsNSRange(id value); -// Returns an AXTextMarker representing the given position in the tree. -id AXTextMarkerFrom(const BrowserAccessibilityCocoa* anchor, - int offset, - ax::mojom::TextAffinity affinity); - -// Returns an AXTextMarkerRange that spans the given AXTextMarkers. -id AXTextMarkerRangeFrom(id anchor_text_marker, id focus_text_marker); - } // namespace content // BrowserAccessibilityCocoa is a cocoa wrapper around the BrowserAccessibility
diff --git a/content/browser/accessibility/browser_accessibility_mac.mm b/content/browser/accessibility/browser_accessibility_mac.mm index 17e743e7..b5b7dc8 100644 --- a/content/browser/accessibility/browser_accessibility_mac.mm +++ b/content/browser/accessibility/browser_accessibility_mac.mm
@@ -7,6 +7,7 @@ #import "content/browser/accessibility/browser_accessibility_mac.h" #include "base/debug/stack_trace.h" +#include "base/memory/scoped_policy.h" #import "base/task/single_thread_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" @@ -69,7 +70,7 @@ // because we need to retrieve some information from the old wrapper in order // to add it to the new one, e.g. its list of children. base::scoped_nsobject<AXPlatformNodeCocoa> old_native_obj( - platform_node_->ReleaseNativeWrapper()); + platform_node_->ReleaseNativeWrapper(), base::scoped_policy::RETAIN); // We should have never called this method if a native wrapper has not been // created, but keep a null check just in case.
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.cc b/content/browser/accessibility/browser_accessibility_manager_android.cc index ab8205f..01ac79f 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.cc +++ b/content/browser/accessibility/browser_accessibility_manager_android.cc
@@ -611,40 +611,6 @@ wcax->UpdateMaxNodesInCache(); } -void BrowserAccessibilityManagerAndroid::OnNodeCreated(ui::AXTree* tree, - ui::AXNode* node) { - BrowserAccessibilityManager::OnNodeCreated(tree, node); - if (node->data().GetBoolAttribute( - ax::mojom::BoolAttribute::kTouchPassthrough)) { - auto* root = static_cast<BrowserAccessibilityManagerAndroid*>( - GetManagerForRootFrame()); - if (root) - root->EnableTouchPassthrough(); - else - EnableTouchPassthrough(); - } -} - -void BrowserAccessibilityManagerAndroid::OnBoolAttributeChanged( - ui::AXTree* tree, - ui::AXNode* node, - ax::mojom::BoolAttribute attr, - bool new_value) { - BrowserAccessibilityManager::OnBoolAttributeChanged(tree, node, attr, - new_value); - if (new_value && attr == ax::mojom::BoolAttribute::kTouchPassthrough) { - // TODO(accessibility): there's a tiny chance we could get this - // called on an iframe before it's attached to the root frame manager. - // If this ever becomes an issue in practice, make this more robust. - auto* root = static_cast<BrowserAccessibilityManagerAndroid*>( - GetManagerForRootFrame()); - if (root) - root->EnableTouchPassthrough(); - else - EnableTouchPassthrough(); - } -} - WebContentsAccessibilityAndroid* BrowserAccessibilityManagerAndroid::GetWebContentsAXFromRootManager() { BrowserAccessibility* parent_node =
diff --git a/content/browser/accessibility/browser_accessibility_manager_android.h b/content/browser/accessibility/browser_accessibility_manager_android.h index c1880094..2b5b3c80 100644 --- a/content/browser/accessibility/browser_accessibility_manager_android.h +++ b/content/browser/accessibility/browser_accessibility_manager_android.h
@@ -127,16 +127,6 @@ // Helper method to clear AccessibilityNodeInfo cache on given node void ClearNodeInfoCacheForGivenId(int32_t unique_id); - // Only set on the root BrowserAccessibilityManager. Keeps track of if - // any node uses touch passthrough in any frame - if so, any incoming - // touch event needs to be processed for possible forwarding. This is - // just an optimization; once touch passthrough is enabled it stays - // on for this main frame until the page is reloaded. In the future if - // there's a need to optimize for touch passthrough being enabled only - // temporarily, this would need to be more sophisticated. - void EnableTouchPassthrough() { touch_passthrough_enabled_ = true; } - bool touch_passthrough_enabled() const { return touch_passthrough_enabled_; } - std::u16string GenerateAccessibilityNodeInfoString(int32_t unique_id); private: @@ -145,12 +135,8 @@ ui::AXTree* tree, bool root_changed, const std::vector<ui::AXTreeObserver::Change>& changes) override; + void OnNodeWillBeDeleted(ui::AXTree* tree, ui::AXNode* node) override; - void OnNodeCreated(ui::AXTree* tree, ui::AXNode* node) override; - void OnBoolAttributeChanged(ui::AXTree* tree, - ui::AXNode* node, - ax::mojom::BoolAttribute attr, - bool new_value) override; WebContentsAccessibilityAndroid* GetWebContentsAXFromRootManager(); @@ -174,11 +160,6 @@ // tree dumps for nodes without creating web_contents_accessibility_android. bool allow_image_descriptions_for_testing_ = false; - // Only set on the root BrowserAccessibilityManager. Keeps track of if - // any node uses touch passthrough in any frame. See comment next to - // any_node_uses_touch_passthrough(), above, for details. - bool touch_passthrough_enabled_ = false; - // An unordered_set of |unique_id| values for nodes cleared from the cache // with each atomic update to prevent superfluous cache clear calls. std::unordered_set<int32_t> nodes_already_cleared_ =
diff --git a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc index 4d361ff..5f1742c 100644 --- a/content/browser/accessibility/dump_accessibility_tree_browsertest.cc +++ b/content/browser/accessibility/dump_accessibility_tree_browsertest.cc
@@ -1408,11 +1408,6 @@ } IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, - AccessibilityAriaTouchPassthrough) { - RunAriaTest(FILE_PATH_LITERAL("aria-touchpassthrough.html")); -} - -IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, DISABLED_AccessibilityAriaTextboxWithSelection) { RunAriaTest(FILE_PATH_LITERAL("aria-textbox-with-selection.html")); }
diff --git a/content/browser/accessibility/hit_testing_browsertest.cc b/content/browser/accessibility/hit_testing_browsertest.cc index eac6036..57d049a 100644 --- a/content/browser/accessibility/hit_testing_browsertest.cc +++ b/content/browser/accessibility/hit_testing_browsertest.cc
@@ -14,7 +14,6 @@ #include "content/browser/accessibility/accessibility_tree_formatter_blink.h" #include "content/browser/accessibility/browser_accessibility.h" #include "content/browser/accessibility/browser_accessibility_manager.h" -#include "content/browser/accessibility/touch_passthrough_manager.h" #include "content/browser/web_contents/web_contents_impl.h" #include "content/public/browser/ax_inspect_factory.h" #include "content/public/browser/web_contents.h" @@ -56,8 +55,6 @@ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( switches::kForceDeviceScaleFactor, base::StringPrintf("%.2f", device_scale_factor)); - base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kEnableBlinkFeatures, "AccessibilityAriaTouchPassthrough"); } std::string AccessibilityHitTestingBrowserTest::TestPassToString::operator()( @@ -840,67 +837,4 @@ } #endif -IN_PROC_BROWSER_TEST_P(AccessibilityHitTestingBrowserTest, - AriaTouchPassthroughKeypadTap) { - ASSERT_TRUE(embedded_test_server()->Start()); - - EXPECT_TRUE(NavigateToURL(shell(), GURL(url::kAboutBlankURL))); - - AccessibilityNotificationWaiter waiter(shell()->web_contents(), - ui::kAXModeComplete, - ax::mojom::Event::kLoadComplete); - - GURL url(embedded_test_server()->GetURL( - "/accessibility/hit_testing/aria_touchpassthrough_key.html")); - EXPECT_TRUE(NavigateToURL(shell(), url)); - SynchronizeThreads(); - // TODO(https://crbug.com/1332468): Investigate why this does not return true. - ASSERT_TRUE(waiter.WaitForNotification()); - - WaitForAccessibilityTreeToContainNodeWithName(shell()->web_contents(), - "Dial"); - - BrowserAccessibility* field = FindNode(ax::mojom::Role::kTextField, ""); - ASSERT_TRUE(field); - - BrowserAccessibility* key5 = FindNode(ax::mojom::Role::kButton, "5"); - ASSERT_TRUE(key5); - - // Press on the '5' key - { - // Hit test a point within the '5' key and ensure we hit the right node. - gfx::Point key5_ctr = key5->GetClippedRootFrameBoundsRect().CenterPoint(); - LOG(ERROR) << "AXAX key5 before: " << key5_ctr.x() << ", " << key5_ctr.y(); - key5_ctr = FrameToCSSPoint(key5_ctr); - LOG(ERROR) << "AXAX key5 after: " << key5_ctr.x() << ", " << key5_ctr.y(); - BrowserAccessibility* hit_node = HitTestAndWaitForResult(key5_ctr); - ASSERT_TRUE(hit_node); - - while (hit_node && hit_node->GetRole() != ax::mojom::Role::kButton) - hit_node = hit_node->PlatformGetParent(); - ASSERT_TRUE(hit_node); - - EXPECT_ACCESSIBILITY_HIT_TEST_RESULT(key5_ctr, key5, hit_node); - - // Ensure that element has touch-passthrough set. - EXPECT_TRUE( - key5->GetBoolAttribute(ax::mojom::BoolAttribute::kTouchPassthrough)); - - AccessibilityNotificationWaiter event_waiter( - shell()->web_contents(), ui::kAXModeComplete, - ui::AXEventGenerator::Event::VALUE_IN_TEXT_FIELD_CHANGED); - - // Simulate a tap at that point using TouchPassthroughManager. - TouchPassthroughManager touch_passthrough_manager( - static_cast<WebContentsImpl*>(shell()->web_contents()) - ->GetPrimaryMainFrame()); - touch_passthrough_manager.OnTouchStart(CSSToFramePoint(key5_ctr)); - touch_passthrough_manager.OnTouchEnd(); - ASSERT_TRUE(event_waiter.WaitForNotification()); - - EXPECT_EQ("5", - field->GetStringAttribute(ax::mojom::StringAttribute::kValue)); - } -} - } // namespace content
diff --git a/content/browser/accessibility/touch_passthrough_manager.cc b/content/browser/accessibility/touch_passthrough_manager.cc deleted file mode 100644 index bc4c4493..0000000 --- a/content/browser/accessibility/touch_passthrough_manager.cc +++ /dev/null
@@ -1,210 +0,0 @@ -// 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. - -#include "content/browser/accessibility/touch_passthrough_manager.h" - -#include "cc/trees/render_frame_metadata.h" -#include "content/browser/accessibility/browser_accessibility.h" -#include "content/browser/accessibility/browser_accessibility_manager.h" -#include "content/browser/renderer_host/input/synthetic_gesture_controller.h" -#include "content/browser/renderer_host/input/synthetic_gesture_target.h" -#include "content/browser/renderer_host/input/synthetic_pointer_action.h" -#include "content/browser/renderer_host/input/synthetic_touch_driver.h" -#include "content/browser/renderer_host/render_frame_host_impl.h" -#include "content/browser/renderer_host/render_frame_metadata_provider_impl.h" -#include "content/browser/renderer_host/render_widget_host_impl.h" -#include "content/browser/web_contents/web_contents_view.h" -#include "content/common/input/synthetic_pointer_action_list_params.h" -#include "content/common/input/synthetic_pointer_action_params.h" -#include "content/common/input/synthetic_tap_gesture_params.h" -#include "ui/accessibility/ax_enums.mojom.h" -#include "ui/accessibility/ax_node_data.h" -#include "ui/accessibility/platform/ax_platform_tree_manager.h" - -namespace content { - -// Touch events require an index, so that you can distinguish between multiple -// fingers in multi-finger gestures. Touch passthrough only simulates a single -// finger, so we always use the same touch index; it doesn't matter what -// number we pass here as long as it's always the same index. -constexpr int kSyntheticTouchIndex = 0; - -TouchPassthroughManager::TouchPassthroughManager(RenderFrameHostImpl* rfh) - : rfh_(rfh) {} - -TouchPassthroughManager::~TouchPassthroughManager() { - CancelTouchesAndDestroyTouchDriver(); -} - -void TouchPassthroughManager::OnTouchStart( - const gfx::Point& point_in_frame_pixels) { - if (is_passthrough_) { - // This shouldn't happen, but if we do ever get a touch start when - // we thought we were already passing through, we should reset our state. - NOTREACHED(); - OnTouchEnd(); - } - - // Keep track of the current state. - is_touch_down_ = true; - - // Perform a hit test to determine if this event is within a touch - // passthrough region. Use an incrementing ID for each hit test so - // that any callbacks that are received late can be ignored. - hit_test_id_++; - SendHitTest(point_in_frame_pixels, - base::BindOnce(&TouchPassthroughManager::OnHitTestResult, - weak_ptr_factory_.GetWeakPtr(), hit_test_id_, - base::TimeTicks::Now(), point_in_frame_pixels)); -} - -void TouchPassthroughManager::OnTouchMove( - const gfx::Point& point_in_frame_pixels) { - DCHECK(is_touch_down_); - - if (is_passthrough_) - SimulateMove(point_in_frame_pixels, base::TimeTicks::Now()); -} - -void TouchPassthroughManager::OnTouchEnd() { - DCHECK(is_touch_down_); - is_touch_down_ = false; - - if (is_passthrough_) { - SimulateRelease(base::TimeTicks::Now()); - is_passthrough_ = false; - } -} - -void TouchPassthroughManager::OnHitTestResult( - int hit_test_id, - base::TimeTicks event_time, - gfx::Point location, - ui::AXPlatformTreeManager* hit_manager, - ui::AXNodeID hit_node_id) { - // Ignore the result if it arrived too late to do something about it. - if (hit_test_id != hit_test_id_) - return; - - // If it's not a touch passthrough node, we're done. - if (!IsTouchPassthroughNode(hit_manager, hit_node_id)) - return; - - // If touch is no longer down, we need to just esnd a tap. - if (!is_touch_down_) { - SimulatePress(location, event_time); - SimulateRelease(event_time); - return; - } - - // Otherwise, send a press and set a flag to keep passing through - // events. - SimulatePress(location, event_time); - is_passthrough_ = true; -} - -bool TouchPassthroughManager::IsTouchPassthroughNode( - ui::AXPlatformTreeManager* hit_manager, - ui::AXNodeID hit_node_id) { - // Given the result of a hit test, walk up the tree to determine if - // this node or an ancestor has the passthrough bit set. - if (!hit_manager) - return false; - - BrowserAccessibility* hit_node = - static_cast<BrowserAccessibilityManager*>(hit_manager) - ->GetFromID(hit_node_id); - if (!hit_node) - return false; - - while (hit_node) { - if (hit_node->GetData().GetBoolAttribute( - ax::mojom::BoolAttribute::kTouchPassthrough)) - return true; - hit_node = hit_node->PlatformGetParent(); - } - - return false; -} - -void TouchPassthroughManager::CreateTouchDriverIfNeeded() { - RenderWidgetHostImpl* rwh = rfh_->GetRenderWidgetHost(); - std::unique_ptr<SyntheticGestureTarget> gesture_target_unique_ptr = - rwh->GetView()->CreateSyntheticGestureTarget(); - gesture_target_ = gesture_target_unique_ptr.get(); - gesture_controller_ = std::make_unique<SyntheticGestureController>( - rwh, std::move(gesture_target_unique_ptr)); - touch_driver_ = std::make_unique<SyntheticTouchDriver>(); -} - -void TouchPassthroughManager::SendHitTest( - const gfx::Point& point_in_frame_pixels, - base::OnceCallback<void(ui::AXPlatformTreeManager* hit_manager, - int hit_node_id)> callback) { - rfh_->AccessibilityHitTest(point_in_frame_pixels, ax::mojom::Event::kNone, 0, - std::move(callback)); -} - -void TouchPassthroughManager::CancelTouchesAndDestroyTouchDriver() { - if (!touch_driver_) - return; - - if (is_passthrough_) { - touch_driver_->Cancel(kSyntheticTouchIndex); - touch_driver_->DispatchEvent(gesture_target_, base::TimeTicks::Now()); - } - - is_touch_down_ = false; - touch_driver_.reset(); - // `gesture_target_` is a raw pointer on a `unique_ptr` owned by - // `gesture_controller_`. Hence we need to clear this raw_ptr first before - // releasing `gesture_controller_`. - gesture_target_ = nullptr; - gesture_controller_.reset(); -} - -void TouchPassthroughManager::SimulatePress(const gfx::Point& point, - const base::TimeTicks& time) { - CreateTouchDriverIfNeeded(); - - gfx::Point css_point = ToCSSPoint(point); - touch_driver_->Press(css_point.x(), css_point.y(), kSyntheticTouchIndex); - touch_driver_->DispatchEvent(gesture_target_, time); -} - -void TouchPassthroughManager::SimulateMove(const gfx::Point& point, - const base::TimeTicks& time) { - DCHECK(touch_driver_); - gfx::Point css_point = ToCSSPoint(point); - touch_driver_->Move(css_point.x(), css_point.y(), kSyntheticTouchIndex); - touch_driver_->DispatchEvent(gesture_target_, time); -} - -void TouchPassthroughManager::SimulateRelease(const base::TimeTicks& time) { - DCHECK(touch_driver_); - touch_driver_->Release(kSyntheticTouchIndex); - touch_driver_->DispatchEvent(gesture_target_, time); -} - -gfx::Point TouchPassthroughManager::ToCSSPoint( - gfx::Point point_in_frame_pixels) { - gfx::Point result = point_in_frame_pixels; - - // Scale by the device scale factor. - float dsf = rfh_->AccessibilityGetDeviceScaleFactor(); - result = ScaleToRoundedPoint(result, 1.0 / dsf); - - // Offset by the top controls height. - RenderWidgetHostImpl* rwhi = rfh_->GetRenderWidgetHost(); - RenderFrameMetadataProviderImpl* render_frame_metadata_provider = - rwhi->render_frame_metadata_provider(); - const cc::RenderFrameMetadata render_frame_metadata = - render_frame_metadata_provider->LastRenderFrameMetadata(); - float offset = render_frame_metadata.top_controls_height / dsf; - result.Offset(0, offset); - - return result; -} - -} // namespace content
diff --git a/content/browser/accessibility/touch_passthrough_manager.h b/content/browser/accessibility/touch_passthrough_manager.h deleted file mode 100644 index 893e77ed..0000000 --- a/content/browser/accessibility/touch_passthrough_manager.h +++ /dev/null
@@ -1,131 +0,0 @@ -// 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. - -#ifndef CONTENT_BROWSER_ACCESSIBILITY_TOUCH_PASSTHROUGH_MANAGER_H_ -#define CONTENT_BROWSER_ACCESSIBILITY_TOUCH_PASSTHROUGH_MANAGER_H_ - -#include <map> - -#include "base/functional/callback_forward.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "content/common/content_export.h" -#include "ui/accessibility/ax_node_data.h" -#include "ui/accessibility/ax_tree_id.h" -#include "ui/gfx/geometry/point.h" - -namespace base { - -class TimeTicks; - -} // namespace base - -namespace ui { - -class AXPlatformTreeManager; - -} // namespace ui - -namespace content { - -class RenderFrameHostImpl; -class SyntheticGestureController; -class SyntheticGestureTarget; -class SyntheticTouchDriver; - -// Class that implements support for aria-touchpassthrough. When a screen -// reader is running on a system with a touch screen, the default mode -// is usually "touch exploration", where tapping or dragging on the screen -// describes the item under the finger but does not activate it. Typically -// double-tapping activates an object. -// -// However, there are some types of interfaces where this mode is inefficient -// or just doesn't work at all, for example a signature pad where you're -// supposed to draw your signature, a musical instrument, a game, or a -// keyboard/keypad. In these scenarios, it's desirable for touch events -// to get passed directly through. -// -// This class implements support for passing through touch events sent to -// a region with aria-touchpassthrough. Its input is the raw touch events -// from the touch exploration system. It does hit tests to determine whether -// those events fall within passthrough regions, and if so, generates touch -// events within those regions. -// -// Note that touch exploration is still running - the first touch within a -// passthrough region would still bring accessibility focus to that region and -// the screen reader would still announce it - the difference is that the -// touch events would also get passed through. -// -// Implementation: -// -// When an onTouchStart is received, we must first do an async hit test to -// determine if it's within a touch passthrough region. If it is, then all -// touch events are passed through until onTouchEnd. -class CONTENT_EXPORT TouchPassthroughManager { - public: - explicit TouchPassthroughManager(RenderFrameHostImpl* rfh); - TouchPassthroughManager(const TouchPassthroughManager&) = delete; - virtual ~TouchPassthroughManager(); - - // These are the touch events sent by the touch exploration system. When - // aria-touchpassthrough is not present, these events are only used to give - // accessibility focus to objects being touched and this class will do - // nothing. However, if aria-touchpassthrough is present on the HTML element - // under the finger, then this class will forward touch events to - // the renderer. - void OnTouchStart(const gfx::Point& point_in_frame_pixels); - void OnTouchMove(const gfx::Point& point_in_frame_pixels); - void OnTouchEnd(); - - protected: - // These are virtual protected for unit-testing. - virtual void SendHitTest( - const gfx::Point& point_in_frame_pixels, - base::OnceCallback<void(ui::AXPlatformTreeManager* hit_manager, - ui::AXNodeID hit_node_id)> callback); - virtual void CancelTouchesAndDestroyTouchDriver(); - virtual void SimulatePress(const gfx::Point& point, - const base::TimeTicks& time); - virtual void SimulateMove(const gfx::Point& point, - const base::TimeTicks& time); - virtual void SimulateRelease(const base::TimeTicks& time); - - private: - // The main frame where touch events should be sent. Touch events - // that target an iframe will be automatically forwarded. - raw_ptr<RenderFrameHostImpl> rfh_; - - // Classes needed to generate touch events. - std::unique_ptr<SyntheticGestureController> gesture_controller_; - raw_ptr<SyntheticGestureTarget> gesture_target_ = nullptr; - std::unique_ptr<SyntheticTouchDriver> touch_driver_; - - // Keeps track of whether or not touch is down, regardless of whether or - // not we're passing through. - bool is_touch_down_ = false; - - // Whether or not we're passing through touch events until the next - // touch up. - bool is_passthrough_ = false; - - // An incrementing ID so that hit test callbacks that arrive late can - // be ignored. - int hit_test_id_ = 0; - - void CreateTouchDriverIfNeeded(); - void OnHitTestResult(int event_id, - base::TimeTicks event_time, - gfx::Point location, - ui::AXPlatformTreeManager* hit_manager, - ui::AXNodeID hit_node_id); - bool IsTouchPassthroughNode(ui::AXPlatformTreeManager* hit_manager, - ui::AXNodeID hit_node_id); - gfx::Point ToCSSPoint(gfx::Point point_in_frame_pixels); - - base::WeakPtrFactory<TouchPassthroughManager> weak_ptr_factory_{this}; -}; - -} // namespace content - -#endif // CONTENT_BROWSER_ACCESSIBILITY_TOUCH_PASSTHROUGH_MANAGER_H_
diff --git a/content/browser/accessibility/touch_passthrough_manager_unittest.cc b/content/browser/accessibility/touch_passthrough_manager_unittest.cc deleted file mode 100644 index a25d1a5..0000000 --- a/content/browser/accessibility/touch_passthrough_manager_unittest.cc +++ /dev/null
@@ -1,177 +0,0 @@ -// 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. - -#include "content/browser/accessibility/touch_passthrough_manager.h" - -#include <string> -#include <vector> - -#include "base/strings/stringprintf.h" -#include "base/time/time.h" -#include "content/browser/accessibility/browser_accessibility.h" -#include "content/browser/accessibility/browser_accessibility_manager.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/accessibility/ax_node_data.h" -#include "ui/accessibility/ax_node_id_forward.h" -#include "ui/accessibility/ax_tree_update.h" -#include "ui/accessibility/platform/ax_platform_tree_manager.h" - -using ::testing::ContainerEq; - -namespace content { - -// Subclass of TouchPassthroughManager enabling us to unit-test it. -class TestTouchPassthroughManager : public TouchPassthroughManager { - public: - TestTouchPassthroughManager() : TouchPassthroughManager(nullptr) { - ui::AXNodeData root; - root.id = 1; - root.child_ids = {2, 3}; - root.relative_bounds.bounds = gfx::RectF(0, 0, 800, 600); - - ui::AXNodeData target1; - target1.id = 2; - target1.AddBoolAttribute(ax::mojom::BoolAttribute::kTouchPassthrough, true); - target1.relative_bounds.bounds = gfx::RectF(100, 100, 400, 100); - - ui::AXNodeData target2; - target2.id = 3; - target2.AddBoolAttribute(ax::mojom::BoolAttribute::kTouchPassthrough, true); - target2.relative_bounds.bounds = gfx::RectF(100, 200, 400, 100); - - browser_accessibility_manager_.reset(BrowserAccessibilityManager::Create( - MakeAXTreeUpdateForTesting(root, target1, target2), nullptr)); - } - - ~TestTouchPassthroughManager() override = default; - - const std::vector<std::string> event_log() { return event_log_; } - - private: - std::unique_ptr<BrowserAccessibilityManager> browser_accessibility_manager_; - std::vector<std::string> event_log_; - base::TimeTicks previous_time_; - bool button_down_ = false; - - // This is needed to prevent a DCHECK failure when OnAccessibilityApiUsage - // is called in BrowserAccessibility::GetRole. - content::BrowserTaskEnvironment task_environment_; - - void SendHitTest( - const gfx::Point& point_in_frame_pixels, - base::OnceCallback<void(ui::AXPlatformTreeManager* hit_manager, - ui::AXNodeID hit_node_id)> callback) override { - BrowserAccessibility* result = - browser_accessibility_manager_->GetBrowserAccessibilityRoot() - ->ApproximateHitTest(point_in_frame_pixels); - ui::AXNodeID hit_node_id = result ? result->GetId() : ui::kInvalidAXNodeID; - std::move(callback).Run(browser_accessibility_manager_.get(), hit_node_id); - } - - void CancelTouchesAndDestroyTouchDriver() override {} - - void SimulatePress(const gfx::Point& point, - const base::TimeTicks& time) override { - EXPECT_FALSE(button_down_); - EXPECT_GE(time, previous_time_); - previous_time_ = time; - button_down_ = true; - event_log_.push_back( - base::StringPrintf("Press %d, %d", point.x(), point.y())); - } - - void SimulateMove(const gfx::Point& point, - const base::TimeTicks& time) override { - EXPECT_TRUE(button_down_); - EXPECT_GE(time, previous_time_); - previous_time_ = time; - event_log_.push_back( - base::StringPrintf("Move %d, %d", point.x(), point.y())); - } - - void SimulateRelease(const base::TimeTicks& time) override { - EXPECT_TRUE(button_down_); - EXPECT_GE(time, previous_time_); - previous_time_ = time; - button_down_ = false; - event_log_.push_back("Release"); - } -}; - -class TouchPassthroughManagerTest : public testing::Test { - public: - TouchPassthroughManagerTest() = default; - - TouchPassthroughManagerTest(const TouchPassthroughManagerTest&) = delete; - TouchPassthroughManagerTest& operator=(const TouchPassthroughManagerTest&) = - delete; - - ~TouchPassthroughManagerTest() override = default; - - protected: - private: - void SetUp() override {} -}; - -TEST_F(TouchPassthroughManagerTest, TapOutsidePassthroughRegion) { - TestTouchPassthroughManager manager; - manager.OnTouchStart(gfx::Point(5, 5)); - manager.OnTouchEnd(); - EXPECT_THAT(manager.event_log(), ContainerEq(std::vector<std::string>())); -} - -TEST_F(TouchPassthroughManagerTest, TapInPassthroughRegion) { - TestTouchPassthroughManager manager; - manager.OnTouchStart(gfx::Point(105, 105)); - manager.OnTouchEnd(); - EXPECT_THAT(manager.event_log(), ContainerEq(std::vector<std::string>{ - "Press 105, 105", "Release"})); -} - -TEST_F(TouchPassthroughManagerTest, DragWithinPassthroughRegion) { - TestTouchPassthroughManager manager; - manager.OnTouchStart(gfx::Point(105, 105)); - manager.OnTouchMove(gfx::Point(495, 195)); - manager.OnTouchEnd(); - EXPECT_THAT(manager.event_log(), - ContainerEq(std::vector<std::string>{ - "Press 105, 105", "Move 495, 195", "Release"})); -} - -TEST_F(TouchPassthroughManagerTest, DragOutOfPassthroughRegion) { - TestTouchPassthroughManager manager; - manager.OnTouchStart(gfx::Point(105, 105)); - manager.OnTouchMove(gfx::Point(105, 95)); - manager.OnTouchEnd(); - EXPECT_THAT(manager.event_log(), - ContainerEq(std::vector<std::string>{"Press 105, 105", - "Move 105, 95", "Release"})); -} - -TEST_F(TouchPassthroughManagerTest, DragIntoPassthroughRegion) { - TestTouchPassthroughManager manager; - manager.OnTouchStart(gfx::Point(80, 80)); - manager.OnTouchMove(gfx::Point(90, 90)); - manager.OnTouchMove(gfx::Point(110, 110)); - manager.OnTouchMove(gfx::Point(120, 120)); - manager.OnTouchEnd(); - EXPECT_THAT(manager.event_log(), ContainerEq(std::vector<std::string>{})); -} - -TEST_F(TouchPassthroughManagerTest, DragBetweenPassthroughRegions) { - TestTouchPassthroughManager manager; - manager.OnTouchStart(gfx::Point(110, 180)); - manager.OnTouchMove(gfx::Point(110, 190)); - manager.OnTouchMove(gfx::Point(110, 210)); - manager.OnTouchMove(gfx::Point(110, 220)); - manager.OnTouchEnd(); - EXPECT_THAT(manager.event_log(), - ContainerEq(std::vector<std::string>{ - "Press 110, 180", "Move 110, 190", "Move 110, 210", - "Move 110, 220", "Release"})); -} - -} // namespace content
diff --git a/content/browser/accessibility/web_contents_accessibility_android.cc b/content/browser/accessibility/web_contents_accessibility_android.cc index d55290f..3daf9bd 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.cc +++ b/content/browser/accessibility/web_contents_accessibility_android.cc
@@ -20,7 +20,6 @@ #include "content/browser/accessibility/browser_accessibility_manager_android.h" #include "content/browser/accessibility/browser_accessibility_state_impl_android.h" #include "content/browser/accessibility/one_shot_accessibility_tree_search.h" -#include "content/browser/accessibility/touch_passthrough_manager.h" #include "content/browser/android/render_widget_host_connector.h" #include "content/browser/renderer_host/render_widget_host_view_android.h" #include "content/browser/web_contents/web_contents_impl.h" @@ -532,46 +531,16 @@ ui::MotionEventAndroid::GetAndroidAction(event.GetAction()))) return false; - if (!GetRootBrowserAccessibilityManager()) - return true; - - // Apply the page scale factor to go from device coordinates to - // render coordinates. - gfx::PointF pointf = event.GetPointPix(); - pointf.Scale(1 / page_scale_); - gfx::Point point = gfx::ToFlooredPoint(pointf); - // |HitTest| sends an IPC to the render process to do the hit testing. // The response is handled by HandleHover when it returns. // Hover event was consumed by accessibility by now. Return true to // stop the event from proceeding. - if (event.GetAction() != ui::MotionEvent::Action::HOVER_EXIT) - GetRootBrowserAccessibilityManager()->HitTest(point, /*request_id=*/0); - - if (!GetRootBrowserAccessibilityManager()->touch_passthrough_enabled()) - return true; - - if (!web_contents_ || !web_contents_->GetPrimaryMainFrame()) - return true; - - if (!touch_passthrough_manager_) { - touch_passthrough_manager_ = std::make_unique<TouchPassthroughManager>( - web_contents_->GetPrimaryMainFrame()); - } - - switch (event.GetAction()) { - case ui::MotionEvent::Action::HOVER_ENTER: - touch_passthrough_manager_->OnTouchStart(point); - break; - case ui::MotionEvent::Action::HOVER_MOVE: - touch_passthrough_manager_->OnTouchMove(point); - break; - case ui::MotionEvent::Action::HOVER_EXIT: - touch_passthrough_manager_->OnTouchEnd(); - break; - default: - NOTREACHED(); - break; + if (event.GetAction() != ui::MotionEvent::Action::HOVER_EXIT && + GetRootBrowserAccessibilityManager()) { + gfx::PointF point = event.GetPointPix(); + point.Scale(1 / page_scale_); + GetRootBrowserAccessibilityManager()->HitTest(gfx::ToFlooredPoint(point), + /*request_id=*/0); } return true;
diff --git a/content/browser/accessibility/web_contents_accessibility_android.h b/content/browser/accessibility/web_contents_accessibility_android.h index 3f5c8033..8eabc1fb 100644 --- a/content/browser/accessibility/web_contents_accessibility_android.h +++ b/content/browser/accessibility/web_contents_accessibility_android.h
@@ -39,7 +39,6 @@ class BrowserAccessibilityAndroid; class BrowserAccessibilityManagerAndroid; -class TouchPassthroughManager; class WebContents; class WebContentsImpl; @@ -417,8 +416,6 @@ // this class is constructed with a ui::AXTreeUpdate. std::unique_ptr<BrowserAccessibilityManagerAndroid> snapshot_root_manager_; - std::unique_ptr<TouchPassthroughManager> touch_passthrough_manager_; - base::WeakPtrFactory<WebContentsAccessibilityAndroid> weak_ptr_factory_{this}; };
diff --git a/content/browser/attribution_reporting/attribution_config.cc b/content/browser/attribution_reporting/attribution_config.cc index 59d58b3..9b984731 100644 --- a/content/browser/attribution_reporting/attribution_config.cc +++ b/content/browser/attribution_reporting/attribution_config.cc
@@ -46,6 +46,17 @@ return true; } +AttributionConfig::RateLimitConfig::RateLimitConfig() + : max_reporting_origins_per_source_reporting_site( + kMaxReportingOriginsPerSiteParam.Get()) { + if (max_reporting_origins_per_source_reporting_site <= 0) { + max_reporting_origins_per_source_reporting_site = + kDefaultMaxReportingOriginsPerSourceReportingSite; + } +} + +AttributionConfig::RateLimitConfig::~RateLimitConfig() = default; + bool AttributionConfig::RateLimitConfig::Validate() const { if (time_window <= base::TimeDelta()) { return false; @@ -63,12 +74,11 @@ return false; } - return true; -} + if (max_reporting_origins_per_source_reporting_site <= 0) { + return false; + } -int AttributionConfig::RateLimitConfig:: - GetMaxSourceReportingOriginsPerReportingSite() const { - return kMaxReportingOriginsPerSiteParam.Get(); + return true; } bool AttributionConfig::EventLevelLimit::Validate() const {
diff --git a/content/browser/attribution_reporting/attribution_config.h b/content/browser/attribution_reporting/attribution_config.h index 3c5e127..81ed530 100644 --- a/content/browser/attribution_reporting/attribution_config.h +++ b/content/browser/attribution_reporting/attribution_config.h
@@ -17,6 +17,9 @@ struct CONTENT_EXPORT AttributionConfig { // Controls rate limits for the API. struct CONTENT_EXPORT RateLimitConfig { + RateLimitConfig(); + ~RateLimitConfig(); + // Returns true if this config is valid. [[nodiscard]] bool Validate() const; @@ -37,9 +40,13 @@ static constexpr int kDefaultMaxReportingOriginsPerSourceReportingSite = 1; - base::TimeDelta origins_per_site_window = base::Days(1); + // Maximum number of distinct reporting origins for a given <source site, + // reporting site> in `origins_per_site_window`. + int max_reporting_origins_per_source_reporting_site = + kDefaultMaxReportingOriginsPerSourceReportingSite; - int GetMaxSourceReportingOriginsPerReportingSite() const; + // Controls the time window for reporting origins per site limit. + base::TimeDelta origins_per_site_window = base::Days(1); // When adding new members, the corresponding `Validate()` definition and // `operator==()` definition in `attribution_interop_parser_unittest.cc`
diff --git a/content/browser/attribution_reporting/attribution_internals.mojom b/content/browser/attribution_reporting/attribution_internals.mojom index bd953f24..db1fd0f 100644 --- a/content/browser/attribution_reporting/attribution_internals.mojom +++ b/content/browser/attribution_reporting/attribution_internals.mojom
@@ -218,9 +218,8 @@ // storage layer. interface Handler { // Returns the state of the Attribution Reporting API in the WebUI's browsing context. - // `attribution_support` is the `Attribution-Reporting-Support` request header value. IsAttributionReportingEnabled() => (bool enabled, bool debug_mode, - string attribution_support); + network.mojom.AttributionSupport attribution_support); // Returns all active sources that are persisted in storage. This does // not include expired sources, or sources that can no longer be attributed
diff --git a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc index 870ca90..69c03d21 100644 --- a/content/browser/attribution_reporting/attribution_internals_handler_impl.cc +++ b/content/browser/attribution_reporting/attribution_internals_handler_impl.cc
@@ -53,7 +53,6 @@ #include "content/public/common/content_client.h" #include "content/public/common/content_switches.h" #include "net/base/net_errors.h" -#include "services/network/public/cpp/attribution_utils.h" #include "services/network/public/mojom/attribution.mojom-forward.h" #include "third_party/abseil-cpp/absl/numeric/int128.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -255,9 +254,8 @@ /*destination_origin=*/nullptr, /*reporting_origin=*/nullptr); bool debug_mode = base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kAttributionReportingDebugMode); - std::move(callback).Run( - attribution_reporting_enabled, debug_mode, - network::GetAttributionSupportHeader(AttributionManager::GetSupport())); + std::move(callback).Run(attribution_reporting_enabled, debug_mode, + AttributionManager::GetSupport()); } void AttributionInternalsHandlerImpl::GetActiveSources(
diff --git a/content/browser/attribution_reporting/attribution_interop_parser.cc b/content/browser/attribution_reporting/attribution_interop_parser.cc index e7b513a..6b4d3cbe 100644 --- a/content/browser/attribution_reporting/attribution_interop_parser.cc +++ b/content/browser/attribution_reporting/attribution_interop_parser.cc
@@ -151,6 +151,9 @@ config.rate_limit.max_attribution_reporting_origins, required); ParseInt64(dict, "rate_limit_max_attributions", config.rate_limit.max_attributions, required); + ParseInt(dict, "rate_limit_max_reporting_origins_per_source_reporting_site", + config.rate_limit.max_reporting_origins_per_source_reporting_site, + required); ParseInt(dict, "max_event_level_reports_per_destination", config.event_level_limit.max_reports_per_destination, required);
diff --git a/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc b/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc index 83180ae1..6663990e 100644 --- a/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc +++ b/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc
@@ -52,6 +52,7 @@ return std::make_tuple( config.time_window, config.max_source_registration_reporting_origins, config.max_attribution_reporting_origins, config.max_attributions, + config.max_reporting_origins_per_source_reporting_site, config.origins_per_site_window); }; return tie(a) == tie(b); @@ -597,17 +598,34 @@ AttributionConfig{.max_destinations_per_source_site_reporting_site = 100}}, {R"json({"rate_limit_time_window":"30"})json", false, - AttributionConfig{.rate_limit = {.time_window = base::Days(30)}}}, + AttributionConfig{.rate_limit = RateLimitWith( + [](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::Days(30); + })}}, {R"json({"rate_limit_max_source_registration_reporting_origins":"10"})json", false, - AttributionConfig{ - .rate_limit = {.max_source_registration_reporting_origins = 10}}}, + AttributionConfig{.rate_limit = RateLimitWith( + [](AttributionConfig::RateLimitConfig& r) { + r.max_source_registration_reporting_origins = 10; + })}}, {R"json({"rate_limit_max_attribution_reporting_origins":"10"})json", false, - AttributionConfig{ - .rate_limit = {.max_attribution_reporting_origins = 10}}}, + AttributionConfig{.rate_limit = RateLimitWith( + [](AttributionConfig::RateLimitConfig& r) { + r.max_attribution_reporting_origins = 10; + })}}, {R"json({"rate_limit_max_attributions":"10"})json", false, - AttributionConfig{.rate_limit = {.max_attributions = 10}}}, + AttributionConfig{.rate_limit = RateLimitWith( + [](AttributionConfig::RateLimitConfig& r) { + r.max_attributions = 10; + })}}, + {R"json({"rate_limit_max_reporting_origins_per_source_reporting_site":"2"})json", + false, + AttributionConfig{ + .rate_limit = + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.max_reporting_origins_per_source_reporting_site = 2; + })}}, {R"json({"navigation_source_trigger_data_cardinality":"10"})json", false, AttributionConfig{.event_level_limit = EventLevelLimitWith( [](AttributionConfig::EventLevelLimit& e) { @@ -657,6 +675,7 @@ "rate_limit_max_source_registration_reporting_origins":"20", "rate_limit_max_attribution_reporting_origins":"15", "rate_limit_max_attributions":"10", + "rate_limit_max_reporting_origins_per_source_reporting_site":"5", "navigation_source_trigger_data_cardinality":"100", "event_source_trigger_data_cardinality":"10", "randomized_response_epsilon":"0.2", @@ -672,10 +691,14 @@ AttributionConfig{ .max_sources_per_origin = 10, .max_destinations_per_source_site_reporting_site = 10, - .rate_limit = {.time_window = base::Days(10), - .max_source_registration_reporting_origins = 20, - .max_attribution_reporting_origins = 15, - .max_attributions = 10}, + .rate_limit = + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::Days(10); + r.max_source_registration_reporting_origins = 20; + r.max_attribution_reporting_origins = 15; + r.max_attributions = 10; + r.max_reporting_origins_per_source_reporting_site = 5; + }), .event_level_limit = EventLevelLimitWith([](AttributionConfig::EventLevelLimit& e) { e.navigation_source_trigger_data_cardinality = 100; @@ -713,6 +736,7 @@ "rate_limit_max_source_registration_reporting_origins", "rate_limit_max_attribution_reporting_origins", "rate_limit_max_attributions", + "rate_limit_max_reporting_origins_per_source_reporting_site", "navigation_source_trigger_data_cardinality", "event_source_trigger_data_cardinality", "max_event_level_reports_per_destination",
diff --git a/content/browser/attribution_reporting/attribution_src_browsertest.cc b/content/browser/attribution_reporting/attribution_src_browsertest.cc index cdd936d..e4beb8a 100644 --- a/content/browser/attribution_reporting/attribution_src_browsertest.cc +++ b/content/browser/attribution_reporting/attribution_src_browsertest.cc
@@ -1104,11 +1104,13 @@ root_rfh->GetPage().fenced_frame_urls_map(); auto fenced_frame_urn = test::AddAndVerifyFencedFrameURL(&url_mapping, fenced_frame_url); - RenderFrameHost* fenced_frame_host = fenced_frame_helper_->CreateFencedFrame( - root_rfh, GURL(url::kAboutBlankURL), net::OK, - blink::FencedFrame::DeprecatedFencedFrameMode::kOpaqueAds); - TestFrameNavigationObserver observer(fenced_frame_host); + RenderFrameHostWrapper fenced_frame_host( + fenced_frame_helper_->CreateFencedFrame( + root_rfh, GURL(url::kAboutBlankURL), net::OK, + blink::FencedFrame::DeprecatedFencedFrameMode::kOpaqueAds)); + + TestFrameNavigationObserver observer(fenced_frame_host.get()); EXPECT_TRUE(ExecJs(root_rfh, JsReplace("document.querySelector('fencedframe')" ".config = new FencedFrameConfig($1);", @@ -1116,8 +1118,17 @@ observer.Wait(); - ASSERT_NE(fenced_frame_host, nullptr); - EXPECT_TRUE(fenced_frame_host->IsFencedFrameRoot()); + if (content::WillSameSiteNavigationsChangeRenderFrameHosts()) { + EXPECT_TRUE(fenced_frame_host.WaitUntilRenderFrameDeleted()); + } else { + ASSERT_NE(fenced_frame_host.get(), nullptr); + } + + RenderFrameHostWrapper fenced_frame_host2( + content::test::FencedFrameTestHelper::GetMostRecentlyAddedFencedFrame( + root_rfh)); + + EXPECT_TRUE(fenced_frame_host2->IsFencedFrameRoot()); std::unique_ptr<MockDataHost> data_host; base::RunLoop loop; @@ -1131,7 +1142,7 @@ }); EXPECT_TRUE(ExecJs( - fenced_frame_host, + fenced_frame_host2.get(), JsReplace( "createAttributionSrcImg($1);", https_server()->GetURL("c.test", "/register_source_headers.html"))));
diff --git a/content/browser/attribution_reporting/attribution_storage_unittest.cc b/content/browser/attribution_reporting/attribution_storage_unittest.cc index 5e272e3..40bcc07 100644 --- a/content/browser/attribution_reporting/attribution_storage_unittest.cc +++ b/content/browser/attribution_reporting/attribution_storage_unittest.cc
@@ -1104,13 +1104,15 @@ } TEST_F(AttributionStorageTest, MaxAttributionsBetweenSites) { - delegate()->set_rate_limits({ - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 2, - }); + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 2; + })); SourceBuilder source_builder = TestAggregatableSourceProvider().GetBuilder(); storage()->StoreSource(source_builder.Build()); @@ -1157,13 +1159,15 @@ TEST_F(AttributionStorageTest, MaxAttributionReportsBetweenSites_IgnoresSourceType) { - delegate()->set_rate_limits({ - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 1, - }); + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 1; + })); storage()->StoreSource( SourceBuilder().SetSourceType(SourceType::kNavigation).Build()); @@ -1204,13 +1208,15 @@ } TEST_F(AttributionStorageTest, NeverAttributeImpression_RateLimitsChanged) { - delegate()->set_rate_limits({ - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 1, - }); + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 1; + })); delegate()->set_randomized_response( std::vector<AttributionStorageDelegate::FakeReport>{}); @@ -1232,13 +1238,15 @@ TEST_F(AttributionStorageTest, NeverAttributeSource_AggregatableReportStoredAndRateLimitsChanged) { - delegate()->set_rate_limits({ - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 2, - }); + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 2; + })); SourceBuilder builder = TestAggregatableSourceProvider().GetBuilder(); @@ -1570,13 +1578,15 @@ TEST_F(AttributionStorageTest, FalselyAttributeImpression_ReportStored) { delegate()->set_max_attributions_per_source(1); - delegate()->set_rate_limits({ - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 2, - }); + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 2; + })); const base::Time fake_report_time = base::Time::Now() + kReportDelay; const base::Time fake_trigger_time = fake_report_time - base::Microseconds(1); @@ -2697,12 +2707,14 @@ // This is tested more thoroughly by the `RateLimitTable` unit tests. Here just // ensure that the rate limits are consulted at all. TEST_F(AttributionStorageTest, MaxReportingOriginsPerSource) { - delegate()->set_rate_limits({ - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = 2, - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = std::numeric_limits<int64_t>::max(), - }); + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = 2; + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = std::numeric_limits<int64_t>::max(); + })); auto result = storage()->StoreSource( SourceBuilder() @@ -2732,13 +2744,14 @@ // This is tested more thoroughly by the `RateLimitTable` unit tests. Here just // ensure that the rate limits are consulted at all. TEST_F(AttributionStorageTest, MaxReportingOriginsPerAttribution) { - delegate()->set_rate_limits({ - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = 2, - .max_attributions = std::numeric_limits<int64_t>::max(), - }); + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = 2; + r.max_attributions = std::numeric_limits<int64_t>::max(); + })); const auto origin1 = *SuitableOrigin::Deserialize("https://r1.test"); const auto origin2 = *SuitableOrigin::Deserialize("https://r2.test"); @@ -3434,13 +3447,15 @@ TEST_F(AttributionStorageTest, MaxAttributions_BoundedBySourceTimeWindow) { constexpr base::TimeDelta kTimeWindow = base::Days(1); - delegate()->set_rate_limits({ - .time_window = kTimeWindow, - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 1, - }); + delegate()->set_rate_limits( + RateLimitWith([kTimeWindow](AttributionConfig::RateLimitConfig& r) { + r.time_window = kTimeWindow; + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 1; + })); storage()->StoreSource(SourceBuilder().SetExpiry(base::Days(7)).Build()); @@ -3600,6 +3615,11 @@ } TEST_F(AttributionStorageTest, MaxSourceReportingOriginsPerSite) { + delegate()->set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.max_reporting_origins_per_source_reporting_site = 1; + })); + auto store_source = [&](std::string source, std::string reporting) { storage()->StoreSource( SourceBuilder()
diff --git a/content/browser/attribution_reporting/attribution_test_utils.cc b/content/browser/attribution_reporting/attribution_test_utils.cc index 7513f10..71dcd32 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.cc +++ b/content/browser/attribution_reporting/attribution_test_utils.cc
@@ -14,6 +14,7 @@ #include "base/check.h" #include "base/functional/callback.h" #include "base/functional/callback_helpers.h" +#include "base/functional/function_ref.h" #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/test/bind.h" @@ -28,6 +29,7 @@ #include "components/attribution_reporting/suitable_origin.h" #include "components/attribution_reporting/test_utils.h" #include "components/attribution_reporting/trigger_registration.h" +#include "content/browser/attribution_reporting/attribution_config.h" #include "content/browser/attribution_reporting/attribution_manager.h" #include "content/browser/attribution_reporting/attribution_observer.h" #include "content/browser/attribution_reporting/attribution_reporting.mojom.h" @@ -86,6 +88,13 @@ return source_time + *declared_window; } +AttributionConfig::RateLimitConfig RateLimitWith( + base::FunctionRef<void(AttributionConfig::RateLimitConfig&)> f) { + AttributionConfig::RateLimitConfig limit; + f(limit); + return limit; +} + // Builds an impression with default values. This is done as a builder because // all values needed to be provided at construction time. SourceBuilder::SourceBuilder(base::Time time)
diff --git a/content/browser/attribution_reporting/attribution_test_utils.h b/content/browser/attribution_reporting/attribution_test_utils.h index 0c9dbea..6e52e37 100644 --- a/content/browser/attribution_reporting/attribution_test_utils.h +++ b/content/browser/attribution_reporting/attribution_test_utils.h
@@ -13,6 +13,7 @@ #include "base/containers/enum_set.h" #include "base/containers/flat_set.h" +#include "base/functional/function_ref.h" #include "base/time/time.h" #include "base/uuid.h" #include "components/aggregation_service/aggregation_service.mojom.h" @@ -26,6 +27,7 @@ #include "components/attribution_reporting/test_utils.h" #include "components/attribution_reporting/trigger_registration.h" #include "content/browser/attribution_reporting/aggregatable_histogram_contribution.h" +#include "content/browser/attribution_reporting/attribution_config.h" #include "content/browser/attribution_reporting/attribution_info.h" #include "content/browser/attribution_reporting/attribution_report.h" #include "content/browser/attribution_reporting/attribution_storage_delegate.h" @@ -67,6 +69,9 @@ absl::optional<base::TimeDelta> declared_window, base::Time source_time); +AttributionConfig::RateLimitConfig RateLimitWith( + base::FunctionRef<void(AttributionConfig::RateLimitConfig&)> f); + // Helper class to construct a StorableSource for tests using default data. // StorableSource members are not mutable after construction requiring a // builder pattern.
diff --git a/content/browser/attribution_reporting/privacy_sandbox_ads_apis_browsertest.cc b/content/browser/attribution_reporting/privacy_sandbox_ads_apis_browsertest.cc index 3a41df3..b1e8a228 100644 --- a/content/browser/attribution_reporting/privacy_sandbox_ads_apis_browsertest.cc +++ b/content/browser/attribution_reporting/privacy_sandbox_ads_apis_browsertest.cc
@@ -218,7 +218,7 @@ EXPECT_TRUE(last_request_is_topics_request()); EXPECT_TRUE(last_topics_header()); EXPECT_EQ(last_topics_header().value(), - "t=(1;v=chrome.1:1:2), p=P00000000000"); + "(1);v=chrome.1:1:2, ();p=P00000000000"); } IN_PROC_BROWSER_TEST_F(PrivacySandboxAdsAPIsAllEnabledBrowserTest, @@ -263,7 +263,7 @@ EXPECT_TRUE(last_request_is_topics_request()); EXPECT_TRUE(last_topics_header()); EXPECT_EQ(last_topics_header().value(), - "t=(1;v=chrome.1:1:2), p=P00000000000"); + "(1);v=chrome.1:1:2, ();p=P00000000000"); } IN_PROC_BROWSER_TEST_F(PrivacySandboxAdsAPIsAllEnabledBrowserTest, @@ -456,7 +456,7 @@ EXPECT_TRUE(last_request_is_topics_request()); EXPECT_TRUE(last_topics_header()); EXPECT_EQ(last_topics_header().value(), - "t=(1;v=chrome.1:1:2), p=P00000000000"); + "(1);v=chrome.1:1:2, ();p=P00000000000"); } IN_PROC_BROWSER_TEST_F(PrivacySandboxAdsAPIsTopicsXHRDisabledBrowserTest, @@ -535,7 +535,7 @@ EXPECT_TRUE(last_request_is_topics_request()); EXPECT_TRUE(last_topics_header()); EXPECT_EQ(last_topics_header().value(), - "t=(1;v=chrome.1:1:2), p=P00000000000"); + "(1);v=chrome.1:1:2, ();p=P00000000000"); } class PrivacySandboxAdsAPIsSharedStorageDisabledBrowserTest
diff --git a/content/browser/attribution_reporting/rate_limit_table.cc b/content/browser/attribution_reporting/rate_limit_table.cc index 0826c11..07a0a363 100644 --- a/content/browser/attribution_reporting/rate_limit_table.cc +++ b/content/browser/attribution_reporting/rate_limit_table.cc
@@ -249,7 +249,7 @@ size_t max_origins = static_cast<size_t>(delegate_->GetRateLimits() - .GetMaxSourceReportingOriginsPerReportingSite()); + .max_reporting_origins_per_source_reporting_site); base::Time min_timestamp = source_time - delegate_->GetRateLimits().origins_per_site_window;
diff --git a/content/browser/attribution_reporting/rate_limit_table_unittest.cc b/content/browser/attribution_reporting/rate_limit_table_unittest.cc index 979568d..07cc1145 100644 --- a/content/browser/attribution_reporting/rate_limit_table_unittest.cc +++ b/content/browser/attribution_reporting/rate_limit_table_unittest.cc
@@ -275,13 +275,15 @@ TEST_F(RateLimitTableTest, AttributionAllowedForAttributionCountLimit_ScopedCorrectly) { constexpr base::TimeDelta kTimeWindow = base::Days(1); - delegate_.set_rate_limits({ - .time_window = kTimeWindow, - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 2, - }); + delegate_.set_rate_limits( + RateLimitWith([kTimeWindow](AttributionConfig::RateLimitConfig& r) { + r.time_window = kTimeWindow; + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 2; + })); const base::Time now = base::Time::Now(); @@ -353,13 +355,15 @@ TEST_F(RateLimitTableTest, AttributionAllowedForAttributionCountLimit_SourceTypesCombined) { - delegate_.set_rate_limits({ - .time_window = base::Days(1), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = 2, - }); + delegate_.set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::Days(1); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = 2; + })); const auto navigation_source = SourceBuilder() @@ -439,12 +443,14 @@ TEST_F(RateLimitTableTest, SourceAllowedForReportingOriginLimit) { constexpr base::TimeDelta kTimeWindow = base::Days(1); - delegate_.set_rate_limits({ - .time_window = kTimeWindow, - .max_source_registration_reporting_origins = 2, - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = std::numeric_limits<int64_t>::max(), - }); + delegate_.set_rate_limits( + RateLimitWith([kTimeWindow](AttributionConfig::RateLimitConfig& r) { + r.time_window = kTimeWindow; + r.max_source_registration_reporting_origins = 2; + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = std::numeric_limits<int64_t>::max(); + })); const base::Time now = base::Time::Now(); @@ -492,11 +498,13 @@ TEST_F(RateLimitTableTest, SourceAllowedForReportingOriginPerSourceReportingSiteLimit) { constexpr base::TimeDelta kTimeWindow = base::Days(1); - delegate_.set_rate_limits({ - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = std::numeric_limits<int64_t>::max(), - .origins_per_site_window = kTimeWindow, - }); + delegate_.set_rate_limits( + RateLimitWith([kTimeWindow](AttributionConfig::RateLimitConfig& r) { + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = std::numeric_limits<int64_t>::max(); + r.origins_per_site_window = kTimeWindow; + })); const base::Time now = base::Time::Now(); @@ -560,13 +568,14 @@ TEST_F(RateLimitTableTest, AttributionAllowedForReportingOriginLimit) { constexpr base::TimeDelta kTimeWindow = base::Days(1); - delegate_.set_rate_limits({ - .time_window = kTimeWindow, - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = 2, - .max_attributions = std::numeric_limits<int64_t>::max(), - }); + delegate_.set_rate_limits( + RateLimitWith([kTimeWindow](AttributionConfig::RateLimitConfig& r) { + r.time_window = kTimeWindow; + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = 2; + r.max_attributions = std::numeric_limits<int64_t>::max(); + })); const base::Time now = base::Time::Now(); @@ -597,12 +606,13 @@ TEST_F(RateLimitTableTest, ReportingOriginLimits_IndependentForSourcesAndAttributions) { - delegate_.set_rate_limits({ - .time_window = base::Days(1), - .max_source_registration_reporting_origins = 2, - .max_attribution_reporting_origins = 1, - .max_attributions = std::numeric_limits<int64_t>::max(), - }); + delegate_.set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::Days(1); + r.max_source_registration_reporting_origins = 2; + r.max_attribution_reporting_origins = 1; + r.max_attributions = std::numeric_limits<int64_t>::max(); + })); const base::Time now = base::Time::Now(); @@ -837,13 +847,15 @@ } TEST_F(RateLimitTableTest, AddRateLimit_DeletesExpiredRows) { - delegate_.set_rate_limits({ - .time_window = base::Minutes(2), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = INT_MAX, - }); + delegate_.set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::Minutes(2); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = INT_MAX; + })); delegate_.set_delete_expired_rate_limits_frequency(base::Minutes(4)); @@ -924,13 +936,15 @@ } TEST_F(RateLimitTableTest, AddRateLimitSource_DeletesExpiredRows) { - delegate_.set_rate_limits({ - .time_window = base::Minutes(2), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = INT_MAX, - }); + delegate_.set_rate_limits( + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::Minutes(2); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = INT_MAX; + })); delegate_.set_delete_expired_rate_limits_frequency(base::Minutes(4)); @@ -1103,11 +1117,13 @@ TEST_F(RateLimitTableFieldTrialLimitsTest, SourceAllowedForReportingOriginPerSourceReportingSiteLimit) { constexpr base::TimeDelta kTimeWindow = base::Days(1); - delegate_.set_rate_limits({ - .max_attribution_reporting_origins = std::numeric_limits<int64_t>::max(), - .max_attributions = std::numeric_limits<int64_t>::max(), - .origins_per_site_window = kTimeWindow, - }); + delegate_.set_rate_limits( + RateLimitWith([kTimeWindow](AttributionConfig::RateLimitConfig& r) { + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = std::numeric_limits<int64_t>::max(); + r.origins_per_site_window = kTimeWindow; + })); const base::Time now = base::Time::Now();
diff --git a/content/browser/attribution_reporting/test/configurable_storage_delegate.cc b/content/browser/attribution_reporting/test/configurable_storage_delegate.cc index 7ac9535f..7a0708e 100644 --- a/content/browser/attribution_reporting/test/configurable_storage_delegate.cc +++ b/content/browser/attribution_reporting/test/configurable_storage_delegate.cc
@@ -24,10 +24,12 @@ #include "content/browser/attribution_reporting/common_source_info.h" #include "third_party/abseil-cpp/absl/types/optional.h" +namespace content { + namespace { -content::AttributionConfig::EventLevelLimit EventLevelLimitWith( - base::FunctionRef<void(content::AttributionConfig::EventLevelLimit&)> f) { +AttributionConfig::EventLevelLimit EventLevelLimitWith( + base::FunctionRef<void(AttributionConfig::EventLevelLimit&)> f) { content::AttributionConfig::EventLevelLimit limit; f(limit); return limit; @@ -35,22 +37,22 @@ } // namespace -namespace content { - ConfigurableStorageDelegate::ConfigurableStorageDelegate() : AttributionStorageDelegate(AttributionConfig{ .max_sources_per_origin = std::numeric_limits<int>::max(), .max_destinations_per_source_site_reporting_site = std::numeric_limits<int>::max(), .rate_limit = - { - .time_window = base::TimeDelta::Max(), - .max_source_registration_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attribution_reporting_origins = - std::numeric_limits<int64_t>::max(), - .max_attributions = std::numeric_limits<int64_t>::max(), - }, + RateLimitWith([](AttributionConfig::RateLimitConfig& r) { + r.time_window = base::TimeDelta::Max(); + r.max_source_registration_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attribution_reporting_origins = + std::numeric_limits<int64_t>::max(); + r.max_attributions = std::numeric_limits<int64_t>::max(); + r.max_reporting_origins_per_source_reporting_site = + std::numeric_limits<int>::max(); + }), .event_level_limit = EventLevelLimitWith([](AttributionConfig::EventLevelLimit& e) { e.navigation_source_trigger_data_cardinality =
diff --git a/content/browser/browser_main_loop.cc b/content/browser/browser_main_loop.cc index 32d7e3a..13aae274 100644 --- a/content/browser/browser_main_loop.cc +++ b/content/browser/browser_main_loop.cc
@@ -786,7 +786,7 @@ } #endif -#if BUILDFLAG(ENABLE_LIBRARY_CDMS) || BUILDFLAG(IS_ANDROID) +#if BUILDFLAG(ENABLE_LIBRARY_CDMS) // Prior to any processing happening on the IO thread, we create the // CDM service as it is predominantly used from the IO thread. This must // be called on the main thread since it involves file path checks. @@ -1432,6 +1432,11 @@ #if BUILDFLAG(IS_ANDROID) media::SetMediaDrmBridgeClient(GetContentClient()->GetMediaDrmBridgeClient()); + + // On Android this must be done after SetMediaDrmBridgeClient(). For Android + // all CDMs are part of the OS, so no file checks are involved. + CdmRegistry::GetInstance()->Init(); + if (base::FeatureList::IsEnabled(features::kFontSrcLocalMatching)) { FontUniqueNameLookup::GetInstance(); }
diff --git a/content/browser/browsing_topics/browsing_topics_browsertest.cc b/content/browser/browsing_topics/browsing_topics_browsertest.cc index c2a50e5..22344c2 100644 --- a/content/browser/browsing_topics/browsing_topics_browsertest.cc +++ b/content/browser/browsing_topics/browsing_topics_browsertest.cc
@@ -239,7 +239,7 @@ EXPECT_TRUE(last_request_is_topics_request()); EXPECT_TRUE(last_topics_header()); EXPECT_EQ(last_topics_header().value(), - "t=(1;v=chrome.1:1:2), p=P00000000000"); + "(1);v=chrome.1:1:2, ();p=P00000000000"); } IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest,
diff --git a/content/browser/browsing_topics/browsing_topics_url_loader_unittest.cc b/content/browser/browsing_topics/browsing_topics_url_loader_unittest.cc index f8896db1..dc771d13 100644 --- a/content/browser/browsing_topics/browsing_topics_url_loader_unittest.cc +++ b/content/browser/browsing_topics/browsing_topics_url_loader_unittest.cc
@@ -30,13 +30,13 @@ network::TestURLLoaderFactory::TestURLLoader::FollowRedirectParams; constexpr char kExpectedHeaderForEmptyTopics[] = - "t=(), p=P000000000000000000000000000"; + "();p=P0000000000000000000000000000000"; constexpr char kExpectedHeaderForOrigin1[] = - "t=(1;v=chrome.1:1:2), p=P00000000000"; + "(1);v=chrome.1:1:2, ();p=P00000000000"; constexpr char kExpectedHeaderForOrigin2[] = - "t=(2;v=chrome.1:1:2), p=P00000000000"; + "(2);v=chrome.1:1:2, ();p=P00000000000"; class TopicsInterceptingContentBrowserClient : public ContentBrowserClient { public:
diff --git a/content/browser/browsing_topics/header_util.cc b/content/browser/browsing_topics/header_util.cc index 0969d00..e8a5a0f 100644 --- a/content/browser/browsing_topics/header_util.cc +++ b/content/browser/browsing_topics/header_util.cc
@@ -18,17 +18,12 @@ namespace { -// These numbers must align with the structured header's internal -// implementation. -// For ' ' character. -constexpr int kInnerListItemsSeparatorLength = 1; -// For ';' and '=' characters. -constexpr int kParamsSeparatorLength = 2; - -constexpr int kParamKeyLength = 1; +// The max number of digits in a topic. As new taxonomies are introduced and old +// topics are expired, the expectation is this value will gradually grow. constexpr int kTopicMaxLength = 3; -// Example: chrome.1:1:10 +// The number of characters in a version string, e.g., chrome.1:1:10. This will +// grow as versions require more digits. constexpr int kVersionMaxLength = 13; static_assert(blink::features::kBrowsingTopicsConfigVersionDefault < 10, @@ -47,93 +42,101 @@ const char kBrowsingTopicsRequestHeaderKey[] = "Sec-Browsing-Topics"; -net::structured_headers::ParameterizedItem CreateParameterizedTopic( - const blink::mojom::EpochTopicPtr& topic, - bool skip_version, - int& serialized_inner_list_length) { - if (skip_version) { - return net::structured_headers::ParameterizedItem( - net::structured_headers::Item(static_cast<int64_t>(topic->topic)), {}); - } - - serialized_inner_list_length += - kParamsSeparatorLength + kParamKeyLength + topic->version.size(); - - return net::structured_headers::ParameterizedItem( - net::structured_headers::Item(static_cast<int64_t>(topic->topic)), - {{"v", net::structured_headers::Item( - topic->version, net::structured_headers::Item::kTokenType)}}); -} - std::string DeriveTopicsHeaderValue( const std::vector<blink::mojom::EpochTopicPtr>& topics, int num_versions_in_epochs) { - std::vector<net::structured_headers::ParameterizedItem> header_list; - - // Manually derive the length of the inner topics list in serialized format. - int serialized_inner_list_length = 0; - + net::structured_headers::List header_list; absl::optional<std::string> last_version; + std::vector<net::structured_headers::ParameterizedItem> cur_topics; + + // Build up the header without the padding parameter. for (auto& topic : topics) { - int topic_digits_count = base::NumberToString(topic->topic).size(); - CHECK_LE(topic_digits_count, kTopicMaxLength); - - serialized_inner_list_length += topic_digits_count; - if (!header_list.empty()) { - serialized_inner_list_length += kInnerListItemsSeparatorLength; + bool new_version = + (!last_version.has_value() || last_version.value() != topic->version); + if (new_version) { + if (cur_topics.size() > 0) { + CHECK(last_version.has_value()); + header_list.push_back(net::structured_headers::ParameterizedMember( + cur_topics, + {{"v", + net::structured_headers::Item( + *last_version, net::structured_headers::Item::kTokenType)}})); + cur_topics.clear(); + } + last_version = topic->version; } - - bool skip_version = - (last_version && last_version.value() == topic->version); - - header_list.push_back(CreateParameterizedTopic( - topic, skip_version, serialized_inner_list_length)); - last_version = topic->version; + cur_topics.push_back(net::structured_headers::ParameterizedItem( + net::structured_headers::Item(static_cast<int64_t>(topic->topic)), {})); } + if (cur_topics.size() > 0) { + CHECK(last_version.has_value()); + header_list.push_back(net::structured_headers::ParameterizedMember( + cur_topics, {{"v", net::structured_headers::Item( + *last_version, + net::structured_headers::Item::kTokenType)}})); + } + + // The header is now complete, except for padding. We want the header to be of + // fixed size for the given number of versions in the list, so we add padding + // to make that happen. + + // When adding padding, we'll always have at least 1 version. + if (num_versions_in_epochs == 0) { + num_versions_in_epochs = 1; + } + + // The number of topics that should be in the padded response. int max_number_of_epochs = blink::features::kBrowsingTopicsNumberOfEpochsToExpose.Get(); CHECK_LE(num_versions_in_epochs, max_number_of_epochs); CHECK_GT(max_number_of_epochs, 0); - // If there are no valid epochs, use the `max_padding_length` for epochs - // having same versions. - if (num_versions_in_epochs == 0) { - num_versions_in_epochs = 1; + // The padded length of the header given the number of versions. + // Example header: Sec-Browsing-Topics: (100 200);v=chrome.1:1:2, + // (300);v=chrome.1:1:4, ();p=P00 + int max_length = + max_number_of_epochs * kTopicMaxLength + // length of three topics + max_number_of_epochs - + num_versions_in_epochs + // spaces between topics in a list + num_versions_in_epochs * 5 + // '();v=' + num_versions_in_epochs * + kVersionMaxLength + // max length of the versions + (num_versions_in_epochs - 1) * 2; // the ', ' between topic lists + + // Add the bytes for the ", " between the last list and the padding list in + // the event that there are no topics. + if (header_list.size() == 0) { + max_length += 2; } - int max_padding_length = - max_number_of_epochs * kTopicMaxLength + - num_versions_in_epochs * - (kVersionMaxLength + kParamsSeparatorLength + kParamKeyLength) + - (max_number_of_epochs - 1) * kInnerListItemsSeparatorLength; + // How many bytes of padding do we need to add? + int padding_needed = + header_list.size() > 0 + ? max_length - + net::structured_headers::SerializeList(header_list)->length() + : max_length; - // If `serialized_inner_list_length` is greater than - // `max_padding_length`, keep the header as-is and don't pad - // anything. This could happen in the following situations: - // - We have a newer config/taxonomoy version from Finch and haven't updated - // the default parameter values. - // - A newer model is used on an old Chrome version. - // - There was a race between call to get `topics` and the call to get the - // `num_versions_in_epochs`. This should be extremely unlikely to occur. - int padding_length = (serialized_inner_list_length <= max_padding_length) - ? (max_padding_length - serialized_inner_list_length) - : 0; - std::string padded_token = - base::StrCat({"P", std::string(padding_length, '0')}); + // The padding should generally be >= 0. It can be negative in certain + // circumstances and we need to handle that here. It can be negative if a new + // version is rolled out via finch (e.g., model or taxonomy) that uses an + // extra digit in its number but the binary hasn't been updated to handle the + // extra digit yet. It could also happen if there is a race between getting + // topics and getting the number of distinct topic versions. We clamp to 0 to + // prevent breakage in these rare circumstances. + if (padding_needed < 0) { + padding_needed = 0; + } - std::vector<net::structured_headers::DictionaryMember> header_dict; - header_dict.emplace_back("t", net::structured_headers::ParameterizedMember( - std::move(header_list), {})); - header_dict.emplace_back( - "p", net::structured_headers::ParameterizedMember( - net::structured_headers::Item( - padded_token, net::structured_headers::Item::kTokenType), - {})); + // Add the padding list at the end. + header_list.push_back(net::structured_headers::ParameterizedMember( + std::vector<net::structured_headers::ParameterizedItem>(), + {{"p", net::structured_headers::Item( + base::StrCat({"P", std::string(padding_needed, '0')}), + net::structured_headers::Item::kTokenType)}})); absl::optional<std::string> serialized_header = - net::structured_headers::SerializeDictionary( - net::structured_headers::Dictionary(std::move(header_dict))); + net::structured_headers::SerializeList(header_list); CHECK(serialized_header); return *serialized_header; @@ -153,8 +156,9 @@ // Check the page's IsPrimary() status again in case it has changed since the // request time. - if (!request_initiator_frame.GetPage().IsPrimary()) + if (!request_initiator_frame.GetPage().IsPrimary()) { return; + } // TODO(crbug.com/1244137): IsPrimary() doesn't actually detect portals yet. // Remove this when it does.
diff --git a/content/browser/browsing_topics/header_util_unittest.cc b/content/browser/browsing_topics/header_util_unittest.cc index 455ee77..cc9b7fd 100644 --- a/content/browser/browsing_topics/header_util_unittest.cc +++ b/content/browser/browsing_topics/header_util_unittest.cc
@@ -100,7 +100,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/0); - EXPECT_EQ(header_value, "t=(), p=P000000000000000000000000000"); + EXPECT_EQ(header_value, "();p=P0000000000000000000000000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -109,7 +109,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1); - EXPECT_EQ(header_value, "t=(), p=P000000000000000000000000000"); + EXPECT_EQ(header_value, "();p=P0000000000000000000000000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -119,7 +119,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2); EXPECT_EQ(header_value, - "t=(), p=P0000000000000000000000000000000000000000000"); + "();p=P00000000000000000000000000000000000000000000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -128,9 +128,10 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3); - EXPECT_EQ(header_value, - "t=(), " - "p=P00000000000000000000000000000000000000000000000000000000000"); + EXPECT_EQ( + header_value, + "();p=" + "P000000000000000000000000000000000000000000000000000000000000000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -141,7 +142,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1); - EXPECT_EQ(header_value, "t=(1;v=chrome.1:1:2), p=P00000000000"); + EXPECT_EQ(header_value, "(1);v=chrome.1:1:2, ();p=P00000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -153,7 +154,7 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2); EXPECT_EQ(header_value, - "t=(1;v=chrome.1:1:2), p=P000000000000000000000000000"); + "(1);v=chrome.1:1:2, ();p=P000000000000000000000000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -164,9 +165,9 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3); - EXPECT_EQ( - header_value, - "t=(1;v=chrome.1:1:2), p=P0000000000000000000000000000000000000000000"); + EXPECT_EQ(header_value, + "(1);v=chrome.1:1:2, " + "();p=P0000000000000000000000000000000000000000000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -178,7 +179,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1); - EXPECT_EQ(header_value, "t=(123;v=chrome.1:1:2), p=P000000000"); + EXPECT_EQ(header_value, "(123);v=chrome.1:1:2, ();p=P000000000"); } TEST_F(BrowsingTopicsUtilTest, @@ -190,7 +191,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1); - EXPECT_EQ(header_value, "t=(1;v=chrome.1:1:2 2), p=P000000000"); + EXPECT_EQ(header_value, "(1 2);v=chrome.1:1:2, ();p=P000000000"); } TEST_F( @@ -203,7 +204,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1); - EXPECT_EQ(header_value, "t=(123;v=chrome.1:1:2 45), p=P000000"); + EXPECT_EQ(header_value, "(123 45);v=chrome.1:1:2, ();p=P000000"); } TEST_F( @@ -217,7 +218,7 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2); EXPECT_EQ(header_value, - "t=(1;v=chrome.1:1:2 2), p=P0000000000000000000000000"); + "(1 2);v=chrome.1:1:2, ();p=P0000000000000000000000000000"); } TEST_F( @@ -231,7 +232,7 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2); EXPECT_EQ(header_value, - "t=(1;v=chrome.1:1:2 1;v=chrome.1:1:4), p=P0000000000"); + "(1);v=chrome.1:1:2, (1);v=chrome.1:1:4, ();p=P0000000000"); } TEST_F( @@ -243,10 +244,9 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3); - EXPECT_EQ(header_value, - "t=(1;v=chrome.1:1:2 1;v=chrome.1:1:4), " - "p=P00000000000000000000000000"); + "(1);v=chrome.1:1:2, (1);v=chrome.1:1:4, " + "();p=P00000000000000000000000000000"); } TEST_F( @@ -260,7 +260,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1); - EXPECT_EQ(header_value, "t=(1;v=chrome.1:1:2 2 3), p=P0000000"); + EXPECT_EQ(header_value, "(1 2 3);v=chrome.1:1:2, ();p=P0000000"); } TEST_F( @@ -274,7 +274,7 @@ std::string header_value = DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/1); - EXPECT_EQ(header_value, "t=(100;v=chrome.1:1:20 200 300), p=P"); + EXPECT_EQ(header_value, "(100 200 300);v=chrome.1:1:20, ();p=P"); } TEST_F( @@ -289,8 +289,7 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2); EXPECT_EQ(header_value, - "t=(100;v=chrome.1:1:2 200 300;v=chrome.1:1:4), " - "p=P00"); + "(100 200);v=chrome.1:1:2, (300);v=chrome.1:1:4, ();p=P00"); } TEST_F( @@ -305,8 +304,7 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2); EXPECT_EQ(header_value, - "t=(100;v=chrome.1:1:2 200;v=chrome.1:1:4 300), " - "p=P00"); + "(100);v=chrome.1:1:2, (200 300);v=chrome.1:1:4, ();p=P00"); } TEST_F(BrowsingTopicsUtilTest, @@ -320,8 +318,8 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3); EXPECT_EQ(header_value, - "t=(100;v=chrome.1:1:20 200;v=chrome.1:1:40 300;v=chrome.1:1:60), " - "p=P"); + "(100);v=chrome.1:1:20, (200);v=chrome.1:1:40, " + "(300);v=chrome.1:1:60, ();p=P"); } TEST_F( @@ -336,8 +334,8 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/2); EXPECT_EQ(header_value, - "t=(100;v=chrome.1:1:20 200;v=chrome.1:1:40 300;v=chrome.1:1:60), " - "p=P"); + "(100);v=chrome.1:1:20, (200);v=chrome.1:1:40, " + "(300);v=chrome.1:1:60, ();p=P"); } TEST_F(BrowsingTopicsUtilTest, @@ -357,8 +355,8 @@ DeriveTopicsHeaderValue(topics, /*num_versions_in_epochs=*/3); EXPECT_EQ(header_value, - "t=(100;v=chrome.1:1:20 200;v=chrome.1:1:40 300;v=chrome.1:1:600), " - "p=P"); + "(100);v=chrome.1:1:20, (200);v=chrome.1:1:40, " + "(300);v=chrome.1:1:600, ();p=P"); } TEST_F(BrowsingTopicsUtilTest,
diff --git a/content/browser/devtools/render_frame_devtools_agent_host_browsertest.cc b/content/browser/devtools/render_frame_devtools_agent_host_browsertest.cc index 2453397..9ce3129 100644 --- a/content/browser/devtools/render_frame_devtools_agent_host_browsertest.cc +++ b/content/browser/devtools/render_frame_devtools_agent_host_browsertest.cc
@@ -6,6 +6,7 @@ #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/web_contents/web_contents_impl.h" +#include "content/common/content_navigation_policy.h" #include "content/public/browser/devtools_agent_host.h" #include "content/public/browser/devtools_agent_host_client.h" #include "content/public/browser/render_process_host.h" @@ -115,30 +116,45 @@ if (AreDefaultSiteInstancesEnabled()) EXPECT_TRUE(speculative_rfh_b->GetSiteInstance()->IsDefaultSiteInstance()); - // 4) Navigate elsewhere, it will cancel the previous navigation. + // 4) Navigate elsewhere, it will cancel the previous navigation if navigation + // queueing is not enabled. // 4.a) Navigation: Start. GURL url_c(embedded_test_server()->GetURL("c.com", "/response_c")); TestNavigationManager observer_c(shell()->web_contents(), url_c); shell()->LoadURL(url_c); EXPECT_TRUE(observer_c.WaitForRequestStart()); - RenderFrameHostImpl* speculative_rfh_c = - root->render_manager()->speculative_frame_host(); - EXPECT_TRUE(speculative_rfh_c); - auto speculative_rfh_c_site_id = - speculative_rfh_c->GetSiteInstance()->GetId(); - if (AreDefaultSiteInstancesEnabled()) { - // Verify that this new URL also belongs to the default SiteInstance and - // therefore the RenderFrameHost from the previous navigation could be - // reused. - EXPECT_TRUE(speculative_rfh_c->GetSiteInstance()->IsDefaultSiteInstance()); - EXPECT_EQ(speculative_rfh_c, rfh_devtools_agent->GetFrameHostForTesting()); - EXPECT_EQ(speculative_rfh_b_site_id, speculative_rfh_c_site_id); + + RenderFrameHostImpl* speculative_rfh_c = nullptr; + + if (ShouldQueueNavigationsWhenPendingCommitRFHExists()) { + // When navigation queueing is enabled, starting a new navigation won't + // cancel an existing pending commit navigation, so wait for the first + // navigation to finish first before continuing. + EXPECT_EQ(speculative_rfh_b, + root->render_manager()->speculative_frame_host()); + EXPECT_EQ(speculative_rfh_b, rfh_devtools_agent->GetFrameHostForTesting()); + ASSERT_TRUE(observer_b.WaitForNavigationFinished()); } else { - // Verify that the RenderFrameHost is restored because the new URL required - // a new SiteInstance. - EXPECT_EQ(current_rfh, rfh_devtools_agent->GetFrameHostForTesting()); - EXPECT_NE(speculative_rfh_b_site_id, speculative_rfh_c_site_id); + speculative_rfh_c = root->render_manager()->speculative_frame_host(); + EXPECT_TRUE(speculative_rfh_c); + auto speculative_rfh_c_site_id = + speculative_rfh_c->GetSiteInstance()->GetId(); + if (AreDefaultSiteInstancesEnabled()) { + // Verify that this new URL also belongs to the default SiteInstance and + // therefore the RenderFrameHost from the previous navigation could be + // reused. + EXPECT_TRUE( + speculative_rfh_c->GetSiteInstance()->IsDefaultSiteInstance()); + EXPECT_EQ(speculative_rfh_c, + rfh_devtools_agent->GetFrameHostForTesting()); + EXPECT_EQ(speculative_rfh_b_site_id, speculative_rfh_c_site_id); + } else { + // Verify that the RenderFrameHost is restored because the new URL + // required a new SiteInstance. + EXPECT_EQ(current_rfh, rfh_devtools_agent->GetFrameHostForTesting()); + EXPECT_NE(speculative_rfh_b_site_id, speculative_rfh_c_site_id); + } } // 4.b) Navigation: ReadyToCommit. @@ -150,6 +166,7 @@ "\r\n"); EXPECT_TRUE(observer_c.WaitForResponse()); // Headers are received. observer_c.ResumeNavigation(); // ReadyToCommitNavigation is called. + speculative_rfh_c = root->render_manager()->speculative_frame_host(); EXPECT_EQ(speculative_rfh_c, rfh_devtools_agent->GetFrameHostForTesting()); // 4.c) Navigation: Commit.
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 72b7f5be..0ac40834 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -263,6 +263,7 @@ switches::kProfilingFlush, switches::kRunAllCompositorStagesBeforeDraw, switches::kSkiaFontCacheLimitMb, + switches::kSkiaGraphiteBackend, switches::kSkiaResourceCacheLimitMb, switches::kTestGLLib, switches::kTraceToConsole,
diff --git a/content/browser/indexed_db/database_impl.cc b/content/browser/indexed_db/database_impl.cc index 0cfabb6..f045393 100644 --- a/content/browser/indexed_db/database_impl.cc +++ b/content/browser/indexed_db/database_impl.cc
@@ -521,23 +521,22 @@ std::move(callbacks))); } -void DatabaseImpl::DeleteRange( - int64_t transaction_id, - int64_t object_store_id, - const IndexedDBKeyRange& key_range, - mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> - pending_callbacks) { +void DatabaseImpl::DeleteRange(int64_t transaction_id, + int64_t object_store_id, + const IndexedDBKeyRange& key_range, + DeleteRangeCallback success_callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - auto callbacks = base::MakeRefCounted<IndexedDBCallbacks>( - dispatcher_host_->AsWeakPtr(), bucket_info_, std::move(pending_callbacks), - idb_runner_); - if (!connection_->IsConnected()) + if (!connection_->IsConnected()) { + std::move(success_callback).Run(/*success=*/false); return; + } IndexedDBTransaction* transaction = connection_->GetTransaction(transaction_id); - if (!transaction) + if (!transaction) { + std::move(success_callback).Run(/*success=*/false); return; + } if (!transaction->IsAcceptingRequests()) { // TODO(https://crbug.com/1249908): If the transaction was already committed @@ -545,13 +544,15 @@ // This branch however also includes cases where the browser process aborted // the transaction, as currently we don't distinguish that state from the // transaction having been committed. So for now simply ignore the request. + std::move(success_callback).Run(/*success=*/false); return; } - transaction->ScheduleTask(BindWeakOperation( - &IndexedDBDatabase::DeleteRangeOperation, - connection_->database()->AsWeakPtr(), object_store_id, - std::make_unique<IndexedDBKeyRange>(key_range), std::move(callbacks))); + transaction->ScheduleTask( + BindWeakOperation(&IndexedDBDatabase::DeleteRangeOperation, + connection_->database()->AsWeakPtr(), object_store_id, + std::make_unique<IndexedDBKeyRange>(key_range), + std::move(success_callback))); } void DatabaseImpl::GetKeyGeneratorCurrentNumber(
diff --git a/content/browser/indexed_db/database_impl.h b/content/browser/indexed_db/database_impl.h index 7a5b96e..b41de35 100644 --- a/content/browser/indexed_db/database_impl.h +++ b/content/browser/indexed_db/database_impl.h
@@ -105,8 +105,7 @@ void DeleteRange(int64_t transaction_id, int64_t object_store_id, const blink::IndexedDBKeyRange& key_range, - mojo::PendingAssociatedRemote<blink::mojom::IDBCallbacks> - pending_callbacks) override; + DeleteRangeCallback success_callback) override; void GetKeyGeneratorCurrentNumber( int64_t transaction_id, int64_t object_store_id,
diff --git a/content/browser/indexed_db/indexed_db_callbacks.cc b/content/browser/indexed_db/indexed_db_callbacks.cc index bd022502..d0eb5c2e 100644 --- a/content/browser/indexed_db/indexed_db_callbacks.cc +++ b/content/browser/indexed_db/indexed_db_callbacks.cc
@@ -223,22 +223,6 @@ complete_ = true; } -void IndexedDBCallbacks::OnSuccess() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DCHECK(!complete_); - - DCHECK_EQ(blink::mojom::IDBDataLoss::None, data_loss_); - - if (!callbacks_) - return; - if (!dispatcher_host_) { - OnConnectionError(); - return; - } - callbacks_->Success(); - complete_ = true; -} - void IndexedDBCallbacks::OnConnectionError() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); callbacks_.reset();
diff --git a/content/browser/indexed_db/indexed_db_callbacks.h b/content/browser/indexed_db/indexed_db_callbacks.h index 40f9f2c5..6c16206c 100644 --- a/content/browser/indexed_db/indexed_db_callbacks.h +++ b/content/browser/indexed_db/indexed_db_callbacks.h
@@ -34,7 +34,6 @@ namespace content { class IndexedDBConnection; -class IndexedDBCursor; class IndexedDBDatabase; struct IndexedDBDataLossInfo; @@ -69,9 +68,6 @@ // IndexedDBDatabase::GetKeyGeneratorCurrentNumber virtual void OnSuccess(int64_t value); - // IndexedDBCursor::Continue / Advance (when complete) - virtual void OnSuccess(); - void OnConnectionError(); bool is_complete() const { return complete_; }
diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc index daa2b2e..b87e56a 100644 --- a/content/browser/indexed_db/indexed_db_database.cc +++ b/content/browser/indexed_db/indexed_db_database.cc
@@ -1617,22 +1617,24 @@ Status IndexedDBDatabase::DeleteRangeOperation( int64_t object_store_id, std::unique_ptr<IndexedDBKeyRange> key_range, - scoped_refptr<IndexedDBCallbacks> callbacks, + blink::mojom::IDBDatabase::DeleteRangeCallback success_callback, IndexedDBTransaction* transaction) { TRACE_EVENT1("IndexedDB", "IndexedDBDatabase::DeleteRangeOperation", "txn.id", transaction->id()); - if (!IsObjectStoreIdInMetadata(object_store_id)) - return leveldb::Status::InvalidArgument("Invalid object_store_id."); - - Status s = backing_store_->DeleteRange(transaction->BackingStoreTransaction(), - id(), object_store_id, *key_range); - if (!s.ok()) - return s; - callbacks->OnSuccess(); - factory_->NotifyIndexedDBContentChanged( - bucket_locator(), metadata_.name, - metadata_.object_stores[object_store_id].name); + Status s; + if (IsObjectStoreIdInMetadata(object_store_id)) { + s = backing_store_->DeleteRange(transaction->BackingStoreTransaction(), + id(), object_store_id, *key_range); + } else { + s = leveldb::Status::InvalidArgument("Invalid object_store_id."); + } + if (s.ok()) { + factory_->NotifyIndexedDBContentChanged( + bucket_locator(), metadata_.name, + metadata_.object_stores[object_store_id].name); + } + std::move(success_callback).Run(s.ok()); return s; }
diff --git a/content/browser/indexed_db/indexed_db_database.h b/content/browser/indexed_db/indexed_db_database.h index 385c698..2ab63b7 100644 --- a/content/browser/indexed_db/indexed_db_database.h +++ b/content/browser/indexed_db/indexed_db_database.h
@@ -285,7 +285,7 @@ leveldb::Status DeleteRangeOperation( int64_t object_store_id, std::unique_ptr<blink::IndexedDBKeyRange> key_range, - scoped_refptr<IndexedDBCallbacks> callbacks, + blink::mojom::IDBDatabase::DeleteRangeCallback success_callback, IndexedDBTransaction* transaction); leveldb::Status GetKeyGeneratorCurrentNumberOperation(
diff --git a/content/browser/indexed_db/indexed_db_unittest.cc b/content/browser/indexed_db/indexed_db_unittest.cc index b7533b912..b60f2375 100644 --- a/content/browser/indexed_db/indexed_db_unittest.cc +++ b/content/browser/indexed_db/indexed_db_unittest.cc
@@ -439,7 +439,6 @@ ForceCloseDBCallbacks(const ForceCloseDBCallbacks&) = delete; ForceCloseDBCallbacks& operator=(const ForceCloseDBCallbacks&) = delete; - void OnSuccess() override {} void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, const IndexedDBDatabaseMetadata& metadata) override { connection_ = std::move(connection);
diff --git a/content/browser/indexed_db/mock_indexed_db_callbacks.cc b/content/browser/indexed_db/mock_indexed_db_callbacks.cc index c69d57d..7293f4764 100644 --- a/content/browser/indexed_db/mock_indexed_db_callbacks.cc +++ b/content/browser/indexed_db/mock_indexed_db_callbacks.cc
@@ -36,8 +36,6 @@ error_called_ = true; } -void MockIndexedDBCallbacks::OnSuccess() {} - void MockIndexedDBCallbacks::OnSuccess(int64_t result) {} void MockIndexedDBCallbacks::OnSuccess(
diff --git a/content/browser/indexed_db/mock_indexed_db_callbacks.h b/content/browser/indexed_db/mock_indexed_db_callbacks.h index 25cf89a..3e66870 100644 --- a/content/browser/indexed_db/mock_indexed_db_callbacks.h +++ b/content/browser/indexed_db/mock_indexed_db_callbacks.h
@@ -30,7 +30,6 @@ void OnError(const IndexedDBDatabaseError& error) override; - void OnSuccess() override; void OnSuccess(int64_t result) override; void OnSuccess(std::unique_ptr<IndexedDBConnection> connection, const blink::IndexedDBDatabaseMetadata& metadata) override;
diff --git a/content/browser/media/capture/desktop_capture_device_unittest.cc b/content/browser/media/capture/desktop_capture_device_unittest.cc index 6a34b4d..2a862a6 100644 --- a/content/browser/media/capture/desktop_capture_device_unittest.cc +++ b/content/browser/media/capture/desktop_capture_device_unittest.cc
@@ -21,6 +21,7 @@ #include "base/strings/string_number_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/task/single_thread_task_runner.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/test_mock_time_task_runner.h" #include "base/test/test_timeouts.h" #include "base/time/tick_clock.h" @@ -75,6 +76,8 @@ // frame test. const uint8_t kFakePixelValueFirst = 2; +const char kFrameIsRefresh[] = "WebRTC.DesktopCapture.FrameIsRefresh.Screen"; + // Creates a DesktopFrame that has the first pixel bytes set to // kFakePixelValueFirst, and the rest of the bytes set to kFakePixelValue, for // UnpackedFrame and InvertedFrame verification. @@ -300,6 +303,7 @@ return result; } + base::HistogramTester histogram_tester_; std::unique_ptr<DesktopCaptureDevice> capture_device_; std::unique_ptr<webrtc::DesktopFrame> output_frame_; }; @@ -626,6 +630,7 @@ capture_device_->RequestRefreshFrame(); capture_device_->StopAndDeAllocate(); + histogram_tester_.ExpectTotalCount(kFrameIsRefresh, 0); } // This test verifies that calling RequestRefreshFrame() on the screen capturer @@ -663,33 +668,27 @@ EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); done_event.Reset(); capture_device_->StopAndDeAllocate(); + histogram_tester_.ExpectBucketCount(kFrameIsRefresh, false, 1); + histogram_tester_.ExpectTotalCount(kFrameIsRefresh, 1); capture_device_->RequestRefreshFrame(); + histogram_tester_.ExpectTotalCount(kFrameIsRefresh, 1); } -// Verify that calling RequestRefreshFrame() results in a copy of the last -// captured frame being sent to the client via OnIncomingCapturedData(). -// -// TODO(crbug.com/1421656) The test is currently broken due to a change that -// was required to fix a serious flickering issue. Attempts will be made to -// enable this test again in a separate CL (and possibly in a new shape) once -// the main fix has landed. -TEST_F(DesktopCaptureDeviceTest, DISABLED_RequestRefreshFrameSendsLatestFrame) { +// Verify that calling RequestRefreshFrame() results in an extra frame being +// captured and sent to the client. The content should not be the same as for +// the first default frame. +TEST_F(DesktopCaptureDeviceTest, RequestRefreshFrameSendsExtraFrame) { FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); CreateScreenCaptureDevice( std::unique_ptr<webrtc::DesktopCapturer>(mock_capturer)); - media::VideoCaptureFormat format; + FormatChecker format_checker(gfx::Size(kTestFrameWidth1, kTestFrameHeight1), + gfx::Size(kTestFrameWidth1, kTestFrameHeight1)); base::WaitableEvent done_event( base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); - int frame_size = 0; - output_frame_ = std::make_unique<webrtc::BasicDesktopFrame>( - webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1)); - - // Ensure that we receive two calls to OnIncomingCapturedData() even if only - // one frame is captured and that the received second frame (which is a - // result of calling RequestRefreshFrame) is a copy of the first frame. + // Ensure that we receive two calls to OnIncomingCapturedData(). std::unique_ptr<media::MockVideoCaptureDeviceClient> client( CreateMockVideoCaptureDeviceClient()); EXPECT_CALL(*client, OnError(_, _, _)).Times(0); @@ -697,8 +696,8 @@ EXPECT_CALL(*client, OnIncomingCapturedData(_, _, _, _, _, _, _, _, _)) .Times(2) .WillRepeatedly( - DoAll(Invoke(this, &DesktopCaptureDeviceTest::CopyFrame), - SaveArg<1>(&frame_size), + DoAll(WithArg<2>(Invoke(&format_checker, + &FormatChecker::ExpectAcceptableSize)), InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal))); media::VideoCaptureParams capture_params; @@ -708,21 +707,17 @@ capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; capture_device_->AllocateAndStart(capture_params, std::move(client)); - - EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); - done_event.Reset(); - capture_device_->RequestRefreshFrame(); - capture_device_->StopAndDeAllocate(); - // Verifies that |output_frame_| has the same pixel values and size as the - // first (and only) captured frame. - std::unique_ptr<webrtc::BasicDesktopFrame> expected_frame = CreateBasicFrame( - webrtc::DesktopSize(kTestFrameWidth1, kTestFrameHeight1)); - EXPECT_EQ(output_frame_->stride() * output_frame_->size().height(), - frame_size); - EXPECT_EQ(0, - memcmp(output_frame_->data(), expected_frame->data(), frame_size)); + // Capture two frames; one default (the first) and one refresh (the second). + // The mock for OnIncomingCapturedData() will use FormatChecker to examine the + // format of each frame being delivered. + EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); + histogram_tester_.ExpectBucketCount(kFrameIsRefresh, false, 1); + EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); + capture_device_->StopAndDeAllocate(); + histogram_tester_.ExpectBucketCount(kFrameIsRefresh, true, 1); + histogram_tester_.ExpectTotalCount(kFrameIsRefresh, 2); } // Verifies that only captured frames which contains updated regions are @@ -739,10 +734,7 @@ CreateScreenCaptureDevice( std::unique_ptr<webrtc::DesktopCapturer>(mock_capturer)); - base::WaitableEvent done_event1( - base::WaitableEvent::ResetPolicy::AUTOMATIC, - base::WaitableEvent::InitialState::NOT_SIGNALED); - base::WaitableEvent done_event2( + base::WaitableEvent done_event( base::WaitableEvent::ResetPolicy::AUTOMATIC, base::WaitableEvent::InitialState::NOT_SIGNALED); @@ -754,8 +746,9 @@ EXPECT_CALL(*client, OnError).Times(0); EXPECT_CALL(*client, OnFrameDropped).Times(0); EXPECT_CALL(*client, OnIncomingCapturedData) - .WillOnce(InvokeWithoutArgs(&done_event1, &base::WaitableEvent::Signal)) - .WillOnce(InvokeWithoutArgs(&done_event2, &base::WaitableEvent::Signal)); + .Times(2) + .WillRepeatedly( + InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)); media::VideoCaptureParams capture_params; capture_params.requested_format.frame_size.SetSize(kTestFrameWidth3, @@ -767,13 +760,70 @@ // Ensure that the client gets two captured frames but the capturer had to // capture three frames to do so since frame #2 is marked as "not updated". - EXPECT_TRUE(done_event1.TimedWait(TestTimeouts::action_max_timeout())); - EXPECT_TRUE(done_event2.TimedWait(TestTimeouts::action_max_timeout())); + EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); + EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); EXPECT_EQ(mock_capturer->captured_frames(), 3); capture_device_->StopAndDeAllocate(); } +// Verifies that RequestRefreshFrame() forces a new captured frame even when the +// content has not changed since the last frame. This is to ensure that the +// client gets a new frame when explicitly asking for it. +TEST_F(DesktopCaptureDeviceTest, + RequestRefreshFrameSendsFrameEvenIfNoRegionsAreUpdated) { + FakeScreenCapturer* mock_capturer = new FakeScreenCapturer(); + // Marks captured frame #2, #4, etc. (first frame is #1) as not updated. + mock_capturer->set_generate_non_updated_frames(true, 2); + CreateScreenCaptureDevice( + std::unique_ptr<webrtc::DesktopCapturer>(mock_capturer)); + + base::WaitableEvent done_event( + base::WaitableEvent::ResetPolicy::AUTOMATIC, + base::WaitableEvent::InitialState::NOT_SIGNALED); + + // Drive three frames to the registered client. A non-forwarded captured frame + // due to "no-change" is silently discarded by the VideoCaptureDevice but the + // rate of capturing new frames is not affected. + std::unique_ptr<media::MockVideoCaptureDeviceClient> client( + CreateMockVideoCaptureDeviceClient()); + EXPECT_CALL(*client, OnError).Times(0); + EXPECT_CALL(*client, OnFrameDropped).Times(0); + EXPECT_CALL(*client, OnIncomingCapturedData) + .Times(3) + .WillRepeatedly( + InvokeWithoutArgs(&done_event, &base::WaitableEvent::Signal)); + + media::VideoCaptureParams capture_params; + capture_params.requested_format.frame_size.SetSize(kTestFrameWidth3, + kTestFrameHeight3); + capture_params.requested_format.frame_rate = kFrameRate; + capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420; + + capture_device_->AllocateAndStart(capture_params, std::move(client)); + + // Ensure that the client gets two captured frames but the capturer had to + // capture three frames to do so since frame #2 is marked as "not updated". + for (int i = 0; i < 2; ++i) { + EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); + } + EXPECT_EQ(mock_capturer->captured_frames(), 3); + histogram_tester_.ExpectBucketCount(kFrameIsRefresh, false, 3); + histogram_tester_.ExpectTotalCount(kFrameIsRefresh, 3); + + // Next frame is #4 and it will be marked as "not updated". Asking for a + // refresh at this point in time should override the default + // "0Hz functionality" and forward the new refresh frame. + capture_device_->RequestRefreshFrame(); + EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout())); + EXPECT_EQ(mock_capturer->captured_frames(), 4); + histogram_tester_.ExpectBucketCount(kFrameIsRefresh, true, 1); + histogram_tester_.ExpectBucketCount(kFrameIsRefresh, false, 3); + histogram_tester_.ExpectTotalCount(kFrameIsRefresh, 4); + + capture_device_->StopAndDeAllocate(); +} + class DesktopCaptureDeviceThrottledTest : public DesktopCaptureDeviceTest { public: // Capture frames at kFrameRate for a duration of total_capture_duration and
diff --git a/content/browser/network/network_service_util_internal.cc b/content/browser/network/network_service_util_internal.cc new file mode 100644 index 0000000..effb3a0 --- /dev/null +++ b/content/browser/network/network_service_util_internal.cc
@@ -0,0 +1,31 @@ +// 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 "content/browser/network/network_service_util_internal.h" + +#include "base/check.h" + +namespace { +absl::optional<bool> g_force_network_service_process_in_or_out; + +} // namespace + +namespace content { + +void ForceInProcessNetworkServiceImpl() { + DCHECK(!g_force_network_service_process_in_or_out || + *g_force_network_service_process_in_or_out); + g_force_network_service_process_in_or_out = true; +} +void ForceOutOfProcessNetworkServiceImpl() { + DCHECK(!g_force_network_service_process_in_or_out || + !*g_force_network_service_process_in_or_out); + g_force_network_service_process_in_or_out = false; +} + +absl::optional<bool> GetForcedNetworkServiceProcessInOrOut() { + return g_force_network_service_process_in_or_out; +} + +} // namespace content
diff --git a/content/browser/network/network_service_util_internal.h b/content/browser/network/network_service_util_internal.h new file mode 100644 index 0000000..e5ab0ef5 --- /dev/null +++ b/content/browser/network/network_service_util_internal.h
@@ -0,0 +1,23 @@ +// 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 CONTENT_BROWSER_NETWORK_NETWORK_SERVICE_UTIL_INTERNAL_H_ +#define CONTENT_BROWSER_NETWORK_NETWORK_SERVICE_UTIL_INTERNAL_H_ + +#include "build/build_config.h" +#include "content/common/content_export.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace content { + +// Sets the flag of where the network service is forced to be running in the +// browser process. +CONTENT_EXPORT void ForceInProcessNetworkServiceImpl(); +CONTENT_EXPORT void ForceOutOfProcessNetworkServiceImpl(); +// Returns nullopt if no flag is forced. +CONTENT_EXPORT absl::optional<bool> GetForcedNetworkServiceProcessInOrOut(); + +} // namespace content + +#endif // CONTENT_BROWSER_NETWORK_NETWORK_SERVICE_UTIL_INTERNAL_H_
diff --git a/content/browser/network/sandboxed_http_cache_browsertest.cc b/content/browser/network/sandboxed_http_cache_browsertest.cc index 2fa283c..4046842 100644 --- a/content/browser/network/sandboxed_http_cache_browsertest.cc +++ b/content/browser/network/sandboxed_http_cache_browsertest.cc
@@ -15,6 +15,7 @@ #include "base/threading/thread_restrictions.h" #include "build/build_config.h" #include "content/browser/network/http_cache_backend_file_operations_factory.h" +#include "content/browser/network/network_service_util_internal.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_util.h" @@ -65,11 +66,15 @@ NonSandboxedNetworkServiceBrowserTest() { std::vector<base::test::FeatureRef> kDisabledFeatures = { sandbox::policy::features::kNetworkServiceSandbox, - features::kNetworkServiceInProcess, }; scoped_feature_list_.InitWithFeatures( /*enabled_features=*/{}, /*disabled_features=*/kDisabledFeatures); + ForceOutOfProcessNetworkServiceImpl(); + } + + void SetUpOnMainThread() override { + ASSERT_TRUE(IsOutOfProcessNetworkService()); } private: @@ -110,9 +115,8 @@ sandbox::policy::features::kNetworkServiceSandbox, #endif }; - scoped_feature_list_.InitWithFeatures( - enabled_features, - /*disabled_features=*/{features::kNetworkServiceInProcess}); + scoped_feature_list_.InitWithFeatures(enabled_features, {}); + ForceOutOfProcessNetworkServiceImpl(); } void SetUp() override { @@ -158,6 +162,10 @@ ContentBrowserTest::SetUp(); } + void SetUpOnMainThread() override { + ASSERT_TRUE(IsOutOfProcessNetworkService()); + } + mojo::Remote<SimpleCache> CreateSimpleCache() { base::RunLoop run_loop;
diff --git a/content/browser/network/sandboxed_nqe_browsertest.cc b/content/browser/network/sandboxed_nqe_browsertest.cc index aa45bb06..1348a99f 100644 --- a/content/browser/network/sandboxed_nqe_browsertest.cc +++ b/content/browser/network/sandboxed_nqe_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/containers/contains.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "content/browser/network/network_service_util_internal.h" #include "content/public/browser/network_service_instance.h" #include "content/public/browser/network_service_util.h" #include "content/public/common/content_features.h" @@ -89,12 +90,11 @@ sandbox::policy::features::kNetworkServiceSandbox, #endif }; - scoped_feature_list_.InitWithFeatures( - enabled_features, - /*disabled_features=*/{features::kNetworkServiceInProcess}); + scoped_feature_list_.InitWithFeatures(enabled_features, {}); + ForceOutOfProcessNetworkServiceImpl(); } - void SetUp() override { + void SetUpOnMainThread() override { #if BUILDFLAG(IS_WIN) if (!sandbox::features::IsAppContainerSandboxSupported()) { // On *some* Windows, sandboxing cannot be enabled. We skip all the tests @@ -107,8 +107,6 @@ // test body from running when one of the assertions fails. ASSERT_TRUE(IsOutOfProcessNetworkService()); ASSERT_TRUE(sandbox::policy::features::IsNetworkSandboxEnabled()); - - ContentBrowserTest::SetUp(); } // Simulates a network quality change.
diff --git a/content/browser/network_service_browsertest.cc b/content/browser/network_service_browsertest.cc index 9928f14..6fe6a6c 100644 --- a/content/browser/network_service_browsertest.cc +++ b/content/browser/network_service_browsertest.cc
@@ -19,6 +19,7 @@ #include "base/threading/platform_thread.h" #include "base/time/time.h" #include "build/build_config.h" +#include "content/browser/network/network_service_util_internal.h" #include "content/browser/network_service_instance_impl.h" #include "content/browser/storage_partition_impl.h" #include "content/public/browser/browser_context.h" @@ -402,8 +403,11 @@ class NetworkServiceOutOfProcessBrowserTest : public NetworkServiceBrowserTest { public: NetworkServiceOutOfProcessBrowserTest() { - scoped_feature_list_.InitAndDisableFeature( - features::kNetworkServiceInProcess); + ForceOutOfProcessNetworkServiceImpl(); + } + + void SetUpOnMainThread() override { + ASSERT_TRUE(IsOutOfProcessNetworkService()); } private:
diff --git a/content/browser/network_service_client.cc b/content/browser/network_service_client.cc index 336a9078..47e3248 100644 --- a/content/browser/network_service_client.cc +++ b/content/browser/network_service_client.cc
@@ -327,6 +327,13 @@ sent_bytes); } +void NetworkServiceClient::OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) { + std::move(callback).Run(); +} + void NetworkServiceClient::Clone( mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver> observer) {
diff --git a/content/browser/network_service_client.h b/content/browser/network_service_client.h index 4d129ff..54aaf3b 100644 --- a/content/browser/network_service_client.h +++ b/content/browser/network_service_client.h
@@ -120,6 +120,10 @@ void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash, int64_t recv_bytes, int64_t sent_bytes) override; + void OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) override; void Clone( mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver> listener) override;
diff --git a/content/browser/network_service_instance_impl.cc b/content/browser/network_service_instance_impl.cc index 2e8bfc3..13dec159 100644 --- a/content/browser/network_service_instance_impl.cc +++ b/content/browser/network_service_instance_impl.cc
@@ -783,7 +783,7 @@ } void ForceCreateNetworkServiceDirectlyForTesting() { - ForceInProcessNetworkService(true); + ForceInProcessNetworkService(); g_force_create_network_service_directly = true; }
diff --git a/content/browser/preloading/prefetch/prefetch_container.cc b/content/browser/preloading/prefetch/prefetch_container.cc index e8fce307..7784e60 100644 --- a/content/browser/preloading/prefetch/prefetch_container.cc +++ b/content/browser/preloading/prefetch/prefetch_container.cc
@@ -252,25 +252,13 @@ } } -std::string GetEagernessHistogramSuffix( - const blink::mojom::SpeculationEagerness& eagerness) { - switch (eagerness) { - case blink::mojom::SpeculationEagerness::kEager: - return "Eager"; - case blink::mojom::SpeculationEagerness::kModerate: - return "Moderate"; - case blink::mojom::SpeculationEagerness::kConservative: - return "Conservative"; - } -} - void RecordWasBlockedUntilHeadWhenServingHistogram( const blink::mojom::SpeculationEagerness& eagerness, bool blocked_until_head) { base::UmaHistogramBoolean( base::StringPrintf( "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", - GetEagernessHistogramSuffix(eagerness).c_str()), + GetPrefetchEagernessHistogramSuffix(eagerness).c_str()), blocked_until_head); } @@ -282,7 +270,7 @@ base::StringPrintf( "PrefetchProxy.AfterClick.BlockUntilHeadDuration.%s.%s", served ? "Served" : "NotServed", - GetEagernessHistogramSuffix(eagerness).c_str()), + GetPrefetchEagernessHistogramSuffix(eagerness).c_str()), block_until_head_duration); }
diff --git a/content/browser/preloading/prefetch/prefetch_params.cc b/content/browser/preloading/prefetch/prefetch_params.cc index 59e41e1e..c0a2baf 100644 --- a/content/browser/preloading/prefetch/prefetch_params.cc +++ b/content/browser/preloading/prefetch/prefetch_params.cc
@@ -240,6 +240,18 @@ } } +std::string GetPrefetchEagernessHistogramSuffix( + const blink::mojom::SpeculationEagerness& eagerness) { + switch (eagerness) { + case blink::mojom::SpeculationEagerness::kEager: + return "Eager"; + case blink::mojom::SpeculationEagerness::kModerate: + return "Moderate"; + case blink::mojom::SpeculationEagerness::kConservative: + return "Conservative"; + } +} + bool IsContentPrefetchHoldback() { return base::GetFieldTrialParamByFeatureAsBool( features::kPrefetchUseContentRefactor, "prefetch_holdback", false);
diff --git a/content/browser/preloading/prefetch/prefetch_params.h b/content/browser/preloading/prefetch/prefetch_params.h index 5ec2cd6..ae9166c6 100644 --- a/content/browser/preloading/prefetch/prefetch_params.h +++ b/content/browser/preloading/prefetch/prefetch_params.h
@@ -114,6 +114,10 @@ bool PrefetchShouldBlockUntilHead( blink::mojom::SpeculationEagerness prefetch_eagerness); +// Gets the histogram suffix to use for the given eagerness parameter. +CONTENT_EXPORT std::string GetPrefetchEagernessHistogramSuffix( + const blink::mojom::SpeculationEagerness& eagerness); + // Returns whether the client is involved in the Holdback Finch // experiment group. bool IsContentPrefetchHoldback();
diff --git a/content/browser/preloading/prefetch/prefetch_service.cc b/content/browser/preloading/prefetch/prefetch_service.cc index 6d4653f..58cb706 100644 --- a/content/browser/preloading/prefetch/prefetch_service.cc +++ b/content/browser/preloading/prefetch/prefetch_service.cc
@@ -1442,6 +1442,7 @@ DVLOG(1) << "PrefetchService::GetPrefetchToServe(" << url << "): PrefetchContainer is not servable"; + prefetch_container->OnReturnPrefetchToServe(/*served=*/false); std::move(on_prefetch_to_serve_ready).Run(nullptr); }
diff --git a/content/browser/preloading/prefetch/prefetch_service_unittest.cc b/content/browser/preloading/prefetch/prefetch_service_unittest.cc index 36526650..666e460 100644 --- a/content/browser/preloading/prefetch/prefetch_service_unittest.cc +++ b/content/browser/preloading/prefetch/prefetch_service_unittest.cc
@@ -217,7 +217,9 @@ class PrefetchServiceTest : public RenderViewHostTestHarness { public: PrefetchServiceTest() - : test_url_loader_factory_(/*observe_loader_requests=*/true), + : RenderViewHostTestHarness( + base::test::TaskEnvironment::TimeSource::MOCK_TIME), + test_url_loader_factory_(/*observe_loader_requests=*/true), test_shared_url_loader_factory_( base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)) {} @@ -503,8 +505,6 @@ void CompleteResponseAndWait(net::Error net_error, uint32_t expected_total_body_size) { - ASSERT_TRUE(producer_handle_); - network::TestURLLoaderFactory::PendingRequest* request = test_url_loader_factory_.GetPendingRequest(0); ASSERT_TRUE(request); @@ -777,6 +777,14 @@ PreloadingHoldbackStatus::kAllowed, PreloadingTriggeringOutcome::kReady, PreloadingFailureReason::kUnspecified); + + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + GetPrefetchEagernessHistogramSuffix( + blink::mojom::SpeculationEagerness::kEager) + .c_str()), + false, 1); } TEST_F(PrefetchServiceTest, NoPrefetchingPreloadingDisabled) { @@ -4632,6 +4640,7 @@ {{features::kPrefetchUseContentRefactor, {{"ineligible_decoy_request_probability", "0"}, {"prefetch_container_lifetime_s", "-1"}, + {"prefetch_timeout_ms", "10000"}, {"block_until_head_eager_prefetch", "true"}, {"block_until_head_moderate_prefetch", "true"}, {"block_until_head_conservative_prefetch", "true"}}}}, @@ -4680,6 +4689,8 @@ &serveable_prefetch_container, &get_prefetch_run_loop)); EXPECT_FALSE(serveable_prefetch_container); + task_environment()->FastForwardBy(base::Milliseconds(500)); + // Sends the head of the prefetch response. This should trigger the above // callback. SendHeadOfResponseAndWait(net::HTTP_OK, kHTMLMimeType, @@ -4737,6 +4748,19 @@ PreloadingHoldbackStatus::kAllowed, PreloadingTriggeringOutcome::kReady, PreloadingFailureReason::kUnspecified); + + std::string histogram_suffix = + GetPrefetchEagernessHistogramSuffix(GetParam()); + histogram_tester.ExpectUniqueTimeSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.BlockUntilHeadDuration.Served.%s", + histogram_suffix.c_str()), + base::Milliseconds(500), 1); + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + histogram_suffix.c_str()), + true, 1); } // TODO(crbug.com/1396460): Test flaky on lacros trybots. @@ -4792,6 +4816,8 @@ &serveable_prefetch_container, &get_prefetch_run_loop)); EXPECT_FALSE(serveable_prefetch_container); + task_environment()->FastForwardBy(base::Milliseconds(600)); + // Sends the head of the prefetch response. This should trigger the above // callback. SendHeadOfResponseAndWait( @@ -4851,6 +4877,19 @@ PreloadingTriggeringOutcome::kReady, PreloadingFailureReason::kUnspecified, /*accurate*/ true); + + std::string histogram_suffix = + GetPrefetchEagernessHistogramSuffix(GetParam()); + histogram_tester.ExpectUniqueTimeSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.BlockUntilHeadDuration.Served.%s", + histogram_suffix.c_str()), + base::Milliseconds(600), 1); + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + histogram_suffix.c_str()), + true, 1); } // TODO(crbug.com/1396460): Test flaky on lacros trybots. @@ -4907,6 +4946,8 @@ &is_nav_unblocked, &get_prefetch_run_loop)); EXPECT_FALSE(is_nav_unblocked); + task_environment()->FastForwardBy(base::Milliseconds(700)); + // Sends the head of the prefetch response. This should trigger the above // callback with a nullptr argument. SendHeadOfResponseAndWait(net::HTTP_OK, kHTMLMimeType, @@ -4959,6 +5000,19 @@ PreloadingTriggeringOutcome::kReady, PreloadingFailureReason::kUnspecified, /*accurate*/ false); + + std::string histogram_suffix = + GetPrefetchEagernessHistogramSuffix(GetParam()); + histogram_tester.ExpectUniqueTimeSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.BlockUntilHeadDuration.NotServed.%s", + histogram_suffix.c_str()), + base::Milliseconds(700), 1); + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + histogram_suffix.c_str()), + true, 1); } // TODO(crbug.com/1396460): Test flaky on lacros trybots. @@ -5015,6 +5069,8 @@ &is_nav_unblocked, &get_prefetch_run_loop)); EXPECT_FALSE(is_nav_unblocked); + task_environment()->FastForwardBy(base::Milliseconds(400)); + // Sends the head of the prefetch response. This should trigger the above // callback with a nullptr argument. SendHeadOfResponseAndWait( @@ -5068,6 +5124,19 @@ PreloadingTriggeringOutcome::kReady, PreloadingFailureReason::kUnspecified, /*accurate*/ false); + + std::string histogram_suffix = + GetPrefetchEagernessHistogramSuffix(GetParam()); + histogram_tester.ExpectUniqueTimeSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.BlockUntilHeadDuration.NotServed.%s", + histogram_suffix.c_str()), + base::Milliseconds(400), 1); + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + histogram_suffix.c_str()), + true, 1); } // TODO(crbug.com/1396460): Test flaky on lacros trybots. @@ -5113,6 +5182,8 @@ &serveable_prefetch_container, &get_prefetch_run_loop)); EXPECT_FALSE(serveable_prefetch_container); + task_environment()->FastForwardBy(base::Milliseconds(800)); + // Adding a cookie after while blocking until the head is received will cause // it to fail. ASSERT_TRUE(SetCookie(GURL("https://example.com"), "testing")); @@ -5167,6 +5238,217 @@ PreloadingTriggeringOutcome::kFailure, ToPreloadingFailureReason( PrefetchStatus::kPrefetchNotUsedCookiesChanged)); + + std::string histogram_suffix = + GetPrefetchEagernessHistogramSuffix(GetParam()); + histogram_tester.ExpectUniqueTimeSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.BlockUntilHeadDuration.NotServed.%s", + histogram_suffix.c_str()), + base::Milliseconds(800), 1); + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + histogram_suffix.c_str()), + true, 1); +} + +// TODO(crbug.com/1396460): Test flaky on lacros trybots. +#if BUILDFLAG(IS_CHROMEOS) +#define MAYBE_FailedTimeoutWhileBlockUntilHead \ + DISABLED_FailedTimeoutWhileBlockUntilHead +#else +#define MAYBE_FailedTimeoutWhileBlockUntilHead FailedTimeoutWhileBlockUntilHead +#endif +TEST_P(PrefetchServiceAlwaysBlockUntilHeadTest, + MAYBE_FailedTimeoutWhileBlockUntilHead) { + base::HistogramTester histogram_tester; + + MakePrefetchService( + std::make_unique<testing::NiceMock<MockPrefetchServiceDelegate>>()); + + MakePrefetchOnMainFrame( + GURL("https://example.com"), + PrefetchType(/*use_prefetch_proxy=*/true, GetParam())); + base::RunLoop().RunUntilIdle(); + + VerifyCommonRequestState(GURL("https://example.com"), + /*use_prefetch_proxy=*/true); + + // Navigate to the URL before the head of the prefetch response is received + Navigate(GURL("https://example.com"), main_rfh()->GetFrameToken()); + + // Request the prefetch from the PrefetchService. The given callback shouldn't + // be called until after the head is received. + base::RunLoop get_prefetch_run_loop; + base::WeakPtr<PrefetchContainer> serveable_prefetch_container; + prefetch_service_->GetPrefetchToServe( + PrefetchContainer::Key(main_rfh()->GetGlobalId(), + GURL("https://example.com")), + base::BindOnce( + [](base::WeakPtr<PrefetchContainer>* serveable_prefetch_container, + base::RunLoop* get_prefetch_run_loop, + base::WeakPtr<PrefetchContainer> prefetch_to_serve) { + *serveable_prefetch_container = prefetch_to_serve; + get_prefetch_run_loop->Quit(); + }, + &serveable_prefetch_container, &get_prefetch_run_loop)); + EXPECT_FALSE(serveable_prefetch_container); + + // If the prefetch times out while PrefetchService is blocking until head, + // then it should unblock without setting serveable_prefetch_container. + task_environment()->FastForwardBy(base::Milliseconds(10000)); + get_prefetch_run_loop.Run(); + EXPECT_FALSE(serveable_prefetch_container); + + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.ExistingPrefetchWithMatchingURL", false, 1); + histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.RespCode", + 0); + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.Mainframe.NetError", std::abs(net::ERR_TIMED_OUT), + 1); + histogram_tester.ExpectTotalCount( + "PrefetchProxy.Prefetch.Mainframe.BodyLength", 0); + histogram_tester.ExpectTotalCount( + "PrefetchProxy.Prefetch.Mainframe.TotalTime", 0); + histogram_tester.ExpectTotalCount( + "PrefetchProxy.Prefetch.Mainframe.ConnectTime", 0); + + absl::optional<PrefetchReferringPageMetrics> referring_page_metrics = + PrefetchReferringPageMetrics::GetForCurrentDocument(main_rfh()); + EXPECT_EQ(referring_page_metrics->prefetch_attempted_count, 1); + EXPECT_EQ(referring_page_metrics->prefetch_eligible_count, 1); + EXPECT_EQ(referring_page_metrics->prefetch_successful_count, 0); + + absl::optional<PrefetchServingPageMetrics> serving_page_metrics = + GetMetricsForMostRecentNavigation(); + ASSERT_TRUE(serving_page_metrics); + EXPECT_TRUE(serving_page_metrics->prefetch_status); + EXPECT_EQ(serving_page_metrics->prefetch_status.value(), + static_cast<int>(PrefetchStatus::kPrefetchFailedNetError)); + EXPECT_TRUE(serving_page_metrics->required_private_prefetch_proxy); + EXPECT_TRUE(serving_page_metrics->same_tab_as_prefetching_tab); + EXPECT_FALSE(serving_page_metrics->prefetch_header_latency); + + ExpectCorrectUkmLogs( + PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed, + PreloadingTriggeringOutcome::kFailure, + ToPreloadingFailureReason(PrefetchStatus::kPrefetchFailedNetError)); + + std::string histogram_suffix = + GetPrefetchEagernessHistogramSuffix(GetParam()); + histogram_tester.ExpectUniqueTimeSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.BlockUntilHeadDuration.NotServed.%s", + histogram_suffix.c_str()), + base::Milliseconds(10000), 1); + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + histogram_suffix.c_str()), + true, 1); +} + +// TODO(crbug.com/1396460): Test flaky on lacros trybots. +#if BUILDFLAG(IS_CHROMEOS) +#define MAYBE_FailedNetErrorWhileBlockUntilHead \ + DISABLED_FailedNetErrorWhileBlockUntilHead +#else +#define MAYBE_FailedNetErrorWhileBlockUntilHead \ + FailedNetErrorWhileBlockUntilHead +#endif +TEST_P(PrefetchServiceAlwaysBlockUntilHeadTest, + MAYBE_FailedNetErrorWhileBlockUntilHead) { + base::HistogramTester histogram_tester; + + MakePrefetchService( + std::make_unique<testing::NiceMock<MockPrefetchServiceDelegate>>()); + + MakePrefetchOnMainFrame( + GURL("https://example.com"), + PrefetchType(/*use_prefetch_proxy=*/true, GetParam())); + base::RunLoop().RunUntilIdle(); + + VerifyCommonRequestState(GURL("https://example.com"), + /*use_prefetch_proxy=*/true); + + // Navigate to the URL before the head of the prefetch response is received + Navigate(GURL("https://example.com"), main_rfh()->GetFrameToken()); + + // Request the prefetch from the PrefetchService. The given callback shouldn't + // be called until after the head is received. + base::RunLoop get_prefetch_run_loop; + base::WeakPtr<PrefetchContainer> serveable_prefetch_container; + prefetch_service_->GetPrefetchToServe( + PrefetchContainer::Key(main_rfh()->GetGlobalId(), + GURL("https://example.com")), + base::BindOnce( + [](base::WeakPtr<PrefetchContainer>* serveable_prefetch_container, + base::RunLoop* get_prefetch_run_loop, + base::WeakPtr<PrefetchContainer> prefetch_to_serve) { + *serveable_prefetch_container = prefetch_to_serve; + get_prefetch_run_loop->Quit(); + }, + &serveable_prefetch_container, &get_prefetch_run_loop)); + EXPECT_FALSE(serveable_prefetch_container); + + task_environment()->FastForwardBy(base::Milliseconds(300)); + + // If the prefetch encounters a net error while PrefetchService is blocking + // until head, then it should unblock without setting + // serveable_prefetch_container. + CompleteResponseAndWait(net::ERR_ACCESS_DENIED, 0); + get_prefetch_run_loop.Run(); + EXPECT_FALSE(serveable_prefetch_container); + + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.ExistingPrefetchWithMatchingURL", false, 1); + histogram_tester.ExpectTotalCount("PrefetchProxy.Prefetch.Mainframe.RespCode", + 0); + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.Mainframe.NetError", + std::abs(net::ERR_ACCESS_DENIED), 1); + histogram_tester.ExpectTotalCount( + "PrefetchProxy.Prefetch.Mainframe.BodyLength", 0); + histogram_tester.ExpectTotalCount( + "PrefetchProxy.Prefetch.Mainframe.TotalTime", 0); + histogram_tester.ExpectTotalCount( + "PrefetchProxy.Prefetch.Mainframe.ConnectTime", 0); + + absl::optional<PrefetchReferringPageMetrics> referring_page_metrics = + PrefetchReferringPageMetrics::GetForCurrentDocument(main_rfh()); + EXPECT_EQ(referring_page_metrics->prefetch_attempted_count, 1); + EXPECT_EQ(referring_page_metrics->prefetch_eligible_count, 1); + EXPECT_EQ(referring_page_metrics->prefetch_successful_count, 0); + + absl::optional<PrefetchServingPageMetrics> serving_page_metrics = + GetMetricsForMostRecentNavigation(); + ASSERT_TRUE(serving_page_metrics); + EXPECT_TRUE(serving_page_metrics->prefetch_status); + EXPECT_EQ(serving_page_metrics->prefetch_status.value(), + static_cast<int>(PrefetchStatus::kPrefetchFailedNetError)); + EXPECT_TRUE(serving_page_metrics->required_private_prefetch_proxy); + EXPECT_TRUE(serving_page_metrics->same_tab_as_prefetching_tab); + EXPECT_FALSE(serving_page_metrics->prefetch_header_latency); + + ExpectCorrectUkmLogs( + PreloadingEligibility::kEligible, PreloadingHoldbackStatus::kAllowed, + PreloadingTriggeringOutcome::kFailure, + ToPreloadingFailureReason(PrefetchStatus::kPrefetchFailedNetError)); + + std::string histogram_suffix = + GetPrefetchEagernessHistogramSuffix(GetParam()); + histogram_tester.ExpectUniqueTimeSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.BlockUntilHeadDuration.NotServed.%s", + histogram_suffix.c_str()), + base::Milliseconds(300), 1); + histogram_tester.ExpectUniqueSample( + base::StringPrintf( + "PrefetchProxy.AfterClick.WasBlockedUntilHeadWhenServing.%s", + histogram_suffix.c_str()), + true, 1); } INSTANTIATE_TEST_SUITE_P(
diff --git a/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc b/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc index d0523a0..c8c4b6e 100644 --- a/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc +++ b/content/browser/preloading/prefetch/prefetch_streaming_url_loader.cc
@@ -349,6 +349,9 @@ // Note that we may have already started serving the prefetch if it was // marked as servable in |OnReceiveResponse|. servable_ = false; + if (on_received_head_callback_) { + std::move(on_received_head_callback_).Run(); + } } std::move(on_prefetch_response_completed_callback_)
diff --git a/content/browser/preloading/prefetch/prefetch_streaming_url_loader_unittest.cc b/content/browser/preloading/prefetch/prefetch_streaming_url_loader_unittest.cc index 642a4cd..634ba6f 100644 --- a/content/browser/preloading/prefetch/prefetch_streaming_url_loader_unittest.cc +++ b/content/browser/preloading/prefetch/prefetch_streaming_url_loader_unittest.cc
@@ -263,7 +263,9 @@ received_redirects_; }; -class PrefetchStreamingURLLoaderTest : public ::testing::Test { +class PrefetchStreamingURLLoaderTest + : public ::testing::Test, + public ::testing::WithParamInterface<bool> { public: void SetUp() override { task_environment_ = @@ -285,7 +287,11 @@ std::unique_ptr<TestURLLoaderFactory> test_url_loader_factory_; }; -TEST_F(PrefetchStreamingURLLoaderTest, SuccessfulServedAfterCompletion) { +// The parameter should determine if the test should call +// SetOnReceivedHeadCallback and check that callback is later called. +INSTANTIATE_TEST_SUITE_P(All, PrefetchStreamingURLLoaderTest, testing::Bool()); + +TEST_P(PrefetchStreamingURLLoaderTest, SuccessfulServedAfterCompletion) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -296,6 +302,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; base::RunLoop on_response_complete_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. @@ -323,10 +330,18 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulates receiving the head and body for the prefetch. test_url_loader_factory()->SimulateReceiveHead(net::HTTP_OK, kBodyContent.size()); on_response_received_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_TRUE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -386,7 +401,7 @@ PrefetchStreamingURLLoaderStatus::kSuccessfulServedAfterCompletion, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, SuccessfulServedBeforeCompletion) { +TEST_P(PrefetchStreamingURLLoaderTest, SuccessfulServedBeforeCompletion) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent1 = "example"; @@ -398,6 +413,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; base::RunLoop on_response_complete_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. @@ -425,6 +441,11 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulates receiving the head for the prefetch, receiving part of the body // data, start to serve the prefetch, and then getting the rest of the body // data. This should result in the data being streamed directly to the serving @@ -432,6 +453,9 @@ test_url_loader_factory()->SimulateReceiveHead( net::HTTP_OK, kBodyContent1.size() + kBodyContent2.size()); on_response_received_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_TRUE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -503,7 +527,7 @@ PrefetchStreamingURLLoaderStatus::kSuccessfulServedBeforeCompletion, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, SuccessfulNotServed) { +TEST_P(PrefetchStreamingURLLoaderTest, SuccessfulNotServed) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -514,6 +538,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; base::RunLoop on_response_complete_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. @@ -541,10 +566,18 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulates a successful prefetch that is not used. test_url_loader_factory()->SimulateReceiveHead(net::HTTP_OK, kBodyContent.size()); on_response_received_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_TRUE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -559,7 +592,7 @@ PrefetchStreamingURLLoaderStatus::kSuccessfulNotServed, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, FailedInvalidHead) { +TEST_P(PrefetchStreamingURLLoaderTest, FailedInvalidHead) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); @@ -569,6 +602,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. std::unique_ptr<PrefetchStreamingURLLoader> streaming_loader = @@ -593,10 +627,18 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulates a prefetch with a non-2XX response. This should be marked as not // servable. test_url_loader_factory()->SimulateReceiveHead(net::HTTP_NOT_FOUND, 0); on_response_received_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_FALSE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -607,7 +649,7 @@ PrefetchStreamingURLLoaderStatus::kFailedInvalidHead, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, FailedNetError) { +TEST_P(PrefetchStreamingURLLoaderTest, FailedNetError_HeadReceived) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -618,6 +660,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; base::RunLoop on_response_complete_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. @@ -645,10 +688,18 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulates a prefetch with a non-OK net error. test_url_loader_factory()->SimulateReceiveHead(net::HTTP_OK, kBodyContent.size()); on_response_received_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_TRUE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -665,7 +716,62 @@ PrefetchStreamingURLLoaderStatus::kFailedNetError, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, FailedNetErrorButServed) { +TEST_P(PrefetchStreamingURLLoaderTest, FailedNetError_HeadNotReveived) { + base::HistogramTester histogram_tester; + const GURL kTestUrl = GURL("https://example.com"); + const std::string kBodyContent = "example body"; + + std::unique_ptr<network::ResourceRequest> prefetch_request = + std::make_unique<network::ResourceRequest>(); + prefetch_request->url = kTestUrl; + prefetch_request->method = "GET"; + + base::RunLoop on_head_received_loop; + base::RunLoop on_response_complete_loop; + + // Create the |PrefetchStreamingURLLoader| that is being tested. + std::unique_ptr<PrefetchStreamingURLLoader> streaming_loader = + std::make_unique<PrefetchStreamingURLLoader>( + test_url_loader_factory(), std::move(prefetch_request), + TRAFFIC_ANNOTATION_FOR_TESTS, /*timeout_duration=*/base::TimeDelta(), + base::BindOnce([](network::mojom::URLResponseHead* head) { + NOTREACHED(); + return PrefetchStreamingURLLoaderStatus::kHeadReceivedWaitingOnBody; + }), + base::BindOnce( + [](base::RunLoop* on_response_complete_loop, + const network::URLLoaderCompletionStatus& completion_status) { + on_response_complete_loop->Quit(); + }, + &on_response_complete_loop), + base::BindRepeating( + [](const net::RedirectInfo& redirect_info, + const network::mojom::URLResponseHead& response_head) { + NOTREACHED(); + })); + + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + + // Simulate getting a non-OK net error. + test_url_loader_factory()->SimulateResponseComplete(net::ERR_FAILED); + on_response_complete_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } + + EXPECT_FALSE(streaming_loader->Servable(base::TimeDelta::Max())); + + streaming_loader.reset(); + + histogram_tester.ExpectUniqueSample( + "PrefetchProxy.Prefetch.StreamingURLLoaderFinalStatus", + PrefetchStreamingURLLoaderStatus::kFailedNetError, 1); +} + +TEST_P(PrefetchStreamingURLLoaderTest, FailedNetErrorButServed) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -676,6 +782,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; base::RunLoop on_response_complete_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. @@ -703,12 +810,20 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulates receiving the head for the prefetch, receiving part of the body // data, start to serve the prefetch, and then getting a net error. The error // should be passed to the serving URL loader. test_url_loader_factory()->SimulateReceiveHead(net::HTTP_OK, kBodyContent.size()); on_response_received_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_TRUE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -775,7 +890,7 @@ PrefetchStreamingURLLoaderStatus::kFailedNetErrorButServed, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, EligibleRedirect) { +TEST_P(PrefetchStreamingURLLoaderTest, EligibleRedirect) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const GURL kRedirectUrl = GURL("https://redirect.com"); @@ -789,6 +904,7 @@ base::RunLoop on_receive_redirect_loop; base::RunLoop on_follow_redirect_loop; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; base::RunLoop on_response_complete_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. @@ -818,6 +934,11 @@ }, &on_receive_redirect_loop)); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + ASSERT_TRUE(test_url_loader_factory()->test_url_loader()); test_url_loader_factory()->test_url_loader()->SetOnFollowRedirectClosure( on_follow_redirect_loop.QuitClosure()); @@ -835,6 +956,9 @@ test_url_loader_factory()->SimulateReceiveHead(net::HTTP_OK, kBodyContent.size()); on_response_received_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_TRUE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -918,7 +1042,7 @@ PrefetchStreamingURLLoaderStatus::kSuccessfulServedAfterCompletion, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, IneligibleRedirect) { +TEST_P(PrefetchStreamingURLLoaderTest, IneligibleRedirect) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -929,6 +1053,7 @@ prefetch_request->method = "GET"; base::RunLoop on_receive_redirect_loop; + base::RunLoop on_head_received_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. std::unique_ptr<PrefetchStreamingURLLoader> streaming_loader = @@ -951,6 +1076,11 @@ }, &on_receive_redirect_loop)); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulate a redirect that should not be followed by the URL loader. test_url_loader_factory()->SimulateRedirect(GURL("https://redirect.com"), net::HTTP_PERMANENT_REDIRECT); @@ -958,6 +1088,9 @@ streaming_loader->HandleRedirect( PrefetchStreamingURLLoaderStatus::kFailedInvalidRedirect); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_FALSE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -968,7 +1101,7 @@ PrefetchStreamingURLLoaderStatus::kFailedInvalidRedirect, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, RedirectSwitchInNetworkContext) { +TEST_P(PrefetchStreamingURLLoaderTest, RedirectSwitchInNetworkContext) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -1001,6 +1134,15 @@ }, &on_receive_redirect_loop)); + if (GetParam()) { + // When a redirect causes a change in network context, the + // on_receive_head_callback_ is not called, and is passed to the follow up + // PrefetchStreamingURLLoader that will follow the redirect in the other + // network context. + streaming_loader->SetOnReceivedHeadCallback( + base::BindOnce([]() { NOTREACHED(); })); + } + // Simulate a redirect that should not be followed by the URL loader. test_url_loader_factory()->SimulateRedirect(GURL("https://redirect.com"), net::HTTP_PERMANENT_REDIRECT); @@ -1059,7 +1201,7 @@ 1); } -TEST_F(PrefetchStreamingURLLoaderTest, +TEST_P(PrefetchStreamingURLLoaderTest, PausedEligibleRedirect_UrlLoaderDisconnect) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); @@ -1071,6 +1213,7 @@ prefetch_request->method = "GET"; base::RunLoop on_receive_redirect_loop; + base::RunLoop on_head_received_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. std::unique_ptr<PrefetchStreamingURLLoader> streaming_loader = @@ -1093,6 +1236,11 @@ }, &on_receive_redirect_loop)); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulate a redirect that should be followed by the URL loader. The URL // loader needs to pause until the eligibility check is complete. test_url_loader_factory()->SimulateRedirect(GURL("https://redirect.com"), @@ -1106,6 +1254,9 @@ streaming_loader->HandleRedirect( PrefetchStreamingURLLoaderStatus::kFollowRedirect); + if (GetParam()) { + on_head_received_loop.Run(); + } // Since the network URL loader was disconnected, then redirect cannot be // followed and the prefetch should not be servable. @@ -1118,7 +1269,7 @@ PrefetchStreamingURLLoaderStatus::kFailedInvalidRedirect, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, Decoy) { +TEST_P(PrefetchStreamingURLLoaderTest, Decoy) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -1129,6 +1280,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_received_loop; + base::RunLoop on_head_received_loop; base::RunLoop on_response_complete_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. @@ -1155,11 +1307,20 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + // Simulates a successful prefetch that is not used. However, since the // prefetch is marked as a decoy, it cannot be served. test_url_loader_factory()->SimulateReceiveHead(net::HTTP_OK, kBodyContent.size()); on_response_received_loop.Run(); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } EXPECT_FALSE(streaming_loader->Servable(base::TimeDelta::Max())); @@ -1176,7 +1337,7 @@ PrefetchStreamingURLLoaderStatus::kPrefetchWasDecoy, 1); } -TEST_F(PrefetchStreamingURLLoaderTest, Timeout) { +TEST_P(PrefetchStreamingURLLoaderTest, Timeout) { base::HistogramTester histogram_tester; const GURL kTestUrl = GURL("https://example.com"); const std::string kBodyContent = "example body"; @@ -1187,6 +1348,7 @@ prefetch_request->method = "GET"; base::RunLoop on_response_complete_loop; + base::RunLoop on_head_received_loop; // Create the |PrefetchStreamingURLLoader| that is being tested. std::unique_ptr<PrefetchStreamingURLLoader> streaming_loader = @@ -1210,8 +1372,16 @@ NOTREACHED(); })); + if (GetParam()) { + streaming_loader->SetOnReceivedHeadCallback( + on_head_received_loop.QuitClosure()); + } + task_environment()->FastForwardBy(base::Seconds(1)); on_response_complete_loop.Run(); + if (GetParam()) { + on_head_received_loop.Run(); + } EXPECT_FALSE(streaming_loader->Servable(base::TimeDelta::Max()));
diff --git a/content/browser/renderer_host/OWNERS b/content/browser/renderer_host/OWNERS index 23cca84..f1d0718 100644 --- a/content/browser/renderer_host/OWNERS +++ b/content/browser/renderer_host/OWNERS
@@ -4,6 +4,7 @@ # Touch input and gesture relatated code. rjkroege@chromium.org +jonross@chromium.org # Surface ID propagation and synchronization, and compositing embedding # via DelegatedFrame*. @@ -19,6 +20,7 @@ # Aura platform code. per-file *aura*=rjkroege@chromium.org +per-file *aura*=jonross@chromium.org # Mac platform GPU-related code. per-file *mac*=kbr@chromium.org
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index f2ef4f18..1a16bef5 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -1072,47 +1072,6 @@ return DeriveTopicsHeaderValue(topics, num_versions_in_epochs); } -// Support logging OriginAgentClusterEndResult with VLOG. -std::ostream& operator<<( - std::ostream& out, - NavigationRequest::OriginAgentClusterEndResult result) { - using OriginAgentClusterEndResult = - NavigationRequest::OriginAgentClusterEndResult; - switch (result) { - case OriginAgentClusterEndResult::kNotRequestedAndNotOriginKeyed: - out << "kNotRequestedAndNotOriginKeyed"; - break; - case OriginAgentClusterEndResult::kNotRequestedButOriginKeyed: - out << "kNotRequestedButOriginKeyed"; - break; - case OriginAgentClusterEndResult::kRequestedButNotOriginKeyed: - out << "kRequestedButNotOriginKeyed"; - break; - case OriginAgentClusterEndResult::kRequestedAndOriginKeyed: - out << "kRequestedAndOriginKeyed"; - break; - case OriginAgentClusterEndResult::kExplicitlyNotRequestedAndNotOriginKeyed: - out << "kExplicitlyNotRequestedAndNotOriginKeyed"; - break; - case OriginAgentClusterEndResult::kExplicitlyNotRequestedButOriginKeyed: - out << "kExplicitlyNotRequestedButOriginKeyed"; - break; - case OriginAgentClusterEndResult::kExplicitlyRequestedButNotOriginKeyed: - out << "kExplicitlyRequestedButNotOriginKeyed"; - break; - case OriginAgentClusterEndResult::kExplicitlyRequestedAndOriginKeyed: - out << "kExplicitlyRequestedAndOriginKeyed"; - break; - case OriginAgentClusterEndResult::kNotExplicitlyRequestedButNotOriginKeyed: - out << "kNotExplicitlyRequestedButNotOriginKeyed"; - break; - case OriginAgentClusterEndResult::kNotExplicitlyRequestedAndOriginKeyed: - out << "kNotExplicitlyRequestedAndOriginKeyed"; - break; - } - return out; -} - } // namespace NavigationRequest::PrerenderActivationNavigationState:: @@ -3501,20 +3460,20 @@ requested_isolation_state) .is_origin_agent_cluster(); - bool are_origin_agent_clusters_enabled_by_default = - SiteIsolationPolicy::AreOriginAgentClustersEnabledByDefault( - frame_tree_node_->navigator().controller().GetBrowserContext()); - // When OAC is enabled by default, report enum values that distinguish - // between explicitly requesting OAC (on or off) and having no related - // header. - bool was_explicitly_requested = - response_head_ && response_head_->parsed_headers->origin_agent_cluster == - network::mojom::OriginAgentClusterValue::kTrue; - bool was_explicitly_not_requested = - response_head_ && response_head_->parsed_headers->origin_agent_cluster == - network::mojom::OriginAgentClusterValue::kFalse; + if (SiteIsolationPolicy::AreOriginAgentClustersEnabledByDefault( + frame_tree_node_->navigator().controller().GetBrowserContext())) { + // When OAC is enabled by default, report enum values that distinguish + // between explicitly requesting OAC (on or off) and having no related + // header. + bool was_explicitly_requested = + response_head_ && + response_head_->parsed_headers->origin_agent_cluster == + network::mojom::OriginAgentClusterValue::kTrue; + bool was_explicitly_not_requested = + response_head_ && + response_head_->parsed_headers->origin_agent_cluster == + network::mojom::OriginAgentClusterValue::kFalse; - if (are_origin_agent_clusters_enabled_by_default) { if (got_origin_agent_cluster) { if (was_explicitly_requested) { origin_agent_cluster_end_result_ = @@ -3577,37 +3536,6 @@ commit_params_->origin_agent_cluster_left_as_default = !response_head_ || response_head_->parsed_headers->origin_agent_cluster == network::mojom::OriginAgentClusterValue::kAbsent; - - // TODO(vogelheim): Support debugging crbug.com/1429587: Log the - // origin-agent clustering decision at VLOG(2), plus the variables - // that inform this decision. Revert this change once crbug.com/1429587 - // is fixed. - VLOG(2) << __func__ << ": " - << "url = " << GetURL().spec() << "\n" - << "\torigin_agent_cluster_end_result_ = " - << origin_agent_cluster_end_result_ << "\n" - << "\tcommit_params_->origin_agent_cluster = " - << commit_params_->origin_agent_cluster << "\n" - << "\tcommit_params_->origin_agent_cluster_left_as_default = " - << commit_params_->origin_agent_cluster_left_as_default << "\n" - << "\tis_opaque_origin_because_sandbox = " - << is_opaque_origin_because_sandbox << "\n" - << "\tis_requested = " << is_requested << "\n" - << "\texpects_origin_agent_cluster = " << expects_origin_agent_cluster - << "\n" - << "\trequires_origin_keyed_process = " - << requires_origin_keyed_process << "\n" - << "\trequested_isolation_state = " - << "(is_origin_agent_cluster=" - << requested_isolation_state.is_origin_agent_cluster() - << ",requires_origin_keyed_process=" - << requested_isolation_state.requires_origin_keyed_process() << ")\n" - << "\tgot_origin_agent_cluster = " << got_origin_agent_cluster << "\n" - << "\tare_origin_agent_clusters_enabled_by_default = " - << are_origin_agent_clusters_enabled_by_default << "\n" - << "\twas_explicitly_requested = " << was_explicitly_requested << "\n" - << "\twas_explicitly_not_requested = " << was_explicitly_not_requested - << "\n"; } void NavigationRequest::ProcessOriginAgentClusterEndResult() {
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 3977557..4407357a 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -11204,8 +11204,16 @@ // frame tree before accessing `GetPrerenderHostRegistry()`. Non-prerendered // frames may outlive the PrerenderHostRegistry during WebContents // destruction. - if (outermost_frame->GetFrameType() != FrameType::kPrerenderMainFrame) + if (outermost_frame->GetFrameType() != FrameType::kPrerenderMainFrame) { return false; + } + + // If this runs during the WebContents destruction, PrerenderHostRegistry was + // already destroyed and bound prerenderings are already cancelled. + // We can check the FrameTree status as the tree's shutdown runs first. + if (outermost_frame->frame_tree().IsBeingDestroyed()) { + return false; + } return delegate_->GetPrerenderHostRegistry()->CancelHost( outermost_frame->frame_tree_node_id(), reason);
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index 4b1c2ca..d0814b8 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3503,7 +3503,6 @@ switches::kDisableBackgroundMediaSuspend, switches::kDisableNotifications, switches::kDisableOriginTrialControlledBlinkFeatures, - switches::kDisablePepper3DImageChromium, switches::kDisablePermissionsAPI, switches::kDisablePresentationAPI, switches::kDisableRTCSmoothnessAlgorithm,
diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index 5c37b56..421a0b8 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc
@@ -560,9 +560,9 @@ // subframes. For this reason we simply use the main frame's browsing context // group. Note that we cannot use this RenderViewHost's site_instance_group(), // which may not match in a popup case. For example, if A opens a - // cross-browsing-context-group popup to B, A can have a RenderViewHost in the - // popup, but it needs to know B's BrowsingContextGroupInfo, which is the - // current page in the popup. + // cross-browsing-context-group popup to B, the RenderViewHost for the opener + // in B's process should have A's BrowsingContextGroupInfo, which is the + // current page in the opener. params->browsing_context_group_info = blink::BrowsingContextGroupInfo( frame_tree_->GetMainFrame()->GetSiteInstance()->browsing_instance_token(), frame_tree_->GetMainFrame()
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc index 9eb7e39..12ee341 100644 --- a/content/browser/renderer_host/render_widget_host_view_android.cc +++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -2537,20 +2537,10 @@ bool RenderWidgetHostViewAndroid::OnMouseEvent( const ui::MotionEventAndroid& event) { - // Ignore ACTION_HOVER_ENTER & ACTION_HOVER_EXIT because every mouse-down on - // Android follows a hover-exit and is followed by a hover-enter. - // https://crbug.com/715114 filed on distinguishing actual hover - // enter/exit from these bogus ones. - auto action = event.GetAction(); - if (action == ui::MotionEventAndroid::Action::HOVER_ENTER || - action == ui::MotionEventAndroid::Action::HOVER_EXIT) { - return false; - } - RecordToolTypeForActionDown(event); blink::WebInputEvent::Type webMouseEventType = - ui::ToWebMouseEventType(action); + ui::ToWebMouseEventType(event.GetAction()); if (webMouseEventType == blink::WebInputEvent::Type::kUndefined) { return false;
diff --git a/content/browser/resources/attribution_reporting/attribution_internals.ts b/content/browser/resources/attribution_reporting/attribution_internals.ts index 657cb88..533d771 100644 --- a/content/browser/resources/attribution_reporting/attribution_internals.ts +++ b/content/browser/resources/attribution_reporting/attribution_internals.ts
@@ -9,7 +9,7 @@ import {getTrustedHTML} from 'chrome://resources/js/static_types.js'; import {Origin} from 'chrome://resources/mojo/url/mojom/origin.mojom-webui.js'; -import {TriggerVerification} from './attribution.mojom-webui.js'; +import {AttributionSupport, TriggerVerification} from './attribution.mojom-webui.js'; import {Factory, HandlerInterface, HandlerRemote, ObserverInterface, ObserverReceiver, ReportID, SourceStatus, WebUIDebugReport, WebUIOsRegistration, WebUIRegistration, WebUIReport, WebUISource, WebUISource_Attributability, WebUISourceRegistration, WebUITrigger, WebUITrigger_Status} from './attribution_internals.mojom-webui.js'; import {AttributionInternalsTableElement} from './attribution_internals_table.js'; import {OsRegistrationResult, OsRegistrationType} from './attribution_reporting.mojom-webui.js'; @@ -1190,7 +1190,22 @@ } const attributionSupport = document.querySelector<HTMLElement>('#attribution-support')!; - attributionSupport.innerText = response.attributionSupport; + switch (response.attributionSupport) { + case AttributionSupport.kWeb: + attributionSupport.innerText = 'web'; + break; + case AttributionSupport.kWebAndOs: + attributionSupport.innerText = 'os, web'; + break; + case AttributionSupport.kOs: + attributionSupport.innerText = 'os'; + break; + case AttributionSupport.kNone: + attributionSupport.innerText = ''; + break; + default: + assertNotReached(); + } }); this.updateSources();
diff --git a/content/browser/shared_storage/shared_storage_header_observer.cc b/content/browser/shared_storage/shared_storage_header_observer.cc new file mode 100644 index 0000000..fc7f6c67 --- /dev/null +++ b/content/browser/shared_storage/shared_storage_header_observer.cc
@@ -0,0 +1,254 @@ +// 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 "content/browser/shared_storage/shared_storage_header_observer.h" + +#include <deque> +#include <iterator> +#include <map> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/check.h" +#include "base/functional/bind.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/notreached.h" +#include "base/strings/utf_string_conversions.h" +#include "components/services/storage/shared_storage/shared_storage_manager.h" +#include "content/browser/storage_partition_impl.h" +#include "content/public/browser/render_frame_host.h" +#include "content/public/common/content_client.h" +#include "services/network/public/mojom/optional_bool.mojom.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/public/common/shared_storage/shared_storage_utils.h" + +namespace content { + +SharedStorageHeaderObserver::SharedStorageHeaderObserver( + StoragePartitionImpl* storage_partition) + : storage_partition_(storage_partition) {} + +SharedStorageHeaderObserver::~SharedStorageHeaderObserver() = default; + +// static +bool& SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowedForTesting() { + return GetBypassIsSharedStorageAllowed(); +} + +void SharedStorageHeaderObserver::HeaderReceived( + const url::Origin& request_origin, + RenderFrameHost* rfh, + std::vector<OperationPtr> operations, + base::OnceClosure callback) { + DCHECK(callback); + if (!IsSharedStorageAllowed(rfh, request_origin)) { + // TODO(crbug.com/1434529): Log the following error message to console: + // "'Shared-Storage-Write: shared storage is disabled." + std::move(callback).Run(); + return; + } + + std::deque<network::mojom::SharedStorageOperationPtr> to_process; + to_process.insert(to_process.end(), + std::make_move_iterator(operations.begin()), + std::make_move_iterator(operations.end())); + + std::vector<bool> header_results; + while (!to_process.empty()) { + network::mojom::SharedStorageOperationPtr operation = + std::move(to_process.front()); + to_process.pop_front(); + header_results.push_back(Invoke(request_origin, std::move(operation))); + } + + OnHeaderProcessed(request_origin, header_results); + std::move(callback).Run(); +} + +// static +bool& SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowed() { + static bool should_bypass = false; + return should_bypass; +} + +bool SharedStorageHeaderObserver::Invoke(const url::Origin& request_origin, + OperationPtr operation) { + switch (operation->type) { + case OperationType::kSet: + if (!operation->key.has_value() || !operation->value.has_value()) { + // TODO(crbug.com/1434529): Log the following error message to console: + // "Shared-Storage-Write: 'set' missing parameter 'key' or 'value'." + return false; + } + return Set(request_origin, std::move(operation->key.value()), + std::move(operation->value.value()), + operation->ignore_if_present); + case OperationType::kAppend: + if (!operation->key.has_value() || !operation->value.has_value()) { + // TODO(crbug.com/1434529): Log the following error message to console: + // "Shared-Storage-Write: 'append' missing parameter 'key' or 'value'." + return false; + } + return Append(request_origin, std::move(operation->key.value()), + std::move(operation->value.value())); + case OperationType::kDelete: + if (!operation->key.has_value()) { + // TODO(crbug.com/1434529): Log the following error message to console: + // "Shared-Storage-Write: 'delete' missing parameter 'key'." + return false; + } + return Delete(request_origin, std::move(operation->key.value())); + case OperationType::kClear: + return Clear(request_origin); + default: + NOTREACHED(); + } + return false; +} + +bool SharedStorageHeaderObserver::Set( + const url::Origin& request_origin, + std::string key, + std::string value, + network::mojom::OptionalBool ignore_if_present) { + std::u16string utf16_key; + std::u16string utf16_value; + if (!base::UTF8ToUTF16(key.c_str(), key.size(), &utf16_key) || + !base::UTF8ToUTF16(value.c_str(), value.size(), &utf16_value) || + !blink::IsValidSharedStorageKeyStringLength(utf16_key.size()) || + !blink::IsValidSharedStorageValueStringLength(utf16_value.size())) { + // TODO(crbug.com/1434529): Log the following error message to console: + // "Shared-Storage-Write: 'set' has invalid parameter 'key' or 'value'." + return false; + } + + storage::SharedStorageDatabase::SetBehavior set_behavior = + (ignore_if_present == network::mojom::OptionalBool::kTrue) + ? storage::SharedStorageDatabase::SetBehavior::kIgnoreIfPresent + : storage::SharedStorageDatabase::SetBehavior::kDefault; + + // TODO(crbug.com/1434529): Consider calling `NotifySharedStorageAccessed()`. + // Would need to add a new `AccessType::kHeaderSet`. + + GetSharedStorageManager()->Set( + request_origin, std::move(utf16_key), std::move(utf16_value), + base::BindOnce(&SharedStorageHeaderObserver::OnOperationFinished, + weak_ptr_factory_.GetWeakPtr(), request_origin, + network::mojom::SharedStorageOperation::New( + OperationType::kSet, std::move(key), std::move(value), + ignore_if_present)), + set_behavior); + return true; +} + +bool SharedStorageHeaderObserver::Append(const url::Origin& request_origin, + + std::string key, + std::string value) { + std::u16string utf16_key; + std::u16string utf16_value; + if (!base::UTF8ToUTF16(key.c_str(), key.size(), &utf16_key) || + !base::UTF8ToUTF16(value.c_str(), value.size(), &utf16_value) || + !blink::IsValidSharedStorageKeyStringLength(utf16_key.size()) || + !blink::IsValidSharedStorageValueStringLength(utf16_value.size())) { + // TODO(crbug.com/1434529): Log the following error message to console: + // "Shared-Storage-Write: 'append' has invalid parameter 'key' or 'value'." + return false; + } + + // TODO(crbug.com/1434529): Consider calling `NotifySharedStorageAccessed()`. + // Would need to add a new `AccessType::kHeaderAppend`. + + GetSharedStorageManager()->Append( + request_origin, std::move(utf16_key), std::move(utf16_value), + base::BindOnce( + &SharedStorageHeaderObserver::OnOperationFinished, + weak_ptr_factory_.GetWeakPtr(), request_origin, + network::mojom::SharedStorageOperation::New( + OperationType::kAppend, std::move(key), std::move(value), + /*ignore_if_present=*/network::mojom::OptionalBool::kUnset))); + return true; +} + +bool SharedStorageHeaderObserver::Delete(const url::Origin& request_origin, + std::string key) { + std::u16string utf16_key; + if (!base::UTF8ToUTF16(key.c_str(), key.size(), &utf16_key) || + !blink::IsValidSharedStorageKeyStringLength(utf16_key.size())) { + // TODO(crbug.com/1434529): Log the following error message to console: + // "Shared-Storage-Write: 'delete' has invalid parameter 'key'." + return false; + } + + // TODO(crbug.com/1434529): Consider calling `NotifySharedStorageAccessed()`. + // Would need to add a new `AccessType::kHeaderDelete`. + + GetSharedStorageManager()->Delete( + request_origin, std::move(utf16_key), + base::BindOnce( + &SharedStorageHeaderObserver::OnOperationFinished, + weak_ptr_factory_.GetWeakPtr(), request_origin, + network::mojom::SharedStorageOperation::New( + OperationType::kDelete, std::move(key), /*value=*/absl::nullopt, + /*ignore_if_present=*/network::mojom::OptionalBool::kUnset))); + return true; +} + +bool SharedStorageHeaderObserver::Clear(const url::Origin& request_origin) { + // TODO(crbug.com/1434529): Consider calling `NotifySharedStorageAccessed()`. + // Would need to add a new `AccessType::kHeaderClear`. + + GetSharedStorageManager()->Clear( + request_origin, + base::BindOnce( + &SharedStorageHeaderObserver::OnOperationFinished, + weak_ptr_factory_.GetWeakPtr(), request_origin, + network::mojom::SharedStorageOperation::New( + OperationType::kClear, + /*key=*/absl::nullopt, /*value=*/absl::nullopt, + /*ignore_if_present=*/network::mojom::OptionalBool::kUnset))); + return true; +} + +storage::SharedStorageManager* +SharedStorageHeaderObserver::GetSharedStorageManager() { + DCHECK(storage_partition_); + storage::SharedStorageManager* shared_storage_manager = + storage_partition_->GetSharedStorageManager(); + + // This `SharedStorageHeaderObserver` is created only if + // `kSharedStorageAPI` is enabled, in which case the `shared_storage_manager` + // must be valid. + DCHECK(shared_storage_manager); + return shared_storage_manager; +} + +bool SharedStorageHeaderObserver::IsSharedStorageAllowed( + RenderFrameHost* rfh, + const url::Origin& request_origin) { + if (GetBypassIsSharedStorageAllowed()) { + return true; + } + + DCHECK(storage_partition_); + DCHECK(storage_partition_->browser_context()); + + // TODO(crbug.com/1434529): 1.Add a metric to track what how often `rfh` is + // nullptr here. + // 2. Cache `top_frame_origin` for the corresponding `rfh` in + // `NavigationOrDocumentHandle` and pass in from `StoragePartitionImpl` in + // order to avoid needing to use an opaque origin in the case where `rfh` has + // been reset. + url::Origin top_frame_origin = + rfh ? rfh->GetOutermostMainFrame()->GetLastCommittedOrigin() + : url::Origin(); + return GetContentClient()->browser()->IsSharedStorageAllowed( + storage_partition_->browser_context(), rfh, top_frame_origin, + request_origin); +} + +} // namespace content
diff --git a/content/browser/shared_storage/shared_storage_header_observer.h b/content/browser/shared_storage/shared_storage_header_observer.h new file mode 100644 index 0000000..5e1a1c5d --- /dev/null +++ b/content/browser/shared_storage/shared_storage_header_observer.h
@@ -0,0 +1,94 @@ +// 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 CONTENT_BROWSER_SHARED_STORAGE_SHARED_STORAGE_HEADER_OBSERVER_H_ +#define CONTENT_BROWSER_SHARED_STORAGE_SHARED_STORAGE_HEADER_OBSERVER_H_ + +#include <map> +#include <memory> +#include <string> +#include <vector> + +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "components/services/storage/shared_storage/shared_storage_manager.h" +#include "content/browser/storage_partition_impl.h" +#include "content/common/content_export.h" +#include "services/network/public/mojom/optional_bool.mojom.h" +#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/origin.h" + +namespace content { + +class RenderFrameHost; + +// Receives notifications from `StoragePartitionImpl` when a parsed +// "Shared-Storage-Write" header is received from the network service. The +// parsed header takes the form of a vector of StructPtrs bundling operation +// types with any parameters. The corresponding shared storage operations are +// invoked in the same order, omitting any operations that are missing any +// necessary parameters or for which any necessary parameters are invalid. +class CONTENT_EXPORT SharedStorageHeaderObserver { + public: + using OperationResult = storage::SharedStorageManager::OperationResult; + using OperationType = network::mojom::SharedStorageOperationType; + using OperationPtr = network::mojom::SharedStorageOperationPtr; + + explicit SharedStorageHeaderObserver(StoragePartitionImpl* storage_partition); + virtual ~SharedStorageHeaderObserver(); + + // If true, allows operations to bypass the permission check in + // `IsSharedStorageAllowed()` for testing. + static bool& GetBypassIsSharedStorageAllowedForTesting(); + + // Called by `StoragePartitionImpl` to notify that a parsed + // "Shared-Storage-Write" header `operations` for a request to + // `request_origin` from `rfh` has been received. For each operation in + // `operations`, validates each operation and then invokes each valid + // operation in the order received, skipping any operations that are missing + // any necessary parameters or for which any necessary parameters are + // invalid.. + void HeaderReceived(const url::Origin& request_origin, + RenderFrameHost* rfh, + std::vector<OperationPtr> operations, + base::OnceClosure callback); + + protected: + // virtual for testing. + virtual void OnHeaderProcessed(const url::Origin& request_origin, + const std::vector<bool>& header_results) {} + virtual void OnOperationFinished(const url::Origin& request_origin, + OperationPtr operation, + OperationResult result) {} + + private: + static bool& GetBypassIsSharedStorageAllowed(); + + bool Invoke(const url::Origin& request_origin, OperationPtr operation); + + bool Set(const url::Origin& request_origin, + std::string key, + std::string value, + network::mojom::OptionalBool ignore_if_present); + bool Append(const url::Origin& request_origin, + std::string key, + std::string value); + bool Delete(const url::Origin& request_origin, std::string key); + bool Clear(const url::Origin& request_origin); + + storage::SharedStorageManager* GetSharedStorageManager(); + + bool IsSharedStorageAllowed(RenderFrameHost* rfh, + const url::Origin& request_origin); + + // `storage_partition_` owns `this`, so it will outlive `this`. + raw_ptr<StoragePartitionImpl> storage_partition_; + + base::WeakPtrFactory<SharedStorageHeaderObserver> weak_ptr_factory_{this}; +}; + +} // namespace content + +#endif // CONTENT_BROWSER_SHARED_STORAGE_SHARED_STORAGE_HEADER_OBSERVER_H_
diff --git a/content/browser/shared_storage/shared_storage_header_observer_unittest.cc b/content/browser/shared_storage/shared_storage_header_observer_unittest.cc new file mode 100644 index 0000000..fae22f4 --- /dev/null +++ b/content/browser/shared_storage/shared_storage_header_observer_unittest.cc
@@ -0,0 +1,551 @@ +// 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 "content/browser/shared_storage/shared_storage_header_observer.h" + +#include <memory> +#include <string> +#include <tuple> +#include <utility> +#include <vector> + +#include "base/notreached.h" +#include "base/run_loop.h" +#include "base/strings/utf_string_conversions.h" +#include "base/test/scoped_feature_list.h" +#include "base/test/test_future.h" +#include "content/browser/storage_partition_impl.h" +#include "content/public/test/navigation_simulator.h" +#include "content/public/test/shared_storage_test_utils.h" +#include "content/public/test/test_renderer_host.h" +#include "content/public/test/test_shared_storage_header_observer.h" +#include "content/test/test_web_contents.h" +#include "services/network/public/mojom/optional_bool.mojom.h" +#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest-param-test.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/blink/public/common/features.h" +#include "url/gurl.h" +#include "url/origin.h" + +namespace content { + +namespace { + +const char kMainOrigin[] = "https://main.test"; +const char kChildOrigin[] = "https://child.test"; +const char kTestOrigin1[] = "https://a.test"; +const char kTestOrigin2[] = "https://b.test"; +const char kTestOrigin3[] = "https://c.test"; + +using OperationPtr = network::mojom::SharedStorageOperationPtr; +using OperationType = network::mojom::SharedStorageOperationType; +using OperationResult = storage::SharedStorageManager::OperationResult; +using GetResult = storage::SharedStorageManager::GetResult; + +enum class RenderFrameHostType { + kMain = 0, + kIframe = 1, + kNull = 2, +}; + +[[nodiscard]] OperationPtr MakeSharedStorageOperationPtr( + OperationType operation_type, + absl::optional<std::string> key, + absl::optional<std::string> value, + absl::optional<bool> ignore_if_present) { + return network::mojom::SharedStorageOperation::New( + operation_type, std::move(key), std::move(value), + AbslToMojomOptionalBool(ignore_if_present)); +} + +[[nodiscard]] std::vector<OperationPtr> MakeOperationVector( + std::vector<std::tuple<OperationType, + absl::optional<std::string>, + absl::optional<std::string>, + absl::optional<bool>>> operation_tuples) { + std::vector<OperationPtr> operations; + for (const auto& operation_tuple : operation_tuples) { + OperationPtr operation = MakeSharedStorageOperationPtr( + std::get<0>(operation_tuple), std::get<1>(operation_tuple), + std::get<2>(operation_tuple), std::get<3>(operation_tuple)); + operations.push_back(std::move(operation)); + } + return operations; +} + +[[nodiscard]] SharedStorageWriteOperationAndResult SetOperation( + const url::Origin& request_origin, + std::string key, + std::string value, + absl::optional<bool> ignore_if_present, + OperationResult result) { + return SharedStorageWriteOperationAndResult::SetOperation( + request_origin, std::move(key), std::move(value), ignore_if_present, + result); +} + +[[nodiscard]] SharedStorageWriteOperationAndResult AppendOperation( + const url::Origin& request_origin, + std::string key, + std::string value, + OperationResult result) { + return SharedStorageWriteOperationAndResult::AppendOperation( + request_origin, std::move(key), std::move(value), result); +} + +[[nodiscard]] SharedStorageWriteOperationAndResult DeleteOperation( + const url::Origin& request_origin, + std::string key, + OperationResult result) { + return SharedStorageWriteOperationAndResult::DeleteOperation( + request_origin, std::move(key), result); +} + +[[nodiscard]] SharedStorageWriteOperationAndResult ClearOperation( + const url::Origin& request_origin, + OperationResult result) { + return SharedStorageWriteOperationAndResult::ClearOperation(request_origin, + result); +} + +class SharedStorageHeaderObserverTest + : public RenderViewHostTestHarness, + public testing::WithParamInterface<RenderFrameHostType> { + public: + SharedStorageHeaderObserverTest() { + feature_list_.InitAndEnableFeature(blink::features::kSharedStorageAPI); + } + + ~SharedStorageHeaderObserverTest() override = default; + + void SetUp() override { + RenderViewHostTestHarness::SetUp(); + observer_ = std::make_unique<TestSharedStorageHeaderObserver>( + browser_context()->GetDefaultStoragePartition()); + NavigateMainFrame(GURL(kMainOrigin)); + } + + void NavigateMainFrame(const GURL& url) { + auto simulator = content::NavigationSimulator::CreateBrowserInitiated( + url, web_contents()); + simulator->Commit(); + } + + RenderFrameHost* CreateAndNavigateIFrame(RenderFrameHost* parent, + const GURL& url, + const std::string& name) { + content::RenderFrameHost* rfh = + content::RenderFrameHostTester::For(parent)->AppendChild(name); + auto simulator = + content::NavigationSimulator::CreateRendererInitiated(url, rfh); + simulator->SetTransition(ui::PAGE_TRANSITION_MANUAL_SUBFRAME); + simulator->Commit(); + return simulator->GetFinalRenderFrameHost(); + } + + RenderFrameHost* GetRequestFrame() { + switch (GetParam()) { + case RenderFrameHostType::kMain: + return main_rfh(); + case RenderFrameHostType::kIframe: + return CreateAndNavigateIFrame(main_rfh(), GURL(kChildOrigin), + "myiframe"); + case RenderFrameHostType::kNull: + return nullptr; + default: + NOTREACHED(); + } + return nullptr; + } + + void RunHeaderReceived(const url::Origin& request_origin, + std::vector<OperationPtr> operations) { + base::RunLoop loop; + observer_->HeaderReceived(request_origin, GetRequestFrame(), + std::move(operations), loop.QuitClosure()); + loop.Run(); + } + + storage::SharedStorageManager* GetSharedStorageManager() { + return static_cast<StoragePartitionImpl*>( + browser_context()->GetDefaultStoragePartition()) + ->GetSharedStorageManager(); + } + + std::string GetExistingValue(const url::Origin& request_origin, + std::string key) { + base::test::TestFuture<GetResult> future; + auto* manager = GetSharedStorageManager(); + DCHECK(manager); + std::u16string utf16_key; + EXPECT_TRUE(base::UTF8ToUTF16(key.c_str(), key.size(), &utf16_key)); + manager->Get(request_origin, utf16_key, future.GetCallback()); + GetResult result = future.Take(); + EXPECT_EQ(result.result, OperationResult::kSuccess); + std::string utf8_value; + EXPECT_TRUE(base::UTF16ToUTF8(result.data.c_str(), result.data.size(), + &utf8_value)); + return utf8_value; + } + + bool ValueNotFound(const url::Origin& request_origin, std::string key) { + base::test::TestFuture<GetResult> future; + auto* manager = GetSharedStorageManager(); + DCHECK(manager); + std::u16string utf16_key; + EXPECT_TRUE(base::UTF8ToUTF16(key.c_str(), key.size(), &utf16_key)); + manager->Get(request_origin, utf16_key, future.GetCallback()); + GetResult result = future.Take(); + return result.result == OperationResult::kNotFound; + } + + int Length(const url::Origin& request_origin) { + base::test::TestFuture<int> future; + auto* manager = GetSharedStorageManager(); + DCHECK(manager); + manager->Length(request_origin, future.GetCallback()); + return future.Get(); + } + + protected: + std::unique_ptr<TestSharedStorageHeaderObserver> observer_; + + private: + base::test::ScopedFeatureList feature_list_; +}; + +} // namespace + +INSTANTIATE_TEST_SUITE_P(All, + SharedStorageHeaderObserverTest, + testing::Values(RenderFrameHostType::kMain, + RenderFrameHostType::kIframe, + RenderFrameHostType::kNull), + [](const auto& info) { + switch (info.param) { + case RenderFrameHostType::kMain: + return "FromMainFrame"; + case RenderFrameHostType::kIframe: + return "FromIFrame"; + case RenderFrameHostType::kNull: + return "FromFrameNoLongerAlive"; + default: + NOTREACHED(); + } + return "NotReached"; + }); + +TEST_P(SharedStorageHeaderObserverTest, SharedStorageNotAllowed) { + // Simulate disabling shared storage in user preferences. + SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowedForTesting() = + false; + + const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1)); + + std::vector<OperationPtr> operations = MakeOperationVector( + {std::make_tuple(OperationType::kClear, /*key*/ absl::nullopt, + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), + std::make_tuple(OperationType::kSet, "key1", "value1", + /*ignore_if_present*/ absl::nullopt), + std::make_tuple(OperationType::kAppend, "key1", "value1", + /*ignore_if_present*/ absl::nullopt), + std::make_tuple(OperationType::kSet, "key1", "value2", + /*ignore_if_present*/ true), + std::make_tuple(OperationType::kSet, "key2", "value2", + /*ignore_if_present*/ false), + std::make_tuple(OperationType::kDelete, "key2", /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt)}); + + // No operations are invoked because we've simulated shared storage being + // disabled in user preferences. + RunHeaderReceived(kOrigin1, std::move(operations)); + EXPECT_TRUE(observer_->header_results().empty()); + EXPECT_TRUE(observer_->operations().empty()); + EXPECT_EQ(Length(kOrigin1), 0); +} + +TEST_P(SharedStorageHeaderObserverTest, Basic_SingleOrigin_AllSuccessful) { + SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowedForTesting() = + true; + + const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1)); + + std::vector<OperationPtr> operations = MakeOperationVector( + {std::make_tuple(OperationType::kClear, /*key*/ absl::nullopt, + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), + std::make_tuple(OperationType::kSet, "key1", "value1", + /*ignore_if_present*/ absl::nullopt), + std::make_tuple(OperationType::kAppend, "key1", "value1", + /*ignore_if_present*/ absl::nullopt), + std::make_tuple(OperationType::kSet, "key1", "value2", + /*ignore_if_present*/ true), + std::make_tuple(OperationType::kSet, "key2", "value2", + /*ignore_if_present*/ false), + std::make_tuple(OperationType::kDelete, "key2", /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt)}); + + RunHeaderReceived(kOrigin1, std::move(operations)); + ASSERT_EQ(observer_->header_results().size(), 1u); + EXPECT_EQ(observer_->header_results().back().first, kOrigin1); + EXPECT_THAT(observer_->header_results().back().second, + testing::ElementsAre(true, true, true, true, true, true)); + + observer_->WaitForOperations(6); + EXPECT_THAT( + observer_->operations(), + testing::ElementsAre( + ClearOperation(kOrigin1, OperationResult::kSuccess), + SetOperation(kOrigin1, "key1", "value1", absl::nullopt, + OperationResult::kSet), + AppendOperation(kOrigin1, "key1", "value1", OperationResult::kSet), + SetOperation(kOrigin1, "key1", "value2", true, + OperationResult::kIgnored), + SetOperation(kOrigin1, "key2", "value2", false, + OperationResult::kSet), + DeleteOperation(kOrigin1, "key2", OperationResult::kSuccess))); + + EXPECT_EQ(GetExistingValue(kOrigin1, "key1"), "value1value1"); + EXPECT_TRUE(ValueNotFound(kOrigin1, "key2")); + EXPECT_EQ(Length(kOrigin1), 1); +} + +TEST_P(SharedStorageHeaderObserverTest, Basic_MultiOrigin_AllSuccessful) { + SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowedForTesting() = + true; + + const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1)); + const url::Origin kOrigin2 = url::Origin::Create(GURL(kTestOrigin2)); + const url::Origin kOrigin3 = url::Origin::Create(GURL(kTestOrigin3)); + + std::vector<OperationPtr> operations1 = MakeOperationVector( + {std::make_tuple(OperationType::kSet, "a", "b", + /*ignore_if_present*/ absl::nullopt)}); + std::vector<OperationPtr> operations2 = + MakeOperationVector({std::make_tuple(OperationType::kSet, "a", "c", + /*ignore_if_present*/ true)}); + std::vector<OperationPtr> operations3 = MakeOperationVector( + {std::make_tuple(OperationType::kDelete, "a", /*value=*/absl::nullopt, + /*ignore_if_present*/ absl::nullopt)}); + + RunHeaderReceived(kOrigin1, std::move(operations1)); + ASSERT_EQ(observer_->header_results().size(), 1u); + EXPECT_EQ(observer_->header_results().back().first, kOrigin1); + EXPECT_THAT(observer_->header_results().back().second, + testing::ElementsAre(true)); + + RunHeaderReceived(kOrigin2, std::move(operations2)); + ASSERT_EQ(observer_->header_results().size(), 2u); + EXPECT_EQ(observer_->header_results().back().first, kOrigin2); + EXPECT_THAT(observer_->header_results().back().second, + testing::ElementsAre(true)); + + RunHeaderReceived(kOrigin3, std::move(operations3)); + ASSERT_EQ(observer_->header_results().size(), 3u); + EXPECT_EQ(observer_->header_results().back().first, kOrigin3); + EXPECT_THAT(observer_->header_results().back().second, + testing::ElementsAre(true)); + + observer_->WaitForOperations(3); + EXPECT_THAT(observer_->operations(), + testing::ElementsAre( + SetOperation(kOrigin1, "a", "b", absl::nullopt, + OperationResult::kSet), + SetOperation(kOrigin2, "a", "c", true, OperationResult::kSet), + DeleteOperation(kOrigin3, "a", OperationResult::kSuccess))); + + // Operations on different origins don't affect each other. + EXPECT_EQ(GetExistingValue(kOrigin1, "a"), "b"); + EXPECT_EQ(GetExistingValue(kOrigin2, "a"), "c"); + EXPECT_TRUE(ValueNotFound(kOrigin3, "a")); + EXPECT_EQ(Length(kOrigin1), 1); + EXPECT_EQ(Length(kOrigin2), 1); + EXPECT_EQ(Length(kOrigin3), 0); +} + +TEST_P(SharedStorageHeaderObserverTest, SkipMissingParams) { + SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowedForTesting() = + true; + + const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1)); + + std::vector<OperationPtr> operations = MakeOperationVector({ + std::make_tuple(OperationType::kClear, /*key*/ absl::nullopt, + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // success + std::make_tuple(OperationType::kSet, "a", /*value*/ absl::nullopt, + /*ignore_if_present*/ false), // fail + std::make_tuple(OperationType::kSet, /*key*/ absl::nullopt, "b", + /*ignore_if_present*/ true), // fail + std::make_tuple(OperationType::kSet, /*key*/ absl::nullopt, + /*value*/ absl::nullopt, + /*ignore_if_present*/ true), // fail + std::make_tuple(OperationType::kAppend, "a", /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kAppend, "a", "b", + /*ignore_if_present*/ absl::nullopt), // success + std::make_tuple(OperationType::kAppend, /*key*/ absl::nullopt, "b", + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kAppend, /*key*/ absl::nullopt, + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kSet, "a", "c", + /*ignore_if_present*/ true), // success + std::make_tuple(OperationType::kSet, "d", "c", + /*ignore_if_present*/ absl::nullopt), // success + std::make_tuple(OperationType::kDelete, /*key*/ absl::nullopt, + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kDelete, "anything", + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // success + }); + + RunHeaderReceived(kOrigin1, std::move(operations)); + ASSERT_EQ(observer_->header_results().size(), 1u); + EXPECT_EQ(observer_->header_results().back().first, kOrigin1); + EXPECT_THAT(observer_->header_results().back().second, + testing::ElementsAre(true, false, false, false, false, true, + false, false, true, true, false, true)); + + observer_->WaitForOperations(5); + EXPECT_THAT( + observer_->operations(), + testing::ElementsAre( + ClearOperation(kOrigin1, OperationResult::kSuccess), + AppendOperation(kOrigin1, "a", "b", OperationResult::kSet), + SetOperation(kOrigin1, "a", "c", true, OperationResult::kIgnored), + SetOperation(kOrigin1, "d", "c", absl::nullopt, + OperationResult::kSet), + DeleteOperation(kOrigin1, "anything", OperationResult::kSuccess))); + + EXPECT_EQ(GetExistingValue(kOrigin1, "a"), "b"); + EXPECT_EQ(GetExistingValue(kOrigin1, "d"), "c"); + EXPECT_TRUE(ValueNotFound(kOrigin1, "anything")); + EXPECT_EQ(Length(kOrigin1), 2); +} + +TEST_P(SharedStorageHeaderObserverTest, SkipInvalidParams) { + SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowedForTesting() = + true; + + const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1)); + const std::string kLong(1025, 'x'); + + std::vector<OperationPtr> operations = MakeOperationVector({ + std::make_tuple(OperationType::kClear, /*key*/ absl::nullopt, + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // success + std::make_tuple(OperationType::kSet, "a", kLong, + /*ignore_if_present*/ false), // fail + std::make_tuple(OperationType::kSet, kLong, "b", + /*ignore_if_present*/ true), // fail + std::make_tuple(OperationType::kSet, "", "b", + /*ignore_if_present*/ true), // fail + std::make_tuple(OperationType::kSet, kLong, kLong, + /*ignore_if_present*/ true), // fail + std::make_tuple(OperationType::kSet, "", kLong, + /*ignore_if_present*/ true), // fail + std::make_tuple(OperationType::kAppend, "a", kLong, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kAppend, "a", "b", + /*ignore_if_present*/ absl::nullopt), // success + std::make_tuple(OperationType::kAppend, kLong, "b", + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kAppend, "", "b", + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kAppend, kLong, kLong, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kAppend, "", kLong, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kSet, "a", "c", + /*ignore_if_present*/ true), // success + std::make_tuple(OperationType::kSet, "d", "c", + /*ignore_if_present*/ absl::nullopt), // success + std::make_tuple(OperationType::kDelete, kLong, + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kDelete, "", + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // fail + std::make_tuple(OperationType::kDelete, "anything", + /*value*/ absl::nullopt, + /*ignore_if_present*/ absl::nullopt), // success + }); + + RunHeaderReceived(kOrigin1, std::move(operations)); + ASSERT_EQ(observer_->header_results().size(), 1u); + EXPECT_EQ(observer_->header_results().back().first, kOrigin1); + EXPECT_THAT(observer_->header_results().back().second, + testing::ElementsAre(true, false, false, false, false, false, + false, true, false, false, false, false, + true, true, false, false, true)); + + observer_->WaitForOperations(5); + EXPECT_THAT( + observer_->operations(), + testing::ElementsAre( + ClearOperation(kOrigin1, OperationResult::kSuccess), + AppendOperation(kOrigin1, "a", "b", OperationResult::kSet), + SetOperation(kOrigin1, "a", "c", true, OperationResult::kIgnored), + SetOperation(kOrigin1, "d", "c", absl::nullopt, + OperationResult::kSet), + DeleteOperation(kOrigin1, "anything", OperationResult::kSuccess))); + + EXPECT_EQ(GetExistingValue(kOrigin1, "a"), "b"); + EXPECT_EQ(GetExistingValue(kOrigin1, "d"), "c"); + EXPECT_TRUE(ValueNotFound(kOrigin1, "anything")); + EXPECT_EQ(Length(kOrigin1), 2); +} + +TEST_P(SharedStorageHeaderObserverTest, IgnoreExtraParams) { + SharedStorageHeaderObserver::GetBypassIsSharedStorageAllowedForTesting() = + true; + + const url::Origin kOrigin1 = url::Origin::Create(GURL(kTestOrigin1)); + + std::vector<OperationPtr> operations = MakeOperationVector( + {std::make_tuple(OperationType::kClear, "key1", "value2", + /*ignore_if_present*/ true), // extra params + std::make_tuple(OperationType::kSet, "key1", "value1", + /*ignore_if_present*/ absl::nullopt), + std::make_tuple(OperationType::kAppend, "key1", "value1", + /*ignore_if_present*/ false), // extra param + std::make_tuple(OperationType::kSet, "key1", "value2", + /*ignore_if_present*/ true), + std::make_tuple(OperationType::kSet, "key2", "value2", + /*ignore_if_present*/ false), + std::make_tuple(OperationType::kDelete, "key2", "value2", + /*ignore_if_present*/ false)}); // extra params + + RunHeaderReceived(kOrigin1, std::move(operations)); + ASSERT_EQ(observer_->header_results().size(), 1u); + EXPECT_EQ(observer_->header_results().back().first, kOrigin1); + EXPECT_THAT(observer_->header_results().back().second, + testing::ElementsAre(true, true, true, true, true, true)); + + // Superfluous parameters are omitted. + observer_->WaitForOperations(6); + EXPECT_THAT( + observer_->operations(), + testing::ElementsAre( + ClearOperation(kOrigin1, OperationResult::kSuccess), + SetOperation(kOrigin1, "key1", "value1", absl::nullopt, + OperationResult::kSet), + AppendOperation(kOrigin1, "key1", "value1", OperationResult::kSet), + SetOperation(kOrigin1, "key1", "value2", true, + OperationResult::kIgnored), + SetOperation(kOrigin1, "key2", "value2", false, + OperationResult::kSet), + DeleteOperation(kOrigin1, "key2", OperationResult::kSuccess))); + + EXPECT_EQ(GetExistingValue(kOrigin1, "key1"), "value1value1"); + EXPECT_TRUE(ValueNotFound(kOrigin1, "key2")); + EXPECT_EQ(Length(kOrigin1), 1); +} + +} // namespace content
diff --git a/content/browser/storage_partition_impl.cc b/content/browser/storage_partition_impl.cc index 902527b2..db9de8fb 100644 --- a/content/browser/storage_partition_impl.cc +++ b/content/browser/storage_partition_impl.cc
@@ -93,6 +93,7 @@ #include "content/browser/runtime_feature_state/runtime_feature_state_document_data.h" #include "content/browser/service_worker/service_worker_container_host.h" #include "content/browser/service_worker/service_worker_context_wrapper.h" +#include "content/browser/shared_storage/shared_storage_header_observer.h" #include "content/browser/shared_storage/shared_storage_worklet_host_manager.h" #include "content/browser/ssl/ssl_client_auth_handler.h" #include "content/browser/ssl/ssl_error_handler.h" @@ -1501,6 +1502,8 @@ : path.Append(storage::kSharedStoragePath); shared_storage_manager_ = std::make_unique<storage::SharedStorageManager>( shared_storage_path, special_storage_policy_); + shared_storage_header_observer_ = + std::make_unique<SharedStorageHeaderObserver>(this); } if (base::FeatureList::IsEnabled(blink::features::kPrivateAggregationApi)) { @@ -2154,6 +2157,22 @@ sent_bytes); } +void StoragePartitionImpl::OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) { + if (!shared_storage_header_observer_) { + std::move(callback).Run(); + return; + } + auto* navigation_or_document = + url_loader_network_observers_.current_context().navigation_or_document(); + DCHECK(navigation_or_document); + RenderFrameHost* rfh = navigation_or_document->GetDocument(); + shared_storage_header_observer_->HeaderReceived( + request_origin, rfh, std::move(operations), std::move(callback)); +} + void StoragePartitionImpl::Clone( mojo::PendingReceiver<network::mojom::URLLoaderNetworkServiceObserver> observer) { @@ -3057,6 +3076,13 @@ std::move(shared_storage_worklet_host_manager); } +void StoragePartitionImpl::OverrideSharedStorageHeaderObserverForTesting( + std::unique_ptr<SharedStorageHeaderObserver> + shared_storage_header_observer) { + DCHECK(initialized_); + shared_storage_header_observer_ = std::move(shared_storage_header_observer); +} + void StoragePartitionImpl::OverrideAggregationServiceForTesting( std::unique_ptr<AggregationService> aggregation_service) { DCHECK(initialized_);
diff --git a/content/browser/storage_partition_impl.h b/content/browser/storage_partition_impl.h index 772d125d..2ec3394 100644 --- a/content/browser/storage_partition_impl.h +++ b/content/browser/storage_partition_impl.h
@@ -92,6 +92,7 @@ class PushMessagingContext; class ResourceCacheManager; class QuotaContext; +class SharedStorageHeaderObserver; class SharedStorageWorkletHostManager; class SharedWorkerServiceImpl; class SubresourceProxyingURLLoaderService; @@ -142,6 +143,9 @@ void OverrideSharedStorageWorkletHostManagerForTesting( std::unique_ptr<SharedStorageWorkletHostManager> shared_storage_worklet_host_manager); + void OverrideSharedStorageHeaderObserverForTesting( + std::unique_ptr<SharedStorageHeaderObserver> + shared_storage_header_observer); void OverrideAggregationServiceForTesting( std::unique_ptr<AggregationService> aggregation_service); void OverrideAttributionManagerForTesting( @@ -351,6 +355,14 @@ void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash, int64_t recv_bytes, int64_t sent_bytes) override; + void OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) override; + + SharedStorageHeaderObserver* shared_storage_header_observer() { + return shared_storage_header_observer_.get(); + } scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter() { return url_loader_factory_getter_; @@ -677,6 +689,9 @@ std::unique_ptr<SharedStorageWorkletHostManager> shared_storage_worklet_host_manager_; + // Owning pointer to the `SharedStorageHeaderObserver` for this partition. + std::unique_ptr<SharedStorageHeaderObserver> shared_storage_header_observer_; + std::unique_ptr<PrivateAggregationManager> private_aggregation_manager_; std::unique_ptr<ResourceCacheManager> resource_cache_manager_;
diff --git a/content/browser/webid/federated_auth_request_impl.cc b/content/browser/webid/federated_auth_request_impl.cc index 3c3a6db3..bd1a357 100644 --- a/content/browser/webid/federated_auth_request_impl.cc +++ b/content/browser/webid/federated_auth_request_impl.cc
@@ -1598,7 +1598,16 @@ IdentityProviderConfigPtr idp, IdpNetworkRequestManager::FetchStatus status, const GURL& continue_on) { - if (!IsFedCmAuthzEnabled()) { + // We only allow loading continue_on urls that are same-origin + // with the IdP. + // This isn't necessarily final, but seemed like a safer + // and sufficient default for now. + // This behavior may change in https://crbug.com/1429083 + bool is_same_origin = + url::Origin::Create(continue_on) + .IsSameOriginWith(url::Origin::Create(idp->config_url)); + + if (!IsFedCmAuthzEnabled() || !is_same_origin) { CompleteRequestWithError( FederatedAuthRequestResult::kErrorFetchingIdTokenInvalidResponse, TokenStatus::kIdTokenInvalidResponse,
diff --git a/content/browser/webid/federated_auth_request_impl_unittest.cc b/content/browser/webid/federated_auth_request_impl_unittest.cc index f73fda3..bffad2c 100644 --- a/content/browser/webid/federated_auth_request_impl_unittest.cc +++ b/content/browser/webid/federated_auth_request_impl_unittest.cc
@@ -4143,7 +4143,7 @@ // Set up the network expectations to return a "continue_on" response // rather than the typical idtoken response. - GURL continue_on("/more-permissions.php"); + GURL continue_on = GURL(kProviderUrlFull).Resolve("/more-permissions.php"); config.continue_on = std::move(continue_on); // Set up the UI dialog controller to show a pop-up window, rather @@ -4178,6 +4178,35 @@ EXPECT_FALSE(DidFetch(FetchedEndpoint::CLIENT_METADATA)); } +// Test successful AuthZ request that request the opening of pop-up +// windows. +TEST_F(FederatedAuthRequestImplTest, + FailsLoadingAContinueOnForADifferentOrigin) { + base::test::ScopedFeatureList list; + list.InitAndEnableFeature(features::kFedCmAuthz); + + RequestParameters parameters = kDefaultRequestParameters; + parameters.identity_providers[0].scope = {"calendar.readonly"}; + + MockConfiguration config = kConfigurationValid; + config.succeed_with_console_message = true; + + // Set up the network expectations to return a "continue_on" response + // rather than the typical idtoken response. + GURL continue_on = + GURL("https://another-origin.example").Resolve("/more-permissions.php"); + config.continue_on = std::move(continue_on); + + RequestExpectations error = { + RequestTokenStatus::kError, + /*devtools_issue_statuses=*/{}, + // TODO(https://crbug.com/1429083): introduce a more granular error. + /*standalone_console_messages=*/{"Provider's token is invalid."}, + /*selected_idp_config_url=*/absl::nullopt}; + + RunAuthTest(parameters, error, config); +} + // Test that IdentityRegistry is notified when modal dialog view is closed. TEST_F(FederatedAuthRequestImplTest, IdentityRegistryIsNotified) { EXPECT_FALSE(test_identity_registry_->notified_);
diff --git a/content/browser/webid/federated_auth_user_info_request.cc b/content/browser/webid/federated_auth_user_info_request.cc index b9b1c0a..6669a8d1 100644 --- a/content/browser/webid/federated_auth_user_info_request.cc +++ b/content/browser/webid/federated_auth_user_info_request.cc
@@ -5,6 +5,7 @@ #include "content/browser/webid/federated_auth_user_info_request.h" #include "base/functional/callback.h" +#include "base/metrics/histogram_functions.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/webid/flags.h" #include "content/browser/webid/webid_utils.h" @@ -38,7 +39,7 @@ } FederatedAuthUserInfoRequest::~FederatedAuthUserInfoRequest() { - CompleteWithError(); + CompleteWithError(RequestStatus::kUnhandledRequest); } FederatedAuthUserInfoRequest::FederatedAuthUserInfoRequest( @@ -70,33 +71,33 @@ // Renderer also checks that the origin is same origin with `idp_config_url_`. // The check is duplicated in case that the renderer is compromised. if (!origin_.IsSameOriginWith(idp_config_url_)) { - Complete(blink::mojom::RequestUserInfoStatus::kError, absl::nullopt); + CompleteWithError(RequestStatus::kNotSameOrigin); return; } // Check that `render_frame_host` is for an iframe. if (!parent_frame_origin_.GetURL().is_valid()) { - CompleteWithError(); + CompleteWithError(RequestStatus::kNotIframe); return; } if (!network::IsOriginPotentiallyTrustworthy( url::Origin::Create(idp_config_url_))) { - CompleteWithError(); + CompleteWithError(RequestStatus::kNotPotentiallyTrustworthy); return; } FederatedApiPermissionStatus permission_status = api_permission_delegate->GetApiPermissionStatus(embedding_origin_); if (permission_status != FederatedApiPermissionStatus::GRANTED) { - CompleteWithError(); + CompleteWithError(RequestStatus::kNoApiPermission); return; } if (webid::ShouldFailAccountsEndpointRequestBecauseNotSignedInWithIdp( idp_config_url_, permission_delegate_) && GetFedCmIdpSigninStatusMode() == FedCmIdpSigninStatusMode::ENABLED) { - CompleteWithError(); + CompleteWithError(RequestStatus::kNotSignedInWithIdp); return; } @@ -105,7 +106,7 @@ url::Origin::Create(idp_config_url_), /*account_id=*/absl::nullopt)) { // If there is no sharing permission, we can abort before performing any // fetch. - CompleteWithError(); + CompleteWithError(RequestStatus::kNoAccountSharingPermission); return; } @@ -128,12 +129,12 @@ if (fetch_results.size() != 1u) { // This could happen when the user info request was sent from a compromised // renderer (>1) or fetch_results is empty (<1). - CompleteWithError(); + CompleteWithError(RequestStatus::kInvalidConfigOrWellKnown); return; } if (fetch_results[0].error) { - CompleteWithError(); + CompleteWithError(RequestStatus::kInvalidConfigOrWellKnown); return; } @@ -144,7 +145,7 @@ idp_config_url_, permission_delegate_); if (does_idp_have_failing_signin_status_ && GetFedCmIdpSigninStatusMode() == FedCmIdpSigninStatusMode::ENABLED) { - CompleteWithError(); + CompleteWithError(RequestStatus::kNotSignedInWithIdp); return; } @@ -163,7 +164,7 @@ if (fetch_status.parse_status != IdpNetworkRequestManager::ParseStatus::kSuccess) { - CompleteWithError(); + CompleteWithError(RequestStatus::kInvalidAccountsResponse); return; } MaybeReturnAccounts(std::move(accounts)); @@ -197,7 +198,7 @@ } if (!has_returning_accounts) { - CompleteWithError(); + CompleteWithError(RequestStatus::kNoReturningUserFromFetchedAccounts); return; } @@ -209,21 +210,25 @@ account.email, account.given_name, account.name, account.picture.spec())); } - Complete(blink::mojom::RequestUserInfoStatus::kSuccess, std::move(user_info)); + Complete(blink::mojom::RequestUserInfoStatus::kSuccess, std::move(user_info), + RequestStatus::kSuccess); } void FederatedAuthUserInfoRequest::Complete( blink::mojom::RequestUserInfoStatus status, - absl::optional<std::vector<blink::mojom::IdentityUserInfoPtr>> user_info) { + absl::optional<std::vector<blink::mojom::IdentityUserInfoPtr>> user_info, + RequestStatus request_status) { if (!callback_) { return; } + base::UmaHistogramEnumeration("Blink.FedCm.UserInfo.Status", request_status); + std::move(callback_).Run(status, std::move(user_info)); } -void FederatedAuthUserInfoRequest::CompleteWithError() { - Complete(blink::mojom::RequestUserInfoStatus::kError, absl::nullopt); +void FederatedAuthUserInfoRequest::CompleteWithError(RequestStatus error) { + Complete(blink::mojom::RequestUserInfoStatus::kError, absl::nullopt, error); } } // namespace content
diff --git a/content/browser/webid/federated_auth_user_info_request.h b/content/browser/webid/federated_auth_user_info_request.h index 69a7404..cb19af5 100644 --- a/content/browser/webid/federated_auth_user_info_request.h +++ b/content/browser/webid/federated_auth_user_info_request.h
@@ -29,6 +29,23 @@ // Fetches data for user-info request. class CONTENT_EXPORT FederatedAuthUserInfoRequest { public: + // Used for metrics recording. Do not modify or remove existing values. You + // may add new values at the end. + enum class RequestStatus { + kSuccess = 0, + kNotSameOrigin = 1, + kNotIframe = 2, + kNotPotentiallyTrustworthy = 3, + kNoApiPermission = 4, + kNotSignedInWithIdp = 5, + kNoAccountSharingPermission = 6, + kInvalidConfigOrWellKnown = 7, + kInvalidAccountsResponse = 8, + kNoReturningUserFromFetchedAccounts = 9, + kUnhandledRequest = 10, + kMaxValue = kUnhandledRequest + }; + // Returns an object which fetches data for user-info request. static std::unique_ptr<FederatedAuthUserInfoRequest> Create( std::unique_ptr<IdpNetworkRequestManager> network_manager, @@ -69,9 +86,10 @@ void Complete( blink::mojom::RequestUserInfoStatus status, - absl::optional<std::vector<blink::mojom::IdentityUserInfoPtr>> user_info); + absl::optional<std::vector<blink::mojom::IdentityUserInfoPtr>> user_info, + RequestStatus request_status); - void CompleteWithError(); + void CompleteWithError(RequestStatus error); std::unique_ptr<IdpNetworkRequestManager> network_manager_; raw_ptr<FederatedIdentityApiPermissionContextDelegate>
diff --git a/content/browser/webid/federated_auth_user_info_request_unittest.cc b/content/browser/webid/federated_auth_user_info_request_unittest.cc index d9bb6df..f272368 100644 --- a/content/browser/webid/federated_auth_user_info_request_unittest.cc +++ b/content/browser/webid/federated_auth_user_info_request_unittest.cc
@@ -13,6 +13,7 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/task/sequenced_task_runner.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/task_environment.h" #include "content/browser/webid/fedcm_metrics.h" #include "content/browser/webid/test/mock_api_permission_delegate.h" @@ -320,6 +321,7 @@ std::unique_ptr<TestPermissionDelegate> permission_delegate_; std::unique_ptr<NiceMock<FedCmMetrics>> metrics_; std::unique_ptr<FederatedAuthUserInfoRequest> request_; + base::HistogramTester histogram_tester_; }; TEST_F(FederatedAuthUserInfoRequestTest, PreviouslySignedIn) { @@ -333,6 +335,10 @@ /*was_granted_sharing_permission=*/false}}; RunUserInfoTest(config, RequestUserInfoStatus::kSuccess, {kAccount1Id, kAccount2Id}); + + histogram_tester_.ExpectUniqueSample( + "Blink.FedCm.UserInfo.Status", + FederatedAuthUserInfoRequest::RequestStatus::kSuccess, 1); } TEST_F(FederatedAuthUserInfoRequestTest, NoSignedInAccount) { @@ -346,6 +352,11 @@ /*was_granted_sharing_permission=*/false}}; RunUserInfoTest(config, RequestUserInfoStatus::kError, {}); EXPECT_FALSE(DidFetchAnyEndpoint()); + + histogram_tester_.ExpectUniqueSample( + "Blink.FedCm.UserInfo.Status", + FederatedAuthUserInfoRequest::RequestStatus::kNoAccountSharingPermission, + 1); } TEST_F(FederatedAuthUserInfoRequestTest, NotInApprovedClientsList) { @@ -358,6 +369,12 @@ {kAccount2Id, /*login_state=*/LoginState::kSignUp, /*was_granted_sharing_permission=*/true}}; RunUserInfoTest(config, RequestUserInfoStatus::kError, {}); + + histogram_tester_.ExpectUniqueSample( + "Blink.FedCm.UserInfo.Status", + FederatedAuthUserInfoRequest::RequestStatus:: + kNoReturningUserFromFetchedAccounts, + 1); } TEST_F(FederatedAuthUserInfoRequestTest, InApprovedClientsList) { @@ -378,6 +395,11 @@ config.config_fetch_status = {ParseStatus::kHttpNotFoundError, 404}; RunUserInfoTest(config, RequestUserInfoStatus::kError, {}); + + histogram_tester_.ExpectUniqueSample( + "Blink.FedCm.UserInfo.Status", + FederatedAuthUserInfoRequest::RequestStatus::kInvalidConfigOrWellKnown, + 1); } TEST_F(FederatedAuthUserInfoRequestTest,
diff --git a/content/browser/webid/idp_network_request_manager.cc b/content/browser/webid/idp_network_request_manager.cc index 8877e98..5eae989 100644 --- a/content/browser/webid/idp_network_request_manager.cc +++ b/content/browser/webid/idp_network_request_manager.cc
@@ -518,6 +518,7 @@ void OnTokenRequestParsed( IdpNetworkRequestManager::TokenRequestCallback callback, IdpNetworkRequestManager::ContinueOnCallback continue_on_callback, + const GURL& token_url, FetchStatus fetch_status, data_decoder::DataDecoder::ValueOrError result) { if (fetch_status.parse_status != ParseStatus::kSuccess) { @@ -536,10 +537,7 @@ } if (continue_on) { - GURL url(*continue_on); - // TODO(crbug.com/1429083): support relative urls. - // TODO(crbug.com/1429083): check that the continue_on url is - // same-origin with the idp origin. + GURL url = token_url.Resolve(*continue_on); if (url.is_valid()) { std::move(continue_on_callback) .Run({ParseStatus::kSuccess, fetch_status.response_code}, @@ -690,7 +688,7 @@ DownloadJsonAndParse( std::move(resource_request), url_encoded_post_data, base::BindOnce(&OnTokenRequestParsed, std::move(callback), - std::move(continue_on)), + std::move(continue_on), token_url), maxResponseSizeInKiB * 1024); }
diff --git a/content/browser/webid/idp_network_request_manager_unittest.cc b/content/browser/webid/idp_network_request_manager_unittest.cc index 214ff52..5aa040d 100644 --- a/content/browser/webid/idp_network_request_manager_unittest.cc +++ b/content/browser/webid/idp_network_request_manager_unittest.cc
@@ -1162,7 +1162,7 @@ const std::string& mime_type = "application/json"; const char response[] = - R"({"continue_on": "https://idp.example/continuation"})"; + R"({"continue_on": "https://idp.test/an-absolute-url-for-continuation"})"; GURL token_endpoint(kTestTokenEndpoint); AddResponse(token_endpoint, http_status, mime_type, response); @@ -1170,12 +1170,38 @@ auto callback = base::BindLambdaForTesting( [&](FetchStatus status, const std::string& token_response) {}); - auto on_continue = - base::BindLambdaForTesting([&](FetchStatus status, const GURL& url) { - // Checks that we got a continuation url event back. - EXPECT_EQ("https://idp.example/continuation", url.spec()); - run_loop.Quit(); - }); + auto on_continue = base::BindLambdaForTesting([&](FetchStatus status, + const GURL& url) { + // Checks that we got a continuation url event back. + EXPECT_EQ("https://idp.test/an-absolute-url-for-continuation", url.spec()); + run_loop.Quit(); + }); + + std::unique_ptr<IdpNetworkRequestManager> manager = CreateTestManager(); + manager->SendTokenRequest(token_endpoint, "account", "request", + std::move(callback), std::move(on_continue)); + run_loop.Run(); +} + +TEST_F(IdpNetworkRequestManagerTest, ContinueOnCanBeRelativeUrl) { + net::HttpStatusCode http_status = net::HTTP_OK; + const std::string& mime_type = "application/json"; + + const char response[] = + R"({"continue_on": "/a-relative-url-for-continuation"})"; + GURL token_endpoint(kTestTokenEndpoint); + AddResponse(token_endpoint, http_status, mime_type, response); + + base::RunLoop run_loop; + auto callback = base::BindLambdaForTesting( + [&](FetchStatus status, const std::string& token_response) {}); + + auto on_continue = base::BindLambdaForTesting([&](FetchStatus status, + const GURL& url) { + // Checks that we got a continuation url event back. + EXPECT_EQ("https://idp.test/a-relative-url-for-continuation", url.spec()); + run_loop.Quit(); + }); std::unique_ptr<IdpNetworkRequestManager> manager = CreateTestManager(); manager->SendTokenRequest(token_endpoint, "account", "request",
diff --git a/content/browser/webid/webid_browsertest.cc b/content/browser/webid/webid_browsertest.cc index c132926..4860b5b7 100644 --- a/content/browser/webid/webid_browsertest.cc +++ b/content/browser/webid/webid_browsertest.cc
@@ -756,12 +756,13 @@ // Points the id assertion endpoint to a servlet. config_details.id_assertion_endpoint_url = "/authz/id_assertion_endpoint.php"; - auto continue_on = GURL(BaseIdpUrl()).Resolve("/authz.html"); + // Points to the relative url of the authorization servlet. + std::string continue_on = "/authz.html"; // Add a servlet to serve a response for the id assertoin endpoint. config_details.servlets["/authz/id_assertion_endpoint.php"] = base::BindRepeating( - [](GURL url, + [](std::string url, const HttpRequest& request) -> std::unique_ptr<HttpResponse> { std::string content; content += "client_id=client_id_1&"; @@ -777,7 +778,7 @@ response->set_content_type("text/json"); // scope=calendar.readonly was requested, so need to // return a continuation url instead of a token. - auto body = R"({"continue_on": ")" + url.spec() + R"("})"; + auto body = R"({"continue_on": ")" + url + R"("})"; response->set_content(body); return response; }, @@ -812,8 +813,10 @@ base::RunLoop run_loop; EXPECT_CALL(*controller, ShowModalDialog(_, _)) .WillOnce(::testing::WithArg<0>( - [&continue_on, &modal, &run_loop](const GURL& url) { - EXPECT_EQ(url, continue_on); + [&config_url, continue_on, &modal, &run_loop](const GURL& url) { + // Expect that the relative continue_on url will be resolved + // before opening the dialog. + EXPECT_EQ(url.spec(), config_url.Resolve(continue_on)); // When the pop-up window is opened, resolve it immediately by // returning a test web contents, which can then later be used // to refer to the identity registry.
diff --git a/content/browser/webui/test_webui_js_bridge_ui.cc b/content/browser/webui/test_webui_js_bridge_ui.cc index eeced08f..bda4156d 100644 --- a/content/browser/webui/test_webui_js_bridge_ui.cc +++ b/content/browser/webui/test_webui_js_bridge_ui.cc
@@ -8,6 +8,6 @@ WEB_UI_CONTROLLER_TYPE_IMPL(TestWebUIJsBridgeUI) -WEB_UI_CONTROLLER_TYPE_IMPL(TestWebUIJsBridgeIncorrectUI) +WEB_UI_CONTROLLER_TYPE_IMPL(TestWebUIJsBridgeUI2) } // namespace content
diff --git a/content/browser/webui/test_webui_js_bridge_ui.h b/content/browser/webui/test_webui_js_bridge_ui.h index 2eca36ae..5816e0a 100644 --- a/content/browser/webui/test_webui_js_bridge_ui.h +++ b/content/browser/webui/test_webui_js_bridge_ui.h
@@ -21,16 +21,14 @@ WEB_UI_CONTROLLER_TYPE_DECL(); }; -// WebUIController for WebUIJsBridge unittests. -class TestWebUIJsBridgeIncorrectUI : public WebUIController { +// Additional WebUIController for WebUIJsBridge unittests. +class TestWebUIJsBridgeUI2 : public WebUIController { public: - explicit TestWebUIJsBridgeIncorrectUI(WebUI* web_ui) - : WebUIController(web_ui) {} - ~TestWebUIJsBridgeIncorrectUI() override = default; + explicit TestWebUIJsBridgeUI2(WebUI* web_ui) : WebUIController(web_ui) {} + ~TestWebUIJsBridgeUI2() override = default; - TestWebUIJsBridgeIncorrectUI(const TestWebUIJsBridgeIncorrectUI&) = delete; - TestWebUIJsBridgeIncorrectUI& operator=(const TestWebUIJsBridgeIncorrectUI&) = - delete; + TestWebUIJsBridgeUI2(const TestWebUIJsBridgeUI2&) = delete; + TestWebUIJsBridgeUI2& operator=(const TestWebUIJsBridgeUI2&) = delete; WEB_UI_CONTROLLER_TYPE_DECL(); };
diff --git a/content/browser/webui/web_ui_browsertest.cc b/content/browser/webui/web_ui_browsertest.cc index 3c413dc8..25d5001 100644 --- a/content/browser/webui/web_ui_browsertest.cc +++ b/content/browser/webui/web_ui_browsertest.cc
@@ -315,7 +315,8 @@ // Push onto window.history. Back should now be an in-page navigation. ASSERT_TRUE( - ExecJs(web_contents, "window.history.pushState({}, '', 'foo.html')")); + ExecJs(web_contents, + "window.history.pushState({}, '', location.href + '#foo')")); shell()->GoBackOrForward(-1); EXPECT_TRUE(WaitForLoadStop(web_contents));
diff --git a/content/browser/webui/web_ui_managed_interface_browsertest.cc b/content/browser/webui/web_ui_managed_interface_browsertest.cc index 3cc5fcc..230ab3e 100644 --- a/content/browser/webui/web_ui_managed_interface_browsertest.cc +++ b/content/browser/webui/web_ui_managed_interface_browsertest.cc
@@ -394,6 +394,7 @@ // Iframe navigation will destroy interface impls. Reload(foo_frame); + foo_frame = ChildFrameAt(web_contents->GetPrimaryMainFrame(), 0); EXPECT_EQ(0, InstanceCounter<FooImpl>::count()); // Interface impls can be created after reload.
diff --git a/content/browser/webui/web_ui_security_browsertest.cc b/content/browser/webui/web_ui_security_browsertest.cc index 68283df..7600e643b 100644 --- a/content/browser/webui/web_ui_security_browsertest.cc +++ b/content/browser/webui/web_ui_security_browsertest.cc
@@ -124,8 +124,8 @@ } // Verify that reloading a WebUI document or navigating between documents on -// the same WebUI will result in using the same SiteInstance and will not -// create a new WebUI instance. +// the same WebUI will result in using the same SiteInstance, and will reuse +// the same WebUI instance if the RenderFrameHost is reused. IN_PROC_BROWSER_TEST_F(WebUISecurityTest, WebUIReuse) { GURL test_url(GetWebUIURL("web-ui/title1.html")); EXPECT_TRUE(NavigateToURL(shell(), test_url)); @@ -138,9 +138,11 @@ // with the ones used after the reload. scoped_refptr<SiteInstance> initial_site_instance = root->current_frame_host()->GetSiteInstance(); + RenderFrameHostImplWrapper initial_rfh(root->current_frame_host()); WebUI* initial_web_ui = root->current_frame_host()->web_ui(); - // Reload the document and check that SiteInstance and WebUI are reused. + // Reload the document and check that SiteInstance is reused, and the WebUI is + // reused if the RenderFrameHost is reused. TestFrameNavigationObserver observer(root); shell()->web_contents()->GetController().Reload(ReloadType::NORMAL, false); observer.Wait(); @@ -149,16 +151,40 @@ EXPECT_EQ(initial_site_instance, root->current_frame_host()->GetSiteInstance()); - EXPECT_EQ(initial_web_ui, root->current_frame_host()->web_ui()); + if (ShouldCreateNewHostForAllFrames()) { + EXPECT_NE(initial_rfh.get(), root->current_frame_host()); + // We can't check for WebUI inequality as the same address might be reused + // for the new WebUI object, but we can check that the new WebUI points to + // the new RFH. + EXPECT_EQ(root->current_frame_host(), + root->current_frame_host()->web_ui()->GetRenderFrameHost()); + EXPECT_NE(initial_rfh.get(), + root->current_frame_host()->web_ui()->GetRenderFrameHost()); + } else { + EXPECT_EQ(initial_rfh.get(), root->current_frame_host()); + EXPECT_EQ(initial_web_ui, root->current_frame_host()->web_ui()); + } // Navigate to another document on the same WebUI and check that SiteInstance - // and WebUI are reused. + // is reused, and the WebUI is reused if the RenderFrameHost is reused. GURL next_url(GetWebUIURL("web-ui/title2.html")); EXPECT_TRUE(NavigateToURL(shell(), next_url)); EXPECT_EQ(initial_site_instance, root->current_frame_host()->GetSiteInstance()); - EXPECT_EQ(initial_web_ui, root->current_frame_host()->web_ui()); + if (ShouldCreateNewHostForAllFrames()) { + EXPECT_NE(initial_rfh.get(), root->current_frame_host()); + // We can't check for WebUI inequality as the same address might be reused + // for the new WebUI object, but we can check that the new WebUI points to + // the new RFH. + EXPECT_EQ(root->current_frame_host(), + root->current_frame_host()->web_ui()->GetRenderFrameHost()); + EXPECT_NE(initial_rfh.get(), + root->current_frame_host()->web_ui()->GetRenderFrameHost()); + } else { + EXPECT_EQ(initial_rfh.get(), root->current_frame_host()); + EXPECT_EQ(initial_web_ui, root->current_frame_host()->web_ui()); + } } // Verify that a WebUI can add a subframe for its own WebUI.
diff --git a/content/browser/webui/web_ui_webui_js_bridge_unittest.cc b/content/browser/webui/web_ui_webui_js_bridge_unittest.cc index 71f23146..0f45653 100644 --- a/content/browser/webui/web_ui_webui_js_bridge_unittest.cc +++ b/content/browser/webui/web_ui_webui_js_bridge_unittest.cc
@@ -2,9 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/supports_user_data.h" #include "base/test/bind.h" #include "base/test/task_environment.h" #include "content/browser/webui/test_webui_js_bridge_ui.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/document_user_data.h" +#include "content/public/browser/per_web_ui_browser_interface_broker.h" +#include "content/public/browser/web_contents.h" +#include "content/public/test/test_renderer_host.h" #include "content/public/test/test_web_ui.h" #include "content/test/web_ui/webui_js_bridge_unittest.test-mojom-webui-js-bridge-impl.h" #include "content/test/web_ui/webui_js_bridge_unittest2.test-mojom-webui-js-bridge-impl.h" @@ -20,21 +26,46 @@ namespace { -class FooPageHandler : public mojom::FooPageHandler { +// WebUI interface implementation that gets created when receiving an interface +// request. It's owned by the WebUI's document. +class FooPageHandler : public mojom::FooPageHandler, + public DocumentUserData<FooPageHandler> { public: - FooPageHandler(mojo::PendingReceiver<mojom::FooPageHandler> receiver, + static void Create(content::WebUIController* controller, + mojo::PendingReceiver<mojom::FooPageHandler> receiver, + mojo::PendingRemote<mojom::FooPage> remote) { + FooPageHandler::CreateForCurrentDocument( + controller->web_ui()->GetRenderFrameHost(), std::move(receiver), + std::move(remote)); + } + + static FooPageHandler& Get(content::WebUIController* controller) { + return *FooPageHandler::GetForCurrentDocument( + controller->web_ui()->GetRenderFrameHost()); + } + + FooPageHandler(RenderFrameHost* rfh, + mojo::PendingReceiver<mojom::FooPageHandler> receiver, mojo::PendingRemote<mojom::FooPage> remote) - : receiver_(this, std::move(receiver)), remote_(std::move(remote)) {} + : DocumentUserData(rfh), + receiver_(this, std::move(receiver)), + remote_(std::move(remote)) {} + ~FooPageHandler() override = default; const mojo::Receiver<mojom::FooPageHandler>& receiver() { return receiver_; } const mojo::Remote<mojom::FooPage>& remote() { return remote_; } private: + friend DocumentUserData; + DOCUMENT_USER_DATA_KEY_DECL(); + mojo::Receiver<mojom::FooPageHandler> receiver_; mojo::Remote<mojom::FooPage> remote_; }; +DOCUMENT_USER_DATA_KEY_IMPL(FooPageHandler); + class FooPage : public mojom::FooPage { public: FooPage() = default; @@ -46,23 +77,46 @@ mojo::Receiver<mojom::FooPage> receiver_{this}; }; -class Bar : public mojom::Bar { +// WebUI interface implementation that is created and owned outside of the +// WebUI. In this case, it's owned by BrowserContext. +class Bar : public mojom::Bar, public base::SupportsUserData::Data { public: Bar() = default; ~Bar() override = default; - void BindBar(mojo::PendingReceiver<mojom::Bar> receiver) { - receivers_.Add(this, std::move(receiver)); + static void Create(BrowserContext* browser_context) { + browser_context->SetUserData("BarImpl", std::make_unique<Bar>()); } - void BindObserver(mojo::PendingRemote<mojom::BarObserver> remote) { - observers_.Add(std::move(remote)); + static Bar& Get(BrowserContext* browser_context) { + Bar* bar = static_cast<Bar*>(browser_context->GetUserData("BarImpl")); + return *bar; + } + + static void BindBar(WebUIController* controller, + mojo::PendingReceiver<mojom::Bar> receiver) { + Bar::Get(controller->web_ui()->GetWebContents()->GetBrowserContext()) + .BindBarImpl(std::move(receiver)); + } + + static void BindObserver(WebUIController* controller, + mojo::PendingRemote<mojom::BarObserver> remote) { + Bar::Get(controller->web_ui()->GetWebContents()->GetBrowserContext()) + .BindObserverImpl(std::move(remote)); } const mojo::ReceiverSet<mojom::Bar>& receivers() { return receivers_; } const mojo::RemoteSet<mojom::BarObserver>& observers() { return observers_; } private: + void BindBarImpl(mojo::PendingReceiver<mojom::Bar> receiver) { + receivers_.Add(this, std::move(receiver)); + } + + void BindObserverImpl(mojo::PendingRemote<mojom::BarObserver> remote) { + observers_.Add(std::move(remote)); + } + mojo::ReceiverSet<mojom::Bar> receivers_; mojo::RemoteSet<mojom::BarObserver> observers_; }; @@ -80,47 +134,52 @@ } // namespace -class WebUIJsBridgeTest : public testing::Test { +class WebUIJsBridgeTest : public RenderViewHostTestHarness { public: WebUIJsBridgeTest() = default; ~WebUIJsBridgeTest() override = default; + void SetUp() override { + RenderViewHostTestHarness::SetUp(); + Bar::Create(browser_context()); + test_web_ui.set_web_contents(web_contents()); + test_web_ui.set_render_frame_host(main_rfh()); + } + + void TearDown() override { + test_web_ui.set_web_contents(nullptr); + RenderViewHostTestHarness::TearDown(); + } + TestWebUI* web_ui() { return &test_web_ui; } private: - base::test::TaskEnvironment task_environment_; TestWebUI test_web_ui; }; // Tests binder methods are overridden and can be called. Calling them does // nothing for now. TEST_F(WebUIJsBridgeTest, Bind) { - std::unique_ptr<FooPageHandler> page_handler; - auto page_handler_binder = base::BindLambdaForTesting( - [&page_handler](mojo::PendingReceiver<mojom::FooPageHandler> receiver, - mojo::PendingRemote<mojom::FooPage> remote) { - page_handler = std::make_unique<FooPageHandler>(std::move(receiver), - std::move(remote)); - }); - Bar bar; - TestWebUIJsBridgeUI controller(web_ui()); mojom::FooWebUIJsBridgeImpl bridge( - &controller, page_handler_binder, - base::BindRepeating(&Bar::BindBar, base::Unretained(&bar)), - base::BindRepeating(&Bar::BindObserver, base::Unretained(&bar))); + &controller, base::BindRepeating(&FooPageHandler::Create), + base::BindRepeating(&Bar::BindBar), + base::BindRepeating(&Bar::BindObserver)); mojo::Remote<mojom::FooPageHandler> page_handler_remote; FooPage page; bridge.BindFooPageHandler(page_handler_remote.BindNewPipeAndPassReceiver(), page.receiver().BindNewPipeAndPassRemote()); + auto& page_handler = FooPageHandler::Get(&controller); EXPECT_TRUE(page_handler_remote.is_bound()); EXPECT_TRUE(page.receiver().is_bound()); - EXPECT_TRUE(page_handler->receiver().is_bound()); - EXPECT_TRUE(page_handler->remote().is_bound()); + EXPECT_TRUE(page_handler.receiver().is_bound()); + EXPECT_TRUE(page_handler.remote().is_bound()); mojo::Remote<mojom::Bar> bar_remote; bridge.BindBar(bar_remote.BindNewPipeAndPassReceiver()); + + auto& bar = Bar::Get(browser_context()); EXPECT_TRUE(bar_remote.is_bound()); EXPECT_EQ(1u, bar.receivers().size()); @@ -130,10 +189,10 @@ EXPECT_EQ(1u, bar.observers().size()); } -// Tests we correctly generate a WebUIJsBridgeImpl for a interface that +// Tests we correctly generate a WebUIJsBridgeImpl for an interface that // binds interfaces in a separate mojom. TEST_F(WebUIJsBridgeTest, CrossModule) { - TestWebUIJsBridgeUI controller(web_ui()); + TestWebUIJsBridgeUI2 controller(web_ui()); mojom::TestWebUIJsBridge2Impl bridge(&controller, base::DoNothing()); bridge.BindSecondaryInterface(mojo::NullReceiver()); } @@ -141,7 +200,8 @@ // Tests that we crash if the wrong WebUIController is passed to the // WebUIJsBridge. TEST_F(WebUIJsBridgeTest, IncorrectWebUIControllerCrash) { - TestWebUIJsBridgeIncorrectUI controller(web_ui()); + // TestWebUIJsBridge2Impl below expects TestWebUIJsBridge2. + TestWebUIJsBridgeUI controller(web_ui()); EXPECT_DEATH_IF_SUPPORTED( mojom::TestWebUIJsBridge2Impl bridge(&controller, base::DoNothing()), ""); }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index a3d6157..5b966aa5 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -476,30 +476,6 @@ } } - // Set the state of EventPath, which can be controlled by various sources in - // decreasing order of precedence: - // 1. Enterprise policy, if set - // 2. base::Feature overrides via field trial or enable/disable feature flags - // 3. --event-path-enabled-by-default flag, if set - // 4. The default value, which is disabled - if (command_line.HasSwitch(blink::switches::kEventPathPolicy)) { - const std::string value = - command_line.GetSwitchValueASCII(blink::switches::kEventPathPolicy); - if (value == blink::switches::kEventPathPolicy_ForceEnable) { - WebRuntimeFeatures::EnableEventPath(true); - } - if (value == blink::switches::kEventPathPolicy_ForceDisable) { - WebRuntimeFeatures::EnableEventPath(false); - } - } else if (base::FeatureList::GetStateIfOverridden( - blink::features::kEventPath) - .has_value()) { - // Do nothing here; it will be handled in the standard way. - } else if (command_line.HasSwitch( - blink::switches::kEventPathEnabledByDefault)) { - WebRuntimeFeatures::EnableEventPath(true); - } - // Enable or disable OffsetParentNewSpecBehavior for Enterprise Policy. This // overrides any existing settings via base::Feature. if (command_line.HasSwitch(
diff --git a/content/common/BUILD.gn b/content/common/BUILD.gn index d38bd55..9e9a06ef 100644 --- a/content/common/BUILD.gn +++ b/content/common/BUILD.gn
@@ -150,6 +150,8 @@ "service_worker/race_network_request_url_loader_client.h", "service_worker/service_worker_resource_loader.cc", "service_worker/service_worker_resource_loader.h", + "service_worker/service_worker_router_evaluator.cc", + "service_worker/service_worker_router_evaluator.h", "set_process_title.cc", "set_process_title.h", "skia_utils.cc", @@ -219,7 +221,6 @@ "//media/base/ipc", "//media/capture", "//media/gpu:buildflags", - "//media/gpu/ipc/client", "//media/gpu/ipc/common", "//media/midi", "//media/midi:mojo",
diff --git a/content/common/content_navigation_policy.cc b/content/common/content_navigation_policy.cc index e078ab15..58b09b7 100644 --- a/content/common/content_navigation_policy.cc +++ b/content/common/content_navigation_policy.cc
@@ -207,7 +207,7 @@ const base::FeatureParam<NavigationQueueingFeatureLevel> kNavigationQueueingFeatureLevelParam{ &features::kQueueNavigationsWhileWaitingForCommit, "queueing_level", - NavigationQueueingFeatureLevel::kAvoidRedundantCancellations, + NavigationQueueingFeatureLevel::kFull, &kNavigationQueueingFeatureLevels}; NavigationQueueingFeatureLevel GetNavigationQueueingFeatureLevel() {
diff --git a/content/common/service_worker/DEPS b/content/common/service_worker/DEPS new file mode 100644 index 0000000..153aa836 --- /dev/null +++ b/content/common/service_worker/DEPS
@@ -0,0 +1,3 @@ +include_rules = { + "+third_party/liburlpattern", +}
diff --git a/content/common/service_worker/service_worker_router_evaluator.cc b/content/common/service_worker/service_worker_router_evaluator.cc new file mode 100644 index 0000000..fded9e2 --- /dev/null +++ b/content/common/service_worker/service_worker_router_evaluator.cc
@@ -0,0 +1,76 @@ +// 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 "content/common/service_worker/service_worker_router_evaluator.h" + +#include "third_party/liburlpattern/options.h" +#include "third_party/liburlpattern/pattern.h" +#include "third_party/re2/src/re2/re2.h" + +namespace { + +std::string ConvertToRegex(const blink::UrlPattern& url_pattern) { + liburlpattern::Options options = {.delimiter_list = "/", + .prefix_list = "/", + .sensitive = true, + .strict = false}; + liburlpattern::Pattern pattern(url_pattern.pathname, options, "[^/]+?"); + VLOG(3) << "regex string:" << pattern.GenerateRegexString(); + return pattern.GenerateRegexString(); +} + +} // namespace + +namespace content { + +ServiceWorkerRouterEvaluator::RouterRule::RouterRule() + : url_patterns(RE2::Set(RE2::Options(), RE2::Anchor::UNANCHORED)) {} + +ServiceWorkerRouterEvaluator::RouterRule::~RouterRule() = default; + +ServiceWorkerRouterEvaluator::ServiceWorkerRouterEvaluator( + blink::ServiceWorkerRouterRules rules) + : rules_(std::move(rules)) { + Compile(); +} +ServiceWorkerRouterEvaluator::~ServiceWorkerRouterEvaluator() = default; + +void ServiceWorkerRouterEvaluator::Compile() { + for (const auto& r : rules_.rules) { + std::unique_ptr<RouterRule> rule = absl::make_unique<RouterRule>(); + for (const auto& condition : r.conditions) { + CHECK_EQ(condition.type, + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern); + if (rule->url_patterns.Add(ConvertToRegex(*condition.url_pattern), + nullptr) == -1) { + // Failed to parse the regex. + return; + } + } + rule->url_pattern_length = r.conditions.size(); + if (!rule->url_patterns.Compile()) { + // Failed to compile the regex. + return; + } + rule->sources = r.sources; + compiled_rules_.emplace_back(std::move(rule)); + } + is_valid_ = true; +} + +std::vector<blink::ServiceWorkerRouterSource> +ServiceWorkerRouterEvaluator::Evaluate( + const network::ResourceRequest& request) const { + for (const auto& rule : compiled_rules_) { + std::vector<int> vec; + if (rule->url_patterns.Match(request.url.path(), &vec) && + // ensure it matches all included patterns. + vec.size() == rule->url_pattern_length) { + return rule->sources; + } + } + return std::vector<blink::ServiceWorkerRouterSource>(); +} + +} // namespace content
diff --git a/content/common/service_worker/service_worker_router_evaluator.h b/content/common/service_worker/service_worker_router_evaluator.h new file mode 100644 index 0000000..4bb0cb1 --- /dev/null +++ b/content/common/service_worker/service_worker_router_evaluator.h
@@ -0,0 +1,48 @@ +// 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 CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_EVALUATOR_H_ +#define CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_EVALUATOR_H_ + +#include <utility> + +#include "content/common/content_export.h" +#include "services/network/public/cpp/resource_request.h" +#include "third_party/blink/public/common/service_worker/service_worker_router_rule.h" +#include "third_party/re2/src/re2/set.h" + +namespace content { + +class CONTENT_EXPORT ServiceWorkerRouterEvaluator { + public: + struct RouterRule { + RouterRule(); + ~RouterRule(); + + RE2::Set url_patterns; + size_t url_pattern_length = 0; + std::vector<blink::ServiceWorkerRouterSource> sources; + }; + explicit ServiceWorkerRouterEvaluator(blink::ServiceWorkerRouterRules rules); + ~ServiceWorkerRouterEvaluator(); + + bool IsValid() { return is_valid_; } + + // Returns an empty list if nothing matched. + std::vector<blink::ServiceWorkerRouterSource> Evaluate( + const network::ResourceRequest& request) const; + + const blink::ServiceWorkerRouterRules& rules() const { return rules_; } + + private: + void Compile(); + + const blink::ServiceWorkerRouterRules rules_; + std::vector<std::unique_ptr<RouterRule>> compiled_rules_; + bool is_valid_ = false; +}; + +} // namespace content + +#endif // CONTENT_COMMON_SERVICE_WORKER_SERVICE_WORKER_ROUTER_EVALUATOR_H_
diff --git a/content/common/service_worker/service_worker_router_evaluator_unittest.cc b/content/common/service_worker/service_worker_router_evaluator_unittest.cc new file mode 100644 index 0000000..c83dd42d --- /dev/null +++ b/content/common/service_worker/service_worker_router_evaluator_unittest.cc
@@ -0,0 +1,309 @@ +// 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 "content/common/service_worker/service_worker_router_evaluator.h" + +#include "base/strings/string_piece.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/liburlpattern/parse.h" +#include "third_party/liburlpattern/pattern.h" + +namespace content { + +namespace { + +TEST(ServiceWorkerRouterEvaluator, EmptyRule) { + blink::ServiceWorkerRouterRules rules; + ServiceWorkerRouterEvaluator evaluator(rules); + EXPECT_EQ(0U, evaluator.rules().rules.size()); + + ASSERT_TRUE(evaluator.IsValid()); + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/"); + const auto sources = evaluator.Evaluate(request); + EXPECT_TRUE(sources.empty()); +} + +TEST(ServiceWorkerRouterEvaluator, SimpleMatch) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "/test/*", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::SourceType::kNetwork; + source.network_source = blink::ServiceWorkerRouterNetworkSource{}; + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(1U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(1U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/test/page.html"); + const auto sources = evaluator.Evaluate(request); + EXPECT_EQ(1U, sources.size()); +} + +TEST(ServiceWorkerRouterEvaluator, SimpleExactMatch) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "/test/page.html", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::SourceType::kNetwork; + source.network_source = blink::ServiceWorkerRouterNetworkSource{}; + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(1U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(1U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/test/page.html"); + const auto sources = evaluator.Evaluate(request); + EXPECT_EQ(1U, sources.size()); +} + +TEST(ServiceWorkerRouterEvaluator, NotMatchingCondition) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "/test/*", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::SourceType::kNetwork; + source.network_source = blink::ServiceWorkerRouterNetworkSource{}; + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(1U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(1U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/notmatched/page.html"); + const auto sources = evaluator.Evaluate(request); + EXPECT_EQ(0U, sources.size()); +} + +TEST(ServiceWorkerRouterEvaluator, OneConditionMisMatch) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "/test/*", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "/notmatch/*", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::SourceType::kNetwork; + source.network_source = blink::ServiceWorkerRouterNetworkSource{}; + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(1U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(1U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/test/page.html"); + const auto sources = evaluator.Evaluate(request); + EXPECT_EQ(0U, sources.size()); +} + +TEST(ServiceWorkerRouterEvaluator, AllConditionMatch) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "/test/*", + [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "*.html", [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::SourceType::kNetwork; + source.network_source = blink::ServiceWorkerRouterNetworkSource{}; + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(1U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(1U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/test/page.html"); + const auto sources = evaluator.Evaluate(request); + EXPECT_EQ(1U, sources.size()); +} + +TEST(ServiceWorkerRouterEvaluator, ChooseMatchedRoute) { + blink::ServiceWorkerRouterRules rules; + { + blink::ServiceWorkerRouterRule rule; + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "*.html", [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::SourceType::kNetwork; + source.network_source = blink::ServiceWorkerRouterNetworkSource{}; + rule.sources.push_back(source); + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + { + blink::ServiceWorkerRouterRule rule; + { + blink::ServiceWorkerRouterCondition condition; + condition.type = + blink::ServiceWorkerRouterCondition::ConditionType::kUrlPattern; + blink::UrlPattern url_pattern; + auto parse_result = liburlpattern::Parse( + "*.css", [](base::StringPiece input) { return std::string(input); }); + ASSERT_TRUE(parse_result.ok()); + url_pattern.pathname = parse_result.value().PartList(); + condition.url_pattern = url_pattern; + rule.conditions.push_back(condition); + } + { + blink::ServiceWorkerRouterSource source; + source.type = blink::ServiceWorkerRouterSource::SourceType::kNetwork; + source.network_source = blink::ServiceWorkerRouterNetworkSource{}; + rule.sources.push_back(source); + rule.sources.push_back(source); + rule.sources.push_back(source); + rule.sources.push_back(source); + } + rules.rules.push_back(rule); + } + ASSERT_EQ(2U, rules.rules.size()); + + ServiceWorkerRouterEvaluator evaluator(rules); + ASSERT_EQ(2U, evaluator.rules().rules.size()); + EXPECT_TRUE(evaluator.IsValid()); + + network::ResourceRequest request; + request.method = "GET"; + request.url = GURL("https://example.com/top/test.css"); + const auto sources = evaluator.Evaluate(request); + EXPECT_EQ(4U, sources.size()); +} + +} // namespace + +} // namespace content
diff --git a/content/public/android/BUILD.gn b/content/public/android/BUILD.gn index f13666c9..e2c0d91f 100644 --- a/content/public/android/BUILD.gn +++ b/content/public/android/BUILD.gn
@@ -42,9 +42,9 @@ "java/res/layout/text_edit_suggestion_item.xml", "java/res/layout/text_edit_suggestion_list_footer.xml", "java/res/layout/two_field_date_picker.xml", - "java/res/menu/select_action_menu.xml", "java/res/values/attrs.xml", "java/res/values/dimens.xml", + "java/res/values/ids.xml", "java/res/values/strings.xml", "java/res/values/styles.xml", ] @@ -170,6 +170,7 @@ "//third_party/android_deps:guava_android_java", "//third_party/androidx:androidx_annotation_annotation_experimental_java", "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_appcompat_appcompat_resources_java", "//third_party/androidx:androidx_collection_collection_java", "//third_party/androidx:androidx_core_core_java", "//third_party/androidx:androidx_privacysandbox_ads_ads_adservices_java", @@ -307,8 +308,6 @@ "java/src/org/chromium/content/browser/remoteobjects/RemoteObjectImpl.java", "java/src/org/chromium/content/browser/remoteobjects/RemoteObjectInjector.java", "java/src/org/chromium/content/browser/remoteobjects/RemoteObjectRegistry.java", - "java/src/org/chromium/content/browser/selection/AdditionalMenuItemProvider.java", - "java/src/org/chromium/content/browser/selection/AdditionalMenuItemProviderImpl.java", "java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java", "java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java", "java/src/org/chromium/content/browser/selection/MagnifierAnimator.java", @@ -316,6 +315,7 @@ "java/src/org/chromium/content/browser/selection/MagnifierWrapper.java", "java/src/org/chromium/content/browser/selection/MagnifierWrapperImpl.java", "java/src/org/chromium/content/browser/selection/PastePopupMenu.java", + "java/src/org/chromium/content/browser/selection/SelectActionMenuHelper.java", "java/src/org/chromium/content/browser/selection/SelectionIndicesConverter.java", "java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java", "java/src/org/chromium/content/browser/selection/SmartSelectionClient.java", @@ -330,6 +330,7 @@ "java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java", "java/src/org/chromium/content/browser/webid/MDocProviderAndroid.java", "java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java", + "java/src/org/chromium/content_public/browser/AdditionalSelectionMenuItemProvider.java", "java/src/org/chromium/content_public/browser/BrowserContextHandle.java", "java/src/org/chromium/content_public/browser/ChildProcessLauncherHelper.java", "java/src/org/chromium/content_public/browser/ClientDataJson.java", @@ -372,6 +373,8 @@ "java/src/org/chromium/content_public/browser/SelectAroundCaretResult.java", "java/src/org/chromium/content_public/browser/SelectionClient.java", "java/src/org/chromium/content_public/browser/SelectionEventProcessor.java", + "java/src/org/chromium/content_public/browser/SelectionMenuGroup.java", + "java/src/org/chromium/content_public/browser/SelectionMenuItem.java", "java/src/org/chromium/content_public/browser/SelectionPopupController.java", "java/src/org/chromium/content_public/browser/SmartClipProvider.java", "java/src/org/chromium/content_public/browser/SpeechRecognition.java",
diff --git a/content/public/android/java/res/menu/select_action_menu.xml b/content/public/android/java/res/menu/select_action_menu.xml deleted file mode 100644 index 65b6351..0000000 --- a/content/public/android/java/res/menu/select_action_menu.xml +++ /dev/null
@@ -1,79 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> - -<!-- -Copyright 2013 The Chromium Authors -Use of this source code is governed by a BSD-style license that can be -found in the LICENSE file. ---> - -<!--suppress AlwaysShowAction --> -<menu xmlns:tools="http://schemas.android.com/tools" - xmlns:android="http://schemas.android.com/apk/res/android"> - <!-- Remove the ordering when Android can reorder the assist menu item - itself. --> - <group - android:id="@+id/select_action_menu_assist_items" - android:orderInCategory="1"> - </group> - <group - android:id="@+id/select_action_menu_default_items"> - <item - android:id="@+id/select_action_menu_cut" - android:icon="?android:attr/actionModeCutDrawable" - android:title="@android:string/cut" - android:showAsAction="always|withText" - android:alphabeticShortcut="x" - android:orderInCategory="2" - /> - <item - android:id="@+id/select_action_menu_copy" - android:icon="?android:attr/actionModeCopyDrawable" - android:title="@android:string/copy" - android:showAsAction="always|withText" - android:alphabeticShortcut="c" - android:orderInCategory="3" - /> - <item - android:id="@+id/select_action_menu_paste" - android:icon="?android:attr/actionModePasteDrawable" - android:title="@android:string/paste" - android:showAsAction="always|withText" - android:alphabeticShortcut="v" - android:orderInCategory="4" - /> - <item - android:id="@+id/select_action_menu_share" - android:title="@string/actionbar_share" - android:showAsAction="always|withText" - style="@style/SelectActionMenuShare" - android:orderInCategory="5" - /> - <item - android:id="@+id/select_action_menu_select_all" - android:icon="?android:attr/actionModeSelectAllDrawable" - android:title="@android:string/selectAll" - android:showAsAction="always|withText" - android:alphabeticShortcut="a" - android:orderInCategory="6" - /> - <!-- android:string/paste_as_plain_text is available since O, - we set title string after inflation if running on O+ devices. --> - <item - android:id="@+id/select_action_menu_paste_as_plain_text" - android:title="" - android:showAsAction="always|withText" - android:orderInCategory="7" - /> - <item - android:id="@+id/select_action_menu_web_search" - android:title="@string/actionbar_web_search" - android:showAsAction="always|withText" - style="@style/SelectActionMenuWebSearch" - android:orderInCategory="8" - /> - </group> - <group - android:id="@+id/select_action_menu_text_processing_menus" - android:orderInCategory="9"> - </group> -</menu>
diff --git a/content/public/android/java/res/values/ids.xml b/content/public/android/java/res/values/ids.xml new file mode 100644 index 0000000..e60f009 --- /dev/null +++ b/content/public/android/java/res/values/ids.xml
@@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <!-- Selection Menu Group IDs --> + <item type="id" name="select_action_menu_assist_items" /> + <item type="id" name="select_action_menu_default_items" /> + <item type="id" name="select_action_menu_text_processing_items" /> + + <!-- Selection Menu Items --> + <item type="id" name="select_action_menu_cut" /> + <item type="id" name="select_action_menu_copy" /> + <item type="id" name="select_action_menu_paste" /> + <item type="id" name="select_action_menu_share" /> + <item type="id" name="select_action_menu_select_all" /> + <item type="id" name="select_action_menu_paste_as_plain_text" /> + <item type="id" name="select_action_menu_web_search" /> +</resources> \ No newline at end of file
diff --git a/content/public/android/java/res/values/styles.xml b/content/public/android/java/res/values/styles.xml index 800d8857..a7bc138 100644 --- a/content/public/android/java/res/values/styles.xml +++ b/content/public/android/java/res/values/styles.xml
@@ -10,12 +10,6 @@ <item name="select_dialog_singlechoice">@android:layout/select_dialog_singlechoice</item> <item name="select_dialog_multichoice">@android:layout/select_dialog_multichoice</item> </style> - <style name="SelectActionMenuShare"> - <item name="android:icon">?android:attr/actionModeShareDrawable</item> - </style> - <style name="SelectActionMenuWebSearch"> - <item name="android:icon">?android:attr/actionModeWebSearchDrawable</item> - </style> <style name="TextAppearance.SuggestionPrefixOrSuffix"> <item name="android:textColor">?android:attr/textColorSecondary</item> </style>
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentClassFactory.java b/content/public/android/java/src/org/chromium/content/browser/ContentClassFactory.java index 5804aaf5..281bb80f 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentClassFactory.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentClassFactory.java
@@ -4,11 +4,7 @@ package org.chromium.content.browser; -import android.os.Build; - import org.chromium.base.ThreadUtils; -import org.chromium.content.browser.selection.AdditionalMenuItemProvider; -import org.chromium.content.browser.selection.AdditionalMenuItemProviderImpl; /** * A class factory for downstream injecting code to content layer. @@ -39,12 +35,4 @@ * Constructor. */ protected ContentClassFactory() {} - - /** - * Creates AddtionalMenuItems object. - */ - public AdditionalMenuItemProvider createAddtionalMenuItemProvider() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return null; - return new AdditionalMenuItemProviderImpl(); - } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java index 6f845f8..efb50a2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityImpl.java
@@ -70,7 +70,6 @@ import android.view.ViewParent; import android.view.ViewStructure; import android.view.accessibility.AccessibilityEvent; -import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityNodeProvider; import android.view.autofill.AutofillManager; @@ -145,7 +144,6 @@ private static final int AUTO_DISABLE_SINGLE_INSTANCE_TOGGLE_LIMIT = 3; private final AccessibilityDelegate mDelegate; - protected AccessibilityManager mAccessibilityManager; protected Context mContext; private final String mProductVersion; protected long mNativeObj; @@ -253,8 +251,6 @@ mView = mDelegate.getContainerView(); mContext = mView.getContext(); mProductVersion = mDelegate.getProductVersion(); - mAccessibilityManager = - (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); WebContents webContents = mDelegate.getWebContents(); if (webContents != null) { @@ -476,14 +472,8 @@ public boolean isAccessibilityEnabled() { return isNativeInitialized() - && (mAccessibilityEnabledOverride || mAccessibilityManager.isEnabled()); - } - - @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) - @Override - public void setAccessibilityEnabledForTesting() { - mAccessibilityEnabledOverride = true; - mIsObscuredByAnotherView = false; + && (mAccessibilityEnabledOverride + || AccessibilityState.isAnyAccessibilityServiceEnabled()); } @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/AdditionalMenuItemProvider.java b/content/public/android/java/src/org/chromium/content/browser/selection/AdditionalMenuItemProvider.java deleted file mode 100644 index f6dab1d..0000000 --- a/content/public/android/java/src/org/chromium/content/browser/selection/AdditionalMenuItemProvider.java +++ /dev/null
@@ -1,40 +0,0 @@ -// 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. - -package org.chromium.content.browser.selection; - -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.textclassifier.TextClassification; - -import java.util.List; - -/** - * An interface for adding more menu items. - */ -public interface AdditionalMenuItemProvider { - /** - * Add menu items to the menu passed in. - * @param context The context from app. - * @param menu Add menu items to this menu. - * @param classification Providing info to generate menu items. - */ - void addMenuItems( - Context context, Menu menu, TextClassification classification, List<Drawable> icons); - - /** - * Call this to trigger internal cleanup. - */ - void clearMenuItemListeners(); - - /** - * Perform action for menu item. - * @param item The clicked menu item. - * @param view Perform action on this view. - */ - void performAction(MenuItem item, View view); -}
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/AdditionalMenuItemProviderImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/AdditionalMenuItemProviderImpl.java deleted file mode 100644 index d586870..0000000 --- a/content/public/android/java/src/org/chromium/content/browser/selection/AdditionalMenuItemProviderImpl.java +++ /dev/null
@@ -1,129 +0,0 @@ -// 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. - -package org.chromium.content.browser.selection; - -import android.app.PendingIntent; -import android.app.RemoteAction; -import android.content.Context; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.text.TextUtils; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.textclassifier.TextClassification; - -import androidx.annotation.RequiresApi; - -import org.chromium.base.Log; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -// TODO(ctzsm): Add unit tests for this class once this is upstreamed. -/** - * Implements AdditionalMenuItemProvider interface. - * We prevent inlinings since this uses a number of new Android APIs which would create verification - * errors (on older Android versions) which would require a slow re-verification at runtime. - */ -@RequiresApi(Build.VERSION_CODES.P) -public class AdditionalMenuItemProviderImpl implements AdditionalMenuItemProvider { - private static final String TAG = "MenuItemProvider"; - // We want the secondary assist actions to come after the default actions but before the text - // processing actions. This constant needs to be greater than all of the default action orders - // but small enough so that all of the secondary items have order less than - // MENU_ITEM_ORDER_TEXT_PROCESS_START in SelectionPopupControllerImpl. - private static final int MENU_ITEM_ORDER_SECONDARY_ASSIST_ACTIONS_START = 50; - - // Record MenuItem OnClickListener pair we added to menu. - private final Map<MenuItem, OnClickListener> mAssistClickHandlers = new HashMap<>(); - - @Override - public void addMenuItems( - Context context, Menu menu, TextClassification classification, List<Drawable> icons) { - if (menu == null || classification == null) return; - - final int count = classification.getActions().size(); - - assert icons == null - || icons.size() - == count - : "icons list should be either null or have the same length with actions."; - - // Fallback to new API to set icon on P. - if (count > 0) { - RemoteAction primaryAction = classification.getActions().get(0); - - MenuItem item = menu.findItem(android.R.id.textAssist); - if (primaryAction.shouldShowIcon()) { - item.setIcon(icons == null ? null : icons.get(0)); - } else { - item.setIcon(null); - } - } - - // First action is reserved for primary action. - for (int i = 1; i < count; ++i) { - RemoteAction action = classification.getActions().get(i); - final OnClickListener listener = - getSupportedOnClickListener(action.getTitle(), action.getActionIntent()); - if (listener == null) continue; - - // We have to use android.R.id.textAssist as group id to make framework show icons for - // these menu items. - MenuItem item = menu.add(android.R.id.textAssist, Menu.NONE, - MENU_ITEM_ORDER_SECONDARY_ASSIST_ACTIONS_START + i, action.getTitle()); - item.setContentDescription(action.getContentDescription()); - if (action.shouldShowIcon()) { - item.setIcon(icons == null ? null : icons.get(i)); - } - // Set this flag to SHOW_AS_ACTION_IF_ROOM to match text processing menu items. So - // Android could put them to the same level and then consider their actual order. - item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); - mAssistClickHandlers.put(item, listener); - } - } - - @Override - public void clearMenuItemListeners() { - mAssistClickHandlers.clear(); - } - - @Override - public void performAction(MenuItem item, View view) { - OnClickListener listener = mAssistClickHandlers.get(item); - if (listener == null) return; - listener.onClick(view); - } - - // Because Icon#loadDrawable() should not be called on UI thread, we pre-load the icons on - // background thread right after we get the text classification result in - // SmartSelectionProvider. TextClassification#getActions() is only available on P and above, so - public static List<Drawable> loadIconDrawables(Context context, TextClassification tc) { - if (context == null || tc == null) return null; - - ArrayList<Drawable> res = new ArrayList<>(); - for (RemoteAction action : tc.getActions()) { - res.add(action.getIcon().loadDrawable(context)); - } - return res; - } - - private static OnClickListener getSupportedOnClickListener( - CharSequence title, PendingIntent pendingIntent) { - if (TextUtils.isEmpty(title) || pendingIntent == null) return null; - - return v -> { - try { - pendingIntent.send(); - } catch (PendingIntent.CanceledException e) { - Log.e(TAG, "Error creating OnClickListener from PendingIntent", e); - } - }; - } -}
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java b/content/public/android/java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java index 651be9f..d7c7e8ce 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/FloatingPastePopupMenu.java
@@ -11,7 +11,11 @@ import android.view.MenuItem; import android.view.View; +import androidx.annotation.Nullable; + import org.chromium.content.R; +import org.chromium.content.browser.selection.SelectActionMenuHelper.SelectActionMenuDelegate; +import org.chromium.content_public.browser.AdditionalSelectionMenuItemProvider; import org.chromium.ui.base.DeviceFormFactor; /** @@ -24,14 +28,14 @@ private ActionMode mActionMode; private Rect mSelectionRect; - private ActionMode.Callback mExternalCallback; + private final @Nullable AdditionalSelectionMenuItemProvider mAdditionalItemProvider; public FloatingPastePopupMenu(Context context, View parent, PastePopupMenuDelegate delegate, - ActionMode.Callback externalCallback) { + @Nullable AdditionalSelectionMenuItemProvider additionalItemProvider) { mParent = parent; mDelegate = delegate; mContext = context; - mExternalCallback = externalCallback; + mAdditionalItemProvider = additionalItemProvider; } @Override @@ -71,7 +75,6 @@ @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { createPasteMenu(mode, menu); - if (mExternalCallback != null) mExternalCallback.onCreateActionMode(mode, menu); return true; } @@ -80,28 +83,49 @@ ? mContext.getString(R.string.actionbar_textselection_title) : null); mode.setSubtitle(null); - SelectionPopupControllerImpl.initializeMenu(mContext, mode, menu); - if (!mDelegate.canPaste()) menu.removeItem(R.id.select_action_menu_paste); - if (!mDelegate.canSelectAll()) menu.removeItem(R.id.select_action_menu_select_all); - if (!mDelegate.canPasteAsPlainText()) { - menu.removeItem(R.id.select_action_menu_paste_as_plain_text); - } + SelectActionMenuDelegate actionMenuDelegate = new SelectActionMenuDelegate() { + @Override + public boolean canCut() { + return false; + } - SelectionPopupControllerImpl.setPasteAsPlainTextMenuItemTitle(menu); + @Override + public boolean canCopy() { + return false; + } - menu.removeItem(R.id.select_action_menu_cut); - menu.removeItem(R.id.select_action_menu_copy); - menu.removeItem(R.id.select_action_menu_share); - menu.removeItem(R.id.select_action_menu_web_search); + @Override + public boolean canPaste() { + return mDelegate.canPaste(); + } + + @Override + public boolean canShare() { + return false; + } + + @Override + public boolean canSelectAll() { + return mDelegate.canSelectAll(); + } + + @Override + public boolean canWebSearch() { + return false; + } + + @Override + public boolean canPasteAsPlainText() { + return mDelegate.canPasteAsPlainText(); + } + }; + SelectionPopupControllerImpl.initializeNonSelectionMenu( + actionMenuDelegate, mContext, mAdditionalItemProvider, mode, menu); } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - boolean ret = false; - if (mExternalCallback != null) { - ret = mExternalCallback.onPrepareActionMode(mode, menu); - } - return ret; + return false; } @Override @@ -117,15 +141,15 @@ } else if (id == R.id.select_action_menu_select_all) { mDelegate.selectAll(); mode.finish(); - } else if (mExternalCallback != null) { - ret = mExternalCallback.onActionItemClicked(mode, item); } return ret; } @Override public void onDestroyActionMode(ActionMode mode) { - if (mExternalCallback != null) mExternalCallback.onDestroyActionMode(mode); + if (mAdditionalItemProvider != null) { + mAdditionalItemProvider.onMenuDestroyed(); + } mActionMode = null; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectActionMenuHelper.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectActionMenuHelper.java new file mode 100644 index 0000000..fa4465a3 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectActionMenuHelper.java
@@ -0,0 +1,415 @@ +// 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. + +package org.chromium.content.browser.selection; + +import android.app.PendingIntent; +import android.app.RemoteAction; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.textclassifier.TextClassification; + +import androidx.annotation.IntDef; +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.annotation.VisibleForTesting; + +import org.chromium.base.Log; +import org.chromium.base.PackageManagerUtils; +import org.chromium.content.R; +import org.chromium.content_public.browser.AdditionalSelectionMenuItemProvider; +import org.chromium.content_public.browser.SelectionClient; +import org.chromium.content_public.browser.SelectionMenuGroup; +import org.chromium.content_public.browser.SelectionMenuItem; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.List; +import java.util.PriorityQueue; + +/** + * Utility class around menu items for the text selection action menu. + * This was created (as opposed to using a menu.xml) because we have multiple ways of rendering the + * menu that cannot necessarily leverage the {@link android.view.Menu} & {@link MenuItem} APIs. + */ +public class SelectActionMenuHelper { + private static final String TAG = "SelectActionMenu"; // 20 char limit. + + @Retention(RetentionPolicy.SOURCE) + @IntDef({GroupItemOrder.ASSIST_ITEMS, GroupItemOrder.DEFAULT_ITEMS, + GroupItemOrder.SECONDARY_ASSIST_ITEMS, GroupItemOrder.TEXT_PROCESSING_ITEMS}) + public @interface GroupItemOrder { + int ASSIST_ITEMS = 1; + int DEFAULT_ITEMS = 2; + int SECONDARY_ASSIST_ITEMS = 3; + int TEXT_PROCESSING_ITEMS = 4; + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef({DefaultItemOrder.CUT, DefaultItemOrder.COPY, DefaultItemOrder.PASTE, + DefaultItemOrder.SHARE, DefaultItemOrder.SELECT_ALL, + DefaultItemOrder.PASTE_AS_PLAIN_TEXT, DefaultItemOrder.WEB_SEARCH}) + public @interface DefaultItemOrder { + int CUT = 1; + int COPY = 2; + int PASTE = 3; + int SHARE = 4; + int SELECT_ALL = 5; + int PASTE_AS_PLAIN_TEXT = 6; + int WEB_SEARCH = 7; + } + + @Retention(RetentionPolicy.SOURCE) + @IntDef({ItemKeyShortcuts.CUT, ItemKeyShortcuts.COPY, ItemKeyShortcuts.PASTE, + ItemKeyShortcuts.SELECT_ALL}) + public @interface ItemKeyShortcuts { + char CUT = 'x'; + char COPY = 'c'; + char PASTE = 'v'; + char SELECT_ALL = 'a'; + } + + /** + * Delegate for the select action menu. + */ + public interface SelectActionMenuDelegate { + boolean canCut(); + boolean canCopy(); + boolean canPaste(); + boolean canShare(); + boolean canSelectAll(); + boolean canWebSearch(); + boolean canPasteAsPlainText(); + } + + /** + * For the text processing menu items. + */ + public interface TextProcessingIntentHandler { + void handleIntent(Intent textProcessingIntent); + } + + // Do not instantiate. + private SelectActionMenuHelper() {} + + /** + * Removes all the menu item groups potentially added using + * {@link #getSelectionMenuItems}. + */ + public static void removeAllAddedGroupsFromMenu(Menu menu) { + // Only remove action mode items we added. See more http://crbug.com/709878. + menu.removeGroup(R.id.select_action_menu_default_items); + menu.removeGroup(R.id.select_action_menu_assist_items); + menu.removeGroup(R.id.select_action_menu_text_processing_items); + menu.removeGroup(android.R.id.textAssist); + } + + /** + * Returns all items for the text selection menu when there is no text selected + * (i.e. an editable input field). + */ + public static PriorityQueue<SelectionMenuGroup> getNonSelectionMenuItems( + SelectActionMenuDelegate delegate, + @Nullable AdditionalSelectionMenuItemProvider nonSelectionAdditionalItemProvider) { + PriorityQueue<SelectionMenuGroup> pasteMenuItems = new PriorityQueue<>(); + pasteMenuItems.add(getDefaultItems(delegate)); + + if (nonSelectionAdditionalItemProvider != null + && !nonSelectionAdditionalItemProvider.getItems().isEmpty()) { + SelectionMenuGroup additionalItemGroup = + new SelectionMenuGroup(Menu.NONE, GroupItemOrder.DEFAULT_ITEMS + 1); + additionalItemGroup.addItems(nonSelectionAdditionalItemProvider.getItems()); + pasteMenuItems.add(additionalItemGroup); + } + return pasteMenuItems; + } + + /** + * Returns all items for the text selection menu when there is text selected. + * @param context the context used by the menu. + * @param classificationResult the text classification result. + * @param isSelectionReadOnly true if the selection is non-editable. + * @param textProcessingIntentHandler the intent handler for text processing actions. + */ + public static PriorityQueue<SelectionMenuGroup> getSelectionMenuItems( + SelectActionMenuDelegate delegate, Context context, + @Nullable SelectionClient.Result classificationResult, boolean isSelectionPassword, + boolean isSelectionReadOnly, + @Nullable TextProcessingIntentHandler textProcessingIntentHandler) { + PriorityQueue<SelectionMenuGroup> itemGroups = new PriorityQueue<>(); + itemGroups.add(getDefaultItems(delegate)); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + SelectionMenuGroup primaryAssistItem = + getPrimaryAssistItems(context, classificationResult); + if (primaryAssistItem != null) { + itemGroups.add(primaryAssistItem); + } + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + SelectionMenuGroup secondaryAssistItems = getSecondaryAssistItems(classificationResult); + if (secondaryAssistItems != null) { + itemGroups.add(secondaryAssistItems); + } + } + SelectionMenuGroup textProcessingItems = getTextProcessingItems( + context, isSelectionPassword, isSelectionReadOnly, textProcessingIntentHandler); + if (textProcessingItems != null) { + itemGroups.add(textProcessingItems); + } + return itemGroups; + } + + @Nullable + @RequiresApi(Build.VERSION_CODES.O) + private static SelectionMenuGroup getPrimaryAssistItems( + Context context, @Nullable SelectionClient.Result classificationResult) { + if (classificationResult == null || !classificationResult.hasNamedAction()) { + return null; + } + SelectionMenuGroup primaryAssistGroup = new SelectionMenuGroup( + R.id.select_action_menu_assist_items, GroupItemOrder.ASSIST_ITEMS); + View.OnClickListener clickListener = null; + if (classificationResult.onClickListener != null) { + clickListener = classificationResult.onClickListener; + } else if (classificationResult.intent != null) { + clickListener = v -> context.startActivity(classificationResult.intent); + } + primaryAssistGroup.addItem( + new SelectionMenuItem.Builder(classificationResult.label) + .setId(android.R.id.textAssist) + .setIcon(getPrimaryActionIconForClassificationResult(classificationResult)) + .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM) + .setClickListener(clickListener) + .build()); + return primaryAssistGroup; + } + + private static SelectionMenuGroup getDefaultItems(SelectActionMenuDelegate delegate) { + SelectionMenuGroup defaultGroup = new SelectionMenuGroup( + R.id.select_action_menu_default_items, GroupItemOrder.DEFAULT_ITEMS); + defaultGroup.addItem(cut(delegate.canCut())); + defaultGroup.addItem(copy(delegate.canCopy())); + defaultGroup.addItem(paste(delegate.canPaste())); + defaultGroup.addItem(share(delegate.canShare())); + defaultGroup.addItem(selectAll(delegate.canSelectAll())); + defaultGroup.addItem(webSearch(delegate.canWebSearch())); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + defaultGroup.addItem(pasteAsPlainText(delegate.canPasteAsPlainText())); + } + return defaultGroup; + } + + @Nullable + @RequiresApi(Build.VERSION_CODES.P) + private static SelectionMenuGroup getSecondaryAssistItems( + @Nullable SelectionClient.Result classificationResult) { + if (classificationResult == null) { + return null; + } + TextClassification classification = classificationResult.textClassification; + if (classification == null) { + return null; + } + List<RemoteAction> actions = classification.getActions(); + if (actions == null) { + return null; + } + final int count = actions.size(); + if (count < 2) { + // More than one item is needed as the first item is reserved for the + // primary assist item. + return null; + } + List<Drawable> icons = classificationResult.additionalIcons; + assert icons == null + || icons.size() + == count + : "icons list should be either null or have the same length with actions."; + + // We have to use android.R.id.textAssist as group id to make framework show icons for + // these menu items. + SelectionMenuGroup secondaryAssistItems = new SelectionMenuGroup( + android.R.id.textAssist, GroupItemOrder.SECONDARY_ASSIST_ITEMS); + + // First action is reserved for primary action so start at index 1. + final int startIndex = 1; + for (int i = startIndex; i < count; i++) { + RemoteAction action = actions.get(i); + final View.OnClickListener listener = getActionClickListener(action); + if (listener == null) continue; + + SelectionMenuItem item = new SelectionMenuItem.Builder(action.getTitle()) + .setId(Menu.NONE) + .setIcon(icons == null ? null : icons.get(i)) + .setOrderInCategory(i - startIndex) + .setContentDescription(action.getContentDescription()) + .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM) + .setClickListener(listener) + .build(); + secondaryAssistItems.addItem(item); + } + return secondaryAssistItems; + } + + @Nullable + @VisibleForTesting + /* package */ static SelectionMenuGroup getTextProcessingItems(Context context, + boolean isSelectionPassword, boolean isSelectionReadOnly, + @Nullable TextProcessingIntentHandler intentHandler) { + if (isSelectionPassword || intentHandler == null) { + return null; + } + List<ResolveInfo> supportedActivities = + PackageManagerUtils.queryIntentActivities(createProcessTextIntent(), 0); + if (supportedActivities.isEmpty()) { + return null; + } + SelectionMenuGroup textProcessingItems = + new SelectionMenuGroup(R.id.select_action_menu_text_processing_items, + GroupItemOrder.TEXT_PROCESSING_ITEMS); + for (int i = 0; i < supportedActivities.size(); i++) { + ResolveInfo resolveInfo = supportedActivities.get(i); + if (resolveInfo.activityInfo == null || !resolveInfo.activityInfo.exported) continue; + CharSequence title = resolveInfo.loadLabel(context.getPackageManager()); + Intent intent = createProcessTextIntentForResolveInfo(resolveInfo, isSelectionReadOnly); + View.OnClickListener listener = v -> intentHandler.handleIntent(intent); + textProcessingItems.addItem( + new SelectionMenuItem.Builder(title) + .setId(Menu.NONE) + .setOrderInCategory(i) + .setShowAsActionFlags(MenuItem.SHOW_AS_ACTION_IF_ROOM) + .setClickListener(listener) + .build()); + } + return textProcessingItems; + } + + private static Intent createProcessTextIntentForResolveInfo( + ResolveInfo info, boolean isSelectionReadOnly) { + return createProcessTextIntent() + .putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, isSelectionReadOnly) + .setClassName(info.activityInfo.packageName, info.activityInfo.name); + } + + private static Intent createProcessTextIntent() { + return new Intent().setAction(Intent.ACTION_PROCESS_TEXT).setType("text/plain"); + } + + @Nullable + private static Drawable getPrimaryActionIconForClassificationResult( + SelectionClient.Result classificationResult) { + final List<Drawable> additionalIcons = classificationResult.additionalIcons; + Drawable icon; + if (additionalIcons != null && !additionalIcons.isEmpty()) { + // The primary action is always first so check index 0. + icon = additionalIcons.get(0); + } else { + icon = classificationResult.icon; + } + return icon; + } + + @Nullable + @RequiresApi(Build.VERSION_CODES.O) + private static View.OnClickListener getActionClickListener(RemoteAction action) { + if (TextUtils.isEmpty(action.getTitle()) || action.getActionIntent() == null) { + return null; + } + return v -> { + try { + action.getActionIntent().send(); + } catch (PendingIntent.CanceledException e) { + Log.e(TAG, "Error creating OnClickListener from PendingIntent", e); + } + }; + } + + private static SelectionMenuItem cut(boolean isEnabled) { + return new SelectionMenuItem.Builder(android.R.string.cut) + .setId(R.id.select_action_menu_cut) + .setIconAttr(android.R.attr.actionModeCutDrawable) + .setAlphabeticShortcut(ItemKeyShortcuts.CUT) + .setOrderInCategory(DefaultItemOrder.CUT) + .setShowAsActionFlags( + MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setIsEnabled(isEnabled) + .build(); + } + + private static SelectionMenuItem copy(boolean isEnabled) { + return new SelectionMenuItem.Builder(android.R.string.copy) + .setId(R.id.select_action_menu_copy) + .setIconAttr(android.R.attr.actionModeCopyDrawable) + .setAlphabeticShortcut(ItemKeyShortcuts.COPY) + .setOrderInCategory(DefaultItemOrder.COPY) + .setShowAsActionFlags( + MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setIsEnabled(isEnabled) + .build(); + } + + private static SelectionMenuItem paste(boolean isEnabled) { + return new SelectionMenuItem.Builder(android.R.string.paste) + .setId(R.id.select_action_menu_paste) + .setIconAttr(android.R.attr.actionModePasteDrawable) + .setAlphabeticShortcut(ItemKeyShortcuts.PASTE) + .setOrderInCategory(DefaultItemOrder.PASTE) + .setShowAsActionFlags( + MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setIsEnabled(isEnabled) + .build(); + } + + private static SelectionMenuItem share(boolean isEnabled) { + return new SelectionMenuItem.Builder(R.string.actionbar_share) + .setId(R.id.select_action_menu_share) + .setIconAttr(android.R.attr.actionModeShareDrawable) + .setOrderInCategory(DefaultItemOrder.SHARE) + .setShowAsActionFlags( + MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setIsEnabled(isEnabled) + .build(); + } + + private static SelectionMenuItem selectAll(boolean isEnabled) { + return new SelectionMenuItem.Builder(android.R.string.selectAll) + .setId(R.id.select_action_menu_select_all) + .setIconAttr(android.R.attr.actionModeSelectAllDrawable) + .setAlphabeticShortcut(ItemKeyShortcuts.SELECT_ALL) + .setOrderInCategory(DefaultItemOrder.SELECT_ALL) + .setShowAsActionFlags( + MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setIsEnabled(isEnabled) + .build(); + } + + @RequiresApi(Build.VERSION_CODES.O) + private static SelectionMenuItem pasteAsPlainText(boolean isEnabled) { + return new SelectionMenuItem.Builder(android.R.string.paste_as_plain_text) + .setId(R.id.select_action_menu_paste_as_plain_text) + .setOrderInCategory(DefaultItemOrder.PASTE_AS_PLAIN_TEXT) + .setShowAsActionFlags( + MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setIsEnabled(isEnabled) + .build(); + } + + private static SelectionMenuItem webSearch(boolean isEnabled) { + return new SelectionMenuItem.Builder(R.string.actionbar_web_search) + .setId(R.id.select_action_menu_web_search) + .setIconAttr(android.R.attr.actionModeWebSearchDrawable) + .setOrderInCategory(DefaultItemOrder.WEB_SEARCH) + .setShowAsActionFlags( + MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT) + .setIsEnabled(isEnabled) + .build(); + } +}
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java index 4d83a07..f7ffcd94 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionPopupControllerImpl.java
@@ -9,9 +9,8 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; -import android.content.res.Resources; import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; import android.provider.Browser; @@ -19,7 +18,6 @@ import android.view.ActionMode; import android.view.HapticFeedbackConstants; import android.view.Menu; -import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; @@ -27,8 +25,8 @@ import android.view.textclassifier.SelectionEvent; import android.view.textclassifier.TextClassifier; +import androidx.annotation.IdRes; import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; import org.chromium.base.Log; @@ -43,20 +41,23 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.content.R; -import org.chromium.content.browser.ContentClassFactory; import org.chromium.content.browser.GestureListenerManagerImpl; import org.chromium.content.browser.PopupController; import org.chromium.content.browser.PopupController.HideablePopup; import org.chromium.content.browser.WindowEventObserver; import org.chromium.content.browser.WindowEventObserverManager; import org.chromium.content.browser.input.ImeAdapterImpl; +import org.chromium.content.browser.selection.SelectActionMenuHelper.SelectActionMenuDelegate; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; import org.chromium.content_public.browser.ActionModeCallbackHelper; +import org.chromium.content_public.browser.AdditionalSelectionMenuItemProvider; import org.chromium.content_public.browser.ImeEventObserver; import org.chromium.content_public.browser.RenderFrameHost; import org.chromium.content_public.browser.SelectAroundCaretResult; import org.chromium.content_public.browser.SelectionClient; +import org.chromium.content_public.browser.SelectionMenuGroup; +import org.chromium.content_public.browser.SelectionMenuItem; import org.chromium.content_public.browser.SelectionPopupController; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.Clipboard; @@ -68,7 +69,7 @@ import org.chromium.ui.touch_selection.SelectionEventType; import org.chromium.ui.touch_selection.TouchSelectionDraggableType; -import java.util.List; +import java.util.PriorityQueue; /** * Implementation of the interface {@link SelectionPopupController}. @@ -76,7 +77,7 @@ @JNINamespace("content") public class SelectionPopupControllerImpl extends ActionModeCallbackHelper implements ImeEventObserver, SelectionPopupController, WindowEventObserver, HideablePopup, - ContainerViewObserver, UserData { + ContainerViewObserver, UserData, SelectActionMenuDelegate { private static final String TAG = "SelectionPopupCtlr"; // 20 char limit private static final boolean DEBUG = false; @@ -133,7 +134,7 @@ private SelectionClient.ResultCallback mResultCallback; // Used to customize PastePopupMenu - private ActionMode.Callback mNonSelectionCallback; + private AdditionalSelectionMenuItemProvider mNonSelectionAdditionalItemProvider; // Selection rectangle in DIP. private final Rect mSelectionRect = new Rect(); @@ -159,7 +160,7 @@ private boolean mEditable; private boolean mIsPasswordType; private boolean mIsInsertionForTesting; - private boolean mCanSelectAllForPastePopup; + private boolean mCanSelectAll; private boolean mCanEditRichly; private boolean mUnselectAllOnDismiss; @@ -198,8 +199,6 @@ private MagnifierAnimator mMagnifierAnimator; - private AdditionalMenuItemProvider mAdditionalMenuItemProvider; - /** * An interface for getting {@link View} for readback. */ @@ -323,7 +322,6 @@ mResultCallback = new SmartSelectionCallback(); mLastSelectedText = ""; - mAdditionalMenuItemProvider = ContentClassFactory.get().createAddtionalMenuItemProvider(); getPopupController().registerPopup(this); } @@ -382,8 +380,9 @@ } @Override - public void setNonSelectionActionModeCallback(ActionMode.Callback callback) { - mNonSelectionCallback = callback; + public void setNonSelectionAdditionalMenuItemProvider( + AdditionalSelectionMenuItemProvider provider) { + mNonSelectionAdditionalItemProvider = provider; } @Override @@ -428,7 +427,7 @@ return MENU_ITEM_SHARE; } else if (id == R.id.select_action_menu_web_search) { return MENU_ITEM_WEB_SEARCH; - } else if (groupId == R.id.select_action_menu_text_processing_menus) { + } else if (groupId == R.id.select_action_menu_text_processing_items) { return MENU_ITEM_PROCESS_TEXT; } return 0; @@ -452,7 +451,7 @@ mLastSelectionOffset = selectionStartOffset; mHasSelection = selectionText.length() != 0; mIsPasswordType = isPasswordType; - mCanSelectAllForPastePopup = canSelectAll; + mCanSelectAll = canSelectAll; mCanEditRichly = canRichlyEdit; mUnselectAllOnDismiss = true; @@ -566,7 +565,7 @@ @Override public boolean canPaste() { - return Clipboard.getInstance().canPaste(); + return SelectionPopupControllerImpl.this.canPaste(); } @Override @@ -586,8 +585,8 @@ }; Context windowContext = mWindowAndroid.getContext().get(); if (windowContext == null) return; - mPastePopupMenu = - new FloatingPastePopupMenu(windowContext, mView, delegate, mNonSelectionCallback); + mPastePopupMenu = new FloatingPastePopupMenu( + windowContext, mView, delegate, mNonSelectionAdditionalItemProvider); showPastePopup(); } @@ -760,115 +759,162 @@ @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { - if (mAdditionalMenuItemProvider != null) { - mAdditionalMenuItemProvider.clearMenuItemListeners(); - } - // Only remove action mode items we added. See more http://crbug.com/709878. - menu.removeGroup(R.id.select_action_menu_default_items); - menu.removeGroup(R.id.select_action_menu_assist_items); - menu.removeGroup(R.id.select_action_menu_text_processing_menus); - menu.removeGroup(android.R.id.textAssist); - createActionMenu(mode, menu); + SelectActionMenuHelper.removeAllAddedGroupsFromMenu(menu); + createSelectionActionMenu(mode, menu); return true; } + public static void initializeNonSelectionMenu(SelectActionMenuDelegate delegate, + Context context, + @Nullable AdditionalSelectionMenuItemProvider nonSelectionAdditionalItemProvider, + ActionMode mode, Menu menu) { + PriorityQueue<SelectionMenuGroup> nonSelectionMenuItems = + SelectActionMenuHelper.getNonSelectionMenuItems( + delegate, nonSelectionAdditionalItemProvider); + initializeActionMenu(context, nonSelectionMenuItems, mode, menu, null); + } + /** - * Initialize the menu by populating all the available items. Embedders should remove - * the items that are not relevant to the input text being edited. + * Initializes the selection menu. + * @param additionalMenuItemClickListener additional actions that need to be executed after a + * menu item is clicked. */ - public static void initializeMenu(Context context, ActionMode mode, Menu menu) { - if (!sMustUseWebContentsContext) { - // For WebView the correct choice is to use the actionMode context because webview - // assets have been added to its asset path. However we need to fall back to - // using the web contents context in the case where the AssetManager associated with - // the actionMode context does not contain our assets, because not doing so will cause a - // crash. - try { - mode.getMenuInflater().inflate(R.menu.select_action_menu, menu); - return; - } catch (Resources.NotFoundException e) { - // TODO(tobiasjs) by the time we get here we have already - // caused a resource loading failure to be logged. WebView - // resource access needs to be improved so that this - // logspam can be avoided. + private static void initializeSelectionMenu(SelectActionMenuDelegate delegate, Context context, + @Nullable SelectionClient.Result classificationResult, boolean isSelectionPassword, + boolean isSelectionReadOnly, + @Nullable SelectActionMenuHelper + .TextProcessingIntentHandler textProcessingIntentHandler, + ActionMode mode, Menu menu, + @Nullable MenuItem.OnMenuItemClickListener additionalMenuItemClickListener) { + PriorityQueue<SelectionMenuGroup> selectionMenuItems = + SelectActionMenuHelper.getSelectionMenuItems(delegate, context, + classificationResult, isSelectionPassword, isSelectionReadOnly, + textProcessingIntentHandler); + initializeActionMenu( + context, selectionMenuItems, mode, menu, additionalMenuItemClickListener); + } + + /** + * Initializes a {@link Menu} with items from the {@link SelectionMenuGroup}s. + * {@link SelectionMenuItem}s where {@link SelectionMenuItem#isEnabled} returns false + * are not added. + */ + private static void initializeActionMenu(Context context, + PriorityQueue<SelectionMenuGroup> menuGroups, ActionMode mode, Menu menu, + @Nullable MenuItem.OnMenuItemClickListener additionalMenuItemClickListener) { + for (SelectionMenuGroup group : menuGroups) { + addMenuGroupToMenu(context, group, mode, menu, additionalMenuItemClickListener); + } + } + + private static void addMenuGroupToMenu(Context context, SelectionMenuGroup group, + ActionMode mode, Menu menu, + @Nullable MenuItem.OnMenuItemClickListener additionalMenuItemClickListener) { + for (SelectionMenuItem item : group.items) { + if (!item.isEnabled) { + // We will only add items if they are enabled. This will prevent us from + // needing to remove them. + continue; } + MenuItem menuItem = + menu.add(group.id, item.id, item.orderInCategory, item.getTitle(context)) + .setShowAsActionFlags(item.showAsActionFlags); + @Nullable + Drawable icon = item.getIcon(context); + if (icon != null) { + menuItem.setIcon(icon); + } + @Nullable + Character alphabeticShortcut = item.alphabeticShortcut; + if (alphabeticShortcut != null) { + menuItem.setAlphabeticShortcut(alphabeticShortcut); + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + // Content descriptions supported on O+. + @Nullable + CharSequence contentDescription = item.contentDescription; + if (contentDescription != null) { + menuItem.setContentDescription(contentDescription); + } + } + menuItem.setOnMenuItemClickListener(clickedMenuItem -> { + if (additionalMenuItemClickListener != null) { + additionalMenuItemClickListener.onMenuItemClick(clickedMenuItem); + } + View.OnClickListener clickListener = item.clickListener; + if (clickListener != null) { + clickListener.onClick(null); + mode.finish(); + return true; + } + return false; + }); } - new MenuInflater(context).inflate(R.menu.select_action_menu, menu); } - @RequiresApi(Build.VERSION_CODES.O) - public static void setPasteAsPlainTextMenuItemTitle(Menu menu) { - MenuItem item = menu.findItem(R.id.select_action_menu_paste_as_plain_text); - if (item == null) return; - // android.R.string.paste_as_plain_text is available in SDK since O. - assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O; - item.setTitle(android.R.string.paste_as_plain_text); + private void createSelectionActionMenu(ActionMode mode, Menu menu) { + SelectActionMenuHelper.TextProcessingIntentHandler textProcessingIntentHandler = null; + if (isSelectActionModeAllowed(MENU_ITEM_PROCESS_TEXT)) { + textProcessingIntentHandler = this::processText; + } + initializeSelectionMenu(this, mContext, mClassificationResult, isSelectionPassword(), + !isFocusedNodeEditable(), textProcessingIntentHandler, mode, menu, item -> { + logSelectionAction(item.getGroupId(), item.getItemId()); + return false; + }); } - private void createActionMenu(ActionMode mode, Menu menu) { - initializeMenu(mContext, mode, menu); - updateAssistMenuItem(menu); - removeActionMenuItemsIfNecessary(menu); - setPasteAsPlainTextMenuItemTitle(menu); - - Context windowContext = mWindowAndroid.getContext().get(); - if (mClassificationResult != null && mAdditionalMenuItemProvider != null - && windowContext != null) { - mAdditionalMenuItemProvider.addMenuItems(windowContext, menu, - mClassificationResult.textClassification, - mClassificationResult.additionalIcons); - } - - if (!hasSelection() || isSelectionPassword()) return; - - initializeTextProcessingMenu(menu); + /** + * Checks if copy action is available. + */ + @Override + public boolean canCopy() { + return hasSelection() && !isSelectionPassword() && Clipboard.getInstance().canCopy(); } - private void removeActionMenuItemsIfNecessary(Menu menu) { - if (!isFocusedNodeEditable() || !Clipboard.getInstance().canPaste()) { - menu.removeItem(R.id.select_action_menu_paste); - menu.removeItem(R.id.select_action_menu_paste_as_plain_text); - } + /** + * Checks if cut action is available. + */ + @Override + public boolean canCut() { + return hasSelection() && !isSelectionPassword() && Clipboard.getInstance().canCopy() + && isFocusedNodeEditable(); + } - if (!canPasteAsPlainText()) { - menu.removeItem(R.id.select_action_menu_paste_as_plain_text); - } + /** + * Checks if paste action is available. + */ + @Override + public boolean canPaste() { + return isFocusedNodeEditable() && Clipboard.getInstance().canPaste(); + } - if (!hasSelection()) { - menu.removeItem(R.id.select_action_menu_select_all); - menu.removeItem(R.id.select_action_menu_cut); - menu.removeItem(R.id.select_action_menu_copy); - menu.removeItem(R.id.select_action_menu_share); - menu.removeItem(R.id.select_action_menu_web_search); - return; - } + /** + * Checks if share action is available. + */ + @Override + public boolean canShare() { + return hasSelection() && !isFocusedNodeEditable() + && isSelectActionModeAllowed(MENU_ITEM_SHARE); + } - if (!isFocusedNodeEditable()) { - menu.removeItem(R.id.select_action_menu_cut); - } - - if (isFocusedNodeEditable() || !isSelectActionModeAllowed(MENU_ITEM_SHARE)) { - menu.removeItem(R.id.select_action_menu_share); - } - - if (isFocusedNodeEditable() || isIncognito() - || !isSelectActionModeAllowed(MENU_ITEM_WEB_SEARCH)) { - menu.removeItem(R.id.select_action_menu_web_search); - } - - if (isSelectionPassword() || !Clipboard.getInstance().canCopy()) { - menu.removeItem(R.id.select_action_menu_copy); - menu.removeItem(R.id.select_action_menu_cut); - } + /** + * Checks if web search action is available. + */ + @Override + public boolean canWebSearch() { + return hasSelection() && !isFocusedNodeEditable() && !isIncognito() + && isSelectActionModeAllowed(MENU_ITEM_WEB_SEARCH); } /** * Check if need to show "paste as plain text" option. - * "paste as plain text" option needs clibpoard content is rich text, and editor supports rich + * "paste as plain text" option needs clipboard content is rich text, and editor supports rich * text as well. */ - @VisibleForTesting + @Override public boolean canPasteAsPlainText() { + if (!canPaste()) return false; // String resource "paste_as_plain_text" only exist in O+. // Also this is an O feature, we need to make it consistent with TextView. if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return false; @@ -881,51 +927,22 @@ return Clipboard.getInstance().hasHTMLOrStyledText(); } - private void updateAssistMenuItem(Menu menu) { - // There is no Assist functionality before Android O. - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) return; - - if (mClassificationResult != null && mClassificationResult.hasNamedAction()) { - menu.add(R.id.select_action_menu_assist_items, android.R.id.textAssist, 1, - mClassificationResult.label) - .setIcon(mClassificationResult.icon); - } - } - /** - * Intialize the menu items for processing text, if there is any. + * Testing use only. Initialize the menu items for processing text, if there is any. */ @VisibleForTesting - /* package */ void initializeTextProcessingMenu(Menu menu) { + /* package */ void initializeTextProcessingMenuForTesting(ActionMode mode, Menu menu) { if (!isSelectActionModeAllowed(MENU_ITEM_PROCESS_TEXT)) { return; } - List<ResolveInfo> supportedActivities = - PackageManagerUtils.queryIntentActivities(createProcessTextIntent(), 0); - for (int i = 0; i < supportedActivities.size(); i++) { - ResolveInfo resolveInfo = supportedActivities.get(i); - if (resolveInfo.activityInfo == null || !resolveInfo.activityInfo.exported) continue; - - CharSequence label = resolveInfo.loadLabel(mContext.getPackageManager()); - menu.add(R.id.select_action_menu_text_processing_menus, Menu.NONE, - MENU_ITEM_ORDER_TEXT_PROCESS_START + i, label) - .setIntent(createProcessTextIntentForResolveInfo(resolveInfo)) - .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); + SelectionMenuGroup textProcessingItems = SelectActionMenuHelper.getTextProcessingItems( + mContext, false, false, this::processText); + if (textProcessingItems != null) { + addMenuGroupToMenu(mContext, textProcessingItems, mode, menu, null); } } - private static Intent createProcessTextIntent() { - return new Intent().setAction(Intent.ACTION_PROCESS_TEXT).setType("text/plain"); - } - - private Intent createProcessTextIntentForResolveInfo(ResolveInfo info) { - boolean isReadOnly = !isFocusedNodeEditable(); - return createProcessTextIntent() - .putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, isReadOnly) - .setClassName(info.activityInfo.packageName, info.activityInfo.name); - } - @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { // Actions should only happen when there is a WindowAndroid so mView should not be null. @@ -933,17 +950,8 @@ if (!isActionModeValid()) return true; int id = item.getItemId(); - int groupId = item.getGroupId(); - if (hasSelection() && mSmartSelectionEventProcessor != null) { - mSmartSelectionEventProcessor.onSelectionAction(mLastSelectedText, mLastSelectionOffset, - getActionType(id, groupId), mClassificationResult); - } - - if (groupId == R.id.select_action_menu_assist_items && id == android.R.id.textAssist) { - doAssistAction(); - mode.finish(); - } else if (id == R.id.select_action_menu_select_all) { + if (id == R.id.select_action_menu_select_all) { selectAll(); } else if (id == R.id.select_action_menu_cut) { cut(); @@ -964,15 +972,6 @@ } else if (id == R.id.select_action_menu_web_search) { search(); mode.finish(); - } else if (groupId == R.id.select_action_menu_text_processing_menus) { - processText(item.getIntent()); - // The ActionMode is not dismissed to match the behavior with - // TextView in Android M. - } else if (groupId == android.R.id.textAssist) { - if (mAdditionalMenuItemProvider != null) { - mAdditionalMenuItemProvider.performAction(item, mView); - mode.finish(); - } } else { return false; } @@ -988,6 +987,16 @@ } } + private void logSelectionAction(@IdRes int groupId, @IdRes int id) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + return; + } + if (hasSelection() && mSmartSelectionEventProcessor != null) { + mSmartSelectionEventProcessor.onSelectionAction(mLastSelectedText, mLastSelectionOffset, + getActionType(id, groupId), mClassificationResult); + } + } + /** * Called when an ActionMode needs to be positioned on screen, potentially occluding view * content. Note this may be called on a per-frame basis. @@ -1047,31 +1056,6 @@ } /** - * Perform an action that depends on the semantics of the selected text. - */ - @VisibleForTesting - void doAssistAction() { - assert mView != null; - if (mClassificationResult == null || !mClassificationResult.hasNamedAction()) return; - - assert mClassificationResult.onClickListener != null - || mClassificationResult.intent != null; - - if (mClassificationResult.onClickListener != null) { - mClassificationResult.onClickListener.onClick(mView); - return; - } - - if (mClassificationResult.intent != null) { - Context context = mWindowAndroid.getContext().get(); - if (context == null) return; - - context.startActivity(mClassificationResult.intent); - return; - } - } - - /** * Perform a select all action. */ @VisibleForTesting @@ -1211,9 +1195,9 @@ /** * @return true if the current selection can select all. */ - @VisibleForTesting + @Override public boolean canSelectAll() { - return mCanSelectAllForPastePopup; + return mCanSelectAll; } /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java index 71d1998..fb5ef73a 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionProvider.java
@@ -5,7 +5,9 @@ package org.chromium.content.browser.selection; import android.annotation.SuppressLint; +import android.app.RemoteAction; import android.content.Context; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Handler; import android.os.LocaleList; @@ -30,6 +32,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; /** * Controls Smart Text selection. Talks to the Android TextClassificationManager API. @@ -247,13 +251,27 @@ result.textClassification = tc; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { - result.additionalIcons = AdditionalMenuItemProviderImpl.loadIconDrawables( - mContext, result.textClassification); + result.additionalIcons = loadIconDrawables(mContext, result.textClassification); } return result; } + // Because Icon#loadDrawable() should not be called on UI thread, we pre-load the icons on + // background thread right after we get the text classification result in + // SmartSelectionProvider. TextClassification#getActions() is only available on P and above, + // so + @RequiresApi(Build.VERSION_CODES.P) + private List<Drawable> loadIconDrawables(Context context, TextClassification tc) { + if (context == null || tc == null) return null; + + ArrayList<Drawable> res = new ArrayList<>(); + for (RemoteAction action : tc.getActions()) { + res.add(action.getIcon().loadDrawable(context)); + } + return res; + } + @Override protected void onPostExecute(SelectionClient.Result result) { mResultCallback.onClassified(result);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/AdditionalSelectionMenuItemProvider.java b/content/public/android/java/src/org/chromium/content_public/browser/AdditionalSelectionMenuItemProvider.java new file mode 100644 index 0000000..302c9463 --- /dev/null +++ b/content/public/android/java/src/org/chromium/content_public/browser/AdditionalSelectionMenuItemProvider.java
@@ -0,0 +1,23 @@ +// 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. + +package org.chromium.content_public.browser; + +import java.util.List; + +/** + * Interface for providing additional menu items w/ click handling to the {@link + * SelectionPopupController}. + */ +public interface AdditionalSelectionMenuItemProvider { + /** + * Returns the list of items if any. + */ + List<SelectionMenuItem> getItems(); + + /** + * Callback for when the menu is destroyed. + */ + void onMenuDestroyed(); +}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SelectionMenuGroup.java b/content/public/android/java/src/org/chromium/content_public/browser/SelectionMenuGroup.java new file mode 100644 index 0000000..430883e --- /dev/null +++ b/content/public/android/java/src/org/chromium/content_public/browser/SelectionMenuGroup.java
@@ -0,0 +1,41 @@ +// 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. + +package org.chromium.content_public.browser; + +import androidx.annotation.IdRes; + +import java.util.Collection; +import java.util.PriorityQueue; + +/** + * Data class representing a group in the text selection menu. + */ +public final class SelectionMenuGroup implements Comparable<SelectionMenuGroup> { + public final @IdRes int id; + public final int order; + public final PriorityQueue<SelectionMenuItem> items; + + public SelectionMenuGroup(int id, int order) { + this.id = id; + this.order = order; + items = new PriorityQueue<>(); + } + + public void addItem(SelectionMenuItem item) { + items.add(item); + } + + public void addItems(Collection<SelectionMenuItem> items) { + this.items.addAll(items); + } + + /** + * Allows usage with {@link PriorityQueue} sorting. + */ + @Override + public int compareTo(SelectionMenuGroup otherGroup) { + return order - otherGroup.order; + } +}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SelectionMenuItem.java b/content/public/android/java/src/org/chromium/content_public/browser/SelectionMenuItem.java new file mode 100644 index 0000000..61add7d --- /dev/null +++ b/content/public/android/java/src/org/chromium/content_public/browser/SelectionMenuItem.java
@@ -0,0 +1,227 @@ +// 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. + +package org.chromium.content_public.browser; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.drawable.Drawable; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; + +import androidx.annotation.AttrRes; +import androidx.annotation.IdRes; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.StringRes; +import androidx.appcompat.content.res.AppCompatResources; + +import java.util.PriorityQueue; + +/** + * Data class representing an item in the text selection menu. + */ +public final class SelectionMenuItem implements Comparable<SelectionMenuItem> { + private final @AttrRes int mIconAttr; + private final @Nullable Drawable mIcon; + private final @StringRes int mTitleRes; + private final @Nullable CharSequence mTitle; + public final @IdRes int id; + public final @Nullable Character alphabeticShortcut; + public final int orderInCategory; + public final int showAsActionFlags; + public final @Nullable CharSequence contentDescription; + public final @Nullable View.OnClickListener clickListener; + public final boolean isEnabled; + + private SelectionMenuItem(@IdRes int id, @AttrRes int iconAttr, @Nullable Drawable icon, + @StringRes int titleRes, @Nullable CharSequence title, + @Nullable Character alphabeticShortcut, int orderInCategory, int showAsActionFlags, + @Nullable CharSequence contentDescription, @Nullable View.OnClickListener clickListener, + boolean isEnabled) { + mIconAttr = iconAttr; + mIcon = icon; + mTitleRes = titleRes; + mTitle = title; + this.id = id; + this.alphabeticShortcut = alphabeticShortcut; + this.orderInCategory = orderInCategory; + this.showAsActionFlags = showAsActionFlags; + this.contentDescription = contentDescription; + this.clickListener = clickListener; + this.isEnabled = isEnabled; + } + + /** + * Convenience method to return the title. + */ + @Nullable + public CharSequence getTitle(Context context) { + if (mTitleRes != 0) { + return context.getString(mTitleRes); + } + return mTitle; + } + + /** + * Convenience method to return the icon, if any. + */ + @Nullable + public Drawable getIcon(Context context) { + if (mIconAttr != 0) { + TypedArray a = context.obtainStyledAttributes(new int[] {mIconAttr}); + int iconResId = a.getResourceId(0, 0); + Drawable icon = + iconResId == 0 ? null : AppCompatResources.getDrawable(context, iconResId); + a.recycle(); + return icon; + } + return mIcon; + } + + /** + * For comparison. Mainly to be enable {@link PriorityQueue} sorting by order. + */ + @Override + public int compareTo(SelectionMenuItem otherItem) { + return orderInCategory - otherItem.orderInCategory; + } + + /** + * The builder class for {@link SelectionMenuItem}. + */ + public static class Builder { + private final @StringRes int mTitleRes; + private final @Nullable CharSequence mTitle; + private @IdRes int mId; + private @AttrRes int mIconAttr; + private @Nullable Drawable mIcon; + private @Nullable Character mAlphabeticShortcut; + private int mOrderInCategory; + private int mShowAsActionFlags; + private @Nullable CharSequence mContentDescription; + private @Nullable View.OnClickListener mClickListener; + private boolean mIsEnabled; + + /** + * Pass in a non-null title. + */ + public Builder(@NonNull CharSequence title) { + mTitle = title; + mTitleRes = 0; + initDefaults(); + } + + /** + * Pass in a valid string res. + */ + public Builder(@StringRes int titleRes) { + mTitleRes = titleRes; + mTitle = null; + initDefaults(); + } + + /** + * Sets default values to avoid inline initialization. + * See https://issuetracker.google.com/issues/37124982. + */ + private void initDefaults() { + mId = Menu.NONE; + mIconAttr = 0; + mIcon = null; + mAlphabeticShortcut = null; + mOrderInCategory = Menu.NONE; + mShowAsActionFlags = Menu.NONE; + mContentDescription = null; + mClickListener = null; + mIsEnabled = true; + } + + /** + * The id of the menu item. + */ + public Builder setId(@IdRes int id) { + mId = id; + return this; + } + + /** + * The attribute resource for the icon. Pass 0 for none. + */ + public Builder setIconAttr(@AttrRes int iconAttr) { + mIconAttr = iconAttr; + return this; + } + + /** + * The drawable icon. + */ + public Builder setIcon(@Nullable Drawable icon) { + mIcon = icon; + return this; + } + + /** + * The character keyboard shortcut. Default modifier is Ctrl. + */ + public Builder setAlphabeticShortcut(@Nullable Character alphabeticShortcut) { + mAlphabeticShortcut = alphabeticShortcut; + return this; + } + + /** + * @param orderInCategory the order, must be >= 0. + */ + public Builder setOrderInCategory(int orderInCategory) { + if (orderInCategory < 0) { + throw new IllegalArgumentException("Invalid order in category. Must be >= 0"); + } + mOrderInCategory = orderInCategory; + return this; + } + + /** + * Must be a {@link MenuItem} constant bit combination + * (i.e. MenuItem.SHOW_AS_ACTION_IF_ROOM) otherwise 0. + */ + public Builder setShowAsActionFlags(int showAsActionFlags) { + mShowAsActionFlags = showAsActionFlags; + return this; + } + + /** + * Content description for a11y. + */ + public Builder setContentDescription(@Nullable CharSequence contentDescription) { + mContentDescription = contentDescription; + return this; + } + + /** + * Click listener for when the menu item is clicked. + */ + public Builder setClickListener(@Nullable View.OnClickListener clickListener) { + mClickListener = clickListener; + return this; + } + + /** + * Pass in true if the item is enabled. Otherwise false. + */ + public Builder setIsEnabled(boolean isEnabled) { + mIsEnabled = isEnabled; + return this; + } + + /** + * Builds the menu item. + */ + public SelectionMenuItem build() { + return new SelectionMenuItem(mId, mIconAttr, mIcon, mTitleRes, mTitle, + mAlphabeticShortcut, mOrderInCategory, mShowAsActionFlags, mContentDescription, + mClickListener, mIsEnabled); + } + } +}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java b/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java index a7a8bb9..d2b8372 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SelectionPopupController.java
@@ -78,11 +78,10 @@ void setActionModeCallback(ActionMode.Callback2 callback); /** - * Set {@link ActionMode.Callback} used by {@link SelectionPopupController} when no text is - * selected. - * @param callback ActionMode.Callback instance. + * Sets the {@link AdditionalSelectionMenuItemProvider} used by {@link SelectionPopupController} + * when no text is selected. */ - void setNonSelectionActionModeCallback(ActionMode.Callback callback); + void setNonSelectionAdditionalMenuItemProvider(AdditionalSelectionMenuItemProvider provider); /** * @return {@link SelectionClient.ResultCallback} instance.
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsAccessibility.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsAccessibility.java index 6c9f505f..8c70fce2 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsAccessibility.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsAccessibility.java
@@ -8,8 +8,6 @@ import android.view.ViewStructure; import android.view.accessibility.AccessibilityNodeProvider; -import androidx.annotation.VisibleForTesting; - import org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl; /** @@ -34,12 +32,6 @@ boolean isNativeInitialized(); /** - * Enables a11y for testing. - */ - @VisibleForTesting - void setAccessibilityEnabledForTesting(); - - /** * If native accessibility is enabled and no other views are temporarily * obscuring this one, returns an AccessibilityNodeProvider that * implements native accessibility for this view. Returns null otherwise.
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java index 7149a554..e680797 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/accessibility/AccessibilityContentShellActivityTestRule.java
@@ -96,11 +96,10 @@ */ /* @Before */ public void setupTestFramework() { - mWcax = getWebContentsAccessibility(); - mWcax.setAccessibilityEnabledForTesting(); AccessibilityState.setIsAnyAccessibilityServiceEnabledForTesting(true); AccessibilityState.setEventTypeMaskForTesting(EVENT_TYPE_MASK_ALL); + mWcax = getWebContentsAccessibility(); mNodeProvider = getAccessibilityNodeProvider(); mTracker = new AccessibilityActionAndEventTracker();
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java b/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java index 7d27c970..a7acab5b 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/input/StylusGestureHandlerTest.java
@@ -7,11 +7,17 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.doCallRealMethod; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; import android.graphics.PointF; import android.graphics.RectF; +import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputConnection; +import androidx.test.filters.LargeTest; import androidx.test.filters.MediumTest; import org.junit.Before; @@ -26,7 +32,10 @@ import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.blink.mojom.StylusWritingGestureAction; import org.chromium.blink.mojom.StylusWritingGestureData; +import org.chromium.content.browser.RenderCoordinatesImpl; +import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content_public.browser.test.ContentJUnit4ClassRunner; +import org.chromium.content_public.browser.test.util.JavaScriptUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.gfx.mojom.Rect; @@ -34,6 +43,7 @@ import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.concurrent.TimeoutException; /** * Tests for using a StylusGestureHandler as an InvocationHandler in place of an InputConnection in @@ -340,6 +350,66 @@ histogram.assertExpected(); } + @Test + @LargeTest + public void testDeleteGestureEndToEnd() + throws TimeoutException, ClassNotFoundException, IllegalAccessException, + InstantiationException, InvocationTargetException { + EditorInfo editorInfo = new EditorInfo(); + ImeAdapterImpl imeAdapter = spy(mRule.getImeAdapter()); + doReturn(mRule.getConnection()) + .when(imeAdapter) + .onCreateInputConnection(any(EditorInfo.class), any(boolean.class)); + doCallRealMethod().when(imeAdapter).onCreateInputConnection(any(EditorInfo.class)); + mWrappedInputConnection = imeAdapter.onCreateInputConnection(editorInfo); + JavaScriptUtils.executeJavaScriptAndWaitForResult(mRule.getWebContents(), + "document.getElementById(\"input_text\").value = \"hello world\""); + + // Gets the bounding box of the element with id: input_text. + float left = Float.parseFloat( + JavaScriptUtils.executeJavaScriptAndWaitForResult(mRule.getWebContents(), + "document.getElementById('input_text').getBoundingClientRect().left")); + float top = Float.parseFloat( + JavaScriptUtils.executeJavaScriptAndWaitForResult(mRule.getWebContents(), + "document.getElementById('input_text').getBoundingClientRect().top")); + float right = Float.parseFloat( + JavaScriptUtils.executeJavaScriptAndWaitForResult(mRule.getWebContents(), + "document.getElementById('input_text').getBoundingClientRect().right")); + float bottom = Float.parseFloat( + JavaScriptUtils.executeJavaScriptAndWaitForResult(mRule.getWebContents(), + "document.getElementById('input_text').getBoundingClientRect().bottom")); + + RectF gestureRect = + toScreenRectF(left, top, right, bottom, (WebContentsImpl) mRule.getWebContents()); + gestureRect.inset(1, 1); // Inset to avoid including the border. + + // The following reflection creates a new DeleteGesture over the left half of the input_text + // element. It has word granularity and the fallback text defined in FALLBACK_TEXT. + Class builderClass = getBuilderForClass(Class.forName(TARGET_PACKAGE + "DeleteGesture")); + Map<String, Method> builderMethods = getMethodsForClass(builderClass); + Object builder = builderClass.newInstance(); + builderMethods.get("setGranularity").invoke(builder, StylusGestureHandler.GRANULARITY_WORD); + builderMethods.get("setDeletionArea").invoke(builder, gestureRect); + builderMethods.get("setFallbackText").invoke(builder, FALLBACK_TEXT); + Object gesture = builderMethods.get("build").invoke(builder); + + TestThreadUtils.runOnUiThreadBlocking(() -> { + Method performHandwritingGesture = + getMethodsForClass(mWrappedInputConnection.getClass()) + .get("performHandwritingGesture"); + try { + performHandwritingGesture.invoke(mWrappedInputConnection, gesture, null, null); + } catch (IllegalAccessException | InvocationTargetException e) { + fail("Failed to call performHandwritingGesture"); + } + }); + + // Get the text inside input_text and assert that it has been deleted. + assertEquals("\"\"", + JavaScriptUtils.executeJavaScriptAndWaitForResult( + mRule.getWebContents(), "document.getElementById(\"input_text\").value")); + } + private static Map<String, Method> getMethodsForClass(Class<?> className) { Map<String, Method> methodMap = new HashMap<>(); for (Method method : className.getDeclaredMethods()) { @@ -385,4 +455,27 @@ } return string.toString(); } + + /** + * @param left the X value for the left edge of the rectangle. + * @param top the Y value for the top edge of the rectangle. + * @param right the X value for the right edge of the rectangle. + * @param bottom the Y value for the bottom edge of the rectangle. + * @param webContents the web contents where this rectangle is being used (for converting to + * screen coordinates). + * @return an Android RectF object represented by the four float values in screen coordinates. + */ + private static RectF toScreenRectF( + float left, float top, float right, float bottom, WebContentsImpl webContents) { + // Convert from local CSS coordinates to absolute screen coordinates. + RenderCoordinatesImpl rc = webContents.getRenderCoordinates(); + int[] screenLocation = new int[2]; + webContents.getViewAndroidDelegate().getContainerView().getLocationOnScreen(screenLocation); + left = rc.fromLocalCssToPix(left) + screenLocation[0]; + top = rc.fromLocalCssToPix(top) + rc.getContentOffsetYPix() + screenLocation[1]; + right = rc.fromLocalCssToPix(right) + screenLocation[0]; + bottom = rc.fromLocalCssToPix(bottom) + rc.getContentOffsetYPixInt() + screenLocation[1]; + + return new RectF(left, top, right, bottom); + } }
diff --git a/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java b/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java index bb2f40c..aa427eb8 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/selection/SelectionPopupControllerTest.java
@@ -659,7 +659,7 @@ Menu menu1 = new RoboMenu(); assertEquals(0, menu1.size()); - spyController.initializeTextProcessingMenu(menu1); + spyController.initializeTextProcessingMenuForTesting(mActionMode, menu1); assertEquals(0, menu1.size()); // test activityInfo exported=true @@ -670,7 +670,7 @@ Menu menu2 = new RoboMenu(); assertEquals(0, menu2.size()); - spyController.initializeTextProcessingMenu(menu2); + spyController.initializeTextProcessingMenuForTesting(mActionMode, menu2); assertEquals(1, menu2.size()); // test null activityInfo @@ -682,7 +682,7 @@ Menu menu3 = new RoboMenu(); assertEquals(0, menu3.size()); - spyController.initializeTextProcessingMenu(menu3); + spyController.initializeTextProcessingMenuForTesting(mActionMode, menu3); assertEquals(0, menu3.size()); }
diff --git a/content/public/browser/BUILD.gn b/content/public/browser/BUILD.gn index d15a912..09ecbb4f 100644 --- a/content/public/browser/BUILD.gn +++ b/content/public/browser/BUILD.gn
@@ -611,6 +611,10 @@ sources += [ "context_factory.h" ] } + if (is_apple) { + configs += [ "//build/config/compiler:enable_arc" ] + } + if (is_mac) { sources += [ "ax_inspect_factory_mac.mm",
diff --git a/content/public/browser/ax_inspect_factory_mac.mm b/content/public/browser/ax_inspect_factory_mac.mm index ae73990..a8c5a45 100644 --- a/content/public/browser/ax_inspect_factory_mac.mm +++ b/content/public/browser/ax_inspect_factory_mac.mm
@@ -9,6 +9,10 @@ #include "ui/accessibility/platform/inspect/ax_event_recorder_mac.h" #include "ui/accessibility/platform/inspect/ax_tree_formatter_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace content { // static @@ -22,8 +26,8 @@ BrowserAccessibilityManager*, base::ProcessId pid, const ui::AXTreeSelector& selector) { - return AXInspectFactory::CreateRecorder(ui::AXApiType::kMac, nullptr, pid, - selector); + return AXInspectFactory::CreateRecorder(ui::AXApiType::kMac, + /*manager=*/nullptr, pid, selector); } // static
diff --git a/content/public/browser/native_event_processor_observer_mac.mm b/content/public/browser/native_event_processor_observer_mac.mm index b378c05..96f6843d 100644 --- a/content/public/browser/native_event_processor_observer_mac.mm +++ b/content/public/browser/native_event_processor_observer_mac.mm
@@ -6,6 +6,10 @@ #include "base/observer_list.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace content { ScopedNotifyNativeEventProcessorObserver:: @@ -15,13 +19,13 @@ NSEvent* event) : observer_list_(observer_list), event_(event) { for (auto& observer : *observer_list_) - observer.WillRunNativeEvent(event_); + observer.WillRunNativeEvent((__bridge const void*)event_); } ScopedNotifyNativeEventProcessorObserver:: ~ScopedNotifyNativeEventProcessorObserver() { for (auto& obs : *observer_list_) { - obs.DidRunNativeEvent(event_); + obs.DidRunNativeEvent((__bridge const void*)event_); } }
diff --git a/content/public/browser/network_service_util.cc b/content/public/browser/network_service_util.cc index fabb29f..d09c43a4b 100644 --- a/content/public/browser/network_service_util.cc +++ b/content/public/browser/network_service_util.cc
@@ -6,6 +6,7 @@ #include "base/command_line.h" #include "build/build_config.h" +#include "content/browser/network/network_service_util_internal.h" #include "content/public/common/content_features.h" #include "content/public/common/content_switches.h" @@ -30,10 +31,6 @@ "network_service_oop_threshold_mb", 1077}; #endif -// Indicates whether the network service is forced to be running in the browser -// process. -bool g_force_in_process_network_service = false; - } // namespace bool IsOutOfProcessNetworkService() { @@ -41,6 +38,17 @@ } bool IsInProcessNetworkService() { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSingleProcess)) { + return true; + } + + const absl::optional<bool>& forced_in_or_out = + content::GetForcedNetworkServiceProcessInOrOut(); + if (forced_in_or_out) { + return *forced_in_or_out; + } + #if BUILDFLAG(IS_ANDROID) // Check RAM size before looking at kNetworkServiceInProcess flag // so that we can throttle the finch groups including control. @@ -50,17 +58,11 @@ } #endif - if (g_force_in_process_network_service || - base::FeatureList::IsEnabled(features::kNetworkServiceInProcess) || - base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kSingleProcess)) { - return true; - } - return false; + return base::FeatureList::IsEnabled(features::kNetworkServiceInProcess); } -void ForceInProcessNetworkService(bool is_forced) { - g_force_in_process_network_service = is_forced; +void ForceInProcessNetworkService() { + ForceInProcessNetworkServiceImpl(); } } // namespace content
diff --git a/content/public/browser/network_service_util.h b/content/public/browser/network_service_util.h index 0a04514c..24aa390 100644 --- a/content/public/browser/network_service_util.h +++ b/content/public/browser/network_service_util.h
@@ -20,7 +20,7 @@ // Sets the flag of whether the network service is forced to be running in the // browser process. The flag will be checked in |IsInProcessNetworkService()|. -CONTENT_EXPORT void ForceInProcessNetworkService(bool is_forced); +CONTENT_EXPORT void ForceInProcessNetworkService(); } // namespace content #endif // CONTENT_PUBLIC_BROWSER_NETWORK_SERVICE_UTIL_H_
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index 5caa3dd3..9f2a164 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -791,14 +791,6 @@ "PeriodicBackgroundSync", base::FEATURE_DISABLED_BY_DEFAULT); -// If Pepper 3D Image Chromium is allowed, this feature controls whether it is -// enabled. -// TODO(https://crbug.com/1196009): Remove this feature, remove the code that -// uses it. -BASE_FEATURE(kPepper3DImageChromium, - "Pepper3DImageChromium", - base::FEATURE_DISABLED_BY_DEFAULT); - // Kill-switch to introduce a compatibility breaking restriction. BASE_FEATURE(kPepperCrossOriginRedirectRestriction, "PepperCrossOriginRedirectRestriction",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 164b944..a49ecc7 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -176,7 +176,6 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kOverscrollHistoryNavigation); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPeriodicBackgroundSync); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFeaturePolicyHeader); -CONTENT_EXPORT BASE_DECLARE_FEATURE(kPepper3DImageChromium); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPepperCrossOriginRedirectRestriction); CONTENT_EXPORT BASE_DECLARE_FEATURE(kPersistentOriginTrials); CONTENT_EXPORT BASE_DECLARE_FEATURE(kHighPriorityBeforeUnload);
diff --git a/content/public/common/content_switches.cc b/content/public/common/content_switches.cc index 4feb7de4..9b641982 100644 --- a/content/public/common/content_switches.cc +++ b/content/public/common/content_switches.cc
@@ -211,9 +211,6 @@ // Disables the Permissions API. const char kDisablePermissionsAPI[] = "disable-permissions-api"; -// Disable Image Chromium for Pepper 3d. -const char kDisablePepper3DImageChromium[] = "disable-pepper-3d-image-chromium"; - // Disables compositor-accelerated touch-screen pinch gestures. const char kDisablePinch[] = "disable-pinch";
diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index f693867..5da1032 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h
@@ -74,7 +74,6 @@ CONTENT_EXPORT extern const char kDisableNv12DxgiVideo[]; CONTENT_EXPORT extern const char kDisableOriginTrialControlledBlinkFeatures[]; extern const char kDisablePepper3d[]; -CONTENT_EXPORT extern const char kDisablePepper3DImageChromium[]; CONTENT_EXPORT extern const char kDisablePermissionsAPI[]; CONTENT_EXPORT extern const char kDisablePinch[]; CONTENT_EXPORT extern const char kDisablePresentationAPI[];
diff --git a/content/public/renderer/BUILD.gn b/content/public/renderer/BUILD.gn index 4c16e493..5ad21dd 100644 --- a/content/public/renderer/BUILD.gn +++ b/content/public/renderer/BUILD.gn
@@ -60,7 +60,6 @@ "//content/renderer", "//gin", "//media/capture", - "//media/gpu/ipc/client", "//net", "//ppapi/buildflags", "//skia",
diff --git a/content/public/test/DEPS b/content/public/test/DEPS index ab62c324..052dfd1 100644 --- a/content/public/test/DEPS +++ b/content/public/test/DEPS
@@ -23,6 +23,7 @@ "+components/network_session_configurator/common/network_switches.h", "+components/services/storage/privileged", "+components/services/storage/public", + "+components/services/storage/shared_storage", "+components/startup_metric_utils/browser", "+components/ukm/test_ukm_recorder.h", "+components/viz/client", @@ -71,5 +72,8 @@ ], "browser_test_utils.cc": [ "+ash/webui/grit/ash_webui_common_resources.h" + ], + "test_shared_storage_header_observer.h": [ + "+content/browser/shared_storage/shared_storage_header_observer.h" ] }
diff --git a/content/public/test/android/BUILD.gn b/content/public/test/android/BUILD.gn index 23b3e99..c901125 100644 --- a/content/public/test/android/BUILD.gn +++ b/content/public/test/android/BUILD.gn
@@ -28,6 +28,7 @@ "//content/public/android:content_java", "//mojo/public/java:bindings_java", "//net/android:net_java", + "//net/android:net_java_test_support", "//services/service_manager/public/java:service_manager_java", "//third_party/androidx:androidx_annotation_annotation_java", "//third_party/androidx:androidx_test_monitor_java",
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java index 6c3d062e..5e50ae8b 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/ContentJUnit4ClassRunner.java
@@ -10,6 +10,7 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.SkipCheck; +import org.chromium.net.test.EmbeddedTestServer; import org.chromium.ui.test.util.DeviceRestrictionSkipCheck; import org.chromium.ui.test.util.UiDisableIfSkipCheck; import org.chromium.ui.test.util.UiRestrictionSkipCheck; @@ -44,4 +45,9 @@ protected List<TestHook> getPreTestHooks() { return addToList(super.getPreTestHooks(), new ChildProcessAllocatorSettingsHook()); } + + @Override + protected List<ClassHook> getPreClassHooks() { + return addToList(super.getPreClassHooks(), EmbeddedTestServer.getPreClassHook()); + } }
diff --git a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java index ea37797..71dc9cb 100644 --- a/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java +++ b/content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestSelectionPopupController.java
@@ -11,6 +11,7 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.content_public.browser.ActionModeCallbackHelper; +import org.chromium.content_public.browser.AdditionalSelectionMenuItemProvider; import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionPopupController; @@ -25,7 +26,8 @@ public void setActionModeCallback(ActionMode.Callback2 callback) {} @Override - public void setNonSelectionActionModeCallback(ActionMode.Callback callback) {} + public void setNonSelectionAdditionalMenuItemProvider( + AdditionalSelectionMenuItemProvider provider) {} @Override public SelectionClient.ResultCallback getResultCallback() {
diff --git a/content/public/test/browser_test_utils.cc b/content/public/test/browser_test_utils.cc index 20332aa..5006cca 100644 --- a/content/public/test/browser_test_utils.cc +++ b/content/public/test/browser_test_utils.cc
@@ -645,7 +645,7 @@ } bool NavigateIframeToURL(WebContents* web_contents, - const std::string& iframe_id, + base::StringPiece iframe_id, const GURL& url) { TestNavigationObserver load_observer(web_contents); bool result = BeginNavigateIframeToURL(web_contents, iframe_id, url); @@ -654,13 +654,11 @@ } bool BeginNavigateIframeToURL(WebContents* web_contents, - const std::string& iframe_id, + base::StringPiece iframe_id, const GURL& url) { - std::string script = base::StringPrintf( - "setTimeout(\"" - "var iframes = document.getElementById('%s');iframes.src='%s';" - "\",0)", - iframe_id.c_str(), url.spec().c_str()); + std::string script = + base::StrCat({"setTimeout(\"var iframes = document.getElementById('", + iframe_id, "');iframes.src='", url.spec(), "';\",0)"}); return ExecJs(web_contents, script, EXECUTE_SCRIPT_NO_USER_GESTURE); } @@ -701,7 +699,7 @@ } GURL GetFileUrlWithQuery(const base::FilePath& path, - const std::string& query_string) { + base::StringPiece query_string) { GURL url = net::FilePathToFileURL(path); if (!query_string.empty()) { GURL::Replacements replacements; @@ -935,7 +933,7 @@ gfx::PointF GetCenterCoordinatesOfElementWithId( content::WebContents* web_contents, - const std::string& id) { + base::StringPiece id) { float x = EvalJs(web_contents, JsReplace("const bounds = " "document.getElementById($1)." @@ -954,7 +952,7 @@ } void SimulateMouseClickOrTapElementWithId(content::WebContents* web_contents, - const std::string& id) { + base::StringPiece id) { gfx::Point point = gfx::ToFlooredPoint( GetCenterCoordinatesOfElementWithId(web_contents, id)); @@ -1358,7 +1356,7 @@ } void ExecuteScriptAsync(const ToRenderFrameHost& adapter, - const std::string& script) { + base::StringPiece script) { // Prerendering pages will never have user gesture. if (adapter.render_frame_host()->GetLifecycleState() == RenderFrameHost::LifecycleState::kPrerendering) { @@ -1370,13 +1368,13 @@ } void ExecuteScriptAsyncWithoutUserGesture(const ToRenderFrameHost& adapter, - const std::string& script) { + base::StringPiece script) { adapter.render_frame_host()->ExecuteJavaScriptForTests( base::UTF8ToUTF16(script), base::NullCallback()); } // EvalJsResult methods. -EvalJsResult::EvalJsResult(base::Value value, const std::string& error) +EvalJsResult::EvalJsResult(base::Value value, base::StringPiece error) : value(error.empty() ? std::move(value) : base::Value()), error(error) {} EvalJsResult::EvalJsResult(const EvalJsResult& other) @@ -1450,9 +1448,9 @@ // // TODO(nick): Elide snippets to 80 chars, since it is common for sources to not // include newlines. -std::string AnnotateAndAdjustJsStackTraces(const std::string& js_error, +std::string AnnotateAndAdjustJsStackTraces(base::StringPiece js_error, std::string source_name, - const std::string& source, + base::StringPiece source, int column_adjustment_for_line_one) { // Escape wildcards in |source_name| for use in MatchPattern. base::ReplaceChars(source_name, "\\", "\\\\", &source_name); @@ -1610,8 +1608,8 @@ }; EvalJsResult EvalJsRunner(const ToRenderFrameHost& execution_target, - const std::string& script, - const std::string& source_url, + base::StringPiece script, + base::StringPiece source_url, int options, int32_t world_id) { RenderFrameHostImpl* rfh = @@ -1648,8 +1646,9 @@ CHECK(result_value.is_string() && !result_value.GetString().empty()); std::string error_text = "a JavaScript error: \"" + result_value.GetString() + "\""; - return EvalJsResult(base::Value(), AnnotateAndAdjustJsStackTraces( - error_text, source_url, script, 0)); + return EvalJsResult(base::Value(), + AnnotateAndAdjustJsStackTraces( + error_text, std::string(source_url), script, 0)); } return EvalJsResult(result_value.Clone(), std::string()); @@ -1658,7 +1657,7 @@ } // namespace ::testing::AssertionResult ExecJs(const ToRenderFrameHost& execution_target, - const std::string& script, + base::StringPiece script, int options, int32_t world_id) { // TODO(nick): Do we care enough about folks shooting themselves in the foot @@ -1674,7 +1673,7 @@ } EvalJsResult EvalJs(const ToRenderFrameHost& execution_target, - const std::string& script, + base::StringPiece script, int options, int32_t world_id) { TRACE_EVENT1("test", "EvalJs", "script", script); @@ -1687,8 +1686,8 @@ // let/const don't leak outside the code being run, but vars will float to // the outer scope. const char* kSourceURL = "__const_std::string&_script__"; - std::string modified_script = base::StringPrintf("{%s\n}\n//# sourceURL=%s", - script.c_str(), kSourceURL); + std::string modified_script = + base::StrCat({"{", script, "\n}\n//# sourceURL=", kSourceURL}); return EvalJsRunner(execution_target, modified_script, kSourceURL, options, world_id); @@ -1696,8 +1695,8 @@ EvalJsResult EvalJsAfterLifecycleUpdate( const ToRenderFrameHost& execution_target, - const std::string& raf_script, - const std::string& script, + base::StringPiece raf_script, + base::StringPiece script, int options, int32_t world_id) { TRACE_EVENT2("test", "EvalJsAfterLifecycleUpdate", "raf_script", raf_script, @@ -1707,11 +1706,11 @@ const char* kWrapperURL = "__const_std::string&_EvalJsAfterLifecycleUpdate__"; std::string modified_raf_script; if (raf_script.length()) { - modified_raf_script = base::StringPrintf("%s;\n//# sourceURL=%s", - raf_script.c_str(), kSourceURL); + modified_raf_script = + base::StrCat({raf_script, ";\n//# sourceURL=", kSourceURL}); } std::string modified_script = - base::StringPrintf("%s;\n//# sourceURL=%s", script.c_str(), kSourceURL); + base::StrCat({script, ";\n//# sourceURL=", kSourceURL}); // This runner_script delays running the argument scripts until just before // (|raf_script|) and after (|script|) a rendering update. @@ -1765,7 +1764,7 @@ return rfh; } -bool FrameMatchesName(const std::string& name, RenderFrameHost* frame) { +bool FrameMatchesName(base::StringPiece name, RenderFrameHost* frame) { return frame->GetFrameName() == name; } @@ -2039,7 +2038,7 @@ } bool AccessibilityTreeContainsNodeWithName(BrowserAccessibility* node, - const std::string& name) { + base::StringPiece name) { // If an image annotation is set, it plays the same role as a name, so it // makes sense to check both in the same test helper. if (node->GetStringAttribute(ax::mojom::StringAttribute::kName) == name || @@ -2060,7 +2059,7 @@ } void WaitForAccessibilityTreeToContainNodeWithName(WebContents* web_contents, - const std::string& name) { + base::StringPiece name) { WebContentsImpl* web_contents_impl = static_cast<WebContentsImpl*>( web_contents); RenderFrameHostImpl* main_frame = static_cast<RenderFrameHostImpl*>( @@ -2356,7 +2355,7 @@ RenderProcessHostKillWaiter::RenderProcessHostKillWaiter( RenderProcessHost* render_process_host, - const std::string& uma_name) + base::StringPiece uma_name) : exit_watcher_(render_process_host, RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT), uma_name_(uma_name) {}
diff --git a/content/public/test/browser_test_utils.h b/content/public/test/browser_test_utils.h index 1f7c98e..a25264a 100644 --- a/content/public/test/browser_test_utils.h +++ b/content/public/test/browser_test_utils.h
@@ -22,6 +22,7 @@ #include "base/process/process.h" #include "base/run_loop.h" #include "base/scoped_observation.h" +#include "base/strings/string_piece.h" #include "base/template_util.h" #include "base/test/metrics/histogram_tester.h" #include "base/types/strong_alias.h" @@ -243,18 +244,18 @@ // necessary, a user activation can be triggered right before calling this // method, e.g. by calling |ExecJs(frame_tree_node, "")|. bool NavigateIframeToURL(WebContents* web_contents, - const std::string& iframe_id, + base::StringPiece iframe_id, const GURL& url); // Similar to |NavigateIframeToURL()| but returns as soon as the navigation is // initiated. bool BeginNavigateIframeToURL(WebContents* web_contents, - const std::string& iframe_id, + base::StringPiece iframe_id, const GURL& url); // Generate a URL for a file path including a query string. GURL GetFileUrlWithQuery(const base::FilePath& path, - const std::string& query_string); + base::StringPiece query_string); // Checks whether the page type of the last committed navigation entry matches // |page_type|. @@ -341,12 +342,12 @@ // friendly by taking zooming into account. gfx::PointF GetCenterCoordinatesOfElementWithId( content::WebContents* web_contents, - const std::string& id); + base::StringPiece id); // Retrieves the center coordinates of the element with id |id| and simulates a // mouse click there using SimulateMouseClickAt(). void SimulateMouseClickOrTapElementWithId(content::WebContents* web_contents, - const std::string& id); + base::StringPiece id); // Simulates asynchronously a mouse enter/move/leave event. The mouse event is // routed through RenderWidgetHostInputEventRouter and thus can target OOPIFs. @@ -571,12 +572,12 @@ // - EvalJs (if you want to retrieve a value) // - DOMMessageQueue (to manually wait for domAutomationController.send(...)) void ExecuteScriptAsync(const ToRenderFrameHost& adapter, - const std::string& script); + base::StringPiece script); // Same as `content::ExecuteScriptAsync()`, but doesn't send a user gesture to // the renderer. void ExecuteScriptAsyncWithoutUserGesture(const ToRenderFrameHost& adapter, - const std::string& script); + base::StringPiece script); // JsLiteralHelper is a helper class that determines what types are legal to // pass to StringifyJsLiteral. Legal types include int, string, StringPiece, @@ -692,7 +693,7 @@ // Creates an EvalJs result. If |error| is non-empty, |value| will be // ignored. - EvalJsResult(base::Value value, const std::string& error); + EvalJsResult(base::Value value, base::StringPiece error); // Copy ctor. EvalJsResult(const EvalJsResult& value); @@ -844,7 +845,7 @@ // // It is guaranteed that EvalJs works even when the target frame is frozen. [[nodiscard]] EvalJsResult EvalJs(const ToRenderFrameHost& execution_target, - const std::string& script, + base::StringPiece script, int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS, int32_t world_id = ISOLATED_WORLD_ID_GLOBAL); @@ -855,8 +856,8 @@ // processed by the browser. [[nodiscard]] EvalJsResult EvalJsAfterLifecycleUpdate( const ToRenderFrameHost& execution_target, - const std::string& raf_script, - const std::string& script, + base::StringPiece raf_script, + base::StringPiece script, int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS, int32_t world_id = ISOLATED_WORLD_ID_GLOBAL); @@ -870,7 +871,7 @@ // until it resolves (by default). [[nodiscard]] ::testing::AssertionResult ExecJs( const ToRenderFrameHost& execution_target, - const std::string& script, + base::StringPiece script, int options = EXECUTE_SCRIPT_DEFAULT_OPTIONS, int32_t world_id = ISOLATED_WORLD_ID_GLOBAL); @@ -889,7 +890,7 @@ base::RepeatingCallback<bool(RenderFrameHost*)> predicate); // Predicates for use with FrameMatchingPredicate[OrNullPtr](). -bool FrameMatchesName(const std::string& name, RenderFrameHost* frame); +bool FrameMatchesName(base::StringPiece name, RenderFrameHost* frame); bool FrameIsChildOfMainFrame(RenderFrameHost* frame); bool FrameHasSourceUrl(const GURL& url, RenderFrameHost* frame); @@ -1023,7 +1024,7 @@ // WaitForAccessibilityTreeToChange, above, and then checks again. // Keeps looping until the text is found (or the test times out). void WaitForAccessibilityTreeToContainNodeWithName(WebContents* web_contents, - const std::string& name); + base::StringPiece name); // Get a snapshot of a web page's accessibility tree. ui::AXTreeUpdate GetAccessibilityTreeSnapshot(WebContents* web_contents); @@ -1193,7 +1194,7 @@ // |uma_name| is the name of the histogram from which the |bad_message_reason| // can be extracted. RenderProcessHostKillWaiter(RenderProcessHost* render_process_host, - const std::string& uma_name); + base::StringPiece uma_name); RenderProcessHostKillWaiter(const RenderProcessHostKillWaiter&) = delete; RenderProcessHostKillWaiter& operator=(const RenderProcessHostKillWaiter&) =
diff --git a/content/public/test/shared_storage_test_utils.cc b/content/public/test/shared_storage_test_utils.cc index c334168..7d31d3a9 100644 --- a/content/public/test/shared_storage_test_utils.cc +++ b/content/public/test/shared_storage_test_utils.cc
@@ -5,8 +5,12 @@ #include "content/public/test/shared_storage_test_utils.h" #include <map> +#include <string> +#include <utility> #include "base/functional/overloaded.h" +#include "base/notreached.h" +#include "components/services/storage/shared_storage/shared_storage_manager.h" #include "content/browser/renderer_host/frame_tree_node.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/browser/shared_storage/shared_storage_document_service_impl.h" @@ -18,10 +22,80 @@ #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_frame_navigation_observer.h" #include "content/test/fenced_frame_test_utils.h" +#include "services/network/public/mojom/optional_bool.mojom.h" +#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" #include "url/gurl.h" namespace content { +namespace { + +std::string SharedStorageOperationTypeToString(OperationType operation_type) { + switch (operation_type) { + case OperationType::kSet: + return "Set"; + case OperationType::kAppend: + return "Append"; + case OperationType::kDelete: + return "Delete"; + case OperationType::kClear: + return "Clear"; + default: + NOTREACHED(); + } + return "None"; +} + +std::string SharedStorageOperationResultToString(OperationResult result) { + switch (result) { + case OperationResult::kSuccess: + return "Success"; + case OperationResult::kSet: + return "Set"; + case OperationResult::kIgnored: + return "Ignored"; + case OperationResult::kSqlError: + return "SqlError"; + case OperationResult::kInitFailure: + return "InitFailure"; + case OperationResult::kNoCapacity: + return "NoCapacity"; + case OperationResult::kInvalidAppend: + return "InvalidAppend"; + case OperationResult::kNotFound: + return "NotFound"; + case OperationResult::kTooManyFound: + return "TooManyFound"; + case OperationResult::kExpired: + return "Expired"; + default: + NOTREACHED(); + } + return "None"; +} + +std::string OptionalStringToString(const absl::optional<std::string>& str) { + return str.has_value() ? str.value() : "[[NULL]]"; +} + +std::string OptionalBoolToString(absl::optional<bool> opt_bool) { + return opt_bool.has_value() ? (opt_bool.value() ? "true" : "false") + : "[[NULL]]"; +} + +absl::optional<bool> MojomToAbslOptionalBool( + network::mojom::OptionalBool opt_bool) { + absl::optional<bool> converted; + if (opt_bool == network::mojom::OptionalBool::kTrue) { + converted = true; + } else if (opt_bool == network::mojom::OptionalBool::kFalse) { + converted = false; + } + return converted; +} + +} // namespace + SharedStorageWorkletHostManager* GetSharedStorageWorkletHostManagerForStoragePartition( StoragePartition* storage_partition) { @@ -99,4 +173,144 @@ return fenced_frame_root_node->current_frame_host(); } +network::mojom::OptionalBool AbslToMojomOptionalBool( + absl::optional<bool> opt_bool) { + return opt_bool.has_value() + ? (opt_bool.value() ? network::mojom::OptionalBool::kTrue + : network::mojom::OptionalBool::kFalse) + : network::mojom::OptionalBool::kUnset; +} + +// static +SharedStorageWriteOperationAndResult +SharedStorageWriteOperationAndResult::SetOperation( + const url::Origin& request_origin, + std::string key, + std::string value, + absl::optional<bool> ignore_if_present, + OperationResult result) { + return SharedStorageWriteOperationAndResult( + request_origin, OperationType::kSet, std::move(key), std::move(value), + ignore_if_present, result); +} + +// static +SharedStorageWriteOperationAndResult +SharedStorageWriteOperationAndResult::AppendOperation( + const url::Origin& request_origin, + std::string key, + std::string value, + OperationResult result) { + return SharedStorageWriteOperationAndResult( + request_origin, OperationType::kAppend, std::move(key), std::move(value), + /*ignore_if_present=*/absl::nullopt, result); +} + +// static +SharedStorageWriteOperationAndResult +SharedStorageWriteOperationAndResult::DeleteOperation( + const url::Origin& request_origin, + std::string key, + OperationResult result) { + return SharedStorageWriteOperationAndResult( + request_origin, OperationType::kDelete, std::move(key), + /*value=*/absl::nullopt, + /*ignore_if_present=*/absl::nullopt, result); +} + +// static +SharedStorageWriteOperationAndResult +SharedStorageWriteOperationAndResult::ClearOperation( + const url::Origin& request_origin, + OperationResult result) { + return SharedStorageWriteOperationAndResult( + request_origin, OperationType::kClear, + /*key=*/absl::nullopt, + /*value=*/absl::nullopt, + /*ignore_if_present=*/absl::nullopt, result); +} + +SharedStorageWriteOperationAndResult::SharedStorageWriteOperationAndResult( + const url::Origin& request_origin, + OperationType operation_type, + absl::optional<std::string> key, + absl::optional<std::string> value, + absl::optional<bool> ignore_if_present, + OperationResult result) + : request_origin(request_origin), + operation_type(operation_type), + key(std::move(key)), + value(std::move(value)), + ignore_if_present(ignore_if_present), + result(result) {} + +SharedStorageWriteOperationAndResult::SharedStorageWriteOperationAndResult( + const url::Origin& request_origin, + OperationType operation_type, + absl::optional<std::string> key, + absl::optional<std::string> value, + network::mojom::OptionalBool ignore_if_present, + OperationResult result) + : SharedStorageWriteOperationAndResult( + request_origin, + operation_type, + std::move(key), + std::move(value), + MojomToAbslOptionalBool(ignore_if_present), + result) {} + +SharedStorageWriteOperationAndResult::SharedStorageWriteOperationAndResult( + const url::Origin& request_origin, + OperationPtr operation, + OperationResult result) + : SharedStorageWriteOperationAndResult(request_origin, + operation->type, + std::move(operation->key), + std::move(operation->value), + operation->ignore_if_present, + result) {} + +SharedStorageWriteOperationAndResult::SharedStorageWriteOperationAndResult( + const SharedStorageWriteOperationAndResult&) = default; + +SharedStorageWriteOperationAndResult::~SharedStorageWriteOperationAndResult() = + default; + +bool operator==(const SharedStorageWriteOperationAndResult& a, + const SharedStorageWriteOperationAndResult& b) { + if (a.request_origin != b.request_origin) { + LOG(ERROR) << "request_origin mismatch: " << a.request_origin.Serialize() + << " <-> " << b.request_origin.Serialize(); + } + if (a.operation_type != b.operation_type) { + LOG(ERROR) << "operation_type mismatch: " + << SharedStorageOperationTypeToString(a.operation_type) + << " <-> " + << SharedStorageOperationTypeToString(b.operation_type); + } + if (a.key != b.key) { + LOG(ERROR) << "key mismatch: " << OptionalStringToString(a.key) << " <-> " + << OptionalStringToString(b.key); + } + if (a.value != b.value) { + LOG(ERROR) << "value mismatch: " << OptionalStringToString(a.value) + << " <-> " << OptionalStringToString(b.value); + } + if (a.ignore_if_present != b.ignore_if_present) { + LOG(ERROR) << "ignore_if_present mismatch: " + << OptionalBoolToString(a.ignore_if_present) << " <-> " + << OptionalBoolToString(b.ignore_if_present); + } + if (a.result != b.result) { + LOG(ERROR) << "result mismatch: " + << SharedStorageOperationResultToString(a.result) << " <-> " + << SharedStorageOperationResultToString(b.result); + } + + return a.request_origin == b.request_origin && + a.operation_type == b.operation_type && a.key == b.key && + a.value == b.value && a.ignore_if_present == b.ignore_if_present && + a.result == b.result; +} + } // namespace content
diff --git a/content/public/test/shared_storage_test_utils.h b/content/public/test/shared_storage_test_utils.h index 7938309..0d628b1 100644 --- a/content/public/test/shared_storage_test_utils.h +++ b/content/public/test/shared_storage_test_utils.h
@@ -8,7 +8,11 @@ #include <stddef.h> #include <string> +#include "components/services/storage/shared_storage/shared_storage_manager.h" +#include "services/network/public/mojom/optional_bool.mojom.h" +#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" #include "third_party/abseil-cpp/absl/types/variant.h" +#include "url/origin.h" class GURL; @@ -19,6 +23,9 @@ class StoragePartition; using FencedFrameNavigationTarget = absl::variant<GURL, std::string>; +using OperationResult = storage::SharedStorageManager::OperationResult; +using OperationType = network::mojom::SharedStorageOperationType; +using OperationPtr = network::mojom::SharedStorageOperationPtr; SharedStorageWorkletHostManager* GetSharedStorageWorkletHostManagerForStoragePartition( @@ -43,6 +50,61 @@ RenderFrameHost* CreateFencedFrame(RenderFrameHost* root, const FencedFrameNavigationTarget& target); +[[nodiscard]] network::mojom::OptionalBool AbslToMojomOptionalBool( + absl::optional<bool> opt_bool); + +// In order to use gmock matchers, it's necessary to copy the members of +// `OperationPtr` into a copyable struct or tuple. We also bundle them with the +// `request_origin` and `result`. +struct SharedStorageWriteOperationAndResult { + static SharedStorageWriteOperationAndResult SetOperation( + const url::Origin& request_origin, + std::string key, + std::string value, + absl::optional<bool> ignore_if_present, + OperationResult result); + static SharedStorageWriteOperationAndResult AppendOperation( + const url::Origin& request_origin, + std::string key, + std::string value, + OperationResult result); + static SharedStorageWriteOperationAndResult DeleteOperation( + const url::Origin& request_origin, + std::string key, + OperationResult result); + static SharedStorageWriteOperationAndResult ClearOperation( + const url::Origin& request_origin, + OperationResult result); + SharedStorageWriteOperationAndResult(const url::Origin& request_origin, + OperationType operation_type, + absl::optional<std::string> key, + absl::optional<std::string> value, + absl::optional<bool> ignore_if_present, + OperationResult result); + SharedStorageWriteOperationAndResult( + const url::Origin& request_origin, + OperationType operation_type, + absl::optional<std::string> key, + absl::optional<std::string> value, + network::mojom::OptionalBool ignore_if_present, + OperationResult result); + SharedStorageWriteOperationAndResult(const url::Origin& request_origin, + OperationPtr operation, + OperationResult result); + SharedStorageWriteOperationAndResult( + const SharedStorageWriteOperationAndResult&); + ~SharedStorageWriteOperationAndResult(); + url::Origin request_origin; + OperationType operation_type; + absl::optional<std::string> key; + absl::optional<std::string> value; + absl::optional<bool> ignore_if_present; + OperationResult result; +}; + +bool operator==(const SharedStorageWriteOperationAndResult& a, + const SharedStorageWriteOperationAndResult& b); + } // namespace content #endif // CONTENT_PUBLIC_TEST_SHARED_STORAGE_TEST_UTILS_H_
diff --git a/content/public/test/test_shared_storage_header_observer.cc b/content/public/test/test_shared_storage_header_observer.cc new file mode 100644 index 0000000..36c4a2e --- /dev/null +++ b/content/public/test/test_shared_storage_header_observer.cc
@@ -0,0 +1,56 @@ +// 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 "content/public/test/test_shared_storage_header_observer.h" + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/run_loop.h" +#include "components/services/storage/shared_storage/shared_storage_manager.h" +#include "content/browser/shared_storage/shared_storage_header_observer.h" +#include "content/browser/storage_partition_impl.h" +#include "content/public/test/shared_storage_test_utils.h" +#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" + +namespace content { + +TestSharedStorageHeaderObserver::TestSharedStorageHeaderObserver( + StoragePartition* storage_partition) + : SharedStorageHeaderObserver( + static_cast<StoragePartitionImpl*>(storage_partition)) {} + +TestSharedStorageHeaderObserver::~TestSharedStorageHeaderObserver() = default; + +void TestSharedStorageHeaderObserver::WaitForOperations(size_t expected_total) { + DCHECK(!loop_); + if (operations_.size() >= expected_total) { + return; + } + expected_total_ = expected_total; + loop_ = std::make_unique<base::RunLoop>(); + loop_->Run(); + loop_.reset(); +} + +void TestSharedStorageHeaderObserver::OnHeaderProcessed( + const url::Origin& request_origin, + const std::vector<bool>& header_results) { + header_results_.emplace_back(request_origin, header_results); +} + +void TestSharedStorageHeaderObserver::OnOperationFinished( + const url::Origin& request_origin, + OperationPtr operation, + OperationResult result) { + operations_.emplace_back(request_origin, std::move(operation), result); + + if (loop_ && loop_->running() && operations_.size() >= expected_total_) { + loop_->Quit(); + } +} + +} // namespace content
diff --git a/content/public/test/test_shared_storage_header_observer.h b/content/public/test/test_shared_storage_header_observer.h new file mode 100644 index 0000000..93d7be1 --- /dev/null +++ b/content/public/test/test_shared_storage_header_observer.h
@@ -0,0 +1,67 @@ +// 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 CONTENT_PUBLIC_TEST_TEST_SHARED_STORAGE_HEADER_OBSERVER_H_ +#define CONTENT_PUBLIC_TEST_TEST_SHARED_STORAGE_HEADER_OBSERVER_H_ + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/memory/weak_ptr.h" +#include "base/run_loop.h" +#include "components/services/storage/shared_storage/shared_storage_manager.h" +#include "content/browser/shared_storage/shared_storage_header_observer.h" +#include "content/public/test/shared_storage_test_utils.h" +#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h" +#include "url/origin.h" + +namespace content { + +using OperationResult = storage::SharedStorageManager::OperationResult; +using OperationType = network::mojom::SharedStorageOperationType; +using OperationPtr = network::mojom::SharedStorageOperationPtr; + +class StoragePartition; + +class TestSharedStorageHeaderObserver : public SharedStorageHeaderObserver { + public: + explicit TestSharedStorageHeaderObserver(StoragePartition* storage_partition); + + ~TestSharedStorageHeaderObserver() override; + + const std::vector<SharedStorageWriteOperationAndResult>& operations() const { + return operations_; + } + + const std::vector<std::pair<url::Origin, std::vector<bool>>>& header_results() + const { + return header_results_; + } + + base::WeakPtr<TestSharedStorageHeaderObserver> GetMutableWeakPtr() const { + return weak_ptr_factory_.GetMutableWeakPtr(); + } + + void WaitForOperations(size_t expected_total); + + private: + // SharedStorageHeaderObserver: + void OnHeaderProcessed(const url::Origin& request_origin, + const std::vector<bool>& header_results) override; + void OnOperationFinished(const url::Origin& request_origin, + OperationPtr operation, + OperationResult result) override; + + std::unique_ptr<base::RunLoop> loop_; + size_t expected_total_; + std::vector<SharedStorageWriteOperationAndResult> operations_; + std::vector<std::pair<url::Origin, std::vector<bool>>> header_results_; + base::WeakPtrFactory<TestSharedStorageHeaderObserver> weak_ptr_factory_{this}; +}; + +} // namespace content + +#endif // CONTENT_PUBLIC_TEST_TEST_SHARED_STORAGE_HEADER_OBSERVER_H_
diff --git a/content/public/test/test_web_ui.cc b/content/public/test/test_web_ui.cc index 0e6d7f4..1a17b54 100644 --- a/content/public/test/test_web_ui.cc +++ b/content/public/test/test_web_ui.cc
@@ -49,7 +49,7 @@ } RenderFrameHost* TestWebUI::GetRenderFrameHost() { - return nullptr; + return render_frame_host_.get(); } void TestWebUI::SetController(std::unique_ptr<WebUIController> controller) {
diff --git a/content/public/test/test_web_ui.h b/content/public/test/test_web_ui.h index c3cc8d9..22aa229 100644 --- a/content/public/test/test_web_ui.h +++ b/content/public/test/test_web_ui.h
@@ -36,6 +36,10 @@ web_contents_ = web_contents; } + void set_render_frame_host(RenderFrameHost* render_frame_host) { + render_frame_host_ = render_frame_host; + } + // WebUI overrides. WebContents* GetWebContents() override; WebUIController* GetController() override; @@ -112,6 +116,7 @@ int bindings_ = 0; std::u16string temp_string_; raw_ptr<WebContents, DanglingUntriaged> web_contents_ = nullptr; + raw_ptr<RenderFrameHost> render_frame_host_ = nullptr; std::unique_ptr<WebUIController> controller_; // Observers to be notified on all javascript calls.
diff --git a/content/renderer/BUILD.gn b/content/renderer/BUILD.gn index 0260ae6a..abf8aa4 100644 --- a/content/renderer/BUILD.gn +++ b/content/renderer/BUILD.gn
@@ -275,7 +275,6 @@ "//media:media_buildflags", "//media/capture", "//media/gpu", - "//media/gpu/ipc/client", "//media/gpu/ipc/common", "//media/midi", "//media/midi:mojo",
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc index 2914dd3..6ed16a5 100644 --- a/content/renderer/media/win/dcomp_texture_wrapper_impl.cc +++ b/content/renderer/media/win/dcomp_texture_wrapper_impl.cc
@@ -218,8 +218,9 @@ // holder. gpu::MailboxHolder holder[media::VideoFrame::kMaxPlanes]; gpu::Mailbox mailbox = sii->CreateSharedImage( - gmb.get(), nullptr, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin, - kPremul_SkAlphaType, usage, "DCOMPTextureWrapperImpl"); + viz::SinglePlaneFormat::kRGBA_8888, natural_size, gfx::ColorSpace(), + kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, usage, + "DCOMPTextureWrapperImpl", gmb->CloneHandle()); gpu::SyncToken sync_token = sii->GenVerifiedSyncToken(); holder[0] = gpu::MailboxHolder(mailbox, sync_token, GL_TEXTURE_2D);
diff --git a/content/renderer/media/win/dcomp_texture_wrapper_unittest.cc b/content/renderer/media/win/dcomp_texture_wrapper_unittest.cc index e36e74ea..7c720edf 100644 --- a/content/renderer/media/win/dcomp_texture_wrapper_unittest.cc +++ b/content/renderer/media/win/dcomp_texture_wrapper_unittest.cc
@@ -29,15 +29,14 @@ StubClientSharedImageInterface() : gpu::ClientSharedImageInterface(nullptr) {} gpu::SyncToken GenVerifiedSyncToken() override { return gpu::SyncToken(); } - gpu::Mailbox CreateSharedImage( - gfx::GpuMemoryBuffer* gpu_memory_buffer, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, - gfx::BufferPlane plane, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - uint32_t usage, - base::StringPiece debug_label) override { + gpu::Mailbox CreateSharedImage(viz::SharedImageFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + GrSurfaceOrigin surface_origin, + SkAlphaType alpha_type, + uint32_t usage, + base::StringPiece debug_label, + gfx::GpuMemoryBufferHandle handle) override { return gpu::Mailbox(); } };
diff --git a/content/renderer/pepper/pepper_video_decoder_host.cc b/content/renderer/pepper/pepper_video_decoder_host.cc index af0cbf31..772351a 100644 --- a/content/renderer/pepper/pepper_video_decoder_host.cc +++ b/content/renderer/pepper/pepper_video_decoder_host.cc
@@ -24,7 +24,6 @@ #include "gpu/ipc/client/command_buffer_proxy_impl.h" #include "media/base/limits.h" #include "media/base/media_util.h" -#include "media/gpu/ipc/client/gpu_video_decode_accelerator_host.h" #include "media/video/video_decode_accelerator.h" #include "ppapi/c/pp_completion_callback.h" #include "ppapi/c/pp_errors.h"
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index 58caad2..a790f20 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -862,8 +862,6 @@ blink::mojom::ServiceWorkerContainerHostInterfaceBase> service_worker_container_host, const blink::WebString& client_id, - blink::mojom::ServiceWorkerFetchHandlerBypassOption - fetch_handler_bypass_option, std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver, scoped_refptr<base::SequencedTaskRunner> task_runner) { @@ -871,7 +869,7 @@ base::MakeRefCounted<ControllerServiceWorkerConnector>( std::move(service_worker_container_host), /*remote_controller=*/mojo::NullRemote(), client_id.Utf8(), - fetch_handler_bypass_option), + blink::mojom::ServiceWorkerFetchHandlerBypassOption::kDefault), network::SharedURLLoaderFactory::Create(std::move(fallback_factory)), std::move(receiver), std::move(task_runner)); }
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index 2a01122..278defc 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -193,8 +193,6 @@ blink::mojom::ServiceWorkerContainerHostInterfaceBase> service_worker_container_host, const blink::WebString& client_id, - blink::mojom::ServiceWorkerFetchHandlerBypassOption - fetch_handler_bypass_option, std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver, scoped_refptr<base::SequencedTaskRunner> task_runner) override;
diff --git a/content/services/auction_worklet/bidder_lazy_filler.cc b/content/services/auction_worklet/bidder_lazy_filler.cc index 93e4ee4..3ab8fe1 100644 --- a/content/services/auction_worklet/bidder_lazy_filler.cc +++ b/content/services/auction_worklet/bidder_lazy_filler.cc
@@ -50,20 +50,35 @@ } DCHECK(win_values[1]->IsObject()); v8::Local<v8::Object> prev_ad = win_values[1].As<v8::Object>(); - v8::Local<v8::Value> serialized_metadata; - v8::Local<v8::Value> metadata; // TODO(crbug.com/1448936): Remove this condition logic when we can assume // it is true (30 days after switching to a Chrome version at least this // recent). // If prev_ad has "renderURL" instead of "render_url" it must be the newer // version. In that version the metadata is still kept as serialized JSON // and needs to be parsed again. If it has metadata, parse it. - if (prev_ad->Has(context, render_url_key).FromMaybe(false) && - prev_ad->Get(context, metadata_key).ToLocal(&serialized_metadata) && - serialized_metadata->IsString()) { - if (!v8::JSON::Parse(context, serialized_metadata.As<v8::String>()) - .ToLocal(&metadata) || - !prev_ad->Set(context, metadata_key, metadata).FromMaybe(false)) { + // We also need to provide the render URL in a "render_url" field for + // backward compatibility. + // TODO(crbug.com/1441988): Remove render_url alias when it is no longer + // needed for compatibility. + if (prev_ad->Has(context, render_url_key).FromMaybe(false)) { + v8::Local<v8::Value> serialized_metadata; + v8::Local<v8::Value> metadata; + if (prev_ad->Get(context, metadata_key).ToLocal(&serialized_metadata) && + serialized_metadata->IsString()) { + if (!v8::JSON::Parse(context, serialized_metadata.As<v8::String>()) + .ToLocal(&metadata) || + !prev_ad->Set(context, metadata_key, metadata).FromMaybe(false)) { + return v8::MaybeLocal<v8::Value>(); + } + } + // For compatibility we need to provide the render URL as the "render_url" + // attribute in addition to the "renderURL" attribute. + v8::Local<v8::Value> render_url; + if (!prev_ad->Get(context, render_url_key).ToLocal(&render_url) || + !prev_ad + ->Set(context, v8_helper->CreateStringFromLiteral("render_url"), + render_url) + .FromMaybe(false)) { return v8::MaybeLocal<v8::Value>(); } }
diff --git a/content/services/auction_worklet/bidder_worklet_unittest.cc b/content/services/auction_worklet/bidder_worklet_unittest.cc index 085f119..06c69f5 100644 --- a/content/services/auction_worklet/bidder_worklet_unittest.cc +++ b/content/services/auction_worklet/bidder_worklet_unittest.cc
@@ -3721,40 +3721,43 @@ { CreateWinList(win1), "browserSignals.prevWins", - R"([[200,{"renderURL":"ad1"}]])", + R"([[200,{"renderURL":"ad1","render_url":"ad1"}]])", }, // Make sure it's passed on as an object and not a string. { CreateWinList(win1), "browserSignals.prevWins[0]", - R"([200,{"renderURL":"ad1"}])", + R"([200,{"renderURL":"ad1","render_url":"ad1"}])", }, // Test rounding. { CreateWinList(win2), "browserSignals.prevWins", - R"([[100,{"renderURL":"ad2","metadata":{"key":"value"}}]])", + R"([[100,{"renderURL":"ad2",)" + R"("metadata":{"key":"value"},"render_url":"ad2"}]])", }, // Multiple previous wins. { CreateWinList(win1, win2), "browserSignals.prevWins", - R"([[200,{"renderURL":"ad1"}],)" - R"([100,{"renderURL":"ad2","metadata":{"key":"value"}}]])", + R"([[200,{"renderURL":"ad1","render_url":"ad1"}],)" + R"([100,{"renderURL":"ad2",)" + R"("metadata":{"key":"value"},"render_url":"ad2"}]])", }, // Times are trimmed at 0. { CreateWinList(future_win), "browserSignals.prevWins", - R"([[0,{"renderURL":"future_ad"}]])", + R"([[0,{"renderURL":"future_ad","render_url":"future_ad"}]])", }, // Out of order wins should be sorted. { CreateWinList(win2, future_win, win1), "browserSignals.prevWins", - R"([[200,{"renderURL":"ad1"}],)" - R"([100,{"renderURL":"ad2","metadata":{"key":"value"}}],)" - R"([0,{"renderURL":"future_ad"}]])", + R"([[200,{"renderURL":"ad1","render_url":"ad1"}],)" + R"([100,{"renderURL":"ad2",)" + R"("metadata":{"key":"value"},"render_url":"ad2"}],)" + R"([0,{"renderURL":"future_ad","render_url":"future_ad"}]])", }, };
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index fe4a300f..b1717c6 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -320,6 +320,8 @@ "../public/test/test_renderer_host.cc", "../public/test/test_renderer_host.h", "../public/test/test_select_url_fenced_frame_config_observer.h", + "../public/test/test_shared_storage_header_observer.cc", + "../public/test/test_shared_storage_header_observer.h", "../public/test/test_storage_partition.cc", "../public/test/test_storage_partition.h", "../public/test/test_utils.cc", @@ -2204,7 +2206,6 @@ "../browser/accessibility/browser_accessibility_state_impl_unittest.cc", "../browser/accessibility/browser_accessibility_unittest.cc", "../browser/accessibility/one_shot_accessibility_tree_search_unittest.cc", - "../browser/accessibility/touch_passthrough_manager_unittest.cc", "../browser/aggregation_service/aggregatable_report_assembler_unittest.cc", "../browser/aggregation_service/aggregatable_report_scheduler_unittest.cc", "../browser/aggregation_service/aggregatable_report_sender_unittest.cc", @@ -2596,6 +2597,7 @@ "../browser/service_worker/service_worker_updated_script_loader_unittest.cc", "../browser/service_worker/service_worker_version_unittest.cc", "../browser/shareable_file_reference_unittest.cc", + "../browser/shared_storage/shared_storage_header_observer_unittest.cc", "../browser/shared_storage/shared_storage_url_loader_factory_proxy_unittest.cc", "../browser/site_instance_group_unittest.cc", "../browser/site_instance_impl_unittest.cc", @@ -2688,6 +2690,7 @@ "../common/input/gesture_event_stream_validator_unittest.cc", "../common/input/touch_event_stream_validator_unittest.cc", "../common/pseudonymization_salt_unittest.cc", + "../common/service_worker/service_worker_router_evaluator_unittest.cc", "../common/url_utils_unittest.cc", "../common/user_agent_unittest.cc", "../common/webid/identity_url_loader_throttle_unittest.cc",
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist index 654f6fa..0d6d523 100644 --- a/content/test/content_test_bundle_data.filelist +++ b/content/test/content_test_bundle_data.filelist
@@ -1495,8 +1495,6 @@ data/accessibility/aria/aria-tooltip-expected-mac.txt data/accessibility/aria/aria-tooltip-expected-win.txt data/accessibility/aria/aria-tooltip.html -data/accessibility/aria/aria-touchpassthrough-expected-blink.txt -data/accessibility/aria/aria-touchpassthrough.html data/accessibility/aria/aria-tree-discontinuous-expected-android-external.txt data/accessibility/aria/aria-tree-discontinuous-expected-android.txt data/accessibility/aria/aria-tree-discontinuous-expected-auralinux.txt @@ -2452,7 +2450,6 @@ data/accessibility/form-controls/role-group.html data/accessibility/fullscreen/iframe.html data/accessibility/fullscreen/links.html -data/accessibility/hit_testing/aria_touchpassthrough_key.html data/accessibility/hit_testing/input-color-with-popup-open.html data/accessibility/hit_testing/simple_rectangles.html data/accessibility/hit_testing/simple_rectangles_iframe.html @@ -5144,6 +5141,7 @@ data/attribution_reporting/interop/multiple_destinations.json data/attribution_reporting/interop/rate_limit_max_attribution_reporting_endpoints.json data/attribution_reporting/interop/rate_limit_max_attributions.json +data/attribution_reporting/interop/rate_limit_max_reporting_origins_per_source_reporting_site.json data/attribution_reporting/interop/rate_limit_max_source_registration_reporting_origin_endpoints.json data/attribution_reporting/interop/same_destination_site.json data/attribution_reporting/interop/same_reporting_origin.json
diff --git a/content/test/content_test_suite.cc b/content/test/content_test_suite.cc index 8f5ed3e..70b1117e 100644 --- a/content/test/content_test_suite.cc +++ b/content/test/content_test_suite.cc
@@ -47,7 +47,7 @@ InitializeResourceBundle(); - ForceInProcessNetworkService(true); + ForceInProcessNetworkService(); ContentTestSuiteBase::Initialize(); {
diff --git a/content/test/data/accessibility/aria/aria-touchpassthrough-expected-blink.txt b/content/test/data/accessibility/aria/aria-touchpassthrough-expected-blink.txt deleted file mode 100644 index 7aa8e6e2..0000000 --- a/content/test/data/accessibility/aria/aria-touchpassthrough-expected-blink.txt +++ /dev/null
@@ -1,5 +0,0 @@ -rootWebArea -++genericContainer ignored -++++genericContainer -++++++canvas name='c1' -++++++canvas name='c2' touchPassthrough=true
diff --git a/content/test/data/accessibility/aria/aria-touchpassthrough.html b/content/test/data/accessibility/aria/aria-touchpassthrough.html deleted file mode 100644 index 791b8234..0000000 --- a/content/test/data/accessibility/aria/aria-touchpassthrough.html +++ /dev/null
@@ -1,10 +0,0 @@ -<!-- -@BLINK-ALLOW:touchPassthrough* ---> -<!DOCTYPE html> -<html> -<body> - <canvas width=400 height=100 aria-label="c1"></canvas> - <canvas width=400 height=100 aria-label="c2" aria-touchpassthrough="true"></canvas> -</body> -</html>
diff --git a/content/test/data/accessibility/hit_testing/aria_touchpassthrough_key.html b/content/test/data/accessibility/hit_testing/aria_touchpassthrough_key.html deleted file mode 100644 index 95f0319..0000000 --- a/content/test/data/accessibility/hit_testing/aria_touchpassthrough_key.html +++ /dev/null
@@ -1,82 +0,0 @@ -<html lang="en"> - <head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - - <title>Aria-touchpassthrough Keypad</title> - - <style> - button { - margin: 3px; - border: 1px solid #999; - border-radius: 10px; - display: inline-block; - text-align: center; - } - - .key { - width: 60px; - height: 30px; - } - - .enter { - width: 200px; - height: 40px; - } - - input { - font-size: 16pt; - width: 200px; - margin: 5px; - } - </style> - - </head> - <body> - - <div> - <input autofocus id="entry"> - </div> - - <div class="keypad"> - <div class="row"> - <button class="key" aria-touchpassthrough="true">1</button> - <button class="key" aria-touchpassthrough="true">2</button> - <button class="key" aria-touchpassthrough="true">3</button> - </div> - <div class="row"> - <button class="key" aria-touchpassthrough="true">4</button> - <button class="key" aria-touchpassthrough="true">5</button> - <button class="key" aria-touchpassthrough="true">6</button> - </div> - <div class="row"> - <button class="key" aria-touchpassthrough="true">7</button> - <button class="key" aria-touchpassthrough="true">8</button> - <button class="key" aria-touchpassthrough="true">9</button> - </div> - <div class="row"> - <button class="key" aria-touchpassthrough="true">*</button> - <button class="key" aria-touchpassthrough="true">0</button> - <button class="key" aria-touchpassthrough="true">x</button> - </div> - <div class="row"> - <button class="enter" id="dial">Dial</button> - </div> - </div> - - <script> - let entry = document.getElementById('entry'); - document.querySelectorAll('button.key').forEach((e) => { - e.addEventListener('click', () => { - let key = e.innerText; - if (key == 'x') { - entry.value = entry.value.substr(0, entry.value.length - 1); - } else { - entry.value += key; - } - entry.focus(); - }); - }); - </script> - </body> -</html>
diff --git a/content/test/data/attribution_reporting/interop/default_config.json b/content/test/data/attribution_reporting/interop/default_config.json index 3303534..8acf539 100644 --- a/content/test/data/attribution_reporting/interop/default_config.json +++ b/content/test/data/attribution_reporting/interop/default_config.json
@@ -5,6 +5,7 @@ "rate_limit_max_source_registration_reporting_origins": "100", "rate_limit_max_attribution_reporting_origins": "10", "rate_limit_max_attributions": "100", + "rate_limit_max_reporting_origins_per_source_reporting_site": "1", "navigation_source_trigger_data_cardinality": "8", "event_source_trigger_data_cardinality": "2", "randomized_response_epsilon": "14",
diff --git a/content/test/data/attribution_reporting/interop/rate_limit_max_attribution_reporting_endpoints.json b/content/test/data/attribution_reporting/interop/rate_limit_max_attribution_reporting_endpoints.json index abbb6351..f879694 100644 --- a/content/test/data/attribution_reporting/interop/rate_limit_max_attribution_reporting_endpoints.json +++ b/content/test/data/attribution_reporting/interop/rate_limit_max_attribution_reporting_endpoints.json
@@ -1,7 +1,8 @@ { "description": "Max attribution reporting endpoints per rate-limit window", "api_config": { - "rate_limit_max_attribution_reporting_origins": "1" + "rate_limit_max_attribution_reporting_origins": "1", + "rate_limit_max_reporting_origins_per_source_reporting_site": "2" }, "input": { "sources": [ @@ -22,7 +23,6 @@ } }] }, - // Will not be registered due to the origin per reporting site restriction. { "timestamp": "1643235573000", "registration_request": { @@ -32,15 +32,13 @@ }, "responses": [{ "url": "https://reporter.test/register-source", - "debug_permission": true, "response": { "Attribution-Reporting-Register-Source": { "destination": [ "https://example.destination.test", "https://another-destination.test" ], - "source_event_id": "111", - "debug_reporting": true + "source_event_id": "111" } } }] @@ -142,7 +140,6 @@ } }] }, - // Won't result in a report as the source wasn't registered. { "timestamp": "1643235574000", "registration_request": { @@ -162,7 +159,8 @@ } }] }, - // Will result in a report. + // Should not result in an event-level report due to the reporting origin + // limit. { "timestamp": "1643235576000", "registration_request": { @@ -275,63 +273,83 @@ ] }, "output": { - "event_level_results": [ { - "payload": { - "attribution_destination": "https://another-destination.test", - "randomized_trigger_rate": 0.0024263, - "scheduled_report_time": "1643411979", - "source_event_id": "333", - "source_type": "navigation", - "trigger_data": "5" - }, - "report_time": "1643411979000", - "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-event-attribution" - },{ - "payload": { - "attribution_destination": "https://destination.test", - "randomized_trigger_rate": 0.0024263, - "scheduled_report_time": "1643411975", - "source_event_id": "999", - "source_type": "navigation", - "trigger_data": "2" - }, - "report_time": "1643411975000", - "report_url": "https://example.reporter.test/.well-known/attribution-reporting/report-event-attribution" - }, { - "payload": { - "attribution_destination": "https://destination.test", - "randomized_trigger_rate": 0.0024263, - "scheduled_report_time": "1643411977", - "source_event_id": "222", - "source_type": "navigation", - "trigger_data": "6" - }, - "report_time": "1643411977000", - "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-event-attribution" - } ], - "verbose_debug_reports": [ { - "payload": [ { - "body": { - "attribution_destination": "https://destination.test", - "limit": "1", - "source_event_id": "444", - "source_site": "https://source.test" - }, - "type": "trigger-reporting-origin-limit" - } ], - "report_time": "1643235582000", - "report_url": "https://another-reporter.test/.well-known/attribution-reporting/debug/verbose" - }, { - "payload": [ { - "body": { + "event_level_results": [ + { + "payload": { "attribution_destination": [ "https://another-destination.test", "https://destination.test" ], + "randomized_trigger_rate": 0.0024263, + "scheduled_report_time": "1643411973", "source_event_id": "111", - "source_site": "https://source.test" + "source_type": "navigation", + "trigger_data": "7" }, - "type": "source-success" - } ], - "report_time": "1643235573000", - "report_url": "https://reporter.test/.well-known/attribution-reporting/debug/verbose" - } ] + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411973000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024263, + "scheduled_report_time": "1643411977", + "source_event_id": "222", + "source_type": "navigation", + "trigger_data": "6" + }, + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411977000" + }, + { + "payload": { + "attribution_destination": "https://another-destination.test", + "randomized_trigger_rate": 0.0024263, + "scheduled_report_time": "1643411979", + "source_event_id": "333", + "source_type": "navigation", + "trigger_data": "5" + }, + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411979000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0000025, + "scheduled_report_time": "1645831181", + "source_event_id": "444", + "source_type": "event", + "trigger_data": "1" + }, + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1645831181000" + } + ], + "verbose_debug_reports": [ + { + "payload": [ { + "body": { + "attribution_destination": "https://destination.test", + "limit": "1", + "source_event_id": "999", + "source_site": "https://source.test" + }, + "type": "trigger-reporting-origin-limit" + } ], + "report_time": "1643235576000", + "report_url": "https://example.reporter.test/.well-known/attribution-reporting/debug/verbose" + }, + { + "payload": [ { + "body": { + "attribution_destination": "https://destination.test", + "limit": "1", + "source_event_id": "444", + "source_site": "https://source.test" + }, + "type": "trigger-reporting-origin-limit" + } ], + "report_time": "1643235582000", + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/debug/verbose" + } + ] } }
diff --git a/content/test/data/attribution_reporting/interop/rate_limit_max_reporting_origins_per_source_reporting_site.json b/content/test/data/attribution_reporting/interop/rate_limit_max_reporting_origins_per_source_reporting_site.json new file mode 100644 index 0000000..f21e858 --- /dev/null +++ b/content/test/data/attribution_reporting/interop/rate_limit_max_reporting_origins_per_source_reporting_site.json
@@ -0,0 +1,271 @@ +{ + "description": "Max reporting origins per source site and reporting site", + "input": { + "sources": [ + { + "timestamp": "1643235573000", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "source_event_id": "111", + "debug_reporting": true + } + } + }] + }, + // Will be registered as the reporting site is different. + { + "timestamp": "1643235573001", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://another-reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://another-reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "source_event_id": "222", + "debug_reporting": true + } + } + }] + }, + // Will be registered as the source site is different. + { + "timestamp": "1643235573002", + "registration_request": { + "source_origin": "https://another-source.test", + "attribution_src_url": "https://a.reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://a.reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "source_event_id": "333", + "debug_reporting": true + } + } + }] + }, + // Will not be registered due to the limit. + { + "timestamp": "1643321972999", + "registration_request": { + "source_origin": "https://b.source.test", + "attribution_src_url": "https://b.reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://b.reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "source_event_id": "444", + "priority": "1", + "debug_reporting": true + } + } + }] + }, + // Will be registered as one day has passed. + { + "timestamp": "1643321973000", + "registration_request": { + "source_origin": "https://b.source.test", + "attribution_src_url": "https://b.reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://b.reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "source_event_id": "555", + "debug_reporting": true + } + } + }] + } + ], + "triggers": [ + // Will result in an event-level report. + { + "timestamp": "1643235574000", + "registration_request": { + "attribution_src_url": "https://another-reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://another-reporter.test/register-trigger", + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "1" + } + ] + } + } + }] + }, + // Will result in an event-level report. + { + "timestamp": "1643235574001", + "registration_request": { + "attribution_src_url": "https://a.reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://a.reporter.test/register-trigger", + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "2" + } + ] + } + } + }] + }, + // Will result in an event-level report. + { + "timestamp": "1643321974000", + "registration_request": { + "attribution_src_url": "https://b.reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://b.reporter.test/register-trigger", + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "4" + } + ] + } + } + }] + } + ] + }, + "output": { + "event_level_results": [ + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024263, + "scheduled_report_time": "1643411973", + "source_event_id": "222", + "source_type": "navigation", + "trigger_data": "1" + }, + "report_time": "1643411973001", + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-event-attribution" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024263, + "scheduled_report_time": "1643411973", + "source_event_id": "333", + "source_type": "navigation", + "trigger_data": "2" + }, + "report_time": "1643411973002", + "report_url": "https://a.reporter.test/.well-known/attribution-reporting/report-event-attribution" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024263, + "scheduled_report_time": "1643498373", + "source_event_id": "555", + "source_type": "navigation", + "trigger_data": "4" + }, + "report_time": "1643498373000", + "report_url": "https://b.reporter.test/.well-known/attribution-reporting/report-event-attribution" + } + ], + "verbose_debug_reports": [ + { + "payload": [ { + "body": { + "attribution_destination": "https://destination.test", + "source_event_id": "111", + "source_site": "https://source.test" + }, + "type": "source-success" + } ], + "report_time": "1643235573000", + "report_url": "https://reporter.test/.well-known/attribution-reporting/debug/verbose" + }, + { + "payload": [ { + "body": { + "attribution_destination": "https://destination.test", + "source_event_id": "222", + "source_site": "https://source.test" + }, + "type": "source-success" + } ], + "report_time": "1643235573001", + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/debug/verbose" + }, + { + "payload": [ { + "body": { + "attribution_destination": "https://destination.test", + "source_event_id": "333", + "source_site": "https://another-source.test" + }, + "type": "source-success" + } ], + "report_time": "1643235573002", + "report_url": "https://a.reporter.test/.well-known/attribution-reporting/debug/verbose" + }, + { + "payload": [ { + "body": { + "attribution_destination": "https://destination.test", + "source_event_id": "444", + "source_site": "https://source.test" + }, + "type": "source-success" + } ], + "report_time": "1643321972999", + "report_url": "https://b.reporter.test/.well-known/attribution-reporting/debug/verbose" + }, + { + "payload": [ { + "body": { + "attribution_destination": "https://destination.test", + "source_event_id": "555", + "source_site": "https://source.test" + }, + "type": "source-success" + } ], + "report_time": "1643321973000", + "report_url": "https://b.reporter.test/.well-known/attribution-reporting/debug/verbose" + } + ] + } +}
diff --git a/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc b/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc index 6a30fdc..202ae7d 100644 --- a/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc +++ b/content/test/fuzzer/presentation_service_mojolpm_fuzzer.cc
@@ -9,6 +9,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" +#include "base/memory/raw_ref.h" #include "base/no_destructor.h" #include "base/run_loop.h" #include "base/task/sequenced_task_runner.h" @@ -104,7 +105,8 @@ void TestBody() override {} // The proto message describing the test actions to perform. - const content::fuzzing::presentation_service::proto::Testcase& testcase_; + const raw_ref<const content::fuzzing::presentation_service::proto::Testcase> + testcase_; // Apply a reasonable upper-bound on testcase complexity to avoid timeouts. const int max_action_count_ = 512; @@ -149,20 +151,20 @@ } bool PresentationServiceTestcase::IsFinished() { - return next_sequence_idx_ >= testcase_.sequence_indexes_size(); + return next_sequence_idx_ >= testcase_->sequence_indexes_size(); } void PresentationServiceTestcase::NextAction() { - if (next_sequence_idx_ < testcase_.sequence_indexes_size()) { - auto sequence_idx = testcase_.sequence_indexes(next_sequence_idx_++); + if (next_sequence_idx_ < testcase_->sequence_indexes_size()) { + auto sequence_idx = testcase_->sequence_indexes(next_sequence_idx_++); const auto& sequence = - testcase_.sequences(sequence_idx % testcase_.sequences_size()); + testcase_->sequences(sequence_idx % testcase_->sequences_size()); for (auto action_idx : sequence.action_indexes()) { - if (!testcase_.actions_size() || ++action_count_ > max_action_count_) { + if (!testcase_->actions_size() || ++action_count_ > max_action_count_) { return; } const auto& action = - testcase_.actions(action_idx % testcase_.actions_size()); + testcase_->actions(action_idx % testcase_->actions_size()); if (action.ByteSizeLong() > max_action_size_) { return; }
diff --git a/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc b/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc index 03531e7..40544eb 100644 --- a/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc +++ b/content/test/fuzzer/video_capture_host_mojolpm_fuzzer.cc
@@ -9,6 +9,7 @@ #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" +#include "base/memory/raw_ref.h" #include "base/no_destructor.h" #include "base/run_loop.h" #include "base/task/sequenced_task_runner.h" @@ -176,7 +177,8 @@ uint32_t device_index); // The proto message describing the test actions to perform. - const content::fuzzing::video_capture_host::proto::Testcase& testcase_; + const raw_ref<const content::fuzzing::video_capture_host::proto::Testcase> + testcase_; // Apply a reasonable upper-bound on testcase complexity to avoid timeouts. const int max_action_count_ = 512; @@ -240,21 +242,21 @@ bool VideoCaptureHostTestcase::IsFinished() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - return next_sequence_idx_ >= testcase_.sequence_indexes_size(); + return next_sequence_idx_ >= testcase_->sequence_indexes_size(); } void VideoCaptureHostTestcase::NextAction() { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (next_sequence_idx_ < testcase_.sequence_indexes_size()) { - auto sequence_idx = testcase_.sequence_indexes(next_sequence_idx_++); + if (next_sequence_idx_ < testcase_->sequence_indexes_size()) { + auto sequence_idx = testcase_->sequence_indexes(next_sequence_idx_++); const auto& sequence = - testcase_.sequences(sequence_idx % testcase_.sequences_size()); + testcase_->sequences(sequence_idx % testcase_->sequences_size()); for (auto action_idx : sequence.action_indexes()) { - if (!testcase_.actions_size() || ++action_count_ > max_action_count_) { + if (!testcase_->actions_size() || ++action_count_ > max_action_count_) { return; } const auto& action = - testcase_.actions(action_idx % testcase_.actions_size()); + testcase_->actions(action_idx % testcase_->actions_size()); if (action.ByteSizeLong() > max_action_size_) { return; }
diff --git a/content/test/gpu/PRESUBMIT.py b/content/test/gpu/PRESUBMIT.py index 2772dbd..bc858a1 100644 --- a/content/test/gpu/PRESUBMIT.py +++ b/content/test/gpu/PRESUBMIT.py
@@ -64,10 +64,7 @@ output_api, input_api.os_path.join(input_api.PresubmitLocalPath(), 'unexpected_passes'), [r'^.+_unittest\.py$'], - env=_GetGpuEnv(input_api), - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + env=_GetGpuEnv(input_api)) def CheckFlakeSuppressorUnittests(input_api, output_api): @@ -77,10 +74,7 @@ output_api, input_api.os_path.join(input_api.PresubmitLocalPath(), 'flake_suppressor'), [r'^.+_unittest\.py$'], - env=_GetGpuEnv(input_api), - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + env=_GetGpuEnv(input_api)) def CheckValidateTagConsistency(input_api, output_api): @@ -91,8 +85,7 @@ 'validate_tag_consistency.py', 'validate' ], kwargs={}, - message=output_api.PresubmitError, - python3=True) + message=output_api.PresubmitError) return input_api.RunTests([command])
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt index 9b29527..031feba 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl2_conformance_expectations.txt
@@ -709,8 +709,6 @@ crbug.com/1143323 [ android android-pixel-2 passthrough ] conformance/rendering/draw-arrays-out-of-bounds.html [ Failure ] crbug.com/1276186 [ android android-pixel-2 ] conformance2/glsl3/array-equality.html [ Failure ] crbug.com/angleproject/7421 [ android android-pixel-2 angle-disabled no-passthrough ] conformance2/renderbuffers/invalidate-framebuffer.html [ Failure ] -crbug.com/1405252 [ android android-pixel-2 ] conformance/extensions/webgl-compressed-texture-etc.html [ Failure ] -crbug.com/1405252 [ android android-pixel-2 ] conformance/extensions/webgl-compressed-texture-etc1.html [ Failure ] ## Pixel 4 ## @@ -810,10 +808,6 @@ crbug.com/1441195 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/extensions/oes-draw-buffers-indexed.html [ Failure ] crbug.com/1441195 [ chromeos chromeos-board-kevin no-passthrough ] conformance2/rendering/framebuffer-mismatched-attachment-targets.html [ Failure ] -crbug.com/1405252 [ chromeos chromeos-board-kevin no-passthrough ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] -crbug.com/1405252 [ chromeos chromeos-board-kevin no-passthrough ] conformance/extensions/webgl-compressed-texture-etc.html [ Failure ] -crbug.com/1405252 [ chromeos chromeos-board-kevin no-passthrough ] conformance/extensions/webgl-compressed-texture-etc1.html [ Failure ] - crbug.com/1232106 [ chromeos chromeos-board-amd64-generic no-passthrough ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] crbug.com/1232118 [ angle-opengles chromeos chromeos-board-amd64-generic passthrough ] conformance/uniforms/uniform-samplers-test.html [ Failure ] crbug.com/1238075 [ chromeos chromeos-board-amd64-generic ] conformance/rendering/gl-scissor-test.html [ Failure ] @@ -851,7 +845,6 @@ crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/rendering/blitframebuffer-r11f-g11f-b10f.html [ Failure ] crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/textures/misc/immutable-tex-render-feedback.html [ Failure ] crbug.com/1446435 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/transform_feedback/transform_feedback.html [ Failure ] -crbug.com/1450357 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/texture-bias.html [ Failure ] ############################## # Lacros-like Linux Failures # @@ -906,6 +899,10 @@ #[ highsierra nvidia debug angle-opengl ] WebglExtension_test_10 [ Failure ] #[ mac nvidia debug angle-opengl ] WebglExtension_test_10 [ Failure ] +############################### +# New failures in WebGL rolls # +############################### + # Roll WebGL d1b65aa..b934957. crbug.com/1448567 [ android ] conformance2/transform_feedback/simultaneous_binding.html [ Failure ] crbug.com/1448567 [ chromeos ] conformance2/transform_feedback/simultaneous_binding.html [ Failure ] @@ -915,7 +912,14 @@ crbug.com/1448567 [ win ] conformance2/transform_feedback/simultaneous_binding.html [ Failure ] crbug.com/1448570 [ android-pixel-4 ] conformance/extensions/webgl-compressed-texture-etc.html [ Failure ] crbug.com/1448570 [ android-pixel-4 ] conformance/extensions/webgl-compressed-texture-etc1.html [ Failure ] +crbug.com/1448570 [ android android-pixel-2 ] conformance/extensions/webgl-compressed-texture-etc.html [ Failure ] +crbug.com/1448570 [ android android-pixel-2 ] conformance/extensions/webgl-compressed-texture-etc1.html [ Failure ] +crbug.com/1405252 [ chromeos chromeos-board-kevin no-passthrough ] conformance/extensions/webgl-compressed-texture-astc.html [ Failure ] +crbug.com/1405252 [ chromeos chromeos-board-kevin no-passthrough ] conformance/extensions/webgl-compressed-texture-etc.html [ Failure ] +crbug.com/1405252 [ chromeos chromeos-board-kevin no-passthrough ] conformance/extensions/webgl-compressed-texture-etc1.html [ Failure ] crbug.com/1448569 [ win angle-d3d11 ] conformance2/glsl3/texture-bias.html [ Failure ] +crbug.com/1450357 [ chromeos lacros-chrome chromeos-board-jacuzzi passthrough ] conformance2/glsl3/texture-bias.html [ Failure ] +crbug.com/1450367 [ chromeos chromeos-board-amd64-generic passthrough ] conformance2/extensions/webgl-clip-cull-distance.html [ Failure ] ####################################################################### # Automated Entries After This Point - Do Not Manually Add Below Here #
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index c33875da..c3f50ab 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -364,7 +364,6 @@ # they are not attributed to some known issue that needs resolving. crbug.com/1441710 [ chromeos chromeos-board-kevin ] conformance/glsl/bugs/temp-expressions-should-not-crash.html [ Slow ] -crbug.com/1450358 [ chromeos chromeos-board-kevin ] conformance/textures/misc/texture-srgb-upload.html [ Slow ] ################### # Failures/Flakes # @@ -702,9 +701,15 @@ crbug.com/angleproject/5038 [ linux intel display-server-wayland ] conformance/extensions/ext-color-buffer-half-float.html [ Failure ] +############################### +# New failures in WebGL rolls # +############################### + # Roll WebGL d1b65aa..b934957. crbug.com/1448573 [ android ] conformance/extensions/oes-texture-float.html [ Failure ] -crbug.com/1448743 [ android-nexus-5x ] conformance/textures/misc/texture-srgb-upload.html [ Skip ] +crbug.com/1448573 [ chromeos chromeos-board-amd64-generic ] conformance/extensions/oes-texture-float.html [ Failure ] +crbug.com/1448743 [ android-nexus-5x ] conformance/textures/misc/texture-srgb-upload.html [ Failure ] +crbug.com/1448743 [ chromeos chromeos-board-amd64-generic ] conformance/textures/misc/texture-srgb-upload.html [ Failure ] crbug.com/1448643 [ win angle-d3d11 ] conformance/uniforms/out-of-bounds-uniform-array-access.html [ Failure ] #######################################################################
diff --git a/content/test/web_ui/BUILD.gn b/content/test/web_ui/BUILD.gn index f2c197a3..8844391c2 100644 --- a/content/test/web_ui/BUILD.gn +++ b/content/test/web_ui/BUILD.gn
@@ -18,7 +18,7 @@ source = "webui_js_bridge_unittest2.test-mojom" public_deps = [ ":test_secondary_interface" ] - webui_controller = "content::TestWebUIJsBridgeUI" + webui_controller = "content::TestWebUIJsBridgeUI2" webui_controller_header = "//content/browser/webui/test_webui_js_bridge_ui.h" webui_controller_deps = [ "//content/test:test_support" ] }
diff --git a/device/bluetooth/floss/bluetooth_device_floss.cc b/device/bluetooth/floss/bluetooth_device_floss.cc index 21ff473..95475f6 100644 --- a/device/bluetooth/floss/bluetooth_device_floss.cc +++ b/device/bluetooth/floss/bluetooth_device_floss.cc
@@ -101,27 +101,19 @@ } VendorIDSource BluetoothDeviceFloss::GetVendorIDSource() const { - NOTIMPLEMENTED(); - - return VendorIDSource::VENDOR_ID_UNKNOWN; + return static_cast<VendorIDSource>(vpi_.vendorIdSrc); } uint16_t BluetoothDeviceFloss::GetVendorID() const { - NOTIMPLEMENTED(); - - return 0; + return vpi_.vendorId; } uint16_t BluetoothDeviceFloss::GetProductID() const { - NOTIMPLEMENTED(); - - return 0; + return vpi_.productId; } uint16_t BluetoothDeviceFloss::GetDeviceID() const { - NOTIMPLEMENTED(); - - return 0; + return vpi_.version; } uint16_t BluetoothDeviceFloss::GetAppearance() const { @@ -731,6 +723,18 @@ TriggerInitDevicePropertiesCallback(); } +void BluetoothDeviceFloss::OnGetRemoteVendorProductInfo( + DBusResult<FlossAdapterClient::VendorProductInfo> ret) { + if (ret.has_value()) { + vpi_ = *ret; + } else { + BLUETOOTH_LOG(ERROR) << "GetRemoteVendorProductInfo() failed: " + << ret.error(); + } + + TriggerInitDevicePropertiesCallback(); +} + void BluetoothDeviceFloss::OnConnectAllEnabledProfiles(DBusResult<Void> ret) { if (!ret.has_value()) { BLUETOOTH_LOG(ERROR) << "Failed to connect all enabled profiles: " @@ -840,7 +844,7 @@ // This must be incremented when adding more properties below // and followed up with a TriggerInitDevicePropertiesCallback() // in the callback. - num_pending_properties_ += 4; + num_pending_properties_ += 5; // TODO(b/204708206): Update with property framework when available FlossDBusManager::Get()->GetAdapterClient()->GetRemoteType( base::BindOnce(&BluetoothDeviceFloss::OnGetRemoteType, @@ -858,6 +862,10 @@ base::BindOnce(&BluetoothDeviceFloss::OnGetRemoteUuids, weak_ptr_factory_.GetWeakPtr()), AsFlossDeviceId()); + FlossDBusManager::Get()->GetAdapterClient()->GetRemoteVendorProductInfo( + base::BindOnce(&BluetoothDeviceFloss::OnGetRemoteVendorProductInfo, + weak_ptr_factory_.GetWeakPtr()), + AsFlossDeviceId()); } void BluetoothDeviceFloss::TriggerInitDevicePropertiesCallback() {
diff --git a/device/bluetooth/floss/bluetooth_device_floss.h b/device/bluetooth/floss/bluetooth_device_floss.h index b77db31a..60e3c1ce 100644 --- a/device/bluetooth/floss/bluetooth_device_floss.h +++ b/device/bluetooth/floss/bluetooth_device_floss.h
@@ -205,6 +205,8 @@ void OnGetRemoteType(DBusResult<FlossAdapterClient::BluetoothDeviceType> ret); void OnGetRemoteClass(DBusResult<uint32_t> ret); void OnGetRemoteAppearance(DBusResult<uint16_t> ret); + void OnGetRemoteVendorProductInfo( + DBusResult<FlossAdapterClient::VendorProductInfo> ret); void OnGetRemoteUuids(DBusResult<UUIDList> ret); void OnConnectAllEnabledProfiles(DBusResult<Void> ret); void OnDisconnectAllEnabledProfiles(base::OnceClosure callback, @@ -275,6 +277,10 @@ // TODO(b/204708206): Update with property framework when available uint16_t appearance_ = 0; + // Vendor and product info of device. + // TODO(b/204708206): Update with property framework when available + FlossAdapterClient::VendorProductInfo vpi_; + // Whether the device is bonded/paired. FlossAdapterClient::BondState bond_state_ = FlossAdapterClient::BondState::kNotBonded;
diff --git a/device/bluetooth/floss/floss_adapter_client.cc b/device/bluetooth/floss/floss_adapter_client.cc index e089dc9..188c498 100644 --- a/device/bluetooth/floss/floss_adapter_client.cc +++ b/device/bluetooth/floss/floss_adapter_client.cc
@@ -114,6 +114,13 @@ std::move(callback), adapter::kGetRemoteUuids, device); } +void FlossAdapterClient::GetRemoteVendorProductInfo( + ResponseCallback<FlossAdapterClient::VendorProductInfo> callback, + FlossDeviceId device) { + CallAdapterMethod<FlossAdapterClient::VendorProductInfo>( + std::move(callback), adapter::kGetRemoteVendorProductInfo, device); +} + void FlossAdapterClient::GetBondState(ResponseCallback<uint32_t> callback, const FlossDeviceId& device) { CallAdapterMethod<uint32_t>(std::move(callback), adapter::kGetBondState,
diff --git a/device/bluetooth/floss/floss_adapter_client.h b/device/bluetooth/floss/floss_adapter_client.h index dd6e5a5..f5e6898 100644 --- a/device/bluetooth/floss/floss_adapter_client.h +++ b/device/bluetooth/floss/floss_adapter_client.h
@@ -89,6 +89,13 @@ kGeneralDiscoverable = 2, }; + struct VendorProductInfo { + uint8_t vendorIdSrc; + uint16_t vendorId; + uint16_t productId; + uint16_t version; + }; + class Observer : public base::CheckedObserver { public: Observer(const Observer&) = delete; @@ -241,6 +248,10 @@ ResponseCallback<device::BluetoothDevice::UUIDList> callback, FlossDeviceId device); + virtual void GetRemoteVendorProductInfo( + ResponseCallback<VendorProductInfo> callback, + FlossDeviceId device); + // Get bonding state of a device. virtual void GetBondState(ResponseCallback<uint32_t> callback, const FlossDeviceId& device);
diff --git a/device/bluetooth/floss/floss_dbus_client.cc b/device/bluetooth/floss/floss_dbus_client.cc index 0afb5e0..962fe61 100644 --- a/device/bluetooth/floss/floss_dbus_client.cc +++ b/device/bluetooth/floss/floss_dbus_client.cc
@@ -57,6 +57,7 @@ const char kGetRemoteType[] = "GetRemoteType"; const char kGetRemoteClass[] = "GetRemoteClass"; const char kGetRemoteAppearance[] = "GetRemoteAppearance"; +const char kGetRemoteVendorProductInfo[] = "GetRemoteVendorProductInfo"; const char kGetConnectionState[] = "GetConnectionState"; const char kGetRemoteUuids[] = "GetRemoteUuids"; const char kGetBondState[] = "GetBondState"; @@ -393,6 +394,13 @@ } template <> +const DBusTypeInfo& GetDBusTypeInfo( + const FlossAdapterClient::VendorProductInfo*) { + static DBusTypeInfo info{"a{sv}", "VendorProductInfo"}; + return info; +} + +template <> DEVICE_BLUETOOTH_EXPORT const DBusTypeInfo& GetDBusTypeInfo( const device::BluetoothUUID*) { static DBusTypeInfo info{"ay", "BluetoothUUID"}; @@ -632,6 +640,25 @@ return struct_reader.ReadDBusParam(reader, device); } +// static +template <> +bool FlossDBusClient::ReadDBusParam( + dbus::MessageReader* reader, + FlossAdapterClient::VendorProductInfo* vpi) { + static StructReader<FlossAdapterClient::VendorProductInfo> struct_reader({ + {"vendor_id_src", + CreateFieldReader(&FlossAdapterClient::VendorProductInfo::vendorIdSrc)}, + {"vendor_id", + CreateFieldReader(&FlossAdapterClient::VendorProductInfo::vendorId)}, + {"product_id", + CreateFieldReader(&FlossAdapterClient::VendorProductInfo::productId)}, + {"version", + CreateFieldReader(&FlossAdapterClient::VendorProductInfo::version)}, + }); + + return struct_reader.ReadDBusParam(reader, vpi); +} + template <> void FlossDBusClient::WriteDBusParam(dbus::MessageWriter* writer, const FlossDeviceId& device) { @@ -773,6 +800,11 @@ dbus::ErrorResponse* error_response); template void FlossDBusClient::DefaultResponseWithCallback( + ResponseCallback<FlossAdapterClient::VendorProductInfo> callback, + dbus::Response* response, + dbus::ErrorResponse* error_response); + +template void FlossDBusClient::DefaultResponseWithCallback( ResponseCallback<FlossDBusClient::BtifStatus> callback, dbus::Response* response, dbus::ErrorResponse* error_response);
diff --git a/device/bluetooth/floss/floss_dbus_client.h b/device/bluetooth/floss/floss_dbus_client.h index 754e4fc..2199ecb 100644 --- a/device/bluetooth/floss/floss_dbus_client.h +++ b/device/bluetooth/floss/floss_dbus_client.h
@@ -62,6 +62,7 @@ extern DEVICE_BLUETOOTH_EXPORT const char kGetRemoteType[]; extern DEVICE_BLUETOOTH_EXPORT const char kGetRemoteClass[]; extern DEVICE_BLUETOOTH_EXPORT const char kGetRemoteAppearance[]; +extern DEVICE_BLUETOOTH_EXPORT const char kGetRemoteVendorProductInfo[]; extern DEVICE_BLUETOOTH_EXPORT const char kGetConnectionState[]; extern DEVICE_BLUETOOTH_EXPORT const char kGetRemoteUuids[]; extern DEVICE_BLUETOOTH_EXPORT const char kGetBondState[];
diff --git a/device/fido/features.cc b/device/fido/features.cc index ad56369..72ea8b0 100644 --- a/device/fido/features.cc +++ b/device/fido/features.cc
@@ -39,19 +39,6 @@ "WebAuthenticationGoogleCorpRemoteDesktopClientPrivilege", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kWebAuthPasskeysUI, - "WebAuthenticationPasskeysUI", - base::FEATURE_ENABLED_BY_DEFAULT); - -BASE_FEATURE(kWebAuthnPhoneConfirmationSheet, - "WebAuthenticationPhoneConfirmationSheet", - base::FEATURE_ENABLED_BY_DEFAULT); - -// Add in M113. Remove in or after M116. -BASE_FEATURE(kWebAuthnNewPrioritiesImpl, - "WebAuthenticationNewPrioritiesImpl", - base::FEATURE_ENABLED_BY_DEFAULT); - // Added in M114. Not yet enabled by default. BASE_FEATURE(kWebAuthnAndroidCredMan, "WebAuthenticationAndroidCredMan",
diff --git a/device/fido/features.h b/device/fido/features.h index 32dda94..7ddf24c 100644 --- a/device/fido/features.h +++ b/device/fido/features.h
@@ -40,20 +40,6 @@ COMPONENT_EXPORT(DEVICE_FIDO) BASE_DECLARE_FEATURE(kWebAuthnGoogleCorpRemoteDesktopClientPrivilege); -// Enable some experimental UI changes -COMPONENT_EXPORT(DEVICE_FIDO) BASE_DECLARE_FEATURE(kWebAuthPasskeysUI); - -// Show a "Use the passkey from your phone" sheet instead of the mechanism -// selection screen if we are confident a request can be resolved using an -// already paired phone. -COMPONENT_EXPORT(DEVICE_FIDO) -BASE_DECLARE_FEATURE(kWebAuthnPhoneConfirmationSheet); - -// Use the new implementation of mechanism priorities in -// AuthenticatorRequestDialogModel. -COMPONENT_EXPORT(DEVICE_FIDO) -BASE_DECLARE_FEATURE(kWebAuthnNewPrioritiesImpl); - // Use the Android 14 Credential Manager API. COMPONENT_EXPORT(DEVICE_FIDO) BASE_DECLARE_FEATURE(kWebAuthnAndroidCredMan);
diff --git a/device/vr/openxr/openxr_device.cc b/device/vr/openxr/openxr_device.cc index 275c7b4..82e2705 100644 --- a/device/vr/openxr/openxr_device.cc +++ b/device/vr/openxr/openxr_device.cc
@@ -137,7 +137,14 @@ void OpenXrDevice::RequestSession( mojom::XRRuntimeSessionOptionsPtr options, mojom::XRRuntime::RequestSessionCallback callback) { - DCHECK(!request_session_callback_); + // TODO(https://crbug.com/1450707): Strengthen the guarantees from the browser + // process that we will not get a session request while one is pending. + if (request_session_callback_) { + LOG(ERROR) << __func__ + << " New session request while processing previous request."; + std::move(callback).Run(nullptr); + return; + } OpenXrCreateInfo create_info; create_info.render_process_id = options->render_process_id;
diff --git a/docs/python3_migration.md b/docs/python3_migration.md index 3fbdcad..a9f610d 100644 --- a/docs/python3_migration.md +++ b/docs/python3_migration.md
@@ -127,9 +127,7 @@ ### Presubmit checks -Presubmit checks are run using Python 2 by default. To run them using -Python3, add the line `USE_PYTHON3 = True` to the PRESUBMIT.py file in -question (effectively creating a global variable). +Presubmit checks are run using Python 3 by default now. [script_test]: https://source.chromium.org/?q=script_test%20file:testing%2Ftest.gni&ss=chromium [vpython]: https://chromium.googlesource.com/infra/infra/+/refs/heads/main/doc/users/vpython.md
diff --git a/docs/updater/dev_manual.md b/docs/updater/dev_manual.md index 139fcac..426b6be 100644 --- a/docs/updater/dev_manual.md +++ b/docs/updater/dev_manual.md
@@ -134,6 +134,63 @@ ## Building +### Configuring the build + +After creating your build configuration directory via +[`gn gen`](https://chromium.googlesource.com/chromium/src/+/main/docs/linux/build_instructions.md#Setting-up-the-build) +(this step is equivalent across all platforms), you will need to use +[`gn args`](https://www.chromium.org/developers/gn-build-configuration/) to +configure the build appropriately. + +#### Flags required for building successfully + +As of 2023-05-24, the updater cannot be built in component mode. It is also not +specifically designed to be built without the updater being enabled. You must +specify these options to `gn` via `gn args`: + +``` +is_component_build=false +enable_updater=true +``` + +Depending on other configuration options, the default `symbol_level`, 2, might +produce object files too large for the linker to handle (in debug builds). +Partial symbols, via `symbol_level=1`, fix this. Omitting almost all symbols +via `symbol_level=0` reuslts in a smaller and faster build but makes debugging +nearly impossible (call stacks will not be symbolicated). + +#### Faster builds + +Building on Goma is typically much faster than your workstation. After you've +set up Goma, specify it in `gn args` with `use_goma=true`. + +To get started on Goma, and for more information on how to use it, review its +[public documentation](https://chromium.googlesource.com/infra/goma/client/+/HEAD/doc/early-access-guide.md) +or its +[Google-internal documentation](https://go.corp.google.com/how-to-use-goma). + +#### More release-like builds + +Chromium projects build in debug mode by default. Release builds (also called +"opt", or "optimized", builds) are faster to link and run more efficiently; +they are, of course, much harder to debug. For a release build, add the +following to the build configuration's `gn args`: + +``` +is_debug=false +``` + +With a Google `src-internal` checkout, you can create a Chrome-branded build: + +``` +is_chrome_branded=true +include_branded_entitlements=false +``` + +Updater branding affects the path the updater installs itself to, among other +things. Differently-branded copies of Chromium Updater are intended to coexist +on a machine, operating independently from each other. + ### Cleaning the build output Running `ninja` with `t clean` cleans the build out directory. For example: ``` @@ -156,6 +213,16 @@ python3 tools/win/update_idl.py ``` +### Build artifacts + +Build outputs will land in the directory created by `gn gen` that you have been +providing to assorted `gn`, `ninja`, and `autoninja` commands. `updater.zip` +contains copies of the "final" outputs created by the build. `UpdaterSetup` is +probably what you want for installing the updater you have built. + +TODO(crbug.com/1448700): list the relevant/interesting outputs here and what +they are, why they're relevant/interesting, etc. + ## Debugging ### Debug into Windows update service @@ -177,13 +244,20 @@ ### Logging -Both the updater and the unit tests can create program logs. The log destination -is different: the updater logs in the product directory, while the unit tests -log into a directory defined by the environment variable `${ISOLATED_OUTDIR}`. -When run by Swarming, the updater logs are copied into `${ISOLATED_OUTDIR}` too, -so that after the swarming task has completed, both types of logs are -available as CAS outputs. The logs for `updater_tests_system` and -`integration_test_helper` are merged into `updater_tests_system.log`. +Both the updater and the unit tests can create program logs. + +#### Updater logs + +The updater itself logs in the product directory. + +#### Unit test logs + +The unit tests log into a directory defined by the environment variable +`${ISOLATED_OUTDIR}`. When run by Swarming, the updater logs are copied +into `${ISOLATED_OUTDIR}` too, so that after the swarming task has completed, +both types of logs are available as CAS outputs. The logs for +`updater_tests_system` and `integration_test_helper` are merged into +`updater_tests_system.log`. Non-bot systems can set up this environment variable to collect logs for debugging when the tests are run locally. @@ -206,3 +280,25 @@ name of the trybot you found. 4. Monitor and debug any failures as you normally would for any builder or tester. + +## Troubleshooting + +### Build errors + +* **Maybe it's not you.** If you pulled from `origin/main` since your last + successful build, or have never successfully built on your current branch, + and the build errors you're seeing aren't obviously related to any changes + you've made, + [check the tree status](https://chromium-status.appspot.com/status_viewer). + Did you pull down a broken version? If so, and the revert is in, pull again + and see if it works better. Or skip checking the tree status and just try + this as your first debugging step for build breaks after a pull. +* **Dependencies are a fast-moving target.** Remember to run `gclient sync -D` + after every pull from `origin/main` _and_ every branch change. If you aren't + sure whether you ran it, just run it, it's fast if you don't need it. +* **Is the Goma client ready?** If your build is failing quickly with a + bunch of errors related to Goma, run `goma_ctl ensure_start` and try again. +* **Symbols too big?** If your build is failing during linking, check your + `gn args` to verify that `symbol_level=1` (or `0`) is present. If it's not, + you're running into a known issue where the default symbol level, `2`, + outputs symbols too large for the linker to comprehend.
diff --git a/docs/updater/functional_spec.md b/docs/updater/functional_spec.md index 35a5489..fc02fa41 100644 --- a/docs/updater/functional_spec.md +++ b/docs/updater/functional_spec.md
@@ -59,10 +59,10 @@ bundle installer is typically used in software distribution scenarios. ### Standalone Installer -TODO(crbug.com/1281688): Implement standalone installers. +TODO(crbug.com/1281688): Add scripts to build standalone installers. -TODO(crbug.com/1035895): Document the standalone installer, including building -a standalone installer for a given application. +TODO(crbug.com/1035895): Document building a standalone installer for a given +application. Standalone installers embed all data required to install the application, including the payload and various configuration data needed by the application @@ -75,6 +75,18 @@ 2. when downloading the application payload is not desirable for any reason. 3. during OEM installation. +On Windows, a standalone installer can be created by embedding a manifest file +and application installer inside of the metainstaller (UpdaterSetup). These +files must be embedded in the metainstaller's `updater.7z` archive at the +following paths: +* `bin\Offline\{GUID}\OfflineManifest.gup` +* `bin\Offline\{GUID}\{app_id}\installer.exe` + +Standalone installers may use any `{GUID}` value as long as it is a valid +Windows GUID in the format `{XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}`. See the +"Offline installs" section below for more information on the manifest file and +application installer. + Applications on macOS frequently install via "drag-install", and then install the updater using a standalone installer on the application's first-run. The updater app can be embedded in a macOS application bundle as a helper and then
diff --git a/docs/updater/user_manual.md b/docs/updater/user_manual.md index dd5d0ea..b19ccdd 100644 --- a/docs/updater/user_manual.md +++ b/docs/updater/user_manual.md
@@ -5,6 +5,10 @@ [TOC] +## Command line usage + +Command line arguments for the updater client are documented in the [functional spec](functional_spec.md#Command-Line). + ## Error codes The updater setup process can exit with the following error codes: @@ -103,3 +107,8 @@ For more information, please see the [functional spec](functional_spec.md#Application-Commands). + +## Logging + +The updater writes logs to its product directory. See +[the functional spec](functional_spec.md#logging) for details.
diff --git a/extensions/browser/PRESUBMIT.py b/extensions/browser/PRESUBMIT.py index 706df3e..6a8a3039 100644 --- a/extensions/browser/PRESUBMIT.py +++ b/extensions/browser/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - import sys def _CreateHistogramValueChecker(input_api, output_api, path):
diff --git a/extensions/browser/extensions_test.cc b/extensions/browser/extensions_test.cc index 79a8186..1709dde 100644 --- a/extensions/browser/extensions_test.cc +++ b/extensions/browser/extensions_test.cc
@@ -53,7 +53,7 @@ } void ExtensionsTest::SetUp() { - content::ForceInProcessNetworkService(true); + content::ForceInProcessNetworkService(); browser_context_ = std::make_unique<content::TestBrowserContext>(); incognito_context_ = CreateTestIncognitoContext();
diff --git a/extensions/common/api/PRESUBMIT.py b/extensions/common/api/PRESUBMIT.py index ff06c6c..34c2a68 100644 --- a/extensions/common/api/PRESUBMIT.py +++ b/extensions/common/api/PRESUBMIT.py
@@ -9,7 +9,6 @@ """ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True import sys
diff --git a/extensions/common/permissions/PRESUBMIT.py b/extensions/common/permissions/PRESUBMIT.py index e22ceb2..b20bdd8 100644 --- a/extensions/common/permissions/PRESUBMIT.py +++ b/extensions/common/permissions/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - import sys def _CreateAPIPermissionIDChecker(input_api, output_api):
diff --git a/extensions/renderer/resources/automation/PRESUBMIT.py b/extensions/renderer/resources/automation/PRESUBMIT.py index ce454d9..fd7ac947 100644 --- a/extensions/renderer/resources/automation/PRESUBMIT.py +++ b/extensions/renderer/resources/automation/PRESUBMIT.py
@@ -8,9 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - - def _CheckWebDevStyle(input_api, output_api): results = []
diff --git a/gpu/PRESUBMIT.py b/gpu/PRESUBMIT.py index 0dccbec..3f3f0bfd 100644 --- a/gpu/PRESUBMIT.py +++ b/gpu/PRESUBMIT.py
@@ -10,10 +10,6 @@ import sys - -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): output = []
diff --git a/gpu/command_buffer/PRESUBMIT.py b/gpu/command_buffer/PRESUBMIT.py index 9a46d85..0548fcf 100644 --- a/gpu/command_buffer/PRESUBMIT.py +++ b/gpu/command_buffer/PRESUBMIT.py
@@ -9,9 +9,6 @@ import os.path -USE_PYTHON3 = True - - def _IsGLES2CmdBufferFile(affected_file): filename = os.path.basename(affected_file.LocalPath()) if filename in [
diff --git a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm index 50fdd4cb..3d3a367 100644 --- a/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm +++ b/gpu/command_buffer/service/shared_image/iosurface_image_backing.mm
@@ -8,6 +8,7 @@ #include "base/mac/scoped_nsobject.h" #include "base/trace_event/memory_dump_manager.h" #include "components/viz/common/gpu/dawn_context_provider.h" +#include "components/viz/common/gpu/metal_context_provider.h" #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/resource_sizes.h" #include "components/viz/common/resources/shared_image_format_utils.h" @@ -124,8 +125,7 @@ graphite_textures.reserve(num_planes); for (int plane = 0; plane < num_planes; plane++) { SkISize sk_size = gfx::SizeToSkISize(format.GetPlaneSize(plane, size)); - skgpu::graphite::BackendTexture backend_texture(sk_size, - mtl_textures[plane].get()); + graphite_textures.emplace_back(sk_size, mtl_textures[plane].get()); } return graphite_textures; } @@ -320,9 +320,11 @@ } void SkiaIOSurfaceRepresentation::EndWriteAccess() { +#if DCHECK_IS_ON() for (auto& surface : write_surfaces_) { DCHECK(surface->unique()); } +#endif CheckContext(); write_surfaces_.clear(); @@ -438,10 +440,12 @@ } void EndWriteAccess() override { - backing_impl()->HandleEndAccessSync(/*readonly=*/false); +#if DCHECK_IS_ON() for (auto& surface : write_surfaces_) { - surface->flush(); + DCHECK(surface->unique()); } +#endif + backing_impl()->HandleEndAccessSync(/*readonly=*/false); write_surfaces_.clear(); } @@ -1046,7 +1050,7 @@ // Use GPU main recorder since this should only be called for // fulfilling Graphite promise images on GPU main thread. return std::make_unique<SkiaGraphiteIOSurfaceRepresentation>( - manager, this, tracker, context_state->gpu_graphite_main_recorder(), + manager, this, tracker, context_state->gpu_main_graphite_recorder(), std::move(mtl_textures)); #endif }
diff --git a/gpu/command_buffer/service/shared_image/shared_image_factory.cc b/gpu/command_buffer/service/shared_image/shared_image_factory.cc index 62d359c..ffeb8172 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_factory.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_factory.cc
@@ -129,6 +129,11 @@ bool set_format_supported_metric = false; #endif +void RecordIsNewMultiplanarFormat(bool is_multiplanar) { + base::UmaHistogramBoolean("GPU.SharedImage.IsNewMultiplanarFormat", + is_multiplanar); +} + } // namespace // Overrides for flat_set lookups: @@ -456,6 +461,11 @@ return false; } + // Log UMA for multiplanar shared image formats. + if (format.is_multi_plane()) { + RecordIsNewMultiplanarFormat(/*is_multiplanar*/ true); + } + gfx::GpuMemoryBufferType gmb_type = buffer_handle.type; bool use_compound = false; @@ -515,6 +525,11 @@ auto si_format = viz::GetSharedImageFormat(format); gfx::GpuMemoryBufferType gmb_type = handle.type; + // Log UMA for multiplanar shared image formats. + if (si_format.IsLegacyMultiplanar()) { + RecordIsNewMultiplanarFormat(/*is_multiplanar*/ false); + } + bool use_compound = false; auto* factory = GetFactoryByUsage(usage, si_format, size, /*pixel_data=*/{}, gmb_type);
diff --git a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc index 497a4f6..0164581 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.cc
@@ -15,7 +15,6 @@ #include "components/viz/common/resources/resource_format.h" #include "components/viz/common/resources/resource_format_utils.h" #include "components/viz/common/resources/shared_image_format_utils.h" -#include "third_party/skia/include/gpu/graphite/TextureInfo.h" namespace gpu { @@ -289,25 +288,7 @@ bool mipmapped) { if (gr_context_type == GrContextType::kGraphiteMetal) { #if BUILDFLAG(SKIA_USE_METAL) - MTLPixelFormat mtl_pixel_format = - static_cast<MTLPixelFormat>(ToMTLPixelFormat(format, plane_index)); - if (mtl_pixel_format != MTLPixelFormatInvalid) { - // Must match CreateMetalTexture in iosurface_image_backing.mm. - // TODO(sunnyps): Move constants to a common utility header. - skgpu::graphite::MtlTextureInfo mtl_texture_info; - mtl_texture_info.fSampleCount = 1; - mtl_texture_info.fFormat = mtl_pixel_format; - mtl_texture_info.fUsage = - MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; -#if BUILDFLAG(IS_IOS) - mtl_texture_info.fStorageMode = MTLStorageModeShared; -#else - mtl_texture_info.fStorageMode = MTLStorageModePrivate; -#endif - mtl_texture_info.fMipmapped = - mipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo; - return mtl_texture_info; - } + return GetGraphiteMetalTextureInfo(format, plane_index, mipmapped); #endif } else { CHECK_EQ(gr_context_type, GrContextType::kGraphiteDawn);
diff --git a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h index 4902d25..9a43b377 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h +++ b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h
@@ -11,9 +11,11 @@ #include "gpu/config/gpu_preferences.h" #include "gpu/gpu_gles2_export.h" #include "gpu/vulkan/buildflags.h" +#include "skia/buildflags.h" #include "third_party/dawn/include/dawn/webgpu.h" #include "third_party/dawn/include/dawn/webgpu_cpp.h" #include "third_party/skia/include/core/SkYUVAInfo.h" +#include "third_party/skia/include/gpu/graphite/TextureInfo.h" #include "ui/gfx/buffer_types.h" #if BUILDFLAG(ENABLE_VULKAN) @@ -122,6 +124,13 @@ int plane_index = 0, bool mipmapped = false); +#if BUILDFLAG(SKIA_USE_METAL) +GPU_GLES2_EXPORT skgpu::graphite::MtlTextureInfo GetGraphiteMetalTextureInfo( + viz::SharedImageFormat format, + int plane_index = 0, + bool mipmapped = false); +#endif + } // namespace gpu #endif // GPU_COMMAND_BUFFER_SERVICE_SHARED_IMAGE_SHARED_IMAGE_FORMAT_SERVICE_UTILS_H_
diff --git a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm index b20c70016..625573d 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm +++ b/gpu/command_buffer/service/shared_image/shared_image_format_service_utils_mac.mm
@@ -4,7 +4,7 @@ #include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h" -#include <Metal/MTLPixelFormat.h> +#include <Metal/Metal.h> #include "base/check_op.h" #include "base/logging.h" @@ -70,4 +70,30 @@ return static_cast<unsigned int>(mtl_pixel_format); } +#if BUILDFLAG(SKIA_USE_METAL) +skgpu::graphite::MtlTextureInfo GetGraphiteMetalTextureInfo( + viz::SharedImageFormat format, + int plane_index, + bool mipmapped) { + MTLPixelFormat mtl_pixel_format = + static_cast<MTLPixelFormat>(ToMTLPixelFormat(format, plane_index)); + CHECK_NE(mtl_pixel_format, MTLPixelFormatInvalid); + // Must match CreateMetalTexture in iosurface_image_backing.mm. + // TODO(sunnyps): Move constants to a common utility header. + skgpu::graphite::MtlTextureInfo mtl_texture_info; + mtl_texture_info.fSampleCount = 1; + mtl_texture_info.fFormat = mtl_pixel_format; + mtl_texture_info.fUsage = + MTLTextureUsageRenderTarget | MTLTextureUsageShaderRead; +#if BUILDFLAG(IS_IOS) + mtl_texture_info.fStorageMode = MTLStorageModeShared; +#else + mtl_texture_info.fStorageMode = MTLStorageModePrivate; +#endif + mtl_texture_info.fMipmapped = + mipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo; + return mtl_texture_info; +} +#endif + } // namespace gpu
diff --git a/gpu/config/PRESUBMIT.py b/gpu/config/PRESUBMIT.py index fbac40e1..9f8f8b7 100644 --- a/gpu/config/PRESUBMIT.py +++ b/gpu/config/PRESUBMIT.py
@@ -12,9 +12,6 @@ import os.path import io -USE_PYTHON3 = True - - def _CheckGPUWorkaroundListSorted(input_api, output_api): """Check: gpu_workaround_list.txt feature list sorted alphabetically. """
diff --git a/gpu/config/gpu_finch_features.cc b/gpu/config/gpu_finch_features.cc index 60999984..e7060ff 100644 --- a/gpu/config/gpu_finch_features.cc +++ b/gpu/config/gpu_finch_features.cc
@@ -296,12 +296,12 @@ &kVulkan, "BlockListByAndroidBuildFP", ""}; // Blocklists meant for DrDc. -// crbug.com/1294648 +// crbug.com/1294648, crbug.com/1397578: the screen flickers. const base::FeatureParam<std::string> kDrDcBlockListByDevice{ &kEnableDrDc, "BlockListByDevice", "LF9810_2GB|amber|chopin|secret|a03|SO-51B|on7xelte|j7xelte|F41B|doha|" "rk322x_box|a20s|HWMAR|HWSTK-HF|HWPOT-H|b2q|channel|galahad|a32|ellis|" - "dandelion|tonga|RMX3231"}; + "dandelion|tonga|RMX3231|ASUS_I006D|ASUS_I004D|bacon"}; // crbug.com/1340059, crbug.com/1340064 const base::FeatureParam<std::string> kDrDcBlockListByModel{
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.cc b/gpu/ipc/client/command_buffer_proxy_impl.cc index 02390a57..05e5b37 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.cc +++ b/gpu/ipc/client/command_buffer_proxy_impl.cc
@@ -159,11 +159,6 @@ OnGpuAsyncMessageError(context_lost_reason, gpu::error::kLostContext); } -void CommandBufferProxyImpl::BindMediaReceiver( - mojo::GenericPendingAssociatedReceiver receiver) { - command_buffer_->BindMediaReceiver(std::move(receiver)); -} - void CommandBufferProxyImpl::OnDestroyed(gpu::error::ContextLostReason reason, gpu::error::Error error) { base::AutoLockMaybe lock(lock_.get());
diff --git a/gpu/ipc/client/command_buffer_proxy_impl.h b/gpu/ipc/client/command_buffer_proxy_impl.h index 3eb219b2..57aed19 100644 --- a/gpu/ipc/client/command_buffer_proxy_impl.h +++ b/gpu/ipc/client/command_buffer_proxy_impl.h
@@ -101,11 +101,6 @@ void OnDisconnect(); - // Asks the GPU side to bind an associated interface which will share message - // ordering with this command buffer. Used by media clients for interfaces not - // defined at the GPU layer. - void BindMediaReceiver(mojo::GenericPendingAssociatedReceiver receiver); - // CommandBuffer implementation: State GetLastState() override; void Flush(int32_t put_offset) override;
diff --git a/gpu/ipc/common/PRESUBMIT.py b/gpu/ipc/common/PRESUBMIT.py index 2e6bd29..82c2006 100644 --- a/gpu/ipc/common/PRESUBMIT.py +++ b/gpu/ipc/common/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - import os.path
diff --git a/gpu/ipc/common/gpu_channel.mojom b/gpu/ipc/common/gpu_channel.mojom index d589c667..a35a5725 100644 --- a/gpu/ipc/common/gpu_channel.mojom +++ b/gpu/ipc/common/gpu_channel.mojom
@@ -12,7 +12,6 @@ import "gpu/ipc/common/vulkan_ycbcr_info.mojom"; import "mojo/public/mojom/base/shared_memory.mojom"; import "mojo/public/mojom/base/unguessable_token.mojom"; -import "mojo/public/mojom/base/generic_pending_associated_receiver.mojom"; import "services/viz/public/mojom/compositing/resource_format.mojom"; import "services/viz/public/mojom/compositing/shared_image_format.mojom"; import "skia/public/mojom/image_info.mojom"; @@ -263,13 +262,6 @@ // then sends a corresponding SignalAck on the CommandBufferClient interface, // using `signal_id` to identify this request. SignalQuery(uint32 query, uint32 signal_id); - - // Binds an associated interface which shares its message ordering with this - // CommandBuffer. This allows the Media stack above the core GPU layer to - // establish such interfaces without introducing a layering violation. See - // GpuChannel::set_command_buffer_media_binder(). - [Sync] BindMediaReceiver( - mojo_base.mojom.GenericPendingAssociatedReceiver receiver) => (); }; // Corresponds to gpu::SwapBuffersCompleteParams.
diff --git a/gpu/ipc/service/command_buffer_stub.cc b/gpu/ipc/service/command_buffer_stub.cc index c09eb05f..4a05fa2 100644 --- a/gpu/ipc/service/command_buffer_stub.cc +++ b/gpu/ipc/service/command_buffer_stub.cc
@@ -595,15 +595,6 @@ } } -void CommandBufferStub::BindMediaReceiver( - mojo::GenericPendingAssociatedReceiver receiver, - BindMediaReceiverCallback callback) { - const auto& binder = channel_->command_buffer_media_binder(); - if (binder) - binder.Run(this, std::move(receiver)); - std::move(callback).Run(); -} - void CommandBufferStub::OnFenceSyncRelease(uint64_t release) { SyncToken sync_token(CommandBufferNamespace::GPU_IO, command_buffer_id_, release);
diff --git a/gpu/ipc/service/command_buffer_stub.h b/gpu/ipc/service/command_buffer_stub.h index 71ca1d4..74214e5 100644 --- a/gpu/ipc/service/command_buffer_stub.h +++ b/gpu/ipc/service/command_buffer_stub.h
@@ -225,8 +225,6 @@ GetGpuFenceHandleCallback callback) override; void SignalSyncToken(const SyncToken& sync_token, uint32_t id) override; void SignalQuery(uint32_t query, uint32_t id) override; - void BindMediaReceiver(mojo::GenericPendingAssociatedReceiver receiver, - BindMediaReceiverCallback callback) override; virtual void OnSetDefaultFramebufferSharedImage(const Mailbox& mailbox, int samples_count,
diff --git a/gpu/vulkan/PRESUBMIT.py b/gpu/vulkan/PRESUBMIT.py index 09d9a4fd..317ff48 100644 --- a/gpu/vulkan/PRESUBMIT.py +++ b/gpu/vulkan/PRESUBMIT.py
@@ -10,10 +10,6 @@ import os.path - -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): generating_files = input_api.AffectedFiles( file_filter=lambda x: os.path.basename(x.LocalPath()) in [
diff --git a/headless/BUILD.gn b/headless/BUILD.gn index 4eccdb3..30f2fc93 100644 --- a/headless/BUILD.gn +++ b/headless/BUILD.gn
@@ -330,8 +330,6 @@ "lib/browser/headless_platform_event_source.h", "lib/browser/headless_request_context_manager.cc", "lib/browser/headless_request_context_manager.h", - "lib/browser/headless_select_file_dialog_factory.cc", - "lib/browser/headless_select_file_dialog_factory.h", "lib/browser/headless_web_contents_impl.cc", "lib/browser/headless_web_contents_impl.h", "lib/browser/headless_window_tree_host.h", @@ -438,6 +436,7 @@ "//components/embedder_support:embedder_support", "//components/embedder_support/origin_trials", "//components/headless/clipboard", + "//components/headless/select_file_dialog", "//components/keyed_service/content", "//components/keyed_service/content:content", "//components/origin_trials:browser", @@ -476,9 +475,6 @@ "//ui/events/devices", "//ui/events/devices:devices", "//ui/gfx", - "//ui/shell_dialogs", - "//ui/shell_dialogs:shell_dialogs", - "//url", "//url", ] @@ -781,6 +777,7 @@ "//components/embedder_support", "//components/embedder_support:browser_util", "//components/embedder_support:embedder_support", + "//components/headless/select_file_dialog", "//components/headless/test", "//components/policy/core/browser", "//components/security_state/content",
diff --git a/headless/lib/browser/DEPS b/headless/lib/browser/DEPS index 8a93273..a359154 100644 --- a/headless/lib/browser/DEPS +++ b/headless/lib/browser/DEPS
@@ -50,9 +50,6 @@ "+components/printing/browser/print_to_pdf", "+third_party/blink/public/mojom/window_features", ], - "headless_select_file_dialog_factory.*": [ - "+ui/shell_dialogs", - ], "command_line_handler.cc": [ "+third_party/blink/public/common/switches.h", ]
diff --git a/headless/lib/browser/headless_browser_main_parts.cc b/headless/lib/browser/headless_browser_main_parts.cc index 94b57e98..f68cdfc 100644 --- a/headless/lib/browser/headless_browser_main_parts.cc +++ b/headless/lib/browser/headless_browser_main_parts.cc
@@ -11,12 +11,12 @@ #include "base/run_loop.h" #include "build/build_config.h" #include "components/headless/clipboard/headless_clipboard.h" +#include "components/headless/select_file_dialog/headless_select_file_dialog.h" #include "content/public/common/result_codes.h" #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_impl.h" #include "headless/lib/browser/headless_devtools.h" #include "headless/lib/browser/headless_screen.h" -#include "headless/lib/browser/headless_select_file_dialog_factory.h" #include "headless/public/switches.h" #if defined(HEADLESS_USE_PREFS)
diff --git a/headless/test/headless_browser_browsertest.cc b/headless/test/headless_browser_browsertest.cc index 8e1e1c0..a06f837 100644 --- a/headless/test/headless_browser_browsertest.cc +++ b/headless/test/headless_browser_browsertest.cc
@@ -19,6 +19,7 @@ #include "base/values.h" #include "build/build_config.h" #include "components/devtools/simple_devtools_protocol_client/simple_devtools_protocol_client.h" +#include "components/headless/select_file_dialog/headless_select_file_dialog.h" #include "content/public/browser/navigation_controller.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/permission_controller_delegate.h" @@ -31,7 +32,6 @@ #include "content/public/test/test_navigation_observer.h" #include "headless/lib/browser/headless_browser_context_impl.h" #include "headless/lib/browser/headless_browser_impl.h" -#include "headless/lib/browser/headless_select_file_dialog_factory.h" #include "headless/lib/browser/headless_web_contents_impl.h" #include "headless/public/headless_browser.h" #include "headless/public/headless_web_contents.h"
diff --git a/infra/config/PRESUBMIT.py b/infra/config/PRESUBMIT.py index df4b233..c575400 100644 --- a/infra/config/PRESUBMIT.py +++ b/infra/config/PRESUBMIT.py
@@ -44,12 +44,8 @@ def CheckTests(input_api, output_api): glob = input_api.os_path.join(input_api.PresubmitLocalPath(), '*_test.py') - tests = input_api.canned_checks.GetUnitTests(input_api, - output_api, - input_api.glob(glob), - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + tests = input_api.canned_checks.GetUnitTests(input_api, output_api, + input_api.glob(glob)) return input_api.RunTests(tests)
diff --git a/infra/config/generated/luci/cr-buildbucket.cfg b/infra/config/generated/luci/cr-buildbucket.cfg index aeb0a7bf..85e675d 100644 --- a/infra/config/generated/luci/cr-buildbucket.cfg +++ b/infra/config/generated/luci/cr-buildbucket.cfg
@@ -26051,6 +26051,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -29606,6 +29607,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -29735,6 +29737,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -29856,6 +29859,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -29978,6 +29982,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -30099,6 +30104,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -30221,6 +30227,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -34551,7 +34558,7 @@ name: "ios16-sdk-simulator" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:ios16-sdk-simulator" - dimensions: "cpu:x86-64" + dimensions: "cpu:arm64" dimensions: "os:Mac-13" dimensions: "pool:luci.chromium.ci" exe { @@ -37402,6 +37409,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -47075,6 +47083,7 @@ ' "metrics_project": "chromium-reclient-metrics"' ' },' ' "$build/siso": {' + ' "config": "remote_all",' ' "enable_cloud_profiler": true,' ' "enable_cloud_trace": true,' ' "project": "rbe-chromium-untrusted"' @@ -62683,7 +62692,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -71465,7 +71474,7 @@ name: "ios16-sdk-simulator" swarming_host: "chromium-swarm.appspot.com" dimensions: "builder:ios16-sdk-simulator" - dimensions: "cpu:x86-64" + dimensions: "cpu:arm64" dimensions: "os:Mac-13" dimensions: "pool:luci.chromium.try" exe { @@ -72008,7 +72017,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -72098,7 +72107,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -72278,7 +72287,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -72561,7 +72570,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -72651,7 +72660,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -72742,7 +72751,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -72832,7 +72841,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -73104,7 +73113,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -73447,7 +73456,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74168,7 +74177,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74258,7 +74267,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74436,7 +74445,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74526,7 +74535,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74616,7 +74625,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74706,7 +74715,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74886,7 +74895,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -74977,7 +74986,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -75067,7 +75076,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -75329,7 +75338,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -75509,7 +75518,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -75875,7 +75884,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -75965,7 +75974,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -76136,7 +76145,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -76226,7 +76235,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -76406,7 +76415,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -77347,7 +77356,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -77617,7 +77626,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -77983,7 +77992,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -78073,7 +78082,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -78163,7 +78172,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -78253,7 +78262,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -78343,7 +78352,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -78523,7 +78532,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -78613,7 +78622,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -78704,7 +78713,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -79254,7 +79263,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -79336,7 +79345,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -79520,7 +79529,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -79610,7 +79619,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe { @@ -79985,7 +79994,7 @@ dimensions: "builderless:1" dimensions: "cores:8" dimensions: "cpu:x86-64" - dimensions: "os:Ubuntu-18.04" + dimensions: "os:Ubuntu-22.04" dimensions: "pool:luci.chromium.try" dimensions: "ssd:0" exe {
diff --git a/infra/config/lib/builders.star b/infra/config/lib/builders.star index efd97e8..e20b00d 100644 --- a/infra/config/lib/builders.star +++ b/infra/config/lib/builders.star
@@ -399,6 +399,7 @@ reclient_cache_silo = None, reclient_ensure_verified = None, reclient_disable_bq_upload = None, + siso_config = None, siso_project = None, siso_enable_cloud_profiler = None, siso_enable_cloud_trace = None, @@ -465,6 +466,7 @@ reclient_cache_silo = None, reclient_ensure_verified = None, reclient_disable_bq_upload = None, + siso_config = args.DEFAULT, siso_project = args.DEFAULT, siso_enable_cloud_profiler = args.DEFAULT, siso_enable_cloud_trace = args.DEFAULT, @@ -647,6 +649,8 @@ effect if reclient_instance is not set. reclient_disable_bq_upload: If True, rbe_metrics will not be uploaded to BigQuery after each build + siso_config: a string of siso config. available values are defined in + //build/config/siso/config.star. siso_project: a string indicating the GCP project hosting the RBE instance and other Cloud services. e.g. logging, trace etc. siso_enable_cloud_profiler: If True, enable cloud profiler in siso. @@ -819,6 +823,7 @@ "project": defaults.get_value("siso_project", siso_project), "enable_cloud_profiler": defaults.get_value("siso_enable_cloud_profiler", siso_enable_cloud_profiler), "enable_cloud_trace": defaults.get_value("siso_enable_cloud_trace", siso_enable_cloud_trace), + "config": defaults.get_value("siso_config", siso_config), } if siso["project"]: properties["$build/siso"] = siso
diff --git a/infra/config/lib/linux-default.json b/infra/config/lib/linux-default.json index 4f15f21f..20432bb 100644 --- a/infra/config/lib/linux-default.json +++ b/infra/config/lib/linux-default.json
@@ -102,28 +102,72 @@ "chromeos-amd64-generic-rel": "Ubuntu-22.04", "chromeos-amd64-generic-rel-compilator": "Ubuntu-22.04", "chromeos-arm-generic-rel": "Ubuntu-22.04", + "chromeos-js-code-coverage": "Ubuntu-22.04", "fuchsia-binary-size": "Ubuntu-22.04", "fuchsia-x64-cast-receiver-rel": "Ubuntu-22.04", "fuchsia-x64-cast-receiver-rel-compilator": "Ubuntu-22.04", "ios-simulator": "Ubuntu-22.04", "lacros-amd64-generic-rel": "Ubuntu-22.04", "lacros-arm-generic-rel": "Ubuntu-22.04", + "layout_test_leak_detection": "Ubuntu-22.04", + "leak_detection_linux": "Ubuntu-22.04", + "linux-afl-asan-rel": "Ubuntu-22.04", + "linux-annotator-rel": "Ubuntu-22.04", + "linux-arm64-castos": "Ubuntu-22.04", + "linux-bfcache-rel": "Ubuntu-22.04", + "linux-blink-heap-verification-try": "Ubuntu-22.04", + "linux-centipede-asan-rel": "Ubuntu-22.04", + "linux-chromeos-code-coverage": "Ubuntu-22.04", "linux-chromeos-compile-dbg": "Ubuntu-22.04", "linux-chromeos-rel": "Ubuntu-22.04", "linux-chromeos-rel-compilator": "Ubuntu-22.04", + "linux-code-coverage": "Ubuntu-22.04", + "linux-cr23-rel": "Ubuntu-22.04", + "linux-dcheck-off-rel": "Ubuntu-22.04", + "linux-exp-tsan-fyi-rel": "Ubuntu-22.04", + "linux-extended-tracing-rel": "Ubuntu-22.04", + "linux-fieldtrial-rel": "Ubuntu-22.04", + "linux-gcc-rel": "Ubuntu-22.04", + "linux-headless-shell-rel": "Ubuntu-22.04", + "linux-inverse-fieldtrials-fyi-rel": "Ubuntu-22.04", + "linux-js-code-coverage": "Ubuntu-22.04", + "linux-lacros-code-coverage": "Ubuntu-22.04", + "linux-lacros-fyi-rel": "Ubuntu-22.04", "linux-lacros-rel": "Ubuntu-22.04", "linux-lacros-rel-compilator": "Ubuntu-22.04", + "linux-lacros-version-skew-fyi": "Ubuntu-22.04", + "linux-layout-tests-edit-ng": "Ubuntu-22.04", "linux-libfuzzer-asan-rel": "Ubuntu-22.04", + "linux-mbi-mode-per-render-process-host-rel": "Ubuntu-22.04", + "linux-mbi-mode-per-site-instance-rel": "Ubuntu-22.04", + "linux-perfetto-rel": "Ubuntu-22.04", "linux-rel": "Ubuntu-22.04", "linux-rel-compilator": "Ubuntu-22.04", + "linux-ubsan-fyi-rel": "Ubuntu-22.04", + "linux-viz-rel": "Ubuntu-22.04", "linux-wayland-rel": "Ubuntu-22.04", "linux-wayland-rel-compilator": "Ubuntu-22.04", + "linux-webkit-msan-rel": "Ubuntu-22.04", + "linux-wpt-content-shell-fyi-rel": "Ubuntu-22.04", + "linux-wpt-content-shell-leak-detection": "Ubuntu-22.04", + "linux-wpt-fyi-rel": "Ubuntu-22.04", + "linux-wpt-identity-fyi-rel": "Ubuntu-22.04", + "linux-wpt-input-fyi-rel": "Ubuntu-22.04", "linux-x64-castos": "Ubuntu-22.04", + "linux-x64-castos-audio": "Ubuntu-22.04", + "linux-x64-castos-dbg": "Ubuntu-22.04", + "linux_chromium_archive_rel_ng": "Ubuntu-22.04", "linux_chromium_asan_rel_ng": "Ubuntu-22.04", "linux_chromium_asan_rel_ng-compilator": "Ubuntu-22.04", + "linux_chromium_clobber_deterministic": "Ubuntu-22.04", + "linux_chromium_clobber_rel_ng": "Ubuntu-22.04", "linux_chromium_compile_dbg_ng": "Ubuntu-22.04", + "linux_chromium_compile_rel_ng": "Ubuntu-22.04", + "linux_chromium_dbg_ng": "Ubuntu-22.04", + "linux_chromium_msan_rel_ng": "Ubuntu-22.04", "linux_chromium_tsan_rel_ng": "Ubuntu-22.04", "linux_chromium_tsan_rel_ng-compilator": "Ubuntu-22.04", + "linux_chromium_ubsan_rel_ng": "Ubuntu-22.04", "mac-rel": "Ubuntu-22.04", "win-rel": "Ubuntu-22.04" }
diff --git a/infra/config/scripts/PRESUBMIT.py b/infra/config/scripts/PRESUBMIT.py index a031c74..21fee6c2 100644 --- a/infra/config/scripts/PRESUBMIT.py +++ b/infra/config/scripts/PRESUBMIT.py
@@ -13,10 +13,9 @@ def CheckTests(input_api, output_api): glob = input_api.os_path.join( input_api.PresubmitLocalPath(), 'tests', '*_test.py') - tests = input_api.canned_checks.GetUnitTests(input_api, - output_api, - input_api.glob(glob), - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + tests = input_api.canned_checks.GetUnitTests( + input_api, + output_api, + input_api.glob(glob), + ) return input_api.RunTests(tests)
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index cc5134c..1aa071f 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -1372,6 +1372,7 @@ # rely on the builder dimension for the bot selection. builderless = False, cores = None, + siso_config = "remote_all", siso_enable_cloud_profiler = True, siso_enable_cloud_trace = True, siso_project = siso.project.DEFAULT_UNTRUSTED, @@ -2368,6 +2369,7 @@ build_gs_bucket = "chromium-fyi-archive", ), os = os.MAC_13, + cpu = cpu.ARM64, console_view_entry = consoles.console_view_entry( category = "iOS|iOS16", short_name = "sdk16",
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star index d7db125..9da7b58 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -575,6 +575,7 @@ "ci/ios16-sdk-simulator", ], os = os.MAC_13, + cpu = cpu.ARM64, xcode = xcode.x14betabots, )
diff --git a/ios/PRESUBMIT.py b/ios/PRESUBMIT.py index 95455270..88faf6f 100644 --- a/ios/PRESUBMIT.py +++ b/ios/PRESUBMIT.py
@@ -10,8 +10,6 @@ import os -USE_PYTHON3 = True - NULLABILITY_PATTERN = r'(nonnull|nullable|_Nullable|_Nonnull)' TODO_PATTERN = r'TO[D]O\(([^\)]*)\)' BUG_PATTERN = r'(crbug\.com|b)/\d+$'
diff --git a/ios/build/bots/scripts/PRESUBMIT.py b/ios/build/bots/scripts/PRESUBMIT.py index fb17a61c..35318b3a 100644 --- a/ios/build/bots/scripts/PRESUBMIT.py +++ b/ios/build/bots/scripts/PRESUBMIT.py
@@ -7,9 +7,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - - def _RunTestRunnerUnitTests(input_api, output_api): # Don't run iOS tests on Windows. if input_api.is_windows: @@ -18,13 +15,7 @@ files = ['.*_test.py$'] return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=files, - run_on_python2=not USE_PYTHON3, - run_on_python3=USE_PYTHON3, - skip_shebang_check=True) + input_api, output_api, '.', files_to_check=files) def CheckChange(input_api, output_api):
diff --git a/ios/build/bots/scripts/plugin/PRESUBMIT.py b/ios/build/bots/scripts/plugin/PRESUBMIT.py index 13748b5..ccedf8b 100644 --- a/ios/build/bots/scripts/plugin/PRESUBMIT.py +++ b/ios/build/bots/scripts/plugin/PRESUBMIT.py
@@ -7,9 +7,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - - def _RunTestRunnerUnitTests(input_api, output_api): # Don't run iOS tests on Windows. if input_api.is_windows: @@ -18,13 +15,7 @@ files = ['.*_test.py$'] return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=files, - run_on_python2=not USE_PYTHON3, - run_on_python3=USE_PYTHON3, - skip_shebang_check=True) + input_api, output_api, '.', files_to_check=files) def CheckChange(input_api, output_api):
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 7aca1e4..f512c7a 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -3024,7 +3024,7 @@ Entered on a deceptive site and found in a data breach </message> <message name="IDS_IOS_COMPROMISED_PASSWORD_ISSUES_DISMISSED_WARNINGS_BUTTON_TITLE" desc="Text of the button presenting the password manager screen displaying compromised credential issues dismissed by the user. [iOS only]"> - Dismissed Warnings (<ph name="COUNT">$1<ex>2</ex></ph>) + Dismissed Warnings </message> <message name="IDS_IOS_CHANGE_COMPROMISED_PASSWORD" desc="Button which is shown on Password Details Screen when password is compromised. [iOS only]" meaning="Telling user to change password on a website since it is compromised."> Change Password on Website
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_DISMISSED_WARNINGS_BUTTON_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_DISMISSED_WARNINGS_BUTTON_TITLE.png.sha1 index f58254d..f80cd4aff 100644 --- a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_DISMISSED_WARNINGS_BUTTON_TITLE.png.sha1 +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_COMPROMISED_PASSWORD_ISSUES_DISMISSED_WARNINGS_BUTTON_TITLE.png.sha1
@@ -1 +1 @@ -b6e430f058cb14f2cc5ecca01658f47c12707657 \ No newline at end of file +bc8e14c9259789fc3fbffe887d618a6057dd49c9 \ No newline at end of file
diff --git a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h index 2ad8fe8d..caf763f 100644 --- a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h +++ b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.h
@@ -14,9 +14,9 @@ class WebFrame; } // namespace web +@protocol AutofillBottomSheetCommands; @class CommandDispatcher; @protocol PasswordsAccountStorageNoticeHandler; -@protocol PasswordBottomSheetCommands; class AutofillBottomSheetTabHelper : public web::WebStateObserver, @@ -35,9 +35,9 @@ // Handler for JavaScript messages. Dispatch to more specific handler. void OnFormMessageReceived(const web::ScriptMessage& message); - // Sets the Password CommandDispatcher. - void SetPasswordBottomSheetHandler( - id<PasswordBottomSheetCommands> password_bottom_sheet_commands_handler); + // Sets the bottom sheet CommandDispatcher. + void SetAutofillBottomSheetHandler( + id<AutofillBottomSheetCommands> commands_handler); // Prepare bottom sheet using data from the password form prediction. void AttachPasswordListeners( @@ -65,8 +65,7 @@ bool HasReachedDismissLimit(); // Handler used to request showing the password bottom sheet. - __weak id<PasswordBottomSheetCommands> - password_bottom_sheet_commands_handler_; + __weak id<AutofillBottomSheetCommands> commands_handler_; // Handler used for the passwords account storage notice. // TODO(crbug.com/1434606): Remove this when the move to account storage
diff --git a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm index 3100ceaf..e6cd124 100644 --- a/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm +++ b/ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_tab_helper.mm
@@ -15,8 +15,8 @@ #import "ios/chrome/browser/autofill/bottom_sheet/autofill_bottom_sheet_java_script_feature.h" #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/shared/model/prefs/pref_names.h" +#import "ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" -#import "ios/chrome/browser/shared/public/commands/password_bottom_sheet_commands.h" #import "ios/web/public/js_messaging/script_message.h" #import "ios/web/public/navigation/navigation_context.h" @@ -38,33 +38,29 @@ // Public methods -void AutofillBottomSheetTabHelper::SetPasswordBottomSheetHandler( - id<PasswordBottomSheetCommands> password_bottom_sheet_commands_handler) { - password_bottom_sheet_commands_handler_ = - password_bottom_sheet_commands_handler; +void AutofillBottomSheetTabHelper::SetAutofillBottomSheetHandler( + id<AutofillBottomSheetCommands> commands_handler) { + commands_handler_ = commands_handler; } void AutofillBottomSheetTabHelper::OnFormMessageReceived( const web::ScriptMessage& message) { autofill::FormActivityParams params; - if (!password_bottom_sheet_commands_handler_ || - !password_account_storage_notice_handler_ || + if (!commands_handler_ || !password_account_storage_notice_handler_ || !autofill::FormActivityParams::FromMessage(message, ¶ms)) { return; } if (![password_account_storage_notice_handler_ shouldShowAccountStorageNotice]) { - [password_bottom_sheet_commands_handler_ showPasswordBottomSheet:params]; + [commands_handler_ showPasswordBottomSheet:params]; return; } - __weak id<PasswordBottomSheetCommands> - weak_password_bottom_sheet_commands_handler = - password_bottom_sheet_commands_handler_; + __weak id<AutofillBottomSheetCommands> weak_commands_handler = + commands_handler_; [password_account_storage_notice_handler_ showAccountStorageNotice:^{ - [weak_password_bottom_sheet_commands_handler - showPasswordBottomSheet:params]; + [weak_commands_handler showPasswordBottomSheet:params]; }]; }
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 7287cec..7d5cb8b 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -1111,6 +1111,10 @@ flag_descriptions::kIOSPasswordBottomSheetName, flag_descriptions::kIOSPasswordBottomSheetDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(password_manager::features::kIOSPasswordBottomSheet)}, + {"ios-payments-bottom-sheet", + flag_descriptions::kIOSPaymentsBottomSheetName, + flag_descriptions::kIOSPaymentsBottomSheetDescription, flags_ui::kOsIos, + FEATURE_VALUE_TYPE(kIOSPaymentsBottomSheet)}, {"ios-new-tab-page-retention", flag_descriptions::kNewTabPageFieldTrialName, flag_descriptions::kNewTabPageFieldTrialDescription, flags_ui::kOsIos, FEATURE_WITH_PARAMS_VALUE_TYPE(ntp_tiles::kNewTabPageFieldTrial, @@ -1532,6 +1536,12 @@ flag_descriptions::kEnableSignedOutViewDemotionName, flag_descriptions::kEnableSignedOutViewDemotionDescription, flags_ui::kOsIos, FEATURE_VALUE_TYPE(kEnableSignedOutViewDemotion)}, + {"autofill-use-two-dots-for-last-four-digits", + flag_descriptions::kAutofillUseTwoDotsForLastFourDigitsName, + flag_descriptions::kAutofillUseTwoDotsForLastFourDigitsDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE( + autofill::features::kAutofillUseTwoDotsForLastFourDigits)}, }; bool SkipConditionalFeatureEntry(const flags_ui::FeatureEntry& entry) {
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc index 422aa63..c6bd3012 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -158,6 +158,12 @@ "When enabled, Autofill logic uses unique numeric renderer IDs instead " "of string form and field identifiers in form filling logic."; +const char kAutofillUseTwoDotsForLastFourDigitsName[] = + "Autofill uses two '•' instead of four"; +const char kAutofillUseTwoDotsForLastFourDigitsDescription[] = + "When enabled, Autofill surfaces will show two '•' characters instead of " + "four when displaying the last four digits of a card number"; + const char kBottomOmniboxSteadyStateName[] = "Bottom Omnibox (Steady)"; const char kBottomOmniboxSteadyStateDescription[] = "Move the omnibox to the bottom in steady state"; @@ -574,6 +580,10 @@ const char kIOSPasswordBottomSheetDescription[] = "Enables the display of the password bottom sheet on IOS."; +const char kIOSPaymentsBottomSheetName[] = "IOS Payments Manager Bottom Sheet"; +const char kIOSPaymentsBottomSheetDescription[] = + "Enables the display of the payments bottom sheet on IOS."; + const char kNewTabPageFieldTrialName[] = "New tab page features that target new users"; const char kNewTabPageFieldTrialDescription[] =
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index bb0a8a9..5ca91327 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -134,6 +134,12 @@ extern const char kAutofillUseRendererIDsName[]; extern const char kAutofillUseRendererIDsDescription[]; +// Title and description for the flag that controls whether Autofill uses +// two or four '•' characters when displaying the last four digits of a credit +// card. +extern const char kAutofillUseTwoDotsForLastFourDigitsName[]; +extern const char kAutofillUseTwoDotsForLastFourDigitsDescription[]; + // Title and description for the flag that moves the omnibox to the bottom in // the steady state. extern const char kBottomOmniboxSteadyStateName[]; @@ -496,6 +502,10 @@ extern const char kIOSPasswordBottomSheetName[]; extern const char kIOSPasswordBottomSheetDescription[]; +// Title and description for the flag to enable payments bottom sheet on IOS. +extern const char kIOSPaymentsBottomSheetName[]; +extern const char kIOSPaymentsBottomSheetDescription[]; + // Title and description of the flag to enable client side new tab page // experiments aimed at improving user retention. extern const char kNewTabPageFieldTrialName[];
diff --git a/ios/chrome/browser/passwords/password_controller_js_unittest.mm b/ios/chrome/browser/passwords/password_controller_js_unittest.mm index e86ebf92..128e78226 100644 --- a/ios/chrome/browser/passwords/password_controller_js_unittest.mm +++ b/ios/chrome/browser/passwords/password_controller_js_unittest.mm
@@ -9,7 +9,6 @@ #import "components/password_manager/ios/password_manager_java_script_feature.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/web/chrome_web_client.h" -#import "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/public/js_messaging/web_frame.h" #import "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/test/js_test_util.h" @@ -102,10 +101,7 @@ return result; } - std::string BaseUrl() { - web::URLVerificationTrustLevel unused_level; - return web_state()->GetCurrentURL(&unused_level).spec(); - } + std::string BaseUrl() { return web_state()->GetLastCommittedURL().spec(); } protected: id ExecuteJavaScript(NSString* script) {
diff --git a/ios/chrome/browser/passwords/password_controller_unittest.mm b/ios/chrome/browser/passwords/password_controller_unittest.mm index 345038d5..a043f79 100644 --- a/ios/chrome/browser/passwords/password_controller_unittest.mm +++ b/ios/chrome/browser/passwords/password_controller_unittest.mm
@@ -47,7 +47,6 @@ #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" #import "ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.h" #import "ios/chrome/browser/web/chrome_web_client.h" -#import "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/public/js_messaging/web_frame.h" #import "ios/web/public/js_messaging/web_frames_manager.h" #import "ios/web/public/navigation/navigation_item.h" @@ -472,8 +471,7 @@ } std::string BaseUrl() const { - web::URLVerificationTrustLevel unused_level; - return web_state()->GetCurrentURL(&unused_level).spec(); + return web_state()->GetLastCommittedURL().spec(); } web::WebState* web_state() const { return web_state_.get(); }
diff --git a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm index 37fccdb..c6e02b0 100644 --- a/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm +++ b/ios/chrome/browser/passwords/well_known_change_password_tab_helper_unittest.mm
@@ -172,9 +172,7 @@ }; GURL WellKnownChangePasswordTabHelperTest::GetNavigatedUrl() const { - web::URLVerificationTrustLevel trust_level = - web::URLVerificationTrustLevel::kAbsolute; - GURL url = web_state()->GetCurrentURL(&trust_level); + GURL url = web_state()->GetLastCommittedURL(); // When redirecting with WebState::OpenURL() `web_state_` is not // updated, we only see the registered request in // FakeWebStateDelegate::last_open_url_request().
diff --git a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm index dd8806f..2e7ad97 100644 --- a/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm +++ b/ios/chrome/browser/policy/configuration_policy_handler_list_factory.mm
@@ -92,6 +92,9 @@ { policy::key::kPolicyRefreshRate, policy::policy_prefs::kUserPolicyRefreshRate, base::Value::Type::INTEGER }, + { policy::key::kPolicyTestPageEnabled, + policy::policy_prefs::kPolicyTestPageEnabled, + base::Value::Type::BOOLEAN}, { policy::key::kPopupsAllowedForUrls, prefs::kManagedPopupsAllowedForUrls, base::Value::Type::LIST },
diff --git a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm index e2a65da..40bb79b 100644 --- a/ios/chrome/browser/shared/model/prefs/browser_prefs.mm +++ b/ios/chrome/browser/shared/model/prefs/browser_prefs.mm
@@ -292,6 +292,8 @@ [SigninPromoViewMediator registerBrowserStatePrefs:registry]; registry->RegisterBooleanPref(prefs::kBottomOmnibox, true); + registry->RegisterBooleanPref(policy::policy_prefs::kPolicyTestPageEnabled, + true); registry->RegisterBooleanPref(kDataSaverEnabled, false); registry->RegisterBooleanPref( prefs::kEnableDoNotTrack, false,
diff --git a/ios/chrome/browser/shared/public/commands/BUILD.gn b/ios/chrome/browser/shared/public/commands/BUILD.gn index 96182c00..e96179ac 100644 --- a/ios/chrome/browser/shared/public/commands/BUILD.gn +++ b/ios/chrome/browser/shared/public/commands/BUILD.gn
@@ -8,6 +8,7 @@ sources = [ "activity_service_commands.h", "application_commands.h", + "autofill_bottom_sheet_commands.h", "bookmarks_commands.h", "bring_android_tabs_commands.h", "browser_commands.h", @@ -30,7 +31,6 @@ "open_new_tab_command.h", "open_new_tab_command.mm", "page_info_commands.h", - "password_bottom_sheet_commands.h", "password_breach_commands.h", "password_protection_commands.h", "password_suggestion_commands.h",
diff --git a/ios/chrome/browser/shared/public/commands/password_bottom_sheet_commands.h b/ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h similarity index 67% rename from ios/chrome/browser/shared/public/commands/password_bottom_sheet_commands.h rename to ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h index 2782caa3..88cd6d7b 100644 --- a/ios/chrome/browser/shared/public/commands/password_bottom_sheet_commands.h +++ b/ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h
@@ -2,19 +2,19 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_PASSWORD_BOTTOM_SHEET_COMMANDS_H_ -#define IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_PASSWORD_BOTTOM_SHEET_COMMANDS_H_ +#ifndef IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_AUTOFILL_BOTTOM_SHEET_COMMANDS_H_ +#define IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_AUTOFILL_BOTTOM_SHEET_COMMANDS_H_ namespace autofill { struct FormActivityParams; } // namespace autofill // Commands related to the passwords bottom sheet. -@protocol PasswordBottomSheetCommands +@protocol AutofillBottomSheetCommands // Shows the password suggestion view controller. - (void)showPasswordBottomSheet:(const autofill::FormActivityParams&)params; @end -#endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_PASSWORD_BOTTOM_SHEET_COMMANDS_H_ +#endif // IOS_CHROME_BROWSER_SHARED_PUBLIC_COMMANDS_AUTOFILL_BOTTOM_SHEET_COMMANDS_H_
diff --git a/ios/chrome/browser/shared/public/features/features.h b/ios/chrome/browser/shared/public/features/features.h index 0489d4b..ee55e1c 100644 --- a/ios/chrome/browser/shared/public/features/features.h +++ b/ios/chrome/browser/shared/public/features/features.h
@@ -12,6 +12,9 @@ // Feature flag to enable default browser blue dot promo. BASE_DECLARE_FEATURE(kDefaultBrowserBlueDotPromo); +// Feature flag to enable the Payments Bottom Sheet. +BASE_DECLARE_FEATURE(kIOSPaymentsBottomSheet); + // Enum for blue dot promo user groups (control/experiment) and its param. The // reason why we need a custom control group is to disable other independent // default browser promos, which are already shipped.
diff --git a/ios/chrome/browser/shared/public/features/features.mm b/ios/chrome/browser/shared/public/features/features.mm index 3a5a67d..e377f0a 100644 --- a/ios/chrome/browser/shared/public/features/features.mm +++ b/ios/chrome/browser/shared/public/features/features.mm
@@ -14,6 +14,10 @@ "DefaultBrowserBlueDotPromo", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kIOSPaymentsBottomSheet, + "IOSPaymentsBottomSheet", + base::FEATURE_DISABLED_BY_DEFAULT); + constexpr base::FeatureParam<BlueDotPromoUserGroup>::Option kBlueDotPromoUserGroupOptions[] = { {BlueDotPromoUserGroup::kAllDBPromosDisabled, "all-db-promos-disabled"},
diff --git a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm index 81d1396..d8571a0 100644 --- a/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm +++ b/ios/chrome/browser/ui/autofill/form_input_accessory/form_input_accessory_mediator.mm
@@ -273,15 +273,14 @@ } // Return early if the URL can't be verified. - web::URLVerificationTrustLevel trustLevel; - const GURL pageURL(webState->GetCurrentURL(&trustLevel)); - if (trustLevel != web::URLVerificationTrustLevel::kAbsolute) { + absl::optional<GURL> pageURL = webState->GetLastCommittedURLIfTrusted(); + if (!pageURL) { [self reset]; return; } // Return early, pause and reset if the url is not HTML. - if (!web::UrlHasWebScheme(pageURL) || !webState->ContentIsHTML()) { + if (!web::UrlHasWebScheme(*pageURL) || !webState->ContentIsHTML()) { [self reset]; return; } @@ -415,14 +414,13 @@ } // Return early if the URL can't be verified. - web::URLVerificationTrustLevel trustLevel; - const GURL pageURL(_webState->GetCurrentURL(&trustLevel)); - if (trustLevel != web::URLVerificationTrustLevel::kAbsolute) { + absl::optional<GURL> pageURL = _webState->GetLastCommittedURLIfTrusted(); + if (!pageURL) { return NO; } // Return early if the url is not HTML. - if (!web::UrlHasWebScheme(pageURL) || !_webState->ContentIsHTML()) { + if (!web::UrlHasWebScheme(*pageURL) || !_webState->ContentIsHTML()) { return NO; }
diff --git a/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm b/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm index 2fcac012..38defaf 100644 --- a/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm +++ b/ios/chrome/browser/ui/autofill/manual_fill/address_view_controller_egtest.mm
@@ -139,8 +139,7 @@ // Tests that returning from "Manage Addresses..." leaves the icons and keyboard // in the right state. -// TODO(crbug.com/1111076): Flaky on iOS simulator and device. -- (void)DISABLED_testAddressesStateAfterPresentingManageAddresses { +- (void)testAddressesStateAfterPresentingManageAddresses { // Bring up the keyboard. [[EarlGrey selectElementWithMatcher:chrome_test_util::WebViewMatcher()] performAction:chrome_test_util::TapWebElementWithId(kFormElementName)];
diff --git a/ios/chrome/browser/ui/browser_container/browser_edit_menu_handler_egtest.mm b/ios/chrome/browser/ui/browser_container/browser_edit_menu_handler_egtest.mm index f94d223..8c9db60 100644 --- a/ios/chrome/browser/ui/browser_container/browser_edit_menu_handler_egtest.mm +++ b/ios/chrome/browser/ui/browser_container/browser_edit_menu_handler_egtest.mm
@@ -369,9 +369,9 @@ // Tests the menu on a normal word. - (void)testBasicMenu { #if !TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1445963): Test failing on iOS 16.4+ devices. - if (@available(iOS 16.4, *)) { - EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.4+ devices."); + // TODO(crbug.com/1445963): Test failing on iOS 16.2+ devices. + if (@available(iOS 16.2, *)) { + EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.2+ devices."); } #endif @@ -386,9 +386,9 @@ - (void)testEditableMenu { #if !TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1445963): Test failing on iOS 16.4+ devices. - if (@available(iOS 16.4, *)) { - EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.4+ devices."); + // TODO(crbug.com/1445963): Test failing on iOS 16.2+ devices. + if (@available(iOS 16.2, *)) { + EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.2+ devices."); } #endif @@ -408,9 +408,9 @@ - (void)testURLMenu { #if !TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1445963): Test failing on iOS 16.4+ devices. - if (@available(iOS 16.4, *)) { - EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.4+ devices."); + // TODO(crbug.com/1445963): Test failing on iOS 16.2+ devices. + if (@available(iOS 16.2, *)) { + EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.2+ devices."); } #endif @@ -430,9 +430,9 @@ - (void)testEmailMenu { #if !TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1445963): Test failing on iOS 16.4+ devices. - if (@available(iOS 16.4, *)) { - EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.4+ devices."); + // TODO(crbug.com/1445963): Test failing on iOS 16.2+ devices. + if (@available(iOS 16.2, *)) { + EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.2+ devices."); } #endif @@ -450,9 +450,9 @@ - (void)testPhoneMenu { #if !TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1445963): Test failing on iOS 16.4+ devices. - if (@available(iOS 16.4, *)) { - EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.4+ devices."); + // TODO(crbug.com/1445963): Test failing on iOS 16.2+ devices. + if (@available(iOS 16.2, *)) { + EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.2+ devices."); } #endif @@ -470,9 +470,9 @@ - (void)testDateMenu { #if !TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1445963): Test failing on iOS 16.4+ devices. - if (@available(iOS 16.4, *)) { - EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.4+ devices."); + // TODO(crbug.com/1445963): Test failing on iOS 16.2+ devices. + if (@available(iOS 16.2, *)) { + EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.2+ devices."); } #endif @@ -489,9 +489,9 @@ - (void)testUnitMenu { #if !TARGET_IPHONE_SIMULATOR - // TODO(crbug.com/1445963): Test failing on iOS 16.4+ devices. - if (@available(iOS 16.4, *)) { - EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.4+ devices."); + // TODO(crbug.com/1445963): Test failing on iOS 16.2+ devices. + if (@available(iOS 16.2, *)) { + EARL_GREY_TEST_DISABLED(@"crbug.com/1445963: Fails on iOS 16.2+ devices."); } #endif
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm index 9422b94..8c129cc 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator.mm
@@ -56,6 +56,7 @@ #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h" #import "ios/chrome/browser/shared/public/commands/activity_service_commands.h" #import "ios/chrome/browser/shared/public/commands/application_commands.h" +#import "ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h" #import "ios/chrome/browser/shared/public/commands/browser_coordinator_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" #import "ios/chrome/browser/shared/public/commands/feed_commands.h" @@ -63,7 +64,6 @@ #import "ios/chrome/browser/shared/public/commands/load_query_commands.h" #import "ios/chrome/browser/shared/public/commands/new_tab_page_commands.h" #import "ios/chrome/browser/shared/public/commands/page_info_commands.h" -#import "ios/chrome/browser/shared/public/commands/password_bottom_sheet_commands.h" #import "ios/chrome/browser/shared/public/commands/password_breach_commands.h" #import "ios/chrome/browser/shared/public/commands/password_protection_commands.h" #import "ios/chrome/browser/shared/public/commands/password_suggestion_commands.h" @@ -130,7 +130,6 @@ #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_mediator.h" #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_scene_agent.h" #import "ios/chrome/browser/ui/lens/lens_coordinator.h" -#import "ios/chrome/browser/ui/location_bar/location_bar_coordinator.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_component_factory.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h" #import "ios/chrome/browser/ui/overlays/overlay_container_coordinator.h" @@ -171,7 +170,7 @@ #import "ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_coordinating.h" #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.h" -#import "ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h" +#import "ios/chrome/browser/ui/toolbar/toolbar_coordinator.h" #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller.h" #import "ios/chrome/browser/ui/voice/text_to_speech_playback_controller_factory.h" #import "ios/chrome/browser/ui/webui/net_export_coordinator.h" @@ -330,9 +329,6 @@ @property(nonatomic, strong) FormInputAccessoryCoordinator* formInputAccessoryCoordinator; -// Coordinator for the location bar containing the omnibox. -@property(nonatomic, strong) LocationBarCoordinator* locationBarCoordinator; - // The container coordinators for the infobar modalities. @property(nonatomic, strong) OverlayContainerCoordinator* infobarBannerOverlayContainerCoordinator; @@ -449,9 +445,7 @@ BubblePresenter* _bubblePresenter; ToolbarAccessoryPresenter* _toolbarAccessoryPresenter; LensCoordinator* _lensCoordinator; - ToolbarCoordinatorAdaptor* _toolbarCoordinatorAdaptor; - PrimaryToolbarCoordinator* _primaryToolbarCoordinator; - SecondaryToolbarCoordinator* _secondaryToolbarCoordinator; + ToolbarCoordinator* _toolbarCoordinator; TabStripCoordinator* _tabStripCoordinator; TabStripLegacyCoordinator* _legacyTabStripCoordinator; SideSwipeController* _sideSwipeController; @@ -713,6 +707,7 @@ // handlers. NSArray<Protocol*>* protocols = @[ @protocol(ActivityServiceCommands), + @protocol(AutofillBottomSheetCommands), @protocol(BrowserCoordinatorCommands), @protocol(DefaultPromoCommands), @protocol(DefaultBrowserPromoNonModalCommands), @@ -721,7 +716,6 @@ @protocol(FindInPageCommands), @protocol(NewTabPageCommands), @protocol(PageInfoCommands), - @protocol(PasswordBottomSheetCommands), @protocol(PasswordBreachCommands), @protocol(PasswordProtectionCommands), @protocol(PasswordSuggestionCommands), @@ -763,23 +757,8 @@ WebNavigationBrowserAgent::FromBrowser(self.browser); _urlLoadingBrowserAgent = UrlLoadingBrowserAgent::FromBrowser(self.browser); - self.locationBarCoordinator = - [[LocationBarCoordinator alloc] initWithBrowser:self.browser]; - - _primaryToolbarCoordinator = - [[PrimaryToolbarCoordinator alloc] initWithBrowser:self.browser]; - _primaryToolbarCoordinator.locationBarCoordinator = - self.locationBarCoordinator; - - _secondaryToolbarCoordinator = - [[SecondaryToolbarCoordinator alloc] initWithBrowser:self.browser]; - - _toolbarCoordinatorAdaptor = - [[ToolbarCoordinatorAdaptor alloc] initWithDispatcher:_dispatcher]; - - [_toolbarCoordinatorAdaptor addToolbarCoordinator:_primaryToolbarCoordinator]; - [_toolbarCoordinatorAdaptor - addToolbarCoordinator:_secondaryToolbarCoordinator]; + _toolbarCoordinator = + [[ToolbarCoordinator alloc] initWithBrowser:self.browser]; feature_engagement::Tracker* engagementTracker = feature_engagement::TrackerFactory::GetForBrowserState(browserState); @@ -789,8 +768,6 @@ [[BubblePresenter alloc] initWithTracker:engagementTracker hostContentSettingsMap:settingsMap webStateList:self.browser->GetWebStateList()]; - _bubblePresenter.toolbarHandler = - HandlerForProtocol(_dispatcher, ToolbarCommands); _bubblePresenter.layoutGuideCenter = _layoutGuideCenter; [_dispatcher startDispatchingToTarget:_bubblePresenter forProtocol:@protocol(HelpCommands)]; @@ -803,11 +780,11 @@ _sideSwipeController = [[SideSwipeController alloc] initWithBrowser:self.browser]; [_sideSwipeController setSnapshotDelegate:self]; - _sideSwipeController.toolbarInteractionHandler = _toolbarCoordinatorAdaptor; + _sideSwipeController.toolbarInteractionHandler = _toolbarCoordinator; _sideSwipeController.primaryToolbarSnapshotProvider = - _primaryToolbarCoordinator; + _toolbarCoordinator.primaryToolbarSnapshotProvider; _sideSwipeController.secondaryToolbarSnapshotProvider = - _secondaryToolbarCoordinator; + _toolbarCoordinator.secondaryToolbarSnapshotProvider; _bookmarksCoordinator = [[BookmarksCoordinator alloc] initWithBrowser:self.browser]; @@ -831,7 +808,7 @@ self.popupMenuCoordinator = [[PopupMenuCoordinator alloc] initWithBrowser:self.browser]; self.popupMenuCoordinator.bubblePresenter = _bubblePresenter; - self.popupMenuCoordinator.UIUpdater = _toolbarCoordinatorAdaptor; + self.popupMenuCoordinator.UIUpdater = _toolbarCoordinator; // Coordinator `start` is executed before setting it's `baseViewController`. // It is done intentionally, since this does not affecting the coordinator's // behavior but helps command handler setup below. @@ -854,7 +831,7 @@ _NTPCoordinator = [[NewTabPageCoordinator alloc] initWithBrowser:self.browser componentFactory:[[NewTabPageComponentFactory alloc] init]]; - _NTPCoordinator.toolbarDelegate = _toolbarCoordinatorAdaptor; + _NTPCoordinator.toolbarDelegate = _toolbarCoordinator; _NTPCoordinator.bubblePresenter = _bubblePresenter; self.tabLifecycleMediator.NTPCoordinator = _NTPCoordinator; @@ -870,10 +847,7 @@ _viewControllerDependencies.popupMenuCoordinator = self.popupMenuCoordinator; _viewControllerDependencies.ntpCoordinator = _NTPCoordinator; _viewControllerDependencies.lensCoordinator = _lensCoordinator; - _viewControllerDependencies.primaryToolbarCoordinator = - _primaryToolbarCoordinator; - _viewControllerDependencies.secondaryToolbarCoordinator = - _secondaryToolbarCoordinator; + _viewControllerDependencies.toolbarCoordinator = _toolbarCoordinator; _viewControllerDependencies.tabStripCoordinator = _tabStripCoordinator; _viewControllerDependencies.legacyTabStripCoordinator = _legacyTabStripCoordinator; @@ -931,11 +905,9 @@ _lensCoordinator.baseViewController = self.viewController; [_lensCoordinator start]; - self.locationBarCoordinator.delegate = self.viewController; - self.locationBarCoordinator.popupPresenterDelegate = self.viewController; - [self.locationBarCoordinator start]; - - [_primaryToolbarCoordinator start]; + _toolbarCoordinator.omniboxFocusDelegate = self.viewController; + _toolbarCoordinator.popupPresenterDelegate = self.viewController; + [_toolbarCoordinator start]; _loadQueryCommandsHandler = HandlerForProtocol(_dispatcher, LoadQueryCommands); @@ -958,8 +930,7 @@ _viewControllerDependencies.popupMenuCoordinator = nil; _viewControllerDependencies.ntpCoordinator = nil; _viewControllerDependencies.lensCoordinator = nil; - _viewControllerDependencies.primaryToolbarCoordinator = nil; - _viewControllerDependencies.secondaryToolbarCoordinator = nil; + _viewControllerDependencies.toolbarCoordinator = nil; _viewControllerDependencies.tabStripCoordinator = nil; _viewControllerDependencies.legacyTabStripCoordinator = nil; _viewControllerDependencies.sideSwipeController = nil; @@ -982,9 +953,7 @@ _legacyTabStripCoordinator = nil; _tabStripCoordinator = nil; _sideSwipeController = nil; - _toolbarCoordinatorAdaptor = nil; - _secondaryToolbarCoordinator = nil; - _primaryToolbarCoordinator = nil; + _toolbarCoordinator = nil; _loadQueryCommandsHandler = nil; _omniboxCommandsHandler = nil; @@ -1010,9 +979,6 @@ [self.browserContainerCoordinator stop]; self.browserContainerCoordinator = nil; - [self.locationBarCoordinator stop]; - self.locationBarCoordinator = nil; - [_NTPCoordinator stop]; _NTPCoordinator = nil; @@ -1356,8 +1322,7 @@ // Exit fullscreen if needed to make sure that share button is visible. _fullscreenController->ExitFullscreen(); - id<SharingPositioner> positioner = - _primaryToolbarCoordinator.SharingPositioner; + id<SharingPositioner> positioner = _toolbarCoordinator.sharingPositioner; UIBarButtonItem* anchor = nil; if ([positioner respondsToSelector:@selector(barButtonItem)]) { anchor = positioner.barButtonItem; @@ -1427,7 +1392,7 @@ [self.sharingCoordinator start]; } -#pragma mark - PasswordBottomSheetCommands +#pragma mark - AutofillBottomSheetCommands - (void)showPasswordBottomSheet:(const autofill::FormActivityParams&)params { self.passwordSuggestionBottomSheetCoordinator =
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.h b/ios/chrome/browser/ui/browser_view/browser_view_controller.h index 34d7458..985fd65 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.h +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.h
@@ -39,15 +39,14 @@ class PagePlaceholderBrowserAgent; @protocol PopupMenuCommands; @class PopupMenuCoordinator; -@class PrimaryToolbarCoordinator; @class SafeAreaProvider; -@class SecondaryToolbarCoordinator; @class SideSwipeController; @class TabStripCoordinator; @class TabStripLegacyCoordinator; class TabUsageRecorderBrowserAgent; @protocol TextZoomCommands; @class ToolbarAccessoryPresenter; +@class ToolbarCoordinator; @protocol IncognitoReauthCommands; @class LayoutGuideCenter; @protocol LoadQueryCommands; @@ -63,8 +62,7 @@ PopupMenuCoordinator* popupMenuCoordinator; NewTabPageCoordinator* ntpCoordinator; LensCoordinator* lensCoordinator; - PrimaryToolbarCoordinator* primaryToolbarCoordinator; - SecondaryToolbarCoordinator* secondaryToolbarCoordinator; + ToolbarCoordinator* toolbarCoordinator; TabStripCoordinator* tabStripCoordinator; TabStripLegacyCoordinator* legacyTabStripCoordinator; SideSwipeController* sideSwipeController;
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index 34e3ab5f..4675f6a 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -81,6 +81,7 @@ #import "ios/chrome/browser/ui/toolbar/public/toolbar_constants.h" #import "ios/chrome/browser/ui/toolbar/public/toolbar_utils.h" #import "ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.h" +#import "ios/chrome/browser/ui/toolbar/toolbar_coordinator.h" #import "ios/chrome/browser/url_loading/url_loading_browser_agent.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_browser_agent.h" #import "ios/chrome/browser/url_loading/url_loading_params.h" @@ -363,12 +364,9 @@ // The FullscreenController. @property(nonatomic, assign) FullscreenController* fullscreenController; -// Primary toolbar. -@property(nonatomic, strong) - PrimaryToolbarCoordinator* primaryToolbarCoordinator; -// Secondary toolbar. -@property(nonatomic, strong) - AdaptiveToolbarCoordinator* secondaryToolbarCoordinator; +// Coordinator of primary and secondary toolbars. +@property(nonatomic, strong) ToolbarCoordinator* toolbarCoordinator; + // The container view for the secondary toolbar. // TODO(crbug.com/880656): Convert to a container coordinator. @property(nonatomic, strong) UIView* secondaryToolbarContainerView; @@ -436,8 +434,7 @@ self.toolbarAccessoryPresenter = dependencies.toolbarAccessoryPresenter; self.ntpCoordinator = dependencies.ntpCoordinator; self.popupMenuCoordinator = dependencies.popupMenuCoordinator; - self.primaryToolbarCoordinator = dependencies.primaryToolbarCoordinator; - self.secondaryToolbarCoordinator = dependencies.secondaryToolbarCoordinator; + self.toolbarCoordinator = dependencies.toolbarCoordinator; self.tabStripCoordinator = dependencies.tabStripCoordinator; self.legacyTabStripCoordinator = dependencies.legacyTabStripCoordinator; @@ -599,22 +596,26 @@ return results; if (!IsRegularXRegularSizeClass(self)) { - if (self.primaryToolbarCoordinator.viewController.view) { - [results addObject:[HeaderDefinition - definitionWithView:self.primaryToolbarCoordinator - .viewController.view - headerBehaviour:Hideable]]; + if (self.toolbarCoordinator.primaryToolbarViewController.view) { + [results + addObject:[HeaderDefinition + definitionWithView:self.toolbarCoordinator + .primaryToolbarViewController + .view + headerBehaviour:Hideable]]; } } else { if (self.tabStripView) { [results addObject:[HeaderDefinition definitionWithView:self.tabStripView headerBehaviour:Hideable]]; } - if (self.primaryToolbarCoordinator.viewController.view) { - [results addObject:[HeaderDefinition - definitionWithView:self.primaryToolbarCoordinator - .viewController.view - headerBehaviour:Hideable]]; + if (self.toolbarCoordinator.primaryToolbarViewController.view) { + [results + addObject:[HeaderDefinition + definitionWithView:self.toolbarCoordinator + .primaryToolbarViewController + .view + headerBehaviour:Hideable]]; } if (self.toolbarAccessoryPresenter.isPresenting) { [results addObject:[HeaderDefinition @@ -900,10 +901,8 @@ [self.contentArea removeGestureRecognizer:self.contentAreaGestureRecognizer]; - [self.primaryToolbarCoordinator stop]; - self.primaryToolbarCoordinator = nil; - [self.secondaryToolbarCoordinator stop]; - self.secondaryToolbarCoordinator = nil; + [self.toolbarCoordinator stop]; + self.toolbarCoordinator = nil; _sideSwipeController = nil; [_voiceSearchController disconnect]; _fullscreenDisabler = nullptr; @@ -1091,10 +1090,8 @@ if (![self isViewLoaded]) { self.typingShield = nil; _voiceSearchController.dispatcher = nil; - [self.primaryToolbarCoordinator stop]; - self.primaryToolbarCoordinator = nil; - [self.secondaryToolbarCoordinator stop]; - self.secondaryToolbarCoordinator = nil; + [self.toolbarCoordinator stop]; + self.toolbarCoordinator = nil; _toolbarUIState = nil; if (base::FeatureList::IsEnabled(kModernTabStrip)) { [self.tabStripCoordinator stop]; @@ -1156,7 +1153,7 @@ // Update the toolbar visibility. // TODO(crbug.com/1329087): Move this update to the toolbar view // controller(s)? - [self.primaryToolbarCoordinator updateToolbar]; + [self.toolbarCoordinator.primaryToolbarCoordinator updateToolbar]; // Update the tab strip visibility. if (self.tabStripView) { @@ -1418,8 +1415,6 @@ - (void)buildToolbarAndTabStrip { DCHECK([self isViewLoaded]); - [self.secondaryToolbarCoordinator start]; - [self updateBroadcastState]; if (_voiceSearchController) { _voiceSearchController.dispatcher = self.loadQueryCommandsHandler; @@ -1450,7 +1445,8 @@ // The height of the primary toolbar with the top safe area inset included. - (CGFloat)primaryToolbarHeightWithInset { - UIView* primaryToolbar = self.primaryToolbarCoordinator.viewController.view; + UIView* primaryToolbar = + self.toolbarCoordinator.primaryToolbarViewController.view; CGFloat intrinsicHeight = primaryToolbar.intrinsicContentSize.height; if (!IsSplitToolbarMode(self)) { // When the adaptive toolbar is unsplit, add a margin. @@ -1480,7 +1476,7 @@ return 0; UIView* secondaryToolbar = - self.secondaryToolbarCoordinator.viewController.view; + self.toolbarCoordinator.secondaryToolbarViewController.view; // Add the safe area inset to the toolbar height. CGFloat unsafeHeight = self.rootSafeAreaInsets.bottom; return secondaryToolbar.intrinsicContentSize.height + unsafeHeight; @@ -1522,9 +1518,9 @@ // whether we've already added the leading and trailing constraints. if (!self.primaryToolbarOffsetConstraint) { [NSLayoutConstraint activateConstraints:@[ - [self.primaryToolbarCoordinator.viewController.view.leadingAnchor + [self.toolbarCoordinator.primaryToolbarViewController.view.leadingAnchor constraintEqualToAnchor:[self view].leadingAnchor], - [self.primaryToolbarCoordinator.viewController.view.trailingAnchor + [self.toolbarCoordinator.primaryToolbarViewController.view.trailingAnchor constraintEqualToAnchor:[self view].trailingAnchor], ]]; } @@ -1534,7 +1530,8 @@ self.primaryToolbarHeightConstraint.active = NO; // Create a constraint for the vertical positioning of the toolbar. - UIView* primaryView = self.primaryToolbarCoordinator.viewController.view; + UIView* primaryView = + self.toolbarCoordinator.primaryToolbarViewController.view; self.primaryToolbarOffsetConstraint = [primaryView.topAnchor constraintEqualToAnchor:topAnchor]; @@ -1548,29 +1545,28 @@ } - (void)addConstraintsToSecondaryToolbar { - if (self.secondaryToolbarCoordinator) { - // Create a constraint for the height of the toolbar to include the unsafe - // area height. - UIView* toolbarView = self.secondaryToolbarCoordinator.viewController.view; - self.secondaryToolbarHeightConstraint = [toolbarView.heightAnchor - constraintEqualToConstant:[self secondaryToolbarHeightWithInset]]; - self.secondaryToolbarHeightConstraint.active = YES; - AddSameConstraintsToSides( - self.secondaryToolbarContainerView, toolbarView, - LayoutSides::kBottom | LayoutSides::kLeading | LayoutSides::kTrailing); + // Create a constraint for the height of the toolbar to include the unsafe + // area height. + UIView* toolbarView = + self.toolbarCoordinator.secondaryToolbarViewController.view; + self.secondaryToolbarHeightConstraint = [toolbarView.heightAnchor + constraintEqualToConstant:[self secondaryToolbarHeightWithInset]]; + self.secondaryToolbarHeightConstraint.active = YES; + AddSameConstraintsToSides( + self.secondaryToolbarContainerView, toolbarView, + LayoutSides::kBottom | LayoutSides::kLeading | LayoutSides::kTrailing); - // Constrain the container view to the bottom of self.view, and add a - // constant height constraint such that the container's frame is equal to - // that of the secondary toolbar at a fullscreen progress of 1.0. - UIView* containerView = self.secondaryToolbarContainerView; - self.secondaryToolbarNoFullscreenHeightConstraint = - [containerView.heightAnchor - constraintEqualToConstant:[self secondaryToolbarHeightWithInset]]; - self.secondaryToolbarNoFullscreenHeightConstraint.active = YES; - AddSameConstraintsToSides( - self.view, containerView, - LayoutSides::kBottom | LayoutSides::kLeading | LayoutSides::kTrailing); - } + // Constrain the container view to the bottom of self.view, and add a + // constant height constraint such that the container's frame is equal to + // that of the secondary toolbar at a fullscreen progress of 1.0. + UIView* containerView = self.secondaryToolbarContainerView; + self.secondaryToolbarNoFullscreenHeightConstraint = + [containerView.heightAnchor + constraintEqualToConstant:[self secondaryToolbarHeightWithInset]]; + self.secondaryToolbarNoFullscreenHeightConstraint.active = YES; + AddSameConstraintsToSides( + self.view, containerView, + LayoutSides::kBottom | LayoutSides::kLeading | LayoutSides::kTrailing); } // Adds constraints to the primary and secondary toolbars, anchoring them to the @@ -1600,16 +1596,15 @@ if (initialLayout) { // Add the toolbars as child view controllers. - [self addChildViewController:self.primaryToolbarCoordinator.viewController]; - if (self.secondaryToolbarCoordinator) { - [self addChildViewController:self.secondaryToolbarCoordinator - .viewController]; - } + [self addChildViewController:self.toolbarCoordinator + .primaryToolbarViewController]; + [self addChildViewController:self.toolbarCoordinator + .secondaryToolbarViewController]; // Add the primary toolbar. On iPad, it should be in front of the tab strip // because the tab strip slides behind it when showing the thumb strip. UIView* primaryToolbarView = - self.primaryToolbarCoordinator.viewController.view; + self.toolbarCoordinator.primaryToolbarViewController.view; if (ui::GetDeviceFormFactor() == ui::DEVICE_FORM_FACTOR_TABLET) { if (base::FeatureList::IsEnabled(kModernTabStrip) && self.tabStripCoordinator) { @@ -1625,16 +1620,14 @@ } // Add the secondary toolbar. - if (self.secondaryToolbarCoordinator) { - // Create the container view for the secondary toolbar and add it to - // the hierarchy - UIView* container = [[LegacyToolbarContainerView alloc] init]; - container.translatesAutoresizingMaskIntoConstraints = NO; - [container - addSubview:self.secondaryToolbarCoordinator.viewController.view]; - [self.view insertSubview:container aboveSubview:primaryToolbarView]; - self.secondaryToolbarContainerView = container; - } + // Create the container view for the secondary toolbar and add it to + // the hierarchy + UIView* container = [[LegacyToolbarContainerView alloc] init]; + container.translatesAutoresizingMaskIntoConstraints = NO; + [container + addSubview:self.toolbarCoordinator.secondaryToolbarViewController.view]; + [self.view insertSubview:container aboveSubview:primaryToolbarView]; + self.secondaryToolbarContainerView = container; // Create the NamedGuides and add them to the browser view. NSArray<GuideName*>* guideNames = @[ @@ -1664,31 +1657,24 @@ .active = YES; LayoutSides contentSides = LayoutSides::kLeading | LayoutSides::kTrailing; - if (self.secondaryToolbarCoordinator) { - // If there's a bottom toolbar, the content area guide is constrained to - // its top. - UIView* secondaryToolbarView = - self.secondaryToolbarCoordinator.viewController.view; - [contentAreaGuide.bottomAnchor - constraintEqualToAnchor:secondaryToolbarView.topAnchor] - .active = YES; - } else { - // Otherwise, the content area guide is constrained to self.view's bootom - // along with its sides; - contentSides = contentSides | LayoutSides::kBottom; - } + // If there's a bottom toolbar, the content area guide is constrained to + // its top. + UIView* secondaryToolbarView = + self.toolbarCoordinator.secondaryToolbarViewController.view; + [contentAreaGuide.bottomAnchor + constraintEqualToAnchor:secondaryToolbarView.topAnchor] + .active = YES; + AddSameConstraintsToSides(self.view, contentAreaGuide, contentSides); // Complete child UIViewController containment flow now that the views are // finished being added. [self.tabStripCoordinator.viewController didMoveToParentViewController:self]; - [self.primaryToolbarCoordinator.viewController + [self.toolbarCoordinator.primaryToolbarViewController didMoveToParentViewController:self]; - if (self.secondaryToolbarCoordinator) { - [self.secondaryToolbarCoordinator.viewController - didMoveToParentViewController:self]; - } + [self.toolbarCoordinator.secondaryToolbarViewController + didMoveToParentViewController:self]; } // Resize the typing shield to cover the entire browser view and bring it to @@ -1759,7 +1745,7 @@ } // TODO(crbug.com/1329087): Move this update to the toolbar coordinator, // somehow. - [self.primaryToolbarCoordinator updateToolbar]; + [self.toolbarCoordinator.primaryToolbarCoordinator updateToolbar]; [self updateWebStateVisibility:YES]; } @@ -1813,7 +1799,7 @@ // Returns the footer view if one exists (e.g. the voice search bar). - (UIView*)footerView { - return self.secondaryToolbarCoordinator.viewController.view; + return self.toolbarCoordinator.secondaryToolbarViewController.view; } // Returns the appropriate frame for the NTP. @@ -1841,7 +1827,8 @@ for (HeaderDefinition* header in headers) { CGFloat yOrigin = height - headerOffset; BOOL isPrimaryToolbar = - header.view == self.primaryToolbarCoordinator.viewController.view; + header.view == + self.toolbarCoordinator.primaryToolbarViewController.view; // Make sure the toolbarView's constraints are also updated. Leaving the // -setFrame call to minimize changes in this CL -- otherwise the way // toolbar_view manages it's alpha changes would also need to be updated. @@ -1931,11 +1918,10 @@ [panHandler addAnimatee:self]; DCHECK([self isViewLoaded]); - DCHECK(self.primaryToolbarCoordinator.animatee); - [panHandler addAnimatee:self.primaryToolbarCoordinator.animatee]; + [panHandler addAnimatee:self.toolbarCoordinator.viewRevealingAnimatee]; - self.primaryToolbarCoordinator.panGestureHandler = panHandler; + self.toolbarCoordinator.panGestureHandler = panHandler; if (!base::FeatureList::IsEnabled(kModernTabStrip)) { self.legacyTabStripCoordinator.panGestureHandler = panHandler; } @@ -1958,7 +1944,7 @@ - (void)thumbStripDisabled { DCHECK([self isThumbStripEnabled]); - self.primaryToolbarCoordinator.panGestureHandler = nil; + self.toolbarCoordinator.panGestureHandler = nil; if (!base::FeatureList::IsEnabled(kModernTabStrip)) { self.legacyTabStripCoordinator.panGestureHandler = nil; } @@ -2308,12 +2294,12 @@ - (UIView*)headerViewForOverscrollActionsController: (OverscrollActionsController*)controller { - return self.primaryToolbarCoordinator.viewController.view; + return self.toolbarCoordinator.primaryToolbarViewController.view; } - (UIView*)toolbarSnapshotViewForOverscrollActionsController: (OverscrollActionsController*)controller { - return [self.primaryToolbarCoordinator.viewController.view + return [self.toolbarCoordinator.primaryToolbarViewController.view snapshotViewAfterScreenUpdates:NO]; } @@ -2508,7 +2494,8 @@ // Prerender tab does not have a toolbar, return `headerHeight` as promised by // API documentation. - if ([self.primaryToolbarCoordinator isLoadingPrerenderer]) { + if ([self.toolbarCoordinator + .primaryToolbarCoordinator isLoadingPrerenderer]) { return self.headerHeight; } @@ -2542,7 +2529,8 @@ }]; } - [self.primaryToolbarCoordinator transitionToLocationBarFocusedState:YES]; + [self.toolbarCoordinator.primaryToolbarCoordinator + transitionToLocationBarFocusedState:YES]; } - (void)omniboxDidResignFirstResponder { @@ -2559,13 +2547,15 @@ // on the omnibox again during this animation. If the animation is // interrupted and the toolbar controller is first responder, it's safe // to assume `self.typingShield` shouldn't be hidden here. - if (!finished && - [self.primaryToolbarCoordinator isOmniboxFirstResponder]) + if (!finished && [self.toolbarCoordinator.primaryToolbarCoordinator + isOmniboxFirstResponder]) { return; + } [self.typingShield setHidden:YES]; }]; - [self.primaryToolbarCoordinator transitionToLocationBarFocusedState:NO]; + [self.toolbarCoordinator.primaryToolbarCoordinator + transitionToLocationBarFocusedState:NO]; } #pragma mark - BrowserCommands @@ -2677,12 +2667,14 @@ topMargin:[self snapshotEdgeInsetsForWebState:webStateBeingActivated] .top]; - [swipeView setTopToolbarImage:[self.primaryToolbarCoordinator - toolbarSideSwipeSnapshotForWebState: - webStateBeingActivated]]; - [swipeView setBottomToolbarImage:[self.secondaryToolbarCoordinator - toolbarSideSwipeSnapshotForWebState: - webStateBeingActivated]]; + [swipeView + setTopToolbarImage: + [self.toolbarCoordinator.primaryToolbarSnapshotProvider + toolbarSideSwipeSnapshotForWebState:webStateBeingActivated]]; + [swipeView + setBottomToolbarImage: + [self.toolbarCoordinator.secondaryToolbarSnapshotProvider + toolbarSideSwipeSnapshotForWebState:webStateBeingActivated]]; SnapshotTabHelper::FromWebState(webStateBeingActivated) ->RetrieveColorSnapshot(^(UIImage* image) { @@ -2762,7 +2754,7 @@ // Add a snapshot of the primary toolbar to the background as the // animation runs. UIViewController* toolbarViewController = - self.primaryToolbarCoordinator.viewController; + self.toolbarCoordinator.primaryToolbarViewController; toolbarSnapshot = [toolbarViewController.view snapshotViewAfterScreenUpdates:NO]; toolbarSnapshot.frame = [self.contentArea convertRect:toolbarSnapshot.frame @@ -2914,7 +2906,7 @@ // TODO(crbug.com/1329087): Signal to the toolbar coordinator to perform this // update. Longer-term, make SideSwipeControllerDelegate observable instead of // delegating. - [self.primaryToolbarCoordinator updateToolbar]; + [self.toolbarCoordinator.primaryToolbarCoordinator updateToolbar]; // Reset horizontal stack view. [sideSwipeView removeFromSuperview]; @@ -2953,7 +2945,7 @@ // TODO(crbug.com/1329087): Signal to the toolbar coordinator to perform // this update. Longer-term, make SideSwipeControllerDelegate observable // instead of delegating. - [self.primaryToolbarCoordinator updateToolbar]; + [self.toolbarCoordinator.primaryToolbarCoordinator updateToolbar]; } else { // Hide UI accessories such as find bar and first visit overlays // for welcome page. @@ -2966,18 +2958,21 @@ // If the toolbar is hidden, only inset the side swipe navigation view by // `safeAreaInsets.top`. Otherwise insetting by `self.headerHeight` would // show a grey strip where the toolbar would normally be. - if (self.primaryToolbarCoordinator.viewController.view.hidden) + if (self.toolbarCoordinator.primaryToolbarViewController.view.hidden) { return self.rootSafeAreaInsets.top; + } return self.headerHeight; } - (BOOL)canBeginToolbarSwipe { - return ![self.primaryToolbarCoordinator isOmniboxFirstResponder] && - ![self.primaryToolbarCoordinator showingOmniboxPopup]; + return ![self.toolbarCoordinator + .primaryToolbarCoordinator isOmniboxFirstResponder] && + ![self.toolbarCoordinator + .primaryToolbarCoordinator showingOmniboxPopup]; } - (UIView*)topToolbarView { - return self.primaryToolbarCoordinator.viewController.view; + return self.toolbarCoordinator.primaryToolbarViewController.view; } #pragma mark - LogoAnimationControllerOwnerOwner (Public) @@ -3014,8 +3009,9 @@ [self.tabStripView setFrame:tabStripFrame]; // The tab strip should be behind the toolbar, because it slides behind the // toolbar during the transition to the thumb strip. - [self.view insertSubview:tabStripView - belowSubview:self.primaryToolbarCoordinator.viewController.view]; + [self.view + insertSubview:tabStripView + belowSubview:self.toolbarCoordinator.primaryToolbarViewController.view]; } #pragma mark - FindBarPresentationDelegate @@ -3030,7 +3026,7 @@ (FindBarCoordinator*)findBarCoordinator { // When the Find bar is presented, hide underlying elements from VoiceOver. self.contentArea.accessibilityElementsHidden = YES; - self.primaryToolbarCoordinator.viewController.view + self.toolbarCoordinator.primaryToolbarViewController.view .accessibilityElementsHidden = YES; self.secondaryToolbarContainerView.accessibilityElementsHidden = YES; } @@ -3039,7 +3035,7 @@ (FindBarCoordinator*)findBarCoordinator { // When the Find bar is dismissed, show underlying elements to VoiceOver. self.contentArea.accessibilityElementsHidden = NO; - self.primaryToolbarCoordinator.viewController.view + self.toolbarCoordinator.primaryToolbarViewController.view .accessibilityElementsHidden = NO; self.secondaryToolbarContainerView.accessibilityElementsHidden = NO; }
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm index 9eb26f8..4a58fd4c 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller_unittest.mm
@@ -55,7 +55,6 @@ #import "ios/chrome/browser/ui/bubble/bubble_presenter.h" #import "ios/chrome/browser/ui/fullscreen/fullscreen_controller.h" #import "ios/chrome/browser/ui/incognito_reauth/incognito_reauth_commands.h" -#import "ios/chrome/browser/ui/location_bar/location_bar_coordinator.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_component_factory.h" #import "ios/chrome/browser/ui/ntp/new_tab_page_coordinator.h" #import "ios/chrome/browser/ui/popup_menu/popup_menu_coordinator.h" @@ -63,9 +62,7 @@ #import "ios/chrome/browser/ui/tab_switcher/tab_strip/tab_strip_coordinator.h" #import "ios/chrome/browser/ui/tabs/foreground_tab_animation_view.h" #import "ios/chrome/browser/ui/tabs/tab_strip_legacy_coordinator.h" -#import "ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.h" -#import "ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.h" -#import "ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h" +#import "ios/chrome/browser/ui/toolbar/toolbar_coordinator.h" #import "ios/chrome/browser/url_loading/new_tab_animation_tab_helper.h" #import "ios/chrome/browser/url_loading/url_loading_notifier_browser_agent.h" #import "ios/chrome/browser/web/page_placeholder_browser_agent.h" @@ -225,21 +222,9 @@ [[PopupMenuCoordinator alloc] initWithBrowser:browser_.get()]; [popup_menu_coordinator_ start]; - toolbar_coordinator_adaptor_ = - [[ToolbarCoordinatorAdaptor alloc] initWithDispatcher:dispatcher]; - - location_bar_coordinator_ = - [[LocationBarCoordinator alloc] initWithBrowser:browser_.get()]; - [location_bar_coordinator_ start]; - - primary_toolbar_coordinator_ = - [[PrimaryToolbarCoordinator alloc] initWithBrowser:browser_.get()]; - primary_toolbar_coordinator_.locationBarCoordinator = - location_bar_coordinator_; - [primary_toolbar_coordinator_ start]; - - secondary_toolbar_coordinator_ = - [[SecondaryToolbarCoordinator alloc] initWithBrowser:browser_.get()]; + toolbar_coordinator_ = + [[ToolbarCoordinator alloc] initWithBrowser:browser_.get()]; + [toolbar_coordinator_ start]; feature_engagement::Tracker* tracker = feature_engagement::TrackerFactory::GetForBrowserState( @@ -281,8 +266,7 @@ BrowserViewControllerDependencies dependencies; dependencies.bubblePresenter = bubble_presenter_; dependencies.popupMenuCoordinator = popup_menu_coordinator_; - dependencies.primaryToolbarCoordinator = primary_toolbar_coordinator_; - dependencies.secondaryToolbarCoordinator = secondary_toolbar_coordinator_; + dependencies.toolbarCoordinator = toolbar_coordinator_; dependencies.tabStripCoordinator = tab_strip_coordinator_; dependencies.legacyTabStripCoordinator = legacy_tab_strip_coordinator_; dependencies.sideSwipeController = side_swipe_controller_; @@ -336,7 +320,6 @@ } void TearDown() override { - [location_bar_coordinator_ stop]; [tab_events_mediator_ disconnect]; [[bvc_ view] removeFromSuperview]; [bvc_ shutdown]; @@ -393,10 +376,7 @@ UIWindow* window_; SceneState* scene_state_; PopupMenuCoordinator* popup_menu_coordinator_; - LocationBarCoordinator* location_bar_coordinator_; - ToolbarCoordinatorAdaptor* toolbar_coordinator_adaptor_; - PrimaryToolbarCoordinator* primary_toolbar_coordinator_; - SecondaryToolbarCoordinator* secondary_toolbar_coordinator_; + ToolbarCoordinator* toolbar_coordinator_; TabStripCoordinator* tab_strip_coordinator_; TabStripLegacyCoordinator* legacy_tab_strip_coordinator_; SideSwipeController* side_swipe_controller_;
diff --git a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm b/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm index 85de6891..1da67171 100644 --- a/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm +++ b/ios/chrome/browser/ui/browser_view/tab_lifecycle_mediator.mm
@@ -18,8 +18,8 @@ #import "ios/chrome/browser/passwords/password_tab_helper.h" #import "ios/chrome/browser/prerender/prerender_service.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" +#import "ios/chrome/browser/shared/public/commands/autofill_bottom_sheet_commands.h" #import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" -#import "ios/chrome/browser/shared/public/commands/password_bottom_sheet_commands.h" #import "ios/chrome/browser/shared/public/commands/web_content_commands.h" #import "ios/chrome/browser/snapshots/snapshot_tab_helper.h" #import "ios/chrome/browser/ssl/captive_portal_tab_helper.h" @@ -89,8 +89,8 @@ AutofillBottomSheetTabHelper* bottomSheetTabHelper = AutofillBottomSheetTabHelper::FromWebState(webState); - bottomSheetTabHelper->SetPasswordBottomSheetHandler( - HandlerForProtocol(_commandDispatcher, PasswordBottomSheetCommands)); + bottomSheetTabHelper->SetAutofillBottomSheetHandler( + HandlerForProtocol(_commandDispatcher, AutofillBottomSheetCommands)); DCHECK(_delegate); OverscrollActionsTabHelper::FromWebState(webState)->SetDelegate(_delegate); @@ -164,7 +164,7 @@ AutofillBottomSheetTabHelper* bottomSheetTabHelper = AutofillBottomSheetTabHelper::FromWebState(webState); - bottomSheetTabHelper->SetPasswordBottomSheetHandler(nil); + bottomSheetTabHelper->SetAutofillBottomSheetHandler(nil); OverscrollActionsTabHelper::FromWebState(webState)->SetDelegate(nil);
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.h b/ios/chrome/browser/ui/bubble/bubble_presenter.h index 4681c453f..3d2ebda 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.h +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.h
@@ -12,7 +12,6 @@ @class BubbleViewControllerPresenter; class HostContentSettingsMap; @class LayoutGuideCenter; -@protocol ToolbarCommands; class WebStateList; namespace feature_engagement { @@ -38,7 +37,6 @@ @property(nonatomic, weak) id<BubblePresenterDelegate> delegate; @property(nonatomic, weak) UIViewController* rootViewController; -@property(nonatomic, weak) id<ToolbarCommands> toolbarHandler; @property(nonatomic, strong) LayoutGuideCenter* layoutGuideCenter; // Stops this presenter.
diff --git a/ios/chrome/browser/ui/bubble/bubble_presenter.mm b/ios/chrome/browser/ui/bubble/bubble_presenter.mm index 7728bf2..cdf61c7e 100644 --- a/ios/chrome/browser/ui/bubble/bubble_presenter.mm +++ b/ios/chrome/browser/ui/bubble/bubble_presenter.mm
@@ -17,7 +17,6 @@ #import "ios/chrome/browser/shared/model/url/chrome_url_constants.h" #import "ios/chrome/browser/shared/model/url/url_util.h" #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" -#import "ios/chrome/browser/shared/public/commands/toolbar_commands.h" #import "ios/chrome/browser/shared/ui/util/named_guide.h" #import "ios/chrome/browser/shared/ui/util/uikit_ui_util.h" #import "ios/chrome/browser/shared/ui/util/util_swift.h"
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn index 3fc56c6..e649dd2 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn +++ b/ios/chrome/browser/ui/settings/password/password_issues/BUILD.gn
@@ -99,6 +99,7 @@ "//ios/chrome/browser/shared/model/browser/test:test_support", "//ios/chrome/browser/shared/model/browser_state:test_support", "//ios/chrome/browser/shared/ui/table_view:test_support", + "//ios/chrome/browser/shared/ui/table_view/cells", "//ios/chrome/browser/sync", "//ios/chrome/browser/sync:test_support", "//ios/chrome/browser/ui/settings/password/password_checkup:password_checkup_constants",
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_consumer.h b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_consumer.h index 3145864c..1a1b3f5 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_consumer.h +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_consumer.h
@@ -11,9 +11,9 @@ // Consumer for the Password Issues Screen. @protocol PasswordIssuesConsumer <NSObject> -// Pass password issues to the consumer. +// Passes password issues to the consumer. - (void)setPasswordIssues:(NSArray<PasswordIssueGroup*>*)passwordGroups - dismissedWarningsButtonText:(NSString*)buttonText; + dismissedWarningsCount:(NSInteger)dismissedWarnings; // Sets the navigation bar title. - (void)setNavigationBarTitle:(NSString*)title;
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm index e7cc869..eaaecf9 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator.mm
@@ -135,15 +135,6 @@ } } -// Builds the text of the Dismissed Warnings button in the consumer. -NSString* GetDismissedWarningsButtonText(NSInteger dismissed_warnings_count) { - return dismissed_warnings_count > 0 - ? l10n_util::GetNSStringF( - IDS_IOS_COMPROMISED_PASSWORD_ISSUES_DISMISSED_WARNINGS_BUTTON_TITLE, - base::NumberToString16(dismissed_warnings_count)) - : nil; -} - // Computes the number of dimissed insecure credentials warnings. // Only Compromissed credentials warnings can be dismissed, other warning types // always return 0. @@ -292,10 +283,9 @@ NSArray<PasswordIssueGroup*>* passwordIssueGroups = GetPasswordIssueGroups(_warningType, insecureCredentialsForWarningType); - NSString* dismissedCredentialsButtonText = - GetDismissedWarningsButtonText(dismissedWarningsCount); + [self.consumer setPasswordIssues:passwordIssueGroups - dismissedWarningsButtonText:dismissedCredentialsButtonText]; + dismissedWarningsCount:dismissedWarningsCount]; [self.consumer setNavigationBarTitle:[self @@ -314,10 +304,10 @@ _manager->GetInsecureCredentials(); [self.consumer - setPasswordIssues:GetPasswordIssueGroups( - WarningType::kCompromisedPasswordsWarning, - insecureCredentials) - dismissedWarningsButtonText:nil]; + setPasswordIssues:GetPasswordIssueGroups( + WarningType::kCompromisedPasswordsWarning, + insecureCredentials) + dismissedWarningsCount:0]; } // Computes the navigation bar title based on `_warningType` and number of
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator_unittest.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator_unittest.mm index 2138cb9..1b416aa 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_mediator_unittest.mm
@@ -98,16 +98,16 @@ @property(nonatomic, copy) CrURL* headerURL; -@property(nonatomic, copy) NSString* dismissedWarningsButtonText; +@property(nonatomic, assign) NSInteger dismissedWarningsCount; @end @implementation FakePasswordIssuesConsumer - (void)setPasswordIssues:(NSArray<PasswordIssueGroup*>*)passwordIssueGroups - dismissedWarningsButtonText:(NSString*)buttonText { + dismissedWarningsCount:(NSInteger)dismissedWarningsCount { _passwordIssueGroups = passwordIssueGroups; - _dismissedWarningsButtonText = buttonText; + _dismissedWarningsCount = dismissedWarningsCount; _passwordIssuesListChangedWasCalled = YES; } @@ -314,15 +314,14 @@ CheckIssue(/*group=*/0, /*index=*/0, /*expected_website=*/kExampleString, /*expected_username=*/GetUsername2()); - EXPECT_NSEQ(consumer().dismissedWarningsButtonText, - @"Dismissed Warnings (1)"); + EXPECT_EQ(consumer().dismissedWarningsCount, 1); // Send only weak passwords to consumer. CreateMediator(WarningType::kWeakPasswordsWarning); CheckIssue(); - EXPECT_FALSE(consumer().dismissedWarningsButtonText); + EXPECT_EQ(0, consumer().dismissedWarningsCount); // Send only reused passwords to consumer. CreateMediator(WarningType::kReusedPasswordsWarning); @@ -331,14 +330,14 @@ CheckIssue(/*group=*/0, /*index=*/1, /*expected_website=*/kExample3String, /*expected_username=*/GetUsername2()); - EXPECT_FALSE(consumer().dismissedWarningsButtonText); + EXPECT_EQ(0, consumer().dismissedWarningsCount); // Send only dismissed passwords to consumer. CreateMediator(WarningType::kDismissedWarningsWarning); CheckIssue(/*group=*/0, /*index=*/0, /*expected_website=*/kExample3String); - EXPECT_FALSE(consumer().dismissedWarningsButtonText); + EXPECT_EQ(0, consumer().dismissedWarningsCount); } /// Tests the mediator sets the consumer title for compromised passwords.
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm index ae57b7a..e704d29 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller.mm
@@ -9,6 +9,7 @@ #import "components/password_manager/core/common/password_manager_features.h" #import "ios/chrome/browser/passwords/password_checkup_metrics.h" #import "ios/chrome/browser/passwords/password_checkup_utils.h" +#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_multi_detail_text_item.h" #import "ios/chrome/browser/shared/ui/table_view/cells/table_view_text_item.h" #import "ios/chrome/browser/shared/ui/table_view/table_view_favicon_data_source.h" #import "ios/chrome/browser/shared/ui/table_view/table_view_utils.h" @@ -67,9 +68,9 @@ // with a text header on top of the first password issue in the group. All // other types of issues are displayed in the same group without header. NSArray<PasswordIssueGroup*>* _passwordGroups; - // Text displayed in the button for presenting dismissed compromised - // credential warnings. When nil, no button is displayed. - NSString* _dismissedWarningsButtonText; + // Number in the button for presenting dismissed compromised + // credential warnings. When zero, no button is displayed. + NSInteger _dismissedWarningsCount; // Type of insecure credentials displayed in the page. WarningType _warningType; } @@ -156,7 +157,8 @@ }]; } - TableViewTextItem* dismissedWarningsItem = [self dismissedWarningsItem]; + TableViewMultiDetailTextItem* dismissedWarningsItem = + [self dismissedWarningsItem]; if (dismissedWarningsItem) { [model addSectionWithIdentifier:SectionIdentifierDismissedCredentialsButton]; @@ -233,18 +235,22 @@ } // Creates the item acting as a button for presenting dismissed compromised -// credential warnings. Returns nil when `_dismissedWarningsButtonText` is nil. -- (TableViewTextItem*)dismissedWarningsItem { +// credential warnings. Returns nil when `_dismissedWarningsCount` is zero. +- (TableViewMultiDetailTextItem*)dismissedWarningsItem { // The button is not visible either because there aren't dismissed compromised // credentials or because the view controller is not showing compromised // credentials. - if (!_dismissedWarningsButtonText) { + if (_dismissedWarningsCount == 0) { return nil; } - TableViewTextItem* dismissedWarningsItem = [[TableViewTextItem alloc] - initWithType:ItemTypeDismissedCredentialsButton]; - dismissedWarningsItem.text = _dismissedWarningsButtonText; + TableViewMultiDetailTextItem* dismissedWarningsItem = + [[TableViewMultiDetailTextItem alloc] + initWithType:ItemTypeDismissedCredentialsButton]; + dismissedWarningsItem.text = l10n_util::GetNSString( + IDS_IOS_COMPROMISED_PASSWORD_ISSUES_DISMISSED_WARNINGS_BUTTON_TITLE); + dismissedWarningsItem.trailingDetailText = + [@(_dismissedWarningsCount) stringValue]; dismissedWarningsItem.accessibilityTraits = UIAccessibilityTraitButton; dismissedWarningsItem.accessoryType = UITableViewCellAccessoryDisclosureIndicator; @@ -429,15 +435,15 @@ #pragma mark - PasswordIssuesConsumer - (void)setPasswordIssues:(NSArray<PasswordIssueGroup*>*)passwordGroups - dismissedWarningsButtonText:(NSString*)buttonText { + dismissedWarningsCount:(NSInteger)dismissedWarnings { _passwordGroups = passwordGroups; - _dismissedWarningsButtonText = buttonText; + _dismissedWarningsCount = dismissedWarnings; [self reloadData]; // User removed/resolved all issues, dismiss the vc and go back to the // previous screen. if (IsPasswordCheckupEnabled() && passwordGroups.count == 0 && - buttonText == nullptr) { + dismissedWarnings == 0) { [self.presenter dismissAfterAllIssuesGone]; } }
diff --git a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm index 7c7d4ad..2d4f5f51 100644 --- a/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm +++ b/ios/chrome/browser/ui/settings/password/password_issues/password_issues_table_view_controller_unittest.mm
@@ -13,6 +13,7 @@ #import "components/password_manager/core/common/password_manager_features.h" #import "ios/chrome/browser/passwords/password_checkup_utils.h" #import "ios/chrome/browser/shared/model/browser_state/test_chrome_browser_state.h" +#import "ios/chrome/browser/shared/ui/table_view/cells/table_view_multi_detail_text_item.h" #import "ios/chrome/browser/shared/ui/table_view/chrome_table_view_controller_test.h" #import "ios/chrome/browser/ui/settings/password/password_checkup/password_checkup_constants.h" #import "ios/chrome/browser/ui/settings/password/password_issues/password_issue.h" @@ -140,22 +141,20 @@ // Adds password issue to the view controller. void AddPasswordIssue() { - SetIssuesAndDismissedWarningsButtonText( - @[ [[PasswordIssueGroup alloc] - initWithHeaderText:nil - passwordIssues:@[ CreateTestPasswordIssue() ]] ], - nil); + SetIssuesAndDismissedWarningsCount(@[ [[PasswordIssueGroup alloc] + initWithHeaderText:nil + passwordIssues:@[ CreateTestPasswordIssue() ]] ]); } // Passes the given PasswordIssues and text for dismissed warnings button to // the view controller. - void SetIssuesAndDismissedWarningsButtonText( + void SetIssuesAndDismissedWarningsCount( NSArray<PasswordIssueGroup*>* password_issue_groups, - NSString* dismissed_warnings_button_text = nil) { + NSInteger dismissed_warnings_count = 0) { PasswordIssuesTableViewController* passwords_controller = static_cast<PasswordIssuesTableViewController*>(controller()); [passwords_controller setPasswordIssues:password_issue_groups - dismissedWarningsButtonText:dismissed_warnings_button_text]; + dismissedWarningsCount:dismissed_warnings_count]; } // Sets the PasswordPasswordIssuesTableViewController header. @@ -186,6 +185,18 @@ } } + // Verifies that the item for the dismissed warnings button is in the model + // with the right content. + void CheckDismissedWarningsButton(NSInteger expected_count, int section) { + TableViewMultiDetailTextItem* dismissed_warnings_button_item = + GetTableViewItem(/*section=*/section, /*item=*/0); + // Validate button text. + EXPECT_NSEQ(@"Dismissed Warnings", dismissed_warnings_button_item.text); + // Validate count. + EXPECT_NSEQ([@(expected_count) stringValue], + dismissed_warnings_button_item.trailingDetailText); + } + FakePasswordIssuesPresenter* presenter() { return presenter_; } private: @@ -268,20 +279,18 @@ // Add two groups with headers and two issues each. NSString* first_header_text = @"Group Header 1"; NSString* second_header_text = @"Group Header 2"; - SetIssuesAndDismissedWarningsButtonText( - @[ - [[PasswordIssueGroup alloc] - initWithHeaderText:first_header_text - passwordIssues:@[ - CreateTestPasswordIssue(), CreateTestPasswordIssue2() - ]], - [[PasswordIssueGroup alloc] - initWithHeaderText:second_header_text - passwordIssues:@[ - CreateTestPasswordIssue(), CreateTestPasswordIssue2() - ]] - ], - nil); + SetIssuesAndDismissedWarningsCount(@[ + [[PasswordIssueGroup alloc] + initWithHeaderText:first_header_text + passwordIssues:@[ + CreateTestPasswordIssue(), CreateTestPasswordIssue2() + ]], + [[PasswordIssueGroup alloc] + initWithHeaderText:second_header_text + passwordIssues:@[ + CreateTestPasswordIssue(), CreateTestPasswordIssue2() + ]] + ]); // Model should have one section for each issue. EXPECT_EQ(4, NumberOfSections()); @@ -345,16 +354,18 @@ password_manager::features::kIOSPasswordCheckup); CreateController(); - SetIssuesAndDismissedWarningsButtonText( + SetIssuesAndDismissedWarningsCount( @[ [[PasswordIssueGroup alloc] initWithHeaderText:nil passwordIssues:@[ CreateTestPasswordIssue() ]] ], - @"Dismiss Warnings (1)"); + 1); - PasswordIssuesTableViewController* passwords_controller = - GetPasswordIssuesController(); + CheckDismissedWarningsButton(/*expected_count=*/1, /*section=*/1); EXPECT_FALSE(presenter().dismissedWarningsPresented); + + PasswordIssuesTableViewController* passwords_controller = + static_cast<PasswordIssuesTableViewController*>(controller()); [passwords_controller tableView:passwords_controller.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:1]]; EXPECT_TRUE(presenter().dismissedWarningsPresented); @@ -366,10 +377,9 @@ password_manager::features::kIOSPasswordCheckup); PasswordIssue* password_issue = CreateTestPasswordIssue(); - SetIssuesAndDismissedWarningsButtonText( + SetIssuesAndDismissedWarningsCount( @[ [[PasswordIssueGroup alloc] initWithHeaderText:nil - passwordIssues:@[ password_issue ]] ], - nil); + passwordIssues:@[ password_issue ]] ]); PasswordIssuesTableViewController* passwords_controller = static_cast<PasswordIssuesTableViewController*>(controller()); @@ -392,10 +402,8 @@ EXPECT_FALSE(presenter().dismissalTriggered); - PasswordIssuesTableViewController* passwords_controller = - GetPasswordIssuesController(); // Simulate all content gone. - [passwords_controller setPasswordIssues:@[] dismissedWarningsButtonText:nil]; + SetIssuesAndDismissedWarningsCount(@[]); EXPECT_TRUE(presenter().dismissalTriggered); }
diff --git a/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm b/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm index bbe90798..c10d482 100644 --- a/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm +++ b/ios/chrome/browser/ui/settings/password/password_manager_view_controller.mm
@@ -63,7 +63,6 @@ #import "ios/chrome/browser/ui/settings/elements/enterprise_info_popover_view_controller.h" #import "ios/chrome/browser/ui/settings/password/branded_navigation_item_title_view.h" #import "ios/chrome/browser/ui/settings/password/create_password_manager_title_view.h" -#import "ios/chrome/browser/ui/settings/password/password_exporter.h" #import "ios/chrome/browser/ui/settings/password/password_manager_view_controller+private.h" #import "ios/chrome/browser/ui/settings/password/password_manager_view_controller_delegate.h" #import "ios/chrome/browser/ui/settings/password/password_manager_view_controller_items.h" @@ -242,9 +241,6 @@ BOOL _faviconMetricLogged; } -// Object handling passwords export operations. -@property(nonatomic, strong) PasswordExporter* passwordExporter; - // Current passwords search term. @property(nonatomic, copy) NSString* searchTerm; @@ -276,10 +272,6 @@ // YES, if the user has tapped on the "Check Now" button. @property(nonatomic, assign) BOOL shouldFocusAccessibilityOnPasswordCheckStatus; -// On-device encryption state according to the sync service. -@property(nonatomic, assign) - OnDeviceEncryptionState onDeviceEncryptionStateInModel; - // Return YES if the search bar should be enabled. @property(nonatomic, assign) BOOL shouldEnableSearchBar; @@ -323,9 +315,6 @@ [self updateUIForEditState]; } - // This value represents the state in the UI. It is set to - // `OnDeviceEncryptionStateNotShown` because nothing is currently shown. - _onDeviceEncryptionStateInModel = OnDeviceEncryptionStateNotShown; return self; }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm index e4a625a..9dd3a05 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.mm
@@ -710,6 +710,29 @@ return cell; } +- (void)collectionView:(UICollectionView*)collectionView + willDisplayCell:(UICollectionViewCell*)cell + forItemAtIndexPath:(NSIndexPath*)indexPath { + // Checking and updating the GridCell's `state` if needed. + // + // For the context: `setMode:` method updates the `state` property of the + // visible GridCells only. However, there are might be some cells that were + // dequeued already but haven't been displayed yet. Those will never update + // their `state` unless we forcely handle it here. + // + // See crbug.com//1427278 + if ([cell isKindOfClass:[GridCell class]]) { + GridCell* gridCell = base::mac::ObjCCastStrict<GridCell>(cell); + + BOOL isTabGridInSelectionMode = _mode == TabGridModeSelection; + BOOL isGridCellInSelectionMode = gridCell.state != GridCellStateNotEditing; + + if (isTabGridInSelectionMode != isGridCellInSelectionMode) { + gridCell.state = isTabGridInSelectionMode ? GridCellStateEditingUnselected + : GridCellStateNotEditing; + } + } +} #pragma mark - UICollectionViewDelegate - (CGSize)collectionView:(UICollectionView*)collectionView
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn index ac5f37f..1f0a341e 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/BUILD.gn
@@ -16,6 +16,7 @@ ] deps = [ ":inactive_tabs_button_ui", + ":inactive_tabs_constants", ":inactive_tabs_ui", "//base", "//components/favicon/ios", @@ -65,6 +66,14 @@ ] } +source_set("inactive_tabs_constants") { + configs += [ "//build/config/compiler:enable_arc" ] + sources = [ + "inactive_tabs_constants.h", + "inactive_tabs_constants.mm", + ] +} + source_set("inactive_tabs_button") { configs += [ "//build/config/compiler:enable_arc" ] sources = [ @@ -110,6 +119,7 @@ "inactive_tabs_button_header.swift", ] deps = [ + ":inactive_tabs_constants", "//ios/chrome/app/strings", "//ios/chrome/browser/shared/ui/symbols", "//ios/chrome/common/ui/colors:swift", @@ -117,3 +127,28 @@ ] frameworks = [ "UIKit.framework" ] } + +source_set("eg2_tests") { + configs += [ + "//build/config/compiler:enable_arc", + "//build/config/ios:xctest_config", + ] + testonly = true + sources = [ "inactive_tabs_egtest.mm" ] + deps = [ + ":inactive_tabs_constants", + "//ios/chrome/app/strings", + "//ios/chrome/browser/shared/model/prefs:pref_names", + "//ios/chrome/browser/tabs/inactive_tabs:features", + "//ios/chrome/browser/ui/reading_list:eg_test_support+eg2", + "//ios/chrome/browser/ui/settings/tabs/inactive_tabs:inactive_tabs_constants", + "//ios/chrome/browser/ui/tab_switcher/tab_grid:tab_grid_ui_constants", + "//ios/chrome/browser/ui/tab_switcher/test:utils", + "//ios/chrome/common/ui/confirmation_alert:constants", + "//ios/chrome/test/earl_grey:eg_test_support+eg2", + "//ios/testing/earl_grey:eg_test_support+eg2", + "//net:test_support", + "//ui/base", + ] + frameworks = [ "UIKit.framework" ] +}
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift index b189ad27..4d03b8b 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button.swift
@@ -32,6 +32,12 @@ } } .buttonStyle(InactiveTabsButtonStyle()) + // Make the accessibility label explicit. + .accessibilityElement(children: .ignore) + .accessibilityLabel([titleString, subtitleString, counterString] + .compactMap { $0 } + .joined(separator: ", ")) + .accessibilityIdentifier(kInactiveTabsButtonAccessibilityIdentifier) } /// MARK - Layouts @@ -69,21 +75,17 @@ /// Displays the button title. @ViewBuilder private func title() -> some View { - Text(L10nUtils.string(messageId: IDS_IOS_INACTIVE_TABS_BUTTON_TITLE)) + Text(titleString) .foregroundColor(.white) } /// Displays the button subtitle. @ViewBuilder private func subtitle() -> some View { - if let daysThreshold = state.daysThreshold { - Text( - L10nUtils.formatString( - messageId: IDS_IOS_INACTIVE_TABS_BUTTON_SUBTITLE, - argument: String(daysThreshold)) - ) - .font(.footnote) - .foregroundColor(.textSecondary) + if let subtitleString { + Text(subtitleString) + .font(.footnote) + .foregroundColor(.textSecondary) } } @@ -93,8 +95,8 @@ /// If the count is not set, this returns nothing. @ViewBuilder private func counter() -> some View { - if let count = state.count { - Text(count > 99 ? "99+" : "\(count)") + if let counterString { + Text(counterString) .foregroundColor(.textSecondary) } } @@ -139,4 +141,31 @@ .environment(\.colorScheme, .dark) } } + + /// MARK - Strings + + /// String for the title. + private var titleString: String { + L10nUtils.string(messageId: IDS_IOS_INACTIVE_TABS_BUTTON_TITLE) + } + + /// Optional string for the subtitle. + private var subtitleString: String? { + if let daysThreshold = state.daysThreshold { + return L10nUtils.formatString( + messageId: IDS_IOS_INACTIVE_TABS_BUTTON_SUBTITLE, + argument: String(daysThreshold)) + } else { + return nil + } + } + + /// Optional string for the counter. + private var counterString: String? { + if let count = state.count { + return count > 99 ? "99+" : "\(count)" + } else { + return nil + } + } }
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_ui_swift_bridge.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_ui_swift_bridge.h index cd24fd5..32b7c291 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_ui_swift_bridge.h +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_button_ui_swift_bridge.h
@@ -9,6 +9,7 @@ // Obj-C and have no C++ in them. #import "ios/chrome/browser/shared/ui/symbols/symbols.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h" #import "ios/chrome/grit/ios_strings.h" // Explicitly import the bridging header of the Swift dependencies, as the
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h new file mode 100644 index 0000000..980389e --- /dev/null +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h
@@ -0,0 +1,20 @@ +// 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 IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_INACTIVE_TABS_INACTIVE_TABS_CONSTANTS_H_ +#define IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_INACTIVE_TABS_INACTIVE_TABS_CONSTANTS_H_ + +#import <Foundation/Foundation.h> + +// Accessibility identifier for the Inactive Tabs button (entry point). +extern NSString* const kInactiveTabsButtonAccessibilityIdentifier; + +// Accessibility identifier for the User Education screen. +extern NSString* const kInactiveTabsUserEducationAccessibilityIdentifier; + +// NSUserDefaults key to check whether the user education screen has ever been +// shown. The associated value in user defaults is a BOOL. +extern NSString* const kInactiveTabsUserEducationShownOnceKey; + +#endif // IOS_CHROME_BROWSER_UI_TAB_SWITCHER_TAB_GRID_INACTIVE_TABS_INACTIVE_TABS_CONSTANTS_H_
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.mm new file mode 100644 index 0000000..7450efe --- /dev/null +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.mm
@@ -0,0 +1,18 @@ +// 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. + +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +NSString* const kInactiveTabsButtonAccessibilityIdentifier = + @"InactiveTabsButtonAccessibilityIdentifier"; + +NSString* const kInactiveTabsUserEducationAccessibilityIdentifier = + @"InactiveTabsUserEducationAccessibilityIdentifier"; + +NSString* const kInactiveTabsUserEducationShownOnceKey = + @"InactiveTabsUserEducationShownOnce";
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm index fe9fe53c..dfc2c8d 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_coordinator.mm
@@ -21,6 +21,7 @@ #import "ios/chrome/browser/tabs/inactive_tabs/features.h" #import "ios/chrome/browser/ui/settings/settings_navigation_controller.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/grid/grid_view_controller.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_mediator.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_user_education_coordinator.h" #import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.h" @@ -100,11 +101,6 @@ // glitch), delay the closing of the tabs in the mediator. const base::TimeDelta kCloseAllInactiveTabsDelay = base::Seconds(0.3); -// NSUserDefaults key to check whether the user education screen has ever been -// shown. The associated value in user defaults is a BOOL. -NSString* const kInactiveTabsUserEducationShownOnce = - @"InactiveTabsUserEducationShownOnce"; - } // namespace @interface InactiveTabsCoordinator () < @@ -625,7 +621,7 @@ // no-op. - (void)startUserEducationIfNeeded { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; - if ([defaults boolForKey:kInactiveTabsUserEducationShownOnce]) { + if ([defaults boolForKey:kInactiveTabsUserEducationShownOnceKey]) { return; } @@ -637,7 +633,7 @@ [self.userEducationCoordinator start]; // Record the presentation. - [defaults setBool:YES forKey:kInactiveTabsUserEducationShownOnce]; + [defaults setBool:YES forKey:kInactiveTabsUserEducationShownOnceKey]; } // Called when the user confirmed wanting to close all inactive tabs.
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_egtest.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_egtest.mm new file mode 100644 index 0000000..3cd7c0f --- /dev/null +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_egtest.mm
@@ -0,0 +1,852 @@ +// 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. + +#import <XCTest/XCTest.h> + +#import "base/strings/sys_string_conversions.h" +#import "ios/chrome/browser/shared/model/prefs/pref_names.h" +#import "ios/chrome/browser/tabs/inactive_tabs/features.h" +#import "ios/chrome/browser/ui/reading_list/reading_list_app_interface.h" +#import "ios/chrome/browser/ui/settings/tabs/inactive_tabs/inactive_tabs_settings_constants.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/tab_grid_constants.h" +#import "ios/chrome/browser/ui/tab_switcher/test/query_title_server_util.h" +#import "ios/chrome/browser/ui/tab_switcher/test/tabs_egtest_util.h" +#import "ios/chrome/common/ui/confirmation_alert/constants.h" +#import "ios/chrome/grit/ios_strings.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey.h" +#import "ios/chrome/test/earl_grey/chrome_earl_grey_ui.h" +#import "ios/chrome/test/earl_grey/chrome_matchers.h" +#import "ios/chrome/test/earl_grey/chrome_test_case.h" +#import "ios/testing/earl_grey/app_launch_configuration.h" +#import "ios/testing/earl_grey/app_launch_manager.h" +#import "ios/testing/earl_grey/earl_grey_test.h" +#import "ios/testing/earl_grey/matchers.h" +#import "net/test/embedded_test_server/embedded_test_server.h" +#import "ui/base/l10n/l10n_util.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +using chrome_test_util::AddToBookmarksButton; +using chrome_test_util::AddToReadingListButton; +using chrome_test_util::BackButton; +using chrome_test_util::CancelButton; +using chrome_test_util::CloseTabMenuButton; +using chrome_test_util::CopyActivityButton; +using chrome_test_util::NavigationBarDoneButton; +using chrome_test_util::ShareButton; +using chrome_test_util::TabGridSearchBar; +using chrome_test_util::TabGridSearchTabsButton; + +namespace { + +// Matcher for the Inactive Tabs button. +id<GREYMatcher> GetMatcherForInactiveTabsButton() { + return grey_accessibilityID(kInactiveTabsButtonAccessibilityIdentifier); +} + +// Matcher for the Inactive Tabs grid. +id<GREYMatcher> GetMatcherForInactiveTabsGrid() { + return grey_accessibilityID(kInactiveTabGridIdentifier); +} + +// Matcher for the Close All Inactive button in the Inactive Tabs grid. +id<GREYMatcher> GetMatcherForCloseAllInactiveButton() { + return grey_accessibilityID(kInactiveTabGridCloseAllButtonIdentifier); +} + +// Matcher for the Close All Inactive button in the Inactive Tabs grid. +id<GREYMatcher> GetMatcherForCloseAllAction() { + NSString* closeAllActionTitle = l10n_util::GetNSString( + IDS_IOS_INACTIVE_TABS_CLOSE_ALL_CONFIRMATION_OPTION); + return chrome_test_util::AlertAction(closeAllActionTitle); +} + +// Matcher for Inactive Tabs Settings link in the preamble of the Inactive Tabs +// grid. +id<GREYMatcher> GetMatcherForInactiveTabsSettingsLink() { + return grey_allOf( + // The link is within a grid view header of class + // `InactiveTabsPreambleHeader`. + grey_ancestor(grey_kindOfClassName(@"InactiveTabsPreambleHeader")), + // UIKit instantiates a `UIAccessibilityLinkSubelement` for the link + // element in the label with attributed string. + grey_kindOfClassName(@"UIAccessibilityLinkSubelement"), + grey_accessibilityTrait(UIAccessibilityTraitLink), nil); +} + +// Matcher for Inactive Tabs Settings screen. +id<GREYMatcher> GetMatcherForInactiveTabsSettings() { + return chrome_test_util::SettingsInactiveTabsTableView(); +} + +// Matcher for Inactive Tabs Setting' Disabled option. +id<GREYMatcher> GetMatcherForSettingsDisabledOption() { + return grey_allOf(grey_accessibilityLabel(l10n_util::GetNSString( + IDS_IOS_OPTIONS_INACTIVE_TABS_DISABLED)), + grey_userInteractionEnabled(), nil); +} + +// Matcher for Inactive Tabs User Education screen. +id<GREYMatcher> GetMatcherForInactiveTabsUserEducation() { + return grey_accessibilityID( + kInactiveTabsUserEducationAccessibilityIdentifier); +} + +// Matcher for Inactive Tabs User Education screen's Done button. +id<GREYMatcher> GetMatcherForUserEducationDoneButton() { + return grey_accessibilityID( + kConfirmationAlertPrimaryActionAccessibilityIdentifier); +} + +// Matcher for Inactive Tabs User Education screen's Settings button. +id<GREYMatcher> GetMatcherForUserEducationSettingsButton() { + return grey_accessibilityID( + kConfirmationAlertSecondaryActionAccessibilityIdentifier); +} + +} // namespace + +// Tests related to the Inactive Tabs feature. +@interface InactiveTabsTestCase : ChromeTestCase +@end + +@implementation InactiveTabsTestCase + +- (void)setUp { + [super setUp]; + [self setUpTestServer]; + + // Just have an NTP, no other previous tabs. + [[self class] closeAllTabs]; + [ChromeEarlGrey openNewTab]; + + // Ensure that inactive tabs preference settings is set to its default state. + [ChromeEarlGrey setIntegerValue:0 + forLocalStatePref:prefs::kInactiveTabsTimeThreshold]; + GREYAssertEqual( + 0, + [ChromeEarlGrey localStateIntegerPref:prefs::kInactiveTabsTimeThreshold], + @"Inactive tabs preference is not set to default value."); + + // Mark the User Education screen as already-seen by default. + [ChromeEarlGrey setUserDefaultObject:@YES + forKey:kInactiveTabsUserEducationShownOnceKey]; +} + +// Sets up the EmbeddedTestServer as needed for tests. +- (void)setUpTestServer { + RegisterQueryTitleHandler(self.testServer); + GREYAssertTrue(self.testServer->Start(), @"Test server failed to start"); +} + +// Relaunches the app with Inactive Tabs still enabled. +- (void)relaunchAppWithInactiveTabsEnabled { + AppLaunchConfiguration config; + config.relaunch_policy = ForceRelaunchByCleanShutdown; + config.additional_args.push_back( + "--enable-features=" + std::string(kTabInactivityThreshold.name) + ":" + + kTabInactivityThresholdParameterName + "/" + + kTabInactivityThresholdImmediateDemoParam); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; +} + +// Relaunches the app with Inactive Tabs still enabled, and the +// Show Inactive Tabs Count feature enabled. +- (void)relaunchAppWithInactiveTabsAndShowCountEnabled { + AppLaunchConfiguration config; + config.relaunch_policy = ForceRelaunchByCleanShutdown; + config.additional_args.push_back( + "--enable-features=" + std::string(kTabInactivityThreshold.name) + ":" + + kTabInactivityThresholdParameterName + "/" + + kTabInactivityThresholdImmediateDemoParam + "," + + std::string(kShowInactiveTabsCount.name)); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; +} + +// Relaunches the app with Inactive Tabs still enabled, and the +// Show Inactive Tabs Count feature explicitly disabled. +- (void)relaunchAppWithInactiveTabsEnabledAndShowCountDisabled { + AppLaunchConfiguration config; + config.relaunch_policy = ForceRelaunchByCleanShutdown; + config.additional_args.push_back( + "--enable-features=" + std::string(kTabInactivityThreshold.name) + ":" + + kTabInactivityThresholdParameterName + "/" + + kTabInactivityThresholdImmediateDemoParam); + config.features_disabled.push_back(kShowInactiveTabsCount); + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; +} + +// Relaunches the app with Inactive Tabs disabled. +- (void)relaunchAppWithInactiveTabsDisabled { + AppLaunchConfiguration config; + config.relaunch_policy = ForceRelaunchByCleanShutdown; + [[AppLaunchManager sharedManager] ensureAppLaunchedWithConfiguration:config]; +} + +#pragma mark - Tests + +// Checks that when Inactive Tabs is not enabled, tabs are not moved to Inactive +// Tabs. +- (void)testInactiveTabDisabled { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + + // Create tabs. + CreateRegularTabs(1, self.testServer); + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 2, + @"Main tab count should be 2"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); + + // Relaunch the app with Inactive Tabs disabled. + [self relaunchAppWithInactiveTabsDisabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // The Inactive Tabs button should not be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_notVisible()]; + + // There should be no inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 2, + @"Main tab count should be 2"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); +} + +// Checks that when Inactive Tabs is enabled and old tabs are found, the +// Inactive Tabs button appears in the Tab Grid. +- (void)testActiveTabsMoveToInactive { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + + // Create tabs. + CreateRegularTabs(1, self.testServer); + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 2, + @"Main tab count should be 2"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); + + // Relaunch the app. + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // The Inactive Tabs button should be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // There should be one inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); +} + +// Checks that when there are inactive tabs and the feature is disabled, the +// Inactive Tabs button no longer appears in the Tab Grid. +- (void)testInactiveTabsMoveToActiveWhenDisabling { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + + // Create tabs. + CreateRegularTabs(1, self.testServer); + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 2, + @"Main tab count should be 2"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); + + // Relaunch the app. + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // The Inactive Tabs button should be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // There should be one inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Relaunch the app with Inactive Tabs disabled. + [self relaunchAppWithInactiveTabsDisabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // The Inactive Tabs button should not be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_notVisible()]; + + // There should be no inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 2, + @"Main tab count should be 2"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); +} + +// Checks that NTPs are not moved. +- (void)testActiveTabsDontMoveNTP { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey openNewTab]; + [ChromeEarlGrey openNewTab]; + + // Relaunch the app. + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // The Inactive Tabs button should not be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_notVisible()]; + + // There should be no inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); +} + +// Checks that inactive tabs can be found with tab search. +- (void)testInactiveTabInTabSearch { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + + // Create tabs with titles. + CreateRegularTab(self.testServer, @"Tab1"); + CreateRegularTab(self.testServer, @"Tab2"); + CreateRegularTab(self.testServer, @"Tab3"); + + // Relaunch the app. + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // Enter search mode. + [[EarlGrey selectElementWithMatcher:TabGridSearchTabsButton()] + performAction:grey_tap()]; + + // Search for the title of the 3rd inactive tab. + [[EarlGrey selectElementWithMatcher:TabGridSearchBar()] + performAction:grey_typeText(@"Tab3")]; + + // Check that the tab is here. + [[EarlGrey selectElementWithMatcher:TabWithTitle(@"Tab3")] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +// Checks that tapping on an inactive tab opens it. +- (void)testReactivateInactiveTab { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTab(self.testServer, @"Tab1"); + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // There should be one inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // Tap on the inactive tab. + [[EarlGrey selectElementWithMatcher:TabWithTitle(@"Tab1")] + performAction:grey_tap()]; + + // There should be no inactive tab anymore, it should have moved alongside the + // initial NTP. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 2, + @"Main tab count should be 2"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); +} + +// Checks that long-pressing on an inactive tab and closing it works as +// expected. +- (void)testCloseInactiveTab { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTab(self.testServer, @"Tab1"); + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // There should be one inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // Long press the tab. + [[EarlGrey selectElementWithMatcher:TabWithTitle(@"Tab1")] + performAction:grey_longPress()]; + + // Close the tab. + [[EarlGrey selectElementWithMatcher:CloseTabMenuButton()] + performAction:grey_tap()]; + + // There should be no inactive tab anymore, just the initial NTP. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); +} + +// Checks that long-pressing on an inactive tab and sharing it opens the share +// sheet. +- (void)testShareInactiveTab { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTab(self.testServer, @"Tab1"); + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // There should be one inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // Long press the tab. + [[EarlGrey selectElementWithMatcher:TabWithTitle(@"Tab1")] + performAction:grey_longPress()]; + + // Share the tab. + [[EarlGrey selectElementWithMatcher:ShareButton()] performAction:grey_tap()]; + + // Check the presence of the Share sheet, for example by looking for the Copy + // button. + [[EarlGrey selectElementWithMatcher:CopyActivityButton()] + performAction:grey_tap()]; + + // There should be still be an inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); +} + +// Checks that long-pressing on an inactive tab and bookmarking it opens the +// "added bookmark" snackbar. +- (void)testBookmarkInactiveTab { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTab(self.testServer, @"Tab1"); + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // There should be one inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // Long press the tab. + [[EarlGrey selectElementWithMatcher:TabWithTitle(@"Tab1")] + performAction:grey_longPress()]; + + NSString* snackbarMessage = base::SysUTF16ToNSString( + l10n_util::GetPluralStringFUTF16(IDS_IOS_BOOKMARK_PAGE_SAVED, 1)); + WaitForSnackbarTriggeredByTappingItem(snackbarMessage, + AddToBookmarksButton()); + + // There should be still be an inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); +} + +// Checks that long-pressing on an inactive tab and adding it to the Reading +// List opens the "added to Reading List" snackbar. +- (void)testAddToReadingListInactiveTab { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTab(self.testServer, @"Tab1"); + [self relaunchAppWithInactiveTabsEnabled]; + // Clear the Reading List. + GREYAssertNil([ReadingListAppInterface clearEntries], + @"Unable to clear Reading List entries"); + GREYAssertEqual(0, [ReadingListAppInterface unreadEntriesCount], + @"Reading List should be empty"); + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // There should be one inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // Long press the tab. + [[EarlGrey selectElementWithMatcher:TabWithTitle(@"Tab1")] + performAction:grey_longPress()]; + + // Tap Add to Reading List. + [[EarlGrey selectElementWithMatcher:AddToReadingListButton()] + performAction:grey_tap()]; + + // Check that the tab was added to Reading List. + GREYAssertEqual(1, [ReadingListAppInterface unreadEntriesCount], + @"Reading List should have one element"); + + // There should be still be an inactive tab. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); +} + +// Checks that the Close All Inactive button and confirmation dialog work as +// expected. +- (void)testCloseAllInactiveTabs { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + + // Create tabs. + CreateRegularTabs(3, self.testServer); + + // Relaunch the app. + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // There should be three inactive tabs. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 3, + @"Inactive tab count should be 3"); + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // Tab the Close All Inactive button. + [[EarlGrey selectElementWithMatcher:GetMatcherForCloseAllInactiveButton()] + performAction:grey_tap()]; + + // Tap Cancel. + [[EarlGrey selectElementWithMatcher:CancelButton()] performAction:grey_tap()]; + + // There should still be three inactive tabs. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 3, + @"Inactive tab count should be 3"); + + // Tab the Close All Inactive button again. + [[EarlGrey selectElementWithMatcher:GetMatcherForCloseAllInactiveButton()] + performAction:grey_tap()]; + + // Tap Close All. + [[EarlGrey selectElementWithMatcher:GetMatcherForCloseAllAction()] + performAction:grey_tap()]; + + // There should be no inactive tab anymore, just the initial NTP. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); + + // The Inactive Tabs grid should no longer be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsGrid()] + assertWithMatcher:grey_notVisible()]; + + // The Inactive Tabs button should not be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_notVisible()]; +} + +// Checks that tapping the Settings link from the Inactive Tabs grid preamble +// opens Inactive Tabs Settings. +- (void)testSettingsFromPreamble { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTabs(1, self.testServer); + [self relaunchAppWithInactiveTabsEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // There should be one inactive tab, and the active NTP. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // Tap on the settings link from the preamble. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsSettingsLink()] + performAction:grey_tap()]; + + // Check that Inactive Tabs Settings are open. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsSettings()] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +// Checks that changing settings when presented from the Inactive Tabs grid +// updates the grid, and pops it when there are no inactive tabs anymore. +- (void)testSettingsChangesPopsInactiveTabs { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTabs(1, self.testServer); + [self relaunchAppWithInactiveTabsEnabled]; + [ChromeEarlGreyUI openTabGrid]; + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // There should be one inactive tab, and the active NTP. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 1, + @"Main tab count should be 1"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 1, + @"Inactive tab count should be 1"); + + // Tap on the settings link from the preamble. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsSettingsLink()] + performAction:grey_tap()]; + + // Disable Inactive Tabs and dismiss the settings screen. + [[EarlGrey selectElementWithMatcher:GetMatcherForSettingsDisabledOption()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:NavigationBarDoneButton()] + performAction:grey_tap()]; + + // The Inactive Tabs grid should no longer be visible. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsGrid()] + assertWithMatcher:grey_notVisible()]; + + // There should be no inactive tab, just 2 active tabs. + GREYAssertTrue([ChromeEarlGrey mainTabCount] == 2, + @"Main tab count should be 2"); + GREYAssertTrue([ChromeEarlGrey incognitoTabCount] == 0, + @"Incognito tab count should be 0"); + GREYAssertTrue([ChromeEarlGrey inactiveTabCount] == 0, + @"Inactive tab count should be 0"); +} + +// Checks that the count of inactive tabs only appear when the +// show-inactive-tabs-count feature is enabled. +- (void)testShowCount { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + CreateRegularTabs(3, self.testServer); + + // Relaunch without the Show Inactive Tabs Count feature enabled. + [self relaunchAppWithInactiveTabsEnabledAndShowCountDisabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // The Inactive Tabs count should not be appended at the end of the button's + // label. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_accessibilityLabel( + @"Inactive Tabs, Tabs not used for 0 days")]; + + // Relaunch with the Show Inactive Tabs Count feature enabled. + [self relaunchAppWithInactiveTabsAndShowCountEnabled]; + + // Open the Tab Grid. + [ChromeEarlGreyUI openTabGrid]; + + // The Inactive Tabs count should be appended at the end of the button's + // label. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + assertWithMatcher:grey_accessibilityLabel( + @"Inactive Tabs, Tabs not used for 0 days, 3")]; +} + +// Checks that the User Education panel only appears the first time Inactive +// Tabs are opened. +- (void)testUserEducationAppearsOnce { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + // Reset the User-Education marker. + [ChromeEarlGrey + removeUserDefaultObjectForKey:kInactiveTabsUserEducationShownOnceKey]; + + // Set up one inactive tab. + CreateRegularTabs(1, self.testServer); + [self relaunchAppWithInactiveTabsEnabled]; + [ChromeEarlGreyUI openTabGrid]; + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // The user education screen is shown. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsUserEducation()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // Dismiss it, go back and re-enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForUserEducationDoneButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:testing::NavigationBarBackButton()] + performAction:grey_tap()]; + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // The user education screen is not shown. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsUserEducation()] + assertWithMatcher:grey_nil()]; +} + +// Checks that Settings can be opened from the User Education panel. +- (void)testUserEducationOpenSettings { + if ([ChromeEarlGrey isIPadIdiom]) { + EARL_GREY_TEST_SKIPPED(@"Skipped for iPad. The Inactive Tabs feature is " + @"only supported on iPhone."); + } + // Reset the User-Education marker. + [ChromeEarlGrey + removeUserDefaultObjectForKey:kInactiveTabsUserEducationShownOnceKey]; + // Set up one inactive tab. + CreateRegularTabs(1, self.testServer); + [self relaunchAppWithInactiveTabsEnabled]; + [ChromeEarlGreyUI openTabGrid]; + + // Enter the Inactive Tabs grid. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsButton()] + performAction:grey_tap()]; + + // The user education screen is shown. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsUserEducation()] + assertWithMatcher:grey_sufficientlyVisible()]; + + // Go to settings from that screen. + [[EarlGrey + selectElementWithMatcher:GetMatcherForUserEducationSettingsButton()] + performAction:grey_tap()]; + + // Check that Inactive Tabs Settings are open. + [[EarlGrey selectElementWithMatcher:GetMatcherForInactiveTabsSettings()] + assertWithMatcher:grey_sufficientlyVisible()]; +} + +@end
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_user_education_coordinator.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_user_education_coordinator.mm index 909f84f2..6beab7c 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_user_education_coordinator.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_user_education_coordinator.mm
@@ -11,6 +11,7 @@ #import "base/time/time.h" #import "ios/chrome/browser/shared/ui/symbols/symbols.h" #import "ios/chrome/browser/tabs/inactive_tabs/features.h" +#import "ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_constants.h" #import "ios/chrome/common/ui/colors/semantic_color_names.h" #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_action_handler.h" #import "ios/chrome/common/ui/confirmation_alert/confirmation_alert_view_controller.h" @@ -133,6 +134,8 @@ } else { _confirmationAlert.modalPresentationStyle = UIModalPresentationFormSheet; } + _confirmationAlert.view.accessibilityIdentifier = + kInactiveTabsUserEducationAccessibilityIdentifier; [self.baseViewController presentViewController:_confirmationAlert animated:YES
diff --git a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm index a8863f6..a7715f3 100644 --- a/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm +++ b/ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs/inactive_tabs_view_controller.mm
@@ -107,7 +107,8 @@ }]; _closeAllInactiveButton = [[UIBarButtonItem alloc] initWithPrimaryAction:closeAllInactiveAction]; - _closeAllInactiveButton.accessibilityIdentifier = kInactiveTabGridIdentifier; + _closeAllInactiveButton.accessibilityIdentifier = + kInactiveTabGridCloseAllButtonIdentifier; UIBarButtonItem* flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil
diff --git a/ios/chrome/browser/ui/tab_switcher/test/tabs_egtest_util.mm b/ios/chrome/browser/ui/tab_switcher/test/tabs_egtest_util.mm index 8436ade..fdcedc1 100644 --- a/ios/chrome/browser/ui/tab_switcher/test/tabs_egtest_util.mm +++ b/ios/chrome/browser/ui/tab_switcher/test/tabs_egtest_util.mm
@@ -99,9 +99,11 @@ error:&error]; return error == nil; }; - GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( - kSnackbarAppearanceTimeout, wait_for_appearance), - @"Snackbar did not appear."); + if (!wait_for_appearance()) { + GREYAssert(base::test::ios::WaitUntilConditionOrTimeout( + kSnackbarAppearanceTimeout, wait_for_appearance), + @"Snackbar did not appear."); + } // Wait for the snackbar to disappear. ConditionBlock wait_for_disappearance = ^{
diff --git a/ios/chrome/browser/ui/toolbar/BUILD.gn b/ios/chrome/browser/ui/toolbar/BUILD.gn index 04d3965..17c29b31 100644 --- a/ios/chrome/browser/ui/toolbar/BUILD.gn +++ b/ios/chrome/browser/ui/toolbar/BUILD.gn
@@ -14,8 +14,8 @@ "secondary_toolbar_coordinator.h", "secondary_toolbar_coordinator.mm", "toolbar_coordinatee.h", - "toolbar_coordinator_adaptor.h", - "toolbar_coordinator_adaptor.mm", + "toolbar_coordinator.h", + "toolbar_coordinator.mm", "toolbar_mediator.h", "toolbar_mediator.mm", ]
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.h b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.h new file mode 100644 index 0000000..fc8b810 --- /dev/null +++ b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.h
@@ -0,0 +1,71 @@ +// 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 IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_H_ +#define IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_H_ + +#import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" +#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h" +#import "ios/chrome/browser/ui/toolbar/public/toolbar_coordinating.h" + +@protocol OmniboxPopupPresenterDelegate; +@protocol OmniboxFocusDelegate; +@class PrimaryToolbarCoordinator; +@class PrimaryToolbarViewController; +@protocol SharingPositioner; +@class SecondaryToolbarViewController; +@protocol SideSwipeToolbarSnapshotProviding; +@protocol ViewRevealingAnimatee; +@class ViewRevealingVerticalPanHandler; + +/// Coordinator above primary and secondary toolbars. It does not have a +/// view controller. This object is also an interface between multiple toolbars +/// and the objects which want to interact with them without having to know to +/// which one specifically send the call. +@interface ToolbarCoordinator + : ChromeCoordinator <PopupMenuUIUpdating, ToolbarCoordinating> + +/// Delegate for focusing omnibox in `locationBarCoordinator`. +@property(nonatomic, weak) id<OmniboxFocusDelegate> omniboxFocusDelegate; +/// Delegate for presenting the popup in `locationBarCoordinator`. +@property(nonatomic, weak) id<OmniboxPopupPresenterDelegate> + popupPresenterDelegate; + +/// Initializes this coordinator with its `browser` and a nil base view +/// controller. +- (instancetype)initWithBrowser:(Browser*)browser NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithBaseViewController:(UIViewController*)viewController + browser:(Browser*)browser NS_UNAVAILABLE; + +/// Returns `primaryToolbarCoordinator`. +- (PrimaryToolbarCoordinator*)primaryToolbarCoordinator; + +/// Returns `primaryToolbarViewController`. +- (UIViewController*)primaryToolbarViewController; +/// Returns `secondaryToolbarViewController`. +- (UIViewController*)secondaryToolbarViewController; + +/// Returns the sharing positioner for the current toolbar configuration. +- (id<SharingPositioner>)sharingPositioner; + +#pragma mark ViewRevealing + +/// A reference to the view controller that implements the view revealing +/// vertical pan handler delegate methods. +- (id<ViewRevealingAnimatee>)viewRevealingAnimatee; +/// Sets the pan gesture handler for the view controller that implements the +/// view revealing. +- (void)setPanGestureHandler: + (ViewRevealingVerticalPanHandler*)panGestureHandler; + +#pragma mark SnapshotProviding + +/// Returns the snapshop provider of primary toolbar. +- (id<SideSwipeToolbarSnapshotProviding>)primaryToolbarSnapshotProvider; +/// Returns the snapshop provider of secondary toolbar. +- (id<SideSwipeToolbarSnapshotProviding>)secondaryToolbarSnapshotProvider; + +@end + +#endif // IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_H_
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm new file mode 100644 index 0000000..c9f8ccbc --- /dev/null +++ b/ios/chrome/browser/ui/toolbar/toolbar_coordinator.mm
@@ -0,0 +1,195 @@ +// 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. + +#import "ios/chrome/browser/ui/toolbar/toolbar_coordinator.h" + +#import "base/mac/foundation_util.h" +#import "ios/chrome/browser/shared/model/browser/browser.h" +#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" +#import "ios/chrome/browser/shared/public/commands/toolbar_commands.h" +#import "ios/chrome/browser/ui/location_bar/location_bar_coordinator.h" +#import "ios/chrome/browser/ui/toolbar/adaptive_toolbar_view_controller.h" +#import "ios/chrome/browser/ui/toolbar/primary_toolbar_coordinator.h" +#import "ios/chrome/browser/ui/toolbar/secondary_toolbar_coordinator.h" +#import "ios/chrome/browser/ui/toolbar/toolbar_coordinatee.h" + +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + +@interface ToolbarCoordinator () <ToolbarCommands> + +/// Whether this coordinator has been started. +@property(nonatomic, assign) BOOL started; +/// Coordinator for the location bar containing the omnibox. +@property(nonatomic, strong) LocationBarCoordinator* locationBarCoordinator; +/// Coordinator for the primary toolbar at the top of the screen. +@property(nonatomic, strong) + PrimaryToolbarCoordinator* primaryToolbarCoordinator; +/// Coordinator for the secondary toolbar at the bottom of the screen. +@property(nonatomic, strong) + SecondaryToolbarCoordinator* secondaryToolbarCoordinator; + +@end + +@implementation ToolbarCoordinator + +- (instancetype)initWithBrowser:(Browser*)browser { + CHECK(browser); + self = [super initWithBaseViewController:nil browser:browser]; + if (self) { + // Initialize both coordinators here as they might be referenced before + // `start`. + _primaryToolbarCoordinator = + [[PrimaryToolbarCoordinator alloc] initWithBrowser:browser]; + _secondaryToolbarCoordinator = + [[SecondaryToolbarCoordinator alloc] initWithBrowser:browser]; + } + return self; +} + +- (void)start { + if (self.started) { + return; + } + + Browser* browser = self.browser; + [browser->GetCommandDispatcher() + startDispatchingToTarget:self + forProtocol:@protocol(ToolbarCommands)]; + + self.locationBarCoordinator = + [[LocationBarCoordinator alloc] initWithBrowser:browser]; + self.locationBarCoordinator.delegate = self.omniboxFocusDelegate; + self.locationBarCoordinator.popupPresenterDelegate = + self.popupPresenterDelegate; + [self.locationBarCoordinator start]; + + self.primaryToolbarCoordinator.locationBarCoordinator = + self.locationBarCoordinator; + [self.primaryToolbarCoordinator start]; + [self.secondaryToolbarCoordinator start]; + + [super start]; + self.started = YES; +} + +- (void)stop { + if (!self.started) { + return; + } + [super stop]; + + [self.locationBarCoordinator stop]; + self.locationBarCoordinator = nil; + [self.primaryToolbarCoordinator stop]; + [self.secondaryToolbarCoordinator stop]; + + [self.browser->GetCommandDispatcher() stopDispatchingToTarget:self]; + + self.started = NO; +} + +#pragma mark - Public + +- (UIViewController*)primaryToolbarViewController { + return self.primaryToolbarCoordinator.viewController; +} + +- (UIViewController*)secondaryToolbarViewController { + return self.secondaryToolbarCoordinator.viewController; +} + +- (id<SharingPositioner>)sharingPositioner { + return self.primaryToolbarCoordinator.SharingPositioner; +} + +#pragma mark ViewRevealing + +- (id<ViewRevealingAnimatee>)viewRevealingAnimatee { + CHECK(self.primaryToolbarCoordinator.animatee); + return self.primaryToolbarCoordinator.animatee; +} + +- (void)setPanGestureHandler: + (ViewRevealingVerticalPanHandler*)panGestureHandler { + [self.primaryToolbarCoordinator setPanGestureHandler:panGestureHandler]; +} + +#pragma mark SnapshotProviding + +- (id<SideSwipeToolbarSnapshotProviding>)primaryToolbarSnapshotProvider { + return self.primaryToolbarCoordinator; +} + +- (id<SideSwipeToolbarSnapshotProviding>)secondaryToolbarSnapshotProvider { + return self.secondaryToolbarCoordinator; +} + +#pragma mark - NewTabPageControllerDelegate + +- (void)setScrollProgressForTabletOmnibox:(CGFloat)progress { + for (id<NewTabPageControllerDelegate> coordinator in self.coordinators) { + [coordinator setScrollProgressForTabletOmnibox:progress]; + } +} + +- (UIResponder<UITextInput>*)fakeboxScribbleForwardingTarget { + for (id<NewTabPageControllerDelegate> coordinator in self.coordinators) { + if (coordinator.fakeboxScribbleForwardingTarget) { + return coordinator.fakeboxScribbleForwardingTarget; + } + } + return nil; +} + +#pragma mark - PopupMenuUIUpdating + +- (void)updateUIForOverflowMenuIPHDisplayed { + for (id<ToolbarCoordinatee> coordinator in self.coordinators) { + [coordinator.popupMenuUIUpdater updateUIForOverflowMenuIPHDisplayed]; + } +} + +- (void)updateUIForIPHDismissed { + for (id<ToolbarCoordinatee> coordinator in self.coordinators) { + [coordinator.popupMenuUIUpdater updateUIForIPHDismissed]; + } +} + +#pragma mark - SideSwipeToolbarInteracting + +- (BOOL)isInsideToolbar:(CGPoint)point { + for (id<ToolbarCoordinatee> coordinator in self.coordinators) { + // The toolbar frame is inset by -1 because CGRectContainsPoint does + // include points on the max X and Y edges, which will happen frequently + // with edge swipes from the right side. + CGRect toolbarFrame = + CGRectInset([coordinator viewController].view.bounds, -1, -1); + CGPoint pointInToolbarCoordinates = + [[coordinator viewController].view convertPoint:point fromView:nil]; + if (CGRectContainsPoint(toolbarFrame, pointInToolbarCoordinates)) { + return YES; + } + } + return NO; +} + +#pragma mark - ToolbarCommands + +- (void)triggerToolbarSlideInAnimation { + for (id<ToolbarCommands> coordinator in self.coordinators) { + [coordinator triggerToolbarSlideInAnimation]; + } +} + +#pragma mark - Private + +/// Returns primary and secondary coordinator in a array. Helper to call method +/// on both coordinators. +- (NSArray<id<ToolbarCoordinatee>>*)coordinators { + return @[ self.primaryToolbarCoordinator, self.secondaryToolbarCoordinator ]; +} + +@end
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h b/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h deleted file mode 100644 index a7bbe8ec..0000000 --- a/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h +++ /dev/null
@@ -1,28 +0,0 @@ -// 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. - -#ifndef IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_ADAPTOR_H_ -#define IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_ADAPTOR_H_ - -#import "ios/chrome/browser/ui/popup_menu/public/popup_menu_ui_updating.h" -#import "ios/chrome/browser/ui/toolbar/public/toolbar_coordinating.h" - -@class CommandDispatcher; -@protocol ToolbarCoordinatee; - -// This object is an interface between multiple toolbars and the objects which -// want to interact with them without having to know to which one specifically -// send the call. -@interface ToolbarCoordinatorAdaptor - : NSObject<PopupMenuUIUpdating, ToolbarCoordinating> - -- (instancetype)initWithDispatcher:(CommandDispatcher*)dispatcher; - -// Adds a `toolbarCoordinator` to the set of coordinators this object is -// interfacing with. -- (void)addToolbarCoordinator:(id<ToolbarCoordinatee>)toolbarCoordinator; - -@end - -#endif // IOS_CHROME_BROWSER_UI_TOOLBAR_TOOLBAR_COORDINATOR_ADAPTOR_H_
diff --git a/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.mm b/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.mm deleted file mode 100644 index 85d26e2..0000000 --- a/ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.mm +++ /dev/null
@@ -1,98 +0,0 @@ -// 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. - -#import "ios/chrome/browser/ui/toolbar/toolbar_coordinator_adaptor.h" - -#import "ios/chrome/browser/shared/public/commands/command_dispatcher.h" -#import "ios/chrome/browser/shared/public/commands/toolbar_commands.h" -#import "ios/chrome/browser/ui/toolbar/toolbar_coordinatee.h" - -#if !defined(__has_feature) || !__has_feature(objc_arc) -#error "This file requires ARC support." -#endif - -@interface ToolbarCoordinatorAdaptor ()<ToolbarCommands> -@property(nonatomic, strong) - NSMutableArray<id<NewTabPageControllerDelegate, ToolbarCommands>>* - coordinators; -@end - -@implementation ToolbarCoordinatorAdaptor - -@synthesize coordinators = _coordinators; - -#pragma mark - Public - -- (instancetype)initWithDispatcher:(CommandDispatcher*)dispatcher { - self = [super init]; - if (self) { - [dispatcher startDispatchingToTarget:self - forProtocol:@protocol(ToolbarCommands)]; - _coordinators = [NSMutableArray array]; - } - return self; -} - -- (void)addToolbarCoordinator: - (id<NewTabPageControllerDelegate, ToolbarCommands>)toolbarCoordinator { - [self.coordinators addObject:toolbarCoordinator]; -} - -#pragma mark - NewTabPageControllerDelegate - -- (void)setScrollProgressForTabletOmnibox:(CGFloat)progress { - for (id<NewTabPageControllerDelegate> coordinator in self.coordinators) { - [coordinator setScrollProgressForTabletOmnibox:progress]; - } -} - -- (UIResponder<UITextInput>*)fakeboxScribbleForwardingTarget { - for (id<NewTabPageControllerDelegate> coordinator in self.coordinators) { - if (coordinator.fakeboxScribbleForwardingTarget) { - return coordinator.fakeboxScribbleForwardingTarget; - } - } - return nil; -} - -#pragma mark - ToolbarCommands - -- (void)triggerToolbarSlideInAnimation { - for (id<ToolbarCommands> coordinator in self.coordinators) { - [coordinator triggerToolbarSlideInAnimation]; - } -} - -#pragma mark - SideSwipeToolbarInteracting - -- (BOOL)isInsideToolbar:(CGPoint)point { - for (id<ToolbarCoordinatee> coordinator in self.coordinators) { - // The toolbar frame is inset by -1 because CGRectContainsPoint does include - // points on the max X and Y edges, which will happen frequently with edge - // swipes from the right side. - CGRect toolbarFrame = - CGRectInset([coordinator viewController].view.bounds, -1, -1); - CGPoint pointInToolbarCoordinates = - [[coordinator viewController].view convertPoint:point fromView:nil]; - if (CGRectContainsPoint(toolbarFrame, pointInToolbarCoordinates)) - return YES; - } - return NO; -} - -#pragma mark - PopupMenuUIUpdating - -- (void)updateUIForOverflowMenuIPHDisplayed { - for (id<ToolbarCoordinatee> coordinator in self.coordinators) { - [coordinator.popupMenuUIUpdater updateUIForOverflowMenuIPHDisplayed]; - } -} - -- (void)updateUIForIPHDismissed { - for (id<ToolbarCoordinatee> coordinator in self.coordinators) { - [coordinator.popupMenuUIUpdater updateUIForIPHDismissed]; - } -} - -@end
diff --git a/ios/chrome/test/data/policy/policy_test_cases.json b/ios/chrome/test/data/policy/policy_test_cases.json index 2029f4e..e2532261d 100644 --- a/ios/chrome/test/data/policy/policy_test_cases.json +++ b/ios/chrome/test/data/policy/policy_test_cases.json
@@ -608,6 +608,40 @@ } ] }, + "PolicyTestPageEnabled":{ + "os": [ + "ios" + ], + "policy_pref_mapping_tests": [ + { + "policies": {}, + "prefs": { + "policy_test_page_enabled": { + "default_value": true, + "location": "user_profile" + } + } + }, + { + "policies": { "PolicyTestPageEnabled": true}, + "prefs": { + "policy_test_page_enabled": { + "value": true, + "location": "user_profile" + } + } + }, + { + "policies": { "PolicyTestPageEnabled": false}, + "prefs": { + "policy_test_page_enabled": { + "value": false, + "location": "user_profile" + } + } + } + ] + }, "PopupsAllowedForUrls": { "os": [ "ios"
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.h b/ios/chrome/test/earl_grey/chrome_earl_grey.h index 7578c279..18b62e3 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.h +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.h
@@ -171,10 +171,14 @@ - (void)waitForUIElementToDisappearWithMatcher:(id<GREYMatcher>)matcher timeout:(base::TimeDelta)timeout; -// Waits for there to be `count` number of non-incognito tabs within a timeout, -// or a GREYAssert is induced. +// Waits for there to be `count` number of non-incognito, active, tabs within a +// timeout, or a GREYAssert is induced. - (void)waitForMainTabCount:(NSUInteger)count; +// Waits for there to be `count` number of inactive tabs within a timeout, or a +// GREYAssert is induced. +- (void)waitForInactiveTabCount:(NSUInteger)count; + // Waits for there to be `count` number of incognito tabs within a timeout, or a // GREYAssert is induced. - (void)waitForIncognitoTabCount:(NSUInteger)count;
diff --git a/ios/chrome/test/earl_grey/chrome_earl_grey.mm b/ios/chrome/test/earl_grey/chrome_earl_grey.mm index d17ddb6..b00bed15 100644 --- a/ios/chrome/test/earl_grey/chrome_earl_grey.mm +++ b/ios/chrome/test/earl_grey/chrome_earl_grey.mm
@@ -607,6 +607,25 @@ EG_TEST_HELPER_ASSERT_TRUE(tabCountEqual, errorString); } +- (void)waitForInactiveTabCount:(NSUInteger)count { + NSString* errorString = [NSString + stringWithFormat: + @"Failed waiting for inactive tab count to become %" PRIuNS, count]; + + // Allow the UI to become idle, in case any tabs are being opened or closed. + GREYWaitForAppToIdle(@"App failed to idle"); + + GREYCondition* tabCountCheck = [GREYCondition + conditionWithName:errorString + block:^{ + return + [ChromeEarlGreyAppInterface inactiveTabCount] == count; + }]; + bool tabCountEqual = + [tabCountCheck waitWithTimeout:kWaitForUIElementTimeout.InSecondsF()]; + EG_TEST_HELPER_ASSERT_TRUE(tabCountEqual, errorString); +} + - (void)waitForIncognitoTabCount:(NSUInteger)count { NSString* errorString = [NSString stringWithFormat:
diff --git a/ios/chrome/test/earl_grey2/BUILD.gn b/ios/chrome/test/earl_grey2/BUILD.gn index 2597a97..ed792ab 100644 --- a/ios/chrome/test/earl_grey2/BUILD.gn +++ b/ios/chrome/test/earl_grey2/BUILD.gn
@@ -205,6 +205,7 @@ "//ios/chrome/browser/ui/side_swipe:eg2_tests", "//ios/chrome/browser/ui/start_surface:eg2_tests", "//ios/chrome/browser/ui/tab_switcher/tab_grid:eg2_tests", + "//ios/chrome/browser/ui/tab_switcher/tab_grid/inactive_tabs:eg2_tests", "//ios/chrome/browser/ui/tab_switcher/tab_grid/pinned_tabs/tests:eg2_tests", "//ios/chrome/browser/ui/tabs:eg2_tests", "//ios/chrome/browser/ui/text_fragments:eg2_tests",
diff --git a/ios/chrome/test/wpt/BUILD.gn b/ios/chrome/test/wpt/BUILD.gn index c94b6c4..b7ce70f 100644 --- a/ios/chrome/test/wpt/BUILD.gn +++ b/ios/chrome/test/wpt/BUILD.gn
@@ -17,9 +17,7 @@ "chrome_ios", "--target", "Release", - "--webdriver-arg=--os=16.0", - "--no-restart-on-unexpected", - "--retry-unexpected=0", + "--zero-tests-executed-ok", # TODO(crbug.com/1351820): Enable more tests to run. "/css/css-transforms/",
diff --git a/ios/testing/PRESUBMIT.py b/ios/testing/PRESUBMIT.py index 480f64d..a492562 100644 --- a/ios/testing/PRESUBMIT.py +++ b/ios/testing/PRESUBMIT.py
@@ -9,9 +9,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - - def CheckChange(input_api, output_api): import sys old_sys_path = sys.path[:]
diff --git a/ios/testing/earl_grey/matchers.h b/ios/testing/earl_grey/matchers.h index 81feaeb..1c5e905 100644 --- a/ios/testing/earl_grey/matchers.h +++ b/ios/testing/earl_grey/matchers.h
@@ -27,6 +27,9 @@ // Matcher for an element whose accessibility label contains `substring`. id<GREYMatcher> ElementWithAccessibilityLabelSubstring(NSString* substring); +// Matcher for the back button of a navigation bar. +id<GREYMatcher> NavigationBarBackButton(); + } // namespace testing #endif // IOS_TESTING_EARL_GREY_MATCHERS_H_
diff --git a/ios/testing/earl_grey/matchers.mm b/ios/testing/earl_grey/matchers.mm index 40c620b..22dacb1 100644 --- a/ios/testing/earl_grey/matchers.mm +++ b/ios/testing/earl_grey/matchers.mm
@@ -48,4 +48,8 @@ nil); } +id<GREYMatcher> NavigationBarBackButton() { + return grey_accessibilityID(@"BackButton"); +} + } // namespace testing
diff --git a/ios/web/content/web_state/content_web_state.h b/ios/web/content/web_state/content_web_state.h index 609688c6..6816be4 100644 --- a/ios/web/content/web_state/content_web_state.h +++ b/ios/web/content/web_state/content_web_state.h
@@ -104,7 +104,7 @@ int GetNavigationItemCount() const override; const GURL& GetVisibleURL() const override; const GURL& GetLastCommittedURL() const override; - GURL GetCurrentURL(URLVerificationTrustLevel* trust_level) const override; + absl::optional<GURL> GetLastCommittedURLIfTrusted() const override; WebFramesManager* GetWebFramesManager(ContentWorld world) override; CRWWebViewProxyType GetWebViewProxy() const override; void AddObserver(WebStateObserver* observer) override;
diff --git a/ios/web/content/web_state/content_web_state.mm b/ios/web/content/web_state/content_web_state.mm index 561627ef..630613d 100644 --- a/ios/web/content/web_state/content_web_state.mm +++ b/ios/web/content/web_state/content_web_state.mm
@@ -347,12 +347,8 @@ return item ? item->GetURL() : GURL::EmptyGURL(); } -GURL ContentWebState::GetCurrentURL( - URLVerificationTrustLevel* trust_level) const { - // TODO(crbug.com/1419001): Make sure that callers are using this correctly - // and that unexpected URLs are not displayed. - auto* item = navigation_manager_->GetLastCommittedItem(); - return item ? item->GetURL() : GURL::EmptyGURL(); +absl::optional<GURL> ContentWebState::GetLastCommittedURLIfTrusted() const { + return GetLastCommittedURL(); } WebFramesManager* ContentWebState::GetWebFramesManager(ContentWorld world) {
diff --git a/ios/web/navigation/navigation_manager_delegate.h b/ios/web/navigation/navigation_manager_delegate.h index 329c92b..6a806ba9a 100644 --- a/ios/web/navigation/navigation_manager_delegate.h +++ b/ios/web/navigation/navigation_manager_delegate.h
@@ -8,6 +8,7 @@ #include <stddef.h> #include "ios/web/common/user_agent.h" +#import "url/gurl.h" @protocol CRWWebViewNavigationProxy; @class WKBackForwardListItem; @@ -71,6 +72,11 @@ // Used to access pending item stored in NavigationContext. virtual NavigationItemImpl* GetPendingItem() = 0; + + // Returns the NavigationManagerDelegate's view of the current URL. This is + // used as a fallback in situations where the NavigationManager doesn't trust + // its own view of the last committed item. + virtual GURL GetCurrentURL() const = 0; }; } // namespace web
diff --git a/ios/web/navigation/navigation_manager_impl.mm b/ios/web/navigation/navigation_manager_impl.mm index c01b49c6..7d53211b 100644 --- a/ios/web/navigation/navigation_manager_impl.mm +++ b/ios/web/navigation/navigation_manager_impl.mm
@@ -1019,7 +1019,7 @@ // Don't check trust level here, as at this point it's expected // the _documentURL and the last_commited_item URL have an origin // mismatch. - GURL document_url = GetWebState()->GetCurrentURL(/*trust_level=*/nullptr); + GURL document_url = delegate_->GetCurrentURL(); if (!last_committed_web_view_item_) { last_committed_web_view_item_ = CreateNavigationItemWithRewriters( /*url=*/GURL::EmptyGURL(), Referrer(),
diff --git a/ios/web/navigation/navigation_manager_impl_unittest.mm b/ios/web/navigation/navigation_manager_impl_unittest.mm index f592b59..fc2f5bc 100644 --- a/ios/web/navigation/navigation_manager_impl_unittest.mm +++ b/ios/web/navigation/navigation_manager_impl_unittest.mm
@@ -97,6 +97,7 @@ NavigationInitiationType, bool)); MOCK_METHOD0(GetPendingItem, NavigationItemImpl*()); + MOCK_CONST_METHOD0(GetCurrentURL, GURL()); private: WebState* GetWebState() override { return web_state_; }
diff --git a/ios/web/public/deprecated/BUILD.gn b/ios/web/public/deprecated/BUILD.gn index 26481bc..b893a94 100644 --- a/ios/web/public/deprecated/BUILD.gn +++ b/ios/web/public/deprecated/BUILD.gn
@@ -12,8 +12,5 @@ "//ios/web/public:web_state_observer", "//url", ] - sources = [ - "global_web_state_observer.h", - "url_verification_constants.h", - ] + sources = [ "global_web_state_observer.h" ] }
diff --git a/ios/web/public/deprecated/url_verification_constants.h b/ios/web/public/deprecated/url_verification_constants.h deleted file mode 100644 index 2e5962c..0000000 --- a/ios/web/public/deprecated/url_verification_constants.h +++ /dev/null
@@ -1,20 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef IOS_WEB_PUBLIC_DEPRECATED_URL_VERIFICATION_CONSTANTS_H_ -#define IOS_WEB_PUBLIC_DEPRECATED_URL_VERIFICATION_CONSTANTS_H_ - -namespace web { -enum URLVerificationTrustLevel { - // The returned URL cannot be trusted. - kNone, - // The returned URL can be displayed to the user, but the DOM of the - // UIWebView doesn't match yet. - kMixed, - // The returned URL can be trusted. - kAbsolute, -}; -} // namespace web - -#endif // IOS_WEB_PUBLIC_DEPRECATED_URL_VERIFICATION_CONSTANTS_H_
diff --git a/ios/web/public/test/fakes/fake_web_state.h b/ios/web/public/test/fakes/fake_web_state.h index 02ea950..242d955 100644 --- a/ios/web/public/test/fakes/fake_web_state.h +++ b/ios/web/public/test/fakes/fake_web_state.h
@@ -14,7 +14,6 @@ #include "base/memory/weak_ptr.h" #include "base/observer_list.h" -#include "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/public/favicon/favicon_status.h" #import "ios/web/public/navigation/navigation_manager.h" #import "ios/web/public/navigation/web_state_policy_decider.h" @@ -86,7 +85,7 @@ int GetNavigationItemCount() const override; const GURL& GetVisibleURL() const override; const GURL& GetLastCommittedURL() const override; - GURL GetCurrentURL(URLVerificationTrustLevel* trust_level) const override; + absl::optional<GURL> GetLastCommittedURLIfTrusted() const override; CRWWebViewProxyType GetWebViewProxy() const override; void AddObserver(WebStateObserver* observer) override; @@ -136,7 +135,6 @@ void SetCurrentURL(const GURL& url); void SetNavigationItemCount(int count); void SetVisibleURL(const GURL& url); - void SetTrustLevel(URLVerificationTrustLevel trust_level); void SetNavigationManager( std::unique_ptr<NavigationManager> navigation_manager); void SetWebFramesManager( @@ -199,7 +197,6 @@ FaviconStatus favicon_status_; GURL url_; std::u16string title_; - URLVerificationTrustLevel trust_level_ = kAbsolute; bool content_is_html_ = true; std::string mime_type_; std::unique_ptr<NavigationManager> navigation_manager_;
diff --git a/ios/web/public/test/fakes/fake_web_state.mm b/ios/web/public/test/fakes/fake_web_state.mm index 319a5ba..1af2be5 100644 --- a/ios/web/public/test/fakes/fake_web_state.mm +++ b/ios/web/public/test/fakes/fake_web_state.mm
@@ -259,10 +259,7 @@ return url_; } -GURL FakeWebState::GetCurrentURL(URLVerificationTrustLevel* trust_level) const { - if (trust_level) { - *trust_level = trust_level_; - } +absl::optional<GURL> FakeWebState::GetLastCommittedURLIfTrusted() const { return url_; } @@ -452,10 +449,6 @@ url_ = url; } -void FakeWebState::SetTrustLevel(URLVerificationTrustLevel trust_level) { - trust_level_ = trust_level; -} - void FakeWebState::SetCanTakeSnapshot(bool can_take_snapshot) { can_take_snapshot_ = can_take_snapshot; }
diff --git a/ios/web/public/test/web_test_with_web_state.mm b/ios/web/public/test/web_test_with_web_state.mm index c25601a..c70a402 100644 --- a/ios/web/public/test/web_test_with_web_state.mm +++ b/ios/web/public/test/web_test_with_web_state.mm
@@ -12,7 +12,6 @@ #import "ios/web/common/features.h" #import "ios/web/navigation/navigation_manager_impl.h" #import "ios/web/navigation/wk_navigation_util.h" -#import "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/public/test/js_test_util.h" #import "ios/web/public/test/task_observer_util.h" #import "ios/web/public/test/web_state_test_util.h" @@ -143,8 +142,7 @@ } std::string WebTestWithWebState::BaseUrl() const { - web::URLVerificationTrustLevel unused_level; - return web_state()->GetCurrentURL(&unused_level).spec(); + return web_state()->GetLastCommittedURL().spec(); } web::WebState* WebTestWithWebState::web_state() {
diff --git a/ios/web/public/web_state.h b/ios/web/public/web_state.h index c697a05..c696e55 100644 --- a/ios/web/public/web_state.h +++ b/ios/web/public/web_state.h
@@ -22,7 +22,6 @@ #include "base/time/time.h" #include "build/blink_buildflags.h" #include "components/sessions/core/session_id.h" -#include "ios/web/public/deprecated/url_verification_constants.h" #include "ios/web/public/js_messaging/content_world.h" #include "ios/web/public/navigation/referrer.h" #include "mojo/public/cpp/bindings/generic_pending_receiver.h" @@ -393,12 +392,9 @@ // displayed in this WebState. It represents the current security context. virtual const GURL& GetLastCommittedURL() const = 0; - // Returns the WebState view of the current URL. Moreover, this method - // will set the trustLevel enum to the appropriate level from a security point - // of view. The caller has to handle the case where `trust_level` is not - // appropriate. Passing `null` will skip the trust check. - // TODO(crbug.com/457679): Figure out a clean API for this. - virtual GURL GetCurrentURL(URLVerificationTrustLevel* trust_level) const = 0; + // Returns the last committed URL if the correctness of this URL's origin is + // trusted, and absl::nullopt otherwise. + virtual absl::optional<GURL> GetLastCommittedURLIfTrusted() const = 0; // Returns the current CRWWebViewProxy object. virtual CRWWebViewProxyType GetWebViewProxy() const = 0;
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.h b/ios/web/test/fakes/fake_navigation_manager_delegate.h index 6bfb6ff..4087834 100644 --- a/ios/web/test/fakes/fake_navigation_manager_delegate.h +++ b/ios/web/test/fakes/fake_navigation_manager_delegate.h
@@ -28,6 +28,7 @@ bool has_user_gesture) override; void RemoveWebView() override; NavigationItemImpl* GetPendingItem() override; + GURL GetCurrentURL() const override; // Setters for tests to inject dependencies. void SetWebViewNavigationProxy(id test_web_view);
diff --git a/ios/web/test/fakes/fake_navigation_manager_delegate.mm b/ios/web/test/fakes/fake_navigation_manager_delegate.mm index 79e6590..326cc920 100644 --- a/ios/web/test/fakes/fake_navigation_manager_delegate.mm +++ b/ios/web/test/fakes/fake_navigation_manager_delegate.mm
@@ -40,6 +40,10 @@ return nullptr; } +GURL FakeNavigationManagerDelegate::GetCurrentURL() const { + return GURL(); +} + void FakeNavigationManagerDelegate::SetWebViewNavigationProxy(id web_view) { test_web_view_ = web_view; }
diff --git a/ios/web/web_state/ui/crw_web_controller.h b/ios/web/web_state/ui/crw_web_controller.h index b65228c..65f1a65 100644 --- a/ios/web/web_state/ui/crw_web_controller.h +++ b/ios/web/web_state/ui/crw_web_controller.h
@@ -8,7 +8,6 @@ #import <UIKit/UIKit.h> #import "base/values.h" -#include "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/web_state/ui/crw_touch_tracking_recognizer.h" #import "ios/web/web_state/ui/crw_web_view_navigation_proxy.h" @@ -116,11 +115,9 @@ // Returns YES if the current live view is a web view with HTML. - (BOOL)contentIsHTML; -// Returns the CRWWebController's view of the current URL. Moreover, this method -// will set the trustLevel enum to the appropriate level from a security point -// of view. The caller has to handle the case where `trustLevel` is not -// appropriate, as this method won't display any error to the user. -- (GURL)currentURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel; +// Returns the CRWWebController's view of the current URL. During navigations, +// this may not be the same as the navigation manager's view of the current URL. +- (GURL)currentURL; // Reloads web view. `isRendererInitiated` is YES for renderer-initiated // navigation. `isRendererInitiated` is NO for browser-initiated navigation.
diff --git a/ios/web/web_state/ui/crw_web_controller.mm b/ios/web/web_state/ui/crw_web_controller.mm index 3d86da41..d2193c69 100644 --- a/ios/web/web_state/ui/crw_web_controller.mm +++ b/ios/web/web_state/ui/crw_web_controller.mm
@@ -169,14 +169,6 @@ @property(nonatomic, strong, readonly) CRWWebRequestController* requestController; -// The web view's view of the current URL. During page transitions -// this may not be the same as the session history's view of the current URL. -// This method can change the state of the CRWWebController, as it will display -// an error if the returned URL is not reliable from a security point of view. -// Note that this method is expensive, so it should always be cached locally if -// it's needed multiple times in a method. -@property(nonatomic, readonly) GURL currentURL; - @property(nonatomic, readonly) web::WebState* webState; // WebStateImpl instance associated with this CRWWebController, web controller // does not own this pointer. @@ -206,10 +198,6 @@ // ContextMenu controller, handling the interactions with the context menu. @property(nonatomic, strong) CRWContextMenuController* contextMenuController; -// Returns the current URL of the web view, and sets `trustLevel` accordingly -// based on the confidence in the verification. -- (GURL)webURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel; - // Called following navigation completion to generate final navigation lifecycle // events. Navigation is considered complete when the document has finished // loading, or when other page load mechanics are completed on a @@ -428,12 +416,6 @@ return observers; } -- (GURL)currentURL { - web::URLVerificationTrustLevel trustLevel = - web::URLVerificationTrustLevel::kNone; - return [self currentURLWithTrustLevel:&trustLevel]; -} - - (WebState*)webState { return _webStateImpl; } @@ -521,9 +503,7 @@ web::IsContentTypeHtml(self.webState->GetContentsMimeType()); } -- (GURL)currentURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel { - DCHECK(trustLevel) << "Verification of the trustLevel state is mandatory"; - +- (GURL)currentURL { // The web view URL is the current URL only if it is neither a placeholder URL // (used to hold WKBackForwardListItem for WebUI) nor a restore_session.html // (used to replay session history in WKWebView). @@ -531,10 +511,9 @@ // it can be implemented using NavigationManager API after removal of legacy // navigation stack. if (self.webView && !IsWKInternalUrl(self.webView.URL)) { - return [self webURLWithTrustLevel:trustLevel]; + return _documentURL; } - // Any non-web URL source is trusted. - *trustLevel = web::URLVerificationTrustLevel::kAbsolute; + web::NavigationItem* item = self.navigationManagerImpl ->GetLastCommittedItemInCurrentOrRestoredSession(); @@ -1177,12 +1156,6 @@ } } -- (GURL)webURLWithTrustLevel:(web::URLVerificationTrustLevel*)trustLevel { - DCHECK(trustLevel); - *trustLevel = web::URLVerificationTrustLevel::kAbsolute; - return _documentURL; -} - - (BOOL)isUserInitiatedAction:(WKNavigationAction*)action { return _userInteractionState.IsUserInteracting(self.webView); }
diff --git a/ios/web/web_state/ui/crw_web_controller_unittest.mm b/ios/web/web_state/ui/crw_web_controller_unittest.mm index b6054ce2..8bc47cf7 100644 --- a/ios/web/web_state/ui/crw_web_controller_unittest.mm +++ b/ios/web/web_state/ui/crw_web_controller_unittest.mm
@@ -26,7 +26,6 @@ #import "ios/web/navigation/navigation_item_impl.h" #import "ios/web/navigation/navigation_manager_impl.h" #import "ios/web/navigation/wk_navigation_action_policy_util.h" -#import "ios/web/public/deprecated/url_verification_constants.h" #import "ios/web/public/download/download_controller.h" #import "ios/web/public/download/download_task.h" #import "ios/web/public/navigation/referrer.h" @@ -857,8 +856,8 @@ EXPECT_EQ("", task->GetMimeType()); } -// Tests `currentURLWithTrustLevel:` method. -TEST_F(CRWWebControllerTest, CurrentUrlWithTrustLevel) { +// Tests `currentURL` method. +TEST_F(CRWWebControllerTest, CurrentUrl) { GURL url("http://chromium.test"); AddPendingItem(url, ui::PAGE_TRANSITION_TYPED); @@ -876,9 +875,7 @@ [fake_wk_list_ setCurrentURL:@"http://chromium.test"]; [navigation_delegate_ webView:mock_web_view_ didCommitNavigation:nil]; - URLVerificationTrustLevel trust_level = kNone; - EXPECT_EQ(url, [web_controller() currentURLWithTrustLevel:&trust_level]); - EXPECT_EQ(kAbsolute, trust_level); + EXPECT_EQ(url, [web_controller() currentURL]); } // Test fixture to test decidePolicyForNavigationAction:decisionHandler:
diff --git a/ios/web/web_state/web_state_impl.h b/ios/web/web_state/web_state_impl.h index 897b70bb..6f20767 100644 --- a/ios/web/web_state/web_state_impl.h +++ b/ios/web/web_state/web_state_impl.h
@@ -314,7 +314,7 @@ int GetNavigationItemCount() const final; const GURL& GetVisibleURL() const final; const GURL& GetLastCommittedURL() const final; - GURL GetCurrentURL(URLVerificationTrustLevel* trust_level) const final; + absl::optional<GURL> GetLastCommittedURLIfTrusted() const final; id<CRWWebViewProxy> GetWebViewProxy() const final; void DidChangeVisibleSecurityState() final; InterfaceBinder* GetInterfaceBinderForMainFrame() final;
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm index 3bd4e6c..da8c4d54 100644 --- a/ios/web/web_state/web_state_impl.mm +++ b/ios/web/web_state/web_state_impl.mm
@@ -580,8 +580,9 @@ : saved_->GetLastCommittedURL(); } -GURL WebStateImpl::GetCurrentURL(URLVerificationTrustLevel* trust_level) const { - return LIKELY(pimpl_) ? pimpl_->GetCurrentURL(trust_level) : GURL(); +absl::optional<GURL> WebStateImpl::GetLastCommittedURLIfTrusted() const { + return LIKELY(pimpl_) ? pimpl_->GetLastCommittedURLIfTrusted() + : saved_->GetLastCommittedURL(); } id<CRWWebViewProxy> WebStateImpl::GetWebViewProxy() const {
diff --git a/ios/web/web_state/web_state_impl_realized_web_state.h b/ios/web/web_state/web_state_impl_realized_web_state.h index f4784c5..ead564b 100644 --- a/ios/web/web_state/web_state_impl_realized_web_state.h +++ b/ios/web/web_state/web_state_impl_realized_web_state.h
@@ -165,7 +165,7 @@ int GetNavigationItemCount() const; const GURL& GetVisibleURL() const; const GURL& GetLastCommittedURL() const; - GURL GetCurrentURL(URLVerificationTrustLevel* trust_level) const; + absl::optional<GURL> GetLastCommittedURLIfTrusted() const; id<CRWWebViewProxy> GetWebViewProxy() const; void DidChangeVisibleSecurityState(); WebState::InterfaceBinder* GetInterfaceBinderForMainFrame(); @@ -207,6 +207,7 @@ bool has_user_gesture) final; void RemoveWebView() final; NavigationItemImpl* GetPendingItem() final; + GURL GetCurrentURL() const final; private: // Creates a WebUIIOS object for `url` that is owned by the called. Returns
diff --git a/ios/web/web_state/web_state_impl_realized_web_state.mm b/ios/web/web_state/web_state_impl_realized_web_state.mm index 00c9a40..c3b0693a 100644 --- a/ios/web/web_state/web_state_impl_realized_web_state.mm +++ b/ios/web/web_state/web_state_impl_realized_web_state.mm
@@ -710,34 +710,22 @@ return item ? item->GetVirtualURL() : GURL::EmptyGURL(); } -GURL WebStateImpl::RealizedWebState::GetCurrentURL( - URLVerificationTrustLevel* trust_level) const { - if (!trust_level) { - auto ignore_trust = URLVerificationTrustLevel::kNone; - return [web_controller_ currentURLWithTrustLevel:&ignore_trust]; - } - GURL result = [web_controller_ currentURLWithTrustLevel:trust_level]; - +absl::optional<GURL> +WebStateImpl::RealizedWebState::GetLastCommittedURLIfTrusted() const { NavigationItemImpl* item = navigation_manager_->GetLastCommittedItemImpl(); - GURL lastCommittedURL = item ? item->GetURL() : GURL(); + if (!item) { + return GURL(); + } - bool equalOrigins; - if (result.SchemeIs(url::kAboutScheme) && - GetWebClient()->IsAppSpecificURL(GetLastCommittedURL())) { - // This special case is added for any app specific URLs that have been - // rewritten to about:// URLs. In this case, an about scheme does not have - // an origin to compare, only a path. - equalOrigins = result.path() == lastCommittedURL.path(); - } else { - equalOrigins = result.DeprecatedGetOriginAsURL() == - lastCommittedURL.DeprecatedGetOriginAsURL(); + if (item->IsUntrusted()) { + return absl::nullopt; } - UMA_HISTOGRAM_BOOLEAN("Web.CurrentOriginEqualsLastCommittedOrigin", - equalOrigins); - if (!equalOrigins || (item && item->IsUntrusted())) { - *trust_level = URLVerificationTrustLevel::kMixed; - } - return result; + + return item->GetVirtualURL(); +} + +GURL WebStateImpl::RealizedWebState::GetCurrentURL() const { + return [web_controller_ currentURL]; } id<CRWWebViewProxy> WebStateImpl::RealizedWebState::GetWebViewProxy() const {
diff --git a/ios/web_view/PRESUBMIT.py b/ios/web_view/PRESUBMIT.py index 2763c350..6f02e1ce 100644 --- a/ios/web_view/PRESUBMIT.py +++ b/ios/web_view/PRESUBMIT.py
@@ -10,7 +10,6 @@ import os -USE_PYTHON3 = True INCLUSION_PREFIXES = ('#import "', '#include "')
diff --git a/media/PRESUBMIT.py b/media/PRESUBMIT.py index 0a4b6a77..f90c598 100644 --- a/media/PRESUBMIT.py +++ b/media/PRESUBMIT.py
@@ -12,10 +12,6 @@ PRESUBMIT_VERSION = '2.0.0' -# This line is 'magic' in that git-cl looks for it to decide whether to -# use Python3 instead of Python2 when running the code in this file. -USE_PYTHON3 = True - # Well-defined simple classes containing only <= 4 ints, or <= 2 floats. BASE_TIME_TYPES = [ 'base::Time',
diff --git a/media/audio/cras/cras_util.cc b/media/audio/cras/cras_util.cc index 01e28bd..e5350406 100644 --- a/media/audio/cras/cras_util.cc +++ b/media/audio/cras/cras_util.cc
@@ -15,7 +15,7 @@ namespace { constexpr char kInternalInputVirtualDevice[] = "Built-in mic"; -constexpr char kInternalOutputVirtualDevice[] = "Built-in speaker"; +constexpr char kInternalOutputVirtualDevice[] = "Built-in speaker/headphone"; constexpr char kHeadphoneLineOutVirtualDevice[] = "Headphone/Line Out"; // Names below are from the node_type_to_str function in CRAS server.
diff --git a/media/base/media_switches.cc b/media/base/media_switches.cc index 68c6cd1..d0b6268 100644 --- a/media/base/media_switches.cc +++ b/media/base/media_switches.cc
@@ -816,12 +816,18 @@ "video-blit-color-accuracy", base::FEATURE_ENABLED_BY_DEFAULT); -#if BUILDFLAG(IS_MAC) +#if BUILDFLAG(IS_APPLE) // Use the new VideoToolboxVideoDecoder for hardware decoding. BASE_FEATURE(kVideoToolboxVideoDecoder, "VideoToolboxVideoDecoder", base::FEATURE_DISABLED_BY_DEFAULT); -#endif // BUILDFLAG(IS_MAC) +#endif // BUILDFLAG(IS_APPLE) + +// Inform webrtc with correct video color space information whenever +// possible. +BASE_FEATURE(kWebRTCColorAccuracy, + "WebRTCColorAccuracy", + base::FEATURE_DISABLED_BY_DEFAULT); // Enable VP9 k-SVC decoding with HW decoder for webrtc use case. BASE_FEATURE(kVp9kSVCHWDecoding, @@ -1269,14 +1275,20 @@ // lacros-chrome through the crosapi. const base::Feature MEDIA_EXPORT kExposeOutOfProcessVideoDecodingToLacros{ "ExposeOutOfProcessVideoDecodingToLacros", - base::FEATURE_DISABLED_BY_DEFAULT}; + base::FEATURE_ENABLED_BY_DEFAULT}; #endif // BUILDFLAG(IS_CHROMEOS_ASH) #if BUILDFLAG(ALLOW_OOP_VIDEO_DECODER) // Spawn utility processes to perform hardware decode acceleration instead of // using the GPU process. const base::Feature MEDIA_EXPORT kUseOutOfProcessVideoDecoding{ - "UseOutOfProcessVideoDecoding", base::FEATURE_DISABLED_BY_DEFAULT}; + "UseOutOfProcessVideoDecoding", +#if BUILDFLAG(IS_CHROMEOS_LACROS) + base::FEATURE_ENABLED_BY_DEFAULT +#else + base::FEATURE_DISABLED_BY_DEFAULT +#endif +}; #endif // BUILDFLAG(ALLOW_OOP_VIDEO_DECODER) #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
diff --git a/media/base/media_switches.h b/media/base/media_switches.h index 1045b34..45cd001 100644 --- a/media/base/media_switches.h +++ b/media/base/media_switches.h
@@ -314,9 +314,10 @@ MEDIA_EXPORT BASE_DECLARE_FEATURE(kV4L2FlatStatefulVideoDecoder); #endif // defined(ARCH_CPU_ARM_FAMILY) && BUILDFLAG(IS_CHROMEOS) MEDIA_EXPORT BASE_DECLARE_FEATURE(kVideoBlitColorAccuracy); -#if BUILDFLAG(IS_MAC) +#if BUILDFLAG(IS_APPLE) MEDIA_EXPORT BASE_DECLARE_FEATURE(kVideoToolboxVideoDecoder); -#endif // BUILDFLAG(IS_MAC) +#endif // BUILDFLAG(IS_APPLE) +MEDIA_EXPORT BASE_DECLARE_FEATURE(kWebRTCColorAccuracy); MEDIA_EXPORT BASE_DECLARE_FEATURE(kVp9kSVCHWDecoding); MEDIA_EXPORT BASE_DECLARE_FEATURE(kWebContentsCaptureHiDpi); MEDIA_EXPORT BASE_DECLARE_FEATURE(kWebrtcMediaCapabilitiesParameters);
diff --git a/media/formats/mp4/writable_box_definitions.cc b/media/formats/mp4/writable_box_definitions.cc index 17b9a00d..17a66778 100644 --- a/media/formats/mp4/writable_box_definitions.cc +++ b/media/formats/mp4/writable_box_definitions.cc
@@ -35,4 +35,20 @@ const ElementaryStreamDescriptor&) = default; #endif +TrackFragmentRun::TrackFragmentRun() = default; +TrackFragmentRun::~TrackFragmentRun() = default; +TrackFragmentRun::TrackFragmentRun(const TrackFragmentRun&) = default; +TrackFragmentRun& TrackFragmentRun::operator=(const TrackFragmentRun&) = + default; + +MovieFragment::MovieFragment() = default; +MovieFragment::~MovieFragment() = default; +MovieFragment::MovieFragment(const MovieFragment&) = default; +MovieFragment& MovieFragment::operator=(const MovieFragment&) = default; + +MediaData::MediaData() = default; +MediaData::~MediaData() = default; +MediaData::MediaData(const MediaData&) = default; +MediaData& MediaData::operator=(const MediaData&) = default; + } // namespace media::mp4::writable_boxes
diff --git a/media/formats/mp4/writable_box_definitions.h b/media/formats/mp4/writable_box_definitions.h index 1f7ad1fe..5897a87 100644 --- a/media/formats/mp4/writable_box_definitions.h +++ b/media/formats/mp4/writable_box_definitions.h
@@ -8,6 +8,7 @@ #include <string> #include <vector> +#include "base/containers/span.h" #include "base/time/time.h" #include "media/base/media_export.h" #include "media/formats/mp4/box_definitions.h" @@ -24,6 +25,35 @@ kTrackInPreview = 0x0004, }; +enum class TrackFragmentHeaderFlags : uint32_t { + kBaseDataOffsetPresent = 0x0001, + kSampleDescriptionIndexPresent = 0x0002, + kDefaultSampleDurationPresent = 0x0008, + kDefaultSampleSizePresent = 0x0010, + kkDefaultSampleFlagsPresent = 0x0020, + + // This is `iso5` brand by spec on 14496-12, so can't be used + // with brand of `isom`, `avc1`, `iso2`. + + // https://www.w3.org/TR/mse-byte-stream-format-isobmff/ said that + // it should have `kDefaultBaseIsMoof', but not `kBaseDataOffsetPresent`. + kDefaultBaseIsMoof = 0x020000, +}; + +enum class TrackFragmentRunFlags : uint16_t { + kDataOffsetPresent = 0x0001, + kFirstSampleFlagsPresent = 0x0004, + kSampleDurationPresent = 0x0100, + kSampleSizePresent = 0x0200, + kSampleFlagsPresent = 0x0400, +}; + +enum class FragmentSampleFlags : uint32_t { + kSampleFlagIsNonSync = 0x00010000, + kSampleFlagDependsYes = 0x01000000, + kSampleFlagDependsNo = 0x02000000, +}; + // Box header without version. struct MEDIA_EXPORT Box {}; @@ -258,6 +288,73 @@ MovieExtends extends; }; +// Track Fragment Run (`trun`) box. +struct MEDIA_EXPORT TrackFragmentRun : FullBox { + TrackFragmentRun(); + ~TrackFragmentRun(); + TrackFragmentRun(const TrackFragmentRun&); + TrackFragmentRun& operator=(const TrackFragmentRun&); + + uint32_t sample_count; + uint32_t first_sample_flags; + + // Optional fields, presence is indicated in `flags`. If not present, the + // default value established in the `TrackFragmentHeader` is used. + std::vector<base::TimeDelta> sample_durations; + std::vector<uint32_t> sample_sizes; + std::vector<uint32_t> sample_flags; + // We don't support sample_composition_time_offsets as we don't know + // how to get it on given data. +}; + +// Track Fragment Decode Time (`tfdt`) box. +struct MEDIA_EXPORT TrackFragmentDecodeTime : Box { + base::TimeDelta base_media_decode_time; +}; + +// Track Fragment Header(`tfhd`) box. +struct MEDIA_EXPORT TrackFragmentHeader : FullBox { + uint32_t track_id; + + // `base_data_offset` will be calculated during fragment write. + // uint64_t base_data_offset; + base::TimeDelta default_sample_duration; + uint32_t default_sample_size; + uint32_t default_sample_flags; +}; + +// Track Fragment Header(`traf`) box. +struct MEDIA_EXPORT TrackFragment : Box { + TrackFragmentHeader header; + TrackFragmentDecodeTime decode_time; + TrackFragmentRun run; +}; + +// Movie Fragment Header(`mfhd`) box. +struct MEDIA_EXPORT MovieFragmentHeader : FullBox { + uint32_t sequence_number; +}; + +// Movie Fragment (`moof`) box. +struct MEDIA_EXPORT MovieFragment : Box { + MovieFragment(); + ~MovieFragment(); + MovieFragment(const MovieFragment&); + MovieFragment& operator=(const MovieFragment&); + + MovieFragmentHeader header; + std::vector<TrackFragment> track_fragments; +}; + +// Media Data (`mdat`) box. +struct MEDIA_EXPORT MediaData : Box { + MediaData(); + ~MediaData(); + MediaData(const MediaData&); + MediaData& operator=(const MediaData&); + std::vector<base::span<uint8_t>> data; +}; + } // namespace media::mp4::writable_boxes #endif // MEDIA_FORMATS_MP4_WRITABLE_BOX_DEFINITIONS_H_
diff --git a/media/gpu/ipc/client/BUILD.gn b/media/gpu/ipc/client/BUILD.gn deleted file mode 100644 index 29164df..0000000 --- a/media/gpu/ipc/client/BUILD.gn +++ /dev/null
@@ -1,25 +0,0 @@ -# Copyright 2016 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -source_set("client") { - sources = [ - "gpu_video_decode_accelerator_host.cc", - "gpu_video_decode_accelerator_host.h", - ] - - deps = [ - "//base", - "//gpu/ipc/common", - "//ipc", - "//media", - "//media:media_buildflags", - "//media/gpu", - "//media/gpu/ipc/common", - "//media/mojo/mojom", - "//ui/gfx:memory_buffer", - "//ui/gfx/geometry", - "//ui/gfx/ipc", - "//ui/gfx/ipc/color", - ] -}
diff --git a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc b/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc deleted file mode 100644 index 1aaef12e..0000000 --- a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.cc +++ /dev/null
@@ -1,256 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/gpu/ipc/client/gpu_video_decode_accelerator_host.h" - -#include "base/functional/bind.h" -#include "base/logging.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/single_thread_task_runner.h" -#include "build/build_config.h" -#include "gpu/ipc/client/gpu_channel_host.h" -#include "ipc/ipc_mojo_bootstrap.h" -#include "mojo/public/cpp/bindings/associated_remote.h" - -namespace media { - -GpuVideoDecodeAcceleratorHost::GpuVideoDecodeAcceleratorHost( - gpu::CommandBufferProxyImpl* impl) - : client_(nullptr), - impl_(impl), - media_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()) { - DCHECK(impl_); - - weak_this_ = weak_this_factory_.GetWeakPtr(); - impl_->AddDeletionObserver(this); -} - -GpuVideoDecodeAcceleratorHost::~GpuVideoDecodeAcceleratorHost() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - base::AutoLock lock(impl_lock_); - if (impl_) - impl_->RemoveDeletionObserver(this); -} - -void GpuVideoDecodeAcceleratorHost::OnDisconnectedFromGpuProcess() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - decoder_.reset(); - client_receiver_.reset(); - DLOG(ERROR) << "OnDisconnectedFromGpuProcess()"; - PostNotifyError(PLATFORM_FAILURE); -} - -bool GpuVideoDecodeAcceleratorHost::Initialize(const Config& config, - Client* client) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - client_ = client; - - base::AutoLock lock(impl_lock_); - if (!impl_) - return false; - - // Mojo will ignore our request to bind to a different thread than the main or - // IO thread unless we construct this object. It does this to avoid breaking - // use cases that depend on the behavior of ignoring other bindings, as - // detailed in the documentation for - // IPC::ScopedAllowOffSequenceChannelAssociatedBindings. - IPC::ScopedAllowOffSequenceChannelAssociatedBindings allow_binding; - - const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = - impl_->channel()->io_task_runner(); - bool succeeded = false; - mojo::SharedAssociatedRemote<mojom::GpuAcceleratedVideoDecoderProvider> - provider; - impl_->BindMediaReceiver( - provider.BindNewEndpointAndPassReceiver(io_task_runner)); - provider->CreateAcceleratedVideoDecoder( - config, decoder_.BindNewEndpointAndPassReceiver(io_task_runner), - client_receiver_.BindNewEndpointAndPassRemote(), &succeeded); - if (!succeeded) { - DLOG(ERROR) << "CreateAcceleratedVideoDecoder() failed"; - PostNotifyError(PLATFORM_FAILURE); - decoder_.reset(); - client_receiver_.reset(); - return false; - } - - decoder_.set_disconnect_handler( - base::BindOnce( - &GpuVideoDecodeAcceleratorHost::OnDisconnectedFromGpuProcess, - weak_this_), - base::SequencedTaskRunner::GetCurrentDefault()); - return true; -} - -void GpuVideoDecodeAcceleratorHost::Decode(BitstreamBuffer bitstream_buffer) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!decoder_) - return; - decoder_->Decode(std::move(bitstream_buffer)); -} - -void GpuVideoDecodeAcceleratorHost::AssignPictureBuffers( - const std::vector<PictureBuffer>& buffers) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!decoder_) - return; - std::vector<mojom::PictureBufferAssignmentPtr> assignments; - for (const auto& buffer : buffers) { - if (buffer.size() != picture_buffer_dimensions_) { - DLOG(ERROR) << "buffer.size() invalid: expected " - << picture_buffer_dimensions_.ToString() << ", got " - << buffer.size().ToString(); - PostNotifyError(INVALID_ARGUMENT); - return; - } - assignments.push_back(mojom::PictureBufferAssignment::New( - buffer.id(), buffer.client_texture_ids())); - } - decoder_->AssignPictureBuffers(std::move(assignments)); -} - -void GpuVideoDecodeAcceleratorHost::ReusePictureBuffer( - int32_t picture_buffer_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!decoder_) - return; - decoder_->ReusePictureBuffer(picture_buffer_id); -} - -void GpuVideoDecodeAcceleratorHost::Flush() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!decoder_) - return; - decoder_->Flush(base::BindOnce(&GpuVideoDecodeAcceleratorHost::OnFlushDone, - base::Unretained(this))); -} - -void GpuVideoDecodeAcceleratorHost::Reset() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!decoder_) - return; - decoder_->Flush(base::BindOnce(&GpuVideoDecodeAcceleratorHost::OnResetDone, - base::Unretained(this))); -} - -void GpuVideoDecodeAcceleratorHost::SetOverlayInfo( - const OverlayInfo& overlay_info) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!decoder_) - return; - decoder_->SetOverlayInfo(overlay_info); -} - -void GpuVideoDecodeAcceleratorHost::Destroy() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - client_ = nullptr; - delete this; -} - -void GpuVideoDecodeAcceleratorHost::OnWillDeleteImpl() { - base::AutoLock lock(impl_lock_); - impl_ = nullptr; - - // The gpu::CommandBufferProxyImpl is going away; error out this VDA. - media_task_runner_->PostTask( - FROM_HERE, - base::BindOnce( - &GpuVideoDecodeAcceleratorHost::OnDisconnectedFromGpuProcess, - weak_this_)); -} - -void GpuVideoDecodeAcceleratorHost::PostNotifyError(Error error) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - DVLOG(2) << "PostNotifyError(): error=" << error; - media_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuVideoDecodeAcceleratorHost::OnError, - weak_this_, error)); -} - -// TODO(tmathmeyer) This needs to accept a Status at some point -void GpuVideoDecodeAcceleratorHost::OnInitializationComplete(bool success) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (client_) { - client_->NotifyInitializationComplete( - success ? DecoderStatus::Codes::kOk : DecoderStatus::Codes::kFailed); - } -} - -void GpuVideoDecodeAcceleratorHost::OnBitstreamBufferProcessed( - int32_t bitstream_buffer_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (client_) - client_->NotifyEndOfBitstreamBuffer(bitstream_buffer_id); -} - -void GpuVideoDecodeAcceleratorHost::OnProvidePictureBuffers( - uint32_t num_requested_buffers, - VideoPixelFormat format, - uint32_t textures_per_buffer, - const gfx::Size& dimensions, - uint32_t texture_target) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - picture_buffer_dimensions_ = dimensions; - - const int kMaxVideoPlanes = 4; - if (textures_per_buffer > kMaxVideoPlanes) { - PostNotifyError(PLATFORM_FAILURE); - return; - } - - if (client_) { - client_->ProvidePictureBuffers(num_requested_buffers, format, - textures_per_buffer, dimensions, - texture_target); - } -} - -void GpuVideoDecodeAcceleratorHost::OnDismissPictureBuffer( - int32_t picture_buffer_id) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (client_) - client_->DismissPictureBuffer(picture_buffer_id); -} - -void GpuVideoDecodeAcceleratorHost::OnPictureReady( - mojom::PictureReadyParamsPtr params) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!client_) - return; - Picture picture(params->picture_buffer_id, params->bitstream_buffer_id, - params->visible_rect, params->color_space, - params->allow_overlay); - picture.set_read_lock_fences_enabled(params->read_lock_fences_enabled); - picture.set_size_changed(params->size_changed); - picture.set_texture_owner(params->surface_texture); - picture.set_wants_promotion_hint(params->wants_promotion_hint); - client_->PictureReady(picture); -} - -void GpuVideoDecodeAcceleratorHost::OnFlushDone() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (client_) - client_->NotifyFlushDone(); -} - -void GpuVideoDecodeAcceleratorHost::OnResetDone() { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (client_) - client_->NotifyResetDone(); -} - -void GpuVideoDecodeAcceleratorHost::OnError(uint32_t error) { - DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - if (!client_) - return; - weak_this_factory_.InvalidateWeakPtrs(); - - // Client::NotifyError() may Destroy() |this|, so calling it needs to be the - // last thing done on this stack! - VideoDecodeAccelerator::Client* client = client_; - client_ = nullptr; - client->NotifyError(static_cast<VideoDecodeAccelerator::Error>(error)); -} - -} // namespace media
diff --git a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.h b/media/gpu/ipc/client/gpu_video_decode_accelerator_host.h deleted file mode 100644 index 29e9197..0000000 --- a/media/gpu/ipc/client/gpu_video_decode_accelerator_host.h +++ /dev/null
@@ -1,111 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_GPU_IPC_CLIENT_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_ -#define MEDIA_GPU_IPC_CLIENT_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_ - -#include <stdint.h> - -#include <vector> - -#include "base/memory/raw_ptr.h" -#include "base/memory/weak_ptr.h" -#include "base/sequence_checker.h" -#include "base/task/single_thread_task_runner.h" -#include "gpu/ipc/client/command_buffer_proxy_impl.h" -#include "media/mojo/mojom/gpu_accelerated_video_decoder.mojom.h" -#include "media/video/video_decode_accelerator.h" -#include "mojo/public/cpp/bindings/associated_receiver.h" -#include "mojo/public/cpp/bindings/shared_associated_remote.h" -#include "ui/gfx/geometry/size.h" - -namespace media { - -// This class is used to talk to VideoDecodeAccelerator in the Gpu process -// through IPC messages. -class GpuVideoDecodeAcceleratorHost - : public VideoDecodeAccelerator, - public gpu::CommandBufferProxyImpl::DeletionObserver, - public mojom::GpuAcceleratedVideoDecoderClient { - public: - // |this| is guaranteed not to outlive |impl|. (See comments for |impl_|.) - explicit GpuVideoDecodeAcceleratorHost(gpu::CommandBufferProxyImpl* impl); - GpuVideoDecodeAcceleratorHost(const GpuVideoDecodeAcceleratorHost&) = delete; - GpuVideoDecodeAcceleratorHost& operator=(GpuVideoDecodeAcceleratorHost&) = - delete; - - // VideoDecodeAccelerator implementation. - bool Initialize(const Config& config, Client* client) override; - void Decode(BitstreamBuffer bitstream_buffer) override; - void AssignPictureBuffers(const std::vector<PictureBuffer>& buffers) override; - void ReusePictureBuffer(int32_t picture_buffer_id) override; - void Flush() override; - void Reset() override; - void SetOverlayInfo(const OverlayInfo&) override; - void Destroy() override; - - // gpu::CommandBufferProxyImpl::DeletionObserver implemetnation. - void OnWillDeleteImpl() override; - - private: - // Only Destroy() should be deleting |this|. - ~GpuVideoDecodeAcceleratorHost() override; - - void OnDisconnectedFromGpuProcess(); - - // Notify |client_| of an error. Posts a task to avoid re-entrancy. - void PostNotifyError(Error); - - // mojom::GpuAcceleratedVideoDecoderClient: - void OnInitializationComplete(bool success) override; - void OnBitstreamBufferProcessed(int32_t bitstream_buffer_id) override; - void OnProvidePictureBuffers(uint32_t num_requested_buffers, - VideoPixelFormat format, - uint32_t textures_per_buffer, - const gfx::Size& dimensions, - uint32_t texture_target) override; - void OnDismissPictureBuffer(int32_t picture_buffer_id) override; - void OnPictureReady(mojom::PictureReadyParamsPtr params) override; - void OnError(uint32_t error) override; - - void OnFlushDone(); - void OnResetDone(); - - // Receiver and remote endpoints for connections to the GPU process. These are - // associated with the corresponding CommandBuffer interface given at - // construction time. - mojo::AssociatedReceiver<mojom::GpuAcceleratedVideoDecoderClient> - client_receiver_{this}; - mojo::SharedAssociatedRemote<mojom::GpuAcceleratedVideoDecoder> decoder_; - - // The client that will receive callbacks from the decoder. - raw_ptr<Client> client_; - - // Protect |impl_|. |impl_| is used on media thread, but it can be invalidated - // on main thread. - base::Lock impl_lock_; - - // Unowned reference to the gpu::CommandBufferProxyImpl that created us. - // |this| registers as a DeletionObserver of |impl_|, the so reference is - // always valid as long as it is not NULL. - raw_ptr<gpu::CommandBufferProxyImpl> impl_; - - // Requested dimensions of the buffer, from ProvidePictureBuffers(). - gfx::Size picture_buffer_dimensions_; - - // Task runner for tasks that should run on the thread this class is - // constructed. - scoped_refptr<base::SingleThreadTaskRunner> media_task_runner_; - - // WeakPtr for posting tasks to ourself. - base::WeakPtr<GpuVideoDecodeAcceleratorHost> weak_this_; - - SEQUENCE_CHECKER(sequence_checker_); - - base::WeakPtrFactory<GpuVideoDecodeAcceleratorHost> weak_this_factory_{this}; -}; - -} // namespace media - -#endif // MEDIA_GPU_IPC_CLIENT_GPU_VIDEO_DECODE_ACCELERATOR_HOST_H_
diff --git a/media/gpu/ipc/service/BUILD.gn b/media/gpu/ipc/service/BUILD.gn index fbd8a05..347148e 100644 --- a/media/gpu/ipc/service/BUILD.gn +++ b/media/gpu/ipc/service/BUILD.gn
@@ -25,8 +25,6 @@ # The legacy VDA API is not supported on Android. if (!is_android) { sources += [ - "gpu_video_decode_accelerator.cc", - "gpu_video_decode_accelerator.h", "picture_buffer_manager.cc", "picture_buffer_manager.h", "vda_video_decoder.cc", @@ -42,7 +40,6 @@ "//ipc", "//media", "//media/gpu", - "//media/mojo/mojom", ] deps = [ "//build:chromeos_buildflags",
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc b/media/gpu/ipc/service/gpu_video_decode_accelerator.cc deleted file mode 100644 index e9362b3..0000000 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.cc +++ /dev/null
@@ -1,650 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "media/gpu/ipc/service/gpu_video_decode_accelerator.h" - -#include <memory> -#include <vector> - -#include "base/functional/bind.h" -#include "base/location.h" -#include "base/logging.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/ref_counted.h" -#include "base/synchronization/waitable_event.h" -#include "base/task/bind_post_task.h" -#include "base/task/sequenced_task_runner.h" -#include "base/task/single_thread_task_runner.h" -#include "build/build_config.h" -#include "gpu/command_buffer/common/command_buffer.h" -#include "gpu/config/gpu_preferences.h" -#include "gpu/ipc/service/gpu_channel.h" -#include "gpu/ipc/service/gpu_channel_manager.h" -#include "ipc/ipc_message_macros.h" -#include "ipc/ipc_message_utils.h" -#include "ipc/message_filter.h" -#include "media/base/limits.h" -#include "media/gpu/gpu_video_accelerator_util.h" -#include "media/gpu/gpu_video_decode_accelerator_factory.h" -#include "mojo/public/cpp/bindings/associated_receiver.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gl/gl_context.h" -#include "ui/gl/gl_image.h" - -namespace media { - -namespace { -static gl::GLContext* GetGLContext( - const base::WeakPtr<gpu::CommandBufferStub>& stub) { - if (!stub) { - DLOG(ERROR) << "Stub is gone; no GLContext."; - return nullptr; - } - - return stub->decoder_context()->GetGLContext(); -} - -static bool MakeDecoderContextCurrent( - const base::WeakPtr<gpu::CommandBufferStub>& stub) { - if (!stub) { - DLOG(ERROR) << "Stub is gone; won't MakeCurrent()."; - return false; - } - - if (!stub->decoder_context()->MakeCurrent()) { - DLOG(ERROR) << "Failed to MakeCurrent()"; - return false; - } - - return true; -} - -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) -static bool BindDecoderManagedImage( - const base::WeakPtr<gpu::CommandBufferStub>& stub, - uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image) { - if (!stub) { - DLOG(ERROR) << "Stub is gone; won't BindImage()."; - return false; - } - - gpu::DecoderContext* command_decoder = stub->decoder_context(); - command_decoder->AttachImageToTextureWithDecoderBinding( - client_texture_id, texture_target, image.get()); - return true; -} -#else -static bool BindClientManagedImage( - const base::WeakPtr<gpu::CommandBufferStub>& stub, - uint32_t client_texture_id, - uint32_t texture_target, - const scoped_refptr<gl::GLImage>& image) { - if (!stub) { - DLOG(ERROR) << "Stub is gone; won't BindImage()."; - return false; - } - - gpu::DecoderContext* command_decoder = stub->decoder_context(); - command_decoder->AttachImageToTextureWithClientBinding( - client_texture_id, texture_target, image.get()); - - return true; -} -#endif - -static gpu::gles2::ContextGroup* GetContextGroup( - const base::WeakPtr<gpu::CommandBufferStub>& stub) { - if (!stub) { - DLOG(ERROR) << "Stub is gone; no DecoderContext."; - return nullptr; - } - - return stub->decoder_context()->GetContextGroup(); -} - -static std::unique_ptr<gpu::gles2::AbstractTexture> CreateAbstractTexture( - const base::WeakPtr<gpu::CommandBufferStub>& stub, - GLenum target, - GLenum internal_format, - GLsizei width, - GLsizei height, - GLsizei depth, - GLint border, - GLenum format, - GLenum type) { - if (!stub) { - DLOG(ERROR) << "Stub is gone; no DecoderContext."; - return nullptr; - } - - return stub->decoder_context()->CreateAbstractTexture( - target, internal_format, width, height, depth, border, format, type); -} - -} // anonymous namespace - -// DebugAutoLock works like AutoLock but only acquires the lock when -// DCHECK is on. -#if DCHECK_IS_ON() -typedef base::AutoLock DebugAutoLock; -#else -class DebugAutoLock { - public: - explicit DebugAutoLock(base::Lock&) {} -}; -#endif - -// Receives incoming messages for the decoder. Operates exclusively on the IO -// thread, since sometimes we want to do decodes directly from there. -class GpuVideoDecodeAccelerator::MessageFilter - : public mojom::GpuAcceleratedVideoDecoder { - public: - MessageFilter(GpuVideoDecodeAccelerator* owner, - scoped_refptr<base::SequencedTaskRunner> owner_task_runner, - bool decode_on_io) - : owner_(owner), - owner_task_runner_(std::move(owner_task_runner)), - decode_on_io_(decode_on_io) {} - ~MessageFilter() override = default; - - // Called from the main thread. Posts to `io_task_runner` to do the binding - // and waits for completion before returning. This ensures the decoder's - // endpoint is established before the synchronous request to establish it is - // acknowledged to the client. - bool Bind(mojo::PendingAssociatedReceiver<mojom::GpuAcceleratedVideoDecoder> - receiver, - const scoped_refptr<base::SequencedTaskRunner>& io_task_runner) { - base::WaitableEvent bound_event; - if (!io_task_runner->PostTask( - FROM_HERE, base::BindOnce(&MessageFilter::BindOnIoThread, - base::Unretained(this), - std::move(receiver), &bound_event))) { - return false; - } - bound_event.Wait(); - return true; - } - - // Must be called on the IO thread. Posts back to the owner's task runner to - // destroy it. - void RequestShutdown() { - if (!owner_) - return; - - // Must be reset here on the IO thread before `this` is destroyed. - receiver_.reset(); - - GpuVideoDecodeAccelerator* owner = owner_; - owner_ = nullptr; - - // Invalidate any IO thread WeakPtrs which may be held by the - // VideoDecodeAccelerator, and post to delete our owner which will in turn - // delete us. Note that it is unsafe to access any members of `this` once - // the task below is posted. - owner->weak_factory_for_io_.InvalidateWeakPtrs(); - owner_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::DeleteSelfNow, - base::Unretained(owner))); - } - - // mojom::GpuAcceleratedVideoDecoder: - void Decode(BitstreamBuffer buffer) override; - void AssignPictureBuffers( - std::vector<mojom::PictureBufferAssignmentPtr> assignments) override; - void ReusePictureBuffer(int32_t picture_buffer_id) override; - void Flush(FlushCallback callback) override; - void Reset(ResetCallback callback) override; - void SetOverlayInfo(const OverlayInfo& overlay_info) override; - - private: - void BindOnIoThread(mojo::PendingAssociatedReceiver< - mojom::GpuAcceleratedVideoDecoder> receiver, - base::WaitableEvent* bound_event) { - receiver_.Bind(std::move(receiver)); - receiver_.set_disconnect_handler( - base::BindOnce(&MessageFilter::OnDisconnect, base::Unretained(this))); - bound_event->Signal(); - } - - void OnDisconnect() { - if (!owner_) - return; - - owner_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnDestroy, - base::Unretained(owner_))); - } - - raw_ptr<GpuVideoDecodeAccelerator> owner_; - const scoped_refptr<base::SequencedTaskRunner> owner_task_runner_; - const bool decode_on_io_; - mojo::AssociatedReceiver<mojom::GpuAcceleratedVideoDecoder> receiver_{this}; -}; - -void GpuVideoDecodeAccelerator::MessageFilter::Decode(BitstreamBuffer buffer) { - if (!owner_) - return; - - if (decode_on_io_) { - owner_->OnDecode(std::move(buffer)); - } else { - owner_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnDecode, - base::Unretained(owner_), std::move(buffer))); - } -} - -void GpuVideoDecodeAccelerator::MessageFilter::AssignPictureBuffers( - std::vector<mojom::PictureBufferAssignmentPtr> assignments) { - if (!owner_) - return; - owner_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&GpuVideoDecodeAccelerator::OnAssignPictureBuffers, - base::Unretained(owner_), std::move(assignments))); -} - -void GpuVideoDecodeAccelerator::MessageFilter::ReusePictureBuffer( - int32_t picture_buffer_id) { - if (!owner_) - return; - owner_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(&GpuVideoDecodeAccelerator::OnReusePictureBuffer, - base::Unretained(owner_), picture_buffer_id)); -} - -void GpuVideoDecodeAccelerator::MessageFilter::Flush(FlushCallback callback) { - if (!owner_) - return; - owner_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnFlush, - base::Unretained(owner_), std::move(callback))); -} - -void GpuVideoDecodeAccelerator::MessageFilter::Reset(ResetCallback callback) { - if (!owner_) - return; - owner_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnReset, - base::Unretained(owner_), std::move(callback))); -} - -void GpuVideoDecodeAccelerator::MessageFilter::SetOverlayInfo( - const OverlayInfo& overlay_info) { - if (!owner_) - return; - owner_task_runner_->PostTask( - FROM_HERE, base::BindOnce(&GpuVideoDecodeAccelerator::OnSetOverlayInfo, - base::Unretained(owner_), overlay_info)); -} - -GpuVideoDecodeAccelerator::GpuVideoDecodeAccelerator( - gpu::CommandBufferStub* stub, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, - const AndroidOverlayMojoFactoryCB& overlay_factory_cb) - : stub_(stub), - texture_target_(0), - pixel_format_(PIXEL_FORMAT_UNKNOWN), - textures_per_buffer_(0), - child_task_runner_(base::SingleThreadTaskRunner::GetCurrentDefault()), - io_task_runner_(io_task_runner), - overlay_factory_cb_(overlay_factory_cb) { - DCHECK(stub_); - stub_->AddDestructionObserver(this); - gl_client_.get_context = - base::BindRepeating(&GetGLContext, stub_->AsWeakPtr()); - gl_client_.make_context_current = - base::BindRepeating(&MakeDecoderContextCurrent, stub_->AsWeakPtr()); - // The semantics of |bind_image| vary per-platform: On Windows and Apple it - // must mark the image as needing binding by the decoder, while on other - // platforms it must mark the image as *not* needing binding by the decoder. -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_APPLE) - gl_client_.bind_image = - base::BindRepeating(&BindDecoderManagedImage, stub_->AsWeakPtr()); -#else - gl_client_.bind_image = - base::BindRepeating(&BindClientManagedImage, stub_->AsWeakPtr()); -#endif - gl_client_.get_context_group = - base::BindRepeating(&GetContextGroup, stub_->AsWeakPtr()); - gl_client_.create_abstract_texture = - base::BindRepeating(&CreateAbstractTexture, stub_->AsWeakPtr()); - gl_client_.is_passthrough = - stub_->decoder_context()->GetFeatureInfo()->is_passthrough_cmd_decoder(); - gl_client_.supports_arb_texture_rectangle = stub_->decoder_context() - ->GetFeatureInfo() - ->feature_flags() - .arb_texture_rectangle; -} - -GpuVideoDecodeAccelerator::~GpuVideoDecodeAccelerator() { - // This class can only be self-deleted from OnWillDestroyStub(), which means - // the VDA has already been destroyed in there. - DCHECK(!video_decode_accelerator_); -} - -void GpuVideoDecodeAccelerator::DeleteSelfNow() { - delete this; -} - -// static -gpu::VideoDecodeAcceleratorCapabilities -GpuVideoDecodeAccelerator::GetCapabilities( - const gpu::GpuPreferences& gpu_preferences, - const gpu::GpuDriverBugWorkarounds& workarounds) { - return GpuVideoDecodeAcceleratorFactory::GetDecoderCapabilities( - gpu_preferences, workarounds); -} - -void GpuVideoDecodeAccelerator::NotifyInitializationComplete( - DecoderStatus status) { - decoder_client_->OnInitializationComplete(status.is_ok()); -} - -void GpuVideoDecodeAccelerator::ProvidePictureBuffers( - uint32_t requested_num_of_buffers, - VideoPixelFormat format, - uint32_t textures_per_buffer, - const gfx::Size& dimensions, - uint32_t texture_target) { - if (dimensions.width() > limits::kMaxDimension || - dimensions.height() > limits::kMaxDimension || - dimensions.GetArea() > limits::kMaxCanvas) { - NotifyError(VideoDecodeAccelerator::PLATFORM_FAILURE); - return; - } - - texture_dimensions_ = dimensions; - textures_per_buffer_ = textures_per_buffer; - texture_target_ = texture_target; - pixel_format_ = format; - - decoder_client_->OnProvidePictureBuffers(requested_num_of_buffers, format, - textures_per_buffer, dimensions, - texture_target); -} - -void GpuVideoDecodeAccelerator::DismissPictureBuffer( - int32_t picture_buffer_id) { - // Notify client that picture buffer is now unused. - decoder_client_->OnDismissPictureBuffer(picture_buffer_id); - DebugAutoLock auto_lock(debug_uncleared_textures_lock_); - uncleared_textures_.erase(picture_buffer_id); -} - -void GpuVideoDecodeAccelerator::PictureReady(const Picture& picture) { - // VDA may call PictureReady on IO thread. SetTextureCleared should run on - // the child thread. VDA is responsible to call PictureReady on the child - // thread when a picture buffer is delivered the first time. - if (child_task_runner_->BelongsToCurrentThread()) { - SetTextureCleared(picture); - } else { - DCHECK(io_task_runner_->BelongsToCurrentThread()); - DebugAutoLock auto_lock(debug_uncleared_textures_lock_); - DCHECK_EQ(0u, uncleared_textures_.count(picture.picture_buffer_id())); - } - - auto params = mojom::PictureReadyParams::New(); - params->picture_buffer_id = picture.picture_buffer_id(); - params->bitstream_buffer_id = picture.bitstream_buffer_id(); - params->visible_rect = picture.visible_rect(); - params->color_space = picture.color_space(); - params->allow_overlay = picture.allow_overlay(); - params->read_lock_fences_enabled = picture.read_lock_fences_enabled(); - params->size_changed = picture.size_changed(); - params->surface_texture = picture.texture_owner(); - params->wants_promotion_hint = picture.wants_promotion_hint(); - decoder_client_->OnPictureReady(std::move(params)); -} - -void GpuVideoDecodeAccelerator::NotifyEndOfBitstreamBuffer( - int32_t bitstream_buffer_id) { - decoder_client_->OnBitstreamBufferProcessed(bitstream_buffer_id); -} - -void GpuVideoDecodeAccelerator::NotifyFlushDone() { - DCHECK(!pending_flushes_.empty()); - std::move(pending_flushes_.front()).Run(); - pending_flushes_.pop_front(); -} - -void GpuVideoDecodeAccelerator::NotifyResetDone() { - DCHECK(!pending_resets_.empty()); - std::move(pending_resets_.front()).Run(); - pending_resets_.pop_front(); -} - -void GpuVideoDecodeAccelerator::NotifyError( - VideoDecodeAccelerator::Error error) { - decoder_client_->OnError(error); -} - -void GpuVideoDecodeAccelerator::OnWillDestroyStub(bool have_context) { - // The stub is going away, so we have to stop and destroy VDA here, before - // returning, because the VDA may need the GL context to run and/or do its - // cleanup. We cannot destroy the VDA before the IO thread message filter is - // removed however, since we cannot service incoming messages with VDA gone. - // We cannot simply check for existence of VDA on IO thread though, because - // we don't want to synchronize the IO thread with the ChildThread. - // So we have to wait for the RemoveFilter callback here instead and remove - // the VDA after it arrives and before returning. - stub_->RemoveDestructionObserver(this); - if (filter_) { - io_task_runner_->PostTask(FROM_HERE, - base::BindOnce(&MessageFilter::RequestShutdown, - base::Unretained(filter_.get()))); - } - - video_decode_accelerator_.reset(); -} - -bool GpuVideoDecodeAccelerator::Initialize( - const VideoDecodeAccelerator::Config& config, - mojo::PendingAssociatedReceiver<mojom::GpuAcceleratedVideoDecoder> receiver, - mojo::PendingAssociatedRemote<mojom::GpuAcceleratedVideoDecoderClient> - client) { - DCHECK(!video_decode_accelerator_); - -#if !BUILDFLAG(IS_WIN) - // Ensure we will be able to get a GL context at all before initializing - // non-Windows VDAs. - if (!gl_client_.make_context_current.Run()) - return false; -#endif - - std::unique_ptr<GpuVideoDecodeAcceleratorFactory> vda_factory = - GpuVideoDecodeAcceleratorFactory::Create(gl_client_); - if (!vda_factory) { - LOG(ERROR) << "Failed creating the VDA factory"; - return false; - } - - const gpu::GpuDriverBugWorkarounds& gpu_workarounds = - stub_->channel()->gpu_channel_manager()->gpu_driver_bug_workarounds(); - const gpu::GpuPreferences& gpu_preferences = - stub_->channel()->gpu_channel_manager()->gpu_preferences(); - - if (config.output_mode != - VideoDecodeAccelerator::Config::OutputMode::ALLOCATE) { - DLOG(ERROR) << "Only ALLOCATE mode is supported"; - return false; - } - - video_decode_accelerator_ = - vda_factory->CreateVDA(this, config, gpu_workarounds, gpu_preferences); - if (!video_decode_accelerator_) { - LOG(ERROR) << "HW video decode not available for profile " - << GetProfileName(config.profile) - << (config.is_encrypted() ? " with encryption" : ""); - return false; - } - - decoder_client_.Bind(std::move(client), io_task_runner_); - - // Attempt to set up performing decoding tasks on IO thread, if supported by - // the VDA. - bool decode_on_io = - video_decode_accelerator_->TryToSetupDecodeOnSeparateSequence( - weak_factory_for_io_.GetWeakPtr(), io_task_runner_); - - // Bind the receiver on the IO thread. We wait here for it to be bound - // before returning and signaling that the decoder has been created. - filter_ = - std::make_unique<MessageFilter>(this, stub_->task_runner(), decode_on_io); - return filter_->Bind(std::move(receiver), io_task_runner_); -} - -// Runs on IO thread if VDA::TryToSetupDecodeOnSeparateSequence() succeeded, -// otherwise on the main thread. -void GpuVideoDecodeAccelerator::OnDecode(BitstreamBuffer bitstream_buffer) { - DCHECK(video_decode_accelerator_); - video_decode_accelerator_->Decode(std::move(bitstream_buffer)); -} - -void GpuVideoDecodeAccelerator::OnAssignPictureBuffers( - std::vector<mojom::PictureBufferAssignmentPtr> assignments) { - gpu::DecoderContext* decoder_context = stub_->decoder_context(); - gpu::gles2::TextureManager* texture_manager = - stub_->decoder_context()->GetContextGroup()->texture_manager(); - - std::vector<PictureBuffer> buffers; - std::vector<std::vector<scoped_refptr<gpu::gles2::TextureRef>>> textures; - for (const auto& assignment : assignments) { - if (assignment->buffer_id < 0) { - DLOG(ERROR) << "Buffer id " << assignment->buffer_id << " out of range"; - NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT); - return; - } - std::vector<scoped_refptr<gpu::gles2::TextureRef>> current_textures; - PictureBuffer::TextureIds buffer_texture_ids = assignment->texture_ids; - PictureBuffer::TextureIds service_ids; - if (buffer_texture_ids.size() != textures_per_buffer_) { - DLOG(ERROR) << "Requested " << textures_per_buffer_ - << " textures per picture buffer, got " - << buffer_texture_ids.size(); - NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT); - return; - } - for (size_t j = 0; j < textures_per_buffer_; j++) { - gpu::TextureBase* texture_base = - decoder_context->GetTextureBase(buffer_texture_ids[j]); - if (!texture_base) { - DLOG(ERROR) << "Failed to find texture id " << buffer_texture_ids[j]; - NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT); - return; - } - - if (texture_base->target() != texture_target_) { - DLOG(ERROR) << "Texture target mismatch for texture id " - << buffer_texture_ids[j]; - NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT); - return; - } - - if (texture_manager) { - gpu::gles2::TextureRef* texture_ref = - texture_manager->GetTexture(buffer_texture_ids[j]); - if (texture_ref) { - gpu::gles2::Texture* info = texture_ref->texture(); - if (texture_target_ == GL_TEXTURE_EXTERNAL_OES || - texture_target_ == GL_TEXTURE_RECTANGLE_ARB) { - // These textures have their dimensions defined by the underlying - // storage. - // Use |texture_dimensions_| for this size. - texture_manager->SetLevelInfo( - texture_ref, texture_target_, 0, GL_RGBA, - texture_dimensions_.width(), texture_dimensions_.height(), 1, 0, - GL_RGBA, GL_UNSIGNED_BYTE, gfx::Rect()); - } else { - // For other targets, texture dimensions should already be defined. - GLsizei width = 0, height = 0; - info->GetLevelSize(texture_target_, 0, &width, &height, nullptr); - if (width != texture_dimensions_.width() || - height != texture_dimensions_.height()) { - DLOG(ERROR) << "Size mismatch for texture id " - << buffer_texture_ids[j]; - NotifyError(VideoDecodeAccelerator::INVALID_ARGUMENT); - return; - } - - // TODO(dshwang): after moving to D3D11, remove this. - // https://crbug.com/438691 - GLenum format = - video_decode_accelerator_->GetSurfaceInternalFormat(); - if (format != GL_RGBA) { - DCHECK(format == GL_BGRA_EXT); - texture_manager->SetLevelInfo(texture_ref, texture_target_, 0, - format, width, height, 1, 0, format, - GL_UNSIGNED_BYTE, gfx::Rect()); - } - } - current_textures.push_back(texture_ref); - } - } - service_ids.push_back(texture_base->service_id()); - } - textures.push_back(current_textures); - buffers.emplace_back(assignment->buffer_id, texture_dimensions_, - buffer_texture_ids, service_ids, texture_target_, - pixel_format_); - } - { - DebugAutoLock auto_lock(debug_uncleared_textures_lock_); - for (uint32_t i = 0; i < assignments.size(); ++i) - uncleared_textures_[assignments[i]->buffer_id] = textures[i]; - } - video_decode_accelerator_->AssignPictureBuffers(buffers); -} - -void GpuVideoDecodeAccelerator::OnReusePictureBuffer( - int32_t picture_buffer_id) { - DCHECK(video_decode_accelerator_); - video_decode_accelerator_->ReusePictureBuffer(picture_buffer_id); -} - -void GpuVideoDecodeAccelerator::OnFlush(base::OnceClosure callback) { - DCHECK(video_decode_accelerator_); - pending_flushes_.push_back( - base::BindPostTask(io_task_runner_, std::move(callback))); - video_decode_accelerator_->Flush(); -} - -void GpuVideoDecodeAccelerator::OnReset(base::OnceClosure callback) { - DCHECK(video_decode_accelerator_); - pending_resets_.push_back( - base::BindPostTask(io_task_runner_, std::move(callback))); - video_decode_accelerator_->Reset(); -} - -void GpuVideoDecodeAccelerator::OnSetOverlayInfo( - const OverlayInfo& overlay_info) { - DCHECK(video_decode_accelerator_); - video_decode_accelerator_->SetOverlayInfo(overlay_info); -} - -void GpuVideoDecodeAccelerator::OnDestroy() { - DCHECK(video_decode_accelerator_); - OnWillDestroyStub(false); -} - -void GpuVideoDecodeAccelerator::SetTextureCleared(const Picture& picture) { - DCHECK(child_task_runner_->BelongsToCurrentThread()); - DebugAutoLock auto_lock(debug_uncleared_textures_lock_); - auto it = uncleared_textures_.find(picture.picture_buffer_id()); - if (it == uncleared_textures_.end()) - return; // the texture has been cleared - - for (auto texture_ref : it->second) { - GLenum target = texture_ref->texture()->target(); - gpu::gles2::TextureManager* texture_manager = - stub_->decoder_context()->GetContextGroup()->texture_manager(); - texture_manager->SetLevelCleared(texture_ref.get(), target, 0, true); - } - uncleared_textures_.erase(it); -} - -} // namespace media
diff --git a/media/gpu/ipc/service/gpu_video_decode_accelerator.h b/media/gpu/ipc/service/gpu_video_decode_accelerator.h deleted file mode 100644 index 6e7c0c0c..0000000 --- a/media/gpu/ipc/service/gpu_video_decode_accelerator.h +++ /dev/null
@@ -1,172 +0,0 @@ -// Copyright 2012 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef MEDIA_GPU_IPC_SERVICE_GPU_VIDEO_DECODE_ACCELERATOR_H_ -#define MEDIA_GPU_IPC_SERVICE_GPU_VIDEO_DECODE_ACCELERATOR_H_ - -#include <stdint.h> - -#include <map> -#include <memory> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/containers/circular_deque.h" -#include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" -#include "base/memory/scoped_refptr.h" -#include "base/task/single_thread_task_runner.h" -#include "gpu/command_buffer/service/texture_manager.h" -#include "gpu/config/gpu_info.h" -#include "gpu/ipc/service/command_buffer_stub.h" -#include "media/base/android_overlay_mojo_factory.h" -#include "media/gpu/gpu_video_decode_accelerator_helpers.h" -#include "media/mojo/mojom/gpu_accelerated_video_decoder.mojom.h" -#include "media/video/video_decode_accelerator.h" -#include "mojo/public/cpp/bindings/pending_associated_receiver.h" -#include "mojo/public/cpp/bindings/pending_associated_remote.h" -#include "mojo/public/cpp/bindings/shared_associated_remote.h" -#include "ui/gfx/geometry/size.h" - -namespace gpu { -class GpuDriverBugWorkarounds; -struct GpuPreferences; -} // namespace gpu - -namespace media { - -class GpuVideoDecodeAccelerator - : public VideoDecodeAccelerator::Client, - public gpu::CommandBufferStub::DestructionObserver { - public: - // Each of the arguments to the constructor must outlive this object. - // |stub->decoder()| will be made current around any operation that touches - // the underlying VDA so that it can make GL calls safely. - GpuVideoDecodeAccelerator( - gpu::CommandBufferStub* stub, - const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, - const AndroidOverlayMojoFactoryCB& factory); - - GpuVideoDecodeAccelerator() = delete; - GpuVideoDecodeAccelerator(const GpuVideoDecodeAccelerator&) = delete; - GpuVideoDecodeAccelerator& operator=(const GpuVideoDecodeAccelerator&) = - delete; - - // Static query for the capabilities, which includes the supported profiles. - // This query calls the appropriate platform-specific version. The returned - // capabilities will not contain duplicate supported profile entries. - static gpu::VideoDecodeAcceleratorCapabilities GetCapabilities( - const gpu::GpuPreferences& gpu_preferences, - const gpu::GpuDriverBugWorkarounds& workarounds); - - // VideoDecodeAccelerator::Client implementation. - void NotifyInitializationComplete(DecoderStatus status) override; - void ProvidePictureBuffers(uint32_t requested_num_of_buffers, - VideoPixelFormat format, - uint32_t textures_per_buffer, - const gfx::Size& dimensions, - uint32_t texture_target) override; - void DismissPictureBuffer(int32_t picture_buffer_id) override; - void PictureReady(const Picture& picture) override; - void NotifyEndOfBitstreamBuffer(int32_t bitstream_buffer_id) override; - void NotifyFlushDone() override; - void NotifyResetDone() override; - void NotifyError(VideoDecodeAccelerator::Error error) override; - - // CommandBufferStub::DestructionObserver implementation. - void OnWillDestroyStub(bool have_context) override; - - // Initialize VDAs from the set of VDAs supported for current platform until - // one of them succeeds for given |config|. Send the |init_done_msg| when - // done. filter_ is passed to gpu::CommandBufferStub channel only if the - // chosen VDA can decode on IO thread. - bool Initialize( - const VideoDecodeAccelerator::Config& config, - mojo::PendingAssociatedReceiver<mojom::GpuAcceleratedVideoDecoder> - receiver, - mojo::PendingAssociatedRemote<mojom::GpuAcceleratedVideoDecoderClient> - client); - - private: - class MessageFilter; - - // We only allow self-delete, from DeleteSelfNow(). - ~GpuVideoDecodeAccelerator() override; - - void DeleteSelfNow(); - - // Handlers for IPC messages. - void OnDecode(BitstreamBuffer bitstream_buffer); - void OnAssignPictureBuffers( - std::vector<mojom::PictureBufferAssignmentPtr> assignments); - void OnReusePictureBuffer(int32_t picture_buffer_id); - void OnFlush(base::OnceClosure callback); - void OnReset(base::OnceClosure callback); - void OnSetOverlayInfo(const OverlayInfo& overlay_info); - void OnDestroy(); - - // Sets the texture to cleared. - void SetTextureCleared(const Picture& picture); - - // OpenGL Callback methods. - GpuVideoDecodeGLClient gl_client_; - - // Unowned pointer to the underlying gpu::CommandBufferStub. |this| is - // registered as a DestructionObserver of |stub_| and will self-delete when - // |stub_| is destroyed. - const raw_ptr<gpu::CommandBufferStub> stub_; - - // The underlying VideoDecodeAccelerator. - std::unique_ptr<VideoDecodeAccelerator> video_decode_accelerator_; - - // An interface back to the client of this decoder. - mojo::SharedAssociatedRemote<mojom::GpuAcceleratedVideoDecoderClient> - decoder_client_; - - // Pending replies to Flush and Reset operations. - base::circular_deque<base::OnceClosure> pending_flushes_; - base::circular_deque<base::OnceClosure> pending_resets_; - - // The texture dimensions as requested by ProvidePictureBuffers(). - gfx::Size texture_dimensions_; - - // The texture target as requested by ProvidePictureBuffers(). - uint32_t texture_target_; - - // The format of the picture buffers requested by ProvidePictureBuffers(). - VideoPixelFormat pixel_format_; - - // The number of textures per picture buffer as requested by - // ProvidePictureBuffers(). - uint32_t textures_per_buffer_; - - // The message filter to run VDA::Decode on IO thread if VDA supports it. - std::unique_ptr<MessageFilter> filter_; - - // GPU child thread task runner. - const scoped_refptr<base::SingleThreadTaskRunner> child_task_runner_; - - // GPU IO thread task runner. - const scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_; - - // Optional factory for mojo-based android overlays. - AndroidOverlayMojoFactoryCB overlay_factory_cb_; - - // Weak pointers will be invalidated on IO thread. - base::WeakPtrFactory<Client> weak_factory_for_io_{this}; - - // Protects |uncleared_textures_| when DCHECK is on. This is for debugging - // only. We don't want to hold a lock on IO thread. When DCHECK is off, - // |uncleared_textures_| is only accessed from the child thread. - base::Lock debug_uncleared_textures_lock_; - - // A map from picture buffer ID to set of TextureRefs that have not been - // cleared. - std::map<int32_t, std::vector<scoped_refptr<gpu::gles2::TextureRef>>> - uncleared_textures_; -}; - -} // namespace media - -#endif // MEDIA_GPU_IPC_SERVICE_GPU_VIDEO_DECODE_ACCELERATOR_H_
diff --git a/media/gpu/ipc/service/media_gpu_channel.cc b/media/gpu/ipc/service/media_gpu_channel.cc index 9dc4d70..1140830 100644 --- a/media/gpu/ipc/service/media_gpu_channel.cc +++ b/media/gpu/ipc/service/media_gpu_channel.cc
@@ -15,90 +15,14 @@ #include "gpu/ipc/service/command_buffer_stub.h" #include "gpu/ipc/service/gpu_channel.h" #include "ipc/ipc_mojo_bootstrap.h" -#include "media/gpu/ipc/service/gpu_video_decode_accelerator.h" -#include "media/mojo/mojom/gpu_accelerated_video_decoder.mojom.h" namespace media { -namespace { - -class DecoderProviderImpl : public mojom::GpuAcceleratedVideoDecoderProvider, - public gpu::CommandBufferStub::DestructionObserver { - public: - DecoderProviderImpl(gpu::CommandBufferStub* stub, - const AndroidOverlayMojoFactoryCB& overlay_factory_cb) - : stub_(stub), overlay_factory_cb_(overlay_factory_cb) { - stub_->AddDestructionObserver(this); - } - - DecoderProviderImpl(const DecoderProviderImpl&) = delete; - DecoderProviderImpl& operator=(const DecoderProviderImpl&) = delete; - ~DecoderProviderImpl() override { - if (stub_) { - stub_->RemoveDestructionObserver(this); - } - } - - // mojom::GpuAcceleratedVideoDecoderProvider: - void CreateAcceleratedVideoDecoder( - const VideoDecodeAccelerator::Config& config, - mojo::PendingAssociatedReceiver<mojom::GpuAcceleratedVideoDecoder> - receiver, - mojo::PendingAssociatedRemote<mojom::GpuAcceleratedVideoDecoderClient> - client, - CreateAcceleratedVideoDecoderCallback callback) override { - TRACE_EVENT0("gpu", "DecoderProviderImpl::CreateAcceleratedVideoDecoder"); -#if BUILDFLAG(IS_ANDROID) - NOTIMPLEMENTED() - << "The legacy VideoDecodeAccelerator API is not supported on Android"; - std::move(callback).Run(false); - return; -#else - // Only allow stubs that have a ContextGroup, that is, the GLES2 ones. Later - // code assumes the ContextGroup is valid. - if (!stub_ || !stub_->decoder_context()->GetContextGroup()) { - std::move(callback).Run(false); - return; - } - - // Note that `decoder` is a self-deleting object. - GpuVideoDecodeAccelerator* decoder = new GpuVideoDecodeAccelerator( - stub_, stub_->channel()->io_task_runner(), overlay_factory_cb_); - std::move(callback).Run( - decoder->Initialize(config, std::move(receiver), std::move(client))); -#endif - } - - private: - // gpu::CommandBufferStub::DestructionObserver: - void OnWillDestroyStub(bool have_context) override { stub_ = nullptr; } - - raw_ptr<gpu::CommandBufferStub> stub_; - const AndroidOverlayMojoFactoryCB overlay_factory_cb_; -}; - -} // namespace - MediaGpuChannel::MediaGpuChannel( gpu::GpuChannel* channel, const AndroidOverlayMojoFactoryCB& overlay_factory_cb) - : channel_(channel), overlay_factory_cb_(overlay_factory_cb) { - channel_->set_command_buffer_media_binder( - base::BindRepeating(&MediaGpuChannel::BindCommandBufferMediaReceiver, - base::Unretained(this))); -} + : channel_(channel), overlay_factory_cb_(overlay_factory_cb) {} MediaGpuChannel::~MediaGpuChannel() = default; -void MediaGpuChannel::BindCommandBufferMediaReceiver( - gpu::CommandBufferStub* stub, - mojo::GenericPendingAssociatedReceiver receiver) { - if (auto r = receiver.As<mojom::GpuAcceleratedVideoDecoderProvider>()) { - IPC::ScopedAllowOffSequenceChannelAssociatedBindings allow_binding; - accelerated_video_decoder_providers_.Add( - std::make_unique<DecoderProviderImpl>(stub, overlay_factory_cb_), - std::move(r), stub->task_runner()); - } -} - } // namespace media
diff --git a/media/gpu/ipc/service/media_gpu_channel.h b/media/gpu/ipc/service/media_gpu_channel.h index cd91d97..ffe2339 100644 --- a/media/gpu/ipc/service/media_gpu_channel.h +++ b/media/gpu/ipc/service/media_gpu_channel.h
@@ -8,13 +8,8 @@ #include "base/memory/raw_ptr.h" #include "base/unguessable_token.h" #include "media/base/android_overlay_mojo_factory.h" -#include "media/mojo/mojom/gpu_accelerated_video_decoder.mojom.h" -#include "media/video/video_decode_accelerator.h" -#include "mojo/public/cpp/bindings/generic_pending_associated_receiver.h" -#include "mojo/public/cpp/bindings/unique_associated_receiver_set.h" namespace gpu { -class CommandBufferStub; class GpuChannel; } @@ -29,14 +24,8 @@ ~MediaGpuChannel(); private: - void BindCommandBufferMediaReceiver( - gpu::CommandBufferStub* stub, - mojo::GenericPendingAssociatedReceiver receiver); - const raw_ptr<gpu::GpuChannel> channel_; AndroidOverlayMojoFactoryCB overlay_factory_cb_; - mojo::UniqueAssociatedReceiverSet<mojom::GpuAcceleratedVideoDecoderProvider> - accelerated_video_decoder_providers_; }; } // namespace media
diff --git a/media/gpu/ipc/service/media_gpu_channel_manager.cc b/media/gpu/ipc/service/media_gpu_channel_manager.cc index 4a5d387f..0bbfd98 100644 --- a/media/gpu/ipc/service/media_gpu_channel_manager.cc +++ b/media/gpu/ipc/service/media_gpu_channel_manager.cc
@@ -11,7 +11,6 @@ #include "gpu/ipc/service/gpu_channel_manager.h" #include "ipc/ipc_message_macros.h" #include "ipc/param_traits_macros.h" -#include "media/gpu/ipc/service/gpu_video_decode_accelerator.h" #include "media/gpu/ipc/service/media_gpu_channel.h" namespace media {
diff --git a/media/gpu/mac/video_toolbox_decompression_interface.cc b/media/gpu/mac/video_toolbox_decompression_interface.cc index ac26e49..021b5a1 100644 --- a/media/gpu/mac/video_toolbox_decompression_interface.cc +++ b/media/gpu/mac/video_toolbox_decompression_interface.cc
@@ -188,6 +188,7 @@ return false; } +#if BUILDFLAG(IS_MAC) CFDictionarySetValue( decoder_config, kVTVideoDecoderSpecification_EnableHardwareAcceleratedVideoDecoder, @@ -196,6 +197,7 @@ decoder_config, kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder, kCFBooleanTrue); +#endif VTDecompressionOutputCallbackRecord callback = {OnOutputThunk, this};
diff --git a/media/gpu/mac/video_toolbox_frame_converter.h b/media/gpu/mac/video_toolbox_frame_converter.h index 3dc958d..b07bf92 100644 --- a/media/gpu/mac/video_toolbox_frame_converter.h +++ b/media/gpu/mac/video_toolbox_frame_converter.h
@@ -9,6 +9,7 @@ #include "base/functional/callback.h" #include "base/mac/scoped_cftyperef.h" +#include "base/memory/raw_ptr.h" #include "base/memory/ref_counted_delete_on_sequence.h" #include "base/memory/scoped_refptr.h" #include "base/task/sequenced_task_runner.h" @@ -67,9 +68,9 @@ GetCommandBufferStubCB get_stub_cb_; bool initialized_ = false; - gpu::CommandBufferStub* stub_ = nullptr; + raw_ptr<gpu::CommandBufferStub> stub_ = nullptr; gpu::SequenceId wait_sequence_id_; - gpu::SharedImageStub* sis_ = nullptr; + raw_ptr<gpu::SharedImageStub> sis_ = nullptr; bool texture_rectangle_ = false; };
diff --git a/media/gpu/windows/d3d11_texture_selector.cc b/media/gpu/windows/d3d11_texture_selector.cc index 6fab0bee..f56fd75 100644 --- a/media/gpu/windows/d3d11_texture_selector.cc +++ b/media/gpu/windows/d3d11_texture_selector.cc
@@ -194,10 +194,11 @@ std::unique_ptr<Texture2DWrapper> TextureSelector::CreateTextureWrapper( ComD3D11Device device, + gfx::ColorSpace color_space, gfx::Size size) { // TODO(liberato): If the output format is rgb, then create a pbuffer wrapper. - return std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat(), - device); + return std::make_unique<DefaultTexture2DWrapper>(size, color_space, + OutputDXGIFormat(), device); } bool TextureSelector::DoesDecoderOutputUseSharedHandle() const { @@ -230,6 +231,7 @@ std::unique_ptr<Texture2DWrapper> CopyTextureSelector::CreateTextureWrapper( ComD3D11Device device, + gfx::ColorSpace color_space, gfx::Size size) { D3D11_TEXTURE2D_DESC texture_desc = {}; texture_desc.MipLevels = 1; @@ -257,8 +259,9 @@ return std::make_unique<CopyingTexture2DWrapper>( size, - std::make_unique<DefaultTexture2DWrapper>(size, OutputDXGIFormat(), - device), + std::make_unique<DefaultTexture2DWrapper>( + size, output_color_space_.value_or(color_space), OutputDXGIFormat(), + device), video_processor_proxy_, out_texture, output_color_space_); }
diff --git a/media/gpu/windows/d3d11_texture_selector.h b/media/gpu/windows/d3d11_texture_selector.h index 18d1a7fd..1624e889 100644 --- a/media/gpu/windows/d3d11_texture_selector.h +++ b/media/gpu/windows/d3d11_texture_selector.h
@@ -51,6 +51,7 @@ virtual std::unique_ptr<Texture2DWrapper> CreateTextureWrapper( ComD3D11Device device, + gfx::ColorSpace color_space, gfx::Size size); virtual bool DoesDecoderOutputUseSharedHandle() const; @@ -96,6 +97,7 @@ std::unique_ptr<Texture2DWrapper> CreateTextureWrapper( ComD3D11Device device, + gfx::ColorSpace color_space, gfx::Size size) override; bool DoesDecoderOutputUseSharedHandle() const override;
diff --git a/media/gpu/windows/d3d11_texture_wrapper.cc b/media/gpu/windows/d3d11_texture_wrapper.cc index 2d0790b..7816d63c 100644 --- a/media/gpu/windows/d3d11_texture_wrapper.cc +++ b/media/gpu/windows/d3d11_texture_wrapper.cc
@@ -93,10 +93,13 @@ Texture2DWrapper::~Texture2DWrapper() = default; -DefaultTexture2DWrapper::DefaultTexture2DWrapper(const gfx::Size& size, - DXGI_FORMAT dxgi_format, - ComD3D11Device device) +DefaultTexture2DWrapper::DefaultTexture2DWrapper( + const gfx::Size& size, + const gfx::ColorSpace& color_space, + DXGI_FORMAT dxgi_format, + ComD3D11Device device) : size_(size), + color_space_(color_space), dxgi_format_(dxgi_format), video_device_(std::move(device)) {} @@ -139,6 +142,10 @@ // We're just binding, so the output and output color spaces are the same. *output_color_space = input_color_space; + // TODO(hitawala): Possibly optimize this method as input and stored color + // spaces should be same. + CHECK_EQ(input_color_space, color_space_); + return D3D11Status::Codes::kOk; } @@ -179,9 +186,9 @@ weak_factory_.GetWeakPtr())); gpu_resources_ = base::SequenceBound<GpuResources>( std::move(gpu_task_runner), std::move(on_error_cb), - std::move(get_helper_cb), std::move(mailboxes), size_, dxgi_format_, - video_device_, texture, array_slice, std::move(picture_buffer), - std::move(gpu_resource_init_cb)); + std::move(get_helper_cb), std::move(mailboxes), size_, color_space_, + dxgi_format_, video_device_, texture, array_slice, + std::move(picture_buffer), std::move(gpu_resource_init_cb)); return D3D11Status::Codes::kOk; } @@ -210,6 +217,7 @@ GetCommandBufferHelperCB get_helper_cb, const std::vector<gpu::Mailbox>& mailboxes, const gfx::Size& size, + const gfx::ColorSpace& color_space, DXGI_FORMAT dxgi_format, ComD3D11Device video_device, ComD3D11Texture2D texture, @@ -273,10 +281,9 @@ std::unique_ptr<gpu::SharedImageBacking> backing = gpu::D3DImageBacking::Create( mailboxes[0], DXGIFormatToMultiPlanarSharedImageFormat(dxgi_format), - size, gfx::ColorSpace(), kTopLeft_GrSurfaceOrigin, - kPremul_SkAlphaType, usage, texture, - std::move(dxgi_shared_handle_state), GL_TEXTURE_EXTERNAL_OES, - array_slice); + size, color_space, kTopLeft_GrSurfaceOrigin, kPremul_SkAlphaType, + usage, texture, std::move(dxgi_shared_handle_state), + GL_TEXTURE_EXTERNAL_OES, array_slice); if (backing) { // Need to clear the backing since the D3D11 Video Decoder will initialize // the textures.
diff --git a/media/gpu/windows/d3d11_texture_wrapper.h b/media/gpu/windows/d3d11_texture_wrapper.h index 00e46097a..c2c560b 100644 --- a/media/gpu/windows/d3d11_texture_wrapper.h +++ b/media/gpu/windows/d3d11_texture_wrapper.h
@@ -99,6 +99,7 @@ // While the specific texture instance can change on every call to // ProcessTexture, the dxgi format must be the same for all of them. DefaultTexture2DWrapper(const gfx::Size& size, + const gfx::ColorSpace& color_space, DXGI_FORMAT dxgi_format, ComD3D11Device device); ~DefaultTexture2DWrapper() override; @@ -137,6 +138,7 @@ GetCommandBufferHelperCB get_helper_cb, const std::vector<gpu::Mailbox>& mailboxes, const gfx::Size& size, + const gfx::ColorSpace& color_space, DXGI_FORMAT dxgi_format, ComD3D11Device video_device, ComD3D11Texture2D texture, @@ -161,6 +163,7 @@ absl::optional<D3D11Status> received_error_; gfx::Size size_; + gfx::ColorSpace color_space_; base::SequenceBound<GpuResources> gpu_resources_; MailboxHolderArray mailbox_holders_; DXGI_FORMAT dxgi_format_;
diff --git a/media/gpu/windows/d3d11_texture_wrapper_unittest.cc b/media/gpu/windows/d3d11_texture_wrapper_unittest.cc index 1c1009f..ad5a8fa 100644 --- a/media/gpu/windows/d3d11_texture_wrapper_unittest.cc +++ b/media/gpu/windows/d3d11_texture_wrapper_unittest.cc
@@ -68,6 +68,8 @@ // Made-up size for the images. const gfx::Size size_{100, 200}; + // Made-up color space for the images. + const gfx::ColorSpace color_space_ = gfx::ColorSpace::CreateSRGB(); // CommandBufferHelper, and a callback that returns it. Useful to initialize // a wrapper. @@ -80,7 +82,8 @@ TEST_F(D3D11TextureWrapperUnittest, NV12InitSucceeds) { const DXGI_FORMAT dxgi_format = DXGI_FORMAT_NV12; - auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format, + auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, color_space_, + dxgi_format, /*device=*/nullptr); const D3D11Status init_result = wrapper->Init(task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, @@ -94,7 +97,8 @@ TEST_F(D3D11TextureWrapperUnittest, BGRA8InitSucceeds) { const DXGI_FORMAT dxgi_format = DXGI_FORMAT_B8G8R8A8_UNORM; - auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format, + auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, color_space_, + dxgi_format, /*device=*/nullptr); const D3D11Status init_result = wrapper->Init(task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, @@ -106,7 +110,8 @@ TEST_F(D3D11TextureWrapperUnittest, FP16InitSucceeds) { const DXGI_FORMAT dxgi_format = DXGI_FORMAT_R16G16B16A16_FLOAT; - auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format, + auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, color_space_, + dxgi_format, /*device=*/nullptr); const D3D11Status init_result = wrapper->Init(task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, @@ -118,7 +123,8 @@ TEST_F(D3D11TextureWrapperUnittest, P010InitSucceeds) { const DXGI_FORMAT dxgi_format = DXGI_FORMAT_P010; - auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format, + auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, color_space_, + dxgi_format, /*device=*/nullptr); const D3D11Status init_result = wrapper->Init(task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr, @@ -130,7 +136,8 @@ TEST_F(D3D11TextureWrapperUnittest, UnknownInitFails) { const DXGI_FORMAT dxgi_format = DXGI_FORMAT_UNKNOWN; - auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, dxgi_format, + auto wrapper = std::make_unique<DefaultTexture2DWrapper>(size_, color_space_, + dxgi_format, /*device=*/nullptr); const D3D11Status init_result = wrapper->Init(task_runner_, get_helper_cb_, /*texture_d3d=*/nullptr,
diff --git a/media/gpu/windows/d3d11_video_decoder.cc b/media/gpu/windows/d3d11_video_decoder.cc index bcc8d39..0fe1104 100644 --- a/media/gpu/windows/d3d11_video_decoder.cc +++ b/media/gpu/windows/d3d11_video_decoder.cc
@@ -681,6 +681,14 @@ set_accelerator_decoder_wrapper_cb_.Run( CreateD3D11VideoDecoderWrapper(video_decoder)); picture_buffers_.clear(); + } else if (result == media::AcceleratedVideoDecoder::kColorSpaceChange) { + MEDIA_LOG(INFO, media_log_) + << "D3D11VideoDecoder color space change: color_space: " + << accelerated_video_decoder_->GetVideoColorSpace().ToString(); + + // Clear the picture buffers and recreate the pictures leading to new + // shared images with new color space. + picture_buffers_.clear(); } else if (result == media::AcceleratedVideoDecoder::kTryAgain) { LOG(ERROR) << "Try again is not supported"; NotifyError(D3D11Status::Codes::kTryAgainNotSupported); @@ -755,6 +763,8 @@ DCHECK(decoder_configurator_); DCHECK(texture_selector_); gfx::Size size = accelerated_video_decoder_->GetPicSize(); + gfx::ColorSpace color_space = + accelerated_video_decoder_->GetVideoColorSpace().ToGfxColorSpace(); // Some streams may have varying metadata, so bitstream metadata should be // preferred over metadata provide by the configuration. @@ -810,7 +820,8 @@ DCHECK(!!in_texture); - auto tex_wrapper = texture_selector_->CreateTextureWrapper(device_, size); + auto tex_wrapper = + texture_selector_->CreateTextureWrapper(device_, color_space, size); if (!tex_wrapper) { return NotifyError( D3D11Status::Codes::kAllocateTextureForCopyingWrapperFailed);
diff --git a/media/mojo/mojom/BUILD.gn b/media/mojo/mojom/BUILD.gn index b86763f0..1f8e20e 100644 --- a/media/mojo/mojom/BUILD.gn +++ b/media/mojo/mojom/BUILD.gn
@@ -29,7 +29,6 @@ "demuxer_stream.mojom", "display_media_information.mojom", "frame_interface_factory.mojom", - "gpu_accelerated_video_decoder.mojom", "interface_factory.mojom", "key_system_support.mojom", "media_log.mojom", @@ -240,32 +239,6 @@ { types = [ { - mojom = "media.mojom.BitstreamBuffer" - cpp = "::media::BitstreamBuffer" - move_only = true - }, - { - mojom = "media.mojom.VideoDecodeAcceleratorConfig" - cpp = "::media::VideoDecodeAccelerator::Config" - }, - ] - traits_headers = [ - "video_decode_accelerator_config_mojom_traits.h", - "//media/base/ipc/media_param_traits_macros.h", - "//media/gpu/ipc/common/media_param_traits.h", - ] - traits_sources = [ "video_decode_accelerator_config_mojom_traits.cc" ] - traits_public_deps = [ - "//base", - "//media", - "//media/base/ipc", - "//media/gpu/ipc/common", - "//ui/gfx/geometry/mojom:mojom_traits", - ] - }, - { - types = [ - { mojom = "media.mojom.CdmKeyInformation" cpp = "::std::unique_ptr<::media::CdmKeyInformation>" move_only = true @@ -855,7 +828,6 @@ "audio_decoder_config_mojom_traits_unittest.cc", "audio_processing_mojom_traits_unittest.cc", "cdm_key_information_mojom_traits_unittest.cc", - "video_decode_accelerator_config_mojom_traits_unittest.cc", "video_decoder_config_mojom_traits_unittest.cc", "video_encode_accelerator_mojom_traits_unittest.cc", "video_frame_metadata_mojom_traits_unittest.cc",
diff --git a/media/mojo/mojom/gpu_accelerated_video_decoder.mojom b/media/mojo/mojom/gpu_accelerated_video_decoder.mojom deleted file mode 100644 index c976252..0000000 --- a/media/mojo/mojom/gpu_accelerated_video_decoder.mojom +++ /dev/null
@@ -1,116 +0,0 @@ -// 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. - -module media.mojom; - -import "media/mojo/mojom/media_types.mojom"; -import "media/mojo/mojom/video_decoder.mojom"; -import "mojo/public/mojom/base/unguessable_token.mojom"; -import "ui/gfx/geometry/mojom/geometry.mojom"; -import "ui/gfx/mojom/color_space.mojom"; -import "ui/gfx/mojom/hdr_metadata.mojom"; - -// Mojo version of VideoDecodeAccelerator::Config -struct VideoDecodeAcceleratorConfig { - VideoCodecProfile profile; - EncryptionScheme encryption_scheme; - mojo_base.mojom.UnguessableToken? cdm_id; - bool is_deferred_initialization_allowed; - OverlayInfo overlay_info; - gfx.mojom.Size initial_expected_coded_size; - // TODO(https://crbug.com/1446302): OutputMode was not included in the IPC - // version of this serialization. Leave it out for now (to avoid any behavior - // changes, but consider reintroducing it). - array<VideoPixelFormat> supported_output_formats; - array<uint8> sps; - array<uint8> pps; - VideoColorSpace container_color_space; - gfx.mojom.ColorSpace target_color_space; - gfx.mojom.HDRMetadata? hdr_metadata; -}; - -// Used by media clients to acquire new VideoDecoder instances from the GPU -// process. -interface GpuAcceleratedVideoDecoderProvider { - // Creates and initializes a new hardware video decoder instance. - [Sync] - CreateAcceleratedVideoDecoder( - VideoDecodeAcceleratorConfig config, - pending_associated_receiver<GpuAcceleratedVideoDecoder> receiver, - pending_associated_remote<GpuAcceleratedVideoDecoderClient> client) - => (bool success); -}; - -[Native] -struct BitstreamBuffer; - -// Links a set of texture IDs to a given PictureBuffer ID. -struct PictureBufferAssignment { - int32 buffer_id; - array<uint32> texture_ids; -}; - -// Interface to control a single hardware video decoder instance. This is -// implemented in the GPU process and called by renderer clients. -interface GpuAcceleratedVideoDecoder { - // Sends an input buffer for decoding. - Decode(BitstreamBuffer buffer); - - // Give texture IDs for the textures to use for output. - AssignPictureBuffers(array<PictureBufferAssignment> assignments); - - // Indicates that the given picture buffer can be recycled for subsequent - // decode operations. - ReusePictureBuffer(int32 picture_buffer_id); - - // Flushes the decoder. - Flush() => (); - - // Resets the decoder. - Reset() => (); - - // Sends overlay info to the decoder. - SetOverlayInfo(OverlayInfo overlay_info); -}; - -// Client interface corresponding with a single AcceleratedVideoDecoder -// instance. This is implemented by renderer clients and called from by the GPU -// process. -interface GpuAcceleratedVideoDecoderClient { - // Notifies the client that deferred initialization has completed. - OnInitializationComplete(bool success); - - // Notifies the client that an input buffer has been consumed. - OnBitstreamBufferProcessed(int32 buffer_id); - - // Allocates video frames for decoder output. - OnProvidePictureBuffers( - uint32 num_frames, VideoPixelFormat format, uint32 num_textures_per_frame, - gfx.mojom.Size buffer_size, uint32 texture_target); - - // Notifies the client that a picture is ready. - OnPictureReady(PictureReadyParams params); - - // Notifies the client that a picture is ready and the buffer does not need to - // be passed back to the decoder. - OnDismissPictureBuffer(int32 buffer_id); - - // Notifies the client of an error encountered by the decoder. - OnError(uint32 error_id); -}; - -// Parameters passed to AcceleratedVideoDecoderClient.OnPictureReady from the -// GPU process to the client renderer. -struct PictureReadyParams { - int32 picture_buffer_id; - int32 bitstream_buffer_id; - gfx.mojom.Rect visible_rect; - gfx.mojom.ColorSpace color_space; - bool allow_overlay; - bool read_lock_fences_enabled; - bool size_changed; - bool surface_texture; - bool wants_promotion_hint; -}; -
diff --git a/media/mojo/mojom/video_decode_accelerator_config_mojom_traits.cc b/media/mojo/mojom/video_decode_accelerator_config_mojom_traits.cc deleted file mode 100644 index 04643d6..0000000 --- a/media/mojo/mojom/video_decode_accelerator_config_mojom_traits.cc +++ /dev/null
@@ -1,53 +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 "media/mojo/mojom/video_decode_accelerator_config_mojom_traits.h" - -namespace mojo { - -// static -bool StructTraits<media::mojom::VideoDecodeAcceleratorConfigDataView, - media::VideoDecodeAccelerator::Config>:: - Read(media::mojom::VideoDecodeAcceleratorConfigDataView input, - media::VideoDecodeAccelerator::Config* output) { - if (!input.ReadProfile(&output->profile)) { - return false; - } - if (!input.ReadEncryptionScheme(&output->encryption_scheme)) { - return false; - } - if (!input.ReadCdmId(&output->cdm_id)) { - return false; - } - output->is_deferred_initialization_allowed = - input.is_deferred_initialization_allowed(); - if (!input.ReadOverlayInfo(&output->overlay_info)) { - return false; - } - if (!input.ReadInitialExpectedCodedSize( - &output->initial_expected_coded_size)) { - return false; - } - if (!input.ReadSupportedOutputFormats(&output->supported_output_formats)) { - return false; - } - if (!input.ReadSps(&output->sps)) { - return false; - } - if (!input.ReadPps(&output->pps)) { - return false; - } - if (!input.ReadContainerColorSpace(&output->container_color_space)) { - return false; - } - if (!input.ReadTargetColorSpace(&output->target_color_space)) { - return false; - } - if (!input.ReadHdrMetadata(&output->hdr_metadata)) { - return false; - } - return true; -} - -} // namespace mojo
diff --git a/media/mojo/mojom/video_decode_accelerator_config_mojom_traits.h b/media/mojo/mojom/video_decode_accelerator_config_mojom_traits.h deleted file mode 100644 index 63ce33f..0000000 --- a/media/mojo/mojom/video_decode_accelerator_config_mojom_traits.h +++ /dev/null
@@ -1,84 +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 MEDIA_MOJO_MOJOM_VIDEO_DECODE_ACCELERATOR_CONFIG_MOJOM_TRAITS_H_ -#define MEDIA_MOJO_MOJOM_VIDEO_DECODE_ACCELERATOR_CONFIG_MOJOM_TRAITS_H_ - -#include "media/base/video_decoder_config.h" -#include "media/mojo/mojom/gpu_accelerated_video_decoder.mojom.h" -#include "media/mojo/mojom/media_types.mojom.h" -#include "media/video/video_decode_accelerator.h" - -namespace mojo { - -template <> -struct StructTraits<media::mojom::VideoDecodeAcceleratorConfigDataView, - media::VideoDecodeAccelerator::Config> { - static media::VideoCodecProfile profile( - const media::VideoDecodeAccelerator::Config& input) { - return input.profile; - } - - static media::EncryptionScheme encryption_scheme( - const media::VideoDecodeAccelerator::Config& input) { - return input.encryption_scheme; - } - - static absl::optional<base::UnguessableToken> cdm_id( - const media::VideoDecodeAccelerator::Config& input) { - return input.cdm_id; - } - - static bool is_deferred_initialization_allowed( - const media::VideoDecodeAccelerator::Config& input) { - return input.is_deferred_initialization_allowed; - } - - static media::OverlayInfo overlay_info( - const media::VideoDecodeAccelerator::Config& input) { - return input.overlay_info; - } - - static gfx::Size initial_expected_coded_size( - const media::VideoDecodeAccelerator::Config& input) { - return input.initial_expected_coded_size; - } - - static std::vector<media::VideoPixelFormat> supported_output_formats( - const media::VideoDecodeAccelerator::Config& input) { - return input.supported_output_formats; - } - - static std::vector<uint8_t> sps( - const media::VideoDecodeAccelerator::Config& input) { - return input.sps; - } - - static std::vector<uint8_t> pps( - const media::VideoDecodeAccelerator::Config& input) { - return input.pps; - } - - static media::VideoColorSpace container_color_space( - const media::VideoDecodeAccelerator::Config& input) { - return input.container_color_space; - } - - static gfx::ColorSpace target_color_space( - const media::VideoDecodeAccelerator::Config& input) { - return input.target_color_space; - } - - static absl::optional<gfx::HDRMetadata> hdr_metadata( - const media::VideoDecodeAccelerator::Config& input) { - return input.hdr_metadata; - } - - static bool Read(media::mojom::VideoDecodeAcceleratorConfigDataView input, - media::VideoDecodeAccelerator::Config* output); -}; - -} // namespace mojo - -#endif // MEDIA_MOJO_MOJOM_VIDEO_DECODE_ACCELERATOR_CONFIG_MOJOM_TRAITS_H_
diff --git a/media/mojo/mojom/video_decode_accelerator_config_mojom_traits_unittest.cc b/media/mojo/mojom/video_decode_accelerator_config_mojom_traits_unittest.cc deleted file mode 100644 index 1ee4dda..0000000 --- a/media/mojo/mojom/video_decode_accelerator_config_mojom_traits_unittest.cc +++ /dev/null
@@ -1,58 +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 "media/mojo/mojom/video_decode_accelerator_config_mojom_traits.h" - -#include "mojo/public/cpp/test_support/test_utils.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace media { - -namespace { - -TEST(VideoDecodeAcceleratorConfig, RoundTrip) { - VideoDecodeAccelerator::Config input; - - input.profile = VP9PROFILE_PROFILE0; - input.encryption_scheme = EncryptionScheme::kCbcs; - input.cdm_id = base::UnguessableToken::Create(); - input.is_deferred_initialization_allowed = true; - input.overlay_info.is_fullscreen = true; - input.initial_expected_coded_size = gfx::Size(123, 456); - input.output_mode = VideoDecodeAccelerator::Config::OutputMode::IMPORT; - input.supported_output_formats.emplace_back(PIXEL_FORMAT_I420A); - input.sps.emplace_back(0xA); - input.pps.emplace_back(0xB); - input.container_color_space = VideoColorSpace::JPEG(); - input.target_color_space = gfx::ColorSpace::CreateDisplayP3D65(); - input.hdr_metadata.emplace(gfx::HdrMetadataCta861_3(123, 456)); - - VideoDecodeAccelerator::Config output; - ASSERT_TRUE( - mojo::test::SerializeAndDeserialize<mojom::VideoDecodeAcceleratorConfig>( - input, output)); - - EXPECT_EQ(input.profile, output.profile); - EXPECT_EQ(input.encryption_scheme, output.encryption_scheme); - EXPECT_EQ(input.cdm_id, output.cdm_id); - EXPECT_EQ(input.is_deferred_initialization_allowed, - output.is_deferred_initialization_allowed); - EXPECT_EQ(input.overlay_info.is_fullscreen, - output.overlay_info.is_fullscreen); - EXPECT_EQ(input.supported_output_formats, output.supported_output_formats); - EXPECT_EQ(input.sps, output.sps); - EXPECT_EQ(input.pps, output.pps); - EXPECT_EQ(input.container_color_space, output.container_color_space); - EXPECT_EQ(input.target_color_space, output.target_color_space); - EXPECT_EQ(input.hdr_metadata, output.hdr_metadata); - - // TODO(https://crbug.com/1446302): OutputMode was not included in the IPC - // version of this serialization. Leave it out for now (to avoid any behavior - // changes, but consider reintroducing it). - EXPECT_NE(input.output_mode, output.output_mode); -} - -} // namespace - -} // namespace media
diff --git a/media/mojo/services/webrtc_video_perf_mojolpm_fuzzer.cc b/media/mojo/services/webrtc_video_perf_mojolpm_fuzzer.cc index 22b893a..0ed01e5 100644 --- a/media/mojo/services/webrtc_video_perf_mojolpm_fuzzer.cc +++ b/media/mojo/services/webrtc_video_perf_mojolpm_fuzzer.cc
@@ -139,7 +139,7 @@ } void NextAction() { - const auto& action = testcase_.actions(action_index_); + const auto& action = testcase_->actions(action_index_); switch (action.action_case()) { case fuzzing::webrtc_video_perf::proto::Action::kUpdateRecord: { const auto& update_record = action.update_record(); @@ -167,10 +167,10 @@ ++action_index_; } - bool IsFinished() { return action_index_ >= testcase_.actions_size(); } + bool IsFinished() { return action_index_ >= testcase_->actions_size(); } private: - const fuzzing::webrtc_video_perf::proto::Testcase& testcase_; + const raw_ref<const fuzzing::webrtc_video_perf::proto::Testcase> testcase_; int action_index_ = 0; // Database storage.
diff --git a/media/muxers/BUILD.gn b/media/muxers/BUILD.gn index e7c97479..2bf68fcc 100644 --- a/media/muxers/BUILD.gn +++ b/media/muxers/BUILD.gn
@@ -19,6 +19,8 @@ "live_webm_muxer_delegate.h", "mp4_box_writer.cc", "mp4_box_writer.h", + "mp4_fragment_box_writer.cc", + "mp4_fragment_box_writer.h", "mp4_movie_box_writer.cc", "mp4_movie_box_writer.h", "mp4_muxer_context.cc",
diff --git a/media/muxers/box_byte_stream.cc b/media/muxers/box_byte_stream.cc index 39df738..b4bae1c 100644 --- a/media/muxers/box_byte_stream.cc +++ b/media/muxers/box_byte_stream.cc
@@ -22,7 +22,7 @@ BoxByteStream::~BoxByteStream() { DCHECK(!writer_); - DCHECK(size_offsets_.empty()); + DCHECK(!has_open_boxes()); } void BoxByteStream::StartBox(mp4::FourCC fourcc) { @@ -37,8 +37,8 @@ uint32_t flags, uint8_t version) { StartBox(fourcc); - WriteU8(version); - WriteU24(flags); + uint32_t value = version << 24 | (flags & 0xffffff); + WriteU32(value); } void BoxByteStream::WriteU8(uint8_t value) { @@ -56,16 +56,6 @@ position_ += 2; } -void BoxByteStream::WriteU24(uint32_t value) { - CHECK(!buffer_.empty()); - CHECK_LE(value, 0xffffffu); - - while (!writer_->WriteBytes(&value, 3)) { - GrowWriter(); - } - position_ += 3; -} - void BoxByteStream::WriteU32(uint32_t value) { CHECK(!buffer_.empty()); while (!writer_->WriteU32(value)) { @@ -106,13 +96,10 @@ std::vector<uint8_t> BoxByteStream::Flush() { CHECK(!buffer_.empty()); + DCHECK(!has_open_boxes()); buffer_.resize(position_); - for (size_t size_offset : size_offsets_) { - WriteSize(position_ - size_offset, &buffer_[size_offset]); - } - writer_.reset(); size_offsets_.clear(); return std::move(buffer_); @@ -128,6 +115,20 @@ WriteSize(position_ - size_offset, &buffer_[size_offset]); } +void BoxByteStream::WriteOffsetPlaceholder() { + data_offsets_by_track_.push(position_); + WriteU32(0); +} + +void BoxByteStream::FlushCurrentOffset() { + CHECK(!data_offsets_by_track_.empty()); + + size_t offset_in_trun = data_offsets_by_track_.front(); + data_offsets_by_track_.pop(); + + WriteSize(position_, &buffer_[offset_in_trun]); +} + void BoxByteStream::GrowWriter() { CHECK(!buffer_.empty()); buffer_.resize(buffer_.size() * 1.5);
diff --git a/media/muxers/box_byte_stream.h b/media/muxers/box_byte_stream.h index da13c8f3..b9b4090 100644 --- a/media/muxers/box_byte_stream.h +++ b/media/muxers/box_byte_stream.h
@@ -5,6 +5,7 @@ #ifndef MEDIA_MUXERS_BOX_BYTE_STREAM_H_ #define MEDIA_MUXERS_BOX_BYTE_STREAM_H_ +#include <queue> #include <vector> #include "base/big_endian.h" @@ -40,7 +41,6 @@ // type. void WriteU8(uint8_t value); void WriteU16(uint16_t value); - void WriteU24(uint32_t value); void WriteU32(uint32_t value); void WriteU64(uint64_t value); void WriteBytes(const void* buf, size_t len); @@ -54,6 +54,19 @@ // is a summation of the box itself with its children. void EndBox(); + // Write placeholder for the track data offset of the `trun` box. The data + // is stored in the `mdat` box so its value will be written during `mdat' + // box `Write` time. + void WriteOffsetPlaceholder(); + + // Populate the placeholder, which was set by `WriteOffsetPlaceholder` + // with the current offset. The current offset is a data offset only + // when the `BoxByteStream` is created with `moof` box. + void FlushCurrentOffset(); + + // Validates whether there is a open box or not. + bool has_open_boxes() const { return !size_offsets_.empty(); } + // TODO(crbug.com/1072056): Investigate if this is a reasonable starting size. static constexpr int kDefaultBufferLimit = 4096; @@ -65,6 +78,8 @@ void GrowWriter(); std::vector<size_t> size_offsets_; + std::queue<size_t> data_offsets_by_track_; + size_t position_ = 0; std::vector<uint8_t> buffer_; absl::optional<base::BigEndianWriter> writer_;
diff --git a/media/muxers/box_byte_stream_unittest.cc b/media/muxers/box_byte_stream_unittest.cc index eb6d2e2..df7d5c3 100644 --- a/media/muxers/box_byte_stream_unittest.cc +++ b/media/muxers/box_byte_stream_unittest.cc
@@ -16,11 +16,11 @@ kPlaceHolder = 0, kType_8 = 1, kType_16 = 2, - kType_24 = 3, - kType_32 = 4, - kType_64 = 5, - kType_Bytes = 6, - kType_String = 7, + kType_32 = 3, + kType_64 = 4, + kType_Bytes = 5, + kType_String = 6, + kEndBox = 7, }; struct DataOrder { @@ -34,16 +34,17 @@ DataOrder test_data[] = { {DataType::kType_8, 0x48}, - {DataType::kPlaceHolder, /*total_size=*/57}, + {DataType::kPlaceHolder, /*total_size=*/44}, {DataType::kType_16, 0x1617}, - {DataType::kType_24, 0x242526}, {DataType::kType_32, 0x32333435}, {DataType::kType_64, 0x64646667686970}, {DataType::kType_Bytes, 0x12345678901234}, - {DataType::kPlaceHolder, /*total_size=*/25}, + {DataType::kPlaceHolder, /*total_size=*/9}, {DataType::kType_8, 0x28}, + {DataType::kEndBox, 0x0}, {DataType::kType_16, 0x0}, {DataType::kType_32, 0x0}, + {DataType::kEndBox, 0x0}, {DataType::kType_String, reinterpret_cast<uint64_t>("")}, {DataType::kType_String, reinterpret_cast<uint64_t>("abcdabcd")}}; for (auto& data : test_data) { @@ -51,15 +52,15 @@ case DataType::kPlaceHolder: box_byte_stream.StartBox(mp4::FOURCC_MOOV); break; + case DataType::kEndBox: + box_byte_stream.EndBox(); + break; case DataType::kType_8: box_byte_stream.WriteU8(static_cast<uint8_t>(data.value)); break; case DataType::kType_16: box_byte_stream.WriteU16(static_cast<uint16_t>(data.value)); break; - case DataType::kType_24: - box_byte_stream.WriteU24(static_cast<uint32_t>(data.value)); - break; case DataType::kType_32: box_byte_stream.WriteU32(static_cast<uint32_t>(data.value)); break; @@ -86,6 +87,8 @@ EXPECT_TRUE(reader.ReadU32(reinterpret_cast<uint32_t*>(&ret_value))); EXPECT_EQ(mp4::FOURCC_MOOV, ret_value); break; + case DataType::kEndBox: + break; case DataType::kType_8: EXPECT_TRUE(reader.ReadU8(reinterpret_cast<uint8_t*>(&ret_value))); EXPECT_EQ(data.value, ret_value); @@ -94,10 +97,6 @@ EXPECT_TRUE(reader.ReadU16(reinterpret_cast<uint16_t*>(&ret_value))); EXPECT_EQ(data.value, ret_value); break; - case DataType::kType_24: - EXPECT_TRUE(reader.ReadBytes(&ret_value, 3)); - EXPECT_EQ(data.value, ret_value); - break; case DataType::kType_32: EXPECT_TRUE(reader.ReadU32(reinterpret_cast<uint32_t*>(&ret_value))); EXPECT_EQ(data.value, ret_value); @@ -235,66 +234,60 @@ reader.ReadU32(&fourcc); EXPECT_EQ(mp4::FOURCC_MVEX, fourcc); } +} - // Flush use. +TEST(BoxByteStreamTest, OffsetPlaceholderAndFlush) { + // Test Flush and EndBox difference. + // EndBox use. + BoxByteStream box_byte_stream; { - BoxByteStream box_byte_stream; + // `moof` + box_byte_stream.StartBox(mp4::FOURCC_MOOF); - // <parent> - box_byte_stream.StartBox(mp4::FOURCC_MOOV); - box_byte_stream.WriteU64(0); - { - // <child 1> - box_byte_stream.StartBox(mp4::FOURCC_TRAK); - EXPECT_EQ(box_byte_stream.GetSizeOffsetsForTesting().size(), 2u); + // `traf` + box_byte_stream.StartBox(mp4::FOURCC_TRAF); - box_byte_stream.WriteU32(0x1617); - { - // <grand child 1> - box_byte_stream.StartBox(mp4::FOURCC_MDIA); - EXPECT_EQ(box_byte_stream.GetSizeOffsetsForTesting().size(), 3u); - box_byte_stream.WriteU16(0); - } - - // <child 2> - box_byte_stream.StartBox(mp4::FOURCC_MVEX); - EXPECT_EQ(box_byte_stream.GetSizeOffsetsForTesting().size(), 4u); - box_byte_stream.WriteU32(0); - } - - // Read. - EXPECT_EQ(box_byte_stream.GetSizeOffsetsForTesting().size(), 4u); - std::vector<uint8_t> written_data = box_byte_stream.Flush(); - base::BigEndianReader reader(written_data.data(), written_data.size()); - - uint32_t parent; - uint32_t fourcc; - reader.ReadU32(&parent); - EXPECT_EQ(50u, parent); - reader.ReadU32(&fourcc); - EXPECT_EQ(mp4::FOURCC_MOOV, fourcc); - reader.Skip(8); - - uint32_t child_1; - reader.ReadU32(&child_1); - EXPECT_EQ(34u, child_1); - reader.ReadU32(&fourcc); - EXPECT_EQ(mp4::FOURCC_TRAK, fourcc); - reader.Skip(4); - - uint32_t grand_child_1; - reader.ReadU32(&grand_child_1); - EXPECT_EQ(22u, grand_child_1); - reader.ReadU32(&fourcc); - EXPECT_EQ(mp4::FOURCC_MDIA, fourcc); - reader.Skip(2); - - uint32_t child_2; - reader.ReadU32(&child_2); - EXPECT_EQ(12u, child_2); - reader.ReadU32(&fourcc); - EXPECT_EQ(mp4::FOURCC_MVEX, fourcc); + // 'trun' + box_byte_stream.StartBox(mp4::FOURCC_TRUN); + box_byte_stream.WriteOffsetPlaceholder(); + box_byte_stream.WriteU32(0); + box_byte_stream.WriteOffsetPlaceholder(); + box_byte_stream.EndBox(); // for FOURCC_TRUN. + box_byte_stream.EndBox(); // for FOURCC_TRAF. + box_byte_stream.EndBox(); // for FOURCC_MOOF. } + + std::vector<uint8_t> data(4000, 0); + { + // `moof` + box_byte_stream.StartBox(mp4::FOURCC_MDAT); + box_byte_stream.FlushCurrentOffset(); + + box_byte_stream.WriteBytes(data.data(), data.size()); + box_byte_stream.EndBox(); // for FOURCC_MDAT. + box_byte_stream.FlushCurrentOffset(); + } + + std::vector<uint8_t> written_data = box_byte_stream.Flush(); + base::BigEndianReader reader(written_data.data(), written_data.size()); + uint32_t fourcc; + reader.Skip(4); + reader.ReadU32(&fourcc); + EXPECT_EQ(mp4::FOURCC_MOOF, fourcc); + reader.Skip(4); + reader.ReadU32(&fourcc); + EXPECT_EQ(mp4::FOURCC_TRAF, fourcc); + reader.Skip(4); + reader.ReadU32(&fourcc); + EXPECT_EQ(mp4::FOURCC_TRUN, fourcc); + + // placeholder. + uint32_t data_offset; + reader.ReadU32(&data_offset); + EXPECT_EQ(44u, data_offset); + reader.Skip(4); + reader.ReadU32(&data_offset); + EXPECT_EQ(44u + data.size(), data_offset); } } // namespace media
diff --git a/media/muxers/mp4_box_writer.cc b/media/muxers/mp4_box_writer.cc index 1a6f9e6f..42a7d506 100644 --- a/media/muxers/mp4_box_writer.cc +++ b/media/muxers/mp4_box_writer.cc
@@ -17,9 +17,16 @@ Mp4BoxWriter::~Mp4BoxWriter() = default; void Mp4BoxWriter::WriteAndFlush() { + // It will write itself as well as children boxes. BoxByteStream writer; - // It will write itself as well as children boxes. + WriteAndFlush(writer); +} + +void Mp4BoxWriter::WriteAndFlush(BoxByteStream& writer) { + DCHECK(!writer.has_open_boxes()); + + // It will write to input writer as well as children boxes. Write(writer); // Update the total size on respective boxes.
diff --git a/media/muxers/mp4_box_writer.h b/media/muxers/mp4_box_writer.h index b2194ab..d00a67ce 100644 --- a/media/muxers/mp4_box_writer.h +++ b/media/muxers/mp4_box_writer.h
@@ -8,6 +8,7 @@ #include <memory> #include <vector> +#include "base/memory/raw_ptr_exclusion.h" #include "base/memory/raw_ref.h" #include "base/sequence_checker.h" #include "media/base/media_export.h" @@ -19,6 +20,35 @@ class BoxByteStream; class Mp4MuxerContext; +#define DECLARE_MP4_BOX_WRITER_CLASS_NO_DATA(class_name) \ + class MEDIA_EXPORT class_name : public Mp4BoxWriter { \ + public: \ + explicit class_name(const Mp4MuxerContext& context); \ + ~class_name() override; \ + class_name(const class_name&) = delete; \ + class_name& operator=(const class_name&) = delete; \ + void Write(BoxByteStream& writer) override; \ + \ + private: \ + SEQUENCE_CHECKER(sequence_checker_); \ + } + +// |box_| field is not a raw_ref<> because it was filtered by the rewriter +// for: #macro +#define DECLARE_MP4_BOX_WRITER_CLASS(class_name, box_type) \ + class MEDIA_EXPORT class_name : public Mp4BoxWriter { \ + public: \ + class_name(const Mp4MuxerContext& context, const box_type& box); \ + ~class_name() override; \ + class_name(const class_name&) = delete; \ + class_name& operator=(const class_name&) = delete; \ + void Write(BoxByteStream& writer) override; \ + \ + private: \ + RAW_PTR_EXCLUSION const box_type& box_; \ + SEQUENCE_CHECKER(sequence_checker_); \ + } + // The Mp4BoxWriter is parent class for all box writers. // Every box writers must derive from Mp4BoxWriter. // The Mp4BoxWriter has container for the children boxes and the derived box @@ -38,6 +68,11 @@ // It is expected that it will create box itself as well as its children. void WriteAndFlush(); + // Same as `WriteAndFlush()` but accept `BoxByteStream` as a parameter. + // It is expected that it write on input `BoxByteStream` object. + // `writer` must not have any opened box. + void WriteAndFlush(BoxByteStream& writer); + protected: // Write for children boxes. The function will calls Write // function of all children boxes.
diff --git a/media/muxers/mp4_fragment_box_writer.cc b/media/muxers/mp4_fragment_box_writer.cc new file mode 100644 index 0000000..23ea9df --- /dev/null +++ b/media/muxers/mp4_fragment_box_writer.cc
@@ -0,0 +1,277 @@ +// 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 "media/muxers/mp4_fragment_box_writer.h" + +#include <memory> +#include <type_traits> +#include <vector> + +#include "media/formats/mp4/fourccs.h" +#include "media/muxers/box_byte_stream.h" +#include "media/muxers/mp4_muxer_context.h" +#include "media/muxers/mp4_type_conversion.h" +#include "media/muxers/output_position_tracker.h" + +namespace media { + +namespace { + +void ValidateSampleFlags(uint32_t flags) { + uint32_t allowed_sample_flags = + static_cast<uint32_t>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagIsNonSync) | + static_cast<uint32_t>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagDependsYes) | + static_cast<uint32_t>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagDependsNo); + CHECK_EQ(flags & ~(allowed_sample_flags), 0u); +} + +} // namespace + +// Mp4MovieFragmentBoxWriter (`moof`) class. +Mp4MovieFragmentBoxWriter::Mp4MovieFragmentBoxWriter( + const Mp4MuxerContext& context, + const mp4::writable_boxes::MovieFragment& box) + : Mp4BoxWriter(context), box_(box) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + AddChildBox( + std::make_unique<Mp4MovieFragmentHeaderBoxWriter>(context, box_.header)); + for (const auto& fragment : box_.track_fragments) { + AddChildBox(std::make_unique<Mp4TrackFragmentBoxWriter>(context, fragment)); + } +} + +Mp4MovieFragmentBoxWriter::~Mp4MovieFragmentBoxWriter() = default; + +void Mp4MovieFragmentBoxWriter::Write(BoxByteStream& writer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + writer.StartBox(mp4::FOURCC_MOOF); + + WriteChildren(writer); + + writer.EndBox(); +} + +// Mp4MovieFragmentHeaderBoxWriter (`mfhd`) class. +Mp4MovieFragmentHeaderBoxWriter::Mp4MovieFragmentHeaderBoxWriter( + const Mp4MuxerContext& context, + const mp4::writable_boxes::MovieFragmentHeader& box) + : Mp4BoxWriter(context), box_(box) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +Mp4MovieFragmentHeaderBoxWriter::~Mp4MovieFragmentHeaderBoxWriter() = default; + +void Mp4MovieFragmentHeaderBoxWriter::Write(BoxByteStream& writer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + writer.StartFullBox(mp4::FOURCC_MFHD, /*flags=*/0, /*version=*/0); + + writer.WriteU32(box_.sequence_number); + + writer.EndBox(); +} + +// Mp4TrackFragmentBoxWriter (`traf`) class. +Mp4TrackFragmentBoxWriter::Mp4TrackFragmentBoxWriter( + const Mp4MuxerContext& context, + const mp4::writable_boxes::TrackFragment& box) + : Mp4BoxWriter(context), box_(box) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + AddChildBox( + std::make_unique<Mp4TrackFragmentHeaderBoxWriter>(context, box_.header)); + AddChildBox(std::make_unique<Mp4TrackFragmentDecodeTimeBoxWriter>( + context, box_.decode_time)); + AddChildBox( + std::make_unique<Mp4TrackFragmentRunBoxWriter>(context, box_.run)); +} + +Mp4TrackFragmentBoxWriter::~Mp4TrackFragmentBoxWriter() = default; + +void Mp4TrackFragmentBoxWriter::Write(BoxByteStream& writer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + writer.StartBox(mp4::FOURCC_TRAF); + + WriteChildren(writer); + + writer.EndBox(); +} + +// Mp4TrackFragmentHeaderBoxWriter (`tfhd`) class. +Mp4TrackFragmentHeaderBoxWriter::Mp4TrackFragmentHeaderBoxWriter( + const Mp4MuxerContext& context, + const mp4::writable_boxes::TrackFragmentHeader& box) + : Mp4BoxWriter(context), box_(box) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +Mp4TrackFragmentHeaderBoxWriter::~Mp4TrackFragmentHeaderBoxWriter() = default; + +void Mp4TrackFragmentHeaderBoxWriter::Write(BoxByteStream& writer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + writer.StartFullBox(mp4::FOURCC_TFHD, box_.flags, /*version=*/0); + + writer.WriteU32(box_.track_id); + + CHECK(box_.flags & + static_cast<uint32_t>( + mp4::writable_boxes::TrackFragmentHeaderFlags::kDefaultBaseIsMoof)); + + if (box_.flags & + static_cast<uint32_t>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kSampleDescriptionIndexPresent)) { + NOTREACHED(); + } + + if (box_.flags & + static_cast<uint32_t>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kDefaultSampleDurationPresent)) { + writer.WriteU32(box_.default_sample_duration.InSeconds()); + } + + if (box_.flags & + static_cast<uint32_t>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kDefaultSampleSizePresent)) { + writer.WriteU32(box_.default_sample_size); + } + + if (box_.flags & + static_cast<uint32_t>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kkDefaultSampleFlagsPresent)) { + ValidateSampleFlags(box_.default_sample_flags); + writer.WriteU32(box_.default_sample_flags); + } + + writer.EndBox(); +} + +// Mp4TrackFragmentDecodeTimeBoxWriter (`tfdt`) class. +Mp4TrackFragmentDecodeTimeBoxWriter::Mp4TrackFragmentDecodeTimeBoxWriter( + const Mp4MuxerContext& context, + const mp4::writable_boxes::TrackFragmentDecodeTime& box) + : Mp4BoxWriter(context), box_(box) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +Mp4TrackFragmentDecodeTimeBoxWriter::~Mp4TrackFragmentDecodeTimeBoxWriter() = + default; + +void Mp4TrackFragmentDecodeTimeBoxWriter::Write(BoxByteStream& writer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + writer.StartBox(mp4::FOURCC_TFDT); + + writer.WriteU64(box_.base_media_decode_time.InSeconds()); + + writer.EndBox(); +} + +// Mp4TrackFragmentRunBoxWriter (`trun`) class. +Mp4TrackFragmentRunBoxWriter::Mp4TrackFragmentRunBoxWriter( + const Mp4MuxerContext& context, + const mp4::writable_boxes::TrackFragmentRun& box) + : Mp4BoxWriter(context), box_(box) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +Mp4TrackFragmentRunBoxWriter::~Mp4TrackFragmentRunBoxWriter() = default; + +void Mp4TrackFragmentRunBoxWriter::Write(BoxByteStream& writer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + writer.StartFullBox(mp4::FOURCC_TRUN, box_.flags, /*version=*/0); + + writer.WriteU32(box_.sample_count); + + { + // `data_offset`. + + // `movie-fragment relative addressing` should exist must by + // `https://www.w3.org/TR/mse-byte-stream-format-isobmff/`. + CHECK(box_.flags & + static_cast<uint16_t>( + mp4::writable_boxes::TrackFragmentRunFlags::kDataOffsetPresent)); + writer.WriteOffsetPlaceholder(); + } + + if (box_.flags & + static_cast<uint16_t>(mp4::writable_boxes::TrackFragmentRunFlags:: + kFirstSampleFlagsPresent)) { + ValidateSampleFlags(box_.first_sample_flags); + writer.WriteU32(box_.first_sample_flags); + } + + bool duration_exists = + (box_.flags & + static_cast<uint16_t>( + mp4::writable_boxes::TrackFragmentRunFlags::kSampleDurationPresent)); + bool size_exists = + (box_.flags & + static_cast<uint16_t>( + mp4::writable_boxes::TrackFragmentRunFlags::kSampleSizePresent)); + bool flags_exists = + (box_.flags & + static_cast<uint16_t>( + mp4::writable_boxes::TrackFragmentRunFlags::kSampleFlagsPresent)); + + if (duration_exists) { + CHECK_EQ(box_.sample_count, box_.sample_durations.size()); + } + + if (size_exists) { + CHECK_EQ(box_.sample_count, box_.sample_sizes.size()); + } + + if (flags_exists) { + CHECK_EQ(box_.sample_count, box_.sample_flags.size()); + } + + for (uint32_t i = 0; i < box_.sample_count; ++i) { + if (duration_exists) { + writer.WriteU32(box_.sample_durations[i].InSeconds()); + } + + if (size_exists) { + writer.WriteU32(box_.sample_sizes[i]); + } + + if (flags_exists) { + writer.WriteU32(box_.sample_flags[i]); + } + } + + writer.EndBox(); +} + +// Mp4MediaDataBoxWriter (`mdat`) class. +Mp4MediaDataBoxWriter::Mp4MediaDataBoxWriter( + const Mp4MuxerContext& context, + const mp4::writable_boxes::MediaData& box) + : Mp4BoxWriter(context), box_(box) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); +} + +Mp4MediaDataBoxWriter::~Mp4MediaDataBoxWriter() = default; + +void Mp4MediaDataBoxWriter::Write(BoxByteStream& writer) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + + writer.StartBox(mp4::FOURCC_MDAT); + + for (const auto& data : box_.data) { + writer.FlushCurrentOffset(); + writer.WriteBytes(data.data(), data.size()); + } + + writer.EndBox(); +} + +} // namespace media
diff --git a/media/muxers/mp4_fragment_box_writer.h b/media/muxers/mp4_fragment_box_writer.h new file mode 100644 index 0000000..404b14f --- /dev/null +++ b/media/muxers/mp4_fragment_box_writer.h
@@ -0,0 +1,30 @@ +// 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 MEDIA_MUXERS_MP4_FRAGMENT_BOX_WRITER_H_ +#define MEDIA_MUXERS_MP4_FRAGMENT_BOX_WRITER_H_ + +#include "media/formats/mp4/writable_box_definitions.h" +#include "media/muxers/mp4_box_writer.h" + +// The file contains the box writer of `moof` and `mdat` and its children. +namespace media { + +DECLARE_MP4_BOX_WRITER_CLASS(Mp4MovieFragmentBoxWriter, + mp4::writable_boxes::MovieFragment); +DECLARE_MP4_BOX_WRITER_CLASS(Mp4MovieFragmentHeaderBoxWriter, + mp4::writable_boxes::MovieFragmentHeader); +DECLARE_MP4_BOX_WRITER_CLASS(Mp4TrackFragmentBoxWriter, + mp4::writable_boxes::TrackFragment); +DECLARE_MP4_BOX_WRITER_CLASS(Mp4TrackFragmentHeaderBoxWriter, + mp4::writable_boxes::TrackFragmentHeader); +DECLARE_MP4_BOX_WRITER_CLASS(Mp4TrackFragmentDecodeTimeBoxWriter, + mp4::writable_boxes::TrackFragmentDecodeTime); +DECLARE_MP4_BOX_WRITER_CLASS(Mp4TrackFragmentRunBoxWriter, + mp4::writable_boxes::TrackFragmentRun); +DECLARE_MP4_BOX_WRITER_CLASS(Mp4MediaDataBoxWriter, + mp4::writable_boxes::MediaData); +} // namespace media + +#endif // MEDIA_MUXERS_MP4_FRAGMENT_BOX_WRITER_H_
diff --git a/media/muxers/mp4_movie_box_writer.cc b/media/muxers/mp4_movie_box_writer.cc index ef68bb9..2ff548a 100644 --- a/media/muxers/mp4_movie_box_writer.cc +++ b/media/muxers/mp4_movie_box_writer.cc
@@ -173,7 +173,7 @@ void Mp4MovieTrackExtendsBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_TREX); + writer.StartFullBox(mp4::FOURCC_TREX, /*flags=*/0, /*version=*/0); writer.WriteU32(box_.track_id); writer.WriteU32(box_.default_sample_description_index); @@ -221,7 +221,7 @@ void Mp4MovieTrackHeaderBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_TKHD, box_.flags, /*version*/ 1); + writer.StartFullBox(mp4::FOURCC_TKHD, box_.flags); WriteIsoTime(writer, box_.creation_time); WriteIsoTime(writer, box_.modification_time); @@ -318,7 +318,7 @@ void Mp4MovieMediaHandlerBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_HDLR); + writer.StartFullBox(mp4::FOURCC_HDLR, /*flags=*/0, /*version=*/0); writer.WriteU32(0); // predefined = 0; writer.WriteU32(box_.handler_type); @@ -379,7 +379,7 @@ void Mp4MovieVideoHeaderBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_VMHD); + writer.StartFullBox(mp4::FOURCC_VMHD, /*flags=*/1, /*version=*/0); writer.WriteU16(0); // graphics_mode. writer.WriteU16(0); // op_color[0]. @@ -401,7 +401,7 @@ void Mp4MovieSoundHeaderBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_SMHD); + writer.StartFullBox(mp4::FOURCC_SMHD, /*flags=*/0, /*version=*/0); writer.WriteU16(0); // balance. writer.WriteU16(0); // reserved. @@ -447,7 +447,7 @@ void Mp4MovieDataReferenceBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_DREF); + writer.StartFullBox(mp4::FOURCC_DREF, /*flags=*/0, /*version=*/0); writer.WriteU32(box_.entries.size()); @@ -468,7 +468,7 @@ void Mp4MovieDataUrlEntryBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_URL); + writer.StartFullBox(mp4::FOURCC_URL, /*flags=*/0, /*version=*/0); // We use empty Url location to prevent accidental PII leak. writer.WriteString(""); @@ -514,7 +514,7 @@ void Mp4MovieSampleToChunkBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_STSC); + writer.StartFullBox(mp4::FOURCC_STSC, /*flags=*/0, /*version=*/0); writer.WriteU32(0); // entry_count. @@ -534,7 +534,7 @@ void Mp4MovieDecodingTimeToSampleBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_STTS); + writer.StartFullBox(mp4::FOURCC_STTS, /*flags=*/0, /*version=*/0); writer.WriteU32(0); // entry_count. @@ -574,7 +574,7 @@ void Mp4MovieSampleChunkOffsetBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_STCO); + writer.StartFullBox(mp4::FOURCC_STCO, /*flags=*/0, /*version=*/0); writer.WriteU32(0); // entry_count. @@ -605,7 +605,7 @@ void Mp4MovieSampleDescriptionBoxWriter::Write(BoxByteStream& writer) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - writer.StartFullBox(mp4::FOURCC_STSD); + writer.StartFullBox(mp4::FOURCC_STSD, /*flags=*/0, /*version=*/0); writer.WriteU32(box_.entry_count);
diff --git a/media/muxers/mp4_movie_box_writer.h b/media/muxers/mp4_movie_box_writer.h index 99c522d6..1afab18a 100644 --- a/media/muxers/mp4_movie_box_writer.h +++ b/media/muxers/mp4_movie_box_writer.h
@@ -5,48 +5,12 @@ #ifndef MEDIA_MUXERS_MP4_MOVIE_BOX_WRITER_H_ #define MEDIA_MUXERS_MP4_MOVIE_BOX_WRITER_H_ -#include "base/memory/raw_ptr_exclusion.h" -#include "base/sequence_checker.h" -#include "media/base/media_export.h" -#include "media/formats/mp4/fourccs.h" #include "media/formats/mp4/writable_box_definitions.h" #include "media/muxers/mp4_box_writer.h" -#include "third_party/abseil-cpp/absl/types/optional.h" // The file contains the box writer of `moov` and its children. namespace media { -class Mp4MuxerContext; - -#define DECLARE_MP4_BOX_WRITER_CLASS_NO_DATA(class_name) \ - class MEDIA_EXPORT class_name : public Mp4BoxWriter { \ - public: \ - explicit class_name(const Mp4MuxerContext& context); \ - ~class_name() override; \ - class_name(const class_name&) = delete; \ - class_name& operator=(const class_name&) = delete; \ - void Write(BoxByteStream& writer) override; \ - \ - private: \ - SEQUENCE_CHECKER(sequence_checker_); \ - } - -// |box_| field is not a raw_ref<> because it was filtered by the rewriter -// for: #macro -#define DECLARE_MP4_BOX_WRITER_CLASS(class_name, box_type) \ - class MEDIA_EXPORT class_name : public Mp4BoxWriter { \ - public: \ - class_name(const Mp4MuxerContext& context, const box_type& box); \ - ~class_name() override; \ - class_name(const class_name&) = delete; \ - class_name& operator=(const class_name&) = delete; \ - void Write(BoxByteStream& writer) override; \ - \ - private: \ - RAW_PTR_EXCLUSION const box_type& box_; \ - SEQUENCE_CHECKER(sequence_checker_); \ - } - DECLARE_MP4_BOX_WRITER_CLASS(Mp4MovieBoxWriter, mp4::writable_boxes::Movie); DECLARE_MP4_BOX_WRITER_CLASS(Mp4MovieHeaderBoxWriter, mp4::writable_boxes::MovieHeader);
diff --git a/media/muxers/mp4_muxer_box_writer_unittest.cc b/media/muxers/mp4_muxer_box_writer_unittest.cc index 402f3775..4845529d 100644 --- a/media/muxers/mp4_muxer_box_writer_unittest.cc +++ b/media/muxers/mp4_muxer_box_writer_unittest.cc
@@ -20,7 +20,9 @@ #include "media/formats/mp4/es_descriptor.h" #include "media/formats/mp4/writable_box_definitions.h" #include "media/formats/mpeg/adts_stream_parser.h" +#include "media/muxers/box_byte_stream.h" #include "media/muxers/mp4_box_writer.h" +#include "media/muxers/mp4_fragment_box_writer.h" #include "media/muxers/mp4_movie_box_writer.h" #include "media/muxers/mp4_muxer_context.h" #include "media/muxers/mp4_type_conversion.h" @@ -109,6 +111,15 @@ run_loop_.Run(); } + void FlushWithBoxWriterAndWait(Mp4BoxWriter* box_writer, + BoxByteStream& box_byte_stream) { + // Flush at requested. + box_writer->WriteAndFlush(box_byte_stream); + + // Wait for finishing flush of all boxes. + run_loop_.Run(); + } + private: base::test::TaskEnvironment task_environment; mp4::writable_boxes::Movie mp4_moov_box_; @@ -708,4 +719,250 @@ } #endif +TEST_F(Mp4MuxerBoxWriterTest, Mp4Fragments) { + // Tests `mvex/trex` box writer. + std::vector<uint8_t> written_data; + CreateContext(written_data); + + constexpr uint32_t kSampleDurations[] = {960, 960, 960}; + constexpr uint32_t kSampleSizes[] = {6400, 333, 333}; + constexpr uint32_t kSampleCount = 3u; + constexpr uint32_t kVideoBaseDecodeTime = 123u; + constexpr uint32_t kAudioBaseDecodeTime = 345u; + constexpr uint32_t kVideoDataSize = 4000u; + constexpr uint32_t kAudioDataSize = 2000u; + constexpr uint32_t kBoxHeaderSize = 8u; + + using H = + std::underlying_type_t<mp4::writable_boxes::TrackFragmentHeaderFlags>; + using R = std::underlying_type_t<mp4::writable_boxes::TrackFragmentRunFlags>; + using S = std::underlying_type_t<mp4::writable_boxes::FragmentSampleFlags>; + + mp4::writable_boxes::MovieFragment moof; + + moof.header.sequence_number = 2u; + + { // `video`. + mp4::writable_boxes::TrackFragment video_fragment; + video_fragment.header.track_id = 1u; + video_fragment.header.flags = + (static_cast<H>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kDefaultBaseIsMoof) | + static_cast<H>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kDefaultSampleDurationPresent) | + static_cast<H>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kkDefaultSampleFlagsPresent)); + + video_fragment.header.default_sample_duration = base::Seconds(kDuration1); + video_fragment.header.default_sample_flags = static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagDependsNo); + + video_fragment.decode_time.base_media_decode_time = + base::Seconds(kVideoBaseDecodeTime); + + { // `video, trun` + mp4::writable_boxes::TrackFragmentRun video_trun; + video_trun.flags = + (static_cast<R>( + mp4::writable_boxes::TrackFragmentRunFlags::kDataOffsetPresent) | + static_cast<R>(mp4::writable_boxes::TrackFragmentRunFlags:: + kFirstSampleFlagsPresent) | + static_cast<R>(mp4::writable_boxes::TrackFragmentRunFlags:: + kSampleDurationPresent)); + + video_trun.sample_count = kSampleCount; + video_trun.first_sample_flags = + (static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagIsNonSync) | + static_cast<S>(mp4::writable_boxes::FragmentSampleFlags:: + kSampleFlagDependsYes)); + + std::vector<base::TimeDelta> durations; + for (auto* iter = std::begin(kSampleDurations); + iter != std::end(kSampleDurations); ++iter) { + durations.push_back(base::Seconds(*iter)); + } + video_trun.sample_durations = std::move(durations); + video_fragment.run = std::move(video_trun); + } + moof.track_fragments.push_back(std::move(video_fragment)); + } + + { // `audio`. + mp4::writable_boxes::TrackFragment audio_fragment; + audio_fragment.header.track_id = 2u; + audio_fragment.header.flags = + (static_cast<H>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kDefaultBaseIsMoof) | + static_cast<H>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kDefaultSampleSizePresent) | + static_cast<H>(mp4::writable_boxes::TrackFragmentHeaderFlags:: + kkDefaultSampleFlagsPresent)); + + audio_fragment.header.default_sample_size = kDefaultSampleSize; + audio_fragment.header.default_sample_flags = + (static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagIsNonSync) | + static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagDependsYes)); + + audio_fragment.decode_time.base_media_decode_time = + base::Seconds(kAudioBaseDecodeTime); + + { // `audio, trun. + mp4::writable_boxes::TrackFragmentRun audio_trun; + audio_trun.flags = + (static_cast<R>( + mp4::writable_boxes::TrackFragmentRunFlags::kDataOffsetPresent) | + static_cast<R>(mp4::writable_boxes::TrackFragmentRunFlags:: + kSampleDurationPresent) | + static_cast<R>( + mp4::writable_boxes::TrackFragmentRunFlags::kSampleSizePresent)); + + audio_trun.sample_count = kSampleCount; + audio_trun.first_sample_flags = + (static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagIsNonSync) | + static_cast<S>(mp4::writable_boxes::FragmentSampleFlags:: + kSampleFlagDependsYes)); + + std::vector<base::TimeDelta> durations; + for (auto* iter = std::begin(kSampleDurations); + iter != std::end(kSampleDurations); ++iter) { + durations.push_back(base::Seconds(*iter)); + } + audio_trun.sample_durations = std::move(durations); + + std::vector<uint32_t> sizes(std::begin(kSampleSizes), + std::end(kSampleSizes)); + audio_trun.sample_sizes = std::move(sizes); + audio_fragment.run = std::move(audio_trun); + } + moof.track_fragments.push_back(std::move(audio_fragment)); + } + + // Write `mdat` data. + mp4::writable_boxes::MediaData media_data; + std::vector<uint8_t> video_data(kVideoDataSize, 0); + std::vector<uint8_t> audio_data(kAudioDataSize, 1); + + base::span<uint8_t> video_span(video_data); + base::span<uint8_t> audio_span(audio_data); + + media_data.data.push_back(std::move(video_span)); + media_data.data.push_back(std::move(audio_span)); + + // Write `moof` boxes. + Mp4MovieFragmentBoxWriter box_writer(*context(), moof); + BoxByteStream box_byte_stream; + box_writer.Write(box_byte_stream); + + // Write `mdat` box with `moof` boxes writer object. + Mp4MediaDataBoxWriter box_mdat_writer(*context(), media_data); + FlushWithBoxWriterAndWait(&box_mdat_writer, box_byte_stream); + + // Validation of the written boxes. + + // `written_data` test. + std::unique_ptr<mp4::BoxReader> reader; + mp4::ParseResult result = mp4::BoxReader::ReadTopLevelBox( + written_data.data(), written_data.size(), nullptr, &reader); + + EXPECT_EQ(result, mp4::ParseResult::kOk); + EXPECT_TRUE(reader); + + // `moof` test. + EXPECT_EQ(mp4::FOURCC_MOOF, reader->type()); + EXPECT_TRUE(reader->ScanChildren()); + + // `mfhd` test. + mp4::MovieFragmentHeader mfhd_box; + EXPECT_TRUE(reader->ReadChild(&mfhd_box)); + + EXPECT_EQ(2u, mfhd_box.sequence_number); + + // `traf` test. + std::vector<mp4::TrackFragment> traf_boxes; + EXPECT_TRUE(reader->ReadChildren(&traf_boxes)); + ASSERT_EQ(traf_boxes.size(), 2u); + + // `tfhd` test of video. + EXPECT_EQ(1u, traf_boxes[0].header.track_id); + EXPECT_EQ(kDuration1, traf_boxes[0].header.default_sample_duration); + EXPECT_EQ(0u, traf_boxes[0].header.default_sample_size); + EXPECT_EQ(true, traf_boxes[0].header.has_default_sample_flags); + EXPECT_EQ(static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagDependsNo), + traf_boxes[0].header.default_sample_flags); + + // `tfdt` test of video. + EXPECT_EQ(kVideoBaseDecodeTime, traf_boxes[0].decode_time.decode_time); + + // `trun` test of video. + uint32_t mdat_video_data_offset; + + ASSERT_EQ(1u, traf_boxes[0].runs.size()); + EXPECT_EQ(kSampleCount, traf_boxes[0].runs[0].sample_count); + EXPECT_EQ(208u, traf_boxes[0].runs[0].data_offset); + mdat_video_data_offset = traf_boxes[0].runs[0].data_offset; + + ASSERT_EQ(kSampleCount, traf_boxes[0].runs[0].sample_durations.size()); + EXPECT_EQ(std::vector<uint32_t>(std::begin(kSampleDurations), + std::end(kSampleDurations)), + traf_boxes[0].runs[0].sample_durations); + ASSERT_EQ(0u, traf_boxes[0].runs[0].sample_sizes.size()); + // kFirstSampleFlagsPresent enabled and no sample_flags entry, + // then sample_flags will have a value of the first sample flags. + ASSERT_EQ(1u, traf_boxes[0].runs[0].sample_flags.size()); + ASSERT_EQ(0u, traf_boxes[0].runs[0].sample_composition_time_offsets.size()); + + // `tfhd` test of audio. + EXPECT_EQ(2u, traf_boxes[1].header.track_id); + EXPECT_EQ(0u, traf_boxes[1].header.default_sample_duration); + EXPECT_EQ(kDefaultSampleSize, traf_boxes[1].header.default_sample_size); + EXPECT_EQ(true, traf_boxes[1].header.has_default_sample_flags); + EXPECT_EQ( + (static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagIsNonSync) | + static_cast<S>( + mp4::writable_boxes::FragmentSampleFlags::kSampleFlagDependsYes)), + traf_boxes[1].header.default_sample_flags); + + // `tfdt` test of audio. + EXPECT_EQ(kAudioBaseDecodeTime, traf_boxes[1].decode_time.decode_time); + + // `trun` test of audio. + ASSERT_EQ(1u, traf_boxes[1].runs.size()); + EXPECT_EQ(kSampleCount, traf_boxes[1].runs[0].sample_count); + + uint32_t audio_data_offset = mdat_video_data_offset + kVideoDataSize; + EXPECT_EQ(audio_data_offset, traf_boxes[1].runs[0].data_offset); + ASSERT_EQ(kSampleCount, traf_boxes[1].runs[0].sample_durations.size()); + EXPECT_EQ(std::vector<uint32_t>(std::begin(kSampleDurations), + std::end(kSampleDurations)), + traf_boxes[1].runs[0].sample_durations); + + ASSERT_EQ(kSampleCount, traf_boxes[1].runs[0].sample_sizes.size()); + ASSERT_EQ(0u, traf_boxes[1].runs[0].sample_flags.size()); + EXPECT_EQ( + std::vector<uint32_t>(std::begin(kSampleSizes), std::end(kSampleSizes)), + traf_boxes[1].runs[0].sample_sizes); + ASSERT_EQ(0u, traf_boxes[1].runs[0].sample_composition_time_offsets.size()); + + // `mdat` test. + std::unique_ptr<mp4::BoxReader> mdat_reader; + mp4::ParseResult result1 = mp4::BoxReader::ReadTopLevelBox( + written_data.data() + mdat_video_data_offset - kBoxHeaderSize, + written_data.size() - mdat_video_data_offset + kBoxHeaderSize, nullptr, + &mdat_reader); + + EXPECT_EQ(result1, mp4::ParseResult::kOk); + EXPECT_TRUE(mdat_reader); + EXPECT_EQ(mp4::FOURCC_MDAT, mdat_reader->type()); + EXPECT_EQ(kVideoDataSize + kAudioDataSize + kBoxHeaderSize, + mdat_reader->box_size()); + // Once Flush, it needs to reset the internal objects of context and buffer. + Reset(); +} + } // namespace media
diff --git a/media/muxers/mp4_muxer_context.cc b/media/muxers/mp4_muxer_context.cc index caf3b6b..72a2142 100644 --- a/media/muxers/mp4_muxer_context.cc +++ b/media/muxers/mp4_muxer_context.cc
@@ -35,22 +35,6 @@ audio_index_ = index; } -void Mp4MuxerContext::SetCurrentFragmentMoofOffset(size_t offset) { - moof_offset_in_fragment_ = offset; -} - -size_t Mp4MuxerContext::GetCurrentFragmentMoofOffset() const { - return moof_offset_in_fragment_.value(); -} - -void Mp4MuxerContext::SetCurrentFragmentMdatOffset(size_t offset) { - mdat_offset_in_fragment_ = offset; -} - -size_t Mp4MuxerContext::GetCurrentFragmentMdatOffset() const { - return mdat_offset_in_fragment_.value(); -} - OutputPositionTracker& Mp4MuxerContext::GetOutputPositionTracker() const { return *output_position_tracker_; }
diff --git a/media/muxers/mp4_muxer_context.h b/media/muxers/mp4_muxer_context.h index 645ba884..1e32c5b 100644 --- a/media/muxers/mp4_muxer_context.h +++ b/media/muxers/mp4_muxer_context.h
@@ -36,24 +36,12 @@ absl::optional<size_t> GetAudioIndex() const; void SetAudioIndex(size_t index); - void SetCurrentFragmentMoofOffset(size_t offset); - size_t GetCurrentFragmentMoofOffset() const; - - void SetCurrentFragmentMdatOffset(size_t offset); - size_t GetCurrentFragmentMdatOffset() const; - OutputPositionTracker& GetOutputPositionTracker() const; private: absl::optional<size_t> video_index_; absl::optional<size_t> audio_index_; - // MOOF offset will be `base_data_offset` of TFHD in the same fragment. - absl::optional<size_t> moof_offset_in_fragment_; - - // MDAT offset will be `data_offset` of TRUN in the same fragment. - absl::optional<size_t> mdat_offset_in_fragment_; - std::unique_ptr<OutputPositionTracker> output_position_tracker_; SEQUENCE_CHECKER(sequence_checker_);
diff --git a/media/muxers/mp4_muxer_context_unittest.cc b/media/muxers/mp4_muxer_context_unittest.cc index a4c8134..846c112 100644 --- a/media/muxers/mp4_muxer_context_unittest.cc +++ b/media/muxers/mp4_muxer_context_unittest.cc
@@ -34,8 +34,6 @@ mp4_context.SetVideoIndex(1); mp4_context.SetAudioIndex(2); - mp4_context.SetCurrentFragmentMoofOffset(12345); - mp4_context.SetCurrentFragmentMdatOffset(12345678); std::string str1 = "abc"; mp4_context.GetOutputPositionTracker().WriteString(str1); @@ -45,10 +43,6 @@ EXPECT_TRUE(mp4_context.GetAudioIndex().has_value()); EXPECT_EQ(mp4_context.GetVideoIndex(), static_cast<size_t>(1)); EXPECT_EQ(mp4_context.GetAudioIndex(), static_cast<size_t>(2)); - EXPECT_EQ(mp4_context.GetCurrentFragmentMoofOffset(), - static_cast<size_t>(12345)); - EXPECT_EQ(mp4_context.GetCurrentFragmentMdatOffset(), - static_cast<size_t>(12345678)); EXPECT_EQ(str1, written_data); }
diff --git a/media/test/PRESUBMIT.py b/media/test/PRESUBMIT.py index 7784c41e..7effaea 100644 --- a/media/test/PRESUBMIT.py +++ b/media/test/PRESUBMIT.py
@@ -12,10 +12,6 @@ PRESUBMIT_VERSION = '2.0.0' -# This line is 'magic' in that git-cl looks for it to decide whether to -# use Python3 instead of Python2 when running the code in this file. -USE_PYTHON3 = True - def _CheckTestDataReadmeUpdated(input_api, output_api): """ Checks to make sure the README.md file is updated when changing test files. @@ -59,4 +55,3 @@ def CheckChange(input_api, output_api): return _CheckFileList(input_api, output_api) -
diff --git a/media/test/pipeline_integration_test_base.cc b/media/test/pipeline_integration_test_base.cc index fe013e0..b7bac43 100644 --- a/media/test/pipeline_integration_test_base.cc +++ b/media/test/pipeline_integration_test_base.cc
@@ -158,6 +158,11 @@ EXPECT_EQ(seek_time, pipeline_->GetMediaTime()); pipeline_status_ = status; + + // If the seek failed, then stop immediately. + if (!pipeline_status_.is_ok() && on_error_closure_) { + std::move(on_error_closure_).Run(); + } } void PipelineIntegrationTestBase::OnStatusCallback( @@ -347,6 +352,23 @@ pipeline_->SetPlaybackRate(0); } +void PipelineIntegrationTestBase::OnBufferingStateChangeForSeek( + BufferingState state, + BufferingStateChangeReason reason) { + // Record the first buffering state we get. + if (!buffering_state_) { + buffering_state_ = state; + + // The first call must be HAVE_ENOUGH. + EXPECT_EQ(state, BUFFERING_HAVE_ENOUGH); + } + + // Once we have HAVE_ENOUGH, we've had enough. + if (on_ended_closure_) { + std::move(on_ended_closure_).Run(); + } +} + bool PipelineIntegrationTestBase::Seek(base::TimeDelta seek_time) { // Enforce that BUFFERING_HAVE_ENOUGH is the first call below. ::testing::InSequence dummy; @@ -354,18 +376,37 @@ ended_ = false; base::RunLoop run_loop; - // Should always transition to HAVE_ENOUGH once the seek completes. - EXPECT_CALL(*this, OnBufferingStateChange(BUFFERING_HAVE_ENOUGH, _)) - .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit)); + pipeline_status_ = PIPELINE_OK; + buffering_state_.reset(); + // Should always transition to HAVE_ENOUGH once the seek completes + // successfully. On error, it shouldn't be called at all. // After initial HAVE_ENOUGH, any buffering state change is allowed as // playback may cause any number of underflow/preroll events. - EXPECT_CALL(*this, OnBufferingStateChange(_, _)).Times(AnyNumber()); + EXPECT_CALL(*this, OnBufferingStateChange(_, _)) + .Times(AnyNumber()) + .WillRepeatedly(Invoke( + this, &PipelineIntegrationTestBase::OnBufferingStateChangeForSeek)); + bool did_call_on_seeked = false; pipeline_->Seek(seek_time, - base::BindOnce(&PipelineIntegrationTestBase::OnSeeked, - base::Unretained(this), seek_time)); - RunUntilQuitOrError(&run_loop); + base::BindOnce( + [](PipelineIntegrationTestBase* thiz, bool* flag, + base::TimeDelta seek_time, PipelineStatus status) { + *flag = true; + thiz->OnSeeked(seek_time, status); + }, + base::Unretained(this), &did_call_on_seeked, seek_time)); + RunUntilQuitOrEndedOrError(&run_loop); + + // We must get at least one `OnSeeked()` status call. + EXPECT_TRUE(did_call_on_seeked); + // If the seek succeeded, then we must get to HAVE_ENOUGH + if (pipeline_status_ == PIPELINE_OK) { + EXPECT_TRUE(buffering_state_); + EXPECT_EQ(*buffering_state_, BUFFERING_HAVE_ENOUGH); + } // else we don't care about buffering state. + return (pipeline_status_ == PIPELINE_OK); }
diff --git a/media/test/pipeline_integration_test_base.h b/media/test/pipeline_integration_test_base.h index 0a431b2..298110c 100644 --- a/media/test/pipeline_integration_test_base.h +++ b/media/test/pipeline_integration_test_base.h
@@ -273,9 +273,18 @@ // RunUntilQuitOrError() on it. void RunUntilQuitOrEndedOrError(base::RunLoop* run_loop); + // Implementation of `Pipeline::Client::OnBufferingStateChange()` used during + // seeks. This handles failed seeks as well as successful ones, which have + // different behavior around exiting the seek. + void OnBufferingStateChangeForSeek(BufferingState state, + BufferingStateChangeReason reason); + CreateVideoDecodersCB prepend_video_decoders_cb_; CreateAudioDecodersCB prepend_audio_decoders_cb_; + // First buffering state we get from the pipeline. + absl::optional<BufferingState> buffering_state_; + base::OnceClosure on_ended_closure_; base::OnceClosure on_error_closure_; };
diff --git a/mojo/PRESUBMIT.py b/mojo/PRESUBMIT.py index 9678b7bb..9946271e 100644 --- a/mojo/PRESUBMIT.py +++ b/mojo/PRESUBMIT.py
@@ -10,7 +10,6 @@ import os.path -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' def CheckChange(input_api, output_api):
diff --git a/mojo/core/invitation_unittest.cc b/mojo/core/invitation_unittest.cc index 1f6e5d09..3a30adc 100644 --- a/mojo/core/invitation_unittest.cc +++ b/mojo/core/invitation_unittest.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include <cstdint> +#include <cstring> #include <string> #include "base/base_paths.h" @@ -13,6 +14,9 @@ #include "base/files/file_path.h" #include "base/functional/bind.h" #include "base/functional/callback.h" +#include "base/memory/read_only_shared_memory_region.h" +#include "base/memory/shared_memory_mapping.h" +#include "base/memory/writable_shared_memory_region.h" #include "base/notreached.h" #include "base/path_service.h" #include "base/process/process.h" @@ -27,6 +31,7 @@ #include "mojo/buildflags.h" #include "mojo/core/core.h" #include "mojo/core/embedder/embedder.h" +#include "mojo/core/ipcz_api.h" #include "mojo/core/node_controller.h" #include "mojo/core/test/mojo_test_base.h" #include "mojo/core/test/test_switches.h" @@ -460,15 +465,15 @@ } }; -#define DEFINE_TEST_CLIENT(name) \ - class name##Impl : public TestClientBase { \ - public: \ - static void Run(); \ - }; \ - MULTIPROCESS_TEST_MAIN(name) { \ - name##Impl::Run(); \ - return 0; \ - } \ +#define DEFINE_TEST_CLIENT(name) \ + class name##Impl : public TestClientBase { \ + public: \ + static void Run(); \ + }; \ + MULTIPROCESS_TEST_MAIN(name) { \ + name##Impl::Run(); \ + return testing::Test::HasFailure() ? 1 : 0; \ + } \ void name##Impl::Run() const std::string kTestMessage1 = "i am the pusher robot"; @@ -980,6 +985,115 @@ WriteMessage(pipe_to_test, "ccc"); EXPECT_EQ("bye", ReadMessage(host)); + MojoClose(host); + MojoClose(pipe_to_test); +} + +TEST_F(MAYBE_InvitationTest, MultiBrokerNetwork) { + // Regression test for https://crbug.com/1432382, ensuring that a non-broker + // can communicate with brokers other than its own and can transmit platform + // handles between them. + + if (!mojo::core::IsMojoIpczEnabled()) { + // Mutli-broker networks are only supported with ipcz enabled. + GTEST_SKIP() << "This tests functionality which is only supported when " + << "MojoIpcz is enabled, but MojoIpcz is not enabled."; + } + + ASSERT_TRUE(mojo::core::GetIpczNodeOptions().is_broker); + + // First we launch a second broker and connect to it. + MojoHandle secondary_broker; + base::Process secondary_broker_process = + LaunchChildTestClient("SecondaryBroker", &secondary_broker, 1, + MOJO_SEND_INVITATION_FLAG_ISOLATED); + + // Then launch a non-broker and connect to it. + MojoHandle client; + base::Process client_process = LaunchChildTestClient( + "MultiBrokerNetworkClient", &client, 1, MOJO_SEND_INVITATION_FLAG_NONE); + + // Pass them each one end of the same pipe. + MessagePipe pipe; + MojoHandle broker_to_client = pipe.handle0.release().value(); + MojoHandle client_to_broker = pipe.handle1.release().value(); + WriteMessageWithHandles(secondary_broker, "hi", &broker_to_client, 1); + WriteMessageWithHandles(client, "hi", &client_to_broker, 1); + + // Signal to the host that it's OK to terminate, then wait for acks. + WriteMessage(secondary_broker, "bye"); + WriteMessage(client, "bye"); + WaitForProcessToTerminate(secondary_broker_process); + WaitForProcessToTerminate(client_process); + MojoClose(secondary_broker); + MojoClose(client); +} + +MojoHandle CreateMemory(base::StringPiece contents) { + auto region = base::WritableSharedMemoryRegion::Create(contents.size()); + auto mapping = region.Map(); + memcpy(mapping.memory(), contents.data(), contents.size()); + auto buffer = WrapReadOnlySharedMemoryRegion( + base::WritableSharedMemoryRegion::ConvertToReadOnly(std::move(region))); + return buffer.release().value(); +} + +std::string ReadMemory(MojoHandle handle) { + auto region = UnwrapReadOnlySharedMemoryRegion( + ScopedSharedBufferHandle{SharedBufferHandle{handle}}); + auto mapping = region.Map(); + base::StringPiece contents{reinterpret_cast<const char*>(mapping.memory()), + region.GetSize()}; + return std::string{contents}; +} + +constexpr size_t kNumMultiBrokerMessageIterations = 100; + +DEFINE_TEST_CLIENT(SecondaryBroker) { + ASSERT_TRUE(mojo::core::GetIpczNodeOptions().is_broker); + MojoHandle invitation = + AcceptInvitation(MOJO_ACCEPT_INVITATION_FLAG_ISOLATED); + MojoHandle test_runner = ExtractPipeFromInvitation(invitation); + + MojoHandle client; + EXPECT_EQ("hi", ReadMessageWithHandles(test_runner, &client, 1)); + + // Note that handle passing can succeed even if communication is broken + // between non-brokers and secondary brokers, as long as no direct link + // between them has been fully negotiated yet. We perform many iterations of + // handle passing to ensure adequate coverage. + for (size_t i = 0; i < kNumMultiBrokerMessageIterations; ++i) { + MojoHandle buffer = CreateMemory("lol"); + WriteMessageWithHandles(client, "aaa", &buffer, 1); + EXPECT_EQ("bbb", ReadMessageWithHandles(client, &buffer, 1)); + EXPECT_EQ("lmao", ReadMemory(buffer)); + } + + EXPECT_EQ("bye", ReadMessage(test_runner)); + + MojoClose(test_runner); + MojoClose(client); +} + +DEFINE_TEST_CLIENT(MultiBrokerNetworkClient) { + ASSERT_FALSE(mojo::core::GetIpczNodeOptions().is_broker); + MojoHandle invitation = AcceptInvitation(MOJO_ACCEPT_INVITATION_FLAG_NONE); + MojoHandle test_runner = ExtractPipeFromInvitation(invitation); + + MojoHandle secondary_broker; + EXPECT_EQ("hi", ReadMessageWithHandles(test_runner, &secondary_broker, 1)); + + for (size_t i = 0; i < kNumMultiBrokerMessageIterations; ++i) { + MojoHandle buffer = CreateMemory("lmao"); + WriteMessageWithHandles(secondary_broker, "bbb", &buffer, 1); + EXPECT_EQ("aaa", ReadMessageWithHandles(secondary_broker, &buffer, 1)); + EXPECT_EQ("lol", ReadMemory(buffer)); + } + + EXPECT_EQ("bye", ReadMessage(test_runner)); + + MojoClose(test_runner); + MojoClose(secondary_broker); } } // namespace
diff --git a/mojo/core/ipcz_api.cc b/mojo/core/ipcz_api.cc index 56bf048..6134fe03 100644 --- a/mojo/core/ipcz_api.cc +++ b/mojo/core/ipcz_api.cc
@@ -48,9 +48,8 @@ // to be expanded. .memory_flags = IPCZ_MEMORY_FIXED_PARCEL_CAPACITY, }; - IpczResult result = - GetIpczAPI().CreateNode(&ipcz_driver::kDriver, IPCZ_INVALID_DRIVER_HANDLE, - flags, &create_options, &g_node); + IpczResult result = GetIpczAPI().CreateNode(&ipcz_driver::kDriver, flags, + &create_options, &g_node); return result == IPCZ_RESULT_OK; }
diff --git a/mojo/core/ipcz_driver/transport.cc b/mojo/core/ipcz_driver/transport.cc index c809e77f..0fe087e 100644 --- a/mojo/core/ipcz_driver/transport.cc +++ b/mojo/core/ipcz_driver/transport.cc
@@ -611,7 +611,7 @@ base::Process process; const auto& header = *reinterpret_cast<const TransportHeader*>(data.data()); #if BUILDFLAG(IS_WIN) - if (handles.size() >= 2 && from_transport.remote_process().IsValid()) { + if (handles.size() >= 2) { process = base::Process(handles[1].ReleaseHandle()); } #endif
diff --git a/mojo/public/cpp/bindings/direct_receiver.cc b/mojo/public/cpp/bindings/direct_receiver.cc index 84f2c3a..9e92ead 100644 --- a/mojo/public/cpp/bindings/direct_receiver.cc +++ b/mojo/public/cpp/bindings/direct_receiver.cc
@@ -36,9 +36,8 @@ .memory_flags = IPCZ_MEMORY_FIXED_PARCEL_CAPACITY, }; IpczHandle node; - const IpczResult create_result = - ipcz.CreateNode(&core::ipcz_driver::kDriver, IPCZ_INVALID_DRIVER_HANDLE, - IPCZ_NO_FLAGS, &create_options, &node); + const IpczResult create_result = ipcz.CreateNode( + &core::ipcz_driver::kDriver, IPCZ_NO_FLAGS, &create_options, &node); CHECK_EQ(create_result, IPCZ_RESULT_OK); node_.reset(Handle(node));
diff --git a/mojo/public/cpp/bindings/tests/default_construct_unittest.cc b/mojo/public/cpp/bindings/tests/default_construct_unittest.cc index c33f1884..e8ec529 100644 --- a/mojo/public/cpp/bindings/tests/default_construct_unittest.cc +++ b/mojo/public/cpp/bindings/tests/default_construct_unittest.cc
@@ -123,4 +123,9 @@ EXPECT_EQ(container.test_struct.value(), 0); } +TEST(DefaultConstructOptionalTest, InitializedToNullopt) { + auto container = mojom::OptionalTestStructContainer::New(); + EXPECT_EQ(absl::nullopt, container->test_struct); +} + } // namespace mojo::test::default_construct
diff --git a/mojo/public/cpp/bindings/tests/default_construct_unittest.test-mojom b/mojo/public/cpp/bindings/tests/default_construct_unittest.test-mojom index 0677f73..7c9ca43 100644 --- a/mojo/public/cpp/bindings/tests/default_construct_unittest.test-mojom +++ b/mojo/public/cpp/bindings/tests/default_construct_unittest.test-mojom
@@ -14,6 +14,10 @@ TestStruct test_struct; }; +struct OptionalTestStructContainer { + TestStruct? test_struct; +}; + interface TestInterface { TestMethod(TestStruct in) => (TestStruct out);
diff --git a/mojo/public/interfaces/bindings/tests/PRESUBMIT.py b/mojo/public/interfaces/bindings/tests/PRESUBMIT.py index e3b171b2..e7109d07 100644 --- a/mojo/public/interfaces/bindings/tests/PRESUBMIT.py +++ b/mojo/public/interfaces/bindings/tests/PRESUBMIT.py
@@ -12,8 +12,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - def CheckChange(input_api, output_api): old_sys_path = sys.path[:] results = []
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl index 1cfc8b4..137495d5 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm.cc.tmpl
@@ -343,10 +343,11 @@ {%- set name = param.name|camel_to_under %} {%- set kind = param.kind %} {%- set param_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set param_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=True) %} {{param_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} }; {%- if kind|is_nullable_kind %} - {{param_maybe_mojom_type}} local_maybe_{{name}}{ {{- kind|default_constructor_args -}} }; +{%- set unnullable_kind = kind|to_unnullable_kind %} +{%- set param_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} + {{param_maybe_mojom_type}} local_maybe_{{name}}{ {{- unnullable_kind|default_constructor_args -}} }; {%- endif %} {%- endfor %} @@ -415,10 +416,11 @@ {%- set name = param.name|camel_to_under %} {%- set kind = param.kind %} {%- set param_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set param_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=True) %} {{param_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} }; {%- if kind|is_nullable_kind %} - {{param_maybe_mojom_type}} local_maybe_{{name}}{ {{- kind|default_constructor_args -}} }; +{%- set unnullable_kind = kind|to_unnullable_kind %} +{%- set param_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} + {{param_maybe_mojom_type}} local_maybe_{{name}}{ {{- unnullable_kind|default_constructor_args -}} }; {%- endif %} {%- endfor %}
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_from_proto_macros.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_from_proto_macros.tmpl index ffa087bc..e06d040 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_from_proto_macros.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_from_proto_macros.tmpl
@@ -3,7 +3,11 @@ {%- macro declare_array(type, kind) %} {%- set mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set mojom_maybe_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} +{%- if kind.kind|is_nullable_kind %} +{%- set mojom_maybe_type = kind.kind|to_unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} +{%- else %} +{%- set mojom_maybe_type = mojom_type %} +{%- endif %} bool FromProto( const {{type}}& input, std::vector<{{mojom_type}}>& output);{{"\n"-}} @@ -26,7 +30,11 @@ {%- macro declare_map(type, kind) %} {%- set mojom_key_type = kind.key_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} {%- set mojom_value_type = kind.value_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set mojom_maybe_value_type = kind.value_kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} +{%- if kind.value_kind|is_nullable_kind %} +{%- set mojom_maybe_value_type = kind.value_kind|to_unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} +{%- else %} +{%- set mojom_maybe_value_type = mojom_value_type %} +{%- endif %} bool FromProto( const {{type}}& input, base::flat_map<{{mojom_key_type}}, @@ -69,7 +77,6 @@ {%- macro define_array(type, kind) %} {%- set mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set mojom_maybe_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} bool FromProto( const {{type}}& input, std::vector<{{mojom_type}}>& output) { @@ -79,7 +86,9 @@ for (const auto& entry : input.values()) { {{mojom_type}} value{ {{- kind.kind|default_constructor_args -}} }; {%- if kind.kind|is_nullable_kind %} - {{mojom_maybe_type}} maybe_value{ {{- kind.kind|default_constructor_args -}} }; +{%- set unnullable_kind = kind.kind|to_unnullable_kind %} +{%- set mojom_maybe_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} + {{mojom_maybe_type}} maybe_value{ {{- unnullable_kind|default_constructor_args -}} }; if (FromProto(entry.value(), maybe_value)) { value = std::move(maybe_value); } @@ -122,7 +131,6 @@ {%- macro define_map(type, kind) %} {%- set mojom_key_type = kind.key_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} {%- set mojom_value_type = kind.value_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set mojom_maybe_value_type = kind.value_kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} bool FromProto( const {{type}}& input, base::flat_map<{{mojom_key_type}}, @@ -130,9 +138,11 @@ bool result = true; for (const auto& entry : input.values()) { {%- if kind.value_kind|is_nullable_kind %} +{%- set unnullable_value_kind = kind.value_kind|to_unnullable_kind %} +{%- set mojom_maybe_value_type = unnullable_value_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} {{mojom_key_type}} key{ {{- kind.key_kind|default_constructor_args -}} }; {{mojom_value_type}} value{ {{- kind.value_kind|default_constructor_args -}} }; - {{mojom_maybe_value_type}} maybe_value{ {{- kind.value_kind|default_constructor_args -}} }; + {{mojom_maybe_value_type}} maybe_value{ {{- unnullable_value_kind|default_constructor_args -}} }; if (FromProto(entry.key(), key)) { if (FromProto(entry.value(), maybe_value)) { @@ -258,10 +268,11 @@ {%- set name = field.name|camel_to_under %} {%- set kind = field.kind %} {%- set field_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set field_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} {{field_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} }; {%- if kind|is_nullable_kind %} - {{field_maybe_mojom_type}} local_maybe_{{name}}{ {{- kind|default_constructor_args -}} }; +{%- set unnullable_kind = kind|to_unnullable_kind %} +{%- set field_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} + {{field_maybe_mojom_type}} local_maybe_{{name}}{ {{- unnullable_kind|default_constructor_args -}} }; {%- endif %} {%- endfor %} @@ -334,9 +345,10 @@ {%- set field_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} case {{union_type}}::k{{("m_" ~ name)|under_to_camel}}: { {%- if kind|is_nullable_kind %} -{%- set field_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} +{%- set unnullable_kind = kind|to_unnullable_kind %} +{%- set field_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} {{field_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} }; - {{field_maybe_mojom_type}} maybe_local_{{name}}{ {{- kind|default_constructor_args -}} }; + {{field_maybe_mojom_type}} maybe_local_{{name}}{ {{- unnullable_kind|default_constructor_args -}} }; if (FromProto(input.m_{{name}}(), maybe_local_{{name}})) { local_{{name}} = std::move(maybe_local_{{name}}); }
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl index 407d0ae..e71836b 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_macros.tmpl
@@ -1,7 +1,7 @@ {%- macro not_null(kind, name) %} {%- if kind|is_typemapped_kind and kind|is_struct_kind and kind|nullable_is_same_kind %} {%- set data_view = kind|get_qualified_name_for_kind ~ "DataView" %} -{%- set data_type = kind|cpp_wrapper_type(ignore_nullable=True) %} +{%- set data_type = kind|to_unnullable_kind|cpp_wrapper_type %} {%- if data_type|truncate(16, true, '', 0) == '::scoped_refptr<' %} {{name}} {%- else %} @@ -71,4 +71,4 @@ } {%- endif %} {%- endif %} -{%- endmacro %} \ No newline at end of file +{%- endmacro %}
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl index bffe1444..2b331cdb 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_to_proto_macros.tmpl
@@ -3,7 +3,11 @@ {%- macro declare_array(type, kind) %} {%- set mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set maybe_mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} +{%- if kind.kind|is_nullable_kind %} +{%- set maybe_mojom_type = kind.kind|to_unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} +{%- else %} +{%- set maybe_mojom_type = mojom_type %} +{%- endif %} bool ToProto( {%- if kind.kind|is_move_only_kind %} std::vector<{{mojom_type}}>&& input, @@ -73,7 +77,11 @@ {%- macro define_array(type, kind) %} {%- set maybe_const = "const " if not kind.kind|is_move_only_kind else "" %} {%- set mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set maybe_mojom_type = kind.kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} +{%- if kind.kind|is_nullable_kind %} +{%- set maybe_mojom_type = kind.kind|to_unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} +{%- else %} +{%- set maybe_mojom_type = mojom_type %} +{%- endif %} bool ToProto( {%- if kind.kind|is_move_only_kind %} std::vector<{{mojom_type}}>&& input,
diff --git a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_traits_specialization_macros.tmpl b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_traits_specialization_macros.tmpl index 2e1fe33f..ac41e0e0 100644 --- a/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_traits_specialization_macros.tmpl +++ b/mojo/public/tools/bindings/generators/mojolpm_templates/mojolpm_traits_specialization_macros.tmpl
@@ -12,11 +12,12 @@ {%- set kind = field.kind %} {%- if field.kind|is_nullable_kind and not field.kind|nullable_is_same_kind %} {%- set field_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set field_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} +{%- set unnullable_kind = kind|to_unnullable_kind %} +{%- set field_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} static {{field_mojom_type}} {{field.name}}( const {{struct_type}}& input) { {{field_mojom_type}} maybe_local_{{name}}{ {{- kind|default_constructor_args -}} }; - {{field_maybe_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} }; + {{field_maybe_mojom_type}} local_{{name}}{ {{- unnullable_kind|default_constructor_args -}} }; if (input.has_m_{{name}}() && mojolpm::FromProto( input.m_{{name}}(), local_{{name}})) { @@ -66,11 +67,12 @@ {%- set kind = field.kind %} {%- if field.kind|is_nullable_kind and not field.kind|nullable_is_same_kind %} {%- set field_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true) %} -{%- set field_maybe_mojom_type = kind|cpp_wrapper_type(add_same_module_namespaces=true, ignore_nullable=true) %} +{%- set unnullable_kind = kind|to_unnullable_kind %} +{%- set field_maybe_mojom_type = unnullable_kind|cpp_wrapper_type(add_same_module_namespaces=true) %} static {{field_mojom_type}} {{field.name}}( const {{union_type}}& input) { {{field_mojom_type}} maybe_local_{{name}}{ {{- kind|default_constructor_args -}} }; - {{field_maybe_mojom_type}} local_{{name}}{ {{- kind|default_constructor_args -}} }; + {{field_maybe_mojom_type}} local_{{name}}{ {{- unnullable_kind|default_constructor_args -}} }; if (mojolpm::FromProto( input.m_{{name}}(), local_{{name}})) {
diff --git a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py index e19deeb..c81e7da 100644 --- a/mojo/public/tools/bindings/generators/mojom_cpp_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_cpp_generator.py
@@ -545,9 +545,10 @@ def _DefaultValue(self, field): if not field.default: - if not self._IsDefaultConstructible(field.kind): - return "mojo::internal::DefaultConstructTag()" - return "" + if mojom.IsNullableKind(field.kind) or self._IsDefaultConstructible( + field.kind): + return "" + return "mojo::internal::DefaultConstructTag()" if mojom.IsStructKind(field.kind): assert field.default == "default" @@ -652,13 +653,8 @@ return "constexpr %s %s = %s" % (self._GetNameForKind( constant.kind), constant.name, self._ConstantValue(constant)) - def _GetCppWrapperType(self, - kind, - add_same_module_namespaces=False, - ignore_nullable=False): + def _GetCppWrapperType(self, kind, add_same_module_namespaces=False): def _AddOptional(type_name): - if ignore_nullable: - return type_name return "absl::optional<%s>" % type_name if self._IsTypemappedKind(kind):
diff --git a/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py b/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py index ddbdcafe..69ee16b 100644 --- a/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py +++ b/mojo/public/tools/bindings/generators/mojom_mojolpm_generator.py
@@ -268,6 +268,7 @@ "is_struct_kind": mojom.IsStructKind, "is_typemapped_kind": self._IsTypemappedKind, "is_union_kind": mojom.IsUnionKind, + "to_unnullable_kind": self._ToUnnullableKind, "under_to_camel": self._UnderToCamel, } return cpp_filters @@ -499,9 +500,9 @@ return False def _DefaultConstructorArgs(self, kind): - if not self._IsDefaultConstructible(kind): - return "mojo::internal::DefaultConstructTag()" - return "" + if mojom.IsNullableKind(kind) or self._IsDefaultConstructible(kind): + return "" + return "mojo::internal::DefaultConstructTag()" def _EnumFieldName(self, name, kind): # The WebFeature enum has entries that differ only by the casing of the @@ -518,3 +519,7 @@ field_names[field.name] = new_field_name self.enum_name_cache[kind] = field_names return self.enum_name_cache[kind][name] + + def _ToUnnullableKind(self, kind): + assert mojom.IsNullableKind(kind) + return kind.MakeUnnullableKind()
diff --git a/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.cc.tmpl b/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.cc.tmpl index 26004866..83e758e 100644 --- a/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.cc.tmpl +++ b/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.cc.tmpl
@@ -14,12 +14,12 @@ {{class_name}}::{{class_name}}( content::WebUIController* controller, {{- macros.constructor_params(webui_js_bridge) | indent(4) -}}) - : + : controller_(raw_ref<content::WebUIController>::from_ptr(controller)), {%- for method in webui_js_bridge.methods %} {{method|binder_variable_name}}_({{method|binder_variable_name}}) {{-"," if not loop.last else ""}} {%- endfor %} { - CHECK(controller->GetAs<{{class_name}}::WebUIControllerSubclass>()); + CHECK(controller_->GetAs<{{class_name}}::WebUIControllerSubclass>()); } {{class_name}}::~{{class_name}}() = default; @@ -30,6 +30,7 @@ {{param.kind|cpp_type}} {{param.name}}{{"," if not loop.last else ""}} {%- endfor -%}) { {{method|binder_variable_name}}_.Run( + &*controller_, {%- for param in method.parameters %} std::move({{param.name}}){{"," if not loop.last else ""}} {%- endfor -%}
diff --git a/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.h.tmpl b/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.h.tmpl index b0728e6..7d4da9c3 100644 --- a/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.h.tmpl +++ b/mojo/public/tools/bindings/generators/webui_js_bridge_templates/webui_js_bridge_impl.h.tmpl
@@ -12,6 +12,7 @@ #include "{{module.path}}.h" +#include "base/memory/raw_ref.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/pending_remote.h" @@ -35,6 +36,7 @@ public: {%- for method in webui_js_bridge.methods %} using BinderFor{{method.name}} = base::RepeatingCallback<void( + content::WebUIController*, {%- for param in method.parameters %} {{param.kind|cpp_type}}{{"," if not loop.last else ""}} {%- endfor -%} @@ -65,6 +67,9 @@ {%- endfor %} private: + // WebUIController is expected to outlive this class. + const raw_ref<content::WebUIController> controller_; + {% for method in webui_js_bridge.methods %} BinderFor{{method.name}} {{method|binder_variable_name}}_; {%- endfor %}
diff --git a/mojo/public/tools/mojom/mojom/generate/module.py b/mojo/public/tools/mojom/mojom/generate/module.py index 52f2d1249..0f20219 100644 --- a/mojo/public/tools/mojom/mojom/generate/module.py +++ b/mojo/public/tools/mojom/mojom/generate/module.py
@@ -298,6 +298,35 @@ return nullable_kind + def MakeUnnullableKind(self): + assert self.is_nullable + + if self == NULLABLE_STRING: + return STRING + if self == NULLABLE_HANDLE: + return HANDLE + if self == NULLABLE_DCPIPE: + return DCPIPE + if self == NULLABLE_DPPIPE: + return DPPIPE + if self == NULLABLE_MSGPIPE: + return MSGPIPE + if self == NULLABLE_SHAREDBUFFER: + return SHAREDBUFFER + if self == NULLABLE_PLATFORMHANDLE: + return PLATFORMHANDLE + + unnullable_kind = type(self)() + unnullable_kind.shared_definition = self.shared_definition + if self.spec is not None: + assert self.spec[0] == '?' + unnullable_kind.spec = self.spec[1:] + unnullable_kind.is_nullable = False + unnullable_kind.parent_kind = self.parent_kind + unnullable_kind.module = self.module + + return unnullable_kind + def __eq__(self, rhs): return (isinstance(rhs, ReferenceKind) and super().__eq__(rhs))
diff --git a/native_client_sdk/src/doc/PRESUBMIT.py b/native_client_sdk/src/doc/PRESUBMIT.py index 7878698..d6f73a02 100644 --- a/native_client_sdk/src/doc/PRESUBMIT.py +++ b/native_client_sdk/src/doc/PRESUBMIT.py
@@ -4,9 +4,6 @@ import subprocess -USE_PYTHON3 = True - - def _CheckSphinxBuild(input_api, output_api): """Check that the docs are buildable without any warnings.
diff --git a/net/BUILD.gn b/net/BUILD.gn index 19f554c8..9f11a36 100644 --- a/net/BUILD.gn +++ b/net/BUILD.gn
@@ -1267,6 +1267,10 @@ configs += [ "//build/config/compiler:enable_arc" ] } + if (is_ios) { + deps += [ "//base/ios" ] + } + if (is_win) { sources += [ "base/file_stream_context_win.cc", @@ -2056,7 +2060,10 @@ } if (is_ios) { - deps += [ ":test_support_bundle_data" ] + deps += [ + ":test_support_bundle_data", + "//base/ios", + ] } if (use_nss_certs) { @@ -2939,6 +2946,10 @@ ] } + if (is_ios) { + deps += [ "//base/ios" ] + } + if (is_posix) { sources += [ "base/sockaddr_util_posix_unittest.cc" ] }
diff --git a/net/PRESUBMIT.py b/net/PRESUBMIT.py index 555e111..6c47b9d 100644 --- a/net/PRESUBMIT.py +++ b/net/PRESUBMIT.py
@@ -10,9 +10,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - - def CheckChange(input_api, output_api): import sys old_sys_path = sys.path[:]
diff --git a/net/android/BUILD.gn b/net/android/BUILD.gn index c9b605d..b464c0e 100644 --- a/net/android/BUILD.gn +++ b/net/android/BUILD.gn
@@ -79,6 +79,7 @@ ":embedded_test_server_aidl_java", ":net_java", "//base:base_java", + "//base:base_java_test_support", "//base:base_java_url_utils_for_test", "//base:jni_java", "//third_party/androidx:androidx_annotation_annotation_java", @@ -144,9 +145,7 @@ # Used as an additional_apk in test scripts. never_incremental = true - # Multidex requires a custom Application class to initialize it. Simpler to - # just disable it. - enable_multidex = false + enable_multidex = true # Required on Android Q+ to read from /sdcard when installing certs. target_sdk_version = 28
diff --git a/net/android/java/src/org/chromium/net/X509Util.java b/net/android/java/src/org/chromium/net/X509Util.java index a9e3dba1..54e02dec 100644 --- a/net/android/java/src/org/chromium/net/X509Util.java +++ b/net/android/java/src/org/chromium/net/X509Util.java
@@ -163,6 +163,11 @@ private static boolean sLoadedSystemKeyStore; /** + * A root that will be installed as a user-trusted root for testing purposes. + */ + private static X509Certificate sTestRoot; + + /** * Lock object used to synchronize all calls that modify or depend on the trust managers. */ private static final Object sLock = new Object(); @@ -319,17 +324,24 @@ new ByteArrayInputStream(derBytes)); } + /** + * Add a test root certificate for use by the Android Platform verifier. + */ public static void addTestRootCertificate(byte[] rootCertBytes) throws CertificateException, KeyStoreException, NoSuchAlgorithmException { X509Certificate rootCert = createCertificateFromBytes(rootCertBytes); synchronized (sLock) { ensureTestInitializedLocked(); + // Add the cert to be used by the Android Platform Verifier. sTestKeyStore.setCertificateEntry( "root_cert_" + Integer.toString(sTestKeyStore.size()), rootCert); reloadTestTrustManager(); } } + /** + * Clear test root certificates in use by the Android Platform verifier. + */ public static void clearTestRootCertificates() throws NoSuchAlgorithmException, CertificateException, KeyStoreException { synchronized (sLock) { @@ -343,6 +355,22 @@ } } + /** + * Set a test root certificate for use by CertVerifierBuiltin. + */ + public static void setTestRootCertificateForBuiltin(byte[] rootCertBytes) + throws NoSuchAlgorithmException, CertificateException, KeyStoreException { + X509Certificate rootCert = createCertificateFromBytes(rootCertBytes); + synchronized (sLock) { + // Add the cert to be used by CertVerifierBuiltin. + // + // This saves the root so it is returned from getUserAddedRoots, for TrustStoreAndroid. + // This is done for the Java EmbeddedTestServer implementation and must run before + // native code is loaded, when getUserAddedRoots is first run. + sTestRoot = rootCert; + } + } + private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', @@ -503,6 +531,14 @@ Log.e(TAG, "Error reading cert aliases: %s", e); return new byte[0][]; } + + if (sTestRoot != null) { + try { + userRootBytes.add(sTestRoot.getEncoded()); + } catch (CertificateEncodingException e) { + Log.e(TAG, "Error encoding test root cert, error %s", e); + } + } } return userRootBytes.toArray(new byte[0][]);
diff --git a/net/base/backoff_entry_serializer_fuzzer.cc b/net/base/backoff_entry_serializer_fuzzer.cc index f08d3d5..8930b2a 100644 --- a/net/base/backoff_entry_serializer_fuzzer.cc +++ b/net/base/backoff_entry_serializer_fuzzer.cc
@@ -32,29 +32,29 @@ : input_(input) {} BackoffEntry::Policy policy() const { - return PolicyFromProto(input_.policy()); + return PolicyFromProto(input_->policy()); } base::Time parse_time() const { - return base::Time() + base::Microseconds(input_.parse_time()); + return base::Time() + base::Microseconds(input_->parse_time()); } base::TimeTicks parse_time_ticks() const { - return base::TimeTicks() + base::Microseconds(input_.parse_time()); + return base::TimeTicks() + base::Microseconds(input_->parse_time()); } base::Time serialize_time() const { - return base::Time() + base::Microseconds(input_.serialize_time()); + return base::Time() + base::Microseconds(input_->serialize_time()); } base::TimeTicks now_ticks() const { - return base::TimeTicks() + base::Microseconds(input_.now_ticks()); + return base::TimeTicks() + base::Microseconds(input_->now_ticks()); } absl::optional<base::Value> serialized_entry() const { json_proto::JsonProtoConverter converter; - std::string json_array = converter.Convert(input_.serialized_entry()); + std::string json_array = converter.Convert(input_->serialized_entry()); absl::optional<base::Value> value = base::JSONReader::Read(json_array); return value; } private: - const fuzz_proto::FuzzerInput& input_; + const raw_ref<const fuzz_proto::FuzzerInput> input_; static BackoffEntry::Policy PolicyFromProto( const fuzz_proto::BackoffEntryPolicy& policy) {
diff --git a/net/dns/BUILD.gn b/net/dns/BUILD.gn index 18afe4f..6eb1429 100644 --- a/net/dns/BUILD.gn +++ b/net/dns/BUILD.gn
@@ -63,6 +63,8 @@ "dns_util.h", "host_cache.cc", "host_resolver.cc", + "host_resolver_cache.cc", + "host_resolver_cache.h", "host_resolver_internal_result.cc", "host_resolver_internal_result.h", "host_resolver_manager.cc", @@ -410,6 +412,7 @@ "dns_udp_tracker_unittest.cc", "dns_util_unittest.cc", "host_cache_unittest.cc", + "host_resolver_cache_unittest.cc", "host_resolver_internal_result_unittest.cc", "host_resolver_manager_unittest.cc", "https_record_rdata_unittest.cc",
diff --git a/net/dns/host_cache_unittest.cc b/net/dns/host_cache_unittest.cc index 65d75b7a..01d0901 100644 --- a/net/dns/host_cache_unittest.cc +++ b/net/dns/host_cache_unittest.cc
@@ -1909,7 +1909,7 @@ "flags": 0, "host_resolver_source": 2, "hostname": "example.com", - "network_isolation_key": [ ], + "network_anonymization_key": [ ], "port": 443, "scheme": "https", "secure": false @@ -1940,7 +1940,7 @@ "flags": 0, "host_resolver_source": 2, "hostname": "example.com", - "network_isolation_key": [ ], + "network_anonymization_key": [ ], "port": 443, "scheme": "https", "secure": false
diff --git a/net/dns/host_resolver_cache.cc b/net/dns/host_resolver_cache.cc new file mode 100644 index 0000000..a92d043 --- /dev/null +++ b/net/dns/host_resolver_cache.cc
@@ -0,0 +1,162 @@ +// 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 "net/dns/host_resolver_cache.h" + +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/strings/string_piece.h" +#include "base/time/clock.h" +#include "net/base/network_anonymization_key.h" +#include "net/dns/host_resolver_internal_result.h" +#include "net/dns/public/dns_query_type.h" +#include "net/dns/public/host_resolver_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/third_party/mozilla/url_parse.h" +#include "url/url_canon.h" +#include "url/url_canon_stdstring.h" + +namespace net { + +HostResolverCache::HostResolverCache(const base::Clock& clock, + const base::TickClock& tick_clock) + : clock_(clock), tick_clock_(tick_clock) {} + +HostResolverCache::~HostResolverCache() = default; + +HostResolverCache::HostResolverCache(HostResolverCache&&) = default; + +HostResolverCache& HostResolverCache::operator=(HostResolverCache&&) = default; + +const HostResolverInternalResult* HostResolverCache::Lookup( + base::StringPiece domain_name, + const NetworkAnonymizationKey& network_anonymization_key, + DnsQueryType query_type, + HostResolverSource source, + absl::optional<bool> secure) const { + std::vector<EntryMap::const_iterator> candidates = LookupInternal( + domain_name, network_anonymization_key, query_type, source, secure); + + // Get the most secure, last-matching (which is first in the vector returned + // by LookupInternal()) non-expired result. + base::TimeTicks now_ticks = tick_clock_->NowTicks(); + base::Time now = clock_->Now(); + HostResolverInternalResult* most_secure_result = nullptr; + for (const EntryMap::const_iterator& candidate : candidates) { + DCHECK(candidate->second.result->timed_expiration().has_value()); + + if (candidate->second.result->expiration().has_value()) { + if (candidate->second.result->expiration() <= now_ticks) { + continue; + } + } else if (candidate->second.result->timed_expiration() <= now) { + continue; + } + + // If the candidate is secure, or all results are insecure, no need to check + // any more. + if (candidate->second.secure || !secure.value_or(true)) { + return candidate->second.result.get(); + } else if (most_secure_result == nullptr) { + most_secure_result = candidate->second.result.get(); + } + } + + return most_secure_result; +} + +void HostResolverCache::Set( + std::unique_ptr<HostResolverInternalResult> result, + const NetworkAnonymizationKey& network_anonymization_key, + HostResolverSource source, + bool secure) { + // Result must have at least a timed expiration to be a cacheable result. + DCHECK(result->timed_expiration().has_value()); + + std::vector<EntryMap::const_iterator> matches = + LookupInternal(result->domain_name(), network_anonymization_key, + result->query_type(), source, secure); + + for (const EntryMap::const_iterator& match : matches) { + entries_.erase(match); + } + + std::string domain_name = result->domain_name(); + entries_.emplace(Key(std::move(domain_name), network_anonymization_key), + Entry(std::move(result), source, secure)); +} + +HostResolverCache::Entry::Entry( + std::unique_ptr<HostResolverInternalResult> result, + HostResolverSource source, + bool secure) + : result(std::move(result)), source(source), secure(secure) {} + +HostResolverCache::Entry::~Entry() = default; + +HostResolverCache::Entry::Entry(Entry&&) = default; + +HostResolverCache::Entry& HostResolverCache::Entry::operator=(Entry&&) = + default; + +std::vector<HostResolverCache::EntryMap::const_iterator> +HostResolverCache::LookupInternal( + base::StringPiece domain_name, + const NetworkAnonymizationKey& network_anonymization_key, + DnsQueryType query_type, + HostResolverSource source, + absl::optional<bool> secure) const { + auto matches = std::vector<EntryMap::const_iterator>(); + + if (entries_.empty()) { + return matches; + } + + std::string canonicalized; + url::StdStringCanonOutput output(&canonicalized); + url::CanonHostInfo host_info; + + url::CanonicalizeHostVerbose(domain_name.data(), + url::Component(0, domain_name.size()), &output, + &host_info); + + // For performance, when canonicalization can't canonicalize, minimize string + // copies and just reuse the input StringPiece. This optimization prevents + // easily reusing a MaybeCanoncalize util with similar code. + base::StringPiece lookup_name = domain_name; + if (host_info.family == url::CanonHostInfo::Family::NEUTRAL) { + output.Complete(); + lookup_name = canonicalized; + } + + auto range = + entries_.equal_range(KeyRef{lookup_name, network_anonymization_key}); + if (range.first == entries_.cend() || range.second == entries_.cbegin()) { + return matches; + } + + // Iterate in reverse order to return most-recently-added entry first. + auto it = --range.second; + while (true) { + if ((query_type == DnsQueryType::UNSPECIFIED || + it->second.result->query_type() == DnsQueryType::UNSPECIFIED || + query_type == it->second.result->query_type()) && + (source == HostResolverSource::ANY || source == it->second.source) && + (!secure.has_value() || secure.value() == it->second.secure)) { + matches.push_back(it); + } + + if (it == range.first) { + break; + } + --it; + } + + return matches; +} + +} // namespace net
diff --git a/net/dns/host_resolver_cache.h b/net/dns/host_resolver_cache.h new file mode 100644 index 0000000..b733ec1 --- /dev/null +++ b/net/dns/host_resolver_cache.h
@@ -0,0 +1,132 @@ +// 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 NET_DNS_HOST_RESOLVER_CACHE_H_ +#define NET_DNS_HOST_RESOLVER_CACHE_H_ + +#include <map> +#include <memory> +#include <string> +#include <tuple> +#include <vector> + +#include "base/memory/raw_ref.h" +#include "base/strings/string_piece.h" +#include "base/time/clock.h" +#include "base/time/default_clock.h" +#include "base/time/default_tick_clock.h" +#include "net/base/net_export.h" +#include "net/base/network_anonymization_key.h" +#include "net/dns/public/dns_query_type.h" +#include "net/dns/public/host_resolver_source.h" +#include "third_party/abseil-cpp/absl/types/optional.h" + +namespace net { + +class HostResolverInternalResult; + +// Cache used by HostResolverManager to save previously resolved information. +class NET_EXPORT HostResolverCache final { + public: + explicit HostResolverCache( + const base::Clock& clock = *base::DefaultClock::GetInstance(), + const base::TickClock& tick_clock = + *base::DefaultTickClock::GetInstance()); + ~HostResolverCache(); + + // Move-only. + HostResolverCache(HostResolverCache&&); + HostResolverCache& operator=(HostResolverCache&&); + + // Lookup an active (non-stale) cached result matching the given criteria. If + // `query_type` is `DnsQueryType::UNSPECIFIED`, `source` is + // `HostResolverSource::ANY`, or `secure` is `absl::nullopt`, it is a wildcard + // that can match for any cached parameter of that type. In cases where a + // wildcard lookup leads to multiple matching results, only the most recently + // set result will be returned. Additionally, if a cached result has + // `DnsQueryType::UNSPECIFIED`, it will match for any argument of + // `query_type`. + // + // Returns nullptr on cache miss (no active result matches the given + // criteria). + const HostResolverInternalResult* Lookup( + base::StringPiece domain_name, + const NetworkAnonymizationKey& network_anonymization_key, + DnsQueryType query_type = DnsQueryType::UNSPECIFIED, + HostResolverSource source = HostResolverSource::ANY, + absl::optional<bool> secure = absl::nullopt) const; + + // Sets the result into the cache, replacing any previous result entries that + // would match the same criteria, even if a previous entry would have matched + // more criteria than the new one, e.g. if the previous entry used a wildcard + // `DnsQueryType::UNSPECIFIED`. + void Set(std::unique_ptr<HostResolverInternalResult> result, + const NetworkAnonymizationKey& network_anonymization_key, + HostResolverSource source, + bool secure); + + private: + struct Key { + std::string domain_name; + NetworkAnonymizationKey network_anonymization_key; + }; + + struct KeyRef { + base::StringPiece domain_name; + const NetworkAnonymizationKey& network_anonymization_key; + }; + + // Allow comparing Key to KeyRef to allow refs for entry lookup. + struct KeyComparator { + using is_transparent = void; + + bool operator()(const Key& lhs, const Key& rhs) const { + return std::tie(lhs.domain_name, lhs.network_anonymization_key) < + std::tie(rhs.domain_name, rhs.network_anonymization_key); + } + + bool operator()(const Key& lhs, const KeyRef& rhs) const { + return std::tie(lhs.domain_name, lhs.network_anonymization_key) < + std::tie(rhs.domain_name, rhs.network_anonymization_key); + } + + bool operator()(const KeyRef& lhs, const Key& rhs) const { + return std::tie(lhs.domain_name, lhs.network_anonymization_key) < + std::tie(rhs.domain_name, rhs.network_anonymization_key); + } + }; + + struct Entry { + Entry(std::unique_ptr<HostResolverInternalResult> result, + HostResolverSource source, + bool secure); + ~Entry(); + + Entry(Entry&&); + Entry& operator=(Entry&&); + + std::unique_ptr<HostResolverInternalResult> result; + HostResolverSource source; + bool secure; + }; + + using EntryMap = std::multimap<Key, Entry, KeyComparator>; + + // Get all matching results, from most to least recently added. + std::vector<EntryMap::const_iterator> LookupInternal( + base::StringPiece domain_name, + const NetworkAnonymizationKey& network_anonymization_key, + DnsQueryType query_type, + HostResolverSource source, + absl::optional<bool> secure) const; + + EntryMap entries_; + + raw_ref<const base::Clock> clock_; + raw_ref<const base::TickClock> tick_clock_; +}; + +} // namespace net + +#endif // NET_DNS_HOST_RESOLVER_CACHE_H_
diff --git a/net/dns/host_resolver_cache_unittest.cc b/net/dns/host_resolver_cache_unittest.cc new file mode 100644 index 0000000..ad227eb6 --- /dev/null +++ b/net/dns/host_resolver_cache_unittest.cc
@@ -0,0 +1,981 @@ +// 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 "net/dns/host_resolver_cache.h" + +#include <memory> +#include <string> +#include <vector> + +#include "base/test/simple_test_clock.h" +#include "base/test/simple_test_tick_clock.h" +#include "base/time/time.h" +#include "net/base/connection_endpoint_metadata.h" +#include "net/base/connection_endpoint_metadata_test_util.h" +#include "net/base/ip_address.h" +#include "net/base/ip_endpoint.h" +#include "net/base/net_errors.h" +#include "net/base/network_anonymization_key.h" +#include "net/base/schemeful_site.h" +#include "net/dns/host_resolver_internal_result.h" +#include "net/dns/host_resolver_internal_result_test_util.h" +#include "net/dns/public/dns_query_type.h" +#include "net/dns/public/host_resolver_source.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "url/gurl.h" + +namespace net { + +namespace { + +using ::testing::ElementsAre; +using ::testing::IsEmpty; +using ::testing::Ne; +using ::testing::Optional; +using ::testing::Pair; +using ::testing::Pointee; + +class HostResolverCacheTest : public ::testing::Test { + protected: + base::SimpleTestClock clock_; + base::SimpleTestTickClock tick_clock_; +}; + +TEST_F(HostResolverCacheTest, CacheAResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::vector<IPEndPoint> kEndpoints = { + IPEndPoint(IPAddress(1, 2, 3, 4), /*port=*/0), + IPEndPoint(IPAddress(2, 3, 4, 5), /*port=*/0)}; + auto result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::A, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + auto matcher = Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::A, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl), + kEndpoints)); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::ANY, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/absl::nullopt), + matcher); + + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::SYSTEM, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/true), + nullptr); +} + +TEST_F(HostResolverCacheTest, CacheAaaaResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::vector<IPEndPoint> kEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0), + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(), + /*port=*/0)}; + auto result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + auto matcher = Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl), + kEndpoints)); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::ANY, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/absl::nullopt), + matcher); + + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::SYSTEM, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/true), + nullptr); +} + +TEST_F(HostResolverCacheTest, CacheHttpsResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata> + kMetadatas = { + {2, ConnectionEndpointMetadata({"h2", "h3"}, + /*ech_config_list=*/{}, kName)}, + {1, + ConnectionEndpointMetadata({"h2"}, /*ech_config_list=*/{}, kName)}}; + auto result = std::make_unique<HostResolverInternalMetadataResult>( + kName, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kMetadatas); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + auto matcher = Pointee(ExpectHostResolverInternalMetadataResult( + kName, DnsQueryType::HTTPS, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl), + kMetadatas)); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::ANY, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::DNS, /*secure=*/absl::nullopt), + matcher); + + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::SYSTEM, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::DNS, /*secure=*/true), + nullptr); +} + +// Domain names containing scheme/port are not expected to be handled any +// differently from other domain names. That is, if an entry is cached with +// a domain name containing scheme or port, it can only be looked up using the +// exact same domain name containing scheme and port. Testing the case simply +// because such things were handled differently in a previous version of the +// cache. +TEST_F(HostResolverCacheTest, RespectsSchemeAndPortInName) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kNameWithScheme = "_411._https.foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::string kAlpn1 = "foo"; + auto result1 = std::make_unique<HostResolverInternalMetadataResult>( + kNameWithScheme, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{ + {4, ConnectionEndpointMetadata({kAlpn1}, /*ech_config_list=*/{}, + kNameWithScheme)}}); + + const std::string kNameWithoutScheme = "foo.test"; + const std::string kAlpn2 = "bar"; + auto result2 = std::make_unique<HostResolverInternalMetadataResult>( + kNameWithoutScheme, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + std::multimap<HttpsRecordPriority, ConnectionEndpointMetadata>{ + {7, ConnectionEndpointMetadata({kAlpn2}, /*ech_config_list=*/{}, + kNameWithoutScheme)}}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT(cache.Lookup(kNameWithScheme, anonymization_key), + Pointee(ExpectHostResolverInternalMetadataResult( + kNameWithScheme, DnsQueryType::HTTPS, + HostResolverInternalResult::Source::kDns, + /*expiration_matcher=*/Ne(absl::nullopt), + /*timed_expiration_matcher=*/Ne(absl::nullopt), + ElementsAre(Pair(4, ExpectConnectionEndpointMetadata( + ElementsAre(kAlpn1), IsEmpty(), + kNameWithScheme)))))); + EXPECT_THAT(cache.Lookup(kNameWithoutScheme, anonymization_key), + Pointee(ExpectHostResolverInternalMetadataResult( + kNameWithoutScheme, DnsQueryType::HTTPS, + HostResolverInternalResult::Source::kDns, + /*expiration_matcher=*/Ne(absl::nullopt), + /*timed_expiration_matcher=*/Ne(absl::nullopt), + ElementsAre(Pair(7, ExpectConnectionEndpointMetadata( + ElementsAre(kAlpn2), IsEmpty(), + kNameWithoutScheme)))))); +} + +TEST_F(HostResolverCacheTest, CacheHttpsAliasResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::string kTarget = "target.test"; + auto result = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::HTTPS, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kTarget); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + auto matcher = Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::HTTPS, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl), + kTarget)); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::ANY, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::DNS, /*secure=*/absl::nullopt), + matcher); + + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::SYSTEM, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS, + HostResolverSource::DNS, /*secure=*/true), + nullptr); +} + +TEST_F(HostResolverCacheTest, CacheCnameAliasResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::string kTarget = "target.test"; + + // CNAME results are not typically queried directly, but received as part of + // the results for queries for other query types. Thus except in the weird + // cases where it is queried directly, CNAME results should be cached for the + // queried type (or as a wildcard UNSPECIFIED type), rather than type CNAME. + // Here, test the case where it is cached under the AAAA query type. + auto result = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kTarget); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + auto matcher = Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl), + kTarget)); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::ANY, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/absl::nullopt), + matcher); + + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::SYSTEM, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/true), + nullptr); +} + +TEST_F(HostResolverCacheTest, CacheWildcardAlias) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const std::string kAliasTarget = "target.test"; + const base::TimeDelta kTtl = base::Minutes(2); + auto result = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::UNSPECIFIED, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kAliasTarget); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + auto matcher = Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::UNSPECIFIED, + HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl), + kAliasTarget)); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A), matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::TXT), + matcher); +} + +TEST_F(HostResolverCacheTest, CacheErrorResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + auto result = std::make_unique<HostResolverInternalErrorResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + ERR_NAME_NOT_RESOLVED); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + auto matcher = Pointee(ExpectHostResolverInternalErrorResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), Optional(clock_.Now() + kTtl), + ERR_NAME_NOT_RESOLVED)); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::UNSPECIFIED, + HostResolverSource::DNS, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::ANY, /*secure=*/false), + matcher); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/absl::nullopt), + matcher); + + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::A, + HostResolverSource::DNS, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::SYSTEM, /*secure=*/false), + nullptr); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::DNS, /*secure=*/true), + nullptr); +} + +TEST_F(HostResolverCacheTest, ResultsCanBeUpdated) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::vector<IPEndPoint> kEndpoints1 = { + IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)}; + auto result1 = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kEndpoints1, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + const std::string kName2 = "goo.test"; + auto result2 = std::make_unique<HostResolverInternalDataResult>( + kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kEndpoints1, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT( + cache.Lookup(kName, anonymization_key), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kEndpoints1))); + EXPECT_THAT( + cache.Lookup(kName2, anonymization_key), + Pointee(ExpectHostResolverInternalDataResult( + kName2, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kEndpoints1))); + + const std::vector<IPEndPoint> kEndpoints2 = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(), + /*port=*/0)}; + auto result3 = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kEndpoints2, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT( + cache.Lookup(kName, anonymization_key), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kEndpoints2))); + EXPECT_THAT( + cache.Lookup(kName2, anonymization_key), + Pointee(ExpectHostResolverInternalDataResult( + kName2, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kEndpoints1))); +} + +TEST_F(HostResolverCacheTest, UpdateCanReplaceWildcard) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const std::string kAliasTarget1 = "target1.test"; + const base::TimeDelta kTtl = base::Minutes(2); + auto result1 = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::UNSPECIFIED, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kAliasTarget1); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_NE(cache.Lookup(kName, anonymization_key, DnsQueryType::A), nullptr); + EXPECT_NE(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA), + nullptr); + + const std::string kAliasTarget2 = "target2.test"; + auto result2 = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::A, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kAliasTarget2); + + cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + // After update, because most recent entry is not wildcard, expect lookup to + // only succeed for the specific type. + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::A), + Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::A, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kAliasTarget2))); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA), + nullptr); +} + +TEST_F(HostResolverCacheTest, WildcardUpdateCanReplaceSpecifics) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const std::string kAliasTarget1 = "target1.test"; + const base::TimeDelta kTtl = base::Minutes(2); + auto result1 = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::A, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kAliasTarget1); + const std::string kAliasTarget2 = "target2.test"; + auto result2 = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kAliasTarget2); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::A), + Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::A, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kAliasTarget1))); + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA), + Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kAliasTarget2))); + EXPECT_EQ(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS), + nullptr); + + const std::string kAliasTarget3 = "target3.test"; + auto result3 = std::make_unique<HostResolverInternalAliasResult>( + kName, DnsQueryType::UNSPECIFIED, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kAliasTarget3); + + cache.Set(std::move(result3), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::A), + Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::UNSPECIFIED, + HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kAliasTarget3))); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA), + Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::UNSPECIFIED, + HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kAliasTarget3))); + EXPECT_THAT(cache.Lookup(kName, anonymization_key, DnsQueryType::HTTPS), + Pointee(ExpectHostResolverInternalAliasResult( + kName, DnsQueryType::UNSPECIFIED, + HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kAliasTarget3))); +} + +TEST_F(HostResolverCacheTest, LookupNameIsCanonicalized) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "fOO.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::vector<IPEndPoint> kEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(), + /*port=*/0)}; + auto result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_NE(cache.Lookup("FOO.TEST", anonymization_key), nullptr); +} + +TEST_F(HostResolverCacheTest, LookupIgnoresExpiredResults) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName1 = "foo.test"; + const base::TimeDelta kTtl1 = base::Minutes(2); + const std::vector<IPEndPoint> kEndpoints1 = { + IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)}; + auto result1 = std::make_unique<HostResolverInternalDataResult>( + kName1, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl1, + clock_.Now() + kTtl1, HostResolverInternalResult::Source::kDns, + kEndpoints1, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const std::string kName2 = "bar.test"; + const base::TimeDelta kTtl2 = base::Minutes(4); + const std::vector<IPEndPoint> kEndpoints2 = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(), + /*port=*/0)}; + auto result2 = std::make_unique<HostResolverInternalDataResult>( + kName2, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl2, + clock_.Now() + kTtl2, HostResolverInternalResult::Source::kDns, + kEndpoints2, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result1), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + cache.Set(std::move(result2), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT( + cache.Lookup(kName1, anonymization_key), + Pointee(ExpectHostResolverInternalDataResult( + kName1, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl1), + Optional(clock_.Now() + kTtl1), kEndpoints1))); + EXPECT_THAT( + cache.Lookup(kName2, anonymization_key), + Pointee(ExpectHostResolverInternalDataResult( + kName2, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl2), + Optional(clock_.Now() + kTtl2), kEndpoints2))); + + // Advance time until just before first expiration. Expect both results still + // active. + clock_.Advance(kTtl1 - base::Milliseconds(1)); + tick_clock_.Advance(kTtl1 - base::Milliseconds(1)); + EXPECT_NE(cache.Lookup(kName1, anonymization_key), nullptr); + EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr); + + // Advance time until just after first expiration. Expect first result now + // stale, but second result still valid. + clock_.Advance(base::Milliseconds(2)); + tick_clock_.Advance(base::Milliseconds(2)); + EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr); + EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr); + + // Advance time util just before second expiration. Expect first still stale + // and second still valid. + clock_.Advance(kTtl2 - kTtl1 - base::Milliseconds(2)); + tick_clock_.Advance(kTtl2 - kTtl1 - base::Milliseconds(2)); + EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr); + EXPECT_NE(cache.Lookup(kName2, anonymization_key), nullptr); + + // Advance time to after second expiration. Expect both results now stale. + clock_.Advance(base::Milliseconds(2)); + tick_clock_.Advance(base::Milliseconds(2)); + EXPECT_EQ(cache.Lookup(kName1, anonymization_key), nullptr); + EXPECT_EQ(cache.Lookup(kName2, anonymization_key), nullptr); +} + +TEST_F(HostResolverCacheTest, ExpiredResultsCanBeUpdated) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const std::vector<IPEndPoint> kEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)}; + auto result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Milliseconds(1), + clock_.Now() - base::Milliseconds(1), + HostResolverInternalResult::Source::kDns, kEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + // Expiration before Now, so expect entry to start expired. + EXPECT_EQ(cache.Lookup(kName, anonymization_key), nullptr); + + const base::TimeDelta kTtl = base::Seconds(45); + auto update_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, kEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + cache.Set(std::move(update_result), anonymization_key, + HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_NE(cache.Lookup(kName, anonymization_key), nullptr); + + // Expect entry to still be expirable for new TTL. + clock_.Advance(kTtl + base::Milliseconds(1)); + tick_clock_.Advance(kTtl + base::Milliseconds(1)); + EXPECT_EQ(cache.Lookup(kName, anonymization_key), nullptr); +} + +TEST_F(HostResolverCacheTest, RespectsNetworkAnonymizationKey) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(5); + const std::vector<IPEndPoint> kEndpoints1 = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(), /*port=*/0)}; + auto result1 = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kEndpoints1, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + const std::vector<IPEndPoint> kEndpoints2 = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::10").value(), /*port=*/0)}; + auto result2 = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kEndpoints2, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const SchemefulSite kSite1(GURL("https://site1.test/")); + const auto kNetworkAnonymizationKey1 = + NetworkAnonymizationKey::CreateSameSite(kSite1); + const SchemefulSite kSite2(GURL("https://site2.test/")); + const auto kNetworkAnonymizationKey2 = + NetworkAnonymizationKey::CreateSameSite(kSite2); + + cache.Set(std::move(result1), kNetworkAnonymizationKey1, + HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_NE(cache.Lookup(kName, kNetworkAnonymizationKey1), nullptr); + EXPECT_EQ(cache.Lookup(kName, kNetworkAnonymizationKey2), nullptr); + + cache.Set(std::move(result2), kNetworkAnonymizationKey2, + HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT( + cache.Lookup(kName, kNetworkAnonymizationKey1), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kEndpoints1))); + EXPECT_THAT( + cache.Lookup(kName, kNetworkAnonymizationKey2), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kEndpoints2))); +} + +// Newly added entries are always considered to be the most up-to-date +// information, so if an unexpired entry is updated with an expired entry, the +// entry should now be expired. +TEST_F(HostResolverCacheTest, UpdateToStale) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const std::vector<IPEndPoint> kEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("::1").value(), /*port=*/0)}; + auto result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + base::Hours(2), + clock_.Now() + base::Hours(2), HostResolverInternalResult::Source::kDns, + kEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + cache.Set(std::move(result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + // Expect initial entry to be unexpired. + EXPECT_NE(cache.Lookup(kName, anonymization_key), nullptr); + + auto update_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() - base::Seconds(1), + clock_.Now() - base::Seconds(1), HostResolverInternalResult::Source::kDns, + kEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + cache.Set(std::move(update_result), anonymization_key, + HostResolverSource::DNS, + /*secure=*/false); + + // Expect entry to be expired. + EXPECT_EQ(cache.Lookup(kName, anonymization_key), nullptr); +} + +// If a wildcard lookup matches multiple result entries, all insecure, expect +// lookup to return the most recently set result. +TEST_F(HostResolverCacheTest, PreferMoreRecentInsecureResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::vector<IPEndPoint> kNewEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(), + /*port=*/0)}; + auto new_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kNewEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + const std::vector<IPEndPoint> kOldEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(), + /*port=*/0)}; + auto old_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kOldEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + + cache.Set(std::move(old_result), anonymization_key, + HostResolverSource::SYSTEM, + /*secure=*/false); + cache.Set(std::move(new_result), anonymization_key, HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::ANY, /*secure=*/false), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kNewEndpoints))); + + // Other result still available for more specific lookups. + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::SYSTEM, /*secure=*/false), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kOldEndpoints))); +} + +// If a wildcard lookup matches multiple result entries, all secure, expect +// lookup to return the most recently set result. +TEST_F(HostResolverCacheTest, PreferMoreRecentSecureResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::vector<IPEndPoint> kNewEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(), + /*port=*/0)}; + auto new_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kNewEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + const std::vector<IPEndPoint> kOldEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(), + /*port=*/0)}; + auto old_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kOldEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + + cache.Set(std::move(old_result), anonymization_key, + HostResolverSource::SYSTEM, + /*secure=*/true); + cache.Set(std::move(new_result), anonymization_key, HostResolverSource::DNS, + /*secure=*/true); + + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::ANY, /*secure=*/true), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kNewEndpoints))); + + // Other result still available for more specific lookups. + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::SYSTEM, /*secure=*/true), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kOldEndpoints))); +} + +// If a wildcard lookup matches multiple result entries of mixed secureness, +// expect lookup to return the most recently set secure result. +TEST_F(HostResolverCacheTest, PreferMoreSecureResult) { + HostResolverCache cache(clock_, tick_clock_); + + const std::string kName = "foo.test"; + const base::TimeDelta kTtl = base::Minutes(2); + const std::vector<IPEndPoint> kInsecureEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::4").value(), + /*port=*/0)}; + auto insecure_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kInsecureEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + const std::vector<IPEndPoint> kSecureEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::8").value(), + /*port=*/0)}; + auto secure_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kSecureEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + const std::vector<IPEndPoint> kOldSecureEndpoints = { + IPEndPoint(IPAddress::FromIPLiteral("2001:DB8::7").value(), + /*port=*/0)}; + auto old_secure_result = std::make_unique<HostResolverInternalDataResult>( + kName, DnsQueryType::AAAA, tick_clock_.NowTicks() + kTtl, + clock_.Now() + kTtl, HostResolverInternalResult::Source::kDns, + kOldSecureEndpoints, + /*strings=*/std::vector<std::string>{}, + /*hosts=*/std::vector<HostPortPair>{}); + + const NetworkAnonymizationKey anonymization_key; + + // Add in the secure results first to ensure they're not being selected by + // being the most recently added result. + cache.Set(std::move(old_secure_result), anonymization_key, + HostResolverSource::SYSTEM, + /*secure=*/true); + cache.Set(std::move(secure_result), anonymization_key, + HostResolverSource::DNS, + /*secure=*/true); + cache.Set(std::move(insecure_result), anonymization_key, + HostResolverSource::DNS, + /*secure=*/false); + + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::ANY, /*secure=*/absl::nullopt), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kSecureEndpoints))); + + // Other results still available for more specific lookups. + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::ANY, /*secure=*/false), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kInsecureEndpoints))); + EXPECT_THAT( + cache.Lookup(kName, anonymization_key, DnsQueryType::AAAA, + HostResolverSource::SYSTEM, /*secure=*/absl::nullopt), + Pointee(ExpectHostResolverInternalDataResult( + kName, DnsQueryType::AAAA, HostResolverInternalResult::Source::kDns, + Optional(tick_clock_.NowTicks() + kTtl), + Optional(clock_.Now() + kTtl), kOldSecureEndpoints))); +} + +} // namespace + +} // namespace net
diff --git a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc index 1c8cbed..b83570d3 100644 --- a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc +++ b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.cc
@@ -189,6 +189,8 @@ DEFINE_CROSS_SEQUENCE_CALL_METHOD(ClearDictionaries) DEFINE_CROSS_SEQUENCE_CALL_METHOD(DeleteExpiredDictionaries) DEFINE_CROSS_SEQUENCE_CALL_METHOD(ProcessEviction) + DEFINE_CROSS_SEQUENCE_CALL_METHOD(GetAllDiskCacheKeyTokens) + DEFINE_CROSS_SEQUENCE_CALL_METHOD(DeleteDictionariesByDiskCacheKeyTokens) #undef DEFINE_CROSS_SEQUENCE_CALL_METHOD void UpdateDictionaryLastUsedTime(int64_t primary_key_in_database, @@ -214,6 +216,9 @@ UnguessableTokenSetOrError DeleteExpiredDictionariesImpl(base::Time now); UnguessableTokenSetOrError ProcessEvictionImpl(uint64_t cache_max_size, uint64_t low_watermark); + UnguessableTokenSetOrError GetAllDiskCacheKeyTokensImpl(); + Error DeleteDictionariesByDiskCacheKeyTokensImpl( + const std::set<base::UnguessableToken>& disk_cache_key_tokens); // If a matching dictionary exists, populates 'size_out' and // 'disk_cache_key_out' with the dictionary's respective values and returns @@ -269,6 +274,10 @@ int64_t* total_size_after_eviction_out); // Deletes a dictionary with `primary_key`. Error DeleteDictionaryByPrimaryKey(int64_t primary_key); + // Deletes a dictionary with `disk_cache_key_token` and returns the deleted + // dictionarie's size. + base::expected<uint64_t, Error> DeleteDictionaryByDiskCacheToken( + const base::UnguessableToken& disk_cache_key_token); // Total number of pending last used time update operations (may not match the // size of `pending_last_used_time_updates_`, due to operation coalescing). @@ -962,6 +971,116 @@ return Error::kOk; } +SQLitePersistentSharedDictionaryStore::Error +SQLitePersistentSharedDictionaryStore::Backend:: + DeleteDictionariesByDiskCacheKeyTokensImpl( + const std::set<base::UnguessableToken>& disk_cache_key_tokens) { + if (!InitializeDatabase()) { + return Error::kFailedToInitializeDatabase; + } + + sql::Transaction transaction(db()); + if (!transaction.Begin()) { + return Error::kFailedToBeginTransaction; + } + + base::CheckedNumeric<int64_t> checked_total_dictionary_size; + for (const auto& token : disk_cache_key_tokens) { + base::expected<uint64_t, Error> result = + DeleteDictionaryByDiskCacheToken(token); + if (!result.has_value()) { + return result.error(); + } + checked_total_dictionary_size += result.value(); + } + + int64_t deleted_size = checked_total_dictionary_size.ValueOrDie(); + if (deleted_size != 0u) { + uint64_t total_dictionary_size = 0; + Error error = UpdateTotalDictionarySizeInMetaTable(-deleted_size, + &total_dictionary_size); + if (error != Error::kOk) { + return error; + } + } + + if (!transaction.Commit()) { + return Error::kFailedToCommitTransaction; + } + return Error::kOk; +} + +base::expected<uint64_t, SQLitePersistentSharedDictionaryStore::Error> +SQLitePersistentSharedDictionaryStore::Backend:: + DeleteDictionaryByDiskCacheToken( + const base::UnguessableToken& disk_cache_key_token) { + CHECK(background_task_runner()->RunsTasksInCurrentSequence()); + if (!InitializeDatabase()) { + return base::unexpected(Error::kFailedToInitializeDatabase); + } + static constexpr char kQuery[] = + // clang-format off + "DELETE FROM dictionaries " + "WHERE token_high=? AND token_low=?" + "RETURNING size"; + // clang-format on + + if (!db()->IsSQLValid(kQuery)) { + return base::unexpected(Error::kInvalidSql); + } + + sql::Statement statement(db()->GetCachedStatement(SQL_FROM_HERE, kQuery)); + // There is no `sql::Statement::BindUint64()` method. So we cast to int64_t. + int64_t token_high = + static_cast<int64_t>(disk_cache_key_token.GetHighForSerialization()); + int64_t token_low = + static_cast<int64_t>(disk_cache_key_token.GetLowForSerialization()); + statement.BindInt64(0, token_high); + statement.BindInt64(1, token_low); + + base::CheckedNumeric<uint64_t> checked_size = 0; + while (statement.Step()) { + const size_t size = statement.ColumnInt64(0); + checked_size += size; + } + return base::ok(checked_size.ValueOrDie()); +} + +SQLitePersistentSharedDictionaryStore::UnguessableTokenSetOrError +SQLitePersistentSharedDictionaryStore::Backend::GetAllDiskCacheKeyTokensImpl() { + CHECK(background_task_runner()->RunsTasksInCurrentSequence()); + if (!InitializeDatabase()) { + return base::unexpected(Error::kFailedToInitializeDatabase); + } + + static constexpr char kQuery[] = + // clang-format off + "SELECT " + "id," + "token_high," + "token_low FROM dictionaries " + "ORDER BY id"; + // clang-format on + + if (!db()->IsSQLValid(kQuery)) { + return base::unexpected(Error::kInvalidSql); + } + + sql::Statement statement(db()->GetCachedStatement(SQL_FROM_HERE, kQuery)); + std::vector<base::UnguessableToken> tokens; + while (statement.Step()) { + absl::optional<base::UnguessableToken> disk_cache_key_token = + ToUnguessableToken(statement.ColumnInt64(1), statement.ColumnInt64(2)); + if (!disk_cache_key_token) { + LOG(WARNING) << "Invalid token"; + continue; + } + tokens.emplace_back(*disk_cache_key_token); + } + return base::ok( + std::set<base::UnguessableToken>(tokens.begin(), tokens.end())); +} + void SQLitePersistentSharedDictionaryStore::Backend:: UpdateDictionaryLastUsedTime(int64_t primary_key_in_database, base::Time last_used_time) { @@ -1136,6 +1255,23 @@ cache_max_size, low_watermark); } +void SQLitePersistentSharedDictionaryStore::GetAllDiskCacheKeyTokens( + base::OnceCallback<void(UnguessableTokenSetOrError)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + backend_->GetAllDiskCacheKeyTokens( + WrapCallbackWithWeakPtrCheck(GetWeakPtr(), std::move(callback))); +} + +void SQLitePersistentSharedDictionaryStore:: + DeleteDictionariesByDiskCacheKeyTokens( + std::set<base::UnguessableToken> disk_cache_key_tokens, + base::OnceCallback<void(Error)> callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + backend_->DeleteDictionariesByDiskCacheKeyTokens( + WrapCallbackWithWeakPtrCheck(GetWeakPtr(), std::move(callback)), + std::move(disk_cache_key_tokens)); +} + void SQLitePersistentSharedDictionaryStore::UpdateDictionaryLastUsedTime( int64_t primary_key_in_database, base::Time last_used_time) {
diff --git a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h index 51fb575..775deccac 100644 --- a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h +++ b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store.h
@@ -100,12 +100,14 @@ const uint64_t cache_max_size, const uint64_t low_watermark, base::OnceCallback<void(UnguessableTokenSetOrError)> callback); + void GetAllDiskCacheKeyTokens( + base::OnceCallback<void(UnguessableTokenSetOrError)> callback); + void DeleteDictionariesByDiskCacheKeyTokens( + std::set<base::UnguessableToken> disk_cache_key_tokens, + base::OnceCallback<void(Error)> callback); void UpdateDictionaryLastUsedTime(int64_t primary_key_in_database, base::Time last_used_time); - // TODO(crbug.com/1413922): Add a method for the garbage collection logic of - // SharedDictionaryDiskCache by using `disk_cache_key_token`. - base::WeakPtr<SQLitePersistentSharedDictionaryStore> GetWeakPtr(); private:
diff --git a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc index 8080f798..3f04eeb 100644 --- a/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc +++ b/net/extras/sqlite/sqlite_persistent_shared_dictionary_store_unittest.cc
@@ -221,6 +221,36 @@ return tokens; } + std::set<base::UnguessableToken> GetAllDiskCacheKeyTokens() { + base::RunLoop run_loop; + std::set<base::UnguessableToken> tokens; + store_->GetAllDiskCacheKeyTokens(base::BindLambdaForTesting( + [&](SQLitePersistentSharedDictionaryStore::UnguessableTokenSetOrError + result) { + ASSERT_TRUE(result.has_value()); + tokens = std::move(result.value()); + run_loop.Quit(); + })); + run_loop.Run(); + return tokens; + } + + SQLitePersistentSharedDictionaryStore::Error + DeleteDictionariesByDiskCacheKeyTokens( + std::set<base::UnguessableToken> disk_cache_key_tokens) { + base::RunLoop run_loop; + SQLitePersistentSharedDictionaryStore::Error error_out; + store_->DeleteDictionariesByDiskCacheKeyTokens( + std::move(disk_cache_key_tokens), + base::BindLambdaForTesting( + [&](SQLitePersistentSharedDictionaryStore::Error result_error) { + error_out = result_error; + run_loop.Quit(); + })); + run_loop.Run(); + return error_out; + } + void CorruptDatabaseFile() { // Execute CreateStore(), ClearAllDictionaries() and DestroyStore() to // create a database file. @@ -289,6 +319,8 @@ uint64_t cache_max_size, uint64_t low_watermark, SQLitePersistentSharedDictionaryStore::Error expected_error); + void RunGetAllDiskCacheKeyTokensFailureTest( + SQLitePersistentSharedDictionaryStore::Error expected_error); base::ScopedTempDir temp_dir_; std::unique_ptr<SQLitePersistentSharedDictionaryStore> store_; @@ -927,6 +959,73 @@ SQLitePersistentSharedDictionaryStore::Error::kFailedToGetTotalDictSize); } +void SQLitePersistentSharedDictionaryStoreTest:: + RunGetAllDiskCacheKeyTokensFailureTest( + SQLitePersistentSharedDictionaryStore::Error expected_error) { + CreateStore(); + base::RunLoop run_loop; + store_->GetAllDiskCacheKeyTokens(base::BindLambdaForTesting( + [&](SQLitePersistentSharedDictionaryStore::UnguessableTokenSetOrError + result) { + ASSERT_FALSE(result.has_value()); + EXPECT_EQ(expected_error, result.error()); + run_loop.Quit(); + })); + run_loop.Run(); + DestroyStore(); +} + +TEST_F(SQLitePersistentSharedDictionaryStoreTest, + GetAllDiskCacheKeyTokensErrorDatabaseInitializationFailure) { + CorruptDatabaseFile(); + RunGetAllDiskCacheKeyTokensFailureTest( + SQLitePersistentSharedDictionaryStore::Error:: + kFailedToInitializeDatabase); + CheckStoreRecovered(); +} + +TEST_F(SQLitePersistentSharedDictionaryStoreTest, + GetAllDiskCacheKeyTokensErrorInvalidSql) { + ManipulateDatabase({"CREATE TABLE dictionaries (dummy TEST NOT NULL)"}); + RunGetAllDiskCacheKeyTokensFailureTest( + SQLitePersistentSharedDictionaryStore::Error::kInvalidSql); +} + +TEST_F( + SQLitePersistentSharedDictionaryStoreTest, + DeleteDictionariesByDiskCacheKeyTokensErrorDatabaseInitializationFailure) { + CorruptDatabaseFile(); + CreateStore(); + EXPECT_EQ( + SQLitePersistentSharedDictionaryStore::Error::kFailedToInitializeDatabase, + DeleteDictionariesByDiskCacheKeyTokens( + {dictionary_info_.disk_cache_key_token()})); + DestroyStore(); + CheckStoreRecovered(); +} + +TEST_F(SQLitePersistentSharedDictionaryStoreTest, + DeleteDictionariesByDiskCacheKeyTokensErrorInvalidSql) { + ManipulateDatabase({"CREATE TABLE dictionaries (dummy TEST NOT NULL)"}); + CreateStore(); + EXPECT_EQ(SQLitePersistentSharedDictionaryStore::Error::kInvalidSql, + DeleteDictionariesByDiskCacheKeyTokens( + {dictionary_info_.disk_cache_key_token()})); +} + +TEST_F(SQLitePersistentSharedDictionaryStoreTest, + DeleteDictionariesByDiskCacheKeyTokensErrorFailedToGetTotalDictSize) { + CreateStore(); + RegisterDictionary(isolation_key_, dictionary_info_); + DestroyStore(); + ManipulateDatabase({"DELETE FROM meta WHERE key='total_dict_size'"}); + CreateStore(); + EXPECT_EQ( + SQLitePersistentSharedDictionaryStore::Error::kFailedToGetTotalDictSize, + DeleteDictionariesByDiskCacheKeyTokens( + {dictionary_info_.disk_cache_key_token()})); +} + TEST_F(SQLitePersistentSharedDictionaryStoreTest, InvalidHash) { CreateStore(); auto register_dictionary_result = @@ -1424,6 +1523,137 @@ EXPECT_EQ(0u, GetTotalDictionarySize()); } +TEST_F(SQLitePersistentSharedDictionaryStoreTest, GetAllDiskCacheKeyTokens) { + CreateStore(); + EXPECT_TRUE(GetAllDiskCacheKeyTokens().empty()); + + auto token1 = base::UnguessableToken::Create(); + SharedDictionaryInfo dict1 = SharedDictionaryInfo( + GURL("https://a.example/dict"), + /*response_time=*/base::Time::Now() - base::Seconds(4), + /*expiration*/ base::Seconds(100), "/pattern*", + /*last_used_time*/ base::Time::Now(), + /*size=*/1000, net::SHA256HashValue({{0x00, 0x01}}), + /*disk_cache_key_token=*/token1, + /*primary_key_in_database=*/absl::nullopt); + RegisterDictionary(isolation_key_, dict1); + + EXPECT_THAT(GetAllDiskCacheKeyTokens(), ElementsAreArray({token1})); + + auto token2 = base::UnguessableToken::Create(); + SharedDictionaryInfo dict2 = SharedDictionaryInfo( + GURL("https://b.example/dict"), + /*response_time=*/base::Time::Now() - base::Seconds(3), + /*expiration*/ base::Seconds(100), "/pattern*", + /*last_used_time*/ base::Time::Now(), + /*size=*/3000, net::SHA256HashValue({{0x00, 0x02}}), + /*disk_cache_key_token=*/token2, + /*primary_key_in_database=*/absl::nullopt); + RegisterDictionary(isolation_key_, dict2); + + EXPECT_THAT(GetAllDiskCacheKeyTokens(), + UnorderedElementsAreArray({token1, token2})); +} + +TEST_F(SQLitePersistentSharedDictionaryStoreTest, + DeleteDictionariesByDiskCacheKeyTokens) { + CreateStore(); + EXPECT_TRUE(GetAllDiskCacheKeyTokens().empty()); + + auto token1 = base::UnguessableToken::Create(); + SharedDictionaryInfo dict1 = SharedDictionaryInfo( + GURL("https://a.example/dict"), + /*response_time=*/base::Time::Now() - base::Seconds(4), + /*expiration*/ base::Seconds(100), "/pattern*", + /*last_used_time*/ base::Time::Now(), + /*size=*/1000, net::SHA256HashValue({{0x00, 0x01}}), + /*disk_cache_key_token=*/token1, + /*primary_key_in_database=*/absl::nullopt); + auto result1 = RegisterDictionary(isolation_key_, dict1); + dict1.set_primary_key_in_database(result1.primary_key_in_database); + + EXPECT_THAT(GetAllDiskCacheKeyTokens(), ElementsAreArray({token1})); + + auto token2 = base::UnguessableToken::Create(); + SharedDictionaryInfo dict2 = SharedDictionaryInfo( + GURL("https://b.example/dict"), + /*response_time=*/base::Time::Now() - base::Seconds(3), + /*expiration*/ base::Seconds(100), "/pattern*", + /*last_used_time*/ base::Time::Now(), + /*size=*/3000, net::SHA256HashValue({{0x00, 0x02}}), + /*disk_cache_key_token=*/token2, + /*primary_key_in_database=*/absl::nullopt); + RegisterDictionary(isolation_key_, dict2); + auto result2 = RegisterDictionary(isolation_key_, dict2); + dict2.set_primary_key_in_database(result2.primary_key_in_database); + + auto token3 = base::UnguessableToken::Create(); + SharedDictionaryInfo dict3 = SharedDictionaryInfo( + GURL("https://c.example/dict"), + /*response_time=*/base::Time::Now() - base::Seconds(2), + /*expiration*/ base::Seconds(100), "/pattern*", + /*last_used_time*/ base::Time::Now(), + /*size=*/5000, net::SHA256HashValue({{0x00, 0x03}}), + /*disk_cache_key_token=*/token3, + /*primary_key_in_database=*/absl::nullopt); + auto result3 = RegisterDictionary(isolation_key_, dict3); + dict3.set_primary_key_in_database(result3.primary_key_in_database); + + auto token4 = base::UnguessableToken::Create(); + SharedDictionaryInfo dict4 = SharedDictionaryInfo( + GURL("https://d.example/dict"), + /*response_time=*/base::Time::Now() - base::Seconds(1), + /*expiration*/ base::Seconds(100), "/pattern*", + /*last_used_time*/ base::Time::Now(), + /*size=*/7000, net::SHA256HashValue({{0x00, 0x04}}), + /*disk_cache_key_token=*/token4, + /*primary_key_in_database=*/absl::nullopt); + auto result4 = RegisterDictionary(isolation_key_, dict4); + dict4.set_primary_key_in_database(result4.primary_key_in_database); + + EXPECT_EQ(SQLitePersistentSharedDictionaryStore::Error::kOk, + DeleteDictionariesByDiskCacheKeyTokens({})); + + EXPECT_THAT( + GetAllDictionaries(), + ElementsAre(Pair(isolation_key_, UnorderedElementsAreArray( + {dict1, dict2, dict3, dict4})))); + EXPECT_EQ(16000u, GetTotalDictionarySize()); + + EXPECT_EQ(SQLitePersistentSharedDictionaryStore::Error::kOk, + DeleteDictionariesByDiskCacheKeyTokens({token1})); + + // dict1 must have been deleted. + EXPECT_THAT(GetAllDictionaries(), + ElementsAre(Pair(isolation_key_, UnorderedElementsAreArray( + {dict2, dict3, dict4})))); + EXPECT_EQ(15000u, GetTotalDictionarySize()); + + EXPECT_EQ(SQLitePersistentSharedDictionaryStore::Error::kOk, + DeleteDictionariesByDiskCacheKeyTokens({token2, token3})); + + // dict2 and dict3 must have been deleted. + EXPECT_THAT( + GetAllDictionaries(), + ElementsAre(Pair(isolation_key_, UnorderedElementsAreArray({dict4})))); + EXPECT_EQ(7000u, GetTotalDictionarySize()); + + // Call DeleteDictionariesByDiskCacheKeyTokens() with no-maching token. + EXPECT_EQ(SQLitePersistentSharedDictionaryStore::Error::kOk, + DeleteDictionariesByDiskCacheKeyTokens( + {base::UnguessableToken::Create()})); + EXPECT_THAT( + GetAllDictionaries(), + ElementsAre(Pair(isolation_key_, UnorderedElementsAreArray({dict4})))); + EXPECT_EQ(7000u, GetTotalDictionarySize()); + + EXPECT_EQ(SQLitePersistentSharedDictionaryStore::Error::kOk, + DeleteDictionariesByDiskCacheKeyTokens({token4})); + // dict4 must have been deleted. + EXPECT_TRUE(GetAllDictionaries().empty()); + EXPECT_EQ(0u, GetTotalDictionarySize()); +} + TEST_F(SQLitePersistentSharedDictionaryStoreTest, UpdateDictionaryLastUsedTime) { CreateStore();
diff --git a/net/test/android/javatests/AndroidManifest.xml b/net/test/android/javatests/AndroidManifest.xml index 830392b..e3ad40b6 100644 --- a/net/test/android/javatests/AndroidManifest.xml +++ b/net/test/android/javatests/AndroidManifest.xml
@@ -11,7 +11,8 @@ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.INTERNET"/> - <application android:label="ChromiumNetTestSupport"> + <application android:label="ChromiumNetTestSupport" + android:name="androidx.multidex.MultiDexApplication"> <uses-library android:name="android.test.runner" />
diff --git a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java index 1b560e5..de076f49 100644 --- a/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java +++ b/net/test/android/javatests/src/org/chromium/net/test/EmbeddedTestServer.java
@@ -18,6 +18,8 @@ import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.base.test.BaseJUnit4ClassRunner.ClassHook; +import org.chromium.base.test.util.UrlUtils; import org.chromium.net.X509Util; import org.chromium.net.test.util.CertTestUtil; @@ -525,4 +527,31 @@ throw new EmbeddedTestServerFailure("Failed to get root cert's path", e); } } + + public static ClassHook getPreClassHook() { + return (targetContext, testClass) -> EmbeddedTestServer.setUpClass(testClass); + } + + private static boolean sTestRootInitDone; + + public static void setUpClass(Class<?> clazz) { + if (sTestRootInitDone) { + return; + } + + // Always try to add the testing HTTPS root to the cert verifier. We do this here because we + // need this to happen before the native code loads the user-added roots, and this is the + // safest place to put it. + try { + // Use the same PEM file as net/test/embedded_test_server/embedded_test_server.cc. + String rootCertPemPath = + UrlUtils.getIsolatedTestFilePath("net/data/ssl/certificates/root_ca_cert.pem"); + byte[] rootCertBytesDer = CertTestUtil.pemToDer(rootCertPemPath); + X509Util.setTestRootCertificateForBuiltin(rootCertBytesDer); + sTestRootInitDone = true; + } catch (Exception e) { + throw new EmbeddedTestServer.EmbeddedTestServerFailure( + "Failed to install root certificate.", e); + } + } }
diff --git a/net/tools/dafsa/PRESUBMIT.py b/net/tools/dafsa/PRESUBMIT.py index c4d19db..eb42779 100644 --- a/net/tools/dafsa/PRESUBMIT.py +++ b/net/tools/dafsa/PRESUBMIT.py
@@ -4,10 +4,6 @@ """Chromium presubmit script for src/net/tools/dafsa.""" - -USE_PYTHON3 = True - - def _RunMakeDafsaTests(input_api, output_api): """Runs unittest for make_dafsa if any related file has been modified.""" files = ('net/tools/dafsa/make_dafsa.py',
diff --git a/pdf/test/PRESUBMIT.py b/pdf/test/PRESUBMIT.py index 61f39fb..1b4f70fa 100644 --- a/pdf/test/PRESUBMIT.py +++ b/pdf/test/PRESUBMIT.py
@@ -12,8 +12,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - def CheckChange(input_api, output_api): old_sys_path = sys.path[:] results = []
diff --git a/ppapi/PRESUBMIT.py b/ppapi/PRESUBMIT.py index fb6c01d..a2f9cd5 100644 --- a/ppapi/PRESUBMIT.py +++ b/ppapi/PRESUBMIT.py
@@ -19,10 +19,6 @@ # TODO: Investigate the incompatibility of `input_api.python3_executable` on # Windows, for this particular PRESUBMIT script. - -USE_PYTHON3 = True - - def RunCmdAndCheck(cmd, err_string, output_api, cwd=None, warning=False): results = [] p = subprocess.Popen(cmd, cwd=cwd,
diff --git a/printing/backend/PRESUBMIT.py b/printing/backend/PRESUBMIT.py index c400aabe..3e6f5558 100644 --- a/printing/backend/PRESUBMIT.py +++ b/printing/backend/PRESUBMIT.py
@@ -9,8 +9,6 @@ for more details about the presubmit API. """ -USE_PYTHON3 = True - def _CheckForStringViewFromNullableIppApi(input_api, output_api): """ Looks for all affected lines in CL where one constructs either
diff --git a/printing/test/PRESUBMIT.py b/printing/test/PRESUBMIT.py index 90af259..aa697d88 100644 --- a/printing/test/PRESUBMIT.py +++ b/printing/test/PRESUBMIT.py
@@ -10,8 +10,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - def CheckChange(input_api, output_api): import sys old_sys_path = sys.path[:]
diff --git a/services/network/attribution/attribution_request_helper.cc b/services/network/attribution/attribution_request_helper.cc index 2840de5..2f8cb6b 100644 --- a/services/network/attribution/attribution_request_helper.cc +++ b/services/network/attribution/attribution_request_helper.cc
@@ -32,7 +32,6 @@ #include "services/network/attribution/boringssl_verification_cryptographer.h" #include "services/network/attribution/request_headers_internal.h" #include "services/network/public/cpp/attribution_reporting_runtime_features.h" -#include "services/network/public/cpp/attribution_utils.h" #include "services/network/public/cpp/features.h" #include "services/network/public/cpp/is_potentially_trustworthy.h" #include "services/network/public/cpp/resource_request.h"
diff --git a/services/network/attribution/request_headers_internal.cc b/services/network/attribution/request_headers_internal.cc index ef0049c..57bfc56 100644 --- a/services/network/attribution/request_headers_internal.cc +++ b/services/network/attribution/request_headers_internal.cc
@@ -16,6 +16,7 @@ #include "base/strings/strcat.h" #include "base/types/cxx23_to_underlying.h" #include "net/http/structured_headers.h" +#include "services/network/public/cpp/attribution_utils.h" #include "services/network/public/mojom/attribution.mojom.h" #include "third_party/abseil-cpp/absl/types/optional.h" @@ -28,6 +29,15 @@ using ::network::mojom::AttributionReportingEligibility; +void AddTrueValuedDictMember( + std::vector<net::structured_headers::DictionaryMember>& dict, + std::string key) { + dict.emplace_back(std::move(key), + net::structured_headers::ParameterizedMember( + net::structured_headers::Item(true), + net::structured_headers::Parameters())); +} + } // namespace // static @@ -69,12 +79,6 @@ const char* const kTrigger = "trigger"; std::vector<net::structured_headers::DictionaryMember> eligibilities; - const auto add_eligibility = [&eligibilities](std::string key) { - eligibilities.emplace_back(std::move(key), - net::structured_headers::ParameterizedMember( - net::structured_headers::Item(true), - net::structured_headers::Parameters())); - }; const char* grease1; const char* grease2; @@ -86,23 +90,23 @@ grease2 = kTrigger; break; case AttributionReportingEligibility::kEventSource: - add_eligibility(kEventSource); + AddTrueValuedDictMember(eligibilities, kEventSource); grease1 = kTrigger; grease2 = kNavigationSource; break; case AttributionReportingEligibility::kNavigationSource: - add_eligibility(kNavigationSource); + AddTrueValuedDictMember(eligibilities, kNavigationSource); grease1 = kEventSource; grease2 = kTrigger; break; case AttributionReportingEligibility::kTrigger: - add_eligibility(kTrigger); + AddTrueValuedDictMember(eligibilities, kTrigger); grease1 = kNavigationSource; grease2 = kEventSource; break; case AttributionReportingEligibility::kEventSourceOrTrigger: - add_eligibility(kEventSource); - add_eligibility(kTrigger); + AddTrueValuedDictMember(eligibilities, kEventSource); + AddTrueValuedDictMember(eligibilities, kTrigger); grease1 = kNavigationSource; grease2 = nullptr; break; @@ -135,7 +139,7 @@ case GreaseContext::kNone: break; case GreaseContext::kKey: - add_eligibility(base::StrCat({"not-", grease})); + AddTrueValuedDictMember(eligibilities, base::StrCat({"not-", grease})); break; case GreaseContext::kValue: if (!eligibilities.empty()) { @@ -174,4 +178,22 @@ return std::move(*eligible_header); } +std::string GetAttributionSupportHeader( + mojom::AttributionSupport attribution_support) { + std::vector<net::structured_headers::DictionaryMember> registrars; + + if (HasAttributionOsSupport(attribution_support)) { + AddTrueValuedDictMember(registrars, "os"); + } + if (HasAttributionWebSupport(attribution_support)) { + AddTrueValuedDictMember(registrars, "web"); + } + + absl::optional<std::string> support_header = + net::structured_headers::SerializeDictionary( + net::structured_headers::Dictionary(std::move(registrars))); + DCHECK(support_header.has_value()); + return std::move(*support_header); +} + } // namespace network
diff --git a/services/network/attribution/request_headers_internal.h b/services/network/attribution/request_headers_internal.h index 42a7ed8e..c368feb 100644 --- a/services/network/attribution/request_headers_internal.h +++ b/services/network/attribution/request_headers_internal.h
@@ -51,6 +51,10 @@ mojom::AttributionReportingEligibility, const AttributionReportingEligibleGreaseOptions&); +// Returns the value to be set for the `Attribution-Reporting-Support` request +// header. +std::string GetAttributionSupportHeader(mojom::AttributionSupport); + } // namespace network #endif // SERVICES_NETWORK_ATTRIBUTION_REQUEST_HEADERS_INTERNAL_H_
diff --git a/services/network/attribution/request_headers_internal_unittest.cc b/services/network/attribution/request_headers_internal_unittest.cc index 3f5fa9d..6cbda8c008 100644 --- a/services/network/attribution/request_headers_internal_unittest.cc +++ b/services/network/attribution/request_headers_internal_unittest.cc
@@ -10,8 +10,10 @@ #include <string> #include <vector> +#include "net/http/structured_headers.h" #include "services/network/public/mojom/attribution.mojom.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/abseil-cpp/absl/types/optional.h" namespace network { @@ -289,5 +291,36 @@ } } +TEST(AttributionRequestHeadersTest, GetAttributionSupportHeader) { + const struct { + mojom::AttributionSupport attribution_support; + std::vector<std::string> required_keys; + std::vector<std::string> prohibited_keys; + } kTestCases[] = { + {mojom::AttributionSupport::kWeb, {"web"}, {"os"}}, + {mojom::AttributionSupport::kWebAndOs, {"os", "web"}, {}}, + {mojom::AttributionSupport::kOs, {"os"}, {"web"}}, + {mojom::AttributionSupport::kNone, {}, {"os", "web"}}, + }; + + for (const auto& test_case : kTestCases) { + SCOPED_TRACE(test_case.attribution_support); + + std::string actual = + GetAttributionSupportHeader(test_case.attribution_support); + + auto dict = net::structured_headers::ParseDictionary(actual); + EXPECT_TRUE(dict.has_value()); + + for (const auto& key : test_case.required_keys) { + EXPECT_TRUE(dict->contains(key)) << key; + } + + for (const auto& key : test_case.prohibited_keys) { + EXPECT_FALSE(dict->contains(key)) << key; + } + } +} + } // namespace } // namespace network
diff --git a/services/network/public/cpp/attribution_utils.cc b/services/network/public/cpp/attribution_utils.cc index 1d3a67c..bb0e5a0a 100644 --- a/services/network/public/cpp/attribution_utils.cc +++ b/services/network/public/cpp/attribution_utils.cc
@@ -4,40 +4,10 @@ #include "services/network/public/cpp/attribution_utils.h" -#include <string> -#include <vector> - -#include "base/check.h" -#include "net/http/structured_headers.h" #include "services/network/public/mojom/attribution.mojom.h" -#include "third_party/abseil-cpp/absl/types/optional.h" namespace network { -std::string GetAttributionSupportHeader( - mojom::AttributionSupport attribution_support) { - std::vector<net::structured_headers::DictionaryMember> registrars; - const auto add_registrar = [®istrars](std::string registrar) { - registrars.emplace_back(std::move(registrar), - net::structured_headers::ParameterizedMember( - net::structured_headers::Item(true), - net::structured_headers::Parameters())); - }; - - if (HasAttributionOsSupport(attribution_support)) { - add_registrar("os"); - } - if (HasAttributionWebSupport(attribution_support)) { - add_registrar("web"); - } - - absl::optional<std::string> support_header = - net::structured_headers::SerializeDictionary( - net::structured_headers::Dictionary(std::move(registrars))); - DCHECK(support_header.has_value()); - return std::move(*support_header); -} - bool HasAttributionOsSupport(mojom::AttributionSupport attribution_support) { switch (attribution_support) { case mojom::AttributionSupport::kOs:
diff --git a/services/network/public/cpp/attribution_utils.h b/services/network/public/cpp/attribution_utils.h index eb8afd8..cd1bbe25 100644 --- a/services/network/public/cpp/attribution_utils.h +++ b/services/network/public/cpp/attribution_utils.h
@@ -5,18 +5,11 @@ #ifndef SERVICES_NETWORK_PUBLIC_CPP_ATTRIBUTION_UTILS_H_ #define SERVICES_NETWORK_PUBLIC_CPP_ATTRIBUTION_UTILS_H_ -#include <string> - #include "base/component_export.h" #include "services/network/public/mojom/attribution.mojom-forward.h" namespace network { -// Returns the value to be set for `Attribution-Reporting-Support` request -// header. -COMPONENT_EXPORT(NETWORK_CPP) -std::string GetAttributionSupportHeader(mojom::AttributionSupport); - // Returns whether OS-level attribution is supported. COMPONENT_EXPORT(NETWORK_CPP) bool HasAttributionOsSupport(mojom::AttributionSupport);
diff --git a/services/network/public/cpp/attribution_utils_unittest.cc b/services/network/public/cpp/attribution_utils_unittest.cc index 7bd45e93..a5f9cd0 100644 --- a/services/network/public/cpp/attribution_utils_unittest.cc +++ b/services/network/public/cpp/attribution_utils_unittest.cc
@@ -4,48 +4,12 @@ #include "services/network/public/cpp/attribution_utils.h" -#include <string> -#include <vector> - -#include "net/http/structured_headers.h" #include "services/network/public/mojom/attribution.mojom.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/abseil-cpp/absl/types/optional.h" namespace network { namespace { -TEST(AttributionSupportTest, GetAttributionSupportHeader) { - const struct { - mojom::AttributionSupport attribution_support; - std::vector<std::string> required_keys; - std::vector<std::string> prohibited_keys; - } kTestCases[] = { - {mojom::AttributionSupport::kWeb, {"web"}, {"os"}}, - {mojom::AttributionSupport::kWebAndOs, {"os", "web"}, {}}, - {mojom::AttributionSupport::kOs, {"os"}, {"web"}}, - {mojom::AttributionSupport::kNone, {}, {"os", "web"}}, - }; - - for (const auto& test_case : kTestCases) { - SCOPED_TRACE(test_case.attribution_support); - - std::string actual = - GetAttributionSupportHeader(test_case.attribution_support); - - auto dict = net::structured_headers::ParseDictionary(actual); - EXPECT_TRUE(dict.has_value()); - - for (const auto& key : test_case.required_keys) { - EXPECT_TRUE(dict->contains(key)) << key; - } - - for (const auto& key : test_case.prohibited_keys) { - EXPECT_FALSE(dict->contains(key)) << key; - } - } -} - TEST(AttributionSupportTest, HasAttributionOsSupport) { const struct { mojom::AttributionSupport attribution_support;
diff --git a/services/network/public/mojom/BUILD.gn b/services/network/public/mojom/BUILD.gn index d0437a0d..c3e0684 100644 --- a/services/network/public/mojom/BUILD.gn +++ b/services/network/public/mojom/BUILD.gn
@@ -425,6 +425,7 @@ "network_interface_change_listener.mojom", "network_types.mojom", "no_vary_search.mojom", + "optional_bool.mojom", "parsed_headers.mojom", "referrer_policy.mojom", "request_priority.mojom", @@ -1311,7 +1312,6 @@ "network_service.mojom", "network_service_test.mojom", "oblivious_http_request.mojom", - "optional_bool.mojom", "proxy_lookup_client.mojom", "proxy_resolving_socket.mojom", "reporting_service.mojom",
diff --git a/services/network/public/mojom/url_loader_network_service_observer.mojom b/services/network/public/mojom/url_loader_network_service_observer.mojom index 77e4b6e3..8c85527 100644 --- a/services/network/public/mojom/url_loader_network_service_observer.mojom +++ b/services/network/public/mojom/url_loader_network_service_observer.mojom
@@ -9,6 +9,8 @@ import "mojo/public/mojom/base/unguessable_token.mojom"; import "services/network/public/mojom/cookie_partition_key.mojom"; import "services/network/public/mojom/network_param.mojom"; +import "services/network/public/mojom/optional_bool.mojom"; +import "url/mojom/origin.mojom"; import "url/mojom/url.mojom"; // Loading info. @@ -77,6 +79,30 @@ OnAuthCredentials(AuthCredentials? credentials); }; +// Shared Storage is an origin-keyed storage mechanism where the output is +// carefully guarded to mitigate the risk of cross-site correlation. +// See https://github.com/WICG/shared-storage/blob/main/README.md. +// +// Each type corresponds to one of the Shared Storage setter or deleter +// operations that can be triggered by response headers. +enum SharedStorageOperationType { + kSet = 0, + kAppend = 1, + kDelete = 2, + kClear = 3, +}; + +// Bundles an operation type with any needed parameters for Shared Storage +// setter/deleter operations that can be triggered by response headers. The +// raw structured headers are parsed into an array of this struct, then sent to +// the browser process. +struct SharedStorageOperation { + SharedStorageOperationType type; + string? key; + string? value; + OptionalBool ignore_if_present = kUnset; +}; + // This interface is used by an URLLoaderFactory to provide notification // of authentication and certificate events. This is typically implemented // by a trusted process such as the browser process. @@ -150,6 +176,34 @@ OnDataUseUpdate(int32 network_traffic_annotation_id_hash, int64 recv_bytes, int64 sent_bytes); + // The syntactic parsing of "Shared-Storage-Write" response headers occurs in + // the network service for security and privacy; this method then notifies + // the browser process or other observer implementers that the raw headers + // have been parsed into an array of `SharedStorageOperation` structs. + // + // The order of the operations as listed in the header(s) is preserved, so + // that the browser process (the main implementer of this API) can guarantee + // that it will invoke the corresponding operations in their originally + // specified order. + // + // Note that any structured header list items that are not parsed as valid + // `SharedStorageOperation`s will simply be omitted. Moreover, if the header + // does not parse as a valid structured header list, or if the parsed list is + // empty, then this method will not be invoked. + // + // Unlike with calls to Shared Storage from the renderer, we don't check the + // the length requirements for keys and values using mojom traits, in order + // to avoid a dependency on blink. Instead, we must check these lengths in + // the implementation (e.g. in the browser process) before invoking the + // actual Shared Storage operations. + // + // TODO(crbug.com/1434529): Make the `OnSharedStorageHeaderReceived()` call + // synchronous so that we can guarantee that order is preserved between calls + // triggered by response headers and Shared Storage calls from the same + // renderer process where this request originated. + OnSharedStorageHeaderReceived(url.mojom.Origin request_origin, + array<SharedStorageOperation> operations) => (); + // Used by the NetworkService to create a copy of this observer. // (e.g. when creating an observer for URLLoader from URLLoaderFactory's // observer).
diff --git a/services/network/shared_dictionary/shared_dictionary_disk_cache.cc b/services/network/shared_dictionary/shared_dictionary_disk_cache.cc index ee560c0d..6bfcf2ea 100644 --- a/services/network/shared_dictionary/shared_dictionary_disk_cache.cc +++ b/services/network/shared_dictionary/shared_dictionary_disk_cache.cc
@@ -160,6 +160,32 @@ } } +void SharedDictionaryDiskCache::CreateIterator( + base::OnceCallback<void(std::unique_ptr<disk_cache::Backend::Iterator>)> + callback) { + switch (state_) { + case State::kBeforeInitialize: + NOTREACHED(); + return; + case State::kInitializing: + // It is safe to use Unretained() below because + // `pending_disk_cache_tasks_` is owned by `this` and the passed task + // `SharedDictionaryDiskCache::CreateIterator()` will be called only when + // `this` is available. + pending_disk_cache_tasks_.push_back( + base::BindOnce(&SharedDictionaryDiskCache::CreateIterator, + base::Unretained(this), std::move(callback))); + return; + case State::kInitialized: + DCHECK(backend_); + std::move(callback).Run(backend_->CreateIterator()); + return; + case State::kFailed: + std::move(callback).Run(nullptr); + return; + } +} + void SharedDictionaryDiskCache::DidCreateBackend( disk_cache::BackendResult result) { if (result.net_error != net::OK) {
diff --git a/services/network/shared_dictionary/shared_dictionary_disk_cache.h b/services/network/shared_dictionary/shared_dictionary_disk_cache.h index 623ad2f..2f50fd0 100644 --- a/services/network/shared_dictionary/shared_dictionary_disk_cache.h +++ b/services/network/shared_dictionary/shared_dictionary_disk_cache.h
@@ -50,6 +50,8 @@ disk_cache::EntryResultCallback callback); int DoomEntry(const std::string& key, net::CompletionOnceCallback callback); int ClearAll(net::CompletionOnceCallback callback); + void CreateIterator( + base::OnceCallback<void(std::unique_ptr<disk_cache::Backend::Iterator>)>); base::WeakPtr<SharedDictionaryDiskCache> GetWeakPtr() { return weak_factory_.GetWeakPtr();
diff --git a/services/network/shared_dictionary/shared_dictionary_disk_cache_unittest.cc b/services/network/shared_dictionary/shared_dictionary_disk_cache_unittest.cc index 5e54590..811446e 100644 --- a/services/network/shared_dictionary/shared_dictionary_disk_cache_unittest.cc +++ b/services/network/shared_dictionary/shared_dictionary_disk_cache_unittest.cc
@@ -203,6 +203,34 @@ EXPECT_EQ(net::ERR_FAILED, OpenEntry(disk_cache.get(), kTestKey).net_error()); } +TEST_F(SharedDictionaryDiskCacheTest, CreateIterator) { + PrepareDiskCacheWithTestData(); + + std::unique_ptr<SharedDictionaryDiskCache> disk_cache = CreateDiskCache(); + FlushCacheTasks(); + + std::unique_ptr<disk_cache::Backend::Iterator> iterator; + disk_cache->CreateIterator(base::BindLambdaForTesting( + [&](std::unique_ptr<disk_cache::Backend::Iterator> it) { + iterator = std::move(it); + })); + EXPECT_TRUE(iterator); +} + +TEST_F(SharedDictionaryDiskCacheTest, CreateIteratorWhileInitializing) { + PrepareDiskCacheWithTestData(); + + std::unique_ptr<SharedDictionaryDiskCache> disk_cache = CreateDiskCache(); + std::unique_ptr<disk_cache::Backend::Iterator> iterator; + disk_cache->CreateIterator(base::BindLambdaForTesting( + [&](std::unique_ptr<disk_cache::Backend::Iterator> it) { + iterator = std::move(it); + })); + EXPECT_FALSE(iterator); + FlushCacheTasks(); + EXPECT_TRUE(iterator); +} + TEST_F(SharedDictionaryDiskCacheTest, CreateWriteOpenReadDeleteReopen) { std::unique_ptr<SharedDictionaryDiskCache> disk_cache = CreateDiskCache(); @@ -311,6 +339,38 @@ EXPECT_EQ(net::ERR_FAILED, ClearAll(disk_cache.get())); } +TEST_F(SharedDictionaryDiskCacheTest, CreateIteratorCorruptedFailure) { + CorruptDiskCache(); + + std::unique_ptr<SharedDictionaryDiskCache> disk_cache = CreateDiskCache(); + FlushCacheTasks(); + + bool callback_called = false; + disk_cache->CreateIterator(base::BindLambdaForTesting( + [&](std::unique_ptr<disk_cache::Backend::Iterator> it) { + ASSERT_FALSE(it); + callback_called = true; + })); + EXPECT_TRUE(callback_called); +} + +TEST_F(SharedDictionaryDiskCacheTest, + CreateIteratorCorruptedFailureWhileInitializing) { + CorruptDiskCache(); + + std::unique_ptr<SharedDictionaryDiskCache> disk_cache = CreateDiskCache(); + + bool callback_called = false; + disk_cache->CreateIterator(base::BindLambdaForTesting( + [&](std::unique_ptr<disk_cache::Backend::Iterator> it) { + ASSERT_FALSE(it); + callback_called = true; + })); + EXPECT_FALSE(callback_called); + FlushCacheTasks(); + EXPECT_TRUE(callback_called); +} + TEST_F(SharedDictionaryDiskCacheTest, DeletedWhileRuningDidCreateBackend) { // Corrupt the disk cache so that the callback is called synchronously. CorruptDiskCache();
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc index 720d343..1256483 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc +++ b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc
@@ -4,14 +4,32 @@ #include "services/network/shared_dictionary/shared_dictionary_manager_on_disk.h" +#include "base/containers/contains.h" #include "base/functional/callback_helpers.h" +#include "base/memory/raw_ptr.h" #include "base/metrics/histogram_functions.h" #include "base/notreached.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" +#include "base/token.h" +#include "base/unguessable_token.h" +#include "net/base/net_errors.h" +#include "net/disk_cache/disk_cache.h" #include "services/network/shared_dictionary/shared_dictionary_storage_on_disk.h" namespace network { +namespace { + +absl::optional<base::UnguessableToken> DeserializeToUnguessableToken( + const std::string& token_string) { + absl::optional<base::Token> token = base::Token::FromString(token_string); + if (!token) { + return absl::nullopt; + } + return base::UnguessableToken::Deserialize(token->high(), token->low()); +} + +} // namespace class SharedDictionaryManagerOnDisk::ClearDataTask : public SharedDictionaryManagerOnDisk::SerializedTask { @@ -43,7 +61,8 @@ net::SQLitePersistentSharedDictionaryStore::UnguessableTokenSetOrError result) { if (result.has_value()) { - manager_->OnDictionaryDeletedFromDatabase(result.value()); + manager_->OnDictionaryDeleted(result.value(), + /*need_to_doom_disk_cache_entries=*/true); } std::move(callback_).Run(); manager_->OnFinishSerializedTask(); @@ -87,6 +106,136 @@ base::OnceClosure callback_; }; +class SharedDictionaryManagerOnDisk::MismatchingEntryDeletionTask + : public SharedDictionaryManagerOnDisk::SerializedTask { + public: + explicit MismatchingEntryDeletionTask( + raw_ptr<SharedDictionaryManagerOnDisk> manager) + : manager_(manager) {} + ~MismatchingEntryDeletionTask() override = default; + MismatchingEntryDeletionTask(const MismatchingEntryDeletionTask&) = delete; + MismatchingEntryDeletionTask& operator=(const MismatchingEntryDeletionTask&) = + delete; + + void Start() override { + // 1) Get the disk cache key tokens currently being written by the manager. + writing_disk_cache_key_tokens_ = manager_->writing_disk_cache_key_tokens(); + // 2) Get the all disk cache key tokens in the metadata store. + manager_->metadata_store().GetAllDiskCacheKeyTokens(BindOnce( + &MismatchingEntryDeletionTask::OnAllDiskCacheKeyTokensInDatabase, + weak_factory_.GetWeakPtr())); + } + + private: + void OnAllDiskCacheKeyTokensInDatabase( + net::SQLitePersistentSharedDictionaryStore::UnguessableTokenSetOrError + result) { + if (!result.has_value()) { + manager_->OnFinishSerializedTask(); + return; + } + disk_cache_key_tokens_ = std::move(result.value()); + + // 3) Get the iterator of the disk cache. + manager_->disk_cache().CreateIterator( + BindOnce(&MismatchingEntryDeletionTask::OnDiskCacheIterator, + weak_factory_.GetWeakPtr())); + } + void OnDiskCacheIterator( + std::unique_ptr<disk_cache::Backend::Iterator> disk_cache_iterator) { + if (!disk_cache_iterator) { + manager_->OnFinishSerializedTask(); + return; + } + disk_cache_iterator_ = std::move(disk_cache_iterator); + OpenNextEntry(); + } + + void OpenNextEntry() { + auto split_callback = base::SplitOnceCallback( + base::BindOnce(&MismatchingEntryDeletionTask::OnDiskCacheEntry, + weak_factory_.GetWeakPtr())); + + // 4) For each disk cache entry, opens the entry. + disk_cache::EntryResult result = + disk_cache_iterator_->OpenNextEntry(std::move(split_callback.first)); + if (result.net_error() != net::ERR_IO_PENDING) { + std::move(split_callback.second).Run(std::move(result)); + } + } + void OnDiskCacheEntry(disk_cache::EntryResult result) { + if (result.net_error() == net::ERR_FAILED) { + // 8) The iteration is complete. + CleanupDatabase(); + return; + } + if (result.net_error() < 0) { + manager_->OnFinishSerializedTask(); + return; + } + disk_cache::ScopedEntryPtr entry(result.ReleaseEntry()); + // 5) Get the disk cache key token of the entry. + absl::optional<base::UnguessableToken> token = + DeserializeToUnguessableToken(entry->GetKey()); + if (!token) { + // 6) If the disk cache entry key is not a valid token, deletes the entry. + entry->Doom(); + } else if (disk_cache_key_tokens_.erase(*token) != 1) { + if (!base::Contains(writing_disk_cache_key_tokens_, *token)) { + // 7) If the disk cache key token is not in the metadata, and is not in + // the set of tokens currently being written by the manager, deletes + // the entry. + entry->Doom(); + } + } + OpenNextEntry(); + } + void CleanupDatabase() { + if (disk_cache_key_tokens_.empty()) { + manager_->OnFinishSerializedTask(); + return; + } + // 9) `disk_cache_key_tokens_` contains the tokens which were in the + // metadata store, but not in the disk cache. + + // 10) Let the manager know such dictionaries are unavailable. + manager_->OnDictionaryDeleted(disk_cache_key_tokens_, + /*need_to_doom_disk_cache_entries=*/false); + + // 11) Deletes such dictionaries from the metadata store. + manager_->metadata_store().DeleteDictionariesByDiskCacheKeyTokens( + std::move(disk_cache_key_tokens_), + base::BindOnce(&MismatchingEntryDeletionTask::CleanupDatabaseDone, + weak_factory_.GetWeakPtr())); + } + void CleanupDatabaseDone( + net::SQLitePersistentSharedDictionaryStore::Error error) { + manager_->OnFinishSerializedTask(); + } + + raw_ptr<SharedDictionaryManagerOnDisk> manager_; + base::OnceCallback<void(int)> callback_; + std::set<base::UnguessableToken> disk_cache_key_tokens_; + std::set<base::UnguessableToken> writing_disk_cache_key_tokens_; + std::unique_ptr<disk_cache::Backend::Iterator> disk_cache_iterator_; + base::WeakPtrFactory<MismatchingEntryDeletionTask> weak_factory_{this}; +}; + +class SharedDictionaryManagerOnDisk::MismatchingEntryDeletionTaskInfo + : public SharedDictionaryManagerOnDisk::SerializedTaskInfo { + public: + MismatchingEntryDeletionTaskInfo() = default; + ~MismatchingEntryDeletionTaskInfo() override = default; + MismatchingEntryDeletionTaskInfo(const MismatchingEntryDeletionTaskInfo&) = + delete; + MismatchingEntryDeletionTaskInfo& operator=( + const MismatchingEntryDeletionTaskInfo&) = delete; + std::unique_ptr<SerializedTask> CreateTask( + SharedDictionaryManagerOnDisk* manager) override { + return std::make_unique<MismatchingEntryDeletionTask>(manager); + } +}; + class SharedDictionaryManagerOnDisk::CacheEvictionTask : public SharedDictionaryManagerOnDisk::SerializedTask { public: @@ -110,7 +259,8 @@ net::SQLitePersistentSharedDictionaryStore::UnguessableTokenSetOrError result) { if (result.has_value()) { - manager_->OnDictionaryDeletedFromDatabase(result.value()); + manager_->OnDictionaryDeleted(result.value(), + /*need_to_doom_disk_cache_entries=*/true); } manager_->OnFinishSerializedTask(); } @@ -165,7 +315,8 @@ net::SQLitePersistentSharedDictionaryStore::UnguessableTokenSetOrError result) { if (result.has_value()) { - manager_->OnDictionaryDeletedFromDatabase(result.value()); + manager_->OnDictionaryDeleted(result.value(), + /*need_to_doom_disk_cache_entries=*/true); } manager_->OnFinishSerializedTask(); } @@ -250,6 +401,7 @@ base::OnceCallback<void(net::SharedDictionaryInfo)> callback) { const base::UnguessableToken disk_cache_key_token = base::UnguessableToken::Create(); + CHECK(writing_disk_cache_key_tokens_.insert(disk_cache_key_token).second); auto writer = base::MakeRefCounted<SharedDictionaryWriterOnDisk>( disk_cache_key_token, base::BindOnce( @@ -273,6 +425,7 @@ size_t size, const net::SHA256HashValue& hash) { if (result != SharedDictionaryWriterOnDisk::Result::kSuccess) { + CHECK(writing_disk_cache_key_tokens_.erase(disk_cache_key_token) == 1); return; } base::Time last_used_time = base::Time::Now(); @@ -292,6 +445,7 @@ base::OnceCallback<void(net::SharedDictionaryInfo)> callback, net::SQLitePersistentSharedDictionaryStore::RegisterDictionaryResultOrError result) { + CHECK(writing_disk_cache_key_tokens_.erase(info.disk_cache_key_token()) == 1); if (!result.has_value()) { disk_cache_.DoomEntry(info.disk_cache_key_token().ToString(), base::DoNothing()); @@ -336,6 +490,7 @@ start_time, end_time, std::move(url_matcher), std::move(callback))); MaybePostExpiredDictionaryDeletionTask(); MaybePostCacheEvictionTask(); + MaybePostMismatchingEntryDeletionTask(); } void SharedDictionaryManagerOnDisk::PostSerializedTask( @@ -361,10 +516,13 @@ running_serialized_task_->Start(); } -void SharedDictionaryManagerOnDisk::OnDictionaryDeletedFromDatabase( - const std::set<base::UnguessableToken>& disk_cache_key_tokens) { - for (const base::UnguessableToken& token : disk_cache_key_tokens) { - disk_cache().DoomEntry(token.ToString(), base::DoNothing()); +void SharedDictionaryManagerOnDisk::OnDictionaryDeleted( + const std::set<base::UnguessableToken>& disk_cache_key_tokens, + bool need_to_doom_disk_cache_entries) { + if (need_to_doom_disk_cache_entries) { + for (const base::UnguessableToken& token : disk_cache_key_tokens) { + disk_cache().DoomEntry(token.ToString(), base::DoNothing()); + } } for (auto& it : storages()) { reinterpret_cast<SharedDictionaryStorageOnDisk*>(it.second.get()) @@ -372,6 +530,17 @@ } } +void SharedDictionaryManagerOnDisk::MaybePostMismatchingEntryDeletionTask() { + // MismatchingEntryDeletionTask is intended to resolve the mismatch between + // the disk cache and metadata database. We run MismatchingEntryDeletionTask + // when ClearData() is called for the first time. + if (mismatching_entry_deletion_task_posted_) { + return; + } + mismatching_entry_deletion_task_posted_ = true; + PostSerializedTask(std::make_unique<MismatchingEntryDeletionTaskInfo>()); +} + void SharedDictionaryManagerOnDisk::MaybePostCacheEvictionTask() { if (cache_eviction_task_queued_ || cache_max_size_ == 0) { return;
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h index e97faa0..11f91e8 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h +++ b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h
@@ -92,10 +92,12 @@ }; class ClearDataTask; + class MismatchingEntryDeletionTask; class CacheEvictionTask; class ExpiredDictionaryDeletionTask; class ClearDataTaskInfo; + class MismatchingEntryDeletionTaskInfo; class CacheEvictionTaskInfo; class ExpiredDictionaryDeletionTaskInfo; @@ -121,11 +123,18 @@ void OnFinishSerializedTask(); void MaybeStartSerializedTask(); + void MaybePostMismatchingEntryDeletionTask(); void MaybePostCacheEvictionTask(); void MaybePostExpiredDictionaryDeletionTask(); - void OnDictionaryDeletedFromDatabase( - const std::set<base::UnguessableToken>& disk_cache_key_tokens); + void OnDictionaryDeleted( + const std::set<base::UnguessableToken>& disk_cache_key_tokens, + bool need_to_doom_disk_cache_entries); + + const std::set<base::UnguessableToken>& writing_disk_cache_key_tokens() + const { + return writing_disk_cache_key_tokens_; + } uint64_t cache_max_size() const { return cache_max_size_; } @@ -136,6 +145,9 @@ std::unique_ptr<SerializedTask> running_serialized_task_; std::deque<std::unique_ptr<SerializedTaskInfo>> pending_serialized_task_info_; + std::set<base::UnguessableToken> writing_disk_cache_key_tokens_; + + bool mismatching_entry_deletion_task_posted_ = false; bool cache_eviction_task_queued_ = false; bool expired_entry_deletion_task_queued_ = false;
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc b/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc index 774e209..229bc0b 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc +++ b/services/network/shared_dictionary/shared_dictionary_manager_on_disk_unittest.cc
@@ -85,16 +85,59 @@ } bool DiskCacheEntryExists(SharedDictionaryManager* manager, - const base::UnguessableToken& disk_cache_key_token) { + const std::string& disk_cache_key) { TestEntryResultCompletionCallback open_callback; disk_cache::EntryResult open_result = open_callback.GetResult( static_cast<SharedDictionaryManagerOnDisk*>(manager) ->disk_cache() - .OpenOrCreateEntry(disk_cache_key_token.ToString(), + .OpenOrCreateEntry(disk_cache_key, /*create=*/false, open_callback.callback())); return open_result.net_error() == net::OK; } +bool DiskCacheEntryExists(SharedDictionaryManager* manager, + const base::UnguessableToken& disk_cache_key_token) { + return DiskCacheEntryExists(manager, disk_cache_key_token.ToString()); +} + +void DoomDiskCacheEntry(SharedDictionaryManager* manager, + const base::UnguessableToken& disk_cache_key_token) { + net::TestCompletionCallback doom_callback; + EXPECT_EQ(net::OK, doom_callback.GetResult( + static_cast<SharedDictionaryManagerOnDisk*>(manager) + ->disk_cache() + .DoomEntry(disk_cache_key_token.ToString(), + doom_callback.callback()))); +} + +void WriteDiskCacheEntry(SharedDictionaryManager* manager, + const std::string& disk_cache_key, + const std::string& data) { + SharedDictionaryDiskCache& disk_cache = + static_cast<SharedDictionaryManagerOnDisk*>(manager)->disk_cache(); + + TestEntryResultCompletionCallback create_callback; + + // Create the entry. + disk_cache::EntryResult create_result = + create_callback.GetResult(disk_cache.OpenOrCreateEntry( + disk_cache_key, /*create=*/true, create_callback.callback())); + EXPECT_EQ(net::OK, create_result.net_error()); + disk_cache::ScopedEntryPtr created_entry; + created_entry.reset(create_result.ReleaseEntry()); + ASSERT_TRUE(created_entry); + + // Write to the entry. + scoped_refptr<net::StringIOBuffer> write_buffer = + base::MakeRefCounted<net::StringIOBuffer>(data); + net::TestCompletionCallback write_callback; + EXPECT_EQ( + base::checked_cast<int>(data.size()), + write_callback.GetResult(created_entry->WriteData( + /*index=*/1, /*offset=*/0, write_buffer.get(), write_buffer->size(), + write_callback.callback(), /*truncate=*/false))); +} + base::UnguessableToken GetDiskCacheKeyTokenOfFirstDictionary( const std::map<url::SchemeHostPort, std::map<std::string, net::SharedDictionaryInfo>>& @@ -1161,4 +1204,208 @@ EXPECT_TRUE(DiskCacheEntryExists(manager.get(), token4)); } +TEST_F(SharedDictionaryManagerOnDiskTest, + MismatchingEntryDeletionMetadataUnavailableDictionary) { + const base::UnguessableToken token = base::UnguessableToken::Create(); + const std::string entry_key = token.ToString(); + const std::string kTestData = "Hello world"; + std::unique_ptr<SharedDictionaryManager> manager = + CreateSharedDictionaryManager(); + + WriteDiskCacheEntry(manager.get(), entry_key, kTestData); + EXPECT_TRUE(DiskCacheEntryExists(manager.get(), entry_key)); + + base::RunLoop run_loop; + manager->ClearData( + base::Time::Now() - base::Days(2), base::Time::Now() - base::Days(1), + base::RepeatingCallback<bool(const GURL&)>(), run_loop.QuitClosure()); + run_loop.Run(); + + EXPECT_TRUE(DiskCacheEntryExists(manager.get(), entry_key)); + task_environment_.RunUntilIdle(); + EXPECT_FALSE(DiskCacheEntryExists(manager.get(), entry_key)); +} + +TEST_F(SharedDictionaryManagerOnDiskTest, + MismatchingEntryDeletionInvalidDiskCacheEntry) { + const std::string kTestKey = "test"; + const std::string kTestData = "Hello world"; + std::unique_ptr<SharedDictionaryManager> manager = + CreateSharedDictionaryManager(); + + WriteDiskCacheEntry(manager.get(), kTestKey, kTestData); + EXPECT_TRUE(DiskCacheEntryExists(manager.get(), kTestKey)); + + base::RunLoop run_loop; + manager->ClearData( + base::Time::Now() - base::Days(2), base::Time::Now() - base::Days(1), + base::RepeatingCallback<bool(const GURL&)>(), run_loop.QuitClosure()); + run_loop.Run(); + + EXPECT_TRUE(DiskCacheEntryExists(manager.get(), kTestKey)); + task_environment_.RunUntilIdle(); + EXPECT_FALSE(DiskCacheEntryExists(manager.get(), kTestKey)); +} + +TEST_F(SharedDictionaryManagerOnDiskTest, + MismatchingEntryDeletionDiskCacheEntryUnavailableDictionary) { + net::SharedDictionaryStorageIsolationKey isolation_key( + url::Origin::Create(kUrl), kSite); + { + std::unique_ptr<SharedDictionaryManager> manager = + CreateSharedDictionaryManager(); + scoped_refptr<SharedDictionaryStorage> storage = + manager->GetStorage(isolation_key); + ASSERT_TRUE(storage); + WriteDictionary(storage.get(), GURL("https://target1.test/d"), "p*", + kTestData1); + // FlushCacheTasks() to finish the persistence operation. + FlushCacheTasks(); + + const auto& dictionary_map = GetOnDiskDictionaryMap(storage.get()); + EXPECT_THAT(dictionary_map, + ElementsAre(Pair( + url::SchemeHostPort(GURL("https://target1.test/")), + ElementsAre(Pair( + "/p*", DictionaryUrlIs("https://target1.test/d")))))); + + DoomDiskCacheEntry(manager.get(), + GetDiskCacheKeyTokenOfFirstDictionary( + dictionary_map, "https://target1.test/")); + + base::RunLoop run_loop; + manager->ClearData( + base::Time::Now() - base::Days(2), base::Time::Now() - base::Days(1), + base::RepeatingCallback<bool(const GURL&)>(), run_loop.QuitClosure()); + run_loop.Run(); + + EXPECT_FALSE(GetOnDiskDictionaryMap(storage.get()).empty()); + + task_environment_.RunUntilIdle(); + + EXPECT_TRUE(GetOnDiskDictionaryMap(storage.get()).empty()); + // Releasing `storage` and `manager`. + } + // FlushCacheTasks() to finish the persistence operation. + FlushCacheTasks(); + + std::unique_ptr<SharedDictionaryManager> manager = + CreateSharedDictionaryManager(); + scoped_refptr<SharedDictionaryStorage> storage = + manager->GetStorage(isolation_key); + ASSERT_TRUE(storage); + + // RunUntilIdle() to load from the database. + task_environment_.RunUntilIdle(); + + // The storage must be empty. + EXPECT_TRUE(GetOnDiskDictionaryMap(storage.get()).empty()); +} + +TEST_F(SharedDictionaryManagerOnDiskTest, + MismatchingEntryDeletionCanBeTriggeredOnlyOnce) { + std::unique_ptr<SharedDictionaryManager> manager = + CreateSharedDictionaryManager(); + // Calls ClearData() to trigger MismatchingEntryDeletionTask. + base::RunLoop run_loop1; + manager->ClearData( + base::Time::Now() - base::Days(2), base::Time::Now() - base::Days(1), + base::RepeatingCallback<bool(const GURL&)>(), run_loop1.QuitClosure()); + run_loop1.Run(); + task_environment_.RunUntilIdle(); + + const base::UnguessableToken token = base::UnguessableToken::Create(); + const std::string entry_key = token.ToString(); + const std::string kTestData = "Hello world"; + + WriteDiskCacheEntry(manager.get(), entry_key, kTestData); + EXPECT_TRUE(DiskCacheEntryExists(manager.get(), entry_key)); + + base::RunLoop run_loop2; + manager->ClearData( + base::Time::Now() - base::Days(2), base::Time::Now() - base::Days(1), + base::RepeatingCallback<bool(const GURL&)>(), run_loop2.QuitClosure()); + run_loop2.Run(); + + EXPECT_TRUE(DiskCacheEntryExists(manager.get(), entry_key)); + task_environment_.RunUntilIdle(); + // MismatchingEntryDeletionTask can be triggered only once. So the disk cache + // entry should not be deleted. + EXPECT_TRUE(DiskCacheEntryExists(manager.get(), entry_key)); +} + +TEST_F(SharedDictionaryManagerOnDiskTest, + MismatchingEntryDeletionWritingEntryMustNotBeDeleted) { + net::SharedDictionaryStorageIsolationKey isolation_key( + url::Origin::Create(kUrl), kSite); + std::unique_ptr<SharedDictionaryManager> manager = + CreateSharedDictionaryManager(); + scoped_refptr<SharedDictionaryStorage> storage = + manager->GetStorage(isolation_key); + ASSERT_TRUE(storage); + + // Start writing a dictionary. + scoped_refptr<net::HttpResponseHeaders> headers = + net::HttpResponseHeaders::TryToCreate(base::StrCat( + {"HTTP/1.1 200 OK\n", shared_dictionary::kUseAsDictionaryHeaderName, + ": match=\"/p*\"\n\n"})); + ASSERT_TRUE(headers); + scoped_refptr<SharedDictionaryWriter> writer = storage->MaybeCreateWriter( + GURL("https://target1.test/d"), base::Time::Now(), *headers); + ASSERT_TRUE(writer); + writer->Append(kTestData1.c_str(), kTestData1.size()); + + base::RunLoop run_loop; + manager->ClearData( + base::Time::Now() - base::Days(2), base::Time::Now() - base::Days(1), + base::RepeatingCallback<bool(const GURL&)>(), run_loop.QuitClosure()); + run_loop.Run(); + + // FlushCacheTasks() to finish the persistence operation. + FlushCacheTasks(); + + // Finish writing the dictionary. + writer->Finish(); + + // FlushCacheTasks() to finish the persistence operation. + FlushCacheTasks(); + + const auto& dictionary_map = GetOnDiskDictionaryMap(storage.get()); + EXPECT_THAT(dictionary_map, + ElementsAre(Pair( + url::SchemeHostPort(GURL("https://target1.test/")), + ElementsAre(Pair( + "/p*", DictionaryUrlIs("https://target1.test/d")))))); +} + +TEST_F(SharedDictionaryManagerOnDiskTest, + MismatchingEntryDeletionWritingDiskCacheEntryMustNotBeDeleted) { + net::SharedDictionaryStorageIsolationKey isolation_key( + url::Origin::Create(kUrl), kSite); + std::unique_ptr<SharedDictionaryManager> manager = + CreateSharedDictionaryManager(); + scoped_refptr<SharedDictionaryStorage> storage = + manager->GetStorage(isolation_key); + ASSERT_TRUE(storage); + // Write a dictionary. + WriteDictionary(storage.get(), GURL("https://target1.test/d"), "p*", + kTestData1); + // But do not call FlushCacheTasks() to keep writing the disk cache entry. + base::RunLoop run_loop; + manager->ClearData( + base::Time::Now() - base::Days(2), base::Time::Now() - base::Days(1), + base::RepeatingCallback<bool(const GURL&)>(), run_loop.QuitClosure()); + run_loop.Run(); + + // FlushCacheTasks() to finish the persistence operation. + FlushCacheTasks(); + + const auto& dictionary_map = GetOnDiskDictionaryMap(storage.get()); + EXPECT_THAT(dictionary_map, + ElementsAre(Pair( + url::SchemeHostPort(GURL("https://target1.test/")), + ElementsAre(Pair( + "/p*", DictionaryUrlIs("https://target1.test/d")))))); +} + } // namespace network
diff --git a/services/network/test/test_url_loader_network_observer.cc b/services/network/test/test_url_loader_network_observer.cc index 66f31a00..ad2971a 100644 --- a/services/network/test/test_url_loader_network_observer.cc +++ b/services/network/test/test_url_loader_network_observer.cc
@@ -64,6 +64,13 @@ int64_t recv_bytes, int64_t sent_bytes) {} +void TestURLLoaderNetworkObserver::OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) { + std::move(callback).Run(); +} + void TestURLLoaderNetworkObserver::Clone( mojo::PendingReceiver<URLLoaderNetworkServiceObserver> observer) { receivers_.Add(this, std::move(observer));
diff --git a/services/network/test/test_url_loader_network_observer.h b/services/network/test/test_url_loader_network_observer.h index 7b6a2ff..262473c 100644 --- a/services/network/test/test_url_loader_network_observer.h +++ b/services/network/test/test_url_loader_network_observer.h
@@ -58,6 +58,10 @@ void OnDataUseUpdate(int32_t network_traffic_annotation_id_hash, int64_t recv_bytes, int64_t sent_bytes) override; + void OnSharedStorageHeaderReceived( + const url::Origin& request_origin, + std::vector<network::mojom::SharedStorageOperationPtr> operations, + OnSharedStorageHeaderReceivedCallback callback) override; void Clone( mojo::PendingReceiver<URLLoaderNetworkServiceObserver> observer) override;
diff --git a/services/viz/PRESUBMIT.py b/services/viz/PRESUBMIT.py index 299e3aa..367bddd 100644 --- a/services/viz/PRESUBMIT.py +++ b/services/viz/PRESUBMIT.py
@@ -4,9 +4,6 @@ """Top-level presubmit script for services/viz.""" -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): import sys original_sys_path = sys.path
diff --git a/services/webnn/dml/command_queue_test.cc b/services/webnn/dml/command_queue_test.cc index 92fee72..3712972 100644 --- a/services/webnn/dml/command_queue_test.cc +++ b/services/webnn/dml/command_queue_test.cc
@@ -27,12 +27,8 @@ }; void WebNNCommandQueueTest::SetUp() { - TestBase::SetUp(); - // Skip all tests for this fixture. - if (!display_) { - return; - } - + SKIP_TEST_IF(!UseGPUInTests()); + ASSERT_TRUE(InitializeGLDisplay()); ComPtr<ID3D11Device> d3d11_device = gl::QueryD3D11DeviceObjectFromANGLE(); ASSERT_NE(d3d11_device.Get(), nullptr); ComPtr<IDXGIDevice> dxgi_device;
diff --git a/services/webnn/dml/command_recorder_test.cc b/services/webnn/dml/command_recorder_test.cc index d2bd095a..7e5d4ad 100644 --- a/services/webnn/dml/command_recorder_test.cc +++ b/services/webnn/dml/command_recorder_test.cc
@@ -24,12 +24,8 @@ }; void WebNNCommandRecorderTest::SetUp() { - TestBase::SetUp(); - // Skip all tests for this fixture. - if (!display_) { - return; - } - + SKIP_TEST_IF(!UseGPUInTests()); + ASSERT_TRUE(InitializeGLDisplay()); ComPtr<ID3D11Device> d3d11_device = gl::QueryD3D11DeviceObjectFromANGLE(); ASSERT_NE(d3d11_device.Get(), nullptr); ComPtr<IDXGIDevice> dxgi_device;
diff --git a/services/webnn/dml/test_base.cc b/services/webnn/dml/test_base.cc index 7b9410e..c8ff85c 100644 --- a/services/webnn/dml/test_base.cc +++ b/services/webnn/dml/test_base.cc
@@ -9,16 +9,21 @@ namespace webnn::dml { -void TestBase::SetUp() { - if (!base::CommandLine::ForCurrentProcess()->HasSwitch( - switches::kUseGpuInTests)) { - // GTEST_SKIP() will let SetUp() method return directly. - GTEST_SKIP() << "Skipping all tests for this fixture if GPU hardware " - "hasn't been used in tests."; - } +bool UseGPUInTests() { + return base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kUseGpuInTests); +} + +bool TestBase::InitializeGLDisplay() { display_ = gl::init::InitializeGLNoExtensionsOneOff( /*init_bindings=*/true, /*gpu_preference=*/gl::GpuPreference::kDefault); + return display_ != nullptr; +} + +void TestBase::SetUp() { + SKIP_TEST_IF(!UseGPUInTests()); + ASSERT_TRUE(InitializeGLDisplay()); } void TestBase::TearDown() {
diff --git a/services/webnn/dml/test_base.h b/services/webnn/dml/test_base.h index 6600985..d96fb1e 100644 --- a/services/webnn/dml/test_base.h +++ b/services/webnn/dml/test_base.h
@@ -8,18 +8,31 @@ #include "base/memory/raw_ptr.h" #include "testing/gtest/include/gtest/gtest.h" +// GTEST_SKIP() will let method return directly. +#define SKIP_TEST_IF(condition) \ + do { \ + if (condition) \ + GTEST_SKIP() << #condition; \ + } while (0) + namespace gl { class GLDisplay; } namespace webnn::dml { +bool UseGPUInTests(); + class TestBase : public testing::Test { public: void SetUp() override; void TearDown() override; - protected: + // Initializing the GL display is required for querying D3D11 device by + // gl::QueryD3D11DeviceObjectFromANGLE(). + bool InitializeGLDisplay(); + + private: raw_ptr<gl::GLDisplay> display_ = nullptr; };
diff --git a/skia/BUILD.gn b/skia/BUILD.gn index 5d27a429..3030446 100644 --- a/skia/BUILD.gn +++ b/skia/BUILD.gn
@@ -825,6 +825,10 @@ "-fobjc-arc", ] deps = [ "//gpu/config:workaround_list" ] + if (skia_use_dawn) { + # Needed due to include chain containing webgpu_cpp.h via GrDawnTypes.h. + public_deps = [ "//third_party/dawn/include/dawn:cpp_headers" ] + } visibility = [ ":skia" ] } }
diff --git a/skia/features.gni b/skia/features.gni index 0db7d3bf..fd22f3e 100644 --- a/skia/features.gni +++ b/skia/features.gni
@@ -12,7 +12,7 @@ # Enable experimental Skia Graphite Metal backend. Intended only for debugging # on non-official developer builds. - skia_use_metal = false + skia_use_metal = is_mac && !is_official_build # Enable gtests using SkiaRenderer on Skia Graphite. # TODO(rivr): Remove this and enable the tests by default once a software
diff --git a/storage/browser/quota/quota_database.cc b/storage/browser/quota/quota_database.cc index e3d2679..42059f4 100644 --- a/storage/browser/quota/quota_database.cc +++ b/storage/browser/quota/quota_database.cc
@@ -222,12 +222,14 @@ GetBucket(params.storage_key, params.name, StorageType::kTemporary); if (!bucket_result.has_value()) { - if (bucket_result.error() != QuotaError::kNotFound) { - bucket_result.error().sqlite_error = sqlite_error_code_; - return bucket_result; + if (bucket_result.error() == QuotaError::kNotFound) { + bucket_result = CreateBucketInternal(params, StorageType::kTemporary, + max_bucket_count); } - return CreateBucketInternal(params, StorageType::kTemporary, - max_bucket_count); + if (!bucket_result.has_value()) { + bucket_result.error().sqlite_error = sqlite_error_code_; + } + return bucket_result; } // Don't bother updating anything if the bucket is expired. @@ -1238,10 +1240,9 @@ /*last_accessed=*/now, /*last_modified=*/now, statement); QuotaErrorOr<BucketInfo> result = BucketInfoFromSqlStatement(statement); - const bool done = !statement.Step(); - DCHECK(done); if (result.has_value()) { + CHECK(!statement.Step()); // Commit immediately so that we persist the bucket metadata to disk before // we inform other services / web apps (via the Buckets API) that we did so. // Once informed, that promise should persist across power failures.
diff --git a/storage/test/PRESUBMIT.py b/storage/test/PRESUBMIT.py index 4ecd778..9ac7d68 100644 --- a/storage/test/PRESUBMIT.py +++ b/storage/test/PRESUBMIT.py
@@ -6,7 +6,7 @@ for more details about the presubmit API built into depot_tools. """ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True + def CheckChange(input_api, output_api): import sys old_sys_path = sys.path[:]
diff --git a/testing/PRESUBMIT.py b/testing/PRESUBMIT.py index bdcfd0b..db072c03 100644 --- a/testing/PRESUBMIT.py +++ b/testing/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - PRESUBMIT_VERSION = '2.0.0' @@ -36,10 +34,7 @@ input_api, output_api, '.', - [r'^.+_unittest\.py$'], - run_on_python2=False, - run_on_python3=USE_PYTHON3, - skip_shebang_check=True) + [r'^.+_unittest\.py$']) def CheckFlakeSuppressorCommonUnittests(input_api, output_api): @@ -50,10 +45,7 @@ input_api.os_path.join(input_api.PresubmitLocalPath(), 'flake_suppressor_common'), [r'^.+_unittest\.py$'], - env=_GetTestingEnv(input_api), - run_on_python2=False, - run_on_python3=USE_PYTHON3, - skip_shebang_check=True) + env=_GetTestingEnv(input_api)) def CheckUnexpectedPassesCommonUnittests(input_api, output_api): @@ -64,10 +56,7 @@ input_api.os_path.join(input_api.PresubmitLocalPath(), 'unexpected_passes_common'), [r'^.+_unittest\.py$'], - env=_GetTestingEnv(input_api), - run_on_python2=False, - run_on_python3=USE_PYTHON3, - skip_shebang_check=True) + env=_GetTestingEnv(input_api)) def CheckPylint(input_api, output_api):
diff --git a/testing/buildbot/PRESUBMIT.py b/testing/buildbot/PRESUBMIT.py index 499a24b..be84a6b0 100644 --- a/testing/buildbot/PRESUBMIT.py +++ b/testing/buildbot/PRESUBMIT.py
@@ -64,12 +64,8 @@ else: return [] glob = input_api.os_path.join(input_api.PresubmitLocalPath(), '*test.py') - tests = input_api.canned_checks.GetUnitTests(input_api, - output_api, - input_api.glob(glob), - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + tests = input_api.canned_checks.GetUnitTests(input_api, output_api, + input_api.glob(glob)) return input_api.RunTests(tests)
diff --git a/testing/buildbot/chromium.android.fyi.json b/testing/buildbot/chromium.android.fyi.json index fc8fecac..68796d7f 100644 --- a/testing/buildbot/chromium.android.fyi.json +++ b/testing/buildbot/chromium.android.fyi.json
@@ -8462,7 +8462,6 @@ { "args": [ "--no-wpt-internal", - "--log-wptreport", "--avd-config=../../tools/android/avd/proto/generic_android28.textpb", "--use-upstream-wpt" ], @@ -9621,7 +9620,6 @@ "args": [ "--no-wpt-internal", "--avd-config=../../tools/android/avd/proto/generic_android28.textpb", - "--log-wptreport", "--use-upstream-wpt" ], "isolate_name": "system_webview_wpt",
diff --git a/testing/buildbot/chromium.chromiumos.json b/testing/buildbot/chromium.chromiumos.json index 06e67c3..d1181622 100644 --- a/testing/buildbot/chromium.chromiumos.json +++ b/testing/buildbot/chromium.chromiumos.json
@@ -5669,9 +5669,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5682,8 +5682,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -5701,9 +5701,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5714,8 +5714,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -5834,9 +5834,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5847,8 +5847,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -5865,9 +5865,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5878,8 +5878,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -5981,9 +5981,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -5994,8 +5994,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -6013,9 +6013,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -6026,8 +6026,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.coverage.json b/testing/buildbot/chromium.coverage.json index 6ea847d..89828317 100644 --- a/testing/buildbot/chromium.coverage.json +++ b/testing/buildbot/chromium.coverage.json
@@ -8834,9 +8834,7 @@ "chromeos-js-code-coverage": { "gtest_tests": [ { - "args": [ - "--gtest_filter=*PersonalizationApp*:*OSSettings*" - ], + "args": [], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25494,9 +25492,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25507,8 +25505,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -25526,9 +25524,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25539,8 +25537,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -25659,9 +25657,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25672,8 +25670,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -25690,9 +25688,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25703,8 +25701,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -25806,9 +25804,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25819,8 +25817,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -25838,9 +25836,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -25851,8 +25849,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [
diff --git a/testing/buildbot/chromium.fyi.json b/testing/buildbot/chromium.fyi.json index 732026d0..e56930a 100644 --- a/testing/buildbot/chromium.fyi.json +++ b/testing/buildbot/chromium.fyi.json
@@ -18100,7 +18100,6 @@ "isolated_scripts": [ { "args": [ - "--log-wptreport", "--no-wpt-internal", "--xcode-build-version", "14c18" @@ -43192,9 +43191,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43204,8 +43203,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -43224,9 +43223,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43236,8 +43235,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -43357,9 +43356,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43369,8 +43368,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -43388,9 +43387,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43400,8 +43399,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -43504,9 +43503,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43516,8 +43515,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -43536,9 +43535,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -43548,8 +43547,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -44981,9 +44980,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -44993,8 +44992,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -45013,9 +45012,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45025,8 +45024,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -45146,9 +45145,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45158,8 +45157,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -45177,9 +45176,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45189,8 +45188,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -45293,9 +45292,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45305,8 +45304,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -45325,9 +45324,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -45337,8 +45336,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -46041,9 +46040,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -46053,8 +46052,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -46072,9 +46071,9 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome" + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" }, @@ -46084,8 +46083,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -48659,7 +48658,6 @@ "isolated_scripts": [ { "args": [ - "--log-wptreport", "--enable-sanitizer" ], "isolate_name": "wpt_tests_isolate_content_shell", @@ -48692,9 +48690,6 @@ "linux-wpt-content-shell-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate_content_shell", "merge": { "args": [ @@ -48722,7 +48717,6 @@ }, { "args": [ - "--log-wptreport", "--flag-specific", "highdpi" ], @@ -48754,7 +48748,6 @@ { "args": [ "--child-processes=8", - "--log-wptreport", "--flag-specific", "disable-site-isolation-trials" ], @@ -48789,7 +48782,6 @@ "isolated_scripts": [ { "args": [ - "--log-wptreport", "--enable-leak-detection" ], "experiment_percentage": 100, @@ -48823,9 +48815,6 @@ "linux-wpt-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate", "merge": { "args": [ @@ -51037,9 +51026,6 @@ "mac10.15-wpt-content-shell-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate_content_shell", "isolate_profile_data": true, "merge": { @@ -51072,9 +51058,6 @@ "mac11-wpt-content-shell-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate_content_shell", "isolate_profile_data": true, "merge": { @@ -51107,9 +51090,6 @@ "mac12-arm64-wpt-content-shell-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate_content_shell", "isolate_profile_data": true, "merge": { @@ -51142,9 +51122,6 @@ "mac12-wpt-content-shell-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate_content_shell", "isolate_profile_data": true, "merge": { @@ -51177,9 +51154,6 @@ "mac13-arm64-wpt-content-shell-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate_content_shell", "isolate_profile_data": true, "merge": { @@ -51212,9 +51186,6 @@ "mac13-wpt-content-shell-fyi-rel": { "isolated_scripts": [ { - "args": [ - "--log-wptreport" - ], "isolate_name": "wpt_tests_isolate_content_shell", "isolate_profile_data": true, "merge": { @@ -54050,7 +54021,6 @@ "isolated_scripts": [ { "args": [ - "--log-wptreport", "--target", "Release_x64" ], @@ -54087,7 +54057,6 @@ "isolated_scripts": [ { "args": [ - "--log-wptreport", "--target", "Release_x64" ],
diff --git a/testing/buildbot/chromium.memory.json b/testing/buildbot/chromium.memory.json index 5b22a8df..5c4f4e25 100644 --- a/testing/buildbot/chromium.memory.json +++ b/testing/buildbot/chromium.memory.json
@@ -18080,12 +18080,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18096,8 +18096,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -18115,12 +18115,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.interactive_ui_tests.skew.dev.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18131,8 +18131,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -18265,12 +18265,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18281,8 +18281,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -18299,12 +18299,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18315,8 +18315,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [ @@ -18427,12 +18427,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 116.0.5805.0", + "description": "Run with ash-chrome version 116.0.5807.0", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18443,8 +18443,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v116.0.5805.0", - "revision": "version:116.0.5805.0" + "location": "lacros_version_skew_tests_v116.0.5807.0", + "revision": "version:116.0.5807.0" } ], "dimension_sets": [ @@ -18462,12 +18462,12 @@ { "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/linux-lacros.lacros_chrome_browsertests.skew.filter", - "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome", + "--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome", "--test-launcher-print-test-stdio=always", "--combine-ash-logs-on-bots", "--asan-symbolize-output" ], - "description": "Run with ash-chrome version 115.0.5790.7", + "description": "Run with ash-chrome version 115.0.5790.13", "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -18478,8 +18478,8 @@ "cipd_packages": [ { "cipd_package": "chromium/testing/linux-ash-chromium/x86_64/ash.zip", - "location": "lacros_version_skew_tests_v115.0.5790.7", - "revision": "version:115.0.5790.7" + "location": "lacros_version_skew_tests_v115.0.5790.13", + "revision": "version:115.0.5790.13" } ], "dimension_sets": [
diff --git a/testing/buildbot/internal.chromeos.fyi.json b/testing/buildbot/internal.chromeos.fyi.json index b8849403..6d346e4 100644 --- a/testing/buildbot/internal.chromeos.fyi.json +++ b/testing/buildbot/internal.chromeos.fyi.json
@@ -1217,6 +1217,29 @@ } ] }, + "chromeos-kevin-chrome-skylab-fyi": { + "additional_compile_targets": [ + "chrome", + "linux_symbols", + "symupload" + ], + "skylab_tests": [ + { + "args": [], + "autotest_name": "tast.chrome-from-tls", + "cros_board": "kevin", + "cros_img": "kevin-release/R114-15408.0.0", + "name": "chrome_all_tast_tests CROS_KEVIN_RELEASE_CHROME_FROM_TLS_LKGM", + "shards": 10, + "swarming": {}, + "tast_expr": "(\"group:mainline\" && \"dep:chrome\" && !informational)", + "test": "chrome_all_tast_tests", + "test_id_prefix": "ninja://chromeos:chrome_all_tast_tests/", + "timeout_sec": 21600, + "variant_id": "CROS_KEVIN_RELEASE_CHROME_FROM_TLS_LKGM" + } + ] + }, "chromeos-octopus-chrome-skylab-fyi": { "additional_compile_targets": [ "chrome",
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 382b8956..435751b 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -3818,7 +3818,6 @@ }, 'android-webview-pie-x86-wpt-fyi-rel': { 'args': [ - '--log-wptreport', '--use-upstream-wpt', ], },
diff --git a/testing/buildbot/test_suites.pyl b/testing/buildbot/test_suites.pyl index 6b1e8e0..e732470 100644 --- a/testing/buildbot/test_suites.pyl +++ b/testing/buildbot/test_suites.pyl
@@ -520,7 +520,6 @@ 'chrome_public_wpt': { 'args': [ '--no-wpt-internal', - '--log-wptreport', ], 'swarming': { 'shards': 36, @@ -715,9 +714,7 @@ 'chromeos_js_code_coverage_browser_tests' : { 'chromeos_js_code_coverage_browser_tests': { - 'args': [ - "--gtest_filter=*PersonalizationApp*:*OSSettings*" - ], + 'args': [], 'test': 'browser_tests', } }, @@ -5558,7 +5555,6 @@ 'wpt_tests_ios': { 'wpt_tests_ios': { 'args': [ - '--log-wptreport', '--no-wpt-internal', ], 'merge': { @@ -5579,9 +5575,6 @@ 'wpt_web_tests': { 'wpt_tests_suite': { - 'args': [ - '--log-wptreport', - ], 'merge': { 'args': [ '--verbose', @@ -5598,9 +5591,6 @@ 'wpt_web_tests_content_shell': { 'wpt_tests_suite': { - 'args': [ - '--log-wptreport' - ], 'merge': { 'args': [ '--verbose', @@ -5618,7 +5608,6 @@ 'wpt_web_tests_enable_leak_detection': { 'wpt_tests_suite': { 'args': [ - '--log-wptreport', '--enable-leak-detection', ], 'merge': { @@ -5639,7 +5628,6 @@ 'wpt_web_tests_highdpi': { 'wpt_tests_suite_highdpi': { 'args': [ - '--log-wptreport', '--flag-specific', 'highdpi', ], @@ -5706,7 +5694,6 @@ 'wpt_tests_suite_not_site_per_process': { 'args': [ '--child-processes=8', - '--log-wptreport', '--flag-specific', 'disable-site-isolation-trials', ], @@ -6774,6 +6761,14 @@ }, }, + 'chromeos_kevin_skylab_tests': { + 'chromeos_chrome_all_tast_tests': { + 'variants': [ + 'CROS_KEVIN_RELEASE_CHROME_FROM_TLS_LKGM', + ] + }, + }, + 'chromeos_octopus_skylab_tests': { 'chromeos_chrome_all_tast_tests': { 'variants': [
diff --git a/testing/buildbot/variants.pyl b/testing/buildbot/variants.pyl index b3e39f9b..a7e13d4 100644 --- a/testing/buildbot/variants.pyl +++ b/testing/buildbot/variants.pyl
@@ -22,32 +22,32 @@ }, 'LACROS_VERSION_SKEW_CANARY': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5805.0/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v116.0.5807.0/test_ash_chrome', ], - 'description': 'Run with ash-chrome version 116.0.5805.0', + 'description': 'Run with ash-chrome version 116.0.5807.0', 'identifier': 'Lacros version skew testing ash canary', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v116.0.5805.0', - 'revision': 'version:116.0.5805.0', + 'location': 'lacros_version_skew_tests_v116.0.5807.0', + 'revision': 'version:116.0.5807.0', }, ], }, }, 'LACROS_VERSION_SKEW_DEV': { 'args': [ - '--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.7/test_ash_chrome', + '--ash-chrome-path-override=../../lacros_version_skew_tests_v115.0.5790.13/test_ash_chrome', ], - 'description': 'Run with ash-chrome version 115.0.5790.7', + 'description': 'Run with ash-chrome version 115.0.5790.13', 'identifier': 'Lacros version skew testing ash dev', 'swarming': { 'cipd_packages': [ { 'cipd_package': 'chromium/testing/linux-ash-chromium/x86_64/ash.zip', - 'location': 'lacros_version_skew_tests_v115.0.5790.7', - 'revision': 'version:115.0.5790.7', + 'location': 'lacros_version_skew_tests_v115.0.5790.13', + 'revision': 'version:115.0.5790.13', }, ], }, @@ -639,6 +639,17 @@ 'enabled': True, 'identifier': 'KEVIN_PUBLIC_LKGM', }, + 'CROS_KEVIN_RELEASE_CHROME_FROM_TLS_LKGM': { + 'skylab': { + 'cros_board': 'kevin', + 'cros_chrome_version': '114.0.5689.0', + 'cros_img': 'kevin-release/R114-15408.0.0', + 'autotest_name': 'tast.chrome-from-tls', + 'shards': 10, + }, + 'enabled': True, + 'identifier': 'CROS_KEVIN_RELEASE_CHROME_FROM_TLS_LKGM', + }, 'CROS_OCTOPUS_PUBLIC_LKGM': { 'skylab': { 'cros_board': 'octopus',
diff --git a/testing/buildbot/waterfalls.pyl b/testing/buildbot/waterfalls.pyl index e8123e7..2f4137f 100644 --- a/testing/buildbot/waterfalls.pyl +++ b/testing/buildbot/waterfalls.pyl
@@ -6693,6 +6693,17 @@ }, 'os_type': 'chromeos', }, + 'chromeos-kevin-chrome-skylab-fyi': { + 'additional_compile_targets': [ + "chrome", + "linux_symbols", + "symupload", + ], + 'test_suites': { + 'skylab_tests': 'chromeos_kevin_skylab_tests', + }, + 'os_type': 'chromeos', + }, 'chromeos-octopus-chrome-skylab-fyi': { 'additional_compile_targets': [ "chrome",
diff --git a/testing/merge_scripts/PRESUBMIT.py b/testing/merge_scripts/PRESUBMIT.py index aaf6065..59ef7ae0 100644 --- a/testing/merge_scripts/PRESUBMIT.py +++ b/testing/merge_scripts/PRESUBMIT.py
@@ -8,12 +8,9 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def CommonChecks(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, output_api, '.', [ r'^.+_test\.py$'], - run_on_python2=False, skip_shebang_check=True) + input_api, output_api, '.', [ r'^.+_test\.py$']) def CheckChangeOnUpload(input_api, output_api): return CommonChecks(input_api, output_api)
diff --git a/testing/merge_scripts/code_coverage/PRESUBMIT.py b/testing/merge_scripts/code_coverage/PRESUBMIT.py index 167b7c1..bf08b21 100644 --- a/testing/merge_scripts/code_coverage/PRESUBMIT.py +++ b/testing/merge_scripts/code_coverage/PRESUBMIT.py
@@ -8,17 +8,12 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def CommonChecks(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( input_api, output_api, '.', - [ r'^.+_test\.py$'], - run_on_python2=not USE_PYTHON3, - run_on_python3=USE_PYTHON3, - skip_shebang_check=True) + [ r'^.+_test\.py$']) def CheckChangeOnUpload(input_api, output_api): return CommonChecks(input_api, output_api)
diff --git a/testing/scripts/PRESUBMIT.py b/testing/scripts/PRESUBMIT.py index 0896e6c..83dbd79 100644 --- a/testing/scripts/PRESUBMIT.py +++ b/testing/scripts/PRESUBMIT.py
@@ -8,14 +8,9 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def CommonChecks(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, output_api, '.', files_to_check=[r'^.+_unittest\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + input_api, output_api, '.', files_to_check=[r'^.+_unittest\.py$']) def CheckChangeOnUpload(input_api, output_api): return CommonChecks(input_api, output_api)
diff --git a/testing/scripts/rust/PRESUBMIT.py b/testing/scripts/rust/PRESUBMIT.py index 0e852d5..70c04b90 100644 --- a/testing/scripts/rust/PRESUBMIT.py +++ b/testing/scripts/rust/PRESUBMIT.py
@@ -5,7 +5,6 @@ """ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True def CheckPythonUnittestsPass(input_api, output_api): # The rust scripts and tests don't work on Windows. @@ -20,9 +19,6 @@ output_api, this_dir, files_to_check=['.*unittest.*\.py$'], - env=None, - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + env=None)) return results
diff --git a/testing/trigger_scripts/PRESUBMIT.py b/testing/trigger_scripts/PRESUBMIT.py index e2adda1..4e519a0d 100644 --- a/testing/trigger_scripts/PRESUBMIT.py +++ b/testing/trigger_scripts/PRESUBMIT.py
@@ -7,18 +7,12 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( input_api, output_api, '.', - files_to_check=['.*test.py'], - run_on_python2=not USE_PYTHON3, - run_on_python3=USE_PYTHON3, - skip_shebang_check=True) + files_to_check=['.*test.py']) def CheckChangeOnUpload(input_api, output_api):
diff --git a/testing/variations/PRESUBMIT.py b/testing/variations/PRESUBMIT.py index fe96a6e..d6716a3b 100644 --- a/testing/variations/PRESUBMIT.py +++ b/testing/variations/PRESUBMIT.py
@@ -14,8 +14,6 @@ from collections import OrderedDict -USE_PYTHON3 = True - VALID_EXPERIMENT_KEYS = [ 'name', 'forcing_flag', 'params', 'enable_features', 'disable_features', 'min_os_version', '//0', '//1', '//2', '//3', '//4', '//5', '//6', '//7',
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 872f5c7f..2dc68e4 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -2603,6 +2603,21 @@ ] } ], + "CertVerifierBuiltin": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "ChromeRootStoreUsed" + ] + } + ] + } + ], "ChangeExtensionEventPageSuspendDelay": [ { "platforms": [ @@ -5806,28 +5821,6 @@ ] } ], - "FlushGpuAtDraw": [ - { - "platforms": [ - "android", - "android_weblayer", - "chromeos", - "chromeos_lacros", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "FlushGpuAtDraw" - ] - } - ] - } - ], "FollowOnboarding": [ { "platforms": [ @@ -6880,22 +6873,6 @@ ] } ], - "IOSEditMenuSearchWith": [ - { - "platforms": [ - "ios" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "IOSEditMenuHideSearchWeb", - "IOSEditMenuSearchWith" - ] - } - ] - } - ], "IOSEmailExperience": [ { "platforms": [ @@ -7153,6 +7130,24 @@ ] } ], + "IOSMagicStack": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "params": { + "kReducedSpaceParam": "-30" + }, + "enable_features": [ + "MagicStack" + ] + } + ] + } + ], "IOSNewOverflowMenuIPH": [ { "platforms": [ @@ -7608,21 +7603,6 @@ ] } ], - "IntelVpSuperResolution": [ - { - "platforms": [ - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "IntelVpSuperResolution" - ] - } - ] - } - ], "JourneysAndroidPreStable": [ { "platforms": [ @@ -7650,29 +7630,6 @@ ] } ], - "JourneysHide": [ - { - "platforms": [ - "chromeos", - "chromeos_lacros", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled_Icon", - "params": { - "hide_visits_icon": "true" - }, - "enable_features": [ - "HistoryClustersHideVisits" - ] - } - ] - } - ], "JourneysNonSupportedLocales": [ { "platforms": [ @@ -7713,32 +7670,6 @@ ] } ], - "JourneysSuggestionRow": [ - { - "platforms": [ - "chromeos", - "chromeos_lacros", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "omnibox_history_cluster_provider_inherit_search_match_score": "false", - "omnibox_history_cluster_provider_rank_above_searches": "false", - "omnibox_history_cluster_provider_shortcuts": "true" - }, - "enable_features": [ - "JourneysOmniboxHistoryClusterProvider", - "OmniboxPreferTailOverHistoryClusterSuggestions" - ] - } - ] - } - ], "JourneysZeroStateFiltering": [ { "platforms": [ @@ -8219,28 +8150,6 @@ ] } ], - "MainRepaintScrollPrefersNewContent": [ - { - "platforms": [ - "android", - "android_weblayer", - "chromeos", - "chromeos_lacros", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "MainRepaintScrollPrefersNewContent" - ] - } - ] - } - ], "MainThreadCompositingPriority": [ { "platforms": [ @@ -9596,6 +9505,39 @@ ] } ], + "OutOfProcessNetworkService": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "EnableOOPNS_over_6656_Mb_20230410", + "disable_features": [ + "NetworkServiceInProcess2" + ] + } + ] + } + ], + "OutOfProcessNetworkServiceMemoryControls": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Over_6500_mb_20230410", + "params": { + "network_service_oop_threshold_mb": "6656" + }, + "enable_features": [ + "NetworkServiceOutOfProcessMemoryThreshold" + ] + } + ] + } + ], "OutOfProcessPrintDriversPrintPreview": [ { "platforms": [ @@ -10427,7 +10369,7 @@ { "name": "Enabled_Nonstable_20230531", "enable_features": [ - "PreconnectCreateNewTab" + "PreconnectOnTabCreation" ] } ] @@ -11384,70 +11326,6 @@ ] } ], - "ReduceUserAgentAndroidVersionDeviceModel": [ - { - "platforms": [ - "android" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "ReduceUserAgentAndroidVersionDeviceModel" - ] - } - ] - } - ], - "ReduceUserAgentMinorVersionStudy": [ - { - "platforms": [ - "android", - "android_weblayer", - "chromeos", - "chromeos_lacros", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "build_version": "0" - }, - "enable_features": [ - "ReduceUserAgentMinorVersion" - ] - } - ] - } - ], - "ReduceUserAgentPlatformOsCpu": [ - { - "platforms": [ - "chromeos", - "chromeos_lacros", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "params": { - "all_except_legacy_windows_platform": "true", - "legacy_windows_platform": "true" - }, - "enable_features": [ - "ReduceUserAgentPlatformOsCpu" - ] - } - ] - } - ], "RemoveFontLinkFallbacks": [ { "platforms": [ @@ -11901,26 +11779,6 @@ ] } ], - "ScrollUnification": [ - { - "platforms": [ - "android", - "chromeos", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "ScrollUnification" - ] - } - ] - } - ], "SearchResumptionModuleAndroid": [ { "platforms": [ @@ -12814,6 +12672,7 @@ "spare_tab_initialize_renderer": "true" }, "enable_features": [ + "SpareTab", "StartSurfaceSpareTab" ] }, @@ -12823,6 +12682,7 @@ "spare_tab_initialize_renderer": "false" }, "enable_features": [ + "SpareTab", "StartSurfaceSpareTab" ] }
diff --git a/third_party/android_platform/development/scripts/PRESUBMIT.py b/third_party/android_platform/development/scripts/PRESUBMIT.py index bd8c8ac..a2a3489 100644 --- a/third_party/android_platform/development/scripts/PRESUBMIT.py +++ b/third_party/android_platform/development/scripts/PRESUBMIT.py
@@ -20,10 +20,7 @@ output_api, input_api.PresubmitLocalPath(), files_to_check=[r'.+_test\.py$'], - files_to_skip=[], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + files_to_skip=[]) output.extend(input_api.RunTests(py_tests, False)) return output
diff --git a/third_party/androidx_javascriptengine/BUILD.gn b/third_party/androidx_javascriptengine/BUILD.gn index 8ca725be76..ee924b1 100644 --- a/third_party/androidx_javascriptengine/BUILD.gn +++ b/third_party/androidx_javascriptengine/BUILD.gn
@@ -23,6 +23,8 @@ android_library("js_sandbox_aidl_java") { srcjar_deps = [ ":js_sandbox_aidl" ] + + deps = [ "//third_party/androidx:androidx_annotation_annotation_java" ] } android_library("javascriptengine_common_java") {
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index b20a83f1..7de7aba 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1077,6 +1077,8 @@ // See https://github.com/WICG/turtledove/blob/main/FLEDGE.md // Feature flag to enable debug reporting APIs. +// Due to an issue in how prevWins were stored this flag should not be enabled +// until July 2023. BASE_FEATURE(kBiddingAndScoringDebugReportingAPI, "BiddingAndScoringDebugReportingAPI", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/third_party/blink/common/frame/user_activation_state.cc b/third_party/blink/common/frame/user_activation_state.cc index de3b52d..0b8210f 100644 --- a/third_party/blink/common/frame/user_activation_state.cc +++ b/third_party/blink/common/frame/user_activation_state.cc
@@ -28,10 +28,16 @@ } // namespace +#if defined(MEMORY_SANITIZER) +// MSan runs can be very slow, so don't time out user gestures quickly. See +// https://crbug.com/1433572 for one example. +constexpr base::TimeDelta kActivationLifespan = base::Seconds(60); +#else // The expiry time should be long enough to allow network round trips even in a // very slow connection (to support xhr-like calls with user activation), yet // not too long to make an "unattended" page feel activated. constexpr base::TimeDelta kActivationLifespan = base::Seconds(5); +#endif UserActivationState::UserActivationState() : first_notification_type_(UserActivationNotificationType::kNone),
diff --git a/third_party/blink/common/frame/user_activation_state_unittest.cc b/third_party/blink/common/frame/user_activation_state_unittest.cc index c5b80663..284b1df3 100644 --- a/third_party/blink/common/frame/user_activation_state_unittest.cc +++ b/third_party/blink/common/frame/user_activation_state_unittest.cc
@@ -61,6 +61,11 @@ EXPECT_FALSE(user_activation_state.ConsumeIfActive()); } +// MSan changes the timing of user activations, so skip this test. We could +// memorize the changes, but they're arbitrary and not worth enforcing. We +// could also move the timeouts into a header, but there's value in having +// them hardcoded here in case of accidental changes to the timeout. +#if !defined(MEMORY_SANITIZER) TEST_F(UserActivationStateTest, ExpirationTest) { UserActivationState user_activation_state; @@ -76,6 +81,7 @@ EXPECT_TRUE(user_activation_state.HasBeenActive()); EXPECT_FALSE(user_activation_state.IsActive()); } +#endif // !MEMORY_SANITIZER TEST_F(UserActivationStateTest, ClearingTest) { UserActivationState user_activation_state; @@ -91,6 +97,11 @@ EXPECT_FALSE(user_activation_state.IsActive()); } +// MSan changes the timing of user activations, so skip this test. We could +// memorize the changes, but they're arbitrary and not worth enforcing. We +// could also move the timeouts into a header, but there's value in having +// them hardcoded here in case of accidental changes to the timeout. +#if !defined(MEMORY_SANITIZER) TEST_F(UserActivationStateTest, ConsumptionPlusExpirationTest) { UserActivationState user_activation_state; @@ -118,5 +129,6 @@ user_activation_state.Activate(mojom::UserActivationNotificationType::kTest); EXPECT_TRUE(user_activation_state.ConsumeIfActive()); } +#endif // !MEMORY_SANITIZER } // namespace blink
diff --git a/third_party/blink/common/page/browsing_context_group_info.cc b/third_party/blink/common/page/browsing_context_group_info.cc index 5a0f86b..7bf3425 100644 --- a/third_party/blink/common/page/browsing_context_group_info.cc +++ b/third_party/blink/common/page/browsing_context_group_info.cc
@@ -21,4 +21,15 @@ BrowsingContextGroupInfo::BrowsingContextGroupInfo( mojo::DefaultConstruct::Tag) {} +bool operator==(const BrowsingContextGroupInfo& lhs, + const BrowsingContextGroupInfo& rhs) { + return lhs.browsing_context_group_token == rhs.browsing_context_group_token && + lhs.coop_related_group_token == rhs.coop_related_group_token; +} + +bool operator!=(const BrowsingContextGroupInfo& lhs, + const BrowsingContextGroupInfo& rhs) { + return !(lhs == rhs); +} + } // namespace blink
diff --git a/third_party/blink/common/page/browsing_context_group_info_unittest.cc b/third_party/blink/common/page/browsing_context_group_info_unittest.cc index aad8b873..88ed1a2 100644 --- a/third_party/blink/common/page/browsing_context_group_info_unittest.cc +++ b/third_party/blink/common/page/browsing_context_group_info_unittest.cc
@@ -36,4 +36,29 @@ bcg_info.browsing_context_group_token); } +TEST(BrowsingContextGroupInfoTest, ComparisonOperator) { + // Check that two different BrowsingContextGroupInfo are not equal. + BrowsingContextGroupInfo bcg_info = BrowsingContextGroupInfo::CreateUnique(); + BrowsingContextGroupInfo other_bcg_info = + BrowsingContextGroupInfo::CreateUnique(); + EXPECT_NE(bcg_info, other_bcg_info); + + // Check that two BrowsingContextGroupInfo copied from one another are equal. + BrowsingContextGroupInfo bcg_info_clone(bcg_info); + EXPECT_EQ(bcg_info, bcg_info_clone); + + // Verify that having different browsing_context_group_token is enough to have + // the comparison fail. + bcg_info_clone.browsing_context_group_token = + base::UnguessableToken::Create(); + EXPECT_NE(bcg_info, bcg_info_clone); + + // Verify that having different coop_related_group_tokens is enough to have + // the comparison fail. + bcg_info_clone.browsing_context_group_token = + bcg_info.browsing_context_group_token; + bcg_info_clone.coop_related_group_token = base::UnguessableToken::Create(); + EXPECT_NE(bcg_info, bcg_info_clone); +} + } // namespace blink
diff --git a/third_party/blink/common/switches.cc b/third_party/blink/common/switches.cc index 5ce300bc..cf09af000 100644 --- a/third_party/blink/common/switches.cc +++ b/third_party/blink/common/switches.cc
@@ -167,23 +167,6 @@ // Controls whether WebSQL is force enabled. const char kWebSQLAccess[] = "web-sql-access"; -// Used to communicate managed policy for the EventPath feature. This feature is -// typically controlled by base::Feature (see blink/common/features.*) but -// requires an enterprise policy override. This is implicitly a tri-state, and -// can be either unset, or set to "1" for force enable, or "0" for force -// disable. -extern const char kEventPathPolicy[] = "event-path-policy"; -extern const char kEventPathPolicy_ForceDisable[] = "0"; -extern const char kEventPathPolicy_ForceEnable[] = "1"; - -// The EventPath feature is disabled by default on almost all platforms and -// channels, with a few exceptions that require a more gradual removal. Those -// platforms/channels should pass this flag to renderer to enable the feature. -// The flag has higher precedence than Blink runtime enabled feature, but lower -// precedence than base::Feature overrides and enterprise policy. -extern const char kEventPathEnabledByDefault[] = - "event-path-enabled-by-default"; - // Used to communicate managed policy for the OffsetParentNewSpecBehavior // feature. This feature is typically controlled by base::Feature (see // blink/common/features.*) but requires an enterprise policy override. This is
diff --git a/third_party/blink/public/common/page/browsing_context_group_info.h b/third_party/blink/public/common/page/browsing_context_group_info.h index d6bafe5..fedd590 100644 --- a/third_party/blink/public/common/page/browsing_context_group_info.h +++ b/third_party/blink/public/common/page/browsing_context_group_info.h
@@ -38,6 +38,11 @@ base::UnguessableToken coop_related_group_token; }; +bool BLINK_COMMON_EXPORT operator==(const BrowsingContextGroupInfo& lhs, + const BrowsingContextGroupInfo& rhs); +bool BLINK_COMMON_EXPORT operator!=(const BrowsingContextGroupInfo& lhs, + const BrowsingContextGroupInfo& rhs); + } // namespace blink #endif // THIRD_PARTY_BLINK_PUBLIC_COMMON_PAGE_BROWSING_CONTEXT_GROUP_INFO_H_
diff --git a/third_party/blink/public/common/switches.h b/third_party/blink/public/common/switches.h index af6a491..88536d9 100644 --- a/third_party/blink/public/common/switches.h +++ b/third_party/blink/public/common/switches.h
@@ -43,10 +43,6 @@ BLINK_COMMON_EXPORT extern const char kEnableRasterSideDarkModeForImages[]; BLINK_COMMON_EXPORT extern const char kEnableRGBA4444Textures[]; BLINK_COMMON_EXPORT extern const char kEnableZeroCopy[]; -BLINK_COMMON_EXPORT extern const char kEventPathPolicy[]; -BLINK_COMMON_EXPORT extern const char kEventPathPolicy_ForceDisable[]; -BLINK_COMMON_EXPORT extern const char kEventPathPolicy_ForceEnable[]; -BLINK_COMMON_EXPORT extern const char kEventPathEnabledByDefault[]; BLINK_COMMON_EXPORT extern const char kOffsetParentNewSpecBehaviorPolicy[]; BLINK_COMMON_EXPORT extern const char kOffsetParentNewSpecBehaviorPolicy_ForceDisable[];
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index 7f29e886..02d6149 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -3984,7 +3984,7 @@ jpeg png webp - # Compression quality from range [0..100] (jpeg only). + # Compression quality from range [0..100] (jpeg and webp only). optional integer quality # Optimize image encoding for speed, not for resulting size (defaults to false) optional boolean optimizeForSpeed
diff --git a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom index b18251d..355ad50 100644 --- a/third_party/blink/public/mojom/indexeddb/indexeddb.mojom +++ b/third_party/blink/public/mojom/indexeddb/indexeddb.mojom
@@ -249,12 +249,9 @@ SuccessDatabase(pending_associated_remote<IDBDatabase>? pending_database, IDBDatabaseMetadata metadata); - // Database::Count / DeleteRange + // Database::Count // Factory::DeleteDatabase SuccessInteger(int64 value); - - // Cursor::Continue / Advance - Success(); }; // The IDBDatabaseCallbacks interface is used to notification of events out of @@ -415,10 +412,10 @@ int64 index_id, IDBKeyRange key_range, pending_associated_remote<IDBCallbacks> pending_callbacks); + // Correlates to IDBObjectStore::delete() and also used by devtools. DeleteRange(int64 transaction_id, int64 object_store_id, - IDBKeyRange key_range, - pending_associated_remote<IDBCallbacks> pending_callbacks); + IDBKeyRange key_range) => (bool success); // Gets the current number of an IndexedDB ObjectStore's key generator. It // is implemented in the browser (more priviledged) and handles requests in // the renderer process: WebIDBDatabaseImpl::GetKeyGeneratorCurrentNumber()
diff --git a/third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom b/third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom index 9c272435..490f848 100644 --- a/third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom +++ b/third_party/blink/public/mojom/service_worker/service_worker_router_rule.mojom
@@ -6,28 +6,29 @@ import "third_party/blink/public/mojom/url_pattern.mojom"; -// TODO(crbug.com/1371756): leave a link to an explainer or a specification -// when it get ready. - // This represents a condition of the router rule. -// TODO(crbug.com/1371756): implement other conditions in the proposal. +// https://github.com/yoshisatoyanagisawa/service-worker-static-routing-api +// TODO(crbug.com/1371756): implement other conditions in the full picture. union ServiceWorkerRouterCondition { // URLPattern to be used for matching. UrlPattern url_pattern; }; // This is used for specifying the source is network. -// TODO(crbug.com/1371756): implement fields in the proposal. +// https://github.com/yoshisatoyanagisawa/service-worker-static-routing-api +// TODO(crbug.com/1371756): implement fields in the full picture. struct ServiceWorkerRouterNetworkSource { }; // This represents a source of the router rule. -// TODO(crbug.com/1371756): implement other sources in the proposal. +// https://github.com/yoshisatoyanagisawa/service-worker-static-routing-api +// TODO(crbug.com/1371756): implement other sources in the full picture. union ServiceWorkerRouterSource { ServiceWorkerRouterNetworkSource network_source; }; // This represents a ServiceWorker static routing API's router rule. +// https://github.com/yoshisatoyanagisawa/service-worker-static-routing-api // It represents each route. // When an request matches `conditions`, a response is fetched from `sources`. // `conditions` are evaluated sequentially to ensure all of them are fulfilled. @@ -43,6 +44,7 @@ }; // This represents a list of ServiceWorker static routing API's router rules. +// https://github.com/yoshisatoyanagisawa/service-worker-static-routing-api struct ServiceWorkerRouterRules { array<ServiceWorkerRouterRule> rules; };
diff --git a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom index f0e9c05..a32a599 100644 --- a/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom +++ b/third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom
@@ -200,7 +200,7 @@ kSVGSVGElementInXMLDocument = 329, kEventSrcElement = 343, kEventCancelBubble = 344, - kEventPath = 345, + kOBSOLETE_EventPath = 345, kNodeIteratorDetach = 347, kEventGetReturnValueTrue = 350, kEventGetReturnValueFalse = 351, @@ -3223,9 +3223,9 @@ kClientHintsPrefersColorScheme = 3915, kOverscrollBehaviorWillBeFixed = 3916, kControlledWorkerWillBeUncontrolled = 3917, - kARIATouchpassthroughAttribute = 3918, + kOBSOLETE_kARIATouchpassthroughAttribute = 3918, kARIAVirtualcontentAttribute = 3919, - kAccessibilityTouchPassthroughSet = 3920, + kOBSOLETE_kAccessibilityTouchPassthroughSet = 3920, kTextFragmentBlockedByForceLoadAtTop = 3921, kOBSOLETE_UrnDocumentAccessedCookies = 3922, kFontFaceAscentOverride = 3923,
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index 1620ec51..f444075 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -52,7 +52,6 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/common/security/protocol_handler_security_level.h" #include "third_party/blink/public/common/user_agent/user_agent_metadata.h" -#include "third_party/blink/public/mojom/service_worker/service_worker_fetch_handler_bypass_option.mojom-shared.h" #include "third_party/blink/public/platform/audio/web_audio_device_source_type.h" #include "third_party/blink/public/platform/cross_variant_mojo_util.h" #include "third_party/blink/public/platform/url_loader_throttle_provider.h" @@ -660,7 +659,6 @@ CrossVariantMojoRemote<mojom::ServiceWorkerContainerHostInterfaceBase> service_worker_container_host, const WebString& client_id, - mojom::ServiceWorkerFetchHandlerBypassOption fetch_handler_bypass_option, std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver, scoped_refptr<base::SequencedTaskRunner> task_runner);
diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index 19b2d32a..5bc7d67 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni
@@ -719,6 +719,8 @@ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_resample_2d_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_resample_2d_options.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_split_options.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_split_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_transpose_options.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_transpose_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_ml_tensor.cc",
diff --git a/third_party/blink/renderer/core/animation/animation_input_helpers.cc b/third_party/blink/renderer/core/animation/animation_input_helpers.cc index c0808e6..61b4cc9 100644 --- a/third_party/blink/renderer/core/animation/animation_input_helpers.cc +++ b/third_party/blink/renderer/core/animation/animation_input_helpers.cc
@@ -90,8 +90,8 @@ return CSSPropertyID::kInvalid; String unprefixed_property = RemoveSVGPrefix(property); - if (SVGElement::IsAnimatableCSSProperty(QualifiedName( - g_null_atom, AtomicString(unprefixed_property), g_null_atom))) { + if (SVGElement::IsAnimatableCSSProperty( + QualifiedName(AtomicString(unprefixed_property)))) { return CssPropertyID(element->GetExecutionContext(), unprefixed_property); } return CSSPropertyID::kInvalid; @@ -211,7 +211,7 @@ QualifiedName SvgAttributeName(const String& property) { DCHECK(!IsSVGPrefixed(property)); - return QualifiedName(g_null_atom, AtomicString(property), g_null_atom); + return QualifiedName(AtomicString(property)); } const QualifiedName* AnimationInputHelpers::KeyframeAttributeToSVGAttribute(
diff --git a/third_party/blink/renderer/core/animation/animation_input_helpers_test.cc b/third_party/blink/renderer/core/animation/animation_input_helpers_test.cc index a242a50..8ddb5ce 100644 --- a/third_party/blink/renderer/core/animation/animation_input_helpers_test.cc +++ b/third_party/blink/renderer/core/animation/animation_input_helpers_test.cc
@@ -178,11 +178,10 @@ PropertyHandleToKeyframeAttribute(GetCSSPropertyOffset(), true)); // SVG attributes. - EXPECT_EQ("calcMode", PropertyHandleToKeyframeAttribute(QualifiedName( - g_null_atom, "calcMode", g_null_atom))); - EXPECT_EQ("overline-position", - PropertyHandleToKeyframeAttribute( - QualifiedName(g_null_atom, "overline-position", g_null_atom))); + EXPECT_EQ("calcMode", + PropertyHandleToKeyframeAttribute(QualifiedName("calcMode"))); + EXPECT_EQ("overline-position", PropertyHandleToKeyframeAttribute( + QualifiedName("overline-position"))); } } // namespace blink
diff --git a/third_party/blink/renderer/core/css/css_selector_test.cc b/third_party/blink/renderer/core/css/css_selector_test.cc index 5d05f116..483f96cc 100644 --- a/third_party/blink/renderer/core/css/css_selector_test.cc +++ b/third_party/blink/renderer/core/css/css_selector_test.cc
@@ -242,33 +242,27 @@ } TEST(CSSSelector, ImplicitPseudoDescendant) { - CSSSelector selector[2] = { - CSSSelector(QualifiedName(/* prefix */ g_null_atom, "div", - /* namespace_uri */ g_null_atom), - /* is_implicit */ false), - CSSSelector("scope", /* is_implicit */ true)}; + CSSSelector selector[2] = {CSSSelector(QualifiedName("div"), + /* is_implicit */ false), + CSSSelector("scope", /* is_implicit */ true)}; selector[0].SetRelation(CSSSelector::kDescendant); selector[1].SetLastInComplexSelector(true); EXPECT_EQ("div", selector[0].SelectorText()); } TEST(CSSSelector, ImplicitPseudoChild) { - CSSSelector selector[2] = { - CSSSelector(QualifiedName(/* prefix */ g_null_atom, "div", - /* namespace_uri */ g_null_atom), - /* is_implicit */ false), - CSSSelector("scope", /* is_implicit */ true)}; + CSSSelector selector[2] = {CSSSelector(QualifiedName("div"), + /* is_implicit */ false), + CSSSelector("scope", /* is_implicit */ true)}; selector[0].SetRelation(CSSSelector::kChild); selector[1].SetLastInComplexSelector(true); EXPECT_EQ("> div", selector[0].SelectorText()); } TEST(CSSSelector, NonImplicitPseudoChild) { - CSSSelector selector[2] = { - CSSSelector(QualifiedName(/* prefix */ g_null_atom, "div", - /* namespace_uri */ g_null_atom), - /* is_implicit */ false), - CSSSelector("scope", /* is_implicit */ false)}; + CSSSelector selector[2] = {CSSSelector(QualifiedName("div"), + /* is_implicit */ false), + CSSSelector("scope", /* is_implicit */ false)}; selector[0].SetRelation(CSSSelector::kChild); selector[1].SetLastInComplexSelector(true); EXPECT_EQ(":scope > div", selector[0].SelectorText()); @@ -293,11 +287,9 @@ } TEST(CSSSelector, PseudoTrueChild) { - CSSSelector selector[2] = { - CSSSelector(QualifiedName(/* prefix */ g_null_atom, "div", - /* namespace_uri */ g_null_atom), - /* is_implicit */ false), - CSSSelector()}; + CSSSelector selector[2] = {CSSSelector(QualifiedName("div"), + /* is_implicit */ false), + CSSSelector()}; selector[0].SetRelation(CSSSelector::kChild); selector[1].SetTrue(); selector[1].SetLastInComplexSelector(true);
diff --git a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc index 7c03a25..5bdb7220 100644 --- a/third_party/blink/renderer/core/css/parser/css_selector_parser.cc +++ b/third_party/blink/renderer/core/css/parser/css_selector_parser.cc
@@ -1438,7 +1438,7 @@ QualifiedName qualified_name = namespace_prefix.IsNull() - ? QualifiedName(g_null_atom, attribute_name, g_null_atom) + ? QualifiedName(attribute_name) : QualifiedName(namespace_prefix, attribute_name, namespace_uri); if (block.AtEnd()) {
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index 5606ebe..caf0fb9 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -2486,9 +2486,7 @@ builder.SetHasAttrContent(); // TODO: Can a namespace be specified for an attr(foo)? QualifiedName attr( - g_null_atom, - To<CSSCustomIdentValue>(function_value->Item(0)).Value(), - g_null_atom); + To<CSSCustomIdentValue>(function_value->Item(0)).Value()); const AtomicString& attr_value = state.GetElement().getAttribute(attr); string = attr_value.IsNull() ? g_empty_string : attr_value.GetString(); } else {
diff --git a/third_party/blink/renderer/core/dom/build.gni b/third_party/blink/renderer/core/dom/build.gni index f16993d..38a5eb2 100644 --- a/third_party/blink/renderer/core/dom/build.gni +++ b/third_party/blink/renderer/core/dom/build.gni
@@ -316,6 +316,7 @@ "node_traversal_test.cc", "nth_index_cache_test.cc", "pseudo_element_test.cc", + "qualified_name_test.cc", "range_test.cc", "scripted_animation_controller_test.cc", "scripted_idle_task_controller_test.cc",
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 353cb5bc0..ae8b183 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -1121,8 +1121,7 @@ html_names::xhtmlNamespaceURI); return MakeGarbageCollected<HTMLUnknownElement>(q_name, *this); } - return MakeGarbageCollected<Element>( - QualifiedName(g_null_atom, name, g_null_atom), this); + return MakeGarbageCollected<Element>(QualifiedName(name), this); } AtomicString GetTypeExtension( @@ -7248,8 +7247,7 @@ return nullptr; } return MakeGarbageCollected<Attr>( - *this, QualifiedName(g_null_atom, ConvertLocalName(name), g_null_atom), - g_empty_atom); + *this, QualifiedName(ConvertLocalName(name)), g_empty_atom); } Attr* Document::createAttributeNS(const AtomicString& namespace_uri,
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index cde308a..8128dae 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -8416,8 +8416,7 @@ // if Element::SynchronizeAttribute() is called on all attributes, // svg_attributes_are_dirty_ remains true. This information is available in // the attribute->property map in SVGElement. - To<SVGElement>(this)->SynchronizeSVGAttribute( - QualifiedName(g_null_atom, local_name, g_null_atom)); + To<SVGElement>(this)->SynchronizeSVGAttribute(QualifiedName(local_name)); } } @@ -8439,20 +8438,16 @@ AtomicString name, WTF::AtomicStringTable::WeakResult hint) const { if (!HasElementData()) { - return std::make_pair( - kNotFound, - QualifiedName(g_null_atom, LowercaseIfNecessary(std::move(name)), - g_null_atom)); + return std::make_pair(kNotFound, + QualifiedName(LowercaseIfNecessary(std::move(name)))); } AttributeCollection attributes = GetElementData()->Attributes(); wtf_size_t index = attributes.FindIndexHinted(name, hint); return std::make_pair( - index, - index != kNotFound - ? attributes[index].GetName() - : QualifiedName(g_null_atom, LowercaseIfNecessary(std::move(name)), - g_null_atom)); + index, index != kNotFound + ? attributes[index].GetName() + : QualifiedName(LowercaseIfNecessary(std::move(name)))); } void Element::setAttribute(const QualifiedName& name,
diff --git a/third_party/blink/renderer/core/dom/events/event.cc b/third_party/blink/renderer/core/dom/events/event.cc index 1addb2c..bb5f18f 100644 --- a/third_party/blink/renderer/core/dom/events/event.cc +++ b/third_party/blink/renderer/core/dom/events/event.cc
@@ -289,25 +289,12 @@ } } -ScriptValue Event::path(ScriptState* script_state) const { - Deprecation::CountDeprecation(ExecutionContext::From(script_state), - WebFeature::kEventPath); - return ScriptValue( - script_state->GetIsolate(), - ToV8(PathInternal(script_state, kNonEmptyAfterDispatch), script_state)); -} - -HeapVector<Member<EventTarget>> Event::composedPath( - ScriptState* script_state) const { - return PathInternal(script_state, kEmptyAfterDispatch); -} - void Event::SetHandlingPassive(PassiveMode mode) { handling_passive_ = mode; } -HeapVector<Member<EventTarget>> Event::PathInternal(ScriptState* script_state, - EventPathMode mode) const { +HeapVector<Member<EventTarget>> Event::composedPath( + ScriptState* script_state) const { if (!current_target_) { DCHECK_EQ(Event::PhaseType::kNone, event_phase_); if (!event_path_) { @@ -316,10 +303,7 @@ } DCHECK(!event_path_->IsEmpty()); // After dispatching the event - if (mode == kEmptyAfterDispatch) - return HeapVector<Member<EventTarget>>(); - return event_path_->Last().GetTreeScopeEventContext().EnsureEventPath( - *event_path_); + return HeapVector<Member<EventTarget>>(); } if (Node* node = current_target_->ToNode()) {
diff --git a/third_party/blink/renderer/core/dom/events/event.h b/third_party/blink/renderer/core/dom/events/event.h index a4cc0a5..7e59468 100644 --- a/third_party/blink/renderer/core/dom/events/event.h +++ b/third_party/blink/renderer/core/dom/events/event.h
@@ -44,7 +44,6 @@ class EventTarget; class Node; class ScriptState; -class ScriptValue; class CORE_EXPORT Event : public ScriptWrappable { DEFINE_WRAPPERTYPEINFO(); @@ -264,7 +263,6 @@ } void InitEventPath(Node&); - ScriptValue path(ScriptState*) const; HeapVector<Member<EventTarget>> composedPath(ScriptState*) const; bool IsBeingDispatched() const { return eventPhase() != PhaseType::kNone; } @@ -322,11 +320,6 @@ PassiveMode HandlingPassive() const { return handling_passive_; } private: - enum EventPathMode { kEmptyAfterDispatch, kNonEmptyAfterDispatch }; - - HeapVector<Member<EventTarget>> PathInternal(ScriptState*, - EventPathMode) const; - AtomicString type_; unsigned bubbles_ : 1; unsigned cancelable_ : 1;
diff --git a/third_party/blink/renderer/core/dom/events/event.idl b/third_party/blink/renderer/core/dom/events/event.idl index a31175b5..5566b4b8 100644 --- a/third_party/blink/renderer/core/dom/events/event.idl +++ b/third_party/blink/renderer/core/dom/events/event.idl
@@ -54,8 +54,4 @@ [MeasureAs=EventSrcElement] readonly attribute EventTarget srcElement; [MeasureAs=EventReturnValue, CallWith=ScriptState, ImplementedAs=legacyReturnValue] attribute boolean returnValue; [MeasureAs=EventCancelBubble, CallWith=ScriptState] attribute boolean cancelBubble; - - // Non-standard APIs - [MeasureAs=EventPath, CallWith=ScriptState, RuntimeEnabled=EventPath] - readonly attribute object path; };
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index a22baa0..3d11917 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -3010,16 +3010,15 @@ if (EnclosingLinkEventParentOrSelf()) return; - // Avoid that canBeScrolledAndHasScrollableArea changes layout tree - // structure. + // Avoid that IsUserScrollable changes layout tree structure. // FIXME: We should avoid synchronous layout if possible. We can // remove this synchronous layout if we avoid synchronous layout in // LayoutTextControlSingleLine::scrollHeight GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kInput); LayoutObject* layout_object = GetLayoutObject(); - while (layout_object && (!layout_object->IsBox() || - !To<LayoutBox>(layout_object) - ->CanBeScrolledAndHasScrollableArea())) { + while (layout_object && + (!layout_object->IsBox() || + !To<LayoutBox>(layout_object)->IsUserScrollable())) { if (auto* document = DynamicTo<Document>(layout_object->GetNode())) { Element* owner = document->LocalOwner(); layout_object = owner ? owner->GetLayoutObject() : nullptr;
diff --git a/third_party/blink/renderer/core/dom/pseudo_element.cc b/third_party/blink/renderer/core/dom/pseudo_element.cc index 6baef74..3fa694a 100644 --- a/third_party/blink/renderer/core/dom/pseudo_element.cc +++ b/third_party/blink/renderer/core/dom/pseudo_element.cc
@@ -74,70 +74,58 @@ const QualifiedName& PseudoElementTagName(PseudoId pseudo_id) { switch (pseudo_id) { case kPseudoIdAfter: { - DEFINE_STATIC_LOCAL(QualifiedName, after, - (g_null_atom, AtomicString("::after"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, after, (AtomicString("::after"))); return after; } case kPseudoIdBefore: { - DEFINE_STATIC_LOCAL(QualifiedName, before, - (g_null_atom, AtomicString("::before"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, before, (AtomicString("::before"))); return before; } case kPseudoIdBackdrop: { - DEFINE_STATIC_LOCAL( - QualifiedName, backdrop, - (g_null_atom, AtomicString("::backdrop"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, backdrop, + (AtomicString("::backdrop"))); return backdrop; } case kPseudoIdFirstLetter: { - DEFINE_STATIC_LOCAL( - QualifiedName, first_letter, - (g_null_atom, AtomicString("::first-letter"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, first_letter, + (AtomicString("::first-letter"))); return first_letter; } case kPseudoIdMarker: { - DEFINE_STATIC_LOCAL(QualifiedName, marker, - (g_null_atom, AtomicString("::marker"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, marker, (AtomicString("::marker"))); return marker; } case kPseudoIdViewTransition: { - DEFINE_STATIC_LOCAL( - QualifiedName, transition, - (g_null_atom, AtomicString("::view-transition"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, transition, + (AtomicString("::view-transition"))); return transition; } case kPseudoIdViewTransitionGroup: { // TODO(khushalsagar) : Update these tag names to include the additional // ID. - DEFINE_STATIC_LOCAL( - QualifiedName, transition_container, - (g_null_atom, AtomicString("::view-transition-group"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, transition_container, + (AtomicString("::view-transition-group"))); return transition_container; } case kPseudoIdViewTransitionImagePair: { - DEFINE_STATIC_LOCAL( - QualifiedName, transition_image_wrapper, - (g_null_atom, AtomicString("::view-transition-image-pair"), - g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, transition_image_wrapper, + (AtomicString("::view-transition-image-pair"))); return transition_image_wrapper; } case kPseudoIdViewTransitionNew: { - DEFINE_STATIC_LOCAL( - QualifiedName, transition_incoming_image, - (g_null_atom, AtomicString("::view-transition-new"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, transition_incoming_image, + (AtomicString("::view-transition-new"))); return transition_incoming_image; } case kPseudoIdViewTransitionOld: { - DEFINE_STATIC_LOCAL( - QualifiedName, transition_outgoing_image, - (g_null_atom, AtomicString("::view-transition-old"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, transition_outgoing_image, + (AtomicString("::view-transition-old"))); return transition_outgoing_image; } default: NOTREACHED(); } - DEFINE_STATIC_LOCAL(QualifiedName, name, - (g_null_atom, AtomicString("::unknown"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, name, (AtomicString("::unknown"))); return name; }
diff --git a/third_party/blink/renderer/core/dom/qualified_name.cc b/third_party/blink/renderer/core/dom/qualified_name.cc index 34ae1bb..d92438cf 100644 --- a/third_party/blink/renderer/core/dom/qualified_name.cc +++ b/third_party/blink/renderer/core/dom/qualified_name.cc
@@ -84,6 +84,9 @@ impl_->Release(); } +QualifiedName::QualifiedName(const AtomicString& local_name) + : QualifiedName(g_null_atom, local_name, g_null_atom) {} + QualifiedName::QualifiedName(const AtomicString& p, const AtomicString& l, const AtomicString& n,
diff --git a/third_party/blink/renderer/core/dom/qualified_name.h b/third_party/blink/renderer/core/dom/qualified_name.h index 1ca692ac..cfa206d 100644 --- a/third_party/blink/renderer/core/dom/qualified_name.h +++ b/third_party/blink/renderer/core/dom/qualified_name.h
@@ -107,6 +107,9 @@ QualifiedName(const AtomicString& prefix, const AtomicString& local_name, const AtomicString& namespace_uri); + // Creates a QualifiedName instance with null prefix, the specified local + // name, and null namespace. + explicit QualifiedName(const AtomicString& local_name); ~QualifiedName(); QualifiedName(const QualifiedName& other) = default;
diff --git a/third_party/blink/renderer/core/dom/qualified_name_test.cc b/third_party/blink/renderer/core/dom/qualified_name_test.cc new file mode 100644 index 0000000..78a1a557 --- /dev/null +++ b/third_party/blink/renderer/core/dom/qualified_name_test.cc
@@ -0,0 +1,22 @@ +// 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 "third_party/blink/renderer/core/dom/qualified_name.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace blink { + +class QualifiedNameTest : public testing::Test {}; + +TEST_F(QualifiedNameTest, Constructor1) { + QualifiedName name{AtomicString("foo")}; + EXPECT_EQ(name.Prefix(), g_null_atom); + EXPECT_EQ(name.LocalName(), AtomicString("foo")); + EXPECT_EQ(name.NamespaceURI(), g_null_atom); + + EXPECT_EQ(name, QualifiedName(g_null_atom, AtomicString("foo"), g_null_atom)); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc index 6b24a72c..ed87175 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.cc
@@ -694,20 +694,32 @@ return InsertTextAndMoveCaret(text, relative_caret_position, ime_text_spans); } -bool InputMethodController::ReplaceText(const String& text, - PlainTextRange range) { +bool InputMethodController::ReplaceTextAndMoveCaret( + const String& text, + PlainTextRange range, + MoveCaretBehavior move_caret_behavior) { EventQueueScope scope; const PlainTextRange old_selection(GetSelectionOffsets()); if (!SetSelectionOffsets(range)) return false; if (!InsertText(text)) return false; - wtf_size_t selection_delta = text.length() - range.length(); - wtf_size_t start = old_selection.Start(); - wtf_size_t end = old_selection.End(); - return SetSelectionOffsets( - {start >= range.End() ? start + selection_delta : start, - end >= range.End() ? end + selection_delta : end}); + + switch (move_caret_behavior) { + case MoveCaretBehavior::kMoveCaretAfterText: { + wtf_size_t absolute_caret_position = range.Start() + text.length(); + return SetSelectionOffsets( + {absolute_caret_position, absolute_caret_position}); + } + case MoveCaretBehavior::kDoNotMove: { + wtf_size_t selection_delta = text.length() - range.length(); + wtf_size_t start = old_selection.Start(); + wtf_size_t end = old_selection.End(); + return SetSelectionOffsets( + {start >= range.End() ? start + selection_delta : start, + end >= range.End() ? end + selection_delta : end}); + } + } } bool InputMethodController::ReplaceComposition(const String& text) { @@ -1556,11 +1568,12 @@ return; } - ReplaceText( + ReplaceTextAndMoveCaret( replacement_text, PlainTextRange( std::max(static_cast<int>(selection_offsets.Start()) - before, 0), - selection_offsets.End() + after)); + selection_offsets.End() + after), + MoveCaretBehavior::kMoveCaretAfterText); } void InputMethodController::GetLayoutBounds(gfx::Rect* control_bounds,
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller.h b/third_party/blink/renderer/core/editing/ime/input_method_controller.h index d9fb2bc..9e93d538 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller.h +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller.h
@@ -60,6 +60,8 @@ kKeepSelection, }; + enum class MoveCaretBehavior { kDoNotMove, kMoveCaretAfterText }; + explicit InputMethodController(LocalDOMWindow&, LocalFrame&); InputMethodController(const InputMethodController&) = delete; InputMethodController& operator=(const InputMethodController&) = delete; @@ -89,8 +91,11 @@ const Vector<ImeTextSpan>& ime_text_spans, int relative_caret_position); - // Replaces the text in the specified range without changing the selection. - bool ReplaceText(const String&, PlainTextRange); + // Replaces the text in the specified range and possibly changes the selection + // or the caret position. + bool ReplaceTextAndMoveCaret(const String&, + PlainTextRange, + MoveCaretBehavior); // Inserts ongoing composing text; changes the selection to the end of // the inserting text if DoNotKeepSelection, or holds the selection if
diff --git a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc index e807f6e3..13ee674 100644 --- a/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc +++ b/third_party/blink/renderer/core/editing/ime/input_method_controller_test.cc
@@ -1079,6 +1079,111 @@ EXPECT_EQ("\xED\xA0\xBC\xE2\x98\x85\xED\xBF\x86", input->Value().Utf8()); } +TEST_F(InputMethodControllerTest, ReplaceTextAndDoNotChangeSelection) { + auto* input = + To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample")); + + // The replaced range does not overlap with the selection range. + input->SetValue("Hello world!"); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest); + EXPECT_EQ("Hello world!", input->Value()); + // Select "world!". + Controller().SetEditableSelectionOffsets(PlainTextRange(6, 12)); + // Replace "Hello" with "Hi". + Controller().ReplaceTextAndMoveCaret( + "Hi", PlainTextRange(0, 5), + InputMethodController::MoveCaretBehavior::kDoNotMove); + EXPECT_EQ("Hi world!", input->Value()); + // The selection is still "world!". + EXPECT_EQ(3u, Controller().GetSelectionOffsets().Start()); + EXPECT_EQ(9u, Controller().GetSelectionOffsets().End()); + + // The replaced range is the same as the selection range. + input->SetValue("Hello world!"); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest); + EXPECT_EQ("Hello world!", input->Value()); + // Select "Hello". + Controller().SetEditableSelectionOffsets(PlainTextRange(0, 5)); + // Replace "Hello" with "Hi". + Controller().ReplaceTextAndMoveCaret( + "Hi", PlainTextRange(0, 5), + InputMethodController::MoveCaretBehavior::kDoNotMove); + EXPECT_EQ("Hi world!", input->Value()); + + // The new selection is "Hi". + EXPECT_EQ(0u, Controller().GetSelectionOffsets().Start()); + EXPECT_EQ(2u, Controller().GetSelectionOffsets().End()); + + // The replaced range partially overlaps with the selection range. + input->SetValue("Hello world!"); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest); + EXPECT_EQ("Hello world!", input->Value()); + // Select "Hello". + Controller().SetEditableSelectionOffsets(PlainTextRange(0, 5)); + // Replace "He" with "Hi". + Controller().ReplaceTextAndMoveCaret( + "Hi", PlainTextRange(0, 2), + InputMethodController::MoveCaretBehavior::kDoNotMove); + EXPECT_EQ("Hillo world!", input->Value()); + // The selection is still "Hillo". + EXPECT_EQ(0u, Controller().GetSelectionOffsets().Start()); + EXPECT_EQ(5u, Controller().GetSelectionOffsets().End()); +} + +TEST_F(InputMethodControllerTest, + ReplaceTextAndMoveCursorAfterTheReplacementText) { + auto* input = + To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample")); + + // The caret should always move to the end of the replacement text no matter + // where the current selection is. + + input->SetValue("Good morning!"); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest); + EXPECT_EQ("Good morning!", input->Value()); + // Select "Good". + Controller().SetEditableSelectionOffsets(PlainTextRange(0, 4)); + // Replace "morning" with "night". The replaced range does not overlap with + // the selection range. + Controller().ReplaceTextAndMoveCaret( + "night", PlainTextRange(5, 12), + InputMethodController::MoveCaretBehavior::kMoveCaretAfterText); + EXPECT_EQ("Good night!", input->Value()); + // The caret should be after "night". + EXPECT_EQ(10u, Controller().GetSelectionOffsets().Start()); + EXPECT_EQ(10u, Controller().GetSelectionOffsets().End()); + + input->SetValue("Good morning!"); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest); + EXPECT_EQ("Good morning!", input->Value()); + // Select "morning". + Controller().SetEditableSelectionOffsets(PlainTextRange(5, 12)); + // Replace "morning" with "night". The replaced range is the same as the + // selection range. + Controller().ReplaceTextAndMoveCaret( + "night", PlainTextRange(5, 12), + InputMethodController::MoveCaretBehavior::kMoveCaretAfterText); + EXPECT_EQ("Good night!", input->Value()); + // The caret should be after "night". + EXPECT_EQ(10u, Controller().GetSelectionOffsets().Start()); + EXPECT_EQ(10u, Controller().GetSelectionOffsets().End()); + + input->SetValue("Good morning!"); + GetDocument().UpdateStyleAndLayout(DocumentUpdateReason::kTest); + EXPECT_EQ("Good morning!", input->Value()); + // Select "d mo". + Controller().SetEditableSelectionOffsets(PlainTextRange(3, 7)); + // Replace "morning" with "night". The replaced range partially overlaps with + // the selection range. + Controller().ReplaceTextAndMoveCaret( + "night", PlainTextRange(5, 12), + InputMethodController::MoveCaretBehavior::kMoveCaretAfterText); + EXPECT_EQ("Good night!", input->Value()); + // The caret should be after "night". + EXPECT_EQ(10u, Controller().GetSelectionOffsets().Start()); + EXPECT_EQ(10u, Controller().GetSelectionOffsets().End()); +} + TEST_F(InputMethodControllerTest, SetCompositionForInputWithNewCaretPositions) { auto* input = To<HTMLInputElement>(InsertHTMLElement("<input id='sample'>", "sample"));
diff --git a/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture.cc b/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture.cc index e1e5ab09..07a21e9 100644 --- a/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture.cc +++ b/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture.cc
@@ -299,13 +299,19 @@ absl::optional<PlainTextRange> StylusWritingTwoRectGesture::GestureRange( LocalFrame* local_frame, const mojom::blink::StylusWritingGestureGranularity granularity) { + Element* const root_editable_element = + local_frame->Selection().RootEditableElementOrDocumentElement(); if (start_rect_.IsEmpty() && end_rect_.IsEmpty()) { - return GestureRangeForPoints(local_frame, start_rect_.origin(), - end_rect_.origin(), granularity); + start_rect_.UnionEvenIfEmpty(end_rect_); + start_rect_.InclusiveIntersect(root_editable_element->BoundsInWidget()); + return GestureRangeForPoints(local_frame, start_rect_.left_center(), + start_rect_.right_center(), granularity); } + start_rect_.InclusiveIntersect(root_editable_element->BoundsInWidget()); absl::optional<PlainTextRange> first_range = GestureRangeForPoints(local_frame, start_rect_.left_center(), start_rect_.right_center(), granularity); + end_rect_.InclusiveIntersect(root_editable_element->BoundsInWidget()); absl::optional<PlainTextRange> last_range = GestureRangeForPoints(local_frame, end_rect_.left_center(), end_rect_.right_center(), granularity); @@ -369,7 +375,9 @@ InputMethodController& input_method_controller = frame->GetInputMethodController(); - input_method_controller.ReplaceText("", space_range.value()); + input_method_controller.ReplaceTextAndMoveCaret( + "", space_range.value(), + InputMethodController::MoveCaretBehavior::kDoNotMove); input_method_controller.SetEditableSelectionOffsets( PlainTextRange(space_range->Start(), space_range->Start())); return true; @@ -476,8 +484,9 @@ } // Remove spaces found. - input_method_controller.ReplaceText("", - PlainTextRange(space_start, space_end)); + input_method_controller.ReplaceTextAndMoveCaret( + "", PlainTextRange(space_start, space_end), + InputMethodController::MoveCaretBehavior::kDoNotMove); input_method_controller.SetEditableSelectionOffsets( PlainTextRange(space_start, space_start)); return true;
diff --git a/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture_test.cc b/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture_test.cc index daea3b4..a926056 100644 --- a/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture_test.cc +++ b/third_party/blink/renderer/core/editing/ime/stylus_writing_gesture_test.cc
@@ -317,6 +317,32 @@ last_gesture_result); } +TEST_P(StylusWritingGestureTest, + TestGestureDeleteMultilinePartiallyOutsideBounds) { + const bool is_RTL = GetParam(); + auto* input = SetUpMultilineInput(is_RTL); + input->SetValue("ABCD\nEFGH"); + const int width = input->BoundsInWidget().width(); + + mojom::blink::StylusWritingGestureDataPtr gesture_data( + mojom::blink::StylusWritingGestureData::New()); + gesture_data->action = mojom::blink::StylusWritingGestureAction::DELETE_TEXT; + gesture_data->start_rect = GetRect(20, 2, 100, 4, width, is_RTL); + gesture_data->end_rect = GetRect(-10, 16, 30, 0, width, is_RTL); + gesture_data->text_alternative = text_alternative; + + WidgetImpl()->HandleStylusWritingGestureAction( + std::move(gesture_data), + WTF::BindOnce(&StylusWritingGestureTest::ResultCallback, + base::Unretained(this))); + WebRange range = Controller()->GetSelectionOffsets(); + EXPECT_EQ("ABGH", input->Value()); + EXPECT_EQ(2, range.StartOffset()); + EXPECT_EQ(2, range.EndOffset()); + EXPECT_EQ(mojom::blink::HandwritingGestureResult::kSuccess, + last_gesture_result); +} + TEST_P(StylusWritingGestureTest, TestGestureRemoveSpaces) { const bool is_RTL = GetParam(); auto* input = SetUpSingleInput(is_RTL); @@ -445,6 +471,31 @@ last_gesture_result); } +TEST_P(StylusWritingGestureTest, TestGestureSelectPartiallyOutsideBounds) { + const bool is_RTL = GetParam(); + auto* input = SetUpSingleInput(is_RTL); + input->SetValue("ABCD EFGH"); + const int width = input->BoundsInWidget().width(); + + mojom::blink::StylusWritingGestureDataPtr gesture_data( + mojom::blink::StylusWritingGestureData::New()); + gesture_data->action = mojom::blink::StylusWritingGestureAction::SELECT_TEXT; + gesture_data->start_rect = GetRect(-10, 6, 0, 0, width, is_RTL); + gesture_data->end_rect = GetRect(30, 6, 0, 0, width, is_RTL); + gesture_data->text_alternative = text_alternative; + + WidgetImpl()->HandleStylusWritingGestureAction( + std::move(gesture_data), + WTF::BindOnce(&StylusWritingGestureTest::ResultCallback, + base::Unretained(this))); + WebRange range = Controller()->GetSelectionOffsets(); + EXPECT_EQ("ABCD EFGH", input->Value()); + EXPECT_EQ(0, range.StartOffset()); + EXPECT_EQ(3, range.EndOffset()); + EXPECT_EQ(mojom::blink::HandwritingGestureResult::kSuccess, + last_gesture_result); +} + TEST_P(StylusWritingGestureTest, TestGestureAddSpaceOrText) { const bool is_RTL = GetParam(); auto* input = SetUpSingleInput(is_RTL);
diff --git a/third_party/blink/renderer/core/editing/serializers/serialization.cc b/third_party/blink/renderer/core/editing/serializers/serialization.cc index 2d40f8c00..6588f95b 100644 --- a/third_party/blink/renderer/core/editing/serializers/serialization.cc +++ b/third_party/blink/renderer/core/editing/serializers/serialization.cc
@@ -98,7 +98,7 @@ DISALLOW_NEW(); public: - AttributeChange() : name_(g_null_atom, g_null_atom, g_null_atom) {} + AttributeChange() : name_(QualifiedName::Null()) {} AttributeChange(Element* element, const QualifiedName& name,
diff --git a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc index 93ca084..9d9a5c0 100644 --- a/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc +++ b/third_party/blink/renderer/core/exported/web_input_method_controller_impl.cc
@@ -156,9 +156,11 @@ GetFrame()->GetDocument()->UpdateStyleAndLayout(DocumentUpdateReason::kInput); if (!replacement_range.IsNull()) { - return GetInputMethodController().ReplaceText( - text, PlainTextRange(replacement_range.StartOffset(), - replacement_range.EndOffset())); + return GetInputMethodController().ReplaceTextAndMoveCaret( + text, + PlainTextRange(replacement_range.StartOffset(), + replacement_range.EndOffset()), + InputMethodController::MoveCaretBehavior::kDoNotMove); } return GetInputMethodController().CommitText(
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc index 2f05be9..ae4750a27 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer.cc
@@ -8,11 +8,15 @@ #include "base/auto_reset.h" #include "base/numerics/safe_conversions.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fetch/body.h" +#include "third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.h" +#include "third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.h" #include "third_party/blink/renderer/core/fetch/bytes_consumer_tee.h" #include "third_party/blink/renderer/core/fetch/bytes_uploader.h" #include "third_party/blink/renderer/core/fetch/readable_stream_bytes_consumer.h" +#include "third_party/blink/renderer/core/streams/readable_byte_stream_controller.h" #include "third_party/blink/renderer/core/streams/readable_stream.h" #include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h" #include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h" @@ -20,6 +24,7 @@ #include "third_party/blink/renderer/platform/bindings/exception_code.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h" +#include "third_party/blink/renderer/platform/bindings/to_v8.h" #include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h" #include "third_party/blink/renderer/platform/blob/blob_data.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" @@ -27,6 +32,7 @@ #include "third_party/blink/renderer/platform/network/encoded_form_data.h" #include "third_party/blink/renderer/platform/scheduler/public/frame_or_worker_scheduler.h" #include "third_party/blink/renderer/platform/wtf/functional.h" +#include "v8/include/v8.h" namespace blink { @@ -126,7 +132,7 @@ AbortSignal* signal, ScriptCachedMetadataHandler* cached_metadata_handler, scoped_refptr<BlobDataHandle> side_data_blob) - : UnderlyingSourceBase(script_state), + : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)), script_state_(script_state), consumer_(consumer), signal_(signal), @@ -137,8 +143,19 @@ void BodyStreamBuffer::Init() { DCHECK(consumer_); - stream_ = - ReadableStream::CreateWithCountQueueingStrategy(script_state_, this, 0); + if (RuntimeEnabledFeatures::ByobFetchEnabled()) { + underlying_byte_source_ = + MakeGarbageCollected<BodyStreamBufferUnderlyingByteSource>( + script_state_, this); + stream_ = ReadableStream::CreateByteStream(script_state_, + underlying_byte_source_); + } else { + underlying_source_ = MakeGarbageCollected<BodyStreamBufferUnderlyingSource>( + script_state_, this); + + stream_ = ReadableStream::CreateWithCountQueueingStrategy( + script_state_, underlying_source_, 0); + } stream_broken_ = !stream_; // ContextDestroyed() can be called inside the ReadableStream constructor when @@ -166,7 +183,7 @@ ReadableStream* stream, ScriptCachedMetadataHandler* cached_metadata_handler, scoped_refptr<BlobDataHandle> side_data_blob) - : UnderlyingSourceBase(script_state), + : ExecutionContextLifecycleObserver(ExecutionContext::From(script_state)), script_state_(script_state), stream_(stream), signal_(nullptr), @@ -280,7 +297,16 @@ ReadableStream* stream1 = nullptr; ReadableStream* stream2 = nullptr; - stream_->Tee(script_state_, &stream1, &stream2, true, exception_state); + // IsByteStreamController() can be false if the stream was constructed from + // a user-defined stream. + if (RuntimeEnabledFeatures::ByobFetchEnabled() && + stream_->GetController()->IsByteStreamController()) { + stream_->ByteStreamTee(script_state_, &stream1, &stream2, + exception_state); + } else { + DCHECK(stream_->GetController()->IsDefaultController()); + stream_->Tee(script_state_, &stream1, &stream2, true, exception_state); + } if (exception_state.HadException()) { stream_broken_ = true; return; @@ -307,35 +333,32 @@ cached_metadata_handler, side_data_blob); } -ScriptPromise BodyStreamBuffer::pull(ScriptState* script_state) { - DCHECK_EQ(script_state, script_state_); - if (!consumer_) { - // This is a speculative workaround for a crash. See - // https://crbug.com/773525. - // TODO(yhirano): Remove this branch or have a better comment. - return ScriptPromise::CastUndefined(script_state); - } - - if (stream_needs_more_) - return ScriptPromise::CastUndefined(script_state); - stream_needs_more_ = true; - if (!in_process_data_) - ProcessData(); - return ScriptPromise::CastUndefined(script_state); -} - ScriptPromise BodyStreamBuffer::Cancel(ScriptState* script_state, ScriptValue reason) { - DCHECK_EQ(script_state, script_state_); - Controller()->Close(); - CancelConsumer(); - return ScriptPromise::CastUndefined(script_state); + if (underlying_byte_source_) { + ExceptionState exception_state(script_state->GetIsolate(), + ExceptionState::kUnknownContext, "", ""); + ScriptPromise cancel_promise = underlying_byte_source_->Cancel( + ToV8(reason, script_state->GetContext()->Global(), + script_state->GetIsolate()), + exception_state); + if (exception_state.HadException()) { + exception_state.ClearException(); + return ScriptPromise::CastUndefined(script_state); + } else { + return cancel_promise; + } + } else { + CHECK(underlying_source_); + return underlying_source_->Cancel(script_state, reason); + } } void BodyStreamBuffer::OnStateChange() { if (!consumer_ || !GetExecutionContext() || - GetExecutionContext()->IsContextDestroyed()) + GetExecutionContext()->IsContextDestroyed()) { return; + } switch (consumer_->GetPublicState()) { case BytesConsumer::PublicState::kReadableOrWaiting: @@ -352,7 +375,6 @@ void BodyStreamBuffer::ContextDestroyed() { CancelConsumer(); - UnderlyingSourceBase::ContextDestroyed(); keep_alive_.Clear(); } @@ -403,6 +425,8 @@ void BodyStreamBuffer::Trace(Visitor* visitor) const { visitor->Trace(script_state_); visitor->Trace(stream_); + visitor->Trace(underlying_byte_source_); + visitor->Trace(underlying_source_); visitor->Trace(stream_uploader_); visitor->Trace(consumer_); visitor->Trace(loader_); @@ -410,7 +434,7 @@ visitor->Trace(stream_buffer_abort_handle_); visitor->Trace(loader_client_abort_handle_); visitor->Trace(cached_metadata_handler_); - UnderlyingSourceBase::Trace(visitor); + ExecutionContextLifecycleObserver::Trace(visitor); } void BodyStreamBuffer::Abort() { @@ -418,24 +442,64 @@ DCHECK(!consumer_); return; } - Controller()->Error( - MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError)); + if (underlying_byte_source_) { + auto* byte_controller = + To<ReadableByteStreamController>(stream_->GetController()); + v8::Local<v8::Value> dom_exception = V8ThrowDOMException::CreateOrEmpty( + script_state_->GetIsolate(), DOMExceptionCode::kAbortError, + "BodyStreamBuffer was aborted"); + CHECK(!dom_exception.IsEmpty()); + ReadableByteStreamController::Error(script_state_, byte_controller, + dom_exception); + } else { + CHECK(underlying_source_); + underlying_source_->Controller()->Error( + MakeGarbageCollected<DOMException>(DOMExceptionCode::kAbortError)); + } CancelConsumer(); } void BodyStreamBuffer::Close() { // Close() can be called during construction, in which case Controller() // will not be set yet. - if (Controller()) - Controller()->Close(); + if (underlying_byte_source_) { + ExceptionState exception_state(script_state_->GetIsolate(), + ExceptionState::kUnknownContext, "", ""); + if (script_state_->ContextIsValid()) { + ScriptState::Scope scope(script_state_); + stream_->CloseStream(script_state_, exception_state); + } else { + // If the context is not valid then Close() will not try to resolve the + // promises, and that is not a problem. + stream_->CloseStream(script_state_, exception_state); + } + if (exception_state.HadException()) { + DLOG(WARNING) << "Controller::close throws exception " + << exception_state.Code() << ", " + << exception_state.Message(); + exception_state.ClearException(); + return; + } + } else if (underlying_source_->Controller()) { + underlying_source_->Controller()->Close(); + } CancelConsumer(); } void BodyStreamBuffer::GetError() { { ScriptState::Scope scope(script_state_); - Controller()->Error(V8ThrowException::CreateTypeError( - script_state_->GetIsolate(), "network error")); + auto error = V8ThrowException::CreateTypeError(script_state_->GetIsolate(), + "network error"); + if (underlying_byte_source_) { + auto* byte_controller = + To<ReadableByteStreamController>(stream_->GetController()); + ReadableByteStreamController::Error(script_state_, byte_controller, + error); + } else { + CHECK(underlying_source_); + underlying_source_->Controller()->Error(error); + } } CancelConsumer(); } @@ -443,8 +507,17 @@ void BodyStreamBuffer::RaiseOOMError() { { ScriptState::Scope scope(script_state_); - Controller()->Error(V8ThrowException::CreateRangeError( - script_state_->GetIsolate(), "Array buffer allocation failed")); + auto error = V8ThrowException::CreateRangeError( + script_state_->GetIsolate(), "Array buffer allocation failed"); + if (underlying_byte_source_) { + auto* byte_controller = + To<ReadableByteStreamController>(stream_->GetController()); + ReadableByteStreamController::Error(script_state_, byte_controller, + error); + } else { + CHECK(underlying_source_); + underlying_source_->Controller()->Error(error); + } } CancelConsumer(); } @@ -471,6 +544,9 @@ return; DOMUint8Array* array = nullptr; if (result == BytesConsumer::Result::kOk) { + // TODO(nidhijaju): Follow the algorithm in + // https://streams.spec.whatwg.org/#readablestream-enqueue, i.e. don't + // create a new array if there is a current BYOB request view. array = DOMUint8Array::CreateOrNull( reinterpret_cast<const unsigned char*>(buffer), base::checked_cast<uint32_t>(available)); @@ -484,19 +560,48 @@ case BytesConsumer::Result::kOk: case BytesConsumer::Result::kDone: if (array) { - // Clear m_streamNeedsMore in order to detect a pull call. + // Clear |stream_needs_more_| in order to detect a pull call. stream_needs_more_ = false; - Controller()->Enqueue(array); + if (underlying_byte_source_) { + ScriptState::Scope scope(script_state_); + auto* byte_controller = + To<ReadableByteStreamController>(stream_->GetController()); + ExceptionState exception_state(script_state_->GetIsolate(), + ExceptionState::kUnknownContext, "", + ""); + ReadableByteStreamController::Enqueue( + script_state_, byte_controller, NotShared(array), + exception_state); + if (exception_state.HadException()) { + exception_state.ClearException(); + return; + } + } else { + CHECK(underlying_source_); + underlying_source_->Controller()->Enqueue(array); + } } if (result == BytesConsumer::Result::kDone) { Close(); return; } - // If m_streamNeedsMore is true, it means that pull is called and + // If |stream_needs_more_| is true, it means that pull is called and // the stream needs more data even if the desired size is not // positive. - if (!stream_needs_more_) - stream_needs_more_ = Controller()->DesiredSize() > 0; + if (!stream_needs_more_) { + if (underlying_byte_source_) { + auto* byte_controller = + To<ReadableByteStreamController>(stream_->GetController()); + absl::optional<double> desired_size = + ReadableByteStreamController::GetDesiredSize(byte_controller); + DCHECK(desired_size.has_value()); + stream_needs_more_ = desired_size.value() > 0; + } else { + CHECK(underlying_source_); + stream_needs_more_ = + underlying_source_->Controller()->DesiredSize() > 0; + } + } break; case BytesConsumer::Result::kShouldWait: NOTREACHED();
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer.h b/third_party/blink/renderer/core/fetch/body_stream_buffer.h index dea2d03..1243db5 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer.h +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer.h
@@ -14,23 +14,28 @@ #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/dom/abort_signal.h" #include "third_party/blink/renderer/core/dom/dom_exception.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/core/fetch/bytes_uploader.h" #include "third_party/blink/renderer/core/fetch/fetch_data_loader.h" -#include "third_party/blink/renderer/core/streams/underlying_source_base.h" #include "third_party/blink/renderer/platform/bindings/trace_wrapper_v8_reference.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h" namespace blink { +class BodyStreamBufferUnderlyingByteSource; +class BodyStreamBufferUnderlyingSource; class EncodedFormData; class ExceptionState; class ReadableStream; class ScriptState; class ScriptCachedMetadataHandler; -class CORE_EXPORT BodyStreamBuffer final : public UnderlyingSourceBase, - public BytesConsumer::Client { +class CORE_EXPORT BodyStreamBuffer final + : public GarbageCollected<BodyStreamBuffer>, + public ExecutionContextLifecycleObserver, + public BytesConsumer::Client { public: using PassKey = base::PassKey<BodyStreamBuffer>; @@ -80,9 +85,9 @@ ExceptionState&); void Tee(BodyStreamBuffer**, BodyStreamBuffer**, ExceptionState&); - // UnderlyingSourceBase - ScriptPromise pull(ScriptState*) override; - ScriptPromise Cancel(ScriptState*, ScriptValue reason) override; + ScriptPromise Cancel(ScriptState*, ScriptValue reason); + + // ExecutionContextLifecycleObserver void ContextDestroyed() override; // BytesConsumer::Client @@ -99,8 +104,6 @@ // be called if |stream_broken_| is true. void CloseAndLockAndDisturb(); - ScriptState* GetScriptState() { return script_state_; } - bool IsAborted(); // Returns the ScriptCachedMetadataHandler associated with the contents of @@ -125,6 +128,9 @@ void Trace(Visitor*) const override; private: + friend class BodyStreamBufferUnderlyingByteSource; + friend class BodyStreamBufferUnderlyingSource; + class LoaderClient; // This method exists to avoid re-entrancy inside the BodyStreamBuffer @@ -144,6 +150,8 @@ Member<ScriptState> script_state_; Member<ReadableStream> stream_; + Member<BodyStreamBufferUnderlyingByteSource> underlying_byte_source_; + Member<BodyStreamBufferUnderlyingSource> underlying_source_; Member<BytesUploader> stream_uploader_; Member<BytesConsumer> consumer_; // We need this member to keep it alive while loading.
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc index a9df890..647dd86 100644 --- a/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_test.cc
@@ -33,6 +33,7 @@ #include "third_party/blink/renderer/platform/loader/testing/replaying_bytes_consumer.h" #include "third_party/blink/renderer/platform/network/encoded_form_data.h" #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" +#include "third_party/blink/renderer/platform/testing/runtime_enabled_features_test_helpers.h" #include "third_party/blink/renderer/platform/testing/unit_test_helpers.h" namespace blink { @@ -47,7 +48,11 @@ using MockFetchDataLoaderClient = BytesConsumerTestUtil::MockFetchDataLoaderClient; -class BodyStreamBufferTest : public testing::Test { +class BodyStreamBufferTest : public testing::Test, + public ::testing::WithParamInterface<bool> { + public: + BodyStreamBufferTest() : byob_fetch_feature_(GetParam()) {} + protected: using Command = ReplayingBytesConsumer::Command; ScriptValue Eval(ScriptState* script_state, const char* s) { @@ -88,6 +93,9 @@ uint64_t length = data->length(); return BlobDataHandle::Create(std::move(data), length); } + + private: + ScopedByobFetchForTest byob_fetch_feature_; }; class MockFetchDataLoader : public FetchDataLoader { @@ -106,7 +114,11 @@ MockFetchDataLoader() = default; }; -TEST_F(BodyStreamBufferTest, Tee) { +INSTANTIATE_TEST_SUITE_P(BodyStreamBufferTest, + BodyStreamBufferTest, + testing::Bool()); + +TEST_P(BodyStreamBufferTest, Tee) { V8TestingScope scope; NonThrowableExceptionState exception_state; Checkpoint checkpoint; @@ -162,7 +174,7 @@ checkpoint.Call(4); } -TEST_F(BodyStreamBufferTest, TeeFromHandleMadeFromStream) { +TEST_P(BodyStreamBufferTest, TeeFromHandleMadeFromStream) { V8TestingScope scope; NonThrowableExceptionState exception_state; @@ -235,7 +247,7 @@ checkpoint.Call(4); } -TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandle) { +TEST_P(BodyStreamBufferTest, DrainAsBlobDataHandle) { V8TestingScope scope; scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob("hello"); scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data"); @@ -259,7 +271,7 @@ EXPECT_EQ(blob_data_handle, output_blob_data_handle); } -TEST_F(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) { +TEST_P(BodyStreamBufferTest, DrainAsBlobDataHandleReturnsNull) { V8TestingScope scope; // This BytesConsumer is not drainable. BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>( @@ -282,7 +294,7 @@ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest()); } -TEST_F(BodyStreamBufferTest, +TEST_P(BodyStreamBufferTest, DrainAsBlobFromBufferMadeFromBufferMadeFromStream) { V8TestingScope scope; NonThrowableExceptionState exception_state; @@ -304,7 +316,7 @@ EXPECT_TRUE(buffer->IsStreamReadable()); } -TEST_F(BodyStreamBufferTest, DrainAsFormData) { +TEST_P(BodyStreamBufferTest, DrainAsFormData) { V8TestingScope scope; auto* data = MakeGarbageCollected<FormData>(UTF8Encoding()); data->append("name1", "value1"); @@ -332,7 +344,7 @@ input_form_data->FlattenToString()); } -TEST_F(BodyStreamBufferTest, DrainAsFormDataReturnsNull) { +TEST_P(BodyStreamBufferTest, DrainAsFormDataReturnsNull) { V8TestingScope scope; // This BytesConsumer is not drainable. BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>( @@ -354,7 +366,7 @@ EXPECT_EQ(side_data_blob, buffer->GetSideDataBlobForTest()); } -TEST_F(BodyStreamBufferTest, +TEST_P(BodyStreamBufferTest, DrainAsFormDataFromBufferMadeFromBufferMadeFromStream) { V8TestingScope scope; NonThrowableExceptionState exception_state; @@ -374,7 +386,7 @@ EXPECT_TRUE(buffer->IsStreamReadable()); } -TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) { +TEST_P(BodyStreamBufferTest, LoadBodyStreamBufferAsArrayBuffer) { V8TestingScope scope; Checkpoint checkpoint; auto* client = MakeGarbageCollected<MockFetchDataLoaderClient>(); @@ -421,7 +433,8 @@ : fake_task_runner_(base::MakeRefCounted<scheduler::FakeTaskRunner>()), blob_registry_receiver_( &fake_blob_registry_, - blob_registry_remote_.BindNewPipeAndPassReceiver()) { + blob_registry_remote_.BindNewPipeAndPassReceiver()), + byob_fetch_feature_(GetParam()) { BlobDataHandle::SetBlobRegistryForTesting(blob_registry_remote_.get()); } @@ -436,9 +449,14 @@ FakeBlobRegistry fake_blob_registry_; mojo::Remote<mojom::blink::BlobRegistry> blob_registry_remote_; mojo::Receiver<mojom::blink::BlobRegistry> blob_registry_receiver_; + ScopedByobFetchForTest byob_fetch_feature_; }; -TEST_F(BodyStreamBufferBlobTest, LoadBodyStreamBufferAsBlob) { +INSTANTIATE_TEST_SUITE_P(BodyStreamBufferBlobTest, + BodyStreamBufferBlobTest, + testing::Bool()); + +TEST_P(BodyStreamBufferBlobTest, LoadBodyStreamBufferAsBlob) { V8TestingScope scope; Checkpoint checkpoint; auto* client = MakeGarbageCollected<MockFetchDataLoaderClient>(); @@ -479,7 +497,7 @@ EXPECT_EQ(5u, blob_data_handle->size()); } -TEST_F(BodyStreamBufferTest, LoadBodyStreamBufferAsString) { +TEST_P(BodyStreamBufferTest, LoadBodyStreamBufferAsString) { V8TestingScope scope; Checkpoint checkpoint; auto* client = MakeGarbageCollected<MockFetchDataLoaderClient>(); @@ -516,7 +534,7 @@ EXPECT_TRUE(buffer->IsStreamDisturbed()); } -TEST_F(BodyStreamBufferTest, LoadClosedHandle) { +TEST_P(BodyStreamBufferTest, LoadClosedHandle) { V8TestingScope scope; Checkpoint checkpoint; auto* client = MakeGarbageCollected<MockFetchDataLoaderClient>(); @@ -548,7 +566,7 @@ EXPECT_TRUE(buffer->IsStreamDisturbed()); } -TEST_F(BodyStreamBufferTest, LoadErroredHandle) { +TEST_P(BodyStreamBufferTest, LoadErroredHandle) { V8TestingScope scope; Checkpoint checkpoint; auto* client = MakeGarbageCollected<MockFetchDataLoaderClient>(); @@ -581,7 +599,7 @@ EXPECT_TRUE(buffer->IsStreamDisturbed()); } -TEST_F(BodyStreamBufferTest, LoaderShouldBeKeptAliveByBodyStreamBuffer) { +TEST_P(BodyStreamBufferTest, LoaderShouldBeKeptAliveByBodyStreamBuffer) { V8TestingScope scope; Checkpoint checkpoint; auto* client = MakeGarbageCollected<MockFetchDataLoaderClient>(); @@ -609,7 +627,7 @@ checkpoint.Call(2); } -TEST_F(BodyStreamBufferTest, SourceShouldBeCanceledWhenCanceled) { +TEST_P(BodyStreamBufferTest, SourceShouldBeCanceledWhenCanceled) { V8TestingScope scope; ReplayingBytesConsumer* consumer = MakeGarbageCollected<ReplayingBytesConsumer>( @@ -625,7 +643,7 @@ EXPECT_TRUE(consumer->IsCancelled()); } -TEST_F(BodyStreamBufferTest, NestedPull) { +TEST_P(BodyStreamBufferTest, NestedPull) { V8TestingScope scope; ReplayingBytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>( scope.GetDocument().GetTaskRunner(TaskType::kNetworking)); @@ -656,7 +674,7 @@ scope.PerformMicrotaskCheckpoint(); } -TEST_F(BodyStreamBufferTest, NullAbortSignalIsNotAborted) { +TEST_P(BodyStreamBufferTest, NullAbortSignalIsNotAborted) { V8TestingScope scope; // This BytesConsumer is not drainable. BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>( @@ -668,7 +686,7 @@ EXPECT_FALSE(buffer->IsAborted()); } -TEST_F(BodyStreamBufferTest, AbortSignalMakesAborted) { +TEST_P(BodyStreamBufferTest, AbortSignalMakesAborted) { V8TestingScope scope; // This BytesConsumer is not drainable. BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>( @@ -683,7 +701,7 @@ EXPECT_TRUE(buffer->IsAborted()); } -TEST_F(BodyStreamBufferTest, +TEST_P(BodyStreamBufferTest, AbortBeforeStartLoadingCallsDataLoaderClientAbort) { V8TestingScope scope; Checkpoint checkpoint; @@ -720,7 +738,7 @@ checkpoint.Call(3); } -TEST_F(BodyStreamBufferTest, AbortAfterStartLoadingCallsDataLoaderClientAbort) { +TEST_P(BodyStreamBufferTest, AbortAfterStartLoadingCallsDataLoaderClientAbort) { V8TestingScope scope; Checkpoint checkpoint; MockFetchDataLoader* loader = MockFetchDataLoader::Create(); @@ -755,7 +773,7 @@ checkpoint.Call(3); } -TEST_F(BodyStreamBufferTest, +TEST_P(BodyStreamBufferTest, AsyncAbortAfterStartLoadingCallsDataLoaderClientAbort) { V8TestingScope scope; Checkpoint checkpoint; @@ -792,7 +810,7 @@ checkpoint.Call(3); } -TEST_F(BodyStreamBufferTest, CachedMetadataHandler) { +TEST_P(BodyStreamBufferTest, CachedMetadataHandler) { V8TestingScope scope; Persistent<BodyStreamBuffer> buffer; WeakPersistent<ScriptCachedMetadataHandler> weak_handler; @@ -816,7 +834,7 @@ EXPECT_EQ(weak_handler.Get(), nullptr); } -TEST_F(BodyStreamBufferTest, CachedMetadataHandlerAndTee) { +TEST_P(BodyStreamBufferTest, CachedMetadataHandlerAndTee) { V8TestingScope scope; BytesConsumer* src = MakeGarbageCollected<ReplayingBytesConsumer>( scope.GetDocument().GetTaskRunner(TaskType::kNetworking)); @@ -835,7 +853,7 @@ EXPECT_EQ(dest2->GetCachedMetadataHandler(), handler); } -TEST_F(BodyStreamBufferTest, +TEST_P(BodyStreamBufferTest, CachedMetadataHandlerAndTeeForBufferMadeFromStream) { V8TestingScope scope; auto* handler = MakeGarbageCollected<ScriptCachedMetadataHandler>( @@ -855,7 +873,7 @@ EXPECT_EQ(dest2->GetCachedMetadataHandler(), handler); } -TEST_F(BodyStreamBufferTest, TakeSideDataBlob) { +TEST_P(BodyStreamBufferTest, TakeSideDataBlob) { V8TestingScope scope; scoped_refptr<BlobDataHandle> blob_data_handle = CreateBlob("hello"); scoped_refptr<BlobDataHandle> side_data_blob = CreateBlob("side data"); @@ -872,7 +890,7 @@ EXPECT_EQ(nullptr, buffer->TakeSideDataBlob()); } -TEST_F(BodyStreamBufferTest, KeptAliveWhileLoading) { +TEST_P(BodyStreamBufferTest, KeptAliveWhileLoading) { V8TestingScope scope; auto* isolate = scope.GetIsolate();
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.cc new file mode 100644 index 0000000..8c11b12f --- /dev/null +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.cc
@@ -0,0 +1,65 @@ +// 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 "third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h" +#include "third_party/blink/renderer/core/streams/readable_byte_stream_controller.h" +#include "third_party/blink/renderer/core/streams/readable_stream.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" +#include "third_party/blink/renderer/platform/bindings/script_state.h" + +namespace blink { + +ScriptPromise BodyStreamBufferUnderlyingByteSource::Pull( + ReadableByteStreamController* controller, + ExceptionState&) { + if (!body_stream_buffer_->consumer_) { + // This is a speculative workaround for a crash. See + // https://crbug.com/773525. + // TODO(yhirano): Remove this branch or have a better comment. + return ScriptPromise::CastUndefined(GetScriptState()); + } + + if (body_stream_buffer_->stream_needs_more_) { + return ScriptPromise::CastUndefined(GetScriptState()); + } + body_stream_buffer_->stream_needs_more_ = true; + if (!body_stream_buffer_->in_process_data_) { + body_stream_buffer_->ProcessData(); + } + return ScriptPromise::CastUndefined(GetScriptState()); +} + +ScriptPromise BodyStreamBufferUnderlyingByteSource::Cancel( + ExceptionState& exception_state) { + return Cancel(v8::Undefined(GetScriptState()->GetIsolate()), exception_state); +} + +ScriptPromise BodyStreamBufferUnderlyingByteSource::Cancel( + v8::Local<v8::Value> reason, + ExceptionState& exception_state) { + ReadableStreamController* controller = + body_stream_buffer_->Stream()->GetController(); + DCHECK(controller->IsByteStreamController()); + ReadableByteStreamController* byte_controller = + To<ReadableByteStreamController>(controller); + byte_controller->Close(GetScriptState(), byte_controller, exception_state); + DCHECK(!exception_state.HadException()); + body_stream_buffer_->CancelConsumer(); + return ScriptPromise::CastUndefined(GetScriptState()); +} + +ScriptState* BodyStreamBufferUnderlyingByteSource::GetScriptState() { + return script_state_; +} + +void BodyStreamBufferUnderlyingByteSource::Trace(Visitor* visitor) const { + visitor->Trace(script_state_); + visitor->Trace(body_stream_buffer_); + UnderlyingByteSourceBase::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.h b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.h new file mode 100644 index 0000000..c255ee3a8 --- /dev/null +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_byte_source.h
@@ -0,0 +1,46 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_UNDERLYING_BYTE_SOURCE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_UNDERLYING_BYTE_SOURCE_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/streams/underlying_byte_source_base.h" +#include "third_party/blink/renderer/platform/heap/member.h" +#include "third_party/blink/renderer/platform/heap/visitor.h" + +namespace blink { + +class BodyStreamBuffer; +class ExceptionState; +class ReadableByteStreamController; +class ScriptPromise; +class ScriptState; + +class CORE_EXPORT BodyStreamBufferUnderlyingByteSource final + : public UnderlyingByteSourceBase { + public: + explicit BodyStreamBufferUnderlyingByteSource( + ScriptState* script_state, + BodyStreamBuffer* body_stream_buffer) + : script_state_(script_state), body_stream_buffer_(body_stream_buffer) {} + + ScriptPromise Pull(ReadableByteStreamController* controller, + ExceptionState&) override; + + ScriptPromise Cancel(ExceptionState&) override; + ScriptPromise Cancel(v8::Local<v8::Value> reason, ExceptionState&) override; + + ScriptState* GetScriptState() override; + + void Trace(Visitor*) const override; + + private: + const Member<ScriptState> script_state_; + const Member<BodyStreamBuffer> body_stream_buffer_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_UNDERLYING_BYTE_SOURCE_H_
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.cc b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.cc new file mode 100644 index 0000000..2b564e30 --- /dev/null +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.cc
@@ -0,0 +1,49 @@ +// 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 "third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.h" + +#include "third_party/blink/renderer/bindings/core/v8/script_promise.h" +#include "third_party/blink/renderer/bindings/core/v8/script_value.h" +#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h" +#include "third_party/blink/renderer/platform/bindings/script_state.h" + +namespace blink { + +ScriptPromise BodyStreamBufferUnderlyingSource::pull( + ScriptState* script_state) { + DCHECK_EQ(script_state, script_state_); + if (!body_stream_buffer_->consumer_) { + // This is a speculative workaround for a crash. See + // https://crbug.com/773525. + // TODO(yhirano): Remove this branch or have a better comment. + return ScriptPromise::CastUndefined(script_state); + } + + if (body_stream_buffer_->stream_needs_more_) { + return ScriptPromise::CastUndefined(script_state); + } + body_stream_buffer_->stream_needs_more_ = true; + if (!body_stream_buffer_->in_process_data_) { + body_stream_buffer_->ProcessData(); + } + return ScriptPromise::CastUndefined(script_state); +} + +ScriptPromise BodyStreamBufferUnderlyingSource::Cancel( + ScriptState* script_state, + ScriptValue reason) { + DCHECK_EQ(script_state, script_state_); + Controller()->Close(); + body_stream_buffer_->CancelConsumer(); + return ScriptPromise::CastUndefined(script_state); +} + +void BodyStreamBufferUnderlyingSource::Trace(Visitor* visitor) const { + visitor->Trace(script_state_); + visitor->Trace(body_stream_buffer_); + UnderlyingSourceBase::Trace(visitor); +} + +} // namespace blink
diff --git a/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.h b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.h new file mode 100644 index 0000000..28395cc --- /dev/null +++ b/third_party/blink/renderer/core/fetch/body_stream_buffer_underlying_source.h
@@ -0,0 +1,43 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_UNDERLYING_SOURCE_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_UNDERLYING_SOURCE_H_ + +#include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/streams/readable_stream_default_controller_with_script_scope.h" +#include "third_party/blink/renderer/core/streams/underlying_source_base.h" + +namespace blink { + +class BodyStreamBuffer; +class ScriptState; +class ScriptPromise; + +class CORE_EXPORT BodyStreamBufferUnderlyingSource final + : public UnderlyingSourceBase { + public: + BodyStreamBufferUnderlyingSource(ScriptState* script_state, + BodyStreamBuffer* body_buffer) + : UnderlyingSourceBase(script_state), + script_state_(script_state), + body_stream_buffer_(body_buffer) {} + + ScriptPromise pull(ScriptState*) override; + ScriptPromise Cancel(ScriptState*, ScriptValue reason) override; + + ReadableStreamDefaultControllerWithScriptScope* Controller() const { + return UnderlyingSourceBase::Controller(); + } + + void Trace(Visitor*) const override; + + private: + Member<ScriptState> script_state_; + Member<BodyStreamBuffer> body_stream_buffer_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FETCH_BODY_STREAM_BUFFER_UNDERLYING_SOURCE_H_
diff --git a/third_party/blink/renderer/core/fetch/build.gni b/third_party/blink/renderer/core/fetch/build.gni index 8914568..0fea5627 100644 --- a/third_party/blink/renderer/core/fetch/build.gni +++ b/third_party/blink/renderer/core/fetch/build.gni
@@ -11,6 +11,10 @@ "body.h", "body_stream_buffer.cc", "body_stream_buffer.h", + "body_stream_buffer_underlying_byte_source.cc", + "body_stream_buffer_underlying_byte_source.h", + "body_stream_buffer_underlying_source.cc", + "body_stream_buffer_underlying_source.h", "bytes_consumer_tee.cc", "bytes_consumer_tee.h", "bytes_uploader.cc",
diff --git a/third_party/blink/renderer/core/fetch/fetch_request_data.h b/third_party/blink/renderer/core/fetch/fetch_request_data.h index d266d07..73fdec1 100644 --- a/third_party/blink/renderer/core/fetch/fetch_request_data.h +++ b/third_party/blink/renderer/core/fetch/fetch_request_data.h
@@ -17,6 +17,7 @@ #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/public/platform/web_url_request.h" #include "third_party/blink/renderer/core/core_export.h" +#include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/core/fetch/body_stream_buffer.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_load_priority.h"
diff --git a/third_party/blink/renderer/core/frame/build.gni b/third_party/blink/renderer/core/frame/build.gni index aed3356..56e502e 100644 --- a/third_party/blink/renderer/core/frame/build.gni +++ b/third_party/blink/renderer/core/frame/build.gni
@@ -262,6 +262,7 @@ "csp/csp_directive_list_test.cc", "csp/csp_source_test.cc", "csp/source_list_directive_test.cc", + "csp/test_util.h", "csp/trusted_types_directive_test.cc", "deprecation/deprecation_report_body_test.cc", "document_loading_rendering_test.cc",
diff --git a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc index 659181fb..7c2911b 100644 --- a/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc +++ b/third_party/blink/renderer/core/frame/csp/content_security_policy_test.cc
@@ -6,6 +6,7 @@ #include "base/test/scoped_feature_list.h" #include "services/network/public/cpp/features.h" +#include "testing/gmock/include/gmock/gmock-matchers.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/security_context/insecure_request_policy.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" @@ -13,6 +14,7 @@ #include "third_party/blink/renderer/core/dom/document.h" #include "third_party/blink/renderer/core/dom/document_init.h" #include "third_party/blink/renderer/core/frame/csp/csp_directive_list.h" +#include "third_party/blink/renderer/core/frame/csp/test_util.h" #include "third_party/blink/renderer/core/frame/local_dom_window.h" #include "third_party/blink/renderer/core/frame/local_frame.h" #include "third_party/blink/renderer/core/html/html_script_element.h" @@ -31,8 +33,14 @@ namespace blink { +namespace { + using network::mojom::ContentSecurityPolicySource; using network::mojom::ContentSecurityPolicyType; +using testing::Contains; +using testing::SizeIs; + +} // namespace class ContentSecurityPolicyTest : public testing::Test { public: @@ -132,6 +140,10 @@ } } +MATCHER_P(HasSubstr, s, "") { + return arg.Contains(s); +} + TEST_F(ContentSecurityPolicyTest, AddPolicies) { csp->AddPolicies(ParseContentSecurityPolicies( "script-src 'none'", ContentSecurityPolicyType::kReport, @@ -144,21 +156,35 @@ const KURL not_example_url("http://not-example.com"); auto* csp2 = MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + csp2->BindToDelegate(*test_delegate); csp2->AddPolicies(mojo::Clone(csp->GetParsedPolicies())); - EXPECT_FALSE(csp2->AllowScriptFromSource( + + EXPECT_TRUE(csp2->AllowScriptFromSource( example_url, String(), IntegrityMetadataSet(), kParserInserted, example_url, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, + ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); + EXPECT_THAT( + test_delegate->console_messages(), + Contains(HasSubstr("Refused to load the script 'http://example.com/'"))); + + test_delegate->console_messages().clear(); EXPECT_TRUE(csp2->AllowImageFromSource( example_url, example_url, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, + ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); - EXPECT_FALSE(csp2->AllowImageFromSource( + EXPECT_THAT(test_delegate->console_messages(), SizeIs(0)); + + test_delegate->console_messages().clear(); + EXPECT_TRUE(csp2->AllowImageFromSource( not_example_url, not_example_url, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, + ReportingDisposition::kReport, ContentSecurityPolicy::CheckHeaderType::kCheckReportOnly)); + EXPECT_THAT(test_delegate->console_messages(), + Contains(HasSubstr( + "Refused to load the image 'http://not-example.com/'"))); } TEST_F(ContentSecurityPolicyTest, IsActiveForConnectionsWithConnectSrc) {
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc index 2610192c..e4cfac8 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list.cc
@@ -28,6 +28,7 @@ #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/weborigin/known_ports.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h" +#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h" #include "third_party/blink/renderer/platform/wtf/text/base64.h" #include "third_party/blink/renderer/platform/wtf/text/string_builder.h" #include "third_party/blink/renderer/platform/wtf/text/string_utf8_adaptor.h" @@ -338,22 +339,6 @@ return true; } -bool CheckSource(ContentSecurityPolicy* policy, - const network::mojom::blink::CSPSourceList* directive, - const network::mojom::blink::CSPSource& self_origin, - const KURL& url, - ResourceRequest::RedirectStatus redirect_status) { - // If |url| is empty, fall back to the policy URL to ensure that <object>'s - // without a `src` can be blocked/allowed, as they can still load plugins - // even though they don't actually have a URL. - if (!directive) - return true; - - return CSPSourceListAllows( - *directive, self_origin, - url.IsEmpty() ? policy->FallbackUrlForPlugin() : url, redirect_status); -} - bool CheckEvalAndReportViolation( const network::mojom::blink::ContentSecurityPolicy& csp, ContentSecurityPolicy* policy, @@ -482,31 +467,14 @@ return true; } -bool CheckSourceAndReportViolation( +void ReportViolationForCheckSource( const network::mojom::blink::ContentSecurityPolicy& csp, ContentSecurityPolicy* policy, CSPOperativeDirective directive, const KURL& url, CSPDirectiveName effective_type, const KURL& url_before_redirects, - ResourceRequest::RedirectStatus redirect_status) { - if (!directive.source_list) - return true; - - String suffix = String(); - if (CheckSource(policy, directive.source_list, *csp.self_origin, url, - redirect_status)) { - // We ignore URL-based allowlists if we're allowing dynamic script - // injection. - if (!CheckDynamic(directive.source_list, effective_type)) { - return true; - } else { - suffix = - " Note that 'strict-dynamic' is present, so host-based allowlisting " - "is disabled."; - } - } - + String suffix) { // We should never have a violation against `child-src` // directly; the effective directive should always be one of the explicit // fetch directives, or default-src in the case of resource hints. @@ -586,9 +554,9 @@ // Wildcards match network schemes ('http', 'https', 'ws', 'wss'), and the // scheme of the protected resource: - // https://w3c.github.io/webappsec-csp/#match-url-to-source-expression. Other - // schemes, including custom schemes, must be explicitly listed in a source - // list. + // https://w3c.github.io/webappsec-csp/#match-url-to-source-expression. + // Other schemes, including custom schemes, must be explicitly listed in a + // source list. if (directive.source_list->allow_star) { suffix = suffix + " Note that '*' matches only URLs with network schemes ('http', " @@ -605,6 +573,44 @@ "Policy directive: \"" + raw_directive + "\"." + suffix + "\n", url_before_redirects); +} + +bool CheckSource(const network::mojom::blink::ContentSecurityPolicy& csp, + ContentSecurityPolicy* policy, + CSPOperativeDirective directive, + const KURL& url, + CSPDirectiveName effective_type, + const KURL& url_before_redirects, + ResourceRequest::RedirectStatus redirect_status, + ReportingDisposition reporting_disposition) { + if (!directive.source_list) { + return true; + } + + // If |url| is empty, fall back to the policy URL to ensure that + // <object>'s without a `src` can be blocked/allowed, as they can + // still load plugins even though they don't actually have a URL. + const KURL& url_to_check = + url.IsEmpty() ? policy->FallbackUrlForPlugin() : url; + String suffix = String(); + if (CSPSourceListAllows(*directive.source_list, *csp.self_origin, + url_to_check, redirect_status)) { + // We ignore URL-based allowlists if we're allowing dynamic script + // injection. + if (!CheckDynamic(directive.source_list, effective_type)) { + return true; + } else { + suffix = + " Note that 'strict-dynamic' is present, so host-based allowlisting " + "is disabled."; + } + } + + if (reporting_disposition == ReportingDisposition::kReport) { + ReportViolationForCheckSource(csp, policy, directive, url, effective_type, + url_before_redirects, suffix); + } + return CSPDirectiveListIsReportOnly(csp); } @@ -861,8 +867,9 @@ if (type == CSPDirectiveName::ScriptSrcElem) { if (parser_disposition == kNotParserInserted && - CSPDirectiveListAllowDynamic(csp, type)) + CSPDirectiveListAllowDynamic(csp, type)) { return true; + } if (AreAllMatchingHashesPresent(OperativeDirective(csp, type).source_list, hashes)) return true; @@ -870,15 +877,13 @@ CSPOperativeDirective directive = OperativeDirective(csp, type); bool result = - reporting_disposition == ReportingDisposition::kReport - ? CheckSourceAndReportViolation(csp, policy, directive, url, type, - url_before_redirects, redirect_status) - : CheckSource(policy, directive.source_list, *csp.self_origin, url, - redirect_status); + CheckSource(csp, policy, directive, url, type, url_before_redirects, + redirect_status, reporting_disposition); if (type == CSPDirectiveName::BaseURI) { - if (result && !CheckSource(policy, directive.source_list, *csp.self_origin, - url, redirect_status)) { + if (result && !CheckSource(csp, policy, directive, url, type, + url_before_redirects, redirect_status, + ReportingDisposition::kSuppressReporting)) { policy->Count(WebFeature::kBaseWouldBeBlockedByDefaultSrc); } }
diff --git a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc index 510b5c4c..bf536373 100644 --- a/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc +++ b/third_party/blink/renderer/core/frame/csp/csp_directive_list_test.cc
@@ -4,7 +4,6 @@ #include "third_party/blink/renderer/core/frame/csp/csp_directive_list.h" -#include <list> #include <string> #include "base/memory/scoped_refptr.h" @@ -16,11 +15,12 @@ #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h" #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "third_party/blink/renderer/core/frame/csp/test_util.h" #include "third_party/blink/renderer/core/inspector/console_message.h" -#include "third_party/blink/renderer/core/inspector/inspector_audits_issue.h" #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" #include "third_party/blink/renderer/platform/loader/subresource_integrity.h" #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" +#include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h" #include "third_party/blink/renderer/platform/weborigin/security_origin.h" #include "third_party/blink/renderer/platform/wtf/text/string_operators.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" @@ -33,57 +33,6 @@ class CSPDirectiveListTest : public testing::Test { public: - // Simple CSP delegate that stores the console messages logged by the - // ContentSecurityPolicy context and allows retrieving them. - class TestCSPDelegate final : public GarbageCollected<TestCSPDelegate>, - public ContentSecurityPolicyDelegate { - public: - Vector<String>& console_messages() { return console_messages_; } - - // ContentSecurityPolicyDelegate override - const SecurityOrigin* GetSecurityOrigin() override { - return security_origin_.get(); - } - const KURL& Url() const override { return url_; } - void SetSandboxFlags(network::mojom::blink::WebSandboxFlags) override {} - void SetRequireTrustedTypes() override {} - void AddInsecureRequestPolicy( - mojom::blink::InsecureRequestPolicy) override {} - std::unique_ptr<SourceLocation> GetSourceLocation() override { - return nullptr; - } - absl::optional<uint16_t> GetStatusCode() override { return absl::nullopt; } - String GetDocumentReferrer() override { return ""; } - void DispatchViolationEvent(const SecurityPolicyViolationEventInit&, - Element*) override {} - void PostViolationReport(const SecurityPolicyViolationEventInit&, - const String& stringified_report, - bool is_frame_ancestors_violation, - const Vector<String>& report_endpoints, - bool use_reporting_api) override {} - void Count(WebFeature) override {} - void AddConsoleMessage(ConsoleMessage* message) override { - console_messages_.push_back(message->Message()); - } - void AddInspectorIssue(AuditsIssue) override {} - void DisableEval(const String& error_message) override {} - void SetWasmEvalErrorMessage(const String& error_message) override {} - void ReportBlockedScriptExecutionToInspector( - const String& directive_text) override {} - void DidAddContentSecurityPolicies( - WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override { - } - - void Trace(Visitor*) const override {} - - private: - const KURL url_ = KURL("https://example.test/index.html"); - const scoped_refptr<SecurityOrigin> security_origin_ = - SecurityOrigin::Create(url_); - Vector<String> console_messages_; - }; - - CSPDirectiveListTest() : csp(MakeGarbageCollected<ContentSecurityPolicy>()) {} void SetUp() override { scoped_feature_list_.InitWithFeatures({network::features::kReporting}, {}); } @@ -99,7 +48,6 @@ } protected: - Persistent<ContentSecurityPolicy> csp; base::test::ScopedFeatureList scoped_feature_list_; }; @@ -165,26 +113,35 @@ "foo", false}, }; + ContentSecurityPolicy* context = + MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + context->BindToDelegate(*test_delegate); + KURL blocked_url = KURL("https://blocked.com"); for (const auto& test : cases) { - // Report-only - network::mojom::blink::ContentSecurityPolicyPtr directive_list = - CreateList(test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ(test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - blocked_url, blocked_url, - ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, test.nonce)); + for (auto reporting_disposition : {ReportingDisposition::kSuppressReporting, + ReportingDisposition::kReport}) { + // Report-only + network::mojom::blink::ContentSecurityPolicyPtr directive_list = + CreateList(test.list, ContentSecurityPolicyType::kReport); - // Enforce - directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); - EXPECT_EQ(test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - blocked_url, blocked_url, - ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, test.nonce)); + EXPECT_TRUE(CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::ScriptSrcElem, + blocked_url, blocked_url, + ResourceRequest::RedirectStatus::kNoRedirect, reporting_disposition, + test.nonce)); + + // Enforce + directive_list = + CreateList(test.list, ContentSecurityPolicyType::kEnforce); + EXPECT_EQ(test.expected, + CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::ScriptSrcElem, + blocked_url, blocked_url, + ResourceRequest::RedirectStatus::kNoRedirect, + reporting_disposition, test.nonce)); + } } } @@ -237,6 +194,11 @@ false}, }; + ContentSecurityPolicy* context = + MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + context->BindToDelegate(*test_delegate); + for (const auto& test : cases) { SCOPED_TRACE(testing::Message() << "List: `" << test.list << "`, URL: `" << test.url << "`"); @@ -245,19 +207,17 @@ // Report-only network::mojom::blink::ContentSecurityPolicyPtr directive_list = CreateList(test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ(test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - script_src, script_src, - ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_TRUE(CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::ScriptSrcElem, script_src, + script_src, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(), + IntegrityMetadataSet(), kParserInserted)); // Enforce directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.expected, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, + *directive_list, context, CSPDirectiveName::ScriptSrcElem, script_src, script_src, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(), @@ -296,6 +256,11 @@ false}, }; + ContentSecurityPolicy* context = + MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + context->BindToDelegate(*test_delegate); + for (const auto& test : cases) { SCOPED_TRACE(testing::Message() << "List: `" << test.list << "`, URL: `" << test.url << "`"); @@ -304,13 +269,11 @@ // Report-only 'script-src' network::mojom::blink::ContentSecurityPolicyPtr directive_list = CreateList( String("script-src ") + test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ( - test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(test.nonce), - IntegrityMetadataSet(), kParserInserted)); + EXPECT_TRUE(CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::ScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(test.nonce), + IntegrityMetadataSet(), kParserInserted)); // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, @@ -318,20 +281,18 @@ EXPECT_EQ( test.expected, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, + *directive_list, context, CSPDirectiveName::ScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce), IntegrityMetadataSet(), kParserInserted)); // Report-only 'style-src' directive_list = CreateList(String("style-src ") + test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ( - test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::StyleSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(test.nonce))); + EXPECT_TRUE(CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::StyleSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(test.nonce))); // Enforce 'style-src' directive_list = CreateList(String("style-src ") + test.list, @@ -339,25 +300,21 @@ EXPECT_EQ( test.expected, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::StyleSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, + *directive_list, context, CSPDirectiveName::StyleSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce))); // Report-only 'style-src' directive_list = CreateList(String("default-src ") + test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ( - test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(test.nonce))); - EXPECT_EQ( - test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::StyleSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(test.nonce))); + EXPECT_TRUE(CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::ScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(test.nonce))); + EXPECT_TRUE(CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::StyleSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(test.nonce))); // Enforce 'style-src' directive_list = CreateList(String("default-src ") + test.list, @@ -365,15 +322,15 @@ EXPECT_EQ( test.expected, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, + *directive_list, context, CSPDirectiveName::ScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce), IntegrityMetadataSet(), kParserInserted)); EXPECT_EQ( test.expected, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::StyleSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, + *directive_list, context, CSPDirectiveName::StyleSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(test.nonce))); } } @@ -443,6 +400,11 @@ {"'sha256-yay'", "https://a.com/file", "", false}, }; + ContentSecurityPolicy* context = + MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + context->BindToDelegate(*test_delegate); + for (const auto& test : cases) { SCOPED_TRACE(testing::Message() << "List: `" << test.list << "`, URL: `" << test.url @@ -457,13 +419,11 @@ // Report-only 'script-src' network::mojom::blink::ContentSecurityPolicyPtr directive_list = CreateList( String("script-src ") + test.list, ContentSecurityPolicyType::kReport); - EXPECT_EQ( - test.expected, - CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kSuppressReporting, String(), - integrity_metadata, kParserInserted)); + EXPECT_TRUE(CSPDirectiveListAllowFromSource( + *directive_list, context, CSPDirectiveName::ScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, + ReportingDisposition::kSuppressReporting, String(), integrity_metadata, + kParserInserted)); // Enforce 'script-src' directive_list = CreateList(String("script-src ") + test.list, @@ -471,8 +431,8 @@ EXPECT_EQ( test.expected, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), CSPDirectiveName::ScriptSrcElem, - resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, + *directive_list, context, CSPDirectiveName::ScriptSrcElem, resource, + resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting, String(), integrity_metadata, kParserInserted)); } @@ -511,13 +471,18 @@ {"default-src https://example.test", true}, }; + ContentSecurityPolicy* context = + MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + context->BindToDelegate(*test_delegate); + for (const auto& test : cases) { SCOPED_TRACE(test.list); const KURL resource("https://example.test/worker.js"); network::mojom::blink::ContentSecurityPolicyPtr directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.allowed, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), + *directive_list, context, CSPDirectiveName::WorkerSrc, resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); @@ -557,13 +522,18 @@ false}, }; + ContentSecurityPolicy* context = + MakeGarbageCollected<ContentSecurityPolicy>(); + TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); + context->BindToDelegate(*test_delegate); + for (const auto& test : cases) { SCOPED_TRACE(test.list); const KURL resource("https://example.test/worker.js"); network::mojom::blink::ContentSecurityPolicyPtr directive_list = CreateList(test.list, ContentSecurityPolicyType::kEnforce); EXPECT_EQ(test.allowed, CSPDirectiveListAllowFromSource( - *directive_list, csp.Get(), + *directive_list, context, CSPDirectiveName::WorkerSrc, resource, resource, ResourceRequest::RedirectStatus::kNoRedirect, ReportingDisposition::kSuppressReporting)); @@ -948,13 +918,16 @@ MakeGarbageCollected<ContentSecurityPolicy>(); TestCSPDelegate* test_delegate = MakeGarbageCollected<TestCSPDelegate>(); context->BindToDelegate(*test_delegate); - EXPECT_EQ( - testCase.allowed, - CSPDirectiveListAllowFromSource( - *testCase.directive_list, context, CSPDirectiveName::ScriptSrcElem, - testCase.script_url, testCase.script_url, - ResourceRequest::RedirectStatus::kNoRedirect, - ReportingDisposition::kReport, testCase.script_nonce)); + for (auto reporting_disposition : {ReportingDisposition::kSuppressReporting, + ReportingDisposition::kReport}) { + EXPECT_EQ( + testCase.allowed, + CSPDirectiveListAllowFromSource( + *testCase.directive_list, context, + CSPDirectiveName::ScriptSrcElem, testCase.script_url, + testCase.script_url, ResourceRequest::RedirectStatus::kNoRedirect, + reporting_disposition, testCase.script_nonce)); + } static const char* message = "Note that 'strict-dynamic' is present, so " "host-based allowlisting is disabled.";
diff --git a/third_party/blink/renderer/core/frame/csp/test_util.h b/third_party/blink/renderer/core/frame/csp/test_util.h new file mode 100644 index 0000000..c7312f6 --- /dev/null +++ b/third_party/blink/renderer/core/frame/csp/test_util.h
@@ -0,0 +1,70 @@ +// 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 THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_TEST_UTIL_H_ +#define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_TEST_UTIL_H_ + +#include "base/memory/scoped_refptr.h" +#include "services/network/public/mojom/content_security_policy.mojom-blink.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" +#include "third_party/blink/renderer/core/inspector/inspector_audits_issue.h" +#include "third_party/blink/renderer/platform/weborigin/security_origin.h" +#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" +#include "third_party/blink/renderer/platform/wtf/vector.h" + +namespace blink { + +// Simple CSP delegate that stores the console messages logged by the +// ContentSecurityPolicy context and allows retrieving them. +class TestCSPDelegate final : public GarbageCollected<TestCSPDelegate>, + public ContentSecurityPolicyDelegate { + public: + Vector<String>& console_messages() { return console_messages_; } + + // ContentSecurityPolicyDelegate override + const SecurityOrigin* GetSecurityOrigin() override { + return security_origin_.get(); + } + const KURL& Url() const override { return url_; } + void SetSandboxFlags(network::mojom::blink::WebSandboxFlags) override {} + void SetRequireTrustedTypes() override {} + void AddInsecureRequestPolicy(mojom::blink::InsecureRequestPolicy) override {} + std::unique_ptr<SourceLocation> GetSourceLocation() override { + return nullptr; + } + absl::optional<uint16_t> GetStatusCode() override { return absl::nullopt; } + String GetDocumentReferrer() override { return ""; } + void DispatchViolationEvent(const SecurityPolicyViolationEventInit&, + Element*) override {} + void PostViolationReport(const SecurityPolicyViolationEventInit&, + const String& stringified_report, + bool is_frame_ancestors_violation, + const Vector<String>& report_endpoints, + bool use_reporting_api) override {} + void Count(WebFeature) override {} + void AddConsoleMessage(ConsoleMessage* message) override { + console_messages_.push_back(message->Message()); + } + void AddInspectorIssue(AuditsIssue) override {} + void DisableEval(const String& error_message) override {} + void SetWasmEvalErrorMessage(const String& error_message) override {} + void ReportBlockedScriptExecutionToInspector( + const String& directive_text) override {} + void DidAddContentSecurityPolicies( + WTF::Vector<network::mojom::blink::ContentSecurityPolicyPtr>) override {} + + void Trace(Visitor*) const override {} + + private: + const KURL url_ = KURL("https://example.test/index.html"); + const scoped_refptr<SecurityOrigin> security_origin_ = + SecurityOrigin::Create(url_); + Vector<String> console_messages_; +}; + +} // namespace blink + +#endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_TEST_UTIL_H_
diff --git a/third_party/blink/renderer/core/frame/deprecation/deprecation.json5 b/third_party/blink/renderer/core/frame/deprecation/deprecation.json5 index 610b6d8..98ef0ac 100644 --- a/third_party/blink/renderer/core/frame/deprecation/deprecation.json5 +++ b/third_party/blink/renderer/core/frame/deprecation/deprecation.json5
@@ -177,16 +177,6 @@ milestone: 127, }, { - name: "EventPath", - message: "`Event.path` is deprecated and will be removed. Please use `Event.composedPath()` instead.", - translation_note: "Warning displayed to developers when the non-standard `Event.path` API is used to notify them that this API is deprecated.", - web_features: [ - "kEventPath", - ], - chrome_status_feature: 5726124632965120, - milestone: 109, - }, - { name: "ExpectCTHeader", message: "The `Expect-CT` header is deprecated and will be removed. Chrome requires Certificate Transparency for all publicly trusted certificates issued after April 30, 2018.", translation_note: "This message is shown when the deprecated Expect-CT header is present.",
diff --git a/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc b/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc index 11c4489..d4718d2 100644 --- a/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc +++ b/third_party/blink/renderer/core/frame/frame_serializer_delegate_impl.cc
@@ -295,14 +295,11 @@ auto* template_element = MakeGarbageCollected<Element>( html_names::kTemplateTag, &(element.GetDocument())); template_element->setAttribute( - QualifiedName(g_null_atom, AtomicString(kShadowModeAttributeName), - g_null_atom), + QualifiedName(AtomicString(kShadowModeAttributeName)), AtomicString(shadow_mode)); if (shadow_root->delegatesFocus()) { template_element->setAttribute( - QualifiedName(g_null_atom, - AtomicString(kShadowDelegatesFocusAttributeName), - g_null_atom), + QualifiedName(AtomicString(kShadowDelegatesFocusAttributeName)), g_empty_atom); } shadow_template_elements_.insert(template_element);
diff --git a/third_party/blink/renderer/core/frame/local_frame_view.cc b/third_party/blink/renderer/core/frame/local_frame_view.cc index 804274b..e4e254d 100644 --- a/third_party/blink/renderer/core/frame/local_frame_view.cc +++ b/third_party/blink/renderer/core/frame/local_frame_view.cc
@@ -679,11 +679,7 @@ } } - if (RuntimeEnabledFeatures::LayoutNewSubtreeRootEnabled()) { - To<LayoutBox>(root).LayoutSubtreeRoot(); - } else { - To<LayoutBox>(root).LayoutSubtreeRootOld(); - } + To<LayoutBox>(root).LayoutSubtreeRoot(); return true; }
diff --git a/third_party/blink/renderer/core/html/aria_properties.json5 b/third_party/blink/renderer/core/html/aria_properties.json5 index faa6fe8..5c99f52 100644 --- a/third_party/blink/renderer/core/html/aria_properties.json5 +++ b/third_party/blink/renderer/core/html/aria_properties.json5
@@ -130,11 +130,6 @@ enum: ["ascending", "descending", "none", "other"], type: "token" }, - { - name: "aria-touchpassthrough", - type: "boolean", - runtimeEnabled: "AriaTouchPassthrough" - }, {name: "aria-valuemax", type: "decimal"}, {name: "aria-valuemin", type: "decimal"}, {name: "aria-valuenow", type: "decimal"},
diff --git a/third_party/blink/renderer/core/html/html_element.cc b/third_party/blink/renderer/core/html/html_element.cc index 47ac7c3..4e0f7f7 100644 --- a/third_party/blink/renderer/core/html/html_element.cc +++ b/third_party/blink/renderer/core/html/html_element.cc
@@ -731,8 +731,6 @@ kNoEvent, nullptr}, {html_names::kAriaSortAttr, WebFeature::kARIASortAttribute, kNoEvent, nullptr}, - {html_names::kAriaTouchpassthroughAttr, - WebFeature::kARIATouchpassthroughAttribute, kNoEvent, nullptr}, {html_names::kAriaValuemaxAttr, WebFeature::kARIAValueMaxAttribute, kNoEvent, nullptr}, {html_names::kAriaValueminAttr, WebFeature::kARIAValueMinAttribute,
diff --git a/third_party/blink/renderer/core/html/media/html_media_element.cc b/third_party/blink/renderer/core/html/media/html_media_element.cc index b6c83c3..310d05e9 100644 --- a/third_party/blink/renderer/core/html/media/html_media_element.cc +++ b/third_party/blink/renderer/core/html/media/html_media_element.cc
@@ -1498,9 +1498,7 @@ } LocalFrame* frame = LocalFrameForPlayer(); - // TODO(srirama.m): Figure out how frame can be null when - // coming from executeDeferredLoad() - if (!frame) { + if (!frame || !GetExecutionContext()) { MediaLoadingFailed( WebMediaPlayer::kNetworkStateFormatError, BuildElementErrorMessage("Player load failure: document has no frame"));
diff --git a/third_party/blink/renderer/core/html/parser/atomic_html_token.h b/third_party/blink/renderer/core/html/parser/atomic_html_token.h index cc933f3..87c49b9 100644 --- a/third_party/blink/renderer/core/html/parser/atomic_html_token.h +++ b/third_party/blink/renderer/core/html/parser/atomic_html_token.h
@@ -333,7 +333,7 @@ QualifiedName name = LookupHTMLAttributeName(attribute.NameBuffer().data(), attribute.NameBuffer().size()); if (name == g_null_name) { - name = QualifiedName(g_null_atom, attribute.GetName(), g_null_atom); + name = QualifiedName(attribute.GetName()); } if constexpr (DedupWithHash) {
diff --git a/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc b/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc index 93afdc9..f9cf9f5 100644 --- a/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc +++ b/third_party/blink/renderer/core/html/parser/html_document_parser_fastpath.cc
@@ -902,11 +902,8 @@ QualifiedName name = LookupHTMLAttributeName( name_span.data(), static_cast<unsigned>(name_span.size())); if (name == g_null_name) { - name = - QualifiedName(g_null_atom, - AtomicString(name_span.data(), - static_cast<unsigned>(name_span.size())), - g_null_atom); + name = QualifiedName(AtomicString( + name_span.data(), static_cast<unsigned>(name_span.size()))); } AtomicString value;
diff --git a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc index c623902..b4b07c13 100644 --- a/third_party/blink/renderer/core/html/parser/html_tree_builder.cc +++ b/third_party/blink/renderer/core/html/parser/html_tree_builder.cc
@@ -521,7 +521,7 @@ } void AddManualLocalName(PrefixedNameToQualifiedNameMap* map, const char* name) { - const QualifiedName item(g_null_atom, AtomicString(name), g_null_atom); + const QualifiedName item{AtomicString(name)}; const blink::QualifiedName* const names = &item; MapLoweredLocalNameToName<QualifiedName>(map, &names, 1); }
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc b/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc index f1abce3..55c4c5fb 100644 --- a/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc +++ b/third_party/blink/renderer/core/html/track/vtt/vtt_element.cc
@@ -36,28 +36,16 @@ static const QualifiedName& NodeTypeToTagName(VTTNodeType node_type) { // Use predefined AtomicStrings in html_names to reduce AtomicString // creation cost. - DEFINE_STATIC_LOCAL(QualifiedName, c_tag, - (g_null_atom, AtomicString("c"), g_null_atom)); - DEFINE_STATIC_LOCAL(QualifiedName, v_tag, - (g_null_atom, AtomicString("v"), g_null_atom)); - DEFINE_STATIC_LOCAL( - QualifiedName, lang_tag, - (g_null_atom, html_names::kLangAttr.LocalName(), g_null_atom)); - DEFINE_STATIC_LOCAL( - QualifiedName, b_tag, - (g_null_atom, html_names::kBTag.LocalName(), g_null_atom)); - DEFINE_STATIC_LOCAL( - QualifiedName, u_tag, - (g_null_atom, html_names::kUTag.LocalName(), g_null_atom)); - DEFINE_STATIC_LOCAL( - QualifiedName, i_tag, - (g_null_atom, html_names::kITag.LocalName(), g_null_atom)); - DEFINE_STATIC_LOCAL( - QualifiedName, ruby_tag, - (g_null_atom, html_names::kRubyTag.LocalName(), g_null_atom)); - DEFINE_STATIC_LOCAL( - QualifiedName, rt_tag, - (g_null_atom, html_names::kRtTag.LocalName(), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, c_tag, (AtomicString("c"))); + DEFINE_STATIC_LOCAL(QualifiedName, v_tag, (AtomicString("v"))); + DEFINE_STATIC_LOCAL(QualifiedName, lang_tag, + (html_names::kLangAttr.LocalName())); + DEFINE_STATIC_LOCAL(QualifiedName, b_tag, (html_names::kBTag.LocalName())); + DEFINE_STATIC_LOCAL(QualifiedName, u_tag, (html_names::kUTag.LocalName())); + DEFINE_STATIC_LOCAL(QualifiedName, i_tag, (html_names::kITag.LocalName())); + DEFINE_STATIC_LOCAL(QualifiedName, ruby_tag, + (html_names::kRubyTag.LocalName())); + DEFINE_STATIC_LOCAL(QualifiedName, rt_tag, (html_names::kRtTag.LocalName())); switch (node_type) { case kVTTNodeTypeClass: return c_tag;
diff --git a/third_party/blink/renderer/core/html/track/vtt/vtt_element.h b/third_party/blink/renderer/core/html/track/vtt/vtt_element.h index 65247819..07bdcbb 100644 --- a/third_party/blink/renderer/core/html/track/vtt/vtt_element.h +++ b/third_party/blink/renderer/core/html/track/vtt/vtt_element.h
@@ -68,14 +68,12 @@ void SetLanguage(AtomicString value) { language_ = value; } static const QualifiedName& VoiceAttributeName() { - DEFINE_STATIC_LOCAL(QualifiedName, voice_attr, - (g_null_atom, AtomicString("voice"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, voice_attr, (AtomicString("voice"))); return voice_attr; } static const QualifiedName& LangAttributeName() { - DEFINE_STATIC_LOCAL(QualifiedName, attr, - (g_null_atom, AtomicString("lang"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, attr, (AtomicString("lang"))); return attr; }
diff --git a/third_party/blink/renderer/core/input/mouse_event_manager.cc b/third_party/blink/renderer/core/input/mouse_event_manager.cc index 52404889..37bb43f 100644 --- a/third_party/blink/renderer/core/input/mouse_event_manager.cc +++ b/third_party/blink/renderer/core/input/mouse_event_manager.cc
@@ -702,7 +702,7 @@ .GetSelectionController() .MouseDownMayStartSelect() || (mouse_press_node_ && mouse_press_node_->GetLayoutBox() && - mouse_press_node_->GetLayoutBox()->CanBeProgrammaticallyScrolled()); + mouse_press_node_->GetLayoutBox()->IsUserScrollable()); return swallow_event ? WebInputEventResult::kHandledSystem : WebInputEventResult::kNotHandled;
diff --git a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc index 6ae7fb3..bbf441c 100644 --- a/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc +++ b/third_party/blink/renderer/core/intersection_observer/intersection_geometry.cc
@@ -519,7 +519,7 @@ if (local_ancestor) { if (local_ancestor->IsScrollContainer()) { PhysicalOffset scroll_offset = - -(PhysicalOffset(local_ancestor->ScrollOrigin()) + + -(PhysicalOffset(local_ancestor->ScrollOriginInt()) + PhysicalOffset( local_ancestor->PixelSnappedScrolledContentOffset())); intersection_rect.Move(scroll_offset);
diff --git a/third_party/blink/renderer/core/layout/anchor_scroll_data.cc b/third_party/blink/renderer/core/layout/anchor_scroll_data.cc index 4e43430..af8fd33 100644 --- a/third_party/blink/renderer/core/layout/anchor_scroll_data.cc +++ b/third_party/blink/renderer/core/layout/anchor_scroll_data.cc
@@ -113,7 +113,7 @@ new_scroll_container_ids.push_back(scrollable_area->GetScrollElementId()); new_accumulated_scroll_offset += scrollable_area->GetScrollOffset(); new_accumulated_scroll_origin += - scrollable_area->ScrollOrigin().OffsetFromOrigin(); + scrollable_area->ScrollOriginInt().OffsetFromOrigin(); } }
diff --git a/third_party/blink/renderer/core/layout/layout_box.cc b/third_party/blink/renderer/core/layout/layout_box.cc index 6e05c99..de7a99e3 100644 --- a/third_party/blink/renderer/core/layout/layout_box.cc +++ b/third_party/blink/renderer/core/layout/layout_box.cc
@@ -463,8 +463,6 @@ LayoutBoxRareData::LayoutBoxRareData() : spanner_placeholder_(nullptr), - override_logical_width_(-1), - override_logical_height_(-1), // TODO(rego): We should store these based on physical direction. has_override_containing_block_content_logical_width_(false), has_override_containing_block_content_logical_height_(false), @@ -512,7 +510,6 @@ void LayoutBox::WillBeDestroyed() { NOT_DESTROYED(); - ClearOverrideSize(); ClearOverrideContainingBlockContentSize(); if (IsOutOfFlowPositioned()) @@ -681,14 +678,6 @@ UpdateShapeOutsideInfoAfterStyleChange(*Style(), old_style); UpdateGridPositionAfterStyleChange(old_style); - // When we're no longer a flex item because we're now absolutely positioned, - // we need to clear the override size so we're not affected by it anymore. - // This technically covers too many cases (even when out-of-flow did not - // change) but that should be harmless. - if (IsOutOfFlowPositioned() && Parent() && - Parent()->StyleRef().IsDisplayFlexibleOrGridBox()) - ClearOverrideSize(); - if (old_style) { // Regular column content (i.e. non-spanners) have a hook into the flow // thread machinery before (StyleWillChange()) and after (here in @@ -979,37 +968,6 @@ } } -void LayoutBox::LayoutSubtreeRootOld() { - NOT_DESTROYED(); - if (!IsLayoutNGObject() && GetSingleCachedLayoutResult()) { - // If this object is laid out by the legacy engine, while its containing - // block is laid out by NG, it means that we normally (when laying out - // starting at the real root, i.e. LayoutView) enter layout of this object - // from NG code. This takes care of setting up a BoxLayoutExtraInput - // structure, which makes legacy layout behave when managed by NG. Make a - // short detour via NG just to set things up to re-enter legacy layout - // correctly. - DCHECK_EQ(PhysicalFragmentCount(), 1u); - LayoutPoint old_location = Location(); - - // Make a copy of the cached constraint space, since we'll overwrite the - // layout result object as part of performing layout. - auto constraint_space = - GetSingleCachedLayoutResult()->GetConstraintSpaceForCaching(); - - NGBlockNode(this).Layout(constraint_space); - - // Restore the old location. While it's usually the job of the containing - // block to position its children, out-of-flow positioned objects set - // their own position, which could be wrong in this case. - SetLocation(old_location); - } else { - UpdateLayout(); - } - - GetDocument().GetFrame()->GetInputMethodController().DidLayoutSubtree(*this); -} - // ClientWidth and ClientHeight represent the interior of an object excluding // border and scrollbar. DISABLE_CFI_PERF @@ -1710,13 +1668,6 @@ return scrollbars; } -bool LayoutBox::CanBeScrolledAndHasScrollableArea() const { - NOT_DESTROYED(); - return CanBeProgrammaticallyScrolled() && - (PixelSnappedScrollHeight() != PixelSnappedClientHeight() || - PixelSnappedScrollWidth() != PixelSnappedClientWidth()); -} - void LayoutBox::Autoscroll(const PhysicalOffset& position_in_root_frame) { NOT_DESTROYED(); LocalFrame* frame = GetFrame(); @@ -1780,9 +1731,8 @@ LayoutBox* LayoutBox::FindAutoscrollable(LayoutObject* layout_object, bool is_middle_click_autoscroll) { - while (layout_object && - !(layout_object->IsBox() && - To<LayoutBox>(layout_object)->CanBeScrolledAndHasScrollableArea())) { + while (layout_object && !(layout_object->IsBox() && + To<LayoutBox>(layout_object)->IsUserScrollable())) { // Do not start selection-based autoscroll when the node is inside a // fixed-position element. if (!is_middle_click_autoscroll && layout_object->IsBox() && @@ -1827,18 +1777,16 @@ return false; } -gfx::Vector2d LayoutBox::OriginAdjustmentForScrollbars() const { +PhysicalOffset LayoutBox::OriginAdjustmentForScrollbars() const { NOT_DESTROYED(); - if (CanSkipComputeScrollbars()) - return gfx::Vector2d(); - - NGPhysicalBoxStrut scrollbars = ComputeScrollbarsInternal(kClampToContentBox); - return gfx::Vector2d(scrollbars.left.ToInt(), scrollbars.top.ToInt()); + return CanSkipComputeScrollbars() + ? PhysicalOffset() + : ComputeScrollbarsInternal(kClampToContentBox).Offset(); } -gfx::Point LayoutBox::ScrollOrigin() const { +gfx::Point LayoutBox::ScrollOriginInt() const { NOT_DESTROYED(); - return GetScrollableArea() ? GetScrollableArea()->ScrollOrigin() + return GetScrollableArea() ? GetScrollableArea()->ScrollOriginInt() : gfx::Point(); } @@ -2073,7 +2021,7 @@ DCHECK(HasOverrideLogicalWidth()); if (extra_input_ && extra_input_->override_inline_size) return *extra_input_->override_inline_size; - return rare_data_->override_logical_width_; + return kIndefiniteSize; } LayoutUnit LayoutBox::OverrideLogicalHeight() const { @@ -2081,7 +2029,7 @@ DCHECK(HasOverrideLogicalHeight()); if (extra_input_ && extra_input_->override_block_size) return *extra_input_->override_block_size; - return rare_data_->override_logical_height_; + return kIndefiniteSize; } bool LayoutBox::IsOverrideLogicalHeightDefinite() const { @@ -2101,50 +2049,12 @@ bool LayoutBox::HasOverrideLogicalHeight() const { NOT_DESTROYED(); - if (extra_input_ && extra_input_->override_block_size) - return true; - return rare_data_ && rare_data_->override_logical_height_ != -1; + return extra_input_ && extra_input_->override_block_size; } bool LayoutBox::HasOverrideLogicalWidth() const { NOT_DESTROYED(); - if (extra_input_ && extra_input_->override_inline_size) - return true; - return rare_data_ && rare_data_->override_logical_width_ != -1; -} - -void LayoutBox::SetOverrideLogicalHeight(LayoutUnit height) { - NOT_DESTROYED(); - DCHECK(!extra_input_); - DCHECK_GE(height, 0); - EnsureRareData().override_logical_height_ = height; -} - -void LayoutBox::SetOverrideLogicalWidth(LayoutUnit width) { - NOT_DESTROYED(); - DCHECK(!extra_input_); - DCHECK_GE(width, 0); - EnsureRareData().override_logical_width_ = width; -} - -void LayoutBox::ClearOverrideLogicalHeight() { - NOT_DESTROYED(); - DCHECK(!extra_input_); - if (rare_data_) - rare_data_->override_logical_height_ = LayoutUnit(-1); -} - -void LayoutBox::ClearOverrideLogicalWidth() { - NOT_DESTROYED(); - DCHECK(!extra_input_); - if (rare_data_) - rare_data_->override_logical_width_ = LayoutUnit(-1); -} - -void LayoutBox::ClearOverrideSize() { - NOT_DESTROYED(); - ClearOverrideLogicalHeight(); - ClearOverrideLogicalWidth(); + return extra_input_ && extra_input_->override_inline_size; } LayoutUnit LayoutBox::OverrideContentLogicalWidth() const {
diff --git a/third_party/blink/renderer/core/layout/layout_box.h b/third_party/blink/renderer/core/layout/layout_box.h index cfbe308..942b6c8b 100644 --- a/third_party/blink/renderer/core/layout/layout_box.h +++ b/third_party/blink/renderer/core/layout/layout_box.h
@@ -99,9 +99,6 @@ // container. Member<LayoutMultiColumnSpannerPlaceholder> spanner_placeholder_; - LayoutUnit override_logical_width_; - LayoutUnit override_logical_height_; - bool has_override_containing_block_content_logical_width_ : 1; bool has_override_containing_block_content_logical_height_ : 1; bool has_previous_content_box_rect_ : 1; @@ -835,7 +832,6 @@ } void LayoutSubtreeRoot(); - void LayoutSubtreeRootOld(); void Paint(const PaintInfo&) const override; @@ -869,11 +865,6 @@ bool StretchBlockSizeIfAuto() const; bool HasOverrideLogicalHeight() const; bool HasOverrideLogicalWidth() const; - void SetOverrideLogicalHeight(LayoutUnit); - void SetOverrideLogicalWidth(LayoutUnit); - void ClearOverrideLogicalHeight(); - void ClearOverrideLogicalWidth(); - void ClearOverrideSize(); LayoutUnit OverrideContentLogicalWidth() const; LayoutUnit OverrideContentLogicalHeight() const; @@ -1241,8 +1232,7 @@ } } - bool CanBeScrolledAndHasScrollableArea() const; - virtual bool CanBeProgrammaticallyScrolled() const; + bool IsUserScrollable() const; virtual void Autoscroll(const PhysicalOffset&); PhysicalOffset CalculateAutoscrollDirection( const gfx::PointF& point_in_root_frame) const; @@ -1286,11 +1276,11 @@ return ScrollsOverflowY() && PixelSnappedScrollHeight() != PixelSnappedClientHeight(); } - virtual bool ScrollsOverflowX() const { + bool ScrollsOverflowX() const { NOT_DESTROYED(); return HasNonVisibleOverflow() && StyleRef().ScrollsOverflowX(); } - virtual bool ScrollsOverflowY() const { + bool ScrollsOverflowY() const { NOT_DESTROYED(); return HasNonVisibleOverflow() && StyleRef().ScrollsOverflowY(); } @@ -1459,8 +1449,8 @@ } // See README.md for an explanation of scroll origin. - gfx::Vector2d OriginAdjustmentForScrollbars() const; - gfx::Point ScrollOrigin() const; + PhysicalOffset OriginAdjustmentForScrollbars() const; + gfx::Point ScrollOriginInt() const; PhysicalOffset ScrolledContentOffset() const; // Scroll offset as snapped to physical pixels. This value should be used in
diff --git a/third_party/blink/renderer/core/layout/layout_box_hot.cc b/third_party/blink/renderer/core/layout/layout_box_hot.cc index b314597..176b551e 100644 --- a/third_party/blink/renderer/core/layout/layout_box_hot.cc +++ b/third_party/blink/renderer/core/layout/layout_box_hot.cc
@@ -47,21 +47,9 @@ return hit_test_location.Intersects(overflow_box); } -bool LayoutBox::CanBeProgrammaticallyScrolled() const { +bool LayoutBox::IsUserScrollable() const { NOT_DESTROYED(); - Node* node = GetNode(); - if (node && node->IsDocumentNode()) - return true; - - if (!IsScrollContainer()) - return false; - - bool has_scrollable_overflow = - HasScrollableOverflowX() || HasScrollableOverflowY(); - if (ScrollsOverflow() && has_scrollable_overflow) - return true; - - return node && IsEditable(*node); + return HasScrollableOverflowX() || HasScrollableOverflowY(); } const NGLayoutResult* LayoutBox::CachedLayoutResult(
diff --git a/third_party/blink/renderer/core/layout/layout_box_test.cc b/third_party/blink/renderer/core/layout/layout_box_test.cc index af3067e0..1db3133 100644 --- a/third_party/blink/renderer/core/layout/layout_box_test.cc +++ b/third_party/blink/renderer/core/layout/layout_box_test.cc
@@ -1513,7 +1513,7 @@ EXPECT_EQ(PhysicalOffset(), box->ScrolledContentOffset()); \ const auto* scrollable_area = box->GetScrollableArea(); \ EXPECT_EQ(gfx::Vector2d(), scrollable_area->ScrollOffsetInt()); \ - EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOrigin()); \ + EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOriginInt()); \ EXPECT_EQ(gfx::PointF(), scrollable_area->ScrollPosition()); \ EXPECT_EQ(gfx::Vector2d(), scrollable_area->MaximumScrollOffsetInt()); \ EXPECT_EQ(gfx::Vector2d(), scrollable_area->MinimumScrollOffsetInt()); \ @@ -1521,7 +1521,7 @@ const auto* normal = GetLayoutBoxByElementId("normal"); EXPECT_ZERO_SCROLL(normal); - EXPECT_EQ(gfx::Vector2d(), normal->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), normal->OriginAdjustmentForScrollbars()); // 540 = border_left + padding_left + width + padding_right + border_right // 400 = border_top + padding_top + height + padding_bottom + border_bottom EXPECT_EQ(LayoutRect(0, 0, 540, 400), normal->BorderBoxRect()); @@ -1538,7 +1538,7 @@ const auto* vlr = GetLayoutBoxByElementId("vlr"); // Same as "normal" EXPECT_ZERO_SCROLL(vlr); - EXPECT_EQ(gfx::Vector2d(), vlr->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), vlr->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(0, 0, 540, 400), vlr->BorderBoxRect()); EXPECT_EQ(LayoutRect(50, 20, 445, 324), vlr->NoOverflowRect()); EXPECT_EQ(PhysicalRect(50, 20, 445, 324), vlr->PhysicalPaddingBoxRect()); @@ -1549,7 +1549,7 @@ // Same as "normal" except that the PaddingBoxRect, ContentBoxRect and // LayoutOverflowRect are flipped. EXPECT_ZERO_SCROLL(vrl); - EXPECT_EQ(gfx::Vector2d(), vrl->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), vrl->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(0, 0, 540, 400), vrl->BorderBoxRect()); EXPECT_EQ(LayoutRect(45, 20, 445, 324), vrl->NoOverflowRect()); EXPECT_EQ(PhysicalRect(50, 20, 445, 324), vrl->PhysicalPaddingBoxRect()); @@ -1560,7 +1560,7 @@ EXPECT_ZERO_SCROLL(rtl); // The scrollbar is on the left, shifting padding box and content box to the // right by 15px. - EXPECT_EQ(gfx::Vector2d(15, 0), rtl->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(15, 0), rtl->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(0, 0, 540, 400), rtl->BorderBoxRect()); EXPECT_EQ(LayoutRect(65, 20, 445, 324), rtl->NoOverflowRect()); EXPECT_EQ(PhysicalRect(65, 20, 445, 324), rtl->PhysicalPaddingBoxRect()); @@ -1570,7 +1570,7 @@ const auto* rtl_vlr = GetLayoutBoxByElementId("rtl-vlr"); // Same as "vlr". EXPECT_ZERO_SCROLL(rtl_vlr); - EXPECT_EQ(gfx::Vector2d(), rtl_vlr->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), rtl_vlr->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(0, 0, 540, 400), rtl_vlr->BorderBoxRect()); EXPECT_EQ(LayoutRect(50, 20, 445, 324), rtl_vlr->NoOverflowRect()); EXPECT_EQ(PhysicalRect(50, 20, 445, 324), rtl_vlr->PhysicalPaddingBoxRect()); @@ -1580,7 +1580,7 @@ const auto* rtl_vrl = GetLayoutBoxByElementId("rtl-vrl"); // Same as "vrl". EXPECT_ZERO_SCROLL(rtl_vrl); - EXPECT_EQ(gfx::Vector2d(), rtl_vrl->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), rtl_vrl->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(0, 0, 540, 400), rtl_vrl->BorderBoxRect()); EXPECT_EQ(LayoutRect(45, 20, 445, 324), rtl_vrl->NoOverflowRect()); EXPECT_EQ(PhysicalRect(50, 20, 445, 324), rtl_vrl->PhysicalPaddingBoxRect()); @@ -1616,13 +1616,13 @@ const auto* normal = GetLayoutBoxByElementId("normal"); const auto* scrollable_area = normal->GetScrollableArea(); EXPECT_EQ(PhysicalOffset(), normal->ScrolledContentOffset()); - EXPECT_EQ(gfx::Vector2d(), normal->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), normal->OriginAdjustmentForScrollbars()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->ScrollOffsetInt()); EXPECT_EQ(LayoutRect(50, 20, 2060, 1040), normal->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(), scrollable_area->ScrollPosition()); // These are the same as in the NonScrollable test. EXPECT_EQ(LayoutRect(0, 0, 540, 400), normal->BorderBoxRect()); @@ -1633,13 +1633,13 @@ const auto* vlr = GetLayoutBoxByElementId("vlr"); scrollable_area = vlr->GetScrollableArea(); EXPECT_EQ(PhysicalOffset(), vlr->ScrolledContentOffset()); - EXPECT_EQ(gfx::Vector2d(), vlr->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), vlr->OriginAdjustmentForScrollbars()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->ScrollOffsetInt()); EXPECT_EQ(LayoutRect(50, 20, 2060, 1040), vlr->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(), scrollable_area->ScrollPosition()); // These are the same as in the NonScrollable test. EXPECT_EQ(LayoutRect(0, 0, 540, 400), vlr->BorderBoxRect()); @@ -1650,13 +1650,13 @@ const auto* vrl = GetLayoutBoxByElementId("vrl"); scrollable_area = vrl->GetScrollableArea(); EXPECT_EQ(PhysicalOffset(), vrl->ScrolledContentOffset()); - EXPECT_EQ(gfx::Vector2d(), vrl->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), vrl->OriginAdjustmentForScrollbars()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->ScrollOffsetInt()); // Same as "vlr" except for flipping. EXPECT_EQ(LayoutRect(45, 20, 2060, 1040), vrl->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(0, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, 0), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 0), scrollable_area->ScrollPosition()); // These are the same as in the NonScrollable test. EXPECT_EQ(LayoutRect(0, 0, 540, 400), vrl->BorderBoxRect()); @@ -1667,12 +1667,12 @@ const auto* rtl = GetLayoutBoxByElementId("rtl"); scrollable_area = rtl->GetScrollableArea(); EXPECT_EQ(PhysicalOffset(), rtl->ScrolledContentOffset()); - EXPECT_EQ(gfx::Vector2d(15, 0), rtl->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(15, 0), rtl->OriginAdjustmentForScrollbars()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->ScrollOffsetInt()); EXPECT_EQ(LayoutRect(-1550, 20, 2060, 1040), rtl->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(0, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, 0), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 0), scrollable_area->ScrollPosition()); // These are the same as in the NonScrollable test. EXPECT_EQ(LayoutRect(0, 0, 540, 400), rtl->BorderBoxRect()); @@ -1683,12 +1683,12 @@ const auto* rtl_vlr = GetLayoutBoxByElementId("rtl-vlr"); scrollable_area = rtl_vlr->GetScrollableArea(); EXPECT_EQ(PhysicalOffset(), rtl_vlr->ScrolledContentOffset()); - EXPECT_EQ(gfx::Vector2d(), rtl_vlr->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), rtl_vlr->OriginAdjustmentForScrollbars()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->ScrollOffsetInt()); EXPECT_EQ(LayoutRect(50, -696, 2060, 1040), rtl_vlr->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 0), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(0, -716), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(0, 716), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(0, 716), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(0, 716), scrollable_area->ScrollPosition()); // These are the same as in the NonScrollable test. EXPECT_EQ(LayoutRect(0, 0, 540, 400), rtl_vlr->BorderBoxRect()); @@ -1699,16 +1699,16 @@ const auto* rtl_vrl = GetLayoutBoxByElementId("rtl-vrl"); scrollable_area = rtl_vrl->GetScrollableArea(); EXPECT_EQ(PhysicalOffset(), rtl_vrl->ScrolledContentOffset()); - EXPECT_EQ(gfx::Vector2d(), rtl_vrl->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), rtl_vrl->OriginAdjustmentForScrollbars()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->ScrollOffsetInt()); // Same as "vlr" except for flipping. EXPECT_EQ(LayoutRect(45, -696, 2060, 1040), rtl_vrl->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, -716), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 716), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 716), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 716), scrollable_area->ScrollPosition()); - EXPECT_EQ(gfx::Vector2d(), rtl_vrl->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), rtl_vrl->OriginAdjustmentForScrollbars()); // These are the same as in the NonScrollable test. EXPECT_EQ(LayoutRect(0, 0, 540, 400), rtl_vrl->BorderBoxRect()); EXPECT_EQ(LayoutRect(45, 20, 445, 324), rtl_vrl->NoOverflowRect()); @@ -2016,6 +2016,56 @@ target3->FindTargetAnchor(anchor_name)); } +TEST_F(LayoutBoxTest, IsUserScrollable) { + SetBodyInnerHTML(R"HTML(" + <style> + #target { width: 100px; height: 100px; overflow: auto; } + </style> + <div id="target"> + <div id="content" style="height: 200px"></div> + </div> + )HTML"); + + auto* target_element = GetDocument().getElementById("target"); + auto* target = target_element->GetLayoutBox(); + EXPECT_TRUE(target->ScrollsOverflow()); + EXPECT_TRUE(target->IsUserScrollable()); + + target_element->setAttribute(html_names::kStyleAttr, "overflow: hidden"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_FALSE(target->ScrollsOverflow()); + EXPECT_FALSE(target->IsUserScrollable()); + + target_element->setAttribute(html_names::kStyleAttr, ""); + GetDocument().getElementById("content")->setAttribute(html_names::kStyleAttr, + "height: 0"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_TRUE(target->ScrollsOverflow()); + EXPECT_FALSE(target->IsUserScrollable()); +} + +TEST_F(LayoutBoxTest, IsUserScrollableLayoutView) { + SetBodyInnerHTML(R"HTML(" + <div id="content" style="height: 2000px"></div> + )HTML"); + + EXPECT_TRUE(GetLayoutView().ScrollsOverflow()); + EXPECT_TRUE(GetLayoutView().IsUserScrollable()); + + GetDocument().body()->setAttribute(html_names::kStyleAttr, + "overflow: hidden"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_FALSE(GetLayoutView().ScrollsOverflow()); + EXPECT_FALSE(GetLayoutView().IsUserScrollable()); + + GetDocument().body()->setAttribute(html_names::kStyleAttr, ""); + GetDocument().getElementById("content")->setAttribute(html_names::kStyleAttr, + "height: 0"); + UpdateAllLifecyclePhasesForTest(); + EXPECT_TRUE(GetLayoutView().ScrollsOverflow()); + EXPECT_FALSE(GetLayoutView().IsUserScrollable()); +} + class LayoutBoxBackgroundPaintLocationTest : public RenderingTest, public PaintTestConfigurations { protected:
diff --git a/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc b/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc index 46cdfcf..bd8720b 100644 --- a/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc +++ b/third_party/blink/renderer/core/layout/layout_flexible_box_test.cc
@@ -79,13 +79,13 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); // 1040 = child_height (1000) + padding_top (10) + padding_bottom (30) EXPECT_EQ(LayoutRect(50, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -107,12 +107,12 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(50, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -134,11 +134,11 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(45, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(0, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, 0), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 0), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -168,11 +168,11 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(-1565, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(0, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, 0), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 0), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -185,11 +185,11 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(50, -696, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 0), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(0, -716), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(0, 716), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(0, 716), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(0, 716), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -211,12 +211,12 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(45, -696, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, -716), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 716), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 716), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 716), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -277,11 +277,11 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(50, -696, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 0), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(0, -716), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(0, 716), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(0, 716), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(0, 716), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -300,11 +300,11 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(-1565, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(0, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, 0), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 0), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -323,12 +323,12 @@ const auto* scrollable_area = flex_box->GetScrollableArea(); CheckFlexBoxPhysicalGeometries(flex_box); - EXPECT_EQ(gfx::Vector2d(), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(-1570, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -342,11 +342,11 @@ CheckFlexBoxPhysicalGeometries(flex_box); // Additional origin due to the scrollbar on the left. - EXPECT_EQ(gfx::Vector2d(15, 0), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(15, 0), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(-1550, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(0, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(-1615, 0), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(1615, 0), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(1615, 0), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child"); @@ -393,12 +393,12 @@ CheckFlexBoxPhysicalGeometries(flex_box); // Additional origin due to the scrollbar on the left. - EXPECT_EQ(gfx::Vector2d(15, 0), flex_box->OriginAdjustmentForScrollbars()); + EXPECT_EQ(PhysicalOffset(15, 0), flex_box->OriginAdjustmentForScrollbars()); EXPECT_EQ(LayoutRect(65, 20, 2060, 1040), flex_box->LayoutOverflowRect()); EXPECT_EQ(gfx::Vector2d(1615, 716), scrollable_area->MaximumScrollOffsetInt()); EXPECT_EQ(gfx::Vector2d(0, 0), scrollable_area->MinimumScrollOffsetInt()); - EXPECT_EQ(gfx::Point(0, 0), scrollable_area->ScrollOrigin()); + EXPECT_EQ(gfx::Point(0, 0), scrollable_area->ScrollOriginInt()); EXPECT_EQ(gfx::PointF(0, 0), scrollable_area->ScrollPosition()); const auto* child = GetLayoutBoxByElementId("child");
diff --git a/third_party/blink/renderer/core/layout/layout_object.cc b/third_party/blink/renderer/core/layout/layout_object.cc index 76cc517..4f559fc8 100644 --- a/third_party/blink/renderer/core/layout/layout_object.cc +++ b/third_party/blink/renderer/core/layout/layout_object.cc
@@ -1288,25 +1288,30 @@ return false; } - if (const NGLayoutResult* layout_result = - layout_box->GetCachedLayoutResult(nullptr)) { - const NGPhysicalFragment& fragment = layout_result->PhysicalFragment(); + const NGLayoutResult* layout_result = + layout_box->GetCachedLayoutResult(nullptr); - // Fragmented nodes cannot be relayout roots. - if (fragment.BreakToken()) - return false; + // We need a previous layout result to begin layout at a subtree root. + if (!layout_result) { + return false; + } - // In LayoutNG, if box has any OOF descendants, they are propagated to - // parent. Therefore, we must mark parent chain for layout. - if (fragment.HasOutOfFlowPositionedDescendants()) - return false; + const NGPhysicalFragment& fragment = layout_result->PhysicalFragment(); - // Anchor queries should be propagated across the layout boundaries, even - // when `contain: strict` is explicitly set. - if (fragment.HasAnchorQuery()) - return false; - } else if (RuntimeEnabledFeatures::LayoutNewSubtreeRootEnabled()) { - // We need a previous layout result to begin layout at a subtree root. + // Fragmented nodes cannot be relayout roots. + if (fragment.BreakToken()) { + return false; + } + + // If a box has any OOF descendants, they are propagated up the tree to + // accumulate their static-position. + if (fragment.HasOutOfFlowPositionedDescendants()) { + return false; + } + + // Anchor queries should be propagated across the layout boundaries, even + // when `contain: strict` is explicitly set. + if (fragment.HasAnchorQuery()) { return false; } @@ -3544,7 +3549,7 @@ // ScrollOrigin accounts for other writing modes whose content's origin is not // at the top-left. - return PhysicalOffset(box->GetScrollableArea()->ScrollOrigin()); + return PhysicalOffset(box->GetScrollableArea()->ScrollOriginInt()); } PhysicalOffset LayoutObject::OffsetFromAncestor(
diff --git a/third_party/blink/renderer/core/layout/layout_object_hot.cc b/third_party/blink/renderer/core/layout/layout_object_hot.cc index 8501788..9b355e8 100644 --- a/third_party/blink/renderer/core/layout/layout_object_hot.cc +++ b/third_party/blink/renderer/core/layout/layout_object_hot.cc
@@ -88,8 +88,9 @@ continue; auto* ancestor_box = To<LayoutBox>(ancestor); - if (ancestor_box->CanBeScrolledAndHasScrollableArea()) + if (ancestor_box->IsUserScrollable()) { return ancestor_box; + } } return nullptr;
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_foreign_object.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_foreign_object.cc index 0438d2e..a7515c1 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_foreign_object.cc +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_foreign_object.cc
@@ -126,16 +126,10 @@ LayoutUnit(viewport_.height() * zoom)) .ConvertToLogical(style.GetWritingMode()); - if (!RuntimeEnabledFeatures::LayoutNewSVGForeignObjectEntryEnabled()) { - SetOverrideLogicalWidth(zoomed_size.inline_size); - SetOverrideLogicalHeight(zoomed_size.block_size); - } - // Use the zoomed version of the viewport as the location, because we will // interpose a transform that "unzooms" the effective zoom to let the children // of the foreign object exist with their specified zoom. - gfx::PointF zoomed_location = - gfx::ScalePoint(viewport_.origin(), style.EffectiveZoom()); + gfx::PointF zoomed_location = gfx::ScalePoint(viewport_.origin(), zoom); // Set box origin to the foreignObject x/y translation, so positioned objects // in XHTML content get correct positions. A regular LayoutBoxModelObject @@ -144,17 +138,13 @@ // specifying them through CSS. overridden_location_ = LayoutPoint(zoomed_location); - if (RuntimeEnabledFeatures::LayoutNewSVGForeignObjectEntryEnabled()) { - NGConstraintSpaceBuilder builder( - style.GetWritingMode(), style.GetWritingDirection(), - /* is_new_fc */ true, /* adjust_inline_size_if_needed */ false); - builder.SetAvailableSize(zoomed_size); - builder.SetIsFixedInlineSize(true); - builder.SetIsFixedBlockSize(true); - NGBlockNode(this).Layout(builder.ToConstraintSpace()); - } else { - UpdateNGBlockLayout(); - } + NGConstraintSpaceBuilder builder( + style.GetWritingMode(), style.GetWritingDirection(), + /* is_new_fc */ true, /* adjust_inline_size_if_needed */ false); + builder.SetAvailableSize(zoomed_size); + builder.SetIsFixedInlineSize(true); + builder.SetIsFixedBlockSize(true); + NGBlockNode(this).Layout(builder.ToConstraintSpace()); DCHECK(!NeedsLayout() || ChildLayoutBlockedByDisplayLock()); const bool bounds_changed = old_frame_rect != FrameRect();
diff --git a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc index 4e85de3..f57a0dc 100644 --- a/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc +++ b/third_party/blink/renderer/core/layout/ng/svg/layout_ng_svg_text.cc
@@ -229,16 +229,12 @@ gfx::RectF old_boundaries = ObjectBoundingBox(); - if (RuntimeEnabledFeatures::LayoutNewSVGTextEntryEnabled()) { - const ComputedStyle& style = StyleRef(); - NGConstraintSpaceBuilder builder( - style.GetWritingMode(), style.GetWritingDirection(), - /* is_new_fc */ true, /* adjust_inline_size_if_needed */ false); - builder.SetAvailableSize(LogicalSize()); - NGBlockNode(this).Layout(builder.ToConstraintSpace()); - } else { - UpdateNGBlockLayout(); - } + const ComputedStyle& style = StyleRef(); + NGConstraintSpaceBuilder builder( + style.GetWritingMode(), style.GetWritingDirection(), + /* is_new_fc */ true, /* adjust_inline_size_if_needed */ false); + builder.SetAvailableSize(LogicalSize()); + NGBlockNode(this).Layout(builder.ToConstraintSpace()); needs_update_bounding_box_ = true;
diff --git a/third_party/blink/renderer/core/layout/paint_containment_test.cc b/third_party/blink/renderer/core/layout/paint_containment_test.cc index 1c0bd98..d93b9b27 100644 --- a/third_party/blink/renderer/core/layout/paint_containment_test.cc +++ b/third_party/blink/renderer/core/layout/paint_containment_test.cc
@@ -40,7 +40,7 @@ DCHECK(obj->IsLayoutBlock()); auto& block = To<LayoutBlock>(*obj); EXPECT_TRUE(block.CreatesNewFormattingContext()); - EXPECT_FALSE(block.CanBeScrolledAndHasScrollableArea()); + EXPECT_FALSE(block.IsUserScrollable()); CheckIsClippingStackingContextAndContainer(block); }
diff --git a/third_party/blink/renderer/core/page/autoscroll_controller.cc b/third_party/blink/renderer/core/page/autoscroll_controller.cc index 359e30a..d267c77 100644 --- a/third_party/blink/renderer/core/page/autoscroll_controller.cc +++ b/third_party/blink/renderer/core/page/autoscroll_controller.cc
@@ -260,9 +260,9 @@ vertical_autoscroll_layout_box_ && vertical_autoscroll_layout_box_->GetNode(); if (horizontal_autoscroll_possible && - !horizontal_autoscroll_layout_box_->CanBeScrolledAndHasScrollableArea() && + !horizontal_autoscroll_layout_box_->IsUserScrollable() && vertical_autoscroll_possible && - !vertical_autoscroll_layout_box_->CanBeScrolledAndHasScrollableArea()) { + !vertical_autoscroll_layout_box_->IsUserScrollable()) { StopMiddleClickAutoscroll(frame); return; }
diff --git a/third_party/blink/renderer/core/page/spatial_navigation.cc b/third_party/blink/renderer/core/page/spatial_navigation.cc index 1a4473c..6b4a567fd 100644 --- a/third_party/blink/renderer/core/page/spatial_navigation.cc +++ b/third_party/blink/renderer/core/page/spatial_navigation.cc
@@ -335,8 +335,9 @@ if (node->IsDocumentNode()) return true; - if (auto* box = DynamicTo<LayoutBox>(node->GetLayoutObject())) - return box->CanBeScrolledAndHasScrollableArea(); + if (auto* box = DynamicTo<LayoutBox>(node->GetLayoutObject())) { + return box->IsUserScrollable(); + } return false; }
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc index 14dc858d..796d2c3 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.cc
@@ -600,12 +600,12 @@ } gfx::Vector2d PaintLayerScrollableArea::MinimumScrollOffsetInt() const { - return -ScrollOrigin().OffsetFromOrigin(); + return -ScrollOriginInt().OffsetFromOrigin(); } gfx::Vector2d PaintLayerScrollableArea::MaximumScrollOffsetInt() const { if (!GetLayoutBox() || !GetLayoutBox()->IsScrollContainer()) - return -ScrollOrigin().OffsetFromOrigin(); + return -ScrollOriginInt().OffsetFromOrigin(); gfx::Size content_size = ContentsSize(); @@ -632,7 +632,7 @@ // based on stale layout overflow data (http://crbug.com/576933). content_size.SetToMax(visible_size); - return -ScrollOrigin().OffsetFromOrigin() + + return -ScrollOriginInt().OffsetFromOrigin() + gfx::Vector2d(content_size.width() - visible_size.width(), content_size.height() - visible_size.height()); } @@ -672,7 +672,8 @@ IncludeScrollbarsInRect scrollbar_inclusion) const { const ComputedStyle* style = GetLayoutBox()->Style(); PhysicalRect layout_content_rect(LayoutContentRect(scrollbar_inclusion)); - layout_content_rect.Move(PhysicalOffset(-ScrollOrigin().OffsetFromOrigin())); + layout_content_rect.Move( + PhysicalOffset(-ScrollOriginInt().OffsetFromOrigin())); NGPhysicalBoxStrut padding( MinimumValueForLength(style->ScrollPaddingTop(), layout_content_rect.Height()), @@ -904,14 +905,15 @@ PhysicalRect scrollable_overflow = overflow_rect_; scrollable_overflow.Move(-PhysicalOffset(GetLayoutBox()->BorderLeft(), GetLayoutBox()->BorderTop())); - gfx::Point new_origin = ToFlooredPoint(-scrollable_overflow.offset) + - GetLayoutBox()->OriginAdjustmentForScrollbars(); - if (new_origin != scroll_origin_) { + gfx::Point new_origin = + ToFlooredPoint(-scrollable_overflow.offset) + + ToFlooredVector2d(GetLayoutBox()->OriginAdjustmentForScrollbars()); + if (new_origin != scroll_origin_int_) { scroll_origin_changed_ = true; // ScrollOrigin affects paint offsets of the scrolling contents. GetLayoutBox()->SetSubtreeShouldCheckForPaintInvalidation(); } - scroll_origin_ = new_origin; + scroll_origin_int_ = new_origin; } void PaintLayerScrollableArea::UpdateScrollDimensions() { @@ -2253,7 +2255,7 @@ -GetLayoutBox()->BorderTop()); // There might be scroll bar between border_origin and scroll_origin. gfx::Vector2d scroll_bar_adjustment = - GetLayoutBox()->OriginAdjustmentForScrollbars(); + ToFlooredVector2d(GetLayoutBox()->OriginAdjustmentForScrollbars()); border_origin_to_scroll_origin.left -= scroll_bar_adjustment.x(); border_origin_to_scroll_origin.top -= scroll_bar_adjustment.y(); border_origin_to_scroll_origin +=
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h index cfc5d5f..11a3250 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area.h
@@ -288,11 +288,11 @@ int ScrollSize(ScrollbarOrientation) const override; gfx::PointF ScrollOffsetToPosition( const ScrollOffset& offset) const override { - return gfx::PointF(ScrollOrigin()) + offset; + return gfx::PointF(ScrollOriginInt()) + offset; } ScrollOffset ScrollPositionToOffset( const gfx::PointF& position) const override { - return ScrollOffset(position - gfx::PointF(ScrollOrigin())); + return ScrollOffset(position - gfx::PointF(ScrollOriginInt())); } gfx::Vector2d ScrollOffsetInt() const override; ScrollOffset GetScrollOffset() const override; @@ -335,7 +335,7 @@ void VisibleSizeChanged(); // See renderer/core/layout/README.md for an explanation of scroll origin. - gfx::Point ScrollOrigin() const { return scroll_origin_; } + gfx::Point ScrollOriginInt() const { return scroll_origin_int_; } bool ScrollOriginChanged() const { return scroll_origin_changed_; } void ScrollToAbsolutePosition(const gfx::PointF& position, @@ -343,7 +343,7 @@ mojom::blink::ScrollBehavior::kInstant, mojom::blink::ScrollType scroll_type = mojom::blink::ScrollType::kProgrammatic) { - SetScrollOffset(ScrollOffset(position - gfx::PointF(ScrollOrigin())), + SetScrollOffset(ScrollOffset(position - gfx::PointF(ScrollOriginInt())), scroll_type, scroll_behavior); } @@ -758,14 +758,14 @@ // There are 6 possible combinations of writing mode and direction. Scroll // origin will be non-zero in the x or y axis if there is any reversed // direction or writing-mode. The combinations are: - // writing-mode / direction scrollOrigin.x() set scrollOrigin.y() set + // writing-mode / direction ScrollOrigin.x() set ScrollOrigin.y() set // horizontal-tb / ltr NO NO // horizontal-tb / rtl YES NO // vertical-lr / ltr NO NO // vertical-lr / rtl NO YES // vertical-rl / ltr YES NO // vertical-rl / rtl YES YES - gfx::Point scroll_origin_; + gfx::Point scroll_origin_int_; // The width/height of our scrolled area. // This is OverflowModel's layout overflow translated to physical
diff --git a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc index 8c5349a1..c4e55d2 100644 --- a/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc +++ b/third_party/blink/renderer/core/paint/paint_layer_scrollable_area_test.cc
@@ -615,7 +615,7 @@ PaintLayerScrollableArea* scrollable_area = container->GetLayoutBox()->GetScrollableArea(); ASSERT_TRUE(scrollable_area); - EXPECT_EQ(scrollable_area->ScrollOrigin().x(), 100); + EXPECT_EQ(scrollable_area->ScrollOriginInt().x(), 100); } TEST_P(MAYBE_PaintLayerScrollableAreaTest,
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 1ae35d6..53fe873 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -2629,9 +2629,9 @@ if (const auto* scroll_translation = properties_->ScrollTranslation()) { context_.current.transform = scroll_translation; // See comments for ScrollTranslation in object_paint_properties.h for the - // reason of adding ScrollOrigin(). + // reason of adding ScrollOriginInt(). context_.current.paint_offset += - PhysicalOffset(To<LayoutBox>(object_).ScrollOrigin()); + PhysicalOffset(To<LayoutBox>(object_).ScrollOriginInt()); // A scroller creates a layout shift root, so we just calculate one scroll // offset delta without accumulation. context_.current.scroll_offset_to_layout_shift_root_delta = @@ -2664,10 +2664,10 @@ if (properties_->Scroll()) context_.fixed_position.scroll = properties_->Scroll(); if (properties_->ScrollTranslation()) { - // Also undo the ScrollOrigin part in paint offset that was added when + // Also undo the ScrollOriginInt part in paint offset that was added when // ScrollTranslation was updated. context_.fixed_position.paint_offset -= - PhysicalOffset(To<LayoutBox>(object_).ScrollOrigin()); + PhysicalOffset(To<LayoutBox>(object_).ScrollOriginInt()); } } else if (object_.CanContainFixedPositionObjects()) { context_.fixed_position = context_.current;
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc index 1449171..8dad253 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder_test.cc
@@ -406,7 +406,7 @@ EXPECT_EQ(gfx::Rect(10, 10, 85, 85), scroll->ContainerRect()); EXPECT_EQ(gfx::Rect(10, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); - EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOrigin()); + EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOriginInt()); EXPECT_EQ(PhysicalOffset(10, 10), content->FirstFragment().PaintOffset()); EXPECT_EQ(DocContentClip(), overflow_clip->Parent()); @@ -425,7 +425,7 @@ EXPECT_EQ(gfx::Rect(10, 10, 85, 85), scroll->ContainerRect()); EXPECT_EQ(gfx::Rect(10, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); - EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOrigin()); + EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOriginInt()); EXPECT_EQ(PhysicalOffset(10, 10), content->FirstFragment().PaintOffset()); EXPECT_EQ(DocContentClip(), overflow_clip->Parent()); @@ -459,7 +459,7 @@ EXPECT_EQ(gfx::Rect(25, 10, 85, 85), scroll->ContainerRect()); EXPECT_EQ(gfx::Rect(25, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); - EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOrigin()); + EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOriginInt()); EXPECT_EQ(PhysicalOffset(25, 10), content->FirstFragment().PaintOffset()); EXPECT_EQ(DocContentClip(), overflow_clip->Parent()); @@ -478,7 +478,7 @@ EXPECT_EQ(gfx::Rect(25, 10, 85, 85), scroll->ContainerRect()); EXPECT_EQ(gfx::Rect(25, 10, 400, 400), scroll->ContentsRect()); EXPECT_EQ(PhysicalOffset(), scroller->FirstFragment().PaintOffset()); - EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOrigin()); + EXPECT_EQ(gfx::Point(315, 0), scroller->ScrollOriginInt()); EXPECT_EQ(PhysicalOffset(25, 10), content->FirstFragment().PaintOffset()); EXPECT_EQ(DocContentClip(), overflow_clip->Parent());
diff --git a/third_party/blink/renderer/core/paint/scoped_paint_state.cc b/third_party/blink/renderer/core/paint/scoped_paint_state.cc index ad5b9a6..ab53a92 100644 --- a/third_party/blink/renderer/core/paint/scoped_paint_state.cc +++ b/third_party/blink/renderer/core/paint/scoped_paint_state.cc
@@ -120,11 +120,11 @@ if (const auto* properties = fragment_to_paint_->PaintProperties()) { // See comments for ScrollTranslation in object_paint_properties.h - // for the reason of adding ScrollOrigin(). The paint offset will + // for the reason of adding ScrollOriginInt(). The paint offset will // be used only for the scrolling contents that are not painted through // descendant objects' Paint() method, e.g. inline boxes. if (properties->ScrollTranslation()) - paint_offset_ += PhysicalOffset(box.ScrollOrigin()); + paint_offset_ += PhysicalOffset(box.ScrollOriginInt()); } // We calculated cull rects for PaintLayers only.
diff --git a/third_party/blink/renderer/core/paint/view_painter.cc b/third_party/blink/renderer/core/paint/view_painter.cc index b41fa73..11f273d 100644 --- a/third_party/blink/renderer/core/paint/view_painter.cc +++ b/third_party/blink/renderer/core/paint/view_painter.cc
@@ -113,10 +113,10 @@ if (painting_background_in_contents_space) { // Layout overflow, combined with the visible content size. auto document_rect = layout_view_.DocumentRect(); - // DocumentRect is relative to ScrollOrigin. Add ScrollOrigin to let it be - // in the space of ContentsProperties(). See ScrollTranslation in + // DocumentRect is relative to ScrollOriginInt. Add ScrollOriginInt to let + // it be in the space of ContentsProperties(). See ScrollTranslation in // object_paint_properties.h for details. - document_rect.Move(PhysicalOffset(layout_view_.ScrollOrigin())); + document_rect.Move(PhysicalOffset(layout_view_.ScrollOriginInt())); background_rect.Unite(document_rect); background_client = &layout_view_.GetScrollableArea() ->GetScrollingBackgroundDisplayItemClient();
diff --git a/third_party/blink/renderer/core/script/detect_javascript_frameworks.cc b/third_party/blink/renderer/core/script/detect_javascript_frameworks.cc index 46f6ef5..d17cdedb 100644 --- a/third_party/blink/renderer/core/script/detect_javascript_frameworks.cc +++ b/third_party/blink/renderer/core/script/detect_javascript_frameworks.cc
@@ -81,11 +81,9 @@ inline void CheckAttributeMatches(const Element& element, JavaScriptFrameworkDetectionResult& result, AtomicString& detected_ng_version) { - DEFINE_STATIC_LOCAL(QualifiedName, ng_version, - (g_null_atom, AtomicString("ng-version"), g_null_atom)); - DEFINE_STATIC_LOCAL( - QualifiedName, data_reactroot, - (g_null_atom, AtomicString("data-reactroot"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, ng_version, (AtomicString("ng-version"))); + DEFINE_STATIC_LOCAL(QualifiedName, data_reactroot, + (AtomicString("data-reactroot"))); static constexpr char kSvelte[] = "svelte-"; if (element.FastHasAttribute(data_reactroot)) { result.detected_versions[JavaScriptFramework::kReact] =
diff --git a/third_party/blink/renderer/core/streams/byte_stream_tee_engine.cc b/third_party/blink/renderer/core/streams/byte_stream_tee_engine.cc index 14920c60..d408dab 100644 --- a/third_party/blink/renderer/core/streams/byte_stream_tee_engine.cc +++ b/third_party/blink/renderer/core/streams/byte_stream_tee_engine.cc
@@ -210,6 +210,7 @@ private: void ChunkStepsBody(ScriptState* script_state, v8::Global<v8::Value> value) const { + ScriptState::Scope scope(script_state); // 1. Set readAgainForBranch1 to false. engine_->read_again_for_branch_[0] = false; // 2. Set readAgainForBranch2 to false.
diff --git a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h index 8cbeb74..e1bb386 100644 --- a/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h +++ b/third_party/blink/renderer/core/streams/readable_byte_stream_controller.h
@@ -67,6 +67,8 @@ void Trace(Visitor*) const override; private: + friend class BodyStreamBuffer; + friend class BodyStreamBufferUnderlyingByteSource; friend class ByteStreamTeeEngine; friend class ReadableStream; friend class ReadableStreamBYOBReader;
diff --git a/third_party/blink/renderer/core/svg/svg_animate_element.cc b/third_party/blink/renderer/core/svg/svg_animate_element.cc index 845dc1d..3608ac7 100644 --- a/third_party/blink/renderer/core/svg/svg_animate_element.cc +++ b/third_party/blink/renderer/core/svg/svg_animate_element.cc
@@ -87,7 +87,7 @@ if (attribute_name.empty()) return AnyQName(); if (!attribute_name.Contains(':')) - return QualifiedName(g_null_atom, attribute_name, g_null_atom); + return QualifiedName(attribute_name); AtomicString prefix; AtomicString local_name;
diff --git a/third_party/blink/renderer/modules/BUILD.gn b/third_party/blink/renderer/modules/BUILD.gn index 40d530b..69c87e5 100644 --- a/third_party/blink/renderer/modules/BUILD.gn +++ b/third_party/blink/renderer/modules/BUILD.gn
@@ -525,7 +525,6 @@ "mediastream/media_stream_set_test.cc", "mediastream/media_stream_track_impl_test.cc", "mediastream/media_stream_track_transfer_test.cc", - "mediastream/media_stream_utils_test.cc", "mediastream/media_stream_video_capturer_source_test.cc", "mediastream/media_stream_video_renderer_sink_test.cc", "mediastream/media_stream_video_source_test.cc",
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object.cc b/third_party/blink/renderer/modules/accessibility/ax_object.cc index 8c06b8f..3508018 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object.cc
@@ -5862,7 +5862,7 @@ } return GetLayoutObject() && GetLayoutObject()->IsBox() && - To<LayoutBox>(GetLayoutObject())->CanBeScrolledAndHasScrollableArea(); + To<LayoutBox>(GetLayoutObject())->IsUserScrollable(); } gfx::Point AXObject::GetScrollOffset() const {
diff --git a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc index e9089beb..83e3fcc 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.cc
@@ -1437,6 +1437,13 @@ AssociateAXID(new_obj, axid); new_obj->Init(parent); + // Only rebuild the child list of the parent if we had to compute + // the parent here, and it wasn't passed in as context. In other situations, + // we should know about the child already. + if (parent && parent != parent_if_known) { + parent->ChildrenChangedWithCleanLayout(); + } + return new_obj; }
diff --git a/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc b/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc index acb3492..cea501f 100644 --- a/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc +++ b/third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.cc
@@ -4,11 +4,9 @@ #include "third_party/blink/renderer/modules/accessibility/ax_sparse_attribute_setter.h" -#include "third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom-blink.h" #include "third_party/blink/renderer/core/dom/qualified_name.h" #include "third_party/blink/renderer/core/execution_context/execution_context.h" #include "third_party/blink/renderer/modules/accessibility/ax_object_cache_impl.h" -#include "third_party/blink/renderer/platform/instrumentation/use_counter.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/wtf/functional.h" @@ -25,18 +23,6 @@ AXObject* object, ui::AXNodeData* node_data, const AtomicString& value) { - // Don't set kTouchPassthrough unless the feature is enabled in this - // context. - if (attribute == ax::mojom::blink::BoolAttribute::kTouchPassthrough) { - auto* context = object->AXObjectCache().GetDocument().GetExecutionContext(); - if (RuntimeEnabledFeatures::AccessibilityAriaTouchPassthroughEnabled( - context)) { - UseCounter::Count(context, WebFeature::kAccessibilityTouchPassthroughSet); - } else { - return; - } - } - // ARIA booleans are true if not "false" and not specifically undefined. bool is_true = !AccessibleNode::IsUndefinedAttrValue(value) && !EqualIgnoringASCIICase(value, "false"); @@ -204,10 +190,6 @@ WTF::BindRepeating( &SetStringAttribute, ax::mojom::blink::StringAttribute::kRoleDescription)); - ax_sparse_setter_map.Set( - html_names::kAriaTouchpassthroughAttr, - WTF::BindRepeating(&SetBoolAttribute, - ax::mojom::blink::BoolAttribute::kTouchPassthrough)); if (RuntimeEnabledFeatures::AccessibilityAriaVirtualContentEnabled()) { ax_sparse_setter_map.Set( html_names::kAriaVirtualcontentAttr,
diff --git a/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py b/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py index 425aa9e..6999bd2 100644 --- a/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py +++ b/third_party/blink/renderer/modules/bluetooth/testing/clusterfuzz/PRESUBMIT.py
@@ -6,13 +6,10 @@ def _RunTests(input_api, output_api): """Runs all test files in the directory.""" - return input_api.canned_checks.RunUnitTests( - input_api, - output_api, [ - input_api.os_path.join(input_api.PresubmitLocalPath(), - 'fuzz_integration_test.py') - ], - skip_shebang_check=True) + return input_api.canned_checks.RunUnitTests(input_api, output_api, [ + input_api.os_path.join(input_api.PresubmitLocalPath(), + 'fuzz_integration_test.py') + ]) def CheckChangeOnUpload(input_api, output_api):
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc index d76c7c4..39bfe5c 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_cursor.cc
@@ -47,6 +47,7 @@ #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/wtf/casting.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -362,7 +363,7 @@ script_state, this, transaction_.Get(), std::move(metrics)); transaction_->BackendDB()->Delete( transaction_->Id(), EffectiveObjectStore()->Id(), IdbPrimaryKey(), - request->CreateWebCallbacks().release()); + WTF::BindOnce(&IDBRequest::OnDelete, WrapPersistent(request))); return request; }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_index.cc b/third_party/blink/renderer/modules/indexeddb/idb_index.cc index b0a879e3..dac5381 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_index.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_index.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h" #include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" +#include "third_party/blink/renderer/platform/wtf/functional.h" namespace blink { @@ -153,10 +154,8 @@ IDBRequest* request = IDBRequest::Create( script_state, this, transaction_.Get(), std::move(metrics)); request->SetCursorDetails(indexed_db::kCursorKeyAndValue, direction); - BackendDB()->OpenCursor(transaction_->Id(), object_store_->Id(), Id(), - key_range, direction, false, - mojom::IDBTaskType::Normal, - request->CreateWebCallbacks().release()); + BackendDB()->OpenCursor(object_store_->Id(), Id(), key_range, direction, + false, mojom::IDBTaskType::Normal, request); return request; } @@ -229,9 +228,8 @@ IDBRequest* request = IDBRequest::Create( script_state, this, transaction_.Get(), std::move(metrics)); request->SetCursorDetails(indexed_db::kCursorKeyOnly, direction); - BackendDB()->OpenCursor( - transaction_->Id(), object_store_->Id(), Id(), key_range, direction, true, - mojom::IDBTaskType::Normal, request->CreateWebCallbacks().release()); + BackendDB()->OpenCursor(object_store_->Id(), Id(), key_range, direction, true, + mojom::IDBTaskType::Normal, request); return request; } @@ -344,7 +342,8 @@ IDBRequest* request = IDBRequest::Create( script_state, this, transaction_.Get(), std::move(metrics)); BackendDB()->Get(transaction_->Id(), object_store_->Id(), Id(), key_range, - key_only, request->CreateWebCallbacks().release()); + key_only, + WTF::BindOnce(&IDBRequest::OnGet, WrapPersistent(request))); return request; }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc index a2822c4..b485517e2 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_object_store.cc
@@ -168,7 +168,7 @@ script_state, this, transaction_.Get(), std::move(metrics)); BackendDB()->Get(transaction_->Id(), Id(), IDBIndexMetadata::kInvalidId, key_range, /*key_only=*/false, - request->CreateWebCallbacks().release()); + WTF::BindOnce(&IDBRequest::OnGet, WrapPersistent(request))); return request; } @@ -210,7 +210,7 @@ script_state, this, transaction_.Get(), std::move(metrics)); BackendDB()->Get(transaction_->Id(), Id(), IDBIndexMetadata::kInvalidId, key_range, /*key_only=*/true, - request->CreateWebCallbacks().release()); + WTF::BindOnce(&IDBRequest::OnGet, WrapPersistent(request))); return request; } @@ -726,9 +726,9 @@ IDBRequest::AsyncTraceState metrics) { IDBRequest* request = IDBRequest::Create( script_state, this, transaction_.Get(), std::move(metrics)); - - BackendDB()->DeleteRange(transaction_->Id(), Id(), key_range, - request->CreateWebCallbacks().release()); + BackendDB()->DeleteRange( + transaction_->Id(), Id(), key_range, + WTF::BindOnce(&IDBRequest::OnDelete, WrapPersistent(request))); return request; } @@ -1084,9 +1084,8 @@ script_state, this, transaction_.Get(), std::move(metrics)); request->SetCursorDetails(indexed_db::kCursorKeyAndValue, direction); - BackendDB()->OpenCursor(transaction_->Id(), Id(), - IDBIndexMetadata::kInvalidId, range, direction, false, - task_type, request->CreateWebCallbacks().release()); + BackendDB()->OpenCursor(Id(), IDBIndexMetadata::kInvalidId, range, direction, + false, task_type, request); return request; } @@ -1127,10 +1126,8 @@ script_state, this, transaction_.Get(), std::move(metrics)); request->SetCursorDetails(indexed_db::kCursorKeyOnly, direction); - BackendDB()->OpenCursor(transaction_->Id(), Id(), - IDBIndexMetadata::kInvalidId, key_range, direction, - true, mojom::IDBTaskType::Normal, - request->CreateWebCallbacks().release()); + BackendDB()->OpenCursor(Id(), IDBIndexMetadata::kInvalidId, key_range, + direction, true, mojom::IDBTaskType::Normal, request); return request; }
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.cc b/third_party/blink/renderer/modules/indexeddb/idb_request.cc index b1abb5a..62713f6 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request.cc
@@ -41,6 +41,7 @@ #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/core/dom/events/event_queue.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" #include "third_party/blink/renderer/modules/indexeddb/idb_cursor_with_value.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database.h" @@ -146,7 +147,10 @@ source_(source), event_queue_( MakeGarbageCollected<EventQueue>(ExecutionContext::From(script_state), - TaskType::kDatabaseAccess)) {} + TaskType::kDatabaseAccess)) { + async_task_context_.Schedule(ExecutionContext::From(script_state), + indexed_db_names::kIndexedDB); +} IDBRequest::~IDBRequest() { if (!GetExecutionContext()) @@ -447,10 +451,72 @@ void IDBRequest::OnClear(bool success) { if (success) { + probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_, + "clear"); HandleResponse(); } } +void IDBRequest::OnDelete(bool success) { + if (success) { + probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_, + "delete"); + HandleResponse(); + } +} + +void IDBRequest::OnGet(mojom::blink::IDBDatabaseGetResultPtr result) { + if (result->is_error_result()) { + HandleError(std::move(result->get_error_result())); + return; + } + + probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_, + "get"); + if (result->is_empty()) { + HandleResponse(); + } else if (result->is_key()) { + HandleResponse(std::move(result->get_key())); + } else if (result->is_value()) { + std::unique_ptr<IDBValue> value = + IDBValue::ConvertReturnValue(result->get_value()); + value->SetIsolate(GetIsolate()); + HandleResponse(std::move(value)); + } +} + +void IDBRequest::OnOpenCursor( + mojom::blink::IDBDatabaseOpenCursorResultPtr result) { + if (result->is_error_result()) { + HandleError(std::move(result->get_error_result())); + return; + } + + probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_, + "openCursor"); + if (result->is_empty()) { + std::unique_ptr<IDBValue> value = IDBValue::ConvertReturnValue(nullptr); + value->SetIsolate(GetIsolate()); + HandleResponse(std::move(value)); + return; + } + + std::unique_ptr<WebIDBCursor> cursor = std::make_unique<WebIDBCursor>( + std::move(result->get_value()->cursor), transaction_->Id(), + GetExecutionContext()->GetTaskRunner(TaskType::kDatabaseAccess)); + std::unique_ptr<IDBValue> value; + if (result->get_value()->value) { + value = std::move(*result->get_value()->value); + } else { + value = std::make_unique<IDBValue>(scoped_refptr<SharedBuffer>(), + Vector<WebBlobInfo>()); + } + + value->SetIsolate(GetIsolate()); + HandleResponse(std::move(cursor), std::move(result->get_value()->key), + std::move(result->get_value()->primary_key), std::move(value)); +} + void IDBRequest::EnqueueResponse(DOMException* error) { TRACE_EVENT0("IndexedDB", "IDBRequest::EnqueueResponse(DOMException)"); if (!ShouldEnqueueEvent()) { @@ -464,6 +530,30 @@ EnqueueEvent(Event::CreateCancelableBubble(event_type_names::kError)); } +void IDBRequest::HandleError(mojom::blink::IDBErrorPtr error) { + mojom::blink::IDBException code = error->error_code; + // In some cases, the backend clears the pending transaction task queue + // which destroys all pending tasks. If our callback was queued with a task + // that gets cleared, we'll get a signal with an IgnorableAbortError as the + // task is torn down. This means the error response can be safely ignored. + if (code == mojom::blink::IDBException::kIgnorableAbortError) { + return; + } + probe::AsyncTask async_task(GetExecutionContext(), &async_task_context_, + "error"); + auto* exception = MakeGarbageCollected<DOMException>( + static_cast<DOMExceptionCode>(code), std::move(error->error_message)); + + transit_blob_handles_.clear(); + if (!transaction_ || !transaction_->HasQueuedResults()) { + return EnqueueResponse(exception); + } + transaction_->EnqueueResult(std::make_unique<IDBRequestQueueItem>( + this, exception, + WTF::BindOnce(&IDBTransaction::OnResultReady, + WrapPersistent(transaction_.Get())))); +} + void IDBRequest::EnqueueResponse(std::unique_ptr<WebIDBCursor> backend, std::unique_ptr<IDBKey> key, std::unique_ptr<IDBKey> primary_key,
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request.h b/third_party/blink/renderer/modules/indexeddb/idb_request.h index 2e67f39e..382c0426 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request.h +++ b/third_party/blink/renderer/modules/indexeddb/idb_request.h
@@ -44,6 +44,7 @@ #include "third_party/blink/renderer/core/dom/events/event_queue.h" #include "third_party/blink/renderer/core/dom/events/event_target.h" #include "third_party/blink/renderer/core/execution_context/execution_context_lifecycle_observer.h" +#include "third_party/blink/renderer/core/probe/async_task_context.h" #include "third_party/blink/renderer/modules/event_modules.h" #include "third_party/blink/renderer/modules/indexeddb/idb_any.h" #include "third_party/blink/renderer/modules/indexeddb/idb_transaction.h" @@ -276,13 +277,15 @@ void HandleResponse(Vector<std::unique_ptr<IDBValue>>); void HandleResponse(Vector<Vector<std::unique_ptr<IDBValue>>>); void HandleResponse(int64_t); - void HandleResponse(); void HandleResponse( bool key_only, mojo::PendingReceiver<mojom::blink::IDBDatabaseGetAllResultSink> receiver); void OnClear(bool success); + void OnDelete(bool success); + void OnGet(mojom::blink::IDBDatabaseGetResultPtr result); + void OnOpenCursor(mojom::blink::IDBDatabaseOpenCursorResultPtr result); // Only IDBOpenDBRequest instances should receive these: virtual void EnqueueBlocked(int64_t old_version) { NOTREACHED(); } @@ -371,14 +374,21 @@ AsyncTraceState metrics_; private: + friend class IDBRequestTest; + // Calls EnqueueResponse(). friend class IDBRequestQueueItem; + // See docs above for HandleResponse() variants. + void HandleResponse(); + void SetResultCursor(IDBCursor*, std::unique_ptr<IDBKey>, std::unique_ptr<IDBKey> primary_key, std::unique_ptr<IDBValue>); + void HandleError(mojom::blink::IDBErrorPtr error); + void EnqueueResponse(DOMException*); void EnqueueResponse(std::unique_ptr<IDBKey>); void EnqueueResponse(std::unique_ptr<WebIDBCursor>, @@ -429,6 +439,8 @@ // // The IDBRequestQueueItem is owned by the result queue in IDBTransaction. IDBRequestQueueItem* queue_item_ = nullptr; + + probe::AsyncTaskContext async_task_context_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc index 624e0cc..ee9cb05 100644 --- a/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc +++ b/third_party/blink/renderer/modules/indexeddb/idb_request_test.cc
@@ -69,7 +69,6 @@ #include "v8/include/v8.h" namespace blink { -namespace { class BackendDatabaseWithMockedClose : public testing::StrictMock<mojom::blink::IDBDatabase> { @@ -134,8 +133,7 @@ void DeleteRange(int64_t transaction_id, int64_t object_store_id, mojom::blink::IDBKeyRangePtr key_range, - mojo::PendingAssociatedRemote<mojom::blink::IDBCallbacks> - pending_callbacks) override {} + DeleteRangeCallback callback) override {} void GetKeyGeneratorCurrentNumber( int64_t transaction_id, int64_t object_store_id, @@ -209,6 +207,26 @@ store_ = MakeGarbageCollected<IDBObjectStore>(store_metadata, transaction_); } + void EnsureIDBCallbacksDontThrow(IDBRequest* request, + ExceptionState& exception_state) { + ASSERT_TRUE(request->transaction()); + V8TestingScope scope; + + request->HandleResponse(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kAbortError, "Description goes here.")); + request->HandleResponse(nullptr, IDBKey::CreateInvalid(), + IDBKey::CreateInvalid(), + CreateNullIDBValueForTesting(scope.GetIsolate())); + request->HandleResponse(IDBKey::CreateInvalid()); + request->HandleResponse(CreateNullIDBValueForTesting(scope.GetIsolate())); + request->HandleResponse(static_cast<int64_t>(0)); + request->HandleResponse(); + request->HandleResponse(IDBKey::CreateInvalid(), IDBKey::CreateInvalid(), + CreateNullIDBValueForTesting(scope.GetIsolate())); + + EXPECT_TRUE(!exception_state.HadException()); + } + URLLoaderMockFactory* url_loader_mock_factory_; Persistent<IDBDatabase> db_; Persistent<IDBTransaction> transaction_; @@ -221,26 +239,6 @@ const int64_t IDBRequestTest::kTransactionId; -void EnsureIDBCallbacksDontThrow(IDBRequest* request, - ExceptionState& exception_state) { - ASSERT_TRUE(request->transaction()); - V8TestingScope scope; - - request->HandleResponse(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kAbortError, "Description goes here.")); - request->HandleResponse(nullptr, IDBKey::CreateInvalid(), - IDBKey::CreateInvalid(), - CreateNullIDBValueForTesting(scope.GetIsolate())); - request->HandleResponse(IDBKey::CreateInvalid()); - request->HandleResponse(CreateNullIDBValueForTesting(scope.GetIsolate())); - request->HandleResponse(static_cast<int64_t>(0)); - request->HandleResponse(); - request->HandleResponse(IDBKey::CreateInvalid(), IDBKey::CreateInvalid(), - CreateNullIDBValueForTesting(scope.GetIsolate())); - - EXPECT_TRUE(!exception_state.HadException()); -} - TEST_F(IDBRequestTest, EventsAfterEarlyDeathStop) { V8TestingScope scope; MockIDBDatabase database_backend; @@ -527,5 +525,4 @@ EXPECT_TRUE(source_state.IsEmpty()); } -} // namespace } // namespace blink
diff --git a/third_party/blink/renderer/modules/indexeddb/mock_idb_database.h b/third_party/blink/renderer/modules/indexeddb/mock_idb_database.h index 4c7940b1..d5789e4e 100644 --- a/third_party/blink/renderer/modules/indexeddb/mock_idb_database.h +++ b/third_party/blink/renderer/modules/indexeddb/mock_idb_database.h
@@ -122,7 +122,7 @@ (int64_t transaction_id, int64_t object_store_id, mojom::blink::IDBKeyRangePtr, - mojo::PendingAssociatedRemote<mojom::blink::IDBCallbacks>), + DeleteRangeCallback), (override)); MOCK_METHOD(void, GetKeyGeneratorCurrentNumber,
diff --git a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.cc b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.cc index 62b0f49d..49f7dc63 100644 --- a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.cc +++ b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.cc
@@ -23,14 +23,6 @@ DoSuccessCursorContinue(key, primary_key, value); } -void MockWebIDBCallbacks::SuccessCursor( - mojo::PendingAssociatedRemote<mojom::blink::IDBCursor> cursor_info, - std::unique_ptr<IDBKey> key, - std::unique_ptr<IDBKey> primary_key, - absl::optional<std::unique_ptr<IDBValue>> optional_value) { - DoSuccessCursor(cursor_info, key, primary_key, optional_value); -} - void MockWebIDBCallbacks::SuccessKey(std::unique_ptr<IDBKey> key) { DoSuccessKey(key); }
diff --git a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h index c42dccc4..fb5b18b 100644 --- a/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h +++ b/third_party/blink/renderer/modules/indexeddb/mock_web_idb_callbacks.h
@@ -40,19 +40,6 @@ const std::unique_ptr<IDBKey>& primaryKey, const absl::optional<std::unique_ptr<IDBValue>>& value)); - void SuccessCursor( - mojo::PendingAssociatedRemote<mojom::blink::IDBCursor> cursor_info, - std::unique_ptr<IDBKey> key, - std::unique_ptr<IDBKey> primary_key, - absl::optional<std::unique_ptr<IDBValue>> optional_value) override; - MOCK_METHOD4( - DoSuccessCursor, - void(const mojo::PendingAssociatedRemote<mojom::blink::IDBCursor>& - cursor_info, - const std::unique_ptr<IDBKey>& key, - const std::unique_ptr<IDBKey>& primary_key, - const absl::optional<std::unique_ptr<IDBValue>>& optional_value)); - MOCK_METHOD3(SuccessCursorPrefetch, void(Vector<std::unique_ptr<IDBKey>> keys, Vector<std::unique_ptr<IDBKey>> primary_keys,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h index c78570d7..d92447c 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks.h
@@ -47,11 +47,6 @@ virtual void DetachRequestFromCallback() = 0; virtual void SetState(base::WeakPtr<WebIDBCursor> cursor, int64_t transaction_id) = 0; - virtual void SuccessCursor( - mojo::PendingAssociatedRemote<mojom::blink::IDBCursor> cursor_info, - std::unique_ptr<IDBKey> key, - std::unique_ptr<IDBKey> primary_key, - absl::optional<std::unique_ptr<IDBValue>> optional_value) = 0; virtual void SuccessCursorContinue( std::unique_ptr<IDBKey>, std::unique_ptr<IDBKey> primary_key,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc index 9670040..f3ae81ca 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.cc
@@ -108,34 +108,6 @@ static_cast<DOMExceptionCode>(code), message)); } -void WebIDBCallbacksImpl::SuccessCursor( - mojo::PendingAssociatedRemote<mojom::blink::IDBCursor> cursor_info, - std::unique_ptr<IDBKey> key, - std::unique_ptr<IDBKey> primary_key, - absl::optional<std::unique_ptr<IDBValue>> optional_value) { - if (!request_) - return; - - std::unique_ptr<WebIDBCursor> cursor = std::make_unique<WebIDBCursor>( - std::move(cursor_info), transaction_id_, task_runner_); - std::unique_ptr<IDBValue> value; - if (optional_value.has_value()) { - value = std::move(optional_value.value()); - } else { - value = std::make_unique<IDBValue>(scoped_refptr<SharedBuffer>(), - Vector<WebBlobInfo>()); - } - DCHECK(value); - - probe::AsyncTask async_task(request_->GetExecutionContext(), - &async_task_context_, "success"); - value->SetIsolate(request_->GetIsolate()); - IDBRequest* request = request_.Get(); - Detach(); - request->HandleResponse(std::move(cursor), std::move(key), - std::move(primary_key), std::move(value)); -} - void WebIDBCallbacksImpl::SuccessCursorPrefetch( Vector<std::unique_ptr<IDBKey>> keys, Vector<std::unique_ptr<IDBKey>> primary_keys, @@ -248,17 +220,6 @@ request->HandleResponse(value); } -void WebIDBCallbacksImpl::Success() { - if (!request_) - return; - - probe::AsyncTask async_task(request_->GetExecutionContext(), - &async_task_context_, "success"); - IDBRequest* request = request_.Get(); - Detach(); - request->HandleResponse(); -} - void WebIDBCallbacksImpl::SuccessCursorContinue( std::unique_ptr<IDBKey> key, std::unique_ptr<IDBKey> primary_key,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h index a0774f7..4d44039a 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_callbacks_impl.h
@@ -66,11 +66,6 @@ // Pointers transfer ownership. void Error(mojom::blink::IDBException code, const String& message) override; - void SuccessCursor( - mojo::PendingAssociatedRemote<mojom::blink::IDBCursor> cursor_info, - std::unique_ptr<IDBKey> key, - std::unique_ptr<IDBKey> primary_key, - absl::optional<std::unique_ptr<IDBValue>> optional_value) override; void SuccessCursorPrefetch(Vector<std::unique_ptr<IDBKey>> keys, Vector<std::unique_ptr<IDBKey>> primary_keys, Vector<std::unique_ptr<IDBValue>> values) override; @@ -83,7 +78,6 @@ void SuccessArrayArray( Vector<Vector<mojom::blink::IDBReturnValuePtr>>) override; void SuccessInteger(int64_t) override; - void Success() override; void SuccessCursorContinue( std::unique_ptr<IDBKey>, std::unique_ptr<IDBKey> primary_key,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database.cc b/third_party/blink/renderer/modules/indexeddb/web_idb_database.cc index 925d442..ea4fb7c 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_database.cc +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database.cc
@@ -14,10 +14,12 @@ #include "third_party/blink/public/mojom/indexeddb/indexeddb.mojom-blink.h" #include "third_party/blink/renderer/modules/indexeddb/idb_database_error.h" #include "third_party/blink/renderer/modules/indexeddb/idb_key_range.h" +#include "third_party/blink/renderer/modules/indexeddb/idb_request.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_blink_mojom_traits.h" #include "third_party/blink/renderer/modules/indexeddb/indexed_db_dispatcher.h" #include "third_party/blink/renderer/platform/wtf/functional.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" + namespace blink { WebIDBDatabase::WebIDBDatabase( @@ -54,50 +56,21 @@ database_->VersionChangeIgnored(); } -void WebIDBDatabase::Get(int64_t transaction_id, - int64_t object_store_id, - int64_t index_id, - const IDBKeyRange* key_range, - bool key_only, - WebIDBCallbacks* callbacks_ptr) { - std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); +void WebIDBDatabase::Get( + int64_t transaction_id, + int64_t object_store_id, + int64_t index_id, + const IDBKeyRange* key_range, + bool key_only, + base::OnceCallback<void(mojom::blink::IDBDatabaseGetResultPtr)> + result_callback) { IndexedDBDispatcher::ResetCursorPrefetchCaches(transaction_id, nullptr); mojom::blink::IDBKeyRangePtr key_range_ptr = mojom::blink::IDBKeyRange::From(key_range); - callbacks->SetState(nullptr, transaction_id); database_->Get(transaction_id, object_store_id, index_id, std::move(key_range_ptr), key_only, - WTF::BindOnce(&WebIDBDatabase::GetCallback, - WTF::Unretained(this), std::move(callbacks))); -} - -void WebIDBDatabase::GetCallback(std::unique_ptr<WebIDBCallbacks> callbacks, - mojom::blink::IDBDatabaseGetResultPtr result) { - if (result->is_error_result()) { - callbacks->Error(result->get_error_result()->error_code, - std::move(result->get_error_result()->error_message)); - callbacks.reset(); - return; - } - - if (result->is_empty()) { - callbacks->Success(); - callbacks.reset(); - return; - } - - if (result->is_key()) { - callbacks->SuccessKey(std::move(result->get_key())); - callbacks.reset(); - return; - } - - if (result->is_value()) { - callbacks->SuccessValue(std::move(result->get_value())); - callbacks.reset(); - return; - } + std::move(result_callback)); } void WebIDBDatabase::BatchGetAll( @@ -177,50 +150,22 @@ std::move(index_ids)); } -void WebIDBDatabase::OpenCursor(int64_t transaction_id, - int64_t object_store_id, +void WebIDBDatabase::OpenCursor(int64_t object_store_id, int64_t index_id, const IDBKeyRange* key_range, mojom::blink::IDBCursorDirection direction, bool key_only, mojom::blink::IDBTaskType task_type, - WebIDBCallbacks* callbacks_ptr) { - std::unique_ptr<WebIDBCallbacks> callbacks(callbacks_ptr); - IndexedDBDispatcher::ResetCursorPrefetchCaches(transaction_id, nullptr); + IDBRequest* request) { + IndexedDBDispatcher::ResetCursorPrefetchCaches(request->transaction()->Id(), + nullptr); mojom::blink::IDBKeyRangePtr key_range_ptr = mojom::blink::IDBKeyRange::From(key_range); - callbacks->SetState(nullptr, transaction_id); database_->OpenCursor( - transaction_id, object_store_id, index_id, std::move(key_range_ptr), - direction, key_only, task_type, - WTF::BindOnce(&WebIDBDatabase::OpenCursorCallback, WTF::Unretained(this), - std::move(callbacks))); -} - -void WebIDBDatabase::OpenCursorCallback( - std::unique_ptr<WebIDBCallbacks> callbacks, - mojom::blink::IDBDatabaseOpenCursorResultPtr result) { - if (result->is_error_result()) { - callbacks->Error(result->get_error_result()->error_code, - std::move(result->get_error_result()->error_message)); - callbacks.reset(); - return; - } - - if (result->is_empty()) { - CHECK(result->get_empty()); // Only true values are allowed. - callbacks->SuccessValue(nullptr); - callbacks.reset(); - return; - } - - CHECK(result->is_value()); - callbacks->SuccessCursor(std::move(result->get_value()->cursor), - std::move(result->get_value()->key), - std::move(result->get_value()->primary_key), - std::move(result->get_value()->value)); - callbacks.reset(); + request->transaction()->Id(), object_store_id, index_id, + std::move(key_range_ptr), direction, key_only, task_type, + WTF::BindOnce(&IDBRequest::OnOpenCursor, WrapPersistent(request))); } void WebIDBDatabase::Count(int64_t transaction_id, @@ -241,29 +186,26 @@ void WebIDBDatabase::Delete(int64_t transaction_id, int64_t object_store_id, const IDBKey* primary_key, - WebIDBCallbacks* callbacks) { + base::OnceCallback<void(bool)> success_callback) { IndexedDBDispatcher::ResetCursorPrefetchCaches(transaction_id, nullptr); mojom::blink::IDBKeyRangePtr key_range_ptr = mojom::blink::IDBKeyRange::From(IDBKeyRange::Create(primary_key)); - callbacks->SetState(nullptr, transaction_id); database_->DeleteRange(transaction_id, object_store_id, - std::move(key_range_ptr), - GetCallbacksProxy(base::WrapUnique(callbacks))); + std::move(key_range_ptr), std::move(success_callback)); } -void WebIDBDatabase::DeleteRange(int64_t transaction_id, - int64_t object_store_id, - const IDBKeyRange* key_range, - WebIDBCallbacks* callbacks) { +void WebIDBDatabase::DeleteRange( + int64_t transaction_id, + int64_t object_store_id, + const IDBKeyRange* key_range, + base::OnceCallback<void(bool)> success_callback) { IndexedDBDispatcher::ResetCursorPrefetchCaches(transaction_id, nullptr); mojom::blink::IDBKeyRangePtr key_range_ptr = mojom::blink::IDBKeyRange::From(key_range); - callbacks->SetState(nullptr, transaction_id); database_->DeleteRange(transaction_id, object_store_id, - std::move(key_range_ptr), - GetCallbacksProxy(base::WrapUnique(callbacks))); + std::move(key_range_ptr), std::move(success_callback)); } void WebIDBDatabase::GetKeyGeneratorCurrentNumber(int64_t transaction_id,
diff --git a/third_party/blink/renderer/modules/indexeddb/web_idb_database.h b/third_party/blink/renderer/modules/indexeddb/web_idb_database.h index 90a60e8..a207ae9 100644 --- a/third_party/blink/renderer/modules/indexeddb/web_idb_database.h +++ b/third_party/blink/renderer/modules/indexeddb/web_idb_database.h
@@ -19,6 +19,7 @@ #include "third_party/blink/renderer/modules/modules_export.h" namespace blink { +class IDBRequest; class WebIDBCallbacks; class MODULES_EXPORT WebIDBDatabase final { @@ -43,14 +44,13 @@ void Close(); void VersionChangeIgnored(); - void Get(int64_t transaction_id, - int64_t object_store_id, - int64_t index_id, - const IDBKeyRange*, - bool key_only, - WebIDBCallbacks*); - void GetCallback(std::unique_ptr<WebIDBCallbacks> callbacks, - mojom::blink::IDBDatabaseGetResultPtr result); + void Get( + int64_t transaction_id, + int64_t object_store_id, + int64_t index_id, + const IDBKeyRange*, + bool key_only, + base::OnceCallback<void(mojom::blink::IDBDatabaseGetResultPtr)> result); void GetAll(int64_t transaction_id, int64_t object_store_id, int64_t index_id, @@ -79,16 +79,13 @@ void SetIndexesReady(int64_t transaction_id, int64_t object_store_id, const Vector<int64_t>& index_ids); - void OpenCursor(int64_t transaction_id, - int64_t object_store_id, + void OpenCursor(int64_t object_store_id, int64_t index_id, const IDBKeyRange*, mojom::blink::IDBCursorDirection direction, bool key_only, mojom::blink::IDBTaskType, - WebIDBCallbacks*); - void OpenCursorCallback(std::unique_ptr<WebIDBCallbacks> callbacks, - mojom::blink::IDBDatabaseOpenCursorResultPtr result); + IDBRequest*); void Count(int64_t transaction_id, int64_t object_store_id, int64_t index_id, @@ -97,11 +94,11 @@ void Delete(int64_t transaction_id, int64_t object_store_id, const IDBKey* primary_key, - WebIDBCallbacks*); + base::OnceCallback<void(bool)> success_callback); void DeleteRange(int64_t transaction_id, int64_t object_store_id, const IDBKeyRange*, - WebIDBCallbacks*); + base::OnceCallback<void(bool)> success_callback); void GetKeyGeneratorCurrentNumber(int64_t transaction_id, int64_t object_store_id, WebIDBCallbacks*);
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc index 60ff5ab..84a15fc 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_playback_speed_list_element.cc
@@ -60,9 +60,8 @@ const QualifiedName& PlaybackRateAttrName() { // Save the playback rate in an attribute. - DEFINE_STATIC_LOCAL( - QualifiedName, playback_rate_attr, - (g_null_atom, AtomicString("data-playback-rate"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, playback_rate_attr, + (AtomicString("data-playback-rate"))); return playback_rate_attr; }
diff --git a/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc b/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc index f4df0d1..7d6d2bc 100644 --- a/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc +++ b/third_party/blink/renderer/modules/media_controls/elements/media_control_text_track_list_element.cc
@@ -32,9 +32,8 @@ const QualifiedName& TrackIndexAttrName() { // Save the track index in an attribute to avoid holding a pointer to the text // track. - DEFINE_STATIC_LOCAL( - QualifiedName, track_index_attr, - (g_null_atom, AtomicString("data-track-index"), g_null_atom)); + DEFINE_STATIC_LOCAL(QualifiedName, track_index_attr, + (AtomicString("data-track-index"))); return track_index_attr; }
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc index b09ed520..d02f94c 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc +++ b/third_party/blink/renderer/modules/mediastream/media_stream_utils.cc
@@ -22,7 +22,6 @@ #include "third_party/blink/renderer/platform/mediastream/webaudio_media_stream_source.h" #include "third_party/blink/renderer/platform/scheduler/public/thread.h" #include "ui/display/screen_info.h" -#include "ui/display/screen_infos.h" namespace blink { @@ -46,23 +45,13 @@ if (!frame) { return kDefaultScreenSize; } - int max_width = 0; - int max_height = 0; - const auto& infos = frame->GetChromeClient().GetScreenInfos(*frame); - for (const display::ScreenInfo& info : infos.screen_infos) { - int width = info.rect.width() * info.device_scale_factor; - int height = info.rect.height() * info.device_scale_factor; - if (width > max_width) { - max_width = width; - } - if (height > max_height) { - max_height = height; - } - } - if (max_width == 0 || max_height == 0) { + const display::ScreenInfo& info = + frame->GetChromeClient().GetScreenInfo(*frame); + // If no screen size info, use the default. + if (info.rect.size().IsEmpty()) { return kDefaultScreenSize; } - return gfx::Size(max_width, max_height); + return info.rect.size(); } } // namespace blink
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_utils.h b/third_party/blink/renderer/modules/mediastream/media_stream_utils.h index 89f60a6..6b994888 100644 --- a/third_party/blink/renderer/modules/mediastream/media_stream_utils.h +++ b/third_party/blink/renderer/modules/mediastream/media_stream_utils.h
@@ -7,7 +7,6 @@ #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/mojom/mediastream/media_stream.mojom-blink.h" -#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" #include "ui/gfx/geometry/size.h" @@ -15,13 +14,16 @@ class ExecutionContext; class LocalFrame; +class MediaStreamComponent; class MediaStreamSource; class MediaStreamTrack; -class MODULES_EXPORT MediaStreamUtils { +class MediaStreamUtils { STATIC_ONLY(MediaStreamUtils); public: + static void DidCreateMediaStreamTrack(MediaStreamComponent*); + static MediaStreamTrack* CreateLocalAudioTrack(ExecutionContext*, MediaStreamSource*);
diff --git a/third_party/blink/renderer/modules/mediastream/media_stream_utils_test.cc b/third_party/blink/renderer/modules/mediastream/media_stream_utils_test.cc deleted file mode 100644 index c8aa9d1f..0000000 --- a/third_party/blink/renderer/modules/mediastream/media_stream_utils_test.cc +++ /dev/null
@@ -1,74 +0,0 @@ -#include "third_party/blink/renderer/modules/mediastream/media_stream_utils.h" - -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/blink/renderer/core/testing/core_unit_test_helper.h" -#include "ui/display/screen_info.h" -#include "ui/display/screen_infos.h" - -namespace blink { -namespace { - -class FakeChromeClient : public RenderingTestChromeClient { - public: - const display::ScreenInfos& GetScreenInfos(LocalFrame&) const override { - return screen_infos_; - } - void AddScreenInfo(display::ScreenInfo info) { - screen_infos_.screen_infos.push_back(info); - } - - private: - display::ScreenInfos screen_infos_ = display::ScreenInfos(); -}; - -class ScreenSizeTest : public RenderingTest { - public: - FakeChromeClient& GetChromeClient() const override { return *client_; } - - protected: - Persistent<FakeChromeClient> client_ = - MakeGarbageCollected<FakeChromeClient>(); -}; - -TEST_F(ScreenSizeTest, Basic) { - display::ScreenInfo screen; - screen.rect = gfx::Rect(1920, 1200); - client_->AddScreenInfo(screen); - EXPECT_EQ(MediaStreamUtils::GetScreenSize(&GetFrame()), - gfx::Size(1920, 1200)); -} - -TEST_F(ScreenSizeTest, ScaleFactor) { - display::ScreenInfo screen; - screen.rect = gfx::Rect(1536, 864); - screen.device_scale_factor = 1.25; - client_->AddScreenInfo(screen); - EXPECT_EQ(MediaStreamUtils::GetScreenSize(&GetFrame()), - gfx::Size(1920, 1080)); -} - -TEST_F(ScreenSizeTest, MultiScreen) { - display::ScreenInfo screen_1; - display::ScreenInfo screen_2; - screen_1.rect = gfx::Rect(1920, 1080); - client_->AddScreenInfo(screen_1); - screen_2.rect = gfx::Rect(1440, 2560); - client_->AddScreenInfo(screen_2); - EXPECT_EQ(MediaStreamUtils::GetScreenSize(&GetFrame()), - gfx::Size(1920, 2560)); -} - -TEST_F(ScreenSizeTest, MultiScreenScaleFactor) { - display::ScreenInfo screen_1; - display::ScreenInfo screen_2; - screen_1.rect = gfx::Rect(1920, 1080); - screen_1.device_scale_factor = 2; - client_->AddScreenInfo(screen_1); - screen_2.rect = gfx::Rect(1440, 2560); - client_->AddScreenInfo(screen_2); - EXPECT_EQ(MediaStreamUtils::GetScreenSize(&GetFrame()), - gfx::Size(3840, 2560)); -} - -} // namespace -} // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc index b8733217..0e4dbba 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
@@ -19,6 +19,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pad_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_resample_2d_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_split_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_transpose_options.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/ml/buildflags.h" @@ -1893,6 +1894,124 @@ return output.value(); } +HeapVector<Member<const MLOperand>> MLGraphBuilder::split( + const MLOperand* input, + const uint32_t splits, + const MLSplitOptions* options, + ExceptionState& exception_state) { + const auto& input_shape = input->Dimensions(); + const auto input_rank = input_shape.size(); + const auto axis = options->axis(); + // According to WebNN spec: + // https://www.w3.org/TR/webnn/#dom-mlsplitoptions-axis, the axis must be in + // the range [0, N-1] where N is the rank of input tensor. + // + // TODO(crbug.com/1273291): Consider adding helpers for ValidateAxis and + // ValidateAxes functions to optimize the code. + if (axis > input_rank - 1) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "The axis must be in the range [0, N-1] " + "where N is the rank of input tensor."); + return {}; + } + if (splits == 0) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "The splits must be greater than 0."); + return {}; + } + if (input_shape[axis] % splits != 0) { + // According to WebNN spec: + // https://www.w3.org/TR/webnn/#dom-mlgraphbuilder-split-input-splits-options-splits, + // the splits specifies the number of output tensors along the axis. The + // number must evenly divide the dimension size of input along options.axis. + exception_state.ThrowDOMException( + DOMExceptionCode::kDataError, + "The splits must evenly divide the dimension size of input along " + "options.axis."); + return {}; + } + + auto output_shape = input_shape; + output_shape[axis] = input_shape[axis] / splits; + auto* split = MakeGarbageCollected<MLSplitOperator>(this, splits, options); + HeapVector<Member<const MLOperand>> outputs; + for (uint32_t i = 0; i < splits; ++i) { + auto output = MLOperand::ValidateAndCreateOutput(this, input->Type(), + output_shape, split); + if (!output.has_value()) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + output.error()); + return {}; + } + outputs.push_back(output.value()); + } + split->Connect({input}, outputs); + return outputs; +} + +// There are some backends don't support "split into sizes" variant, e.g. +// XNNPACK, and there is an ongoing discussion in WG: +// https://github.com/webmachinelearning/webnn/issues/392 +HeapVector<Member<const MLOperand>> MLGraphBuilder::split( + const MLOperand* input, + const Vector<uint32_t>& splits, + const MLSplitOptions* options, + ExceptionState& exception_state) { + const auto& input_shape = input->Dimensions(); + const auto input_rank = input_shape.size(); + const auto axis = options->axis(); + // According to WebNN spec: + // https://www.w3.org/TR/webnn/#dom-mlsplitoptions-axis, the axis must be in + // the range [0, N-1] where N is the rank of input tensor. + // + // TODO(crbug.com/1273291): Consider adding helpers for ValidateAxis and + // ValidateAxes functions to optimize the code. + if (axis > input_rank - 1) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "The axis must be in the range [0, N-1] " + "where N is the rank of input tensor."); + return {}; + } + auto checked_splits_sum = base::MakeCheckedNum<uint32_t>(0); + for (auto split_size : splits) { + checked_splits_sum += split_size; + } + if (!checked_splits_sum.IsValid()) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "The values of splits are too large."); + return {}; + } + if (checked_splits_sum.ValueOrDie() != input_shape[axis]) { + // According to WebNN spec: + // https://www.w3.org/TR/webnn/#dom-mlgraphbuilder-split-input-splits-options-splits, + // the splits parameter specifies the sizes of each output tensor along the + // options.axis. The sum of sizes must equal to the dimension size of input + // along options.axis. + exception_state.ThrowDOMException( + DOMExceptionCode::kDataError, + "The sum of split sizes must equal to the dimension size of input " + "along options.axis."); + return {}; + } + + auto* split = MakeGarbageCollected<MLSplitOperator>(this, splits, options); + HeapVector<Member<const MLOperand>> outputs; + for (auto split_size : splits) { + auto output_shape = input_shape; + output_shape[axis] = split_size; + auto output = MLOperand::ValidateAndCreateOutput(this, input->Type(), + output_shape, split); + if (!output.has_value()) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + output.error()); + return {}; + } + outputs.push_back(output.value()); + } + split->Connect({input}, outputs); + return outputs; +} + MLOperand* MLGraphBuilder::transpose(const MLOperand* input, const MLTransposeOptions* options, ExceptionState& exception_state) {
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h index 092d454ee..8246cf6 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h
@@ -33,6 +33,7 @@ class MLPadOptions; class MLPool2dOptions; class MLResample2dOptions; +class MLSplitOptions; class MLTransposeOptions; class MLOperand; class MLOperandDescriptor; @@ -222,6 +223,15 @@ MLOperand* softmax(const MLOperand* input, ExceptionState& exception_state); + HeapVector<Member<const MLOperand>> split(const MLOperand* input, + const uint32_t splits, + const MLSplitOptions* options, + ExceptionState& exception_state); + HeapVector<Member<const MLOperand>> split(const MLOperand* input, + const Vector<uint32_t>& splits, + const MLSplitOptions* options, + ExceptionState& exception_state); + MLOperand* transpose(const MLOperand* input, const MLTransposeOptions* options, ExceptionState& exception_state);
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl index 65d4393..eae4423 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.idl
@@ -98,10 +98,14 @@ sequence<[EnforceRange] unsigned long> axes; }; -dictionary MLTransposeOptions{ +dictionary MLTransposeOptions { sequence<[EnforceRange] unsigned long> permutation; }; +dictionary MLSplitOptions { + [EnforceRange] unsigned long axis = 0; +}; + [ RuntimeEnabled=MachineLearningNeuralNetwork, Exposed=(Window, DedicatedWorker) @@ -170,6 +174,8 @@ [RaisesException] MLOperand softmax(MLOperand input); + [RaisesException] sequence<MLOperand> split(MLOperand input, [EnforceRange] sequence<unsigned long> splits, optional MLSplitOptions options = {}); + [ CallWith=ScriptState, RaisesException,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc index eefa65c..67f7dbd 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.cc
@@ -3963,6 +3963,145 @@ } } +TEST_F(MLGraphBuilderTest, Split) { + V8TestingScope scope; + MLGraphBuilder* builder = CreateMLGraphBuilder(scope.GetExecutionContext()); + { + // Test building split with default option. + auto* input = + BuildInput(builder, "input", {2, 6}, V8MLOperandType::Enum::kFloat32, + scope.GetExceptionState()); + const uint32_t splits = 2; + auto* options = MLSplitOptions::Create(); + auto outputs = + builder->split(input, splits, options, scope.GetExceptionState()); + EXPECT_EQ(outputs.size(), splits); + for (auto output : outputs) { + EXPECT_NE(output, nullptr); + EXPECT_EQ(output->Kind(), MLOperand::OperandKind::kOutput); + EXPECT_EQ(output->Type(), V8MLOperandType::Enum::kFloat32); + EXPECT_EQ(output->Dimensions(), Vector<uint32_t>({1, 6})); + } + auto* split = static_cast<const MLSplitOperator*>(outputs[0]->Operator()); + EXPECT_NE(split, nullptr); + EXPECT_EQ(split->isEvenSplit(), true); + EXPECT_EQ(split->SplitNumber(), splits); + EXPECT_EQ(split->Kind(), MLOperator::OperatorKind::kSplit); + EXPECT_EQ(split->IsConnected(), true); + } + { + // Test building split with a sequence of unsigned long splits and with + // options.axis = 1. + auto* input = + BuildInput(builder, "input", {2, 6}, V8MLOperandType::Enum::kFloat32, + scope.GetExceptionState()); + const Vector<uint32_t> splits = {1, 2, 3}; + auto* options = MLSplitOptions::Create(); + options->setAxis(1); + auto outputs = + builder->split(input, splits, options, scope.GetExceptionState()); + EXPECT_EQ(outputs.size(), splits.size()); + for (uint32_t i = 0; i < outputs.size(); ++i) { + EXPECT_NE(outputs[i], nullptr); + EXPECT_EQ(outputs[i]->Kind(), MLOperand::OperandKind::kOutput); + EXPECT_EQ(outputs[i]->Type(), V8MLOperandType::Enum::kFloat32); + EXPECT_EQ(outputs[i]->Dimensions(), Vector<uint32_t>({2, splits[i]})); + } + auto* split = static_cast<const MLSplitOperator*>(outputs[0]->Operator()); + EXPECT_NE(split, nullptr); + EXPECT_EQ(split->isEvenSplit(), false); + EXPECT_EQ(split->SplitSizes(), splits); + EXPECT_EQ(split->Kind(), MLOperator::OperatorKind::kSplit); + EXPECT_EQ(split->IsConnected(), true); + } + { + // Test throwing exception when axis is larger than input rank. + auto* input = + BuildInput(builder, "input", {2, 6}, V8MLOperandType::Enum::kFloat32, + scope.GetExceptionState()); + const uint32_t splits = 2; + auto* options = MLSplitOptions::Create(); + options->setAxis(2); + auto outputs = + builder->split(input, splits, options, scope.GetExceptionState()); + EXPECT_EQ(outputs.size(), 0u); + EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(), + DOMExceptionCode::kDataError); + EXPECT_EQ(scope.GetExceptionState().Message(), + "The axis must be in the range [0, N-1] where N is the rank of " + "input tensor."); + } + { + // Test throwing exception when axis is larger than input rank when splits + // parameter is a sequence of unsigned long. + auto* input = + BuildInput(builder, "input", {2, 6}, V8MLOperandType::Enum::kFloat32, + scope.GetExceptionState()); + const Vector<uint32_t> splits = {1, 2, 3}; + auto* options = MLSplitOptions::Create(); + options->setAxis(2); + auto outputs = + builder->split(input, splits, options, scope.GetExceptionState()); + EXPECT_EQ(outputs.size(), 0u); + EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(), + DOMExceptionCode::kDataError); + EXPECT_EQ(scope.GetExceptionState().Message(), + "The axis must be in the range [0, N-1] where N is the rank of " + "input tensor."); + } + { + // Test throwing exception when splits is equal to 0. + auto* input = + BuildInput(builder, "input", {2, 6}, V8MLOperandType::Enum::kFloat32, + scope.GetExceptionState()); + const uint32_t splits = 0; + auto* options = MLSplitOptions::Create(); + auto outputs = + builder->split(input, splits, options, scope.GetExceptionState()); + EXPECT_EQ(outputs.size(), 0u); + EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(), + DOMExceptionCode::kDataError); + EXPECT_EQ(scope.GetExceptionState().Message(), + "The splits must be greater than 0."); + } + { + // Test throwing exception when the splits (unsigned long) can not evenly + // divide the dimension size of input along options.axis. + auto* input = + BuildInput(builder, "input", {2, 5}, V8MLOperandType::Enum::kFloat32, + scope.GetExceptionState()); + const uint32_t splits = 2; + auto* options = MLSplitOptions::Create(); + options->setAxis(1); + auto outputs = + builder->split(input, splits, options, scope.GetExceptionState()); + EXPECT_EQ(outputs.size(), 0u); + EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(), + DOMExceptionCode::kDataError); + EXPECT_EQ(scope.GetExceptionState().Message(), + "The splits must evenly divide the dimension size of input along " + "options.axis."); + } + { + // Test throwing exception when the sum of splits (sequence of unsigned + // long) sizes not equal to the dimension size of input along options.axis. + auto* input = + BuildInput(builder, "input", {2, 6}, V8MLOperandType::Enum::kFloat32, + scope.GetExceptionState()); + const Vector<uint32_t> splits = {2, 2, 3}; + auto* options = MLSplitOptions::Create(); + options->setAxis(1); + auto outputs = + builder->split(input, splits, options, scope.GetExceptionState()); + EXPECT_EQ(outputs.size(), 0u); + EXPECT_EQ(scope.GetExceptionState().CodeAs<DOMExceptionCode>(), + DOMExceptionCode::kDataError); + EXPECT_EQ(scope.GetExceptionState().Message(), + "The sum of split sizes must equal to the dimension size of " + "input along options.axis."); + } +} + class FakeMLGraphBackend final : public MLGraph { public: // Create and build a FakeMLGraphBackend object. Resolve the promise with
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h index 938c201..6a2f117a 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder_test.h
@@ -16,6 +16,7 @@ #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pad_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_pool_2d_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_resample_2d_options.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_ml_split_options.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_transpose_options.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h"
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc index a23308e..a2256e06 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.cc
@@ -4,6 +4,8 @@ #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h" +#include "base/numerics/checked_math.h" +#include "base/types/expected.h" #include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_ml_compute_result.h" #include "third_party/blink/renderer/core/dom/dom_exception.h" @@ -19,6 +21,32 @@ flatbuffers::DetachedBuffer* g_flatbuffer_for_testing = nullptr; +using ml::model_loader::mojom::blink::ComputeResult; + +base::expected<bool, String> ValidateModelLoadedTensorInfo( + const HashMap<String, ml::model_loader::mojom::blink::TensorInfoPtr>& + model_tensor_info, + const HashMap<String, MLGraph::ResourceInfo>& graph_resources_info) { + if (model_tensor_info.size() != graph_resources_info.size()) { + return base::unexpected( + "The number of model loaded tensor info doesn't match graph's " + "expectation."); + } + for (const auto& [name, mojo_tensor] : model_tensor_info) { + if (!graph_resources_info.Contains(name)) { + return base::unexpected(String::Format( + "The name \"%s\" isn't part of the graph.", name.Utf8().c_str())); + } + if (mojo_tensor->byte_size != graph_resources_info.at(name).byte_length) { + return base::unexpected(String::Format( + "The byte length of the model loaded tensor info with name \"%s\" " + "doesn't match graph's expectation.", + name.Utf8().c_str())); + } + } + return true; +} + } // namespace // static @@ -72,30 +100,32 @@ DOMExceptionCode::kUnknownError, "Unknown error.")); return; } + // Verifies the inputs from model are expected for the WebNN graph. + auto valid_inputs = ValidateModelLoadedTensorInfo( + tensor_info->input_tensor_info, input_resources_info_); + if (!valid_inputs.has_value()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kDataError, + "Invalid inputs: " + valid_inputs.error())); + return; + } + // Verifies the outputs from model are expected for the WebNN graph. + auto valid_outputs = ValidateModelLoadedTensorInfo( + tensor_info->output_tensor_info, output_resources_info_); + if (!valid_outputs.has_value()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kDataError, + "Invalid outputs: " + valid_outputs.error())); + return; + } + remote_model_.Bind( std::move(pending_remote), execution_context->GetTaskRunner(TaskType::kInternalDefault)); - // Stores input tensor information of loaded model to verify the input - // data by user including name and byte length. - input_tensor_name_to_info_ = std::move(tensor_info->input_tensor_info); - // Stores output tensor information of loaded model to verify the output - // data returned from `MLService` after computing. - output_tensor_name_to_info_ = std::move(tensor_info->output_tensor_info); - resolver->Resolve(this); } -const HashMap<String, ml::model_loader::mojom::blink::TensorInfoPtr>& -MLGraphCrOS::GetInputTensorInfoMapForTesting() const { - return input_tensor_name_to_info_; -} - -const HashMap<String, ml::model_loader::mojom::blink::TensorInfoPtr>& -MLGraphCrOS::GetOutputTensorInfoMapForTesting() const { - return output_tensor_name_to_info_; -} - // static void MLGraphCrOS::SetFlatbufferForTesting( flatbuffers::DetachedBuffer* flatbuffer) { @@ -115,9 +145,80 @@ const MLNamedArrayBufferViews& outputs, ScriptPromiseResolver* resolver, ExceptionState& exception_state) { - // TODO(crbug.com/1273291): Support async compute. - resolver->Reject(MakeGarbageCollected<DOMException>( - DOMExceptionCode::kNotSupportedError, "Not implemented.")); + // Transfer the `MLNamedArrayBufferViews` to `NamedArrayBufferViewsInfo` which + // is safe to compute asynchronously. + auto inputs_info = TransferNamedArrayBufferViews( + resolver->GetScriptState()->GetIsolate(), inputs, exception_state); + if (!inputs_info) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kDataError, + "Invalid inputs: " + exception_state.Message())); + return; + } + auto outputs_info = TransferNamedArrayBufferViews( + resolver->GetScriptState()->GetIsolate(), outputs, exception_state); + if (!outputs_info) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kDataError, + "Invalid outputs: " + exception_state.Message())); + return; + } + // The inputs were already verified in the base class. so we can fill the + // buffer directly with the input tensors. + HashMap<String, Vector<uint8_t>> input_mojo; + for (const auto& [name, input_info] : *inputs_info) { + wtf_size_t input_byte_length = + base::checked_cast<wtf_size_t>(input_info.contents.DataLength()); + Vector<uint8_t> tensor(input_byte_length); + memcpy(tensor.data(), input_info.contents.Data(), input_byte_length); + + input_mojo.insert(name, std::move(tensor)); + } + remote_model_->Compute( + std::move(input_mojo), + WTF::BindOnce(&MLGraphCrOS::OnComputeGraph, WrapPersistent(this), + WrapPersistent(resolver), std::move(inputs_info), + std::move(outputs_info))); +} + +void MLGraphCrOS::OnComputeGraph( + ScriptPromiseResolver* resolver, + std::unique_ptr<Vector<std::pair<String, ArrayBufferViewInfo>>> inputs_info, + std::unique_ptr<Vector<std::pair<String, ArrayBufferViewInfo>>> + outputs_info, + ComputeResult mojo_result, + const absl::optional<HashMap<String, Vector<uint8_t>>>& mojo_outputs) { + if (mojo_result != ComputeResult::kOk || !mojo_outputs.has_value()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kOperationError, + "Failed to obtain the computation result.")); + return; + } + + for (const auto& [name, view_info] : *outputs_info) { + // The verification before computing ensures the `ml_outputs` match graph's + // expectation, so we only need to verify the `mojo_outputs` here. + auto output_tensor_data = mojo_outputs.value().find(name); + if (output_tensor_data == mojo_outputs.value().end()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kOperationError, + "Failed to get result for the output " + name)); + return; + } + if (output_tensor_data->value.size() != view_info.contents.DataLength()) { + resolver->Reject(MakeGarbageCollected<DOMException>( + DOMExceptionCode::kUnknownError, + "The output tensor size does not match graph's expectation: " + + name)); + return; + } + memcpy(view_info.contents.Data(), output_tensor_data->value.data(), + output_tensor_data->value.size()); + } + auto* result = MLComputeResult::Create(); + result->setInputs(*CreateNamedArrayBufferViews(std::move(inputs_info))); + result->setOutputs(*CreateNamedArrayBufferViews(std::move(outputs_info))); + resolver->Resolve(result); } void MLGraphCrOS::ComputeSyncImpl(const MLNamedArrayBufferViews& inputs,
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h index 1db67e2..5c0d463 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_cros.h
@@ -7,6 +7,7 @@ #include "components/ml/mojom/web_platform_model.mojom-blink.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h" +#include "third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_operand.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -35,11 +36,6 @@ void Trace(Visitor* visitor) const override; - const HashMap<String, ml::model_loader::mojom::blink::TensorInfoPtr>& - GetInputTensorInfoMapForTesting() const; - const HashMap<String, ml::model_loader::mojom::blink::TensorInfoPtr>& - GetOutputTensorInfoMapForTesting() const; - // The caller of this function is responsible to keep flatbuffer alive and // unset it when it's no longer used. static void SetFlatbufferForTesting(flatbuffers::DetachedBuffer* flatbuffer); @@ -69,6 +65,18 @@ const MLNamedArrayBufferViews& outputs, ScriptPromiseResolver* resolver, ExceptionState& exception_state) override; + // Resolve the promise with an MLComputeResult that contains input and output + // ArrayBufferViews. The `inputs_info` and `outputs_info` carry the backing + // memory in `ArrayBufferContents` transferred from the original user supplied + // `ArrayBufferView`s. + void OnComputeGraph( + ScriptPromiseResolver* resolver, + std::unique_ptr<Vector<std::pair<String, ArrayBufferViewInfo>>> + inputs_info, + std::unique_ptr<Vector<std::pair<String, ArrayBufferViewInfo>>> + outputs_info, + ml::model_loader::mojom::blink::ComputeResult mojo_result, + const absl::optional<HashMap<String, Vector<uint8_t>>>& mojo_outputs); // Compute the converted model with synchronous call of `Model` interface. void ComputeSyncImpl(const MLNamedArrayBufferViews& inputs, @@ -76,10 +84,6 @@ ExceptionState& exception_state) override; HeapMojoRemote<ml::model_loader::mojom::blink::Model> remote_model_; - HashMap<String, ml::model_loader::mojom::blink::TensorInfoPtr> - input_tensor_name_to_info_; - HashMap<String, ml::model_loader::mojom::blink::TensorInfoPtr> - output_tensor_name_to_info_; }; } // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc index 0b5646d..8d7f0cf5 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test_cros.cc
@@ -104,6 +104,28 @@ return kTfLiteOk; } + TfLiteStatus Compute( + const WTF::HashMap<WTF::String, WTF::Vector<uint8_t>>& named_input, + WTF::HashMap<WTF::String, WTF::Vector<uint8_t>>& named_output) { + for (auto index : interpreter_->inputs()) { + auto* tensor = interpreter_->tensor(index); + Vector<uint8_t> input_data = named_input.at(WTF::String(tensor->name)); + memcpy(tensor->data.raw, input_data.data(), tensor->bytes); + } + + // Compute the graph. + EXPECT_EQ(interpreter_->Invoke(), kTfLiteOk); + + for (auto index : interpreter_->outputs()) { + auto* tensor = interpreter_->tensor(index); + WTF::Vector<uint8_t> output_data( + base::checked_cast<wtf_size_t>(tensor->bytes)); + memcpy(output_data.data(), tensor->data.raw, tensor->bytes); + named_output.insert(WTF::String(tensor->name), std::move(output_data)); + } + return kTfLiteOk; + } + private: std::unique_ptr<tflite::Interpreter> interpreter_; }; @@ -127,6 +149,9 @@ blink_mojom::ModelInfoPtr info = blink_mojom::ModelInfo::New(); EXPECT_EQ(runtime_->Load(buffer, info), kTfLiteOk); + // Hold the flatbuffer for computing with tflite runtime. + buffer_ = std::move(buffer); + receiver_.reset(); std::move(callback).Run(blink_mojom::LoadModelResult::kOk, receiver_.BindNewPipeAndPassRemote(), @@ -136,11 +161,15 @@ // Override methods from blink_mojom::Model. void Compute(const WTF::HashMap<WTF::String, WTF::Vector<uint8_t>>& input, blink_mojom::Model::ComputeCallback callback) override { - NOTIMPLEMENTED(); + WTF::HashMap<WTF::String, WTF::Vector<uint8_t>> named_output; + EXPECT_EQ(runtime_->Compute(input, named_output), kTfLiteOk); + std::move(callback).Run(blink_mojom::ComputeResult::kOk, named_output); } mojo::Receiver<blink_mojom::Model> receiver_{this}; std::unique_ptr<TfLiteRuntime> runtime_; + // The buffer of tflite model must be alive for computing. + mojo_base::BigBuffer buffer_; }; class MLGraphTestCrOS : public MLGraphTestBase { @@ -191,18 +220,23 @@ helper.BuildGraph(scope, builder, {{"output", output}}); EXPECT_NE(graph, nullptr); MLGraphCrOS* cros_graph = static_cast<MLGraphCrOS*>(graph.Get()); - const auto& input_tensor_info = - cros_graph->GetInputTensorInfoMapForTesting(); + const auto& input_tensor_info = cros_graph->GetInputResourcesInfo(); EXPECT_EQ(input_tensor_info.size(), 1u); EXPECT_EQ(input_tensor_info.Contains("input"), true); - EXPECT_EQ(input_tensor_info.find("input")->value->dimensions, - lhs.dimensions); - const auto& output_tensor_info = - cros_graph->GetOutputTensorInfoMapForTesting(); + const auto& output_tensor_info = cros_graph->GetOutputResourcesInfo(); EXPECT_EQ(output_tensor_info.size(), 1u); EXPECT_EQ(output_tensor_info.Contains("output"), true); - EXPECT_EQ(output_tensor_info.find("output")->value->dimensions, - expected.dimensions); + + // Compute the graph. + MLNamedArrayBufferViews inputs( + {{"input", CreateArrayBufferViewForOperand(input, lhs.values)}}); + MLNamedArrayBufferViews outputs( + {{"output", CreateArrayBufferViewForOperand(output)}}); + auto* compute_exception = + helper.ComputeGraph(scope, graph, inputs, outputs); + EXPECT_EQ(compute_exception, nullptr); + auto results = GetArrayBufferViewValues<T>(outputs[0].second); + EXPECT_EQ(results, expected.values); } private: @@ -296,7 +330,8 @@ .dimensions = {2}, .values = {3.0, 4.0}}, .expected = {.type = V8MLOperandType::Enum::kFloat32, - .dimensions = {2}}} + .dimensions = {2}, + .values = {4.0, 6.0}}} .Test(*this, scope); } { @@ -310,7 +345,8 @@ .dimensions = {2}, .values = {5.0, 6.0}}, .expected = {.type = V8MLOperandType::Enum::kFloat32, - .dimensions = {2, 2}}} + .dimensions = {2, 2}, + .values = {6.0, 8.0, 8.0, 10.0}}} .Test(*this, scope); } }
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc index 750870a..fa2ae30 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_type_converter.cc
@@ -157,6 +157,7 @@ case MLOperator::OperatorKind::kFloor: case MLOperator::OperatorKind::kNeg: case MLOperator::OperatorKind::kSlice: + case MLOperator::OperatorKind::kSplit: NOTIMPLEMENTED(); return nullptr; }
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.cc index 4b18899a..37172ce9 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_typed_array.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_operand.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_operator.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_deque.h" @@ -11,6 +12,13 @@ namespace blink { +namespace { + +using NamedArrayBufferViewsInfo = + Vector<std::pair<String, ArrayBufferViewInfo>>; + +} // namespace + HeapVector<Member<const MLOperator>>* GetOperatorsInTopologicalOrder( const MLNamedOperands& named_outputs) { // A WebNN graph is represented by a directed acyclic graph (DAG) that has @@ -73,4 +81,112 @@ return toposorted_operators; } +absl::optional<ArrayBufferViewInfo> TransferArrayBufferView( + v8::Isolate* isolate, + NotShared<DOMArrayBufferView> source_view, + ExceptionState& exception_state) { + // A detached ArrayBufferView should be caught by + // `ValidateNamedArrayBufferViews()` called in `MLGraph::ComputeAsync()`. + CHECK(!source_view->IsDetached()); + + // Avoid transferring a non-detachable ArrayBuffer. + // `DOMArrayBuffer::Transfer()` would make a copy if the ArrayBuffer is not + // detachable. This behavior doesn't follow the algorithm to transfer an + // ArrayBuffer of WebIDL spec: + // https://webidl.spec.whatwg.org/#arraybuffer-transfer + if (!source_view->buffer()->IsDetachable(isolate)) { + exception_state.ThrowDOMException(DOMExceptionCode::kDataError, + "The ArrayBuffer is not detachable."); + return absl::nullopt; + } + + // Get the offset and length of the source view before transferring it. + ArrayBufferViewInfo view_info; + view_info.type = source_view->GetType(); + view_info.offset = source_view->byteOffset(); + view_info.length = source_view->byteLength() / source_view->TypeSize(); + + ArrayBufferContents contents; + // The following `DOMArrayBuffer::Transfer()` call would fail if the + // detach key of the ArrayBuffer is not `undefined`. + if (!source_view->buffer()->Transfer(isolate, view_info.contents, + exception_state)) { + return absl::nullopt; + } + + return view_info; +} + +DOMArrayBufferView* CreateArrayBufferView(ArrayBufferViewInfo view_info) { + auto* target_buffer = DOMArrayBuffer::Create(std::move(view_info.contents)); + + // Align with the ArrayBufferView types supported by WebNN MLOperandType: + // https://www.w3.org/TR/webnn/#appendices-mloperandtype-arraybufferview-compatibility + DOMArrayBufferView* target_view = nullptr; + switch (view_info.type) { + case DOMArrayBufferView::kTypeFloat32: + // Float32Array is used for MLOperandType::float32. + target_view = DOMFloat32Array::Create(target_buffer, view_info.offset, + view_info.length); + break; + case DOMArrayBufferView::kTypeUint16: + // Using Uint16Array for float16 is a workaround of WebNN spec issue: + // https://github.com/webmachinelearning/webnn/issues/127 + target_view = DOMUint16Array::Create(target_buffer, view_info.offset, + view_info.length); + break; + case DOMArrayBufferView::kTypeInt32: + // Int32Array is used for MLOperandType::int32. + target_view = DOMInt32Array::Create(target_buffer, view_info.offset, + view_info.length); + break; + case DOMArrayBufferView::kTypeUint32: + // Uint32Array is used for MLOperandType::uint32. + target_view = DOMUint32Array::Create(target_buffer, view_info.offset, + view_info.length); + break; + case DOMArrayBufferView::kTypeInt8: + // Int8Array is used for MLOperandType::int8. + target_view = DOMInt8Array::Create(target_buffer, view_info.offset, + view_info.length); + break; + case DOMArrayBufferView::kTypeUint8: + // Uint8Array is used for MLOperandType::uint8. + target_view = DOMUint8Array::Create(target_buffer, view_info.offset, + view_info.length); + break; + default: + // Other ArrayBufferView types should not pass the + // `ValidateNamedArrayBufferViews()` and reach here. + NOTREACHED_NORETURN(); + } + return target_view; +} + +std::unique_ptr<NamedArrayBufferViewsInfo> TransferNamedArrayBufferViews( + v8::Isolate* isolate, + const MLNamedArrayBufferViews& source_views, + ExceptionState& exception_state) { + auto views_info = std::make_unique<NamedArrayBufferViewsInfo>(); + for (const auto& [name, source_view] : source_views) { + auto view_info = + TransferArrayBufferView(isolate, source_view, exception_state); + if (!view_info) { + return nullptr; + } + views_info->push_back(std::make_pair(name, std::move(view_info.value()))); + } + return views_info; +} + +MLNamedArrayBufferViews* CreateNamedArrayBufferViews( + std::unique_ptr<NamedArrayBufferViewsInfo> views_info) { + auto* target_views = MakeGarbageCollected<MLNamedArrayBufferViews>(); + for (auto& [name, view_info] : *views_info) { + target_views->push_back( + std::make_pair(name, CreateArrayBufferView(std::move(view_info)))); + } + return target_views; +} + } // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h index 6b59014..de6f41a 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h
@@ -5,7 +5,14 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_UTILS_H_ #define THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_UTILS_H_ +#include <utility> +#include <vector> + +#include "third_party/blink/renderer/core/typed_arrays/array_buffer/array_buffer_contents.h" +#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer_view.h" +#include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -19,6 +26,53 @@ MODULES_EXPORT HeapVector<Member<const MLOperator>>* GetOperatorsInTopologicalOrder(const MLNamedOperands& named_outputs); +// Stores information about a transferred `ArrayBufferView`. This struct doesn't +// include Blink GC objects, and can be accessed by any threads. +// +// The information is used to recreate `ArrayBufferView` when computation +// completes. +struct ArrayBufferViewInfo { + ArrayBufferViewInfo() = default; + ~ArrayBufferViewInfo() = default; + + ArrayBufferViewInfo(ArrayBufferViewInfo&& other) = default; + ArrayBufferViewInfo& operator=(ArrayBufferViewInfo&& other) = default; + + ArrayBufferViewInfo(const ArrayBufferViewInfo&) = delete; + ArrayBufferViewInfo& operator=(const ArrayBufferViewInfo&) = delete; + + DOMArrayBufferView::ViewType type; + size_t offset; + size_t length; + ArrayBufferContents contents; +}; + +// `TransferNamedArrayBufferViews()` and `CreateNamedArrayBufferViews()` +// implement the MLNamedArrayBufferViews transfer algorithm of WebNN spec: +// https://www.w3.org/TR/webnn/#mlnamedarraybufferviews-transfer +// +// The `NamedArrayBufferViewsInfo` returned by `TransferNamedArrayBufferViews()` +// doesn't contain any GC objects, so it is safe to be posted to a background +// thread that invokes the XNNPACK Runtime. After that, +// `NamedArrayBufferViewsInfo` should be posted back to the calling thread and +// call `CreateNamedArrayBufferViews()` to create `MLNamedArrayBufferViews` from +// the info. +// +// If it fails to transfer an `ArrayBufferView` of the +// `MLNamedArrayBufferViews`, the current implementation leaves the +// already-transferred views detached, the failing one and remaining others +// unchanged. +// +// TODO(crbug.com/1273291): Revisit the error handling once the WebNN spec issue +// is resolved: https://github.com/webmachinelearning/webnn/issues/351 +std::unique_ptr<Vector<std::pair<String, ArrayBufferViewInfo>>> +TransferNamedArrayBufferViews(v8::Isolate* isolate, + const MLNamedArrayBufferViews& source_views, + ExceptionState& exception_state); + +MLNamedArrayBufferViews* CreateNamedArrayBufferViews( + std::unique_ptr<Vector<std::pair<String, ArrayBufferViewInfo>>> views_info); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_GRAPH_UTILS_H_
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc index 99e12be..f3af8f29 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.cc
@@ -318,153 +318,6 @@ std::unique_ptr<xnn_runtime, decltype(&xnn_delete_runtime)> xnn_runtime_; }; -// Stores information about a transferred `ArrayBufferView`. This struct doesn't -// include Blink GC objects, and can be accessed by any threads. -// -// The information is used to recreate `ArrayBufferView` when computation -// completes. -struct ArrayBufferViewInfo { - ArrayBufferViewInfo() = default; - ~ArrayBufferViewInfo() = default; - - ArrayBufferViewInfo(ArrayBufferViewInfo&& other) = default; - ArrayBufferViewInfo& operator=(ArrayBufferViewInfo&& other) = default; - - ArrayBufferViewInfo(const ArrayBufferViewInfo&) = delete; - ArrayBufferViewInfo& operator=(const ArrayBufferViewInfo&) = delete; - - DOMArrayBufferView::ViewType type; - size_t offset; - size_t length; - ArrayBufferContents contents; -}; - -absl::optional<ArrayBufferViewInfo> TransferArrayBufferView( - v8::Isolate* isolate, - NotShared<DOMArrayBufferView> source_view, - ExceptionState& exception_state) { - // A detached ArrayBufferView should be caught by - // `ValidateNamedArrayBufferViews()` called in `MLGraph::ComputeAsync()`. - CHECK(!source_view->IsDetached()); - - // Avoid transferring a non-detachable ArrayBuffer. - // `DOMArrayBuffer::Transfer()` would make a copy if the ArrayBuffer is not - // detachable. This behavior doesn't follow the algorithm to transfer an - // ArrayBuffer of WebIDL spec: - // https://webidl.spec.whatwg.org/#arraybuffer-transfer - if (!source_view->buffer()->IsDetachable(isolate)) { - exception_state.ThrowDOMException(DOMExceptionCode::kDataError, - "The ArrayBuffer is not detachable."); - return absl::nullopt; - } - - // Get the offset and length of the source view before transferring it. - ArrayBufferViewInfo view_info; - view_info.type = source_view->GetType(); - view_info.offset = source_view->byteOffset(); - view_info.length = source_view->byteLength() / source_view->TypeSize(); - - ArrayBufferContents contents; - // The following `DOMArrayBuffer::Transfer()` call would fail if the - // detach key of the ArrayBuffer is not `undefined`. - if (!source_view->buffer()->Transfer(isolate, view_info.contents, - exception_state)) { - return absl::nullopt; - } - - return view_info; -} - -DOMArrayBufferView* CreateArrayBufferView(ArrayBufferViewInfo view_info) { - auto* target_buffer = DOMArrayBuffer::Create(std::move(view_info.contents)); - - // Align with the ArrayBufferView types supported by WebNN MLOperandType: - // https://www.w3.org/TR/webnn/#appendices-mloperandtype-arraybufferview-compatibility - DOMArrayBufferView* target_view = nullptr; - switch (view_info.type) { - case DOMArrayBufferView::kTypeFloat32: - // Float32Array is used for MLOperandType::float32. - target_view = DOMFloat32Array::Create(target_buffer, view_info.offset, - view_info.length); - break; - case DOMArrayBufferView::kTypeUint16: - // Using Uint16Array for float16 is a workaround of WebNN spec issue: - // https://github.com/webmachinelearning/webnn/issues/127 - target_view = DOMUint16Array::Create(target_buffer, view_info.offset, - view_info.length); - break; - case DOMArrayBufferView::kTypeInt32: - // Int32Array is used for MLOperandType::int32. - target_view = DOMInt32Array::Create(target_buffer, view_info.offset, - view_info.length); - break; - case DOMArrayBufferView::kTypeUint32: - // Uint32Array is used for MLOperandType::uint32. - target_view = DOMUint32Array::Create(target_buffer, view_info.offset, - view_info.length); - break; - case DOMArrayBufferView::kTypeInt8: - // Int8Array is used for MLOperandType::int8. - target_view = DOMInt8Array::Create(target_buffer, view_info.offset, - view_info.length); - break; - case DOMArrayBufferView::kTypeUint8: - // Uint8Array is used for MLOperandType::uint8. - target_view = DOMUint8Array::Create(target_buffer, view_info.offset, - view_info.length); - break; - default: - // Other ArrayBufferView types should not pass the - // `ValidateNamedArrayBufferViews()` and reach here. - NOTREACHED_NORETURN(); - } - return target_view; -} - -// `TransferNamedArrayBufferViews()` and `CreateNamedArrayBufferViews()` -// implement the MLNamedArrayBufferViews transfer algorithm of WebNN spec: -// https://www.w3.org/TR/webnn/#mlnamedarraybufferviews-transfer -// -// The `NamedArrayBufferViewsInfo` returned by `TransferNamedArrayBufferViews()` -// doesn't contain any GC objects, so it is safe to be posted to a background -// thread that invokes the XNNPACK Runtime. After that, -// `NamedArrayBufferViewsInfo` should be posted back to the calling thread and -// call `CreateNamedArrayBufferViews()` to create `MLNamedArrayBufferViews` from -// the info. -// -// If it fails to transfer an `ArrayBufferView` of the -// `MLNamedArrayBufferViews`, the current implementation leaves the -// already-transferred views detached, the failing one and remaining others -// unchanged. -// -// TODO(crbug.com/1273291): Revisit the error handling once the WebNN spec issue -// is resolved: https://github.com/webmachinelearning/webnn/issues/351 -NamedArrayBufferViewsInfoPtr TransferNamedArrayBufferViews( - v8::Isolate* isolate, - const MLNamedArrayBufferViews& source_views, - ExceptionState& exception_state) { - auto views_info = std::make_unique<NamedArrayBufferViewsInfo>(); - for (const auto& [name, source_view] : source_views) { - auto view_info = - TransferArrayBufferView(isolate, source_view, exception_state); - if (!view_info) { - return nullptr; - } - views_info->push_back(std::make_pair(name, std::move(view_info.value()))); - } - return views_info; -} - -MLNamedArrayBufferViews* CreateNamedArrayBufferViews( - NamedArrayBufferViewsInfoPtr views_info) { - auto* target_views = MakeGarbageCollected<MLNamedArrayBufferViews>(); - for (auto& [name, view_info] : *views_info) { - target_views->push_back( - std::make_pair(name, CreateArrayBufferView(std::move(view_info)))); - } - return target_views; -} - xnn_datatype GetXnnDataType(V8MLOperandType::Enum operand_type) { switch (operand_type) { case V8MLOperandType::Enum::kFloat32:
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h index 17d10ab5..2b64037 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_xnnpack.h
@@ -7,6 +7,7 @@ #include "base/task/sequenced_task_runner.h" #include "third_party/blink/renderer/modules/ml/webnn/ml_graph.h" +#include "third_party/blink/renderer/modules/ml/webnn/ml_graph_utils.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_vector.h" #include "third_party/blink/renderer/platform/heap/cross_thread_handle.h" @@ -19,7 +20,6 @@ namespace { class SharedXnnpackContext; class XnnRuntimeWrapper; -struct ArrayBufferViewInfo; } // Map the MLGraph's input or output name to the XNNPACK external Value ID.
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc b/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc index 99d8b2f1..6be21e0c 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_operator.cc
@@ -68,6 +68,8 @@ return "slice"; case MLOperator::OperatorKind::kSoftmax: return "softmax"; + case MLOperator::OperatorKind::kSplit: + return "split"; case MLOperator::OperatorKind::kTranspose: return "transpose"; } @@ -151,4 +153,34 @@ const Vector<uint32_t>& MLSliceOperator::Sizes() const { return sizes_; } + +MLSplitOperator::MLSplitOperator(MLGraphBuilder* builder, + const uint32_t splits, + const bindings::DictionaryBase* options) + : MLOperator(builder, MLOperator::OperatorKind::kSplit, options), + is_even_split_(true), + split_number_(splits) {} + +MLSplitOperator::MLSplitOperator(MLGraphBuilder* builder, + const Vector<uint32_t>& splits, + const bindings::DictionaryBase* options) + : MLOperator(builder, MLOperator::OperatorKind::kSplit, options), + is_even_split_(false), + split_sizes_(splits) {} + +MLSplitOperator::~MLSplitOperator() = default; + +bool MLSplitOperator::isEvenSplit() const { + return is_even_split_; +} + +uint32_t MLSplitOperator::SplitNumber() const { + CHECK(is_even_split_); + return split_number_; +} + +const Vector<uint32_t>& MLSplitOperator::SplitSizes() const { + CHECK(!is_even_split_); + return split_sizes_; +} } // namespace blink
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h index b368755..9d7dc58f 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_operator.h +++ b/third_party/blink/renderer/modules/ml/webnn/ml_operator.h
@@ -49,6 +49,7 @@ kSigmoid, kSlice, kSoftmax, + kSplit, kTranspose }; @@ -144,6 +145,30 @@ Vector<uint32_t> starts_; Vector<uint32_t> sizes_; }; + +class MODULES_EXPORT MLSplitOperator : public MLOperator { + public: + MLSplitOperator(MLGraphBuilder* builder, + const uint32_t splits, + const bindings::DictionaryBase* options = nullptr); + MLSplitOperator(MLGraphBuilder* builder, + const Vector<uint32_t>& splits, + const bindings::DictionaryBase* options = nullptr); + + MLSplitOperator(const MLSplitOperator&) = delete; + MLSplitOperator& operator=(const MLSplitOperator&) = delete; + + ~MLSplitOperator(); + + bool isEvenSplit() const; + uint32_t SplitNumber() const; + const Vector<uint32_t>& SplitSizes() const; + + private: + bool is_even_split_; + uint32_t split_number_; + Vector<uint32_t> split_sizes_; +}; } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_MODULES_ML_WEBNN_ML_OPERATOR_H_
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc index 0770f162..795f25f0 100644 --- a/third_party/blink/renderer/platform/exported/platform.cc +++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -310,8 +310,6 @@ CrossVariantMojoRemote<mojom::ServiceWorkerContainerHostInterfaceBase> service_worker_container_host, const WebString& client_id, - mojom::blink::ServiceWorkerFetchHandlerBypassOption - fetch_handler_bypass_option, std::unique_ptr<network::PendingSharedURLLoaderFactory> fallback_factory, mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver, scoped_refptr<base::SequencedTaskRunner> task_runner) {}
diff --git a/third_party/blink/renderer/platform/graphics/cpu/loongarch64/webgl_image_conversion_lsx.h b/third_party/blink/renderer/platform/graphics/cpu/loongarch64/webgl_image_conversion_lsx.h index fcbabae..1ce9a9c 100644 --- a/third_party/blink/renderer/platform/graphics/cpu/loongarch64/webgl_image_conversion_lsx.h +++ b/third_party/blink/renderer/platform/graphics/cpu/loongarch64/webgl_image_conversion_lsx.h
@@ -7,7 +7,7 @@ #include "build/build_config.h" -#if defined(ARCH_CPU_LOONG_FAMILY) +#if defined(ARCH_CPU_LOONGARCH_FAMILY) #include <lsxintrin.h> namespace blink { @@ -225,6 +225,6 @@ } // namespace simd } // namespace blink -#endif // ARCH_CPU_LOONG_FAMILY +#endif // ARCH_CPU_LOONGARCH_FAMILY #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_GRAPHICS_CPU_LOONGARCH64_WEBGL_IMAGE_CONVERSION_LSX_H_
diff --git a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc index 94066c4..2397119 100644 --- a/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc +++ b/third_party/blink/renderer/platform/graphics/gpu/webgl_image_conversion.cc
@@ -903,7 +903,7 @@ simd::unpackOneRowOfBGRA8LittleToRGBA8MSA(source32, destination32, pixels_per_row); #endif -#if defined(ARCH_CPU_LOONG_FAMILY) +#if defined(ARCH_CPU_LOONGARCH_FAMILY) simd::UnpackOneRowOfBGRA8LittleToRGBA8(source32, destination32, pixels_per_row); #endif @@ -937,7 +937,7 @@ #if defined(HAVE_MIPS_MSA_INTRINSICS) simd::unpackOneRowOfRGBA5551ToRGBA8MSA(source, destination, pixels_per_row); #endif -#if defined(ARCH_CPU_LOONG_FAMILY) +#if defined(ARCH_CPU_LOONGARCH_FAMILY) simd::UnpackOneRowOfRGBA5551LittleToRGBA8(source, destination, pixels_per_row); #endif @@ -971,7 +971,7 @@ #if defined(HAVE_MIPS_MSA_INTRINSICS) simd::unpackOneRowOfRGBA4444ToRGBA8MSA(source, destination, pixels_per_row); #endif -#if defined(ARCH_CPU_LOONG_FAMILY) +#if defined(ARCH_CPU_LOONGARCH_FAMILY) simd::UnpackOneRowOfRGBA4444LittleToRGBA8(source, destination, pixels_per_row); #endif @@ -1289,7 +1289,7 @@ #if defined(HAVE_MIPS_MSA_INTRINSICS) simd::packOneRowOfRGBA8LittleToR8MSA(source, destination, pixels_per_row); #endif -#if defined(ARCH_CPU_LOONG_FAMILY) +#if defined(ARCH_CPU_LOONGARCH_FAMILY) simd::PackOneRowOfRGBA8LittleToR8(source, destination, pixels_per_row); #endif for (unsigned i = 0; i < pixels_per_row; ++i) { @@ -1394,7 +1394,7 @@ #if defined(HAVE_MIPS_MSA_INTRINSICS) simd::packOneRowOfRGBA8LittleToRA8MSA(source, destination, pixels_per_row); #endif -#if defined(ARCH_CPU_LOONG_FAMILY) +#if defined(ARCH_CPU_LOONGARCH_FAMILY) simd::PackOneRowOfRGBA8LittleToRA8(source, destination, pixels_per_row); #endif for (unsigned i = 0; i < pixels_per_row; ++i) { @@ -1590,7 +1590,7 @@ #if defined(HAVE_MIPS_MSA_INTRINSICS) simd::packOneRowOfRGBA8LittleToRGBA8MSA(source, destination, pixels_per_row); #endif -#if defined(ARCH_CPU_LOONG_FAMILY) +#if defined(ARCH_CPU_LOONGARCH_FAMILY) simd::PackOneRowOfRGBA8LittleToRGBA8(source, destination, pixels_per_row); #endif for (unsigned i = 0; i < pixels_per_row; ++i) {
diff --git a/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc b/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc index 9feca11..7e8f5adc 100644 --- a/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc +++ b/third_party/blink/renderer/platform/loader/fetch/url_loader/dedicated_or_shared_worker_fetch_context_impl.cc
@@ -50,7 +50,6 @@ scoped_refptr<base::SequencedTaskRunner> task_runner) { Platform::Current()->CreateServiceWorkerSubresourceLoaderFactory( std::move(service_worker_container_host), client_id, - mojom::blink::ServiceWorkerFetchHandlerBypassOption::kDefault, std::move(fallback_factory), std::move(receiver), std::move(task_runner)); }
diff --git a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc index 28caa21..8fdcc8e 100644 --- a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc +++ b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source.cc
@@ -9,8 +9,10 @@ #include "base/logging.h" #include "base/trace_event/trace_event.h" #include "base/types/optional_util.h" +#include "media/base/media_switches.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/blink/renderer/platform/webrtc/convert_to_webrtc_video_frame_buffer.h" +#include "third_party/blink/renderer/platform/webrtc/webrtc_video_utils.h" #include "third_party/webrtc/rtc_base/ref_counted_object.h" namespace { @@ -336,6 +338,9 @@ update_rect->x(), update_rect->y(), update_rect->width(), update_rect->height()}); } + if (base::FeatureList::IsEnabled(media::kWebRTCColorAccuracy)) { + frame_builder.set_color_space(GfxToWebRtcColorSpace(frame->ColorSpace())); + } OnFrame(frame_builder.build()); // Clear accumulated_update_rect_.
diff --git a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc index 120460a..2c9c60c 100644 --- a/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc +++ b/third_party/blink/renderer/platform/peerconnection/webrtc_video_track_source_test.cc
@@ -8,7 +8,9 @@ #include "base/strings/strcat.h" #include "base/task/single_thread_task_runner.h" #include "base/test/bind.h" +#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" +#include "media/base/media_switches.h" #include "media/base/video_frame.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -115,6 +117,16 @@ track_source_->OnFrameCaptured(frame, {}); } + void SendTestFrameWithColorSpace(const FrameParameters& frame_parameters, + const gfx::ColorSpace& color_space) { + scoped_refptr<media::VideoFrame> frame = CreateTestFrame( + frame_parameters.coded_size, frame_parameters.visible_rect, + frame_parameters.natural_size, frame_parameters.storage_type, + frame_parameters.pixel_format, base::TimeDelta()); + frame->set_color_space(color_space); + track_source_->OnFrameCaptured(frame, {}); + } + WebRtcVideoTrackSource::FrameAdaptationParams FrameAdaptation_KeepAsIs( const gfx::Size& natural_size) { return WebRtcVideoTrackSource::FrameAdaptationParams{ @@ -226,6 +238,57 @@ SendTestFrame(frame_parameters, base::TimeDelta()); } +TEST_P(WebRtcVideoTrackSourceTest, TestColorSpaceSettings) { + base::test::ScopedFeatureList scoped_feature_list; + scoped_feature_list.InitWithFeatures( + /* enabled_features*/ {media::kWebRTCColorAccuracy}, + /* disabled_features*/ {}); + FrameParameters frame_parameters = { + .coded_size = gfx::Size(640, 480), + .visible_rect = gfx::Rect(0, 60, 640, 360), + .natural_size = gfx::Size(640, 360), + .storage_type = std::get<0>(GetParam()), + .pixel_format = std::get<1>(GetParam())}; + + Sequence s; + + EXPECT_CALL(mock_sink_, OnFrame(_)) + .InSequence(s) + .WillOnce(Invoke([](const webrtc::VideoFrame& frame) { + ASSERT_TRUE(frame.color_space().has_value()); + EXPECT_EQ(frame.color_space().value().matrix(), + webrtc::ColorSpace::MatrixID::kSMPTE170M); + EXPECT_EQ(frame.color_space().value().transfer(), + webrtc::ColorSpace::TransferID::kBT709); + EXPECT_EQ(frame.color_space().value().primaries(), + webrtc::ColorSpace::PrimaryID::kBT709); + EXPECT_EQ(frame.color_space().value().range(), + webrtc::ColorSpace::RangeID::kLimited); + })); + EXPECT_CALL(mock_sink_, OnFrame(_)) + .InSequence(s) + .WillOnce(Invoke([](const webrtc::VideoFrame& frame) { + ASSERT_TRUE(frame.color_space().has_value()); + EXPECT_EQ(frame.color_space().value().matrix(), + webrtc::ColorSpace::MatrixID::kBT709); + EXPECT_EQ(frame.color_space().value().transfer(), + webrtc::ColorSpace::TransferID::kBT709); + EXPECT_EQ(frame.color_space().value().primaries(), + webrtc::ColorSpace::PrimaryID::kBT709); + EXPECT_EQ(frame.color_space().value().range(), + webrtc::ColorSpace::RangeID::kFull); + })); + + gfx::ColorSpace color_range_limited( + gfx::ColorSpace::PrimaryID::BT709, gfx::ColorSpace::TransferID::BT709, + gfx::ColorSpace::MatrixID::SMPTE170M, gfx::ColorSpace::RangeID::LIMITED); + SendTestFrameWithColorSpace(frame_parameters, color_range_limited); + gfx::ColorSpace color_range_full( + gfx::ColorSpace::PrimaryID::BT709, gfx::ColorSpace::TransferID::BT709, + gfx::ColorSpace::MatrixID::BT709, gfx::ColorSpace::RangeID::FULL); + SendTestFrameWithColorSpace(frame_parameters, color_range_full); +} + TEST_P(WebRtcVideoTrackSourceTest, SetsFeedback) { FrameParameters frame_parameters = { .coded_size = gfx::Size(640, 480),
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 2fbfba6..b092c5c0 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -240,12 +240,6 @@ base_feature: "none", }, { - name: "AccessibilityAriaTouchPassthrough", - status: "experimental", - base_feature: "none", - origin_trial_feature_name: "AccessibilityAriaTouchPassthrough", - }, - { name: "AccessibilityAriaVirtualContent", public: true, status: "experimental", @@ -345,11 +339,6 @@ base_feature: "none", }, { - name: "AriaTouchPassthrough", - status: "experimental", - base_feature: "none", - }, - { name: "AttributionReporting", origin_trial_feature_name: "PrivacySandboxAdsAPIs", origin_trial_allows_third_party: true, @@ -525,6 +514,10 @@ public: true, }, { + name: "ByobFetch", + status: "experimental", + }, + { name: "CacheStorageCodeCacheHint", origin_trial_feature_name: "CacheStorageCodeCacheHint", status: "experimental", @@ -1231,6 +1224,10 @@ depends_on: ["CSSTextWrap"], }, { + name: "CSSWordBoundaryDetection", + status: "test", + }, + { name: "CSSZoom", status: "stable", }, @@ -1490,11 +1487,6 @@ status: "experimental", }, { - // Non-standard API Event.path. Should be replaced by Event.composedPath. - name: "EventPath", - public: true, - }, - { name: "EventTimingInteractionCount", status: "experimental", base_feature: "none", @@ -2077,18 +2069,6 @@ status: "stable", }, { - name: "LayoutNewSubtreeRoot", - status: "stable", - }, - { - name: "LayoutNewSVGForeignObjectEntry", - status: "stable", - }, - { - name: "LayoutNewSVGTextEntry", - status: "stable", - }, - { name: "LayoutNewTextAreaScrollbar", status: "stable", },
diff --git a/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.cc b/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.cc index ab815db..c178895 100644 --- a/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.cc +++ b/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.cc
@@ -4,6 +4,7 @@ #include "third_party/blink/renderer/platform/webrtc/webrtc_video_utils.h" +#include "base/logging.h" #include "third_party/webrtc/api/video_codecs/h264_profile_level_id.h" #include "third_party/webrtc/api/video_codecs/video_codec.h" #include "third_party/webrtc/api/video_codecs/vp9_profile.h" @@ -241,4 +242,156 @@ return media::VideoColorSpace(primaries, transfer, matrix, range); } +webrtc::ColorSpace GfxToWebRtcColorSpace(const gfx::ColorSpace& color_space) { + webrtc::ColorSpace::PrimaryID primaries = + webrtc::ColorSpace::PrimaryID::kUnspecified; + switch (color_space.GetPrimaryID()) { + case gfx::ColorSpace::PrimaryID::BT709: + primaries = webrtc::ColorSpace::PrimaryID::kBT709; + break; + case gfx::ColorSpace::PrimaryID::BT470M: + primaries = webrtc::ColorSpace::PrimaryID::kBT470M; + break; + case gfx::ColorSpace::PrimaryID::BT470BG: + primaries = webrtc::ColorSpace::PrimaryID::kBT470BG; + break; + case gfx::ColorSpace::PrimaryID::SMPTE170M: + primaries = webrtc::ColorSpace::PrimaryID::kSMPTE170M; + break; + case gfx::ColorSpace::PrimaryID::SMPTE240M: + primaries = webrtc::ColorSpace::PrimaryID::kSMPTE240M; + break; + case gfx::ColorSpace::PrimaryID::FILM: + primaries = webrtc::ColorSpace::PrimaryID::kFILM; + break; + case gfx::ColorSpace::PrimaryID::BT2020: + primaries = webrtc::ColorSpace::PrimaryID::kBT2020; + break; + case gfx::ColorSpace::PrimaryID::SMPTEST428_1: + primaries = webrtc::ColorSpace::PrimaryID::kSMPTEST428; + break; + case gfx::ColorSpace::PrimaryID::SMPTEST431_2: + primaries = webrtc::ColorSpace::PrimaryID::kSMPTEST431; + break; + case gfx::ColorSpace::PrimaryID::P3: + primaries = webrtc::ColorSpace::PrimaryID::kSMPTEST432; + break; + default: + DVLOG(1) << "Unsupported color primaries."; + break; + } + + webrtc::ColorSpace::TransferID transfer = + webrtc::ColorSpace::TransferID::kUnspecified; + switch (color_space.GetTransferID()) { + case gfx::ColorSpace::TransferID::BT709: + transfer = webrtc::ColorSpace::TransferID::kBT709; + break; + case gfx::ColorSpace::TransferID::GAMMA22: + transfer = webrtc::ColorSpace::TransferID::kGAMMA22; + break; + case gfx::ColorSpace::TransferID::GAMMA28: + transfer = webrtc::ColorSpace::TransferID::kGAMMA28; + break; + case gfx::ColorSpace::TransferID::SMPTE170M: + transfer = webrtc::ColorSpace::TransferID::kSMPTE170M; + break; + case gfx::ColorSpace::TransferID::SMPTE240M: + transfer = webrtc::ColorSpace::TransferID::kSMPTE240M; + break; + case gfx::ColorSpace::TransferID::LINEAR: + transfer = webrtc::ColorSpace::TransferID::kLINEAR; + break; + case gfx::ColorSpace::TransferID::LOG: + transfer = webrtc::ColorSpace::TransferID::kLOG; + break; + case gfx::ColorSpace::TransferID::LOG_SQRT: + transfer = webrtc::ColorSpace::TransferID::kLOG_SQRT; + break; + case gfx::ColorSpace::TransferID::IEC61966_2_4: + transfer = webrtc::ColorSpace::TransferID::kIEC61966_2_4; + break; + case gfx::ColorSpace::TransferID::BT1361_ECG: + transfer = webrtc::ColorSpace::TransferID::kBT1361_ECG; + break; + case gfx::ColorSpace::TransferID::SRGB: + transfer = webrtc::ColorSpace::TransferID::kIEC61966_2_1; + break; + case gfx::ColorSpace::TransferID::BT2020_10: + transfer = webrtc::ColorSpace::TransferID::kBT2020_10; + break; + case gfx::ColorSpace::TransferID::BT2020_12: + transfer = webrtc::ColorSpace::TransferID::kBT2020_12; + break; + case gfx::ColorSpace::TransferID::PQ: + transfer = webrtc::ColorSpace::TransferID::kSMPTEST2084; + break; + case gfx::ColorSpace::TransferID::SMPTEST428_1: + transfer = webrtc::ColorSpace::TransferID::kSMPTEST428; + break; + case gfx::ColorSpace::TransferID::HLG: + transfer = webrtc::ColorSpace::TransferID::kARIB_STD_B67; + break; + default: + DVLOG(1) << "Unsupported transfer."; + break; + } + + webrtc::ColorSpace::MatrixID matrix = + webrtc::ColorSpace::MatrixID::kUnspecified; + switch (color_space.GetMatrixID()) { + case gfx::ColorSpace::MatrixID::RGB: + matrix = webrtc::ColorSpace::MatrixID::kRGB; + break; + case gfx::ColorSpace::MatrixID::BT709: + matrix = webrtc::ColorSpace::MatrixID::kBT709; + break; + case gfx::ColorSpace::MatrixID::FCC: + matrix = webrtc::ColorSpace::MatrixID::kFCC; + break; + case gfx::ColorSpace::MatrixID::BT470BG: + matrix = webrtc::ColorSpace::MatrixID::kBT470BG; + break; + case gfx::ColorSpace::MatrixID::SMPTE170M: + matrix = webrtc::ColorSpace::MatrixID::kSMPTE170M; + break; + case gfx::ColorSpace::MatrixID::SMPTE240M: + matrix = webrtc::ColorSpace::MatrixID::kSMPTE240M; + break; + case gfx::ColorSpace::MatrixID::YCOCG: + matrix = webrtc::ColorSpace::MatrixID::kYCOCG; + break; + case gfx::ColorSpace::MatrixID::BT2020_NCL: + matrix = webrtc::ColorSpace::MatrixID::kBT2020_NCL; + break; + case gfx::ColorSpace::MatrixID::BT2020_CL: + matrix = webrtc::ColorSpace::MatrixID::kBT2020_CL; + break; + case gfx::ColorSpace::MatrixID::YDZDX: + matrix = webrtc::ColorSpace::MatrixID::kSMPTE2085; + break; + default: + DVLOG(1) << "Unsupported color matrix."; + break; + } + + webrtc::ColorSpace::RangeID range = webrtc::ColorSpace::RangeID::kInvalid; + switch (color_space.GetRangeID()) { + case gfx::ColorSpace::RangeID::LIMITED: + range = webrtc::ColorSpace::RangeID::kLimited; + break; + case gfx::ColorSpace::RangeID::FULL: + range = webrtc::ColorSpace::RangeID::kFull; + break; + case gfx::ColorSpace::RangeID::DERIVED: + range = webrtc::ColorSpace::RangeID::kDerived; + break; + default: + DVLOG(1) << "Unsupported color range."; + break; + } + + return webrtc::ColorSpace(primaries, transfer, matrix, range); +} + } // namespace blink
diff --git a/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.h b/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.h index 96a1b1e..ada5615 100644 --- a/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.h +++ b/third_party/blink/renderer/platform/webrtc/webrtc_video_utils.h
@@ -32,6 +32,9 @@ media::VideoColorSpace PLATFORM_EXPORT WebRtcToMediaVideoColorSpace(const webrtc::ColorSpace& color_space); +webrtc::ColorSpace PLATFORM_EXPORT +GfxToWebRtcColorSpace(const gfx::ColorSpace& color_space); + } // namespace blink #endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WEBRTC_WEBRTC_VIDEO_UTILS_H_
diff --git a/third_party/blink/tools/blinkpy/common/checkout/baseline_copier.py b/third_party/blink/tools/blinkpy/common/checkout/baseline_copier.py index 0c1fef1..8f3dff2 100644 --- a/third_party/blink/tools/blinkpy/common/checkout/baseline_copier.py +++ b/third_party/blink/tools/blinkpy/common/checkout/baseline_copier.py
@@ -140,8 +140,16 @@ flag_specific = self._host.builders.flag_specific_option( build.builder_name, step_name) port = self._optimizer.port(port_name, flag_specific) - yield self._optimizer.location( + location = self._optimizer.location( self._fs.join(port.baseline_version_dir(), test)) + maybe_test_file_path = self._fs.join(port.web_tests_dir(), test) + # Coerce this location to a non-virtual one for physical tests under + # a virtual directory. See crbug.com/1450725. + if self._fs.exists(maybe_test_file_path): + location = BaselineLocation( + platform=location.platform, + flag_specific=location.flag_specific) + yield location def _resolve_sources( self,
diff --git a/third_party/blink/tools/blinkpy/common/checkout/baseline_copier_unittest.py b/third_party/blink/tools/blinkpy/common/checkout/baseline_copier_unittest.py index 564162e..6e9602a 100644 --- a/third_party/blink/tools/blinkpy/common/checkout/baseline_copier_unittest.py +++ b/third_party/blink/tools/blinkpy/common/checkout/baseline_copier_unittest.py
@@ -500,3 +500,23 @@ 'platform/test-win-win7/virtual/other_virtual/': 'virtual win10 result', }) + + def test_copy_for_physical_test_under_virtual_dir(self): + self._write_baselines( + 'physical1-expected.txt', { + 'platform/test-mac-mac10.11/virtual/virtual_empty_bases/': + 'virtual mac10.11 result', + }) + baseline_set = self._baseline_set([ + ('virtual/virtual_empty_bases/physical1.html', 'MOCK mac10.11-rel', + None), + ]) + self.copier.write_copies( + self.copier.find_baselines_to_copy( + 'virtual/virtual_empty_bases/physical1.html', 'txt', + baseline_set)) + self._assert_baselines( + 'physical1-expected.txt', { + 'platform/test-mac-mac10.10/virtual/virtual_empty_bases/': + 'virtual mac10.11 result', + })
diff --git a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py index 6bedd6e..0950d1d7 100644 --- a/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py +++ b/third_party/blink/tools/blinkpy/common/checkout/baseline_optimizer_unittest.py
@@ -26,6 +26,7 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +import json import optparse import unittest @@ -154,9 +155,25 @@ baseline_name = 'mock-test-expected.' + suffix self.fs.write_text_file( self.finder.path_from_web_tests('VirtualTestSuites'), - '[{"prefix": "gpu", "platforms": ["Linux", "Mac", "Win"], ' - '"bases": ["fast/canvas", "slow/canvas/mock-test.html"], ' - '"args": ["--foo"], "expires": "never"}]') + json.dumps([{ + 'prefix': + 'gpu', + 'platforms': ['Linux', 'Mac', 'Win'], + 'bases': [ + 'fast/canvas', + 'slow/canvas/mock-test.html', + 'virtual/virtual_empty_bases/', + ], + 'args': ['--foo'], + 'expires': + 'never', + }, { + 'prefix': 'virtual_empty_bases', + 'platforms': ['Linux', 'Mac', 'Win'], + 'bases': [], + 'args': ['--foo'], + 'expires': 'never', + }])) self.fs.write_text_file( self.finder.path_from_web_tests('FlagSpecificConfig'), '[{"name": "highdpi", "args": ["--force-device-scale-factor=1.5"]}]' @@ -643,6 +660,17 @@ }, baseline_dirname='virtual/gpu/slow/canvas') + def test_physical_under_dir_falls_back_to_virtual(self): + self._assert_optimization( + { + 'virtual/gpu/virtual/virtual_empty_bases/': '1', + 'virtual/virtual_empty_bases/': '1', + }, { + 'virtual/gpu/virtual/virtual_empty_bases/': None, + 'virtual/virtual_empty_bases/': '1', + }, + baseline_dirname='virtual/virtual_empty_bases/') + def test_empty_at_root(self): self._assert_optimization({'': ''}, {'': None})
diff --git a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py index 82c592d1..fd676845 100644 --- a/third_party/blink/tools/blinkpy/common/net/results_fetcher.py +++ b/third_party/blink/tools/blinkpy/common/net/results_fetcher.py
@@ -289,7 +289,7 @@ 'followEdges': { 'includedInvocations': True, }, - 'artifactIdRegexp': 'wpt_reports_(.*)\.json', + 'artifactIdRegexp': 'wpt_reports.json', }) artifacts.sort(key=lambda artifact: artifact['artifactId']) return [artifact['fetchUrl'] for artifact in artifacts]
diff --git a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py index 30530425..5c6af20f 100644 --- a/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py +++ b/third_party/blink/tools/blinkpy/w3c/wpt_results_processor.py
@@ -295,8 +295,7 @@ destination = self.fs.join(self.artifacts_dir, file) self.fs.copyfile(source, destination) if file == 'results.html': - _log.info('Copied results viewer (%s -> %s)', source, - destination) + _log.info(f'View the test results at file://{destination}') def process_results_json(self, raw_results_path,
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_analyzer.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/analyzer.py similarity index 98% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_analyzer.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/analyzer.py index 424afb2..f4b605f 100644 --- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_analyzer.py +++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/analyzer.py
@@ -6,7 +6,7 @@ import numpy as np from typing import List -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_data_types as dt +from blinkpy.web_tests.fuzzy_diff_analyzer import data_types as dt class ImageMatchingAnalyzer:
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_analyzer_unittest.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/analyzer_unittest.py similarity index 97% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_analyzer_unittest.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/analyzer_unittest.py index 576cfbc..c2af75cc 100644 --- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_analyzer_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/analyzer_unittest.py
@@ -4,8 +4,8 @@ import unittest -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_analyzer as analyzer -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_data_types as dt +from blinkpy.web_tests.fuzzy_diff_analyzer import analyzer +from blinkpy.web_tests.fuzzy_diff_analyzer import data_types as dt class FuzzyMatchingAnalyzerTest(unittest.TestCase):
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_data_types.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/data_types.py similarity index 100% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_data_types.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/data_types.py
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_data_types_unittest.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/data_types_unittest.py similarity index 96% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_data_types_unittest.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/data_types_unittest.py index 98d4f4d4d..ce2350b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_data_types_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/data_types_unittest.py
@@ -5,7 +5,7 @@ import typing import unittest -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_data_types as data_types +from blinkpy.web_tests.fuzzy_diff_analyzer import data_types class FuzzyDiffAnalyzerDataTypesUnittest(unittest.TestCase):
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_queries.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries.py similarity index 100% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_queries.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries.py
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_queries_unittest.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries_unittest.py similarity index 95% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_queries_unittest.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries_unittest.py index 429a261..e9e22e8 100644 --- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_queries_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/queries_unittest.py
@@ -6,7 +6,7 @@ import unittest import unittest.mock as mock -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_queries as queries +from blinkpy.web_tests.fuzzy_diff_analyzer import queries from flake_suppressor_common import unittest_utils as uu QUERY_DATA = [{
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_results.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/results.py similarity index 95% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_results.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/results.py index a70b9ea..a0e74d1 100644 --- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_results.py +++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/results.py
@@ -8,7 +8,7 @@ from flake_suppressor_common import common_typing as ct from flake_suppressor_common import tag_utils -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_data_types as dt +from blinkpy.web_tests.fuzzy_diff_analyzer import data_types as dt class ResultProcessor:
diff --git a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_results_unittest.py b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/results_unittest.py similarity index 92% rename from third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_results_unittest.py rename to third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/results_unittest.py index 28151c14..2f5f8fe 100644 --- a/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/fuzzy_diff_analyzer_results_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/fuzzy_diff_analyzer/results_unittest.py
@@ -4,8 +4,8 @@ import unittest -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_data_types as data_types -from blinkpy.web_tests.fuzzy_diff_analyzer import fuzzy_diff_analyzer_results as results_processor +from blinkpy.web_tests.fuzzy_diff_analyzer import data_types +from blinkpy.web_tests.fuzzy_diff_analyzer import results from flake_suppressor_common import tag_utils as common_tag_utils from flake_suppressor_common import unittest_utils as uu @@ -13,7 +13,7 @@ class BaseResultsUnittest(unittest.TestCase): def setUp(self) -> None: common_tag_utils.SetTagUtilsImplementation(uu.UnitTestTagUtils) - self._result_processor = results_processor.ResultProcessor() + self._result_processor = results.ResultProcessor() class AggregateResultsUnittest(BaseResultsUnittest):
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py index 2b38146..1c2d76e3 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations.py
@@ -34,7 +34,16 @@ from collections import defaultdict from collections import OrderedDict from functools import reduce -from typing import Collection, Dict, FrozenSet, List, Optional, Tuple +from typing import ( + ClassVar, + Collection, + Dict, + FrozenSet, + List, + Optional, + Set, + Tuple, +) from blinkpy.common.memoized import memoized from blinkpy.web_tests.models import typ_types @@ -501,6 +510,8 @@ class SystemConfigurationEditor: + ALL_SYSTEMS: ClassVar[str] = '' # Sentinel value to indicate no tag + def __init__(self, test_expectations: TestExpectations): self._test_expectations = test_expectations macros = self._test_expectations.port.configuration_specifier_macros() @@ -516,7 +527,7 @@ self._generic_exp_file_path = \ self._test_expectations.port.path_to_generic_test_expectations_file() fs = self._test_expectations.port.host.filesystem - self._tags_in_expectation = self._tags_in_expectation_file( + self._tags_in_file = self._tags_in_expectation_file( self._generic_exp_file_path, fs.read_text_file(self._generic_exp_file_path)) @@ -538,10 +549,10 @@ def _resolve_versions(self, tags: FrozenSet[str]) -> FrozenSet[str]: tag = self._system_tag(tags) - if tag: - return self._versions_by_os.get(tag, {tag}) - # A line without any OS/version specifiers applies to all versions. - return self._version_specifiers + if tag == self.ALL_SYSTEMS: + # A line without any OS/version specifiers applies to all versions. + return self._version_specifiers + return self._versions_by_os.get(tag, {tag}) def _system_tag(self, tags: FrozenSet[str]) -> str: maybe_version = tags & self._version_specifiers @@ -552,17 +563,34 @@ elif maybe_os: (os, ) = maybe_os return os - return '' + return self.ALL_SYSTEMS - def _simplify_versions(self, versions: FrozenSet[str]) -> FrozenSet[str]: - system_specifiers = set(versions) + def _simplify_versions(self, + versions: FrozenSet[str]) -> Dict[str, Set[str]]: + """Find a minimal set of system specifiers to write. + + Returns: + A map from new system specifiers to old ones in `versions`. System + specifiers may be at the OS or version level. Tags that could not + be simplified are mapped identically (e.g., Mac -> {Mac}). + """ + system_specifiers = defaultdict(set) for os, os_versions in self._versions_by_os.items(): # If all the versions of an OS are in the system specifiers set, then # replace all those specifiers with the OS specifier. - if os_versions <= system_specifiers: - system_specifiers -= os_versions - system_specifiers.add(os) - return frozenset(system_specifiers) + if os_versions <= versions: + system_specifiers[os].update(os_versions) + for version in versions - frozenset().union( + *system_specifiers.values()): + system_specifiers[version].add(version) + if set(system_specifiers) >= self._os_specifiers: + return {self.ALL_SYSTEMS: set(versions)} + # Skip tags not listed in TestExpectations + return { + new_tag: old_tags + for new_tag, old_tags in system_specifiers.items() + if new_tag in self._tags_in_file + } def update_versions(self, test_name: str, @@ -613,6 +641,59 @@ self._test_expectations.add_expectations( self._generic_exp_file_path, [new_exp], anchor_exp.lineno) + def merge_versions(self, test_name: str): + """Merge test expectations for systems with the same results.""" + expectations = self._test_expectations.get_expectations_from_file( + self._generic_exp_file_path, test_name) + exps_by_other_tags = defaultdict(list) + for exp in expectations: + other_tags = exp.tags - {self._system_tag(exp.tags)} + exps_by_other_tags[other_tags, exp.results].append(exp) + exps_to_remove = [] + # Try to collapse the group along the system tag dimension. + for (other_tags, _), exp_group in exps_by_other_tags.items(): + exps_by_system_tags = { + self._system_tag(exp.tags): exp + for exp in exp_group + } + system_tags = self._simplify_versions( + frozenset(exps_by_system_tags)) + for new_tag, old_tags in system_tags.items(): + exps_to_remove.extend(exps_by_system_tags[tag] + for tag in old_tags if tag != new_tag) + if new_tag not in old_tags: + new_tags = set(other_tags) + if new_tag != self.ALL_SYSTEMS: + new_tags.add(new_tag) + old_exps = [exps_by_system_tags[tag] for tag in old_tags] + new_exp = self._merge_expectations(old_exps, new_tags) + self._test_expectations.add_expectations( + self._generic_exp_file_path, [new_exp], new_exp.lineno) + self._test_expectations.remove_expectations( + self._generic_exp_file_path, exps_to_remove) + + def _merge_expectations(self, exps: List[typ_types.Expectation], + tags: FrozenSet[str]) -> typ_types.Expectation: + reasons = {exp.reason.strip() for exp in exps} + comments = set() + for exp in exps: + comment = exp.trailing_comments.strip() + if comment.startswith('#'): + comment = comment[1:].strip() + if comment: + comments.add(comment) + new_comment = ' # ' + ', '.join(sorted(comments)) if comments else '' + assert len({exp.test for exp in exps}) == 1 + assert len({exp.results for exp in exps}) == 1 + return typ_types.Expectation( + lineno=exps[0].lineno, + is_slow_test=any(exp.is_slow_test for exp in exps), + reason=' '.join(sorted(reason for reason in reasons if reason)), + trailing_comments=new_comment, + test=exps[0].test, + results=exps[0].results, + tags=tags) + def _find_marker(self, marker: Optional[str] = None) -> typ_types.Expectation: lines = self._test_expectations.get_updated_lines( @@ -651,17 +732,17 @@ other_specifiers = (exp.tags - self._os_specifiers - self._version_specifiers) systems = self._simplify_versions(versions) - # Skip tags not listed in TestExpectations - systems &= self._tags_in_expectation + tag_sets = [({system} if system != self.ALL_SYSTEMS else set()) + | other_specifiers for system in sorted(systems)] residual_exps = [ - typ_types.Expectation(tags=({system} | other_specifiers), + typ_types.Expectation(tags=tags, results=exp.results, is_slow_test=exp.is_slow_test, reason=exp.reason, test=exp.test, lineno=exp.lineno, trailing_comments=exp.trailing_comments) - for system in sorted(systems) + for tags in tag_sets ] self._test_expectations.remove_expectations( self._generic_exp_file_path, [exp])
diff --git a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py index 69f920e..f4ccb46e 100644 --- a/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py +++ b/third_party/blink/tools/blinkpy/web_tests/models/test_expectations_unittest.py
@@ -335,6 +335,7 @@ 'win': ['win7', 'win10'], 'linux': ['precise', 'trusty'] } + self.maxDiff = None def set_up_using_raw_expectations(self, content): self._general_exp_filename = self._port.host.filesystem.join( @@ -456,6 +457,138 @@ [ Mac10.11 ] failures/expected/text.html?\* [ Crash Failure ] """)) + def test_merge_versions_os(self): + raw_expectations = textwrap.dedent("""\ + # tags: [ Mac10.10 Mac10.11 Mac10.12 Mac10.13 Mac Win7 Win10 Win ] + # results: [ Failure Crash ] + # Below Expectation should be merged + crbug.com/123 [ Win7 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Mac10.10 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Mac10.11 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/456 [ Mac10.12 ] failures/expected/text.html?\* [ Failure ] # comment 2 + crbug.com/456 [ Mac10.13 ] failures/expected/text.html?\* [ Failure ] # comment 2 + """) + self.set_up_using_raw_expectations(raw_expectations) + self._system_config_remover.merge_versions( + 'failures/expected/text.html?*') + self._system_config_remover.update_expectations() + updated_exps = self._port.host.filesystem.read_text_file( + self._general_exp_filename) + self.assertEqual( + updated_exps, + textwrap.dedent("""\ + # tags: [ Mac10.10 Mac10.11 Mac10.12 Mac10.13 Mac Win7 Win10 Win ] + # results: [ Failure Crash ] + # Below Expectation should be merged + crbug.com/123 [ Win7 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 crbug.com/456 [ Mac ] failures/expected/text.html?\* [ Failure ] # comment, comment 2 + """)) + + def test_merge_versions_generic(self): + raw_expectations = textwrap.dedent("""\ + # tags: [ Mac10.10 Mac10.11 Mac10.12 Mac10.13 Mac Win7 Win10 Win Precise Trusty Linux ] + # results: [ Failure Crash ] + # Below Expectation should be merged + crbug.com/123 [ Win7 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Win10 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Mac ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Precise ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Trusty ] failures/expected/text.html?\* [ Failure ] # comment + """) + self.set_up_using_raw_expectations(raw_expectations) + self._system_config_remover.merge_versions( + 'failures/expected/text.html?*') + self._system_config_remover.update_expectations() + updated_exps = self._port.host.filesystem.read_text_file( + self._general_exp_filename) + self.assertEqual( + updated_exps, + textwrap.dedent("""\ + # tags: [ Mac10.10 Mac10.11 Mac10.12 Mac10.13 Mac Win7 Win10 Win Precise Trusty Linux ] + # results: [ Failure Crash ] + # Below Expectation should be merged + crbug.com/123 failures/expected/text.html?\* [ Failure ] # comment + """)) + + def test_merge_versions_with_other_specifiers(self): + raw_expectations = textwrap.dedent("""\ + # tags: [ Win7 Win10 Win ] + # tags: [ Debug Release ] + # results: [ Failure Crash ] + crbug.com/123 [ Debug Win7 ] failures/expected/text.html?\* [ Crash ] # DCHECK triggered + crbug.com/123 [ Debug Win10 ] failures/expected/text.html?\* [ Crash ] + """) + self.set_up_using_raw_expectations(raw_expectations) + self._system_config_remover.merge_versions( + 'failures/expected/text.html?*') + self._system_config_remover.update_expectations() + updated_exps = self._port.host.filesystem.read_text_file( + self._general_exp_filename) + self.assertEqual( + updated_exps, + textwrap.dedent("""\ + # tags: [ Win7 Win10 Win ] + # tags: [ Debug Release ] + # results: [ Failure Crash ] + crbug.com/123 [ Debug Win ] failures/expected/text.html?\* [ Crash ] # DCHECK triggered + """)) + + def test_merge_versions_skip_with_different_results(self): + raw_expectations = textwrap.dedent("""\ + # tags: [ Mac10.10 Mac10.11 Mac10.12 Mac10.13 Mac Win7 Win10 Win Precise Trusty Linux ] + # results: [ Failure Crash ] + # The Win and Linux expectations should be merged. + # The Mac results prevent merging to a generic expectation. + crbug.com/123 [ Win7 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Win10 ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Mac ] failures/expected/text.html?\* [ Crash Failure ] # comment + crbug.com/123 [ Precise ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Trusty ] failures/expected/text.html?\* [ Failure ] # comment + """) + self.set_up_using_raw_expectations(raw_expectations) + self._system_config_remover.merge_versions( + 'failures/expected/text.html?*') + self._system_config_remover.update_expectations() + updated_exps = self._port.host.filesystem.read_text_file( + self._general_exp_filename) + self.assertEqual( + updated_exps, + textwrap.dedent("""\ + # tags: [ Mac10.10 Mac10.11 Mac10.12 Mac10.13 Mac Win7 Win10 Win Precise Trusty Linux ] + # results: [ Failure Crash ] + # The Win and Linux expectations should be merged. + # The Mac results prevent merging to a generic expectation. + crbug.com/123 [ Win ] failures/expected/text.html?\* [ Failure ] # comment + crbug.com/123 [ Mac ] failures/expected/text.html?\* [ Crash Failure ] # comment + crbug.com/123 [ Linux ] failures/expected/text.html?\* [ Failure ] # comment + """)) + + def test_merge_versions_skip_with_disjoint_specifiers(self): + raw_expectations = textwrap.dedent("""\ + # tags: [ Win7 Win10 Win ] + # tags: [ Debug Release ] + # results: [ Failure Crash ] + # Debug and Release describe disjoint test configurations. + crbug.com/123 [ Debug Win7 ] failures/expected/text.html?\* [ Failure ] + crbug.com/123 [ Release Win10 ] failures/expected/text.html?\* [ Failure ] + """) + self.set_up_using_raw_expectations(raw_expectations) + self._system_config_remover.merge_versions( + 'failures/expected/text.html?*') + self._system_config_remover.update_expectations() + updated_exps = self._port.host.filesystem.read_text_file( + self._general_exp_filename) + self.assertEqual( + updated_exps, + textwrap.dedent("""\ + # tags: [ Win7 Win10 Win ] + # tags: [ Debug Release ] + # results: [ Failure Crash ] + # Debug and Release describe disjoint test configurations. + crbug.com/123 [ Debug Win7 ] failures/expected/text.html?\* [ Failure ] + crbug.com/123 [ Release Win10 ] failures/expected/text.html?\* [ Failure ] + """)) + def test_remove_mac_version_from_mac_expectation(self): raw_expectations = ( '# tags: [ Mac10.10 Mac10.11 Mac10.12 Mac ]\n'
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/factory.py b/third_party/blink/tools/blinkpy/web_tests/port/factory.py index 871dce79..e037372 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/factory.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/factory.py
@@ -30,6 +30,7 @@ import argparse import fnmatch import optparse +import os import re import sys from copy import deepcopy @@ -186,15 +187,14 @@ # TODO(crbug.com/1431070): Remove the `*_options` methods above once all tools # use `argparse`. - - def add_platform_options_group(parser: argparse.ArgumentParser): group = parser.add_argument_group('Platform Options') group.add_argument('--platform', help='Platform to use (e.g., "mac-lion")') - return group -def add_configuration_options_group(parser: argparse.ArgumentParser): +def add_configuration_options_group(parser: argparse.ArgumentParser, + rwt: bool = True, + product_choices: list = None): group = parser.add_argument_group('Configuration Options') group.add_argument( '-t', @@ -214,19 +214,491 @@ action='store_false', dest='use_xvfb', help='Do not run tests with Xvfb') - return group - - -def add_wpt_options_group(parser: argparse.ArgumentParser): - group = parser.add_argument_group('web-platform-tests (WPT) Options') group.add_argument('--no-manifest-update', dest='manifest_update', action='store_false', help=('Do not update the web-platform-tests ' 'MANIFEST.json unless it does not exist.')) + if not rwt: + group.add_argument( + '-p', + '--product', + default='content_shell', + choices=(product_choices or []), + metavar='PRODUCT', + help='Product (browser or browser component) to test.') + group.add_argument('--no-headless', + action='store_false', + dest='headless', + help='Do not run the browser in headless mode.') + group.add_argument('--webdriver-binary', + type=str, + help='Alternate path of the webdriver binary.') + group.add_argument( + '--use-upstream-wpt', + action='store_true', + help=('Use tests and tools from upstream WPT GitHub repo. ' + 'Used to create wpt reports for uploading to wpt.fyi.')) + + +def add_results_options_group(parser: argparse.ArgumentParser, + rwt: bool = True): + results_group = parser.add_argument_group('Results Options') + results_group.add_argument( + '--flag-specific', + help=('Name of a flag-specific configuration defined in ' + 'FlagSpecificConfig.')) + results_group.add_argument( + '--additional-driver-flag', + '--additional-drt-flag', + dest='additional_driver_flag', + action='append', + default=[], + help=('Additional command line flag to pass to the driver. ' + 'Specify multiple times to add multiple flags.')) + results_group.add_argument( + '--build-directory', + default='out', + help=( + 'Path to the directory where build files are kept, not including ' + 'configuration. In general this will be "out".')) + results_group.add_argument( + '--clobber-old-results', + action='store_true', + help='Clobbers test results from previous runs.') + results_group.add_argument( + '--json-test-results', # New name from json_results_generator + '--write-full-results-to', # Old argument name + '--isolated-script-test-output', # Isolated API + help='Path to write the JSON test results for *all* tests.') + results_group.add_argument( + '--write-run-histories-to', + help='Path to write the JSON test run histories.') + results_group.add_argument( + '--no-show-results', + dest='show_results', + action='store_false', + help="Don't launch a browser with results after the tests are done") + results_group.add_argument('--results-directory', + help='Location of test results') + if rwt: + results_group.add_argument( + '--additional-expectations', + action='append', + default=[], + help=( + 'Path to a test_expectations file that will override previous ' + 'expectations. Specify multiple times for multiple sets of ' + 'overrides.')) + results_group.add_argument( + '--ignore-default-expectations', + action='store_true', + help='Do not use the default set of TestExpectations files.') + results_group.add_argument( + '--no-expectations', + action='store_true', + help=('Do not use TestExpectations, only run the tests without ' + 'reporting any results. Useful for generating code ' + 'coverage reports.')) + results_group.add_argument( + '--additional-platform-directory', + action='append', + default=[], + help=( + 'Additional directory where to look for test baselines (will ' + 'take precedence over platform baselines). Specify multiple ' + 'times to add multiple search path entries.')) + results_group.add_argument( + '--compare-port', help="Use the specified port's baselines first") + results_group.add_argument( + '--copy-baselines', + action='store_true', + help=( + 'If the actual result is different from the current baseline, ' + 'copy the current baseline into the *most-specific-platform* ' + 'directory, or the flag-specific generic-platform directory if ' + '--additional-driver-flag is specified. See --reset-results.')) + results_group.add_argument('--driver-name', + help='Alternative driver binary to use') + results_group.add_argument( + '--reset-results', + action='store_true', + help= + ('Reset baselines to the generated results in their existing ' + 'location or the default location if no baseline exists. For ' + 'virtual tests, reset the virtual baselines. If ' + '--additional-driver-flag is specified, reset the flag-specific ' + 'baselines. If --copy-baselines is specified, the copied ' + 'baselines will be reset.')) + results_group.add_argument('--smoke', + action='store_true', + default=None, + help='Run just the SmokeTests') + results_group.add_argument('--no-smoke', + dest='smoke', + action='store_false', + default=None, + help='Do not run just the SmokeTests') + else: + results_group.add_argument( + '--reset-results', + action='store_true', + help='Reset test metadata to the generated results.') + + +def add_testing_options_group(parser: argparse.ArgumentParser, + rwt: bool = True): + testing_group = parser.add_argument_group('Testing Options') + testing_group.add_argument( + '--additional-env-var', + action='append', + default=[], + help=('Passes that environment variable to the tests ' + '(--additional-env-var=NAME=VALUE)')) + testing_group.add_argument('--child-processes', + '--jobs', + '-j', + help='Number of drivers to run in parallel.') + testing_group.add_argument( + '--enable-leak-detection', + action='store_true', + help='Enable the leak detection of DOM objects.') + testing_group.add_argument( + '--enable-sanitizer', + action='store_true', + help='Only alert on sanitizer-related errors and crashes') + testing_group.add_argument( + '--exit-after-n-crashes-or-timeouts', + type=int, + default=None, + help='Exit after the first N crashes instead of running all tests') + testing_group.add_argument( + '--exit-after-n-failures', + type=int, + default=None, + help='Exit after the first N failures instead of running all tests') + testing_group.add_argument( + '--iterations', + '--isolated-script-test-repeat', + # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it. + '--gtest_repeat', + type=int, + default=1, + help='Number of times to run the set of tests (e.g. ABCABCABC)') + testing_group.add_argument( + '--repeat-each', + type=int, + default=1, + help='Number of times to run each test (e.g. AAABBBCCC)') + testing_group.add_argument( + '--num-retries', + '--test-launcher-retry-limit', + '--isolated-script-test-launcher-retry-limit', + type=int, + default=None, + help=('Number of times to retry failures. Default (when this ' + 'flag is not specified) is to retry 3 times, unless an ' + 'explicit list of tests is given. ' + 'If a non-zero value is given explicitly, failures are ' + 'retried regardless.')) + testing_group.add_argument( + '--no-retry-failures', + dest='num_retries', + action='store_const', + const=0, + help="Don't retry any failures (equivalent to --num-retries=0).") + testing_group.add_argument( + '--total-shards', + type=int, + help=('Total number of shards being used for this test run. ' + 'Must be used with --shard-index. ' + '(The user of this script is responsible for spawning ' + 'all of the shards.)')) + testing_group.add_argument( + '--shard-index', + type=int, + help=('Shard index [0..total_shards) of this test run. ' + 'Must be used with --total-shards.')) + testing_group.add_argument('--test-list', + action='append', + metavar='FILE', + help='read filters for tests to run') + testing_group.add_argument( + '--isolated-script-test-filter-file', + '--test-launcher-filter-file', + action='append', + metavar='FILE', + help=('read filters for tests to not run as if ' + 'they were specified on the command line')) + testing_group.add_argument( + '--isolated-script-test-filter', + action='append', + help=('A list of test globs to run or skip, separated by TWO colons, ' + 'e.g. fast::css/test.html; prefix the glob with "-" to skip it')) + # TODO(crbug.com/893235): Remove gtest_filter when FindIt no longer uses it. + testing_group.add_argument( + '--gtest_filter', + help=('A colon-separated list of tests to run. Wildcards are ' + 'NOT supported. It is the same as listing the tests as ' + 'positional arguments.')) + testing_group.add_argument( + '-i', + '--ignore-tests', + action='append', + default=[], + help='directories or test to ignore (may specify multiple times)') + testing_group.add_argument( + '--zero-tests-executed-ok', + action='store_true', + help=('If set, exit with a success code when no tests are run. ' + 'Used on trybots when web tests are retried without patch.')) + if rwt: + testing_group.add_argument( + '--build', + action='store_true', + default=True, + help=('Check to ensure the build is up to date (default).')) + testing_group.add_argument( + '--no-build', + dest='build', + action='store_false', + help="Don't check to see if the build is up to date.") + testing_group.add_argument('--wpt-only', + action='store_true', + help='Run web platform tests only.') + testing_group.add_argument( + '--disable-breakpad', + action='store_true', + help="Don't use breakpad to symbolize unexpected crashes.") + testing_group.add_argument( + '--driver-logging', + action='store_true', + help='Print detailed logging of the driver/content_shell') + testing_group.add_argument( + '--enable-tracing', + help=( + 'Capture and write a trace file with the specified ' + 'categories for each test. Passes appropriate --trace-startup ' + 'flags to the driver. If in doubt, use "*".')) + testing_group.add_argument( + '--fuzzy-diff', + action='store_true', + help=( + 'When running tests on an actual GPU, variance in pixel output ' + 'can lead to image differences causing failed expectations. ' + 'Using a fuzzy diff instead accounts for this variance. ' + 'See //tools/imagediff/image_diff.cc')) + testing_group.add_argument( + '--ignore-builder-category', + help=( + 'The category of builders to use with the --ignore-flaky-tests ' + "option ('layout' or 'deps').")) + testing_group.add_argument( + '--ignore-flaky-tests', + help= + ('Control whether tests that are flaky on the bots get ignored. ' + "'very-flaky' == Ignore any tests that flaked more than once on " + "the bot. 'maybe-flaky' == Ignore any tests that flaked once on " + "the bot. 'unexpected' == Ignore any tests that had unexpected " + 'results on the bot.')) + testing_group.add_argument('--layout-tests-directory', + help='Path to a custom web tests directory') + testing_group.add_argument( + '--max-locked-shards', + type=int, + default=0, + help='Set the maximum number of locked shards') + testing_group.add_argument( + '--nocheck-sys-deps', + action='store_true', + help="Don't check the system dependencies (themes)") + testing_group.add_argument( + '--order', + choices=['none', 'random', 'natural'], + default='random', + help= + ('Determine the order in which the test cases will be run. ' + "'none' == use the order in which the tests were listed " + 'either in arguments or test list, ' + "'random' == pseudo-random order (default). Seed can be " + "specified via --seed, otherwise it will default to the current " + "unix timestamp. 'natural' == use the natural order")) + testing_group.add_argument('--profile', + action='store_true', + help='Output per-test profile information.') + testing_group.add_argument( + '--profiler', + help=('Output per-test profile information, ' + 'using the specified profiler.')) + testing_group.add_argument( + '--restart-shell-between-tests', + choices=['always', 'never', 'on_retry'], + default='on_retry', + help=( + 'Restarting the shell between tests produces more ' + 'consistent results, as it prevents state from carrying over ' + 'from previous tests. It also increases test run time by at ' + 'least 2X. By default, the shell is restarted when tests get ' + 'retried, since leaking state between retries can sometimes ' + 'mask underlying flakiness, and the whole point of retries is ' + 'to look for flakiness.')) + testing_group.add_argument( + '--seed', + type=int, + help=('Seed to use for random test order (default: %(default)s). ' + 'Only applicable in combination with --order=random.')) + testing_group.add_argument( + '--skipped', + help= + ('Control how tests marked SKIP are run. ' + '"default" == Skip tests unless explicitly listed on the command ' + 'line, "ignore" == Run them anyway, ' + '"only" == only run the SKIP tests, ' + '"always" == always skip, even if listed on the command line.')) + testing_group.add_argument( + '--isolated-script-test-also-run-disabled-tests', + # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it. + '--gtest_also_run_disabled_tests', + action='store_const', + const='ignore', + dest='skipped', + help=('Equivalent to --skipped=ignore.')) + testing_group.add_argument( + '--skip-failing-tests', + action='store_true', + help=( + 'Skip tests that are expected to fail. Note: When using this ' + 'option, you might miss new crashes in these tests.')) + testing_group.add_argument( + '--skip-timeouts', + action='store_true', + help=('Skip tests marked TIMEOUT. Use it to speed up running the ' + 'entire test suite.')) + testing_group.add_argument('--timeout-ms', + type=float, + help='Set the timeout for each test') + testing_group.add_argument( + '--fastest', + type=float, + help=('Run the N%% fastest tests as well as any tests listed ' + 'on the command line')) + testing_group.add_argument( + '--initialize-webgpu-adapter-at-startup-timeout-ms', + type=float, + help='Initialize WebGPU adapter before running any tests.') + testing_group.add_argument( + '--wrapper', + help=( + 'wrapper command to insert before invocations of the driver; ' + 'option is split on whitespace before running. (Example: ' + '--wrapper="valgrind --smc-check=all")')) + # FIXME: Display the default number of child processes that will run. + testing_group.add_argument('-f', + '--fully-parallel', + action='store_true', + help='run all tests in parallel') + testing_group.add_argument( + '--virtual-parallel', + action='store_true', + help=( + 'When running in parallel, include virtual tests. Useful for ' + 'running a single virtual test suite, but will be slower ' + 'in other cases.')) + testing_group.add_argument( + '-n', + '--dry-run', + action='store_true', + help='Do everything but actually run the tests or upload results.') + testing_group.add_argument( + '-w', + '--watch', + action='store_true', + help='Re-run tests quickly (e.g. avoid restarting the server)') + testing_group.add_argument( + '--driver-kill-timeout-secs', + type=float, + default=1.0, + help=( + 'Number of seconds to wait before killing a driver, and the ' + 'main use case is to leave enough time to allow the process to ' + 'finish post-run hooks, such as dumping code coverage data. ' + 'Default is 1 second, can be overriden for specific use cases.' + )) + testing_group.add_argument( + '--ignore-testharness-expected-txt', + action='store_true', + help=('Ignore *-expected.txt for all testharness tests. All ' + 'testharness test failures will be shown, even if the ' + 'failures are expected in *-expected.txt.')) + else: + testing_group.add_argument('--no-wpt-internal', + action='store_false', + dest='run_wpt_internal', + help='Do not run internal WPTs.') + + +# for run_wpt_tests.py only +def add_android_options_group(parser: argparse.ArgumentParser): + group = parser.add_argument_group('Android Options') + group.add_argument( + '--avd-config', + help=('Path to the avd config. Used by the test runner to launch ' + 'Android emulators. Required when there is no android ' + 'emulators running, or no devices connected to the system.' + '(See //tools/android/avd/proto for message definition ' + 'and existing *.textpb files.)')) + group.add_argument('--emulator-window', + action='store_true', + help='Enable graphical window display on the emulator.') + group.add_argument( + '--browser-apk', + help= + ('Specify path under src/out/ of the browser APK to install and run. ' + 'For WebView, this should point to the shell. ' + 'The default value is apks/ChromePublic.apk for Chrome Android, ' + 'and apks/SystemWebViewShell.apk for WebView.')) + group.add_argument( + '--webview-provider', + help= + ('Specify path under src/out/ of the WebView provider APK to install. ' + 'The default value is apks/SystemWebView.apk.')) + group.add_argument('--no-install', + action='store_true', + help=('Do not install packages to devices. ' + 'Use the packages preinstalled.')) return group +def add_ios_options_group(parser: argparse.ArgumentParser): + group = parser.add_argument_group('iOS Options') + group.add_argument('--xcode-build-version', + help='Xcode build version to install. Use chrome_ios' + ' product to enable this', + metavar='build_id') + return group + + +def add_logging_options_group(parser: argparse.ArgumentParser): + group = parser.add_argument_group('Logging Options') + group.add_argument('-v', + '--verbose', + action='count', + default=0, + help='Increase verbosity'), + # TODO: when using run_wpt_tests.py on swarming, we should run + # that inside run_isolated_script_test.py so that we can remove + # the workaround below + group.add_argument('--isolated-outdir', help=argparse.SUPPRESS), + group.add_argument('--isolated-script-test-also-run-disabled-tests', + action='store_true', + help=argparse.SUPPRESS), + group.add_argument('--isolated-script-test-chartjson-output', + help=argparse.SUPPRESS), + group.add_argument('--isolated-script-test-perf-output', + help=argparse.SUPPRESS), + group.add_argument('--script-type', help=argparse.SUPPRESS) + + def _builder_options(builder_name): return optparse.Values({ 'builder_name':
diff --git a/third_party/blink/tools/blinkpy/web_tests/port/win.py b/third_party/blink/tools/blinkpy/web_tests/port/win.py index 2f8dd23c..da8d56b 100644 --- a/third_party/blink/tools/blinkpy/web_tests/port/win.py +++ b/third_party/blink/tools/blinkpy/web_tests/port/win.py
@@ -30,6 +30,7 @@ import errno import logging import os +import platform import tempfile # The _winreg library is only available on Windows. @@ -73,7 +74,7 @@ version = host.platform.os_version port_name = port_name + '-' + version - if host.platform.get_machine() == 'arm64': + if 'ARM' in platform.processor(): port_name = port_name + '-arm64' return port_name
diff --git a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py index 8c65f67e..008f6c4 100644 --- a/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py +++ b/third_party/blink/tools/blinkpy/web_tests/run_web_tests.py
@@ -93,7 +93,6 @@ factory.add_platform_options_group(parser) factory.add_configuration_options_group(parser) printing.add_print_options_group(parser) - factory.add_wpt_options_group(parser) fuchsia_group = parser.add_argument_group('Fuchsia-specific Options') fuchsia_group.add_argument( @@ -135,369 +134,8 @@ fuchsia_group.add_argument('--logs-dir', help='Location of diagnostics logs') - results_group = parser.add_argument_group('Results Options') - results_group.add_argument( - '--flag-specific', - help=('Name of a flag-specific configuration defined in ' - 'FlagSpecificConfig. It is like a shortcut of ' - '--additional-driver-flag, --additional-expectations and ' - '--additional-platform-directory. When setting up flag-specific ' - 'testing on bots, we should use this option instead of the ' - 'discrete options. See crbug.com/1238155 for details.')) - results_group.add_argument( - '--additional-driver-flag', - '--additional-drt-flag', - dest='additional_driver_flag', - action='append', - default=[], - help=('Additional command line flag to pass to the driver. ' - 'Specify multiple times to add multiple flags.')) - results_group.add_argument( - '--additional-expectations', - action='append', - default=[], - help=('Path to a test_expectations file that will override previous ' - 'expectations. Specify multiple times for multiple sets of ' - 'overrides.')) - results_group.add_argument( - '--ignore-default-expectations', - action='store_true', - help='Do not use the default set of TestExpectations files.') - results_group.add_argument( - '--no-expectations', - action='store_true', - help=('Do not use TestExpectations, only run the tests without ' - 'reporting any results. Useful for generating code ' - 'coverage reports.')) - results_group.add_argument( - '--additional-platform-directory', - action='append', - default=[], - help=('Additional directory where to look for test baselines (will ' - 'take precedence over platform baselines). Specify multiple ' - 'times to add multiple search path entries.')) - results_group.add_argument( - '--build-directory', - default='out', - help=( - 'Path to the directory where build files are kept, not including ' - 'configuration. In general this will be "out".')) - results_group.add_argument( - '--clobber-old-results', - action='store_true', - help='Clobbers test results from previous runs.') - results_group.add_argument('--compare-port', - help="Use the specified port's baselines first") - results_group.add_argument( - '--copy-baselines', - action='store_true', - help=('If the actual result is different from the current baseline, ' - 'copy the current baseline into the *most-specific-platform* ' - 'directory, or the flag-specific generic-platform directory if ' - '--additional-driver-flag is specified. See --reset-results.')) - results_group.add_argument('--driver-name', - help='Alternative driver binary to use') - results_group.add_argument( - '--json-test-results', # New name from json_results_generator - '--write-full-results-to', # Old argument name - '--isolated-script-test-output', # Isolated API - help='Path to write the JSON test results for *all* tests.') - results_group.add_argument( - '--write-run-histories-to', - help='Path to write the JSON test run histories.') - results_group.add_argument( - '--no-show-results', - dest='show_results', - action='store_false', - help="Don't launch a browser with results after the tests are done") - results_group.add_argument( - '--reset-results', - action='store_true', - help=('Reset baselines to the generated results in their existing ' - 'location or the default location if no baseline exists. For ' - 'virtual tests, reset the virtual baselines. If ' - '--additional-driver-flag is specified, reset the flag-specific ' - 'baselines. If --copy-baselines is specified, the copied ' - 'baselines will be reset.')) - results_group.add_argument('--results-directory', - help='Location of test results') - results_group.add_argument('--smoke', - action='store_true', - default=None, - help='Run just the SmokeTests') - results_group.add_argument('--no-smoke', - dest='smoke', - action='store_false', - default=None, - help='Do not run just the SmokeTests') - - testing_group = parser.add_argument_group('Testing Options') - testing_group.add_argument( - '--additional-env-var', - action='append', - default=[], - help=('Passes that environment variable to the tests ' - '(--additional-env-var=NAME=VALUE)')) - testing_group.add_argument( - '--build', - action='store_true', - default=True, - help=('Check to ensure the build is up to date (default).')) - testing_group.add_argument( - '--no-build', - dest='build', - action='store_false', - help="Don't check to see if the build is up to date.") - testing_group.add_argument('--wpt-only', - action='store_true', - help='Run web platform tests only.') - testing_group.add_argument('--child-processes', - '--jobs', - '-j', - help='Number of drivers to run in parallel.') - testing_group.add_argument( - '--disable-breakpad', - action='store_true', - help="Don't use breakpad to symbolize unexpected crashes.") - testing_group.add_argument( - '--driver-logging', - action='store_true', - help='Print detailed logging of the driver/content_shell') - testing_group.add_argument( - '--enable-leak-detection', - action='store_true', - help='Enable the leak detection of DOM objects.') - testing_group.add_argument( - '--enable-sanitizer', - action='store_true', - help='Only alert on sanitizer-related errors and crashes') - testing_group.add_argument( - '--enable-tracing', - help=('Capture and write a trace file with the specified ' - 'categories for each test. Passes appropriate --trace-startup ' - 'flags to the driver. If in doubt, use "*".')) - testing_group.add_argument( - '--exit-after-n-crashes-or-timeouts', - type=int, - default=None, - help='Exit after the first N crashes instead of running all tests') - testing_group.add_argument( - '--exit-after-n-failures', - type=int, - default=None, - help='Exit after the first N failures instead of running all tests') - testing_group.add_argument( - '--fuzzy-diff', - action='store_true', - help=('When running tests on an actual GPU, variance in pixel output ' - 'can lead to image differences causing failed expectations. ' - 'Using a fuzzy diff instead accounts for this variance. ' - 'See //tools/imagediff/image_diff.cc')) - testing_group.add_argument( - '--ignore-builder-category', - help=('The category of builders to use with the --ignore-flaky-tests ' - "option ('layout' or 'deps').")) - testing_group.add_argument( - '--ignore-flaky-tests', - help=('Control whether tests that are flaky on the bots get ignored. ' - "'very-flaky' == Ignore any tests that flaked more than once on " - "the bot. 'maybe-flaky' == Ignore any tests that flaked once on " - "the bot. 'unexpected' == Ignore any tests that had unexpected " - 'results on the bot.')) - testing_group.add_argument( - '--iterations', - '--isolated-script-test-repeat', - # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it. - '--gtest_repeat', - type=int, - default=1, - help='Number of times to run the set of tests (e.g. ABCABCABC)') - testing_group.add_argument('--layout-tests-directory', - help='Path to a custom web tests directory') - testing_group.add_argument('--max-locked-shards', - type=int, - default=0, - help='Set the maximum number of locked shards') - testing_group.add_argument( - '--nocheck-sys-deps', - action='store_true', - help="Don't check the system dependencies (themes)") - testing_group.add_argument( - '--order', - choices=['none', 'random', 'natural'], - default='random', - help=('Determine the order in which the test cases will be run. ' - "'none' == use the order in which the tests were listed " - 'either in arguments or test list, ' - "'random' == pseudo-random order (default). Seed can be " - "specified via --seed, otherwise it will default to the current " - "unix timestamp. 'natural' == use the natural order")) - testing_group.add_argument('--profile', - action='store_true', - help='Output per-test profile information.') - testing_group.add_argument('--profiler', - help=('Output per-test profile information, ' - 'using the specified profiler.')) - testing_group.add_argument( - '--restart-shell-between-tests', - choices=['always', 'never', 'on_retry'], - default='on_retry', - help=('Restarting the shell between tests produces more ' - 'consistent results, as it prevents state from carrying over ' - 'from previous tests. It also increases test run time by at ' - 'least 2X. By default, the shell is restarted when tests get ' - 'retried, since leaking state between retries can sometimes ' - 'mask underlying flakiness, and the whole point of retries is ' - 'to look for flakiness.')) - testing_group.add_argument( - '--repeat-each', - type=int, - default=1, - help='Number of times to run each test (e.g. AAABBBCCC)') - testing_group.add_argument( - '--num-retries', - '--test-launcher-retry-limit', - '--isolated-script-test-launcher-retry-limit', - type=int, - default=None, - help=('Number of times to retry failures. Default (when this ' - 'flag is not specified) is to retry 3 times, unless an ' - 'explicit list of tests is passed to run_web_tests.py. ' - 'If a non-zero value is given explicitly, failures are ' - 'retried regardless.')) - testing_group.add_argument( - '--no-retry-failures', - dest='num_retries', - action='store_const', - const=0, - help="Don't retry any failures (equivalent to --num-retries=0).") - testing_group.add_argument( - '--total-shards', - type=int, - help=('Total number of shards being used for this test run. ' - 'Must be used with --shard-index. ' - '(The user of this script is responsible for spawning ' - 'all of the shards.)')) - testing_group.add_argument( - '--shard-index', - type=int, - help=('Shard index [0..total_shards) of this test run. ' - 'Must be used with --total-shards.')) - testing_group.add_argument( - '--seed', - type=int, - help=('Seed to use for random test order (default: %(default)s). ' - 'Only applicable in combination with --order=random.')) - testing_group.add_argument( - '--skipped', - help=( - 'Control how tests marked SKIP are run. ' - '"default" == Skip tests unless explicitly listed on the command ' - 'line, "ignore" == Run them anyway, ' - '"only" == only run the SKIP tests, ' - '"always" == always skip, even if listed on the command line.')) - testing_group.add_argument( - '--isolated-script-test-also-run-disabled-tests', - # TODO(crbug.com/893235): Remove the gtest alias when FindIt no longer uses it. - '--gtest_also_run_disabled_tests', - action='store_const', - const='ignore', - dest='skipped', - help=('Equivalent to --skipped=ignore.')) - testing_group.add_argument( - '--skip-failing-tests', - action='store_true', - help=('Skip tests that are expected to fail. Note: When using this ' - 'option, you might miss new crashes in these tests.')) - testing_group.add_argument( - '--skip-timeouts', - action='store_true', - help=('Skip tests marked TIMEOUT. Use it to speed up running the ' - 'entire test suite.')) - testing_group.add_argument( - '--fastest', - type=float, - help=('Run the N%% fastest tests as well as any tests listed ' - 'on the command line')) - testing_group.add_argument('--test-list', - action='append', - metavar='FILE', - help='read filters for tests to run') - testing_group.add_argument( - '--isolated-script-test-filter-file', - '--test-launcher-filter-file', - action='append', - metavar='FILE', - help=('read filters for tests to not run as if ' - 'they were specified on the command line')) - testing_group.add_argument( - '--isolated-script-test-filter', - action='append', - help=('A list of test globs to run or skip, separated by TWO colons, ' - 'e.g. fast::css/test.html; prefix the glob with "-" to skip it')) - # TODO(crbug.com/893235): Remove gtest_filter when FindIt no longer uses it. - testing_group.add_argument( - '--gtest_filter', - help=('A colon-separated list of tests to run. Wildcards are ' - 'NOT supported. It is the same as listing the tests as ' - 'positional arguments.')) - testing_group.add_argument('--timeout-ms', - help='Set the timeout for each test') - testing_group.add_argument( - '--initialize-webgpu-adapter-at-startup-timeout-ms', - type=float, - help='Initialize WebGPU adapter before running any tests.') - testing_group.add_argument( - '--wrapper', - help=('wrapper command to insert before invocations of the driver; ' - 'option is split on whitespace before running. (Example: ' - '--wrapper="valgrind --smc-check=all")')) - # FIXME: Display the default number of child processes that will run. - testing_group.add_argument('-f', - '--fully-parallel', - action='store_true', - help='run all tests in parallel') - testing_group.add_argument( - '--virtual-parallel', - action='store_true', - help=('When running in parallel, include virtual tests. Useful for ' - 'running a single virtual test suite, but will be slower ' - 'in other cases.')) - testing_group.add_argument( - '-i', - '--ignore-tests', - action='append', - default=[], - help='directories or test to ignore (may specify multiple times)') - testing_group.add_argument( - '-n', - '--dry-run', - action='store_true', - help='Do everything but actually run the tests or upload results.') - testing_group.add_argument( - '-w', - '--watch', - action='store_true', - help='Re-run tests quickly (e.g. avoid restarting the server)') - testing_group.add_argument( - '--zero-tests-executed-ok', - action='store_true', - help=('If set, exit with a success code when no tests are run. ' - 'Used on trybots when web tests are retried without patch.')) - testing_group.add_argument( - '--driver-kill-timeout-secs', - type=float, - default=1.0, - help=('Number of seconds to wait before killing a driver, and the ' - 'main use case is to leave enough time to allow the process to ' - 'finish post-run hooks, such as dumping code coverage data. ' - 'Default is 1 second, can be overriden for specific use cases.')) - testing_group.add_argument( - '--ignore-testharness-expected-txt', - action='store_true', - help=('Ignore *-expected.txt for all testharness tests. All ' - 'testharness test failures will be shown, even if the ' - 'failures are expected in *-expected.txt.')) + factory.add_results_options_group(parser) + factory.add_testing_options_group(parser) # FIXME: Move these into json_results_generator.py. json_group = parser.add_argument_group('Result JSON Options')
diff --git a/third_party/blink/tools/run_wpt_tests.py b/third_party/blink/tools/run_wpt_tests.py index b551334e..deca5b90 100755 --- a/third_party/blink/tools/run_wpt_tests.py +++ b/third_party/blink/tools/run_wpt_tests.py
@@ -12,20 +12,19 @@ import logging import multiprocessing import os +import optparse import re -import shutil import signal import subprocess import sys -import warnings -from typing import List, Optional, Tuple +from typing import List, Tuple from blinkpy.common import exit_codes from blinkpy.common import path_finder from blinkpy.common.host import Host -from blinkpy.common.path_finder import PathFinder from blinkpy.w3c.wpt_results_processor import WPTResultsProcessor from blinkpy.web_tests.port.base import Port +from blinkpy.web_tests.port import factory path_finder.add_testing_dir_to_sys_path() path_finder.add_build_android_to_sys_path() @@ -33,9 +32,9 @@ path_finder.bootstrap_wpt_imports() import mozlog -from scripts import common from wptrunner import wptcommandline, wptlogging +logging.basicConfig(level=logging.INFO) logger = logging.getLogger('run_wpt_tests') UPSTREAM_GIT_URL = 'https://github.com/web-platform-tests/wpt.git' @@ -127,137 +126,18 @@ self._fallback_handler.emit(record) -PARAMETER_DENYLIST = { - # Parameters specific to non-Chromium vendors. - '--prefs-root', - '--preload-browser', - '--no-preload-browser', - '--disable-e10s', - '--enable-fission', - '--no-enable-fission', - '--stackfix-dir', - '--specialpowers-path', - '--setpref', - '--leak-check', - '--no-leak-check', - '--stylo-threads', - '--reftest-screenshot', - '--reftest-internal', - '--reftest-external', - '--chaos', - '--user-stylesheet', - '--sauce-browser', - '--sauce-platform', - '--sauce-version', - '--sauce-build', - '--sauce-tags', - '--sauce-tunnel-id', - '--sauce-user', - '--sauce-key', - '--sauce-connect-binary', - '--sauce-init-timeout', - '--sauce-connect-arg', - '--github-checks-text-file', - '--webkit-port', - '--kill-safari', -} -if not _ANDROID_ENABLED: - PARAMETER_DENYLIST.update({ - '--adb-binary', - '--package-name', - '--keep-app-data-directory', - '--device-serial', - }) - - class WPTAdapter: - def __init__(self): - self.host = Host() - self.fs = self.host.filesystem - self.path_finder = PathFinder(self.fs) - self.port = self.host.port_factory.get() - self._product_registry = make_product_registry() - self._shard_index = _parse_environ_int('GTEST_SHARD_INDEX') - self._total_shards = _parse_environ_int('GTEST_TOTAL_SHARDS') + def __init__(self, product, port, options, paths): + self.product = product + self.port = port + self.host = port.host + self.fs = port.host.filesystem + self.options = options + self.paths = paths - def parse_arguments( - self, - argv: Optional[List[str]] = None, - ) -> argparse.Namespace: - wptrunner_parser = wptcommandline.create_parser( - product_choices=sorted(self._product_registry, key=len)) - # Not ideal, but this creates a wptrunner-compliant CLI without showing - # many irrelevant parameters. - for group in wptrunner_parser._action_groups: - group.conflict_handler = 'resolve' - for action in wptrunner_parser._actions: - if frozenset(action.option_strings) & PARAMETER_DENYLIST: - action.help = argparse.SUPPRESS - parser = argparse.ArgumentParser( - description=__doc__, - parents=[ - wptrunner_parser, - # Put the overridden parameters in a separate parent instead of on - # this parser so that arguments of groups with the same title are - # merged together. - self._make_override_parser(), - ], - conflict_handler='resolve', - epilog=('All unrecognized arguments are passed through to the ' - 'browser binary.'), - ) - options, unknown_args = parser.parse_known_intermixed_args(argv) - try: - self._check_and_update_options(options) - except ValueError as error: - parser.error(error) - options.binary_args.extend(unknown_args) - return options - - def _make_override_parser(self) -> argparse.ArgumentParser: - """Create a parser that overrides existing wptrunner options. - - `argument.ArgumentParser` can extend other parsers and override their - options, with the caveat that the child parser only inherits options - that the parent had at the time of the child's initialization. - - See Also: - https://docs.python.org/3/library/argparse.html#parents - """ - parser = argparse.ArgumentParser() - # Absorb options that are part of the isolated script convention, but - # should have no effect. - parser.add_argument('--isolated-outdir', help=argparse.SUPPRESS) - parser.add_argument('--isolated-script-test-also-run-disabled-tests', - action='store_true', - help=argparse.SUPPRESS) - parser.add_argument('--isolated-script-test-chartjson-output', - help=argparse.SUPPRESS) - parser.add_argument('--isolated-script-test-perf-output', - help=argparse.SUPPRESS) - parser.add_argument('--script-type', help=argparse.SUPPRESS) - parser.add_argument( - '-j', - '--processes', - '--child-processes', - type=lambda processes: max(0, int(processes)), - help=('Number of drivers to start in parallel. (For Android, ' - 'this number is the number of emulators started.) ' - 'The actual number of devices tested may be greater ' - 'if physical devices are available.)')) - self.add_output_arguments(parser) - self.add_binary_arguments(parser) - self.add_test_arguments(parser) - self.add_debugging_arguments(parser) - self.add_configuration_arguments(parser) - if _ANDROID_ENABLED: - self.add_android_arguments(parser) - else: - warnings.warn('Android tools not found') - if _IOS_ENABLED: - self.add_ios_arguments(parser) - else: - warnings.warn('iOS tools not found') + def _set_up_runner_options(self): + """Set up wptrunner options based on run_wpt_tests.py arguments and defaults.""" + parser = wptcommandline.create_parser() # Nightly installation is not supported, so just add defaults. parser.set_defaults( prompt=False, @@ -266,109 +146,201 @@ channel='nightly', affected=None, ) - return parser - def _check_and_update_options(self, options): - """Postprocess options, some of which can depend on each other.""" - self._check_and_update_sharding_options(options) - # Set up logging as early as possible. - self._check_and_update_output_options(options) - self._check_and_update_upstream_options(options) - self._check_and_update_config_options(options) - self._check_and_update_debugging_options(options) + # Install customized versions of `mozlog` formatters. + for name, formatter in [ + ('grouped', GroupingFormatter), + ('mach', MachFormatter), + ]: + mozlog.commandline.log_formatters[name] = ( + formatter, + mozlog.commandline.log_formatters[name][1], + ) + + runner_options = parser.parse_args(['--product', self.product.name]) + runner_options.include = [] + runner_options.exclude = [] + # TODO(crbug/1316055): Enable tombstone with '--stackwalk-binary' and # '--symbols-path'. - options.exclude = options.exclude or [] - options.exclude.extend([ - # Exclude webdriver tests for now. The CI runs them separately. - 'webdriver', - 'infrastructure/webdriver', - ]) - options.no_capture_stdio = True - options.manifest_download = False + runner_options.no_capture_stdio = True + runner_options.manifest_download = False + runner_options.manifest_update = False + runner_options.headless = True - def _check_and_update_output_options(self, options): - if options.verbose >= 1: - options.log_mach = '-' - options.log_mach_level = 'info' - options.log_mach_verbose = True - if options.verbose >= 2: - options.log_mach_level = 'debug' - if options.verbose >= 3: - options.webdriver_args.extend([ + # Set up logging as early as possible. + self._set_up_runner_output_options(runner_options) + self._set_up_runner_sharding_options(runner_options) + self._set_up_runner_config_options(runner_options) + # self._set_up_runner_debugging_options() + self._set_up_runner_tests(runner_options) + + for name, value in self.product.product_specific_options().items(): + self._ensure_value(runner_options, name, value) + + runner_options.webdriver_args.extend( + self.product.additional_webdriver_args()) + return runner_options + + def _ensure_value(self, options, name, value): + if not getattr(options, name, None): + setattr(options, name, value) + + def _set_up_runner_output_options(self, runner_options): + verbose_level = int(self.options.verbose) + if verbose_level >= 1: + runner_options.log_mach = '-' + runner_options.log_mach_level = 'info' + runner_options.log_mach_verbose = True + if verbose_level >= 2: + runner_options.log_mach_level = 'debug' + if verbose_level >= 3: + runner_options.webdriver_args.extend([ '--verbose', '--log-path=-', ]) - output_dir = self.path_from_output_dir(options.target) - if not self.fs.isdir(output_dir): - raise ValueError("'--target' must be a directory under //out") - self.port.set_option_default('target', options.target) - if options.results_directory: - self.port.set_option_default('results_directory', - options.results_directory) + if self.options.json_test_results: + runner_options.log_chromium = self.options.json_test_results else: - options.results_directory = self.port.results_directory() - if options.log_chromium == '' or options.show_results: - options.log_chromium = self.fs.join(output_dir, 'results.json') - if options.log_wptreport == '': - filename = 'wpt_reports_%s_%02d.json' % (options.product, - options.this_chunk) - options.log_wptreport = self.fs.join(output_dir, filename) + runner_options.log_chromium = self.fs.join( + self.port.results_directory(), 'results.json') + runner_options.log_wptreport = self.fs.join( + self.port.artifacts_directory(), 'wpt_reports.json') for log_type in ('chromium', 'wptreport'): dest = 'log_%s' % log_type - filename = getattr(options, dest) + filename = getattr(runner_options, dest) if filename: filename = self.fs.abspath(filename) - setattr(options, dest, [mozlog.commandline.log_file(filename)]) - options.log = wptlogging.setup(dict(vars(options)), - {'grouped': sys.stdout}) + setattr(runner_options, dest, + [mozlog.commandline.log_file(filename)]) + runner_options.log = wptlogging.setup(dict(vars(runner_options)), + {'grouped': sys.stdout}) logging.root.handlers.clear() - logging.root.addHandler(StructuredLogAdapter(options.log)) + logging.root.addHandler(StructuredLogAdapter(runner_options.log)) - def _check_and_update_config_options(self, options: argparse.Namespace): - options.webdriver_args.extend([ + def _set_up_runner_sharding_options(self, runner_options): + if (self.options.total_shards is not None + or 'GTEST_TOTAL_SHARDS' in self.host.environ): + runner_options.total_chunks = int( + self.options.total_shards + or self.host.environ['GTEST_TOTAL_SHARDS']) + + if (self.options.shard_index is not None + or 'GTEST_SHARD_INDEX' in self.host.environ): + runner_options.this_chunk = 1 + int( + self.options.shard_index + or self.host.environ['GTEST_SHARD_INDEX']) + + # Override the default sharding strategy, which is to shard by directory + # (`dir_hash`). Sharding by test ID attempts to maximize shard workload + # uniformity, as test leaf directories can vary greatly in size. + runner_options.chunk_type = 'id_hash' + + def _set_up_runner_config_options(self, runner_options): + runner_options.webdriver_args.extend([ '--enable-chrome-logs', ]) - options.binary_args.extend([ + runner_options.binary_args.extend([ '--host-resolver-rules=' 'MAP nonexistent.*.test ~NOTFOUND, MAP *.test 127.0.0.1', '--enable-experimental-web-platform-features', '--enable-blink-features=MojoJS,MojoJSTest', '--enable-blink-test-features', '--disable-field-trial-config', - '--enable-features=' - 'DownloadService<DownloadServiceStudy', - '--force-fieldtrials=DownloadServiceStudy/Enabled', - '--force-fieldtrial-params=' - 'DownloadServiceStudy.Enabled:start_up_delay_ms/0', ]) - if options.sanitizer_enabled and (options.timeout_multiplier or 1) < 2: - options.timeout_multiplier = 2 - logger.info('Defaulting to 2x timeout multiplier because ' - 'sanitizer is enabled') - if not options.mojojs_path: - options.mojojs_path = self.path_from_output_dir( - options.target, 'gen') - if not options.config and options.run_wpt_internal: - options.config = self.path_finder.path_from_web_tests( + runner_options.mojojs_path = self.port.generated_sources_directory() + + # TODO: RWT has subtle control on how tests are retried. For example + # there won't be automatic retry of failed tests when they are specified + # at command line individually. We need such capability for repeat to + # work correctly. + runner_options.repeat = self.options.iterations + + if self.options.run_wpt_internal: + runner_options.config = self.port._path_finder.path_from_web_tests( 'wptrunner.blink.ini') - if options.flag_specific: + + if self.port.flag_specific_config_name(): # Enable adding smoke tests later. - self.port.set_option_default('flag_specific', - options.flag_specific) configs = self.port.flag_specific_configs() - args, _ = configs[options.flag_specific] + args, _ = configs[self.port.flag_specific_config_name()] logger.info('Running with flag-specific arguments: "%s"', ' '.join(args)) - options.binary_args.extend(args) + runner_options.binary_args.extend(args) + + if self.options.enable_leak_detection: + runner_options.binary_args.extend(['--enable-leak-detection']) + + runner_options.binary_args.extend(self.options.additional_driver_flag) + + if self.options.enable_sanitizer: + runner_options.timeout_multiplier = 2 + logger.info('Defaulting to 2x timeout multiplier because ' + 'sanitizer is enabled') + + if self.options.use_upstream_wpt: + # when running with upstream, the goal is to get wpt report that can + # be uploaded to wpt.fyi. We do not really care if tests failed or + # not. Add '--no-fail-on-unexpected' so that the overall result is + # success. Add '--no-restart-on-unexpected' to speed up the test. On + # Android side, we are always running with one emulator or worker, + # so do not add '--run-by-dir=0' + runner_options.retry_unexpected = 0 + runner_options.fail_on_unexpected = False + runner_options.restart_on_unexpected = False + else: + # By default, wpt will treat unexpected passes as errors, so we + # disable that to be consistent with Chromium CI. Add + # '--run-by-dir=0' so that tests can be more evenly distributed + # among workers. + runner_options.retry_unexpected = 3 + runner_options.fail_on_unexpected_pass = False + runner_options.restart_on_unexpected = False + runner_options.restart_on_new_group = False + runner_options.run_by_dir = 0 + runner_options.reuse_window = True + + if self.options.num_retries is not None: + runner_options.retry_unexpected = self.options.num_retries + + # TODO: repeat_each will restart browsers between tests. Wptrunner's + # rerun will not restart browsers. Might also need to restart the + # browser at Wptrunner side. + runner_options.rerun = self.options.repeat_each + + # TODO: Wptrunner's pause_after_test feature could be useful. Need to figure out + # the correct CLI for that. + # def _set_up_runner_debugging_options(self): + # self.port.set_option_default('use_xvfb', self.port.get_option('headless')) + # if not options.headless and options.processes is None: + # logger.info('Not headless; default to 1 worker to avoid ' + # 'opening too many windows') + # options.processes = 1 + + def _set_up_runner_tests(self, runner_options): + if self.options.gtest_filter: + runner_options.include.extend( + self._parse_gtest_filter(self.options.gtest_filter)) + + if self.options.isolated_script_test_filter: + include, exclude = self._parse_isolated_script_test_filter( + self.options.isolated_script_test_filter) + runner_options.include.extend(include) + runner_options.exclude.extend(exclude) + + runner_options.exclude.extend(self.options.ignore_tests) + + for path in self.paths: + runner_options.include.append( + self.port._path_finder.strip_wpt_path(path)) if self.port.default_smoke_test_only(): smoke_file_short_path = self.fs.relpath( self.port.path_to_smoke_tests_file(), self.port.web_tests_dir()) - if not _has_explicit_tests(options): - self._load_smoke_tests(options) + if not _has_explicit_tests(runner_options): + runner_options.include.extend(self._load_smoke_tests()) logger.info( 'Tests not explicitly specified; ' 'running tests from %s', smoke_file_short_path) @@ -377,14 +349,16 @@ 'Tests explicitly specified; ' 'not running tests from %s', smoke_file_short_path) - def _check_and_update_debugging_options(self, options: argparse.Namespace): - self.port.set_option_default('use_xvfb', options.headless) - if not options.headless and options.processes is None: - logger.info('Not headless; default to 1 worker to avoid ' - 'opening too many windows') - options.processes = 1 + runner_options.exclude.extend([ + # Exclude webdriver tests for now. The CI runs them separately. + 'webdriver', + 'infrastructure/webdriver', + ]) - def _load_smoke_tests(self, options: argparse.Namespace): + if self.options.zero_tests_executed_ok and runner_options.include: + runner_options.default_exclude = True + + def _load_smoke_tests(self): """Read the smoke tests file and append its tests to the test list. This method handles smoke test files inherited from `run_web_tests.py` @@ -394,7 +368,7 @@ assumed to be a legacy layout test that is excluded. """ smoke_file_path = self.port.path_to_smoke_tests_file() - options.include = options.include or [] + tests = [] with self.fs.open_text_file_for_reading(smoke_file_path) as smoke_file: for line in smoke_file: test, _, _ = line.partition('#') @@ -403,101 +377,64 @@ if not wpt_dir.endswith('/'): wpt_dir += '/' if test.startswith(wpt_dir): - options.include.append( - test.replace(wpt_dir, url_prefix, 1)) + tests.append(test.replace(wpt_dir, url_prefix, 1)) + return tests - def _check_and_update_upstream_options(self, options: argparse.Namespace): - if options.use_upstream_wpt: - # when running with upstream, the goal is to get wpt report that can - # be uploaded to wpt.fyi. We do not really cares if tests failed or - # not. Add '--no-fail-on-unexpected' so that the overall result is - # success. Add '--no-restart-on-unexpected' to speed up the test. On - # Android side, we are always running with one emulator or worker, - # so do not add '--run-by-dir=0' - options.retry_unexpected = 0 - options.fail_on_unexpected = False - options.restart_on_unexpected = False - options.run_wpt_internal = False - else: - # By default, wpt will treat unexpected passes as errors, so we - # disable that to be consistent with Chromium CI. Add - # '--run-by-dir=0' so that tests can be more evenly distributed - # among workers. - options.fail_on_unexpected_pass = False - options.restart_on_unexpected = False - options.restart_on_new_group = False - options.run_by_dir = 0 - options.reuse_window = True - - def _check_and_update_sharding_options(self, options): - # Command line arguments take priority over environment variables - if (options.total_chunks == 1 and self._shard_index is not None - and self._total_shards is not None): - # wptrunner uses a 1-based index, whereas LUCI uses 0-based. - options.this_chunk = self._shard_index + 1 - options.total_chunks = self._total_shards - # Override the default sharding strategy, which is to shard by directory - # (`dir_hash`). Sharding by test ID attempts to maximize shard workload - # uniformity, as test leaf directories can vary greatly in size. - options.chunk_type = options.chunk_type or 'id_hash' - - def path_from_output_dir(self, *parts): - return self.path_finder.path_from_chromium_base('out', *parts) - - def run_tests(self, options: argparse.Namespace) -> int: + def run_tests(self) -> int: with contextlib.ExitStack() as stack: tmp_dir = stack.enter_context(self.fs.mkdtemp()) # Manually remove the temporary directory's contents recursively # after the tests complete. Otherwise, `mkdtemp()` raise an error. stack.callback(self.fs.rmtree, tmp_dir) - product = self._make_product(options) - stack.enter_context(product.test_env()) - product.update_options_for_product(options) - if options.use_upstream_wpt: - tests_root = tools_root = self.fs.join(tmp_dir, 'upstream-wpt') - logger.info('Using upstream wpt, cloning to %s ...', - tests_root) - if self.fs.isdir(tests_root): - shutil.rmtree(tests_root, ignore_errors=True) - self.host.executive.run_command([ - 'git', 'clone', UPSTREAM_GIT_URL, tests_root, '--depth=25' - ]) - self._checkout_3h_epoch_commit(tools_root) - else: - tests_root = self.path_finder.path_from_wpt_tests() - tools_root = path_finder.get_wpt_tools_wpt_dir() - - options.tests_root = options.tests_root or tests_root - options.metadata_root = options.metadata_root or tests_root - options.run_info = options.run_info or tmp_dir - logger.debug('Using WPT tests (external) from %s', tests_root) - logger.debug('Using WPT tools from %s', tools_root) - self._create_extra_run_info(options) - - if options.clobber_old_results: + if self.options.clobber_old_results: self.port.clobber_old_results() - elif self.port._filesystem.exists(self.port.artifacts_directory()): + elif self.fs.exists(self.port.artifacts_directory()): self.port.limit_archived_results_count() # Rename the existing results folder for archiving. self.port.rename_results_folder() # Create the output directory if it doesn't already exist. - self.port.host.filesystem.maybe_make_directory( - self.port.artifacts_directory()) + self.fs.maybe_make_directory(self.port.artifacts_directory()) + + stack.enter_context(self.product.test_env()) + + runner_options = self._set_up_runner_options() + + if self.options.use_upstream_wpt: + tests_root = tools_root = self.fs.join(tmp_dir, 'upstream-wpt') + logger.info('Using upstream wpt, cloning to %s ...', + tests_root) + self.host.executive.run_command([ + 'git', 'clone', UPSTREAM_GIT_URL, tests_root, '--depth=25' + ]) + self._checkout_3h_epoch_commit(tools_root) + else: + tests_root = self.port._path_finder.path_from_wpt_tests() + tools_root = path_finder.get_wpt_tools_wpt_dir() + + runner_options.tests_root = tests_root + runner_options.metadata_root = tests_root + logger.debug('Using WPT tests (external) from %s', tests_root) + logger.debug('Using WPT tools from %s', tools_root) + + runner_options.run_info = tmp_dir + # The filename must be `mozinfo.json` for wptrunner to read it from the + # `--run-info` directory. + self._create_extra_run_info(self.fs.join(tmp_dir, 'mozinfo.json'), + tests_root) self.port.setup_test_run() # Start Xvfb, if necessary. stack.callback(self.port.clean_up_test_run) - self.fs.chdir(self.path_finder.web_tests_dir()) + self.fs.chdir(self.port.web_tests_dir()) run = _load_entry_point(tools_root) - stack.enter_context(self.process_and_upload_results(options)) - exit_code = run(**vars(options)) + stack.enter_context( + self.process_and_upload_results(runner_options)) + + exit_code = run(**vars(runner_options)) return exit_code - def _make_product(self, options: argparse.Namespace) -> 'Product': - product_cls = self._product_registry[options.product] - return product_cls(self.host, options, self.port.python3_command()) def _checkout_3h_epoch_commit(self, tools_root: str): wpt_executable = self.fs.join(tools_root, 'wpt') @@ -508,7 +445,7 @@ self.host.executive.run_command(['git', 'checkout', commit], cwd=tools_root) - def _create_extra_run_info(self, options: argparse.Namespace): + def _create_extra_run_info(self, run_info_path, tests_root): run_info = { # This property should always be a string so that the metadata # updater works, even when wptrunner is not running a flag-specific @@ -516,272 +453,44 @@ 'os': self.port.operating_system(), 'port': self.port.version(), 'debug': self.port.get_option('configuration') == 'Debug', - 'flag_specific': options.flag_specific or '', - 'used_upstream': options.use_upstream_wpt, - 'sanitizer_enabled': options.sanitizer_enabled, + 'flag_specific': self.port.flag_specific_config_name() or '', + 'used_upstream': self.options.use_upstream_wpt, + 'sanitizer_enabled': self.options.enable_sanitizer, } - if options.use_upstream_wpt: + if self.options.use_upstream_wpt: # `run_wpt_tests` does not run in the upstream checkout's git # context, so wptrunner cannot infer the latest revision. Manually # add the revision here. run_info['revision'] = self.host.git( - path=options.tests_root).current_revision() - # The filename must be `mozinfo.json` for wptrunner to read it from the - # `--run-info` directory. - run_info_path = self.fs.join(options.run_info, 'mozinfo.json') + path=tests_root).current_revision() + with self.fs.open_text_file_for_writing(run_info_path) as file_handle: json.dump(run_info, file_handle) @contextlib.contextmanager def process_and_upload_results(self, options): artifacts_dir = self.port.artifacts_directory() - processor = WPTResultsProcessor(self.host.filesystem, + processor = WPTResultsProcessor(self.fs, self.port, artifacts_dir=artifacts_dir) with processor.stream_results() as events: options.log.add_handler(events.put) yield - if options.log_wptreport: - processor.process_wpt_report(options.log_wptreport[0].name) - if options.log_chromium: - processor.process_results_json(options.log_chromium[0].name) - if options.show_results and processor.has_regressions: + + processor.process_wpt_report(options.log_wptreport[0].name) + + processor.process_results_json(options.log_chromium[0].name) + + if self.port.get_option('show_results') and processor.has_regressions: self.port.show_results_html_file( self.fs.join(artifacts_dir, 'results.html')) - def add_configuration_arguments(self, parser: argparse.ArgumentParser): - group = parser.add_argument_group('Configuration') - group.add_argument('-t', - '--target', - default='Release', - help='Target build subdirectory under //out') - group.add_argument( - '-p', - '--product', - default='content_shell', - choices=sorted(self._product_registry, key=len), - help='Product (browser or browser component) to test.') - group.add_argument('--headless', - action='store_true', - default=True, - help=argparse.SUPPRESS) - group.add_argument('--webdriver-binary', - type=os.path.abspath, - help=('Path of the webdriver binary.' - 'It needs to have the same major version ' - 'as the browser binary or APK.')) - group.add_argument( - '--use-upstream-wpt', - action='store_true', - help=('Use tests and tools from the main branch of the WPT GitHub ' - 'repo instead of chromium/src. The repo will be cloned to ' - 'a temporary directory.')) - group.add_argument( - '--flag-specific', - choices=sorted(self.port.flag_specific_configs()), - metavar='CONFIG', - help=('The name of a flag-specific suite to run. ' - 'See "web_tests/FlagSpecificConfig" for the full list.')) - return group - - def add_debugging_arguments(self, parser: argparse.ArgumentParser): - group = parser.add_argument_group('Debugging') - group.add_argument('--repeat', - '--gtest_repeat', - '--isolated-script-test-repeat', - type=lambda value: max(1, int(value)), - default=1, - help=('Number of times to run the tests, ' - 'restarting between each run.')) - group.add_argument( - '--retry-unexpected', - '--test-launcher-retry-limit', - '--isolated-script-test-launcher-retry-limit', - metavar='RETRIES', - type=lambda value: max(0, int(value)), - default=3, - help=('Maximum number of times to rerun unexpectedly failed ' - 'tests. Defaults to 3.')) - group.add_argument('--no-show-results', - dest='show_results', - action='store_false', - default=self.host.platform.interactive, - help=("Don't launch a browser with results after" - "the tests are done")) - group.add_argument('--enable-leak-detection', - action='append_const', - dest='binary_args', - const='--enable-leak-detection', - help='Enable the leak detection of DOM objects.') - return group - - def add_binary_arguments(self, parser): - group = parser.add_argument_group( - 'Chrome-specific', - 'Options for configuring the binary under test.') - group.add_argument( - '--enable-features', - metavar='FEATURES', - action='append', - dest='binary_args', - type=lambda feature: '--enable-features=%s' % feature, - help='Chromium features to enable during testing.') - group.add_argument( - '--disable-features', - metavar='FEATURES', - action='append', - dest='binary_args', - type=lambda feature: '--disable-features=%s' % feature, - help='Chromium features to disable during testing.') - group.add_argument( - '--force-fieldtrials', - metavar='TRIALS', - action='append', - dest='binary_args', - type=lambda feature: '--force-fieldtrials=%s' % feature, - help='Force trials for Chromium features.') - group.add_argument( - '--force-fieldtrial-params', - metavar='TRIAL_PARAMS', - action='append', - dest='binary_args', - type=lambda feature: '--force-fieldtrial-params=%s' % feature, - help='Force trial params for Chromium features.') - return group - - def add_test_arguments(self, parser): - group = parser.add_argument_group( - 'Test Selection', 'Options for selecting tests to run.') - # `--gtest_filter` and `--isolated-script-test-filter` have slightly - # different formats and behavior, so keep them as separate options. - # See: crbug/1316164#c4 - group.add_argument( - '--test-filter', - '--gtest_filter', - metavar='<test1>:...', - dest='include', - action='extend', - type=self._parse_gtest_filter, - help='Colon-separated list of test names or directories.') - group.add_argument( - '--isolated-script-test-filter', - metavar='<glob1>::...', - action=functools.partial(IsolatedScriptTestFilterAction, - finder=self.path_finder), - help=('An isolated script-style pattern for selecting tests. ' - 'The pattern consists of globs separated by double-colons ' - "'::'. A glob prefixed by '-' will exclude tests that match " - 'instead of including them.')) - group.add_argument('--no-wpt-internal', - action='store_false', - dest='run_wpt_internal', - help='Do not run internal WPTs.') - return group - def _parse_gtest_filter(self, value: str) -> List[str]: return [ self.path_finder.strip_wpt_path(test_id) for test_id in value.split(':') ] - def add_output_arguments(self, parser): - group = parser.add_argument_group( - 'Output Logging', 'Options for controlling logging behavior.') - group.add_argument('--results-directory', - help='Location of test results'), - # For the overridden '--log-*' options, the value will be `None` if no - # report should be logged, or the empty string if a default filename - # should be derived. - group.add_argument( - '--log-chromium', - '--isolated-script-test-output', - nargs='?', - const='', - help=('Log results in the legacy Chromium JSON results format. ' - 'See https://chromium.googlesource.com/chromium/src/+/HEAD/' - 'docs/testing/json_test_results_format.md')) - group.add_argument( - '--log-wptreport', - nargs='?', - const='', - help=('Log a wptreport as newline-delimited JSON objects ' - '(default: //out/<target>/' - 'wpt_reports_<product>_<shard-index>.json)')) - group.add_argument('--clobber-old-results', - action='store_true', - help='Clobbers test results from previous runs.'), - group.add_argument('-v', - '--verbose', - action='count', - default=0, - help='Increase verbosity') - # Install customized versions of `mozlog` formatters. - for name, formatter in [ - ('grouped', GroupingFormatter), - ('mach', MachFormatter), - ]: - mozlog.commandline.log_formatters[name] = ( - formatter, - mozlog.commandline.log_formatters[name][1], - ) - return group - - def add_android_arguments(self, parser): - group = parser.add_argument_group( - 'Android specific arguments', - 'Options for configuring Android devices and tooling.') - common.add_emulator_args(group) - group.add_argument('--browser-apk', - type=os.path.abspath, - help=('Path to the browser APK to install and run. ' - '(For WebView, this value is the shell.)')) - group.add_argument('--webview-provider', - type=os.path.abspath, - help=('Path to a WebView provider APK to install. ' - '(WebView only.)')) - group.add_argument('--no-install', - action='store_true', - help=('Do not install packages to device. ' - 'Use the packages preinstalled instead.')) - return group - - def add_ios_arguments(self, parser): - group = parser.add_argument_group( - 'iOS specific arguments', 'Options for configuring iOS tooling.') - group.add_argument( - '--xcode-build-version', - help='Xcode build version to install. Use chrome_ios' - ' product to enable this', - metavar='build_id') - return group - - -class IsolatedScriptTestFilterAction(argparse.Action): - def __init__(self, finder, *args, **kwargs): - self._finder = finder - super().__init__(*args, **kwargs) - - def __call__(self, parser, namespace, values, option_string=None): - include = getattr(namespace, 'include') or [] - exclude = getattr(namespace, 'exclude') or [] - if isinstance(values, str): - values = [values] - if isinstance(values, list): - for test_filter in values: - extra_include, extra_exclude = self._resolve_tests(test_filter) - include.extend(extra_include) - exclude.extend(extra_exclude) - namespace.include, namespace.exclude = include, exclude - # The `chromium_tests` recipe passes `--isolated-script-test-filter` to - # retry failed tests without the patch. Because the patch may have added - # the failed tests (common for imported tests), - # 1. `run_wpt_tests.py --isolated-script-test-filter` must tolerate - # test IDs that don't exist. - # 2. When all tests retried don't exist without the patch, wptrunner - # must run zero tests and exit successfully instead of interpreting - # the lack of explicit tests as running all tests. - namespace.default_exclude = True - def _resolve_tests(self, test_filter: str) -> Tuple[List[str], List[str]]: """Resolve an isolated script-style filter string into lists of tests. @@ -799,17 +508,30 @@ test_group = included_tests if pattern.startswith('-'): test_group, pattern = excluded_tests, pattern[1:] - if self._finder.is_wpt_internal_path(pattern): - pattern_on_disk = self._finder.path_from_web_tests(pattern) + if self.port._path_finder.is_wpt_internal_path(pattern): + pattern_on_disk = self.port._path_finder.path_from_web_tests( + pattern) else: - pattern_on_disk = self._finder.path_from_wpt_tests(pattern) + pattern_on_disk = self.port._path_finder.path_from_wpt_tests( + pattern) test_group.extend(glob.glob(pattern_on_disk)) + return included_tests, excluded_tests + def _parse_isolated_script_test_filter(self, values): + include, exclude = [], [] + if isinstance(values, str): + values = [values] + if isinstance(values, list): + for test_filter in values: + extra_include, extra_exclude = self._resolve_tests(test_filter) + include.extend(extra_include) + exclude.extend(extra_exclude) + return include, exclude + def _has_explicit_tests(options: argparse.Namespace) -> bool: - return (options.include or options.exclude or options.include_file - or options.test_list) + return (options.include or options.exclude or options.include_file) def _load_entry_point(tools_root: str): @@ -844,6 +566,12 @@ return functools.partial(run.run, dummy_venv) +def make_product(port, options) -> 'Product': + name = options.product + product_cls = make_product_registry()[name] + return product_cls(port, options) + + def make_product_registry(): """Create a mapping from all product names (including aliases) to their respective classes. @@ -866,32 +594,25 @@ name = '' aliases = [] - def __init__(self, host, options, python_executable=None): - self._host = host - self._path_finder = PathFinder(self._host.filesystem) + def __init__(self, port, options): + self._port = port + self._host = port.host self._options = options - self._python_executable = python_executable self._tasks = contextlib.ExitStack() - def _path_from_target(self, *components): - return self._path_finder.path_from_chromium_base( - 'out', self._options.target, *components) - @contextlib.contextmanager def test_env(self): """Set up and clean up the test environment.""" with self._tasks: yield - def update_options_for_product(self, options): - """Override product-specific wptrunner parameters.""" - self._ensure_value(options, 'browser_version', self.get_version()) - self._ensure_value(options, 'webdriver_binary', - self.default_webdriver_binary) + def product_specific_options(self): + """Product-specific wptrunner parameters needed to run tests.""" + return {} - def _ensure_value(self, options, name, value): - if not getattr(options, name, None) and value is not None: - setattr(options, name, value) + def additional_webdriver_args(self): + """Additional webdriver parameters for the product""" + return [] def get_version(self): """Get the product version, if available.""" @@ -902,23 +623,22 @@ """Path to the default webdriver binary, if available.""" return None - -class DesktopBase(Product): @property def default_binary(self): return None - def update_options_for_product(self, options): - super().update_options_for_product(options) - self._ensure_value(options, 'binary', self.default_binary) - port = self._host.port_factory.get() - self._ensure_value(options, 'processes', - port.default_child_processes()) - -class Chrome(DesktopBase): +class Chrome(Product): name = 'chrome' + def product_specific_options(self): + """Product-specific wptrunner parameters needed to run tests.""" + return { + 'binary': self.default_binary, + 'webdriver_binary': self.default_webdriver_binary, + 'processes': self._port.default_child_processes() + } + @property def default_binary(self): binary_path = 'chrome' @@ -928,7 +648,7 @@ binary_path = self._host.filesystem.join('Chromium.app', 'Contents', 'MacOS', 'Chromium') - return self._path_from_target(binary_path) + return self._port._build_path(binary_path) @property def default_webdriver_binary(self): @@ -936,12 +656,19 @@ path = 'chromedriver.exe' else: path = 'chromedriver' #linux and mac - return self._path_from_target(path) + return self._port._build_path(path) -class ContentShell(DesktopBase): +class ContentShell(Product): name = 'content_shell' + def product_specific_options(self): + """Product-specific wptrunner parameters needed to run tests.""" + return { + 'binary': self.default_binary, + 'processes': self._port.default_child_processes() + } + @property def default_binary(self): binary_path = 'content_shell' @@ -951,35 +678,42 @@ binary_path = self._host.filesystem.join('Content Shell.app', 'Contents', 'MacOS', 'Content Shell') - return self._path_from_target(binary_path) + return self._port._build_path(binary_path) class ChromeiOS(Product): name = 'chrome_ios' + def __init__(self, port, options): + super().__init__(port, options) + self.xcode_build_version = options.xcode_build_version + + def product_specific_options(self): + """Product-specific wptrunner parameters needed to run tests.""" + return {'webdriver_binary': self.default_webdriver_binary} + @property - def default_webdriver_binary(self) -> Optional[str]: - return self._path_finder.path_from_chromium_base( + def default_webdriver_binary(self) -> str: + return self._port._path_finder.path_from_chromium_base( 'ios', 'chrome', 'test', 'wpt', 'tools', 'run_cwt_chromedriver_wrapper.py') + def additional_webdriver_args(self): + # Set up xcode log output dir. + output_dir = self._host.filesystem.join( + self._port.artifacts_directory(), "xcode-output") + return ['--out-dir=' + output_dir, '--os=16.0'] + @contextlib.contextmanager def test_env(self): with super().test_env(): - # Set up xcode log output dir. - output_dir = self._host.filesystem.join( - self._host.filesystem.dirname( - self._options.log_chromium[0].name), "xcode-output") - self._options.webdriver_args.extend([ - '--out-dir=' + output_dir, - ]) - # Install xcode. - if self._options.xcode_build_version: + if self.xcode_build_version: try: runtime_cache_folder = xcode.construct_runtime_cache_folder( '../../Runtime-ios-', '16.0') - os.makedirs(runtime_cache_folder, exist_ok=True) + self._host.filesystem.maybe_make_directory( + runtime_cache_folder) xcode.install('../../mac_toolchain', self._options.xcode_build_version, '../../Xcode.app', @@ -989,11 +723,11 @@ except subprocess.CalledProcessError as e: logger.error( 'Xcode build version %s failed to install: %s ', - self._options.xcode_build_version, e) + self.xcode_build_version, e) else: logger.info( 'Xcode build version %s successfully installed.', - self._options.xcode_build_version) + self.xcode_build_version) else: logger.warning('Skip the Xcode installation, no ' '--xcode-build-version') @@ -1001,10 +735,13 @@ class ChromeAndroidBase(Product): - def __init__(self, host, options, python_executable=None): - super().__init__(host, options, python_executable) - self.browser_apk = options.browser_apk or self.default_browser_apk - self.no_install = options.no_install + def __init__(self, port, options): + super().__init__(port, options) + if options.browser_apk: + self.browser_apk = options.browser_apk + else: + self.browser_apk = self.default_browser_apk + self.adb_binary = devil_env.config.FetchPath('adb') self.devices = [] @contextlib.contextmanager @@ -1017,28 +754,54 @@ device.Uninstall(path) @contextlib.contextmanager + def get_devices(self): + if not _ANDROID_ENABLED: + raise Exception('Android is not available') + instances = [] + try: + if self._options.avd_config: + logger.info( + f'Installing emulator from {self._options.avd_config}') + config = avd.AvdConfig(self._options.avd_config) + config.Install() + + # use '--child-processes' to decide how many emulators to launch + for _ in range(max(self._options.child_processes or 1, 1)): + instance = config.CreateInstance() + instances.append(instance) + + SyncParallelizer(instances).Start( + writable_system=True, + window=self._options.emulator_window, + require_fast_start=True) + + #TODO(weizhong): when choose device, make sure abi matches with target + yield device_utils.DeviceUtils.HealthyDevices() + finally: + SyncParallelizer(instances).Stop() + + @contextlib.contextmanager def test_env(self): with super().test_env(): - self.adb_binary = devil_env.config.FetchPath('adb') devil_chromium.Initialize(adb_path=self.adb_binary) - self.devices = self._tasks.enter_context(get_devices( - self._options)) + self.devices = self._tasks.enter_context(self.get_devices()) if not self.devices: raise Exception('No devices attached to this host. ' "Make sure to provide '--avd-config' " 'if using only emulators.') - if not self.no_install: + if not self._options.no_install: self.provision_devices() yield - def update_options_for_product(self, options): - super().update_options_for_product(options) - self._ensure_value(options, 'adb_binary', self.adb_binary) - self._ensure_value(options, 'device_serial', - [device.serial for device in self.devices]) - self._ensure_value(options, 'package_name', - self.get_browser_package_name()) + def product_specific_options(self): + return { + 'adb_binary': self.adb_binary, + 'device_serial': [device.serial for device in self.devices], + 'package_name': self.get_browser_package_name(), + 'browser_version': self.get_version(), + 'webdriver_binary': self.default_webdriver_binary + } def get_version(self): version_provider = self.get_version_provider_package_name() @@ -1058,7 +821,7 @@ @property def default_webdriver_binary(self): - return self._path_from_target('clang_x64', 'chromedriver') + return self._port._build_path('clang_x64', 'chromedriver') def get_browser_package_name(self): """Get the name of the package to run tests against. @@ -1118,17 +881,20 @@ name = 'android_webview' aliases = ['webview'] - def __init__(self, host, options, python_executable=None): - super().__init__(host, options, python_executable) - self.webview_provider = options.webview_provider or self.default_webview_provider + def __init__(self, port, options): + super().__init__(port, options) + if options.webview_provider: + self.webview_provider = options.webview_provider + else: + self.webview_provider = self.default_webview_provider @property def default_browser_apk(self): - return self._path_from_target('apks', 'SystemWebViewShell.apk') + return self._port._build_path('apks', 'SystemWebViewShell.apk') @property def default_webview_provider(self): - return self._path_from_target('apks', 'SystemWebView.apk') + return self._port._build_path('apks', 'SystemWebView.apk') def _install_webview(self, device): # Prioritize local builds. @@ -1139,14 +905,11 @@ or 'org.chromium.webview_shell') def get_version_provider_package_name(self): - # Prioritize using the webview provider, not the shell, since the + # Use the version from the webview provider, not the shell, since the # provider is distributed to end users. The shell is developer-facing, # so its version is usually not actively updated. - if self._options.webview_provider: - with contextlib.suppress(apk_helper.ApkHelperError): - return apk_helper.GetPackageName( - self._options.webview_provider) - return super().get_version_provider_package_name() + with contextlib.suppress(apk_helper.ApkHelperError): + return apk_helper.GetPackageName(self.webview_provider) @contextlib.contextmanager def _provision_device(self, device): @@ -1160,40 +923,7 @@ @property def default_browser_apk(self): - return self._path_from_target('apks', 'ChromePublic.apk') - - -@contextlib.contextmanager -def get_devices(args): - if not _ANDROID_ENABLED: - raise Exception('Android is not available') - instances = [] - try: - if args.avd_config: - avd_config = avd.AvdConfig(args.avd_config) - logger.warning('Installing emulator from %s', args.avd_config) - avd_config.Install() - - for _ in range(max(args.processes or 1, 1)): - instance = avd_config.CreateInstance() - instances.append(instance) - - SyncParallelizer(instances).Start(writable_system=True, - window=args.emulator_window, - require_fast_start=True) - - #TODO(weizhong): when choose device, make sure abi matches with target - yield device_utils.DeviceUtils.HealthyDevices() - finally: - SyncParallelizer(instances).Stop() - - -def _parse_environ_int(name: str) -> Optional[int]: - value = os.environ.get(name) - with contextlib.suppress(ValueError): - if value is not None: - return int(value) - return None + return self._port._build_path('apks', 'ChromePublic.apk') def handle_interrupt_signals(): @@ -1206,25 +936,59 @@ signal.signal(signal.SIGTERM, termination_handler) -def main() -> int: +def parse_arguments(argv): + parser = argparse.ArgumentParser( + usage='%(prog)s [options] [tests]', + description= + 'Runs Blink wpt tests as described in //docs/testing/web_platform_tests_wptrunner.md' + ) + factory.add_configuration_options_group(parser, + rwt=False, + product_choices=list( + make_product_registry())) + factory.add_logging_options_group(parser) + factory.add_results_options_group(parser, rwt=False) + factory.add_testing_options_group(parser, rwt=False) + factory.add_android_options_group(parser) + factory.add_ios_options_group(parser) + + parser.add_argument('tests', + nargs='*', + help='Paths to test files or directories to run') + params = vars(parser.parse_args(argv)) + args = params.pop('tests') + options = optparse.Values(params) + return (options, args) + + +def main(argv) -> int: # Force log output in utf-8 instead of a locale-dependent encoding. On # Windows, this can be cp1252. See: crbug.com/1371195. if sys.version_info[:2] >= (3, 7): sys.stdout.reconfigure(encoding='utf-8') sys.stderr.reconfigure(encoding='utf-8') + # Also apply utf-8 mode to python subprocesses. os.environ['PYTHONUTF8'] = '1' + # Convert SIGTERM to be handled as KeyboardInterrupt to handle early termination # Same handle is declared later on in wptrunner # See: https://github.com/web-platform-tests/wpt/blob/25cd6eb086db5977ac51f7dee7faafe6772dc9d7/tools/wptrunner/wptrunner/wptrunner.py # This early declaration allow graceful exit when Chromium swarming kill process before wpt starts handle_interrupt_signals() + try: - adapter = WPTAdapter() - options = adapter.parse_arguments() - logger.info('Selecting tests for shard %d/%d', options.this_chunk, - options.total_chunks) - return adapter.run_tests(options) + host = Host() + options, args = parse_arguments(argv) + port = host.port_factory.get(None, options) + product = make_product(port, options) + adapter = WPTAdapter(product, port, options, args) + except (NotImplementedError, ValueError) as error: + logger.error(error) + return exit_codes.UNEXPECTED_ERROR_EXIT_STATUS + + try: + return adapter.run_tests() except KeyboardInterrupt: logger.critical("Harness exited after signal interrupt") return exit_codes.INTERRUPTED_EXIT_STATUS @@ -1232,4 +996,4 @@ if __name__ == '__main__': multiprocessing.set_start_method('spawn') - sys.exit(main()) + sys.exit(main(sys.argv[1:]))
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index 35eb87c..c2a93cdf 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -5043,15 +5043,7 @@ crbug.com/1223601 [ Linux ] fast/scrolling/reset-scroll-in-onscroll.html [ Failure Pass ] # Sheriff 2021-06-29 -# Flaky on Mac11 Tests -crbug.com/1197464 [ Debug Mac ] plugins/refcount-leaks.html [ Failure Pass ] -crbug.com/1197464 [ Mac10.13 Release ] plugins/refcount-leaks.html [ Failure Pass ] -crbug.com/1197464 [ Mac10.14 Release ] plugins/refcount-leaks.html [ Failure Pass ] -crbug.com/1197464 [ Mac10.15 Release ] plugins/refcount-leaks.html [ Failure Pass ] -crbug.com/1197464 [ Mac11 Release ] plugins/refcount-leaks.html [ Failure Pass ] -crbug.com/1197464 [ Mac11-arm64 Release ] plugins/refcount-leaks.html [ Failure Pass ] -crbug.com/1197464 [ Mac12 Release ] plugins/refcount-leaks.html [ Failure Pass ] -crbug.com/1197464 [ Mac12-arm64 Release ] plugins/refcount-leaks.html [ Failure Pass ] +crbug.com/1197464 [ Mac ] plugins/refcount-leaks.html [ Failure Pass ] # Sheriff 2021-07-12 crbug.com/1228432 [ Linux ] external/wpt/video-rvfc/request-video-frame-callback-before-xr-session.https.html [ Pass Timeout ] @@ -5978,6 +5970,10 @@ crbug.com/1279220 [ Win10.20h2 ] virtual/percent-based-scrolling/fast/scrolling/scrollbars/touch-scrolling-on-root-scrollbar.html [ Pass Timeout ] crbug.com/1279220 [ Linux ] fast/scrolling/non-composited-scroller-in-position-fixed-scroller.html [ Failure Pass ] +# Temporarily disable to land DevTools changes +crbug.com/1393057 http/tests/devtools/security/interstitial-sidebar.js [ Failure Pass ] +crbug.com/1393057 http/tests/devtools/security/mixed-content-sidebar.js [ Failure Pass ] + # Sheriff 2022-10-12 crbug.com/1280883 [ Debug Mac12 ] virtual/compositor-threaded-percent-based-scrolling-dsf-2/virtual/percent-based-scrolling/max-percent-delta.html [ Failure Pass ] @@ -6796,6 +6792,69 @@ crbug.com/1449995 [ Mac12 ] virtual/text-antialias/justify-ideograph-vertical.html [ Failure Pass ] crbug.com/1449995 [ Mac12 ] virtual/text-antialias/trailing-white-space-2.html [ Failure Pass ] crbug.com/1449995 [ Mac12 ] virtual/text-antialias/firstline/001.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/font-features/caps-native-synthesis.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/font-initial.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/font-stretch.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/font-weight.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/in-rendered-text-rtl.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/international/bidi-LDB-2-formatting-characters.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/international/bidi-neutral-directionality-paragraph-start.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/international/plane2.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/international/text-combine-image-test.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/international/vertical-text-glyph-test.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/international/lang-glyph-cache-separation.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/justify-ideograph-simple.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/midword-break-after-breakable-char.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/selection/atsui-kerning-and-ligatures.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/selection/selection-hard-linebreak.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/selection/should-use-atsui.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/trailing-white-space.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/whitespace/pre-wrap-last-char.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/justify-ideograph-vertical.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/trailing-white-space-2.html [ Failure Pass ] +crbug.com/1449995 [ Mac12-arm64 ] virtual/text-antialias/firstline/001.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/font-features/caps-native-synthesis.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/font-initial.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/font-stretch.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/font-weight.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/in-rendered-text-rtl.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/international/bidi-LDB-2-formatting-characters.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/international/bidi-neutral-directionality-paragraph-start.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/international/plane2.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/international/text-combine-image-test.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/international/vertical-text-glyph-test.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/international/lang-glyph-cache-separation.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/justify-ideograph-simple.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/midword-break-after-breakable-char.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/selection/atsui-kerning-and-ligatures.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/selection/selection-hard-linebreak.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/selection/should-use-atsui.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/trailing-white-space.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/whitespace/pre-wrap-last-char.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/justify-ideograph-vertical.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/trailing-white-space-2.html [ Failure Pass ] +crbug.com/1449995 [ Mac13 ] virtual/text-antialias/firstline/001.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/font-features/caps-native-synthesis.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/font-initial.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/font-stretch.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/font-weight.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/in-rendered-text-rtl.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/international/bidi-LDB-2-formatting-characters.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/international/bidi-neutral-directionality-paragraph-start.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/international/plane2.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/international/text-combine-image-test.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/international/vertical-text-glyph-test.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/international/lang-glyph-cache-separation.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/justify-ideograph-simple.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/midword-break-after-breakable-char.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/selection/atsui-kerning-and-ligatures.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/selection/selection-hard-linebreak.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/selection/should-use-atsui.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/trailing-white-space.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/whitespace/pre-wrap-last-char.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/justify-ideograph-vertical.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/trailing-white-space-2.html [ Failure Pass ] +crbug.com/1449995 [ Mac13-arm64 ] virtual/text-antialias/firstline/001.html [ Failure Pass ] crbug.com/1448011 http/tests/devtools/application-panel/resources-panel-iframe-idb.js [ Failure Pass ] @@ -6814,3 +6873,10 @@ # Sheriff 2023-05-30 crbug.com/1450020 [ Mac ] compositing/geometry/preserve-3d-switching.html [ Failure Pass ] + +crbug.com/1406017 http/tests/devtools/cache-storage/cache-data.js [ Failure Pass Timeout ] +crbug.com/1406017 http/tests/devtools/cache-storage/cache-deletion.js [ Failure Pass Timeout ] +crbug.com/1406017 http/tests/devtools/cache-storage/cache-entry-deletion.js [ Failure Pass Timeout ] +crbug.com/1406017 http/tests/devtools/cache-storage/cache-live-update-cache-content.js [ Failure Pass Timeout ] +crbug.com/1406017 http/tests/devtools/cache-storage/cache-names.js [ Failure Pass Timeout ] +
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 0a93349..54fb1d0d 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -19,29 +19,18 @@ " to expire. Tests will not be run starting from the expiration date. ", { - "prefix": "anonymous-iframe-origin-trial", - "platforms": ["Linux", "Mac", "Win", "Fuchsia"], - "bases": ["wpt_internal/origin_trials/anonymous-iframe"], - "args": [ - "--disable-blink-features=AnonymousIframe", - "--disable-features=PartitionedCookies,ThirdPartyStoragePartitioning", - "--enable-features=AnonymousIframeOriginTrial" - ], - "expires": "Jul 1, 2023" - }, - { "prefix": "lna-permission", "platforms": ["Linux", "Mac", "Win"], "bases": ["external/wpt/fetch/local-network-access"], "args": ["--enable-features=PrivateNetworkAccessPermissionPrompt"], - "expires": "Jul 1, 2023" + "expires": "Jan 1, 2024" }, { "prefix": "lna-workers-disabled", "platforms": ["Linux", "Mac", "Win"], "bases": ["external/wpt/fetch/local-network-access"], "args": ["--disable-features=PrivateNetworkAccessForWorkers"], - "expires": "Jul 1, 2023" + "expires": "Jan 1, 2024" }, { "prefix": "lna-workers-enabled", @@ -51,7 +40,7 @@ "--enable-features=PrivateNetworkAccessForWorkers", "--disable-features=PrivateNetworkAccessForWorkersWarningOnly" ], - "expires": "Jul 1, 2023" + "expires": "Jan 1, 2024" }, { "prefix": "reduce-accept-language", @@ -582,7 +571,7 @@ "inspector-protocol/worker" ], "args": ["--enable-features=PlzDedicatedWorker"], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { "prefix": "service-worker-storage-control-on-thread-pool", @@ -722,7 +711,7 @@ "args": ["--disable-auto-wpt-origin-isolation", "--reset-browsing-instance-between-tests", "--disable-features=OriginAgentClusterDefaultEnable"], - "expires": "Jul 1, 2023" + "expires": "never" }, { "prefix": "focusless-spat-nav", @@ -958,7 +947,7 @@ "bases": ["external/wpt/fetch/http-cache"], "exclusive_tests": "ALL", "args": ["--enable-features=SplitCacheByIncludeCredentials"], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { "prefix": "split-http-cache", @@ -1650,7 +1639,7 @@ "--disable-features=OriginAgentClusterDefaultEnable", "--disable-auto-wpt-origin-isolation" ], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { @@ -1718,14 +1707,14 @@ "platforms": ["Linux", "Mac", "Win"], "bases": [ "external/wpt/html/infrastructure/urls/terminology-0/" ], "args": [ "--enable-features=IsolateSandboxedIframes" ], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { "prefix": "coop-restrict-properties", "platforms": ["Linux", "Mac", "Win"], "bases": [ "external/wpt/html/cross-origin-opener-policy/tentative/restrict-properties" ], "args": [ "--enable-features=CoopRestrictProperties" ], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, "These tests require the experimental speculative prefetch feature, and", @@ -1820,7 +1809,7 @@ "external/wpt/fetch/nosniff" ], "args": ["--enable-features=OpaqueResponseBlockingV01"], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { "prefix": "orb-v02", @@ -1829,7 +1818,7 @@ "bases": [ "external/wpt/fetch/corb" ], - "expires": "Jul 1, 2023" + "expires": "Jul 1, 2024" }, { "prefix": "js-shared-memory", @@ -1937,7 +1926,7 @@ "fast/forms/week/week-appearance-pseudo-elements.html" ], "args": ["--disable-blink-features=DateInputInlineBlock"], - "expires": "Jun 1, 2023" + "expires": "Jun 8, 2023" }, { "prefix": "allow-rtc-encoded-video-frame-set-metadata-all-fields",
diff --git a/third_party/blink/web_tests/editing/selection/caret-at-bidi-boundary.html b/third_party/blink/web_tests/editing/selection/caret-at-bidi-boundary.html index 11dec260..72fa9f62 100644 --- a/third_party/blink/web_tests/editing/selection/caret-at-bidi-boundary.html +++ b/third_party/blink/web_tests/editing/selection/caret-at-bidi-boundary.html
@@ -60,7 +60,7 @@ var previousOffset = -1; var j = 0; - for (var x = 5; x <= target.offsetWidth - 5; x++) { + for (var x = 5; x <= target.offsetWidth - 5; x += 5) { // Reset the click count eventSender.mouseMoveTo(1, 1); eventSender.mouseDown();
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 79951a8..3b6569f 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
@@ -136336,7 +136336,7 @@ "css-highlight-api": { "painting": { "css-highlight-painting-underline-offset-001.html": [ - "14b238ce1700fc9e1fe1ea3745b0a818d5c615c1", + "534438089ca0afd4a565e615f43cd964db3a0eb6", [ null, [ @@ -136345,7 +136345,52 @@ "==" ] ], - {} + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 56 + ], + [ + 0, + 10 + ] + ] + ] + ] + } + ] + ], + "css-target-text-decoration-001.html": [ + "fa76c0bc4e7636c416ac876530f11d9a4e40050a", + [ + null, + [ + [ + "/css/css-highlight-api/painting/css-target-text-decoration-001-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 60 + ], + [ + 0, + 32 + ] + ] + ] + ] + } ] ], "custom-highlight-painting-001.html": [ @@ -137019,7 +137064,38 @@ ], {} ] - ] + ], + "invalidation": { + "css-highlight-invalidation-001.html": [ + "d885424765d3934eb2187d78a2f0791158441c8b", + [ + null, + [ + [ + "/css/css-highlight-api/painting/invalidation/css-highlight-invalidation-001-ref.html", + "==" + ] + ], + { + "fuzzy": [ + [ + null, + [ + [ + 0, + 56 + ], + [ + 0, + 10 + ] + ] + ] + ] + } + ] + ] + } } }, "css-images": { @@ -265561,6 +265637,19 @@ }, "scroll-animations": { "css": { + "animation-inactive-outside-range-test.html": [ + "c0021a1fbc2cf9c7b25305120a3e1d64aa4a13c4", + [ + null, + [ + [ + "/scroll-animations/css/animation-inactive-outside-range-ref.html", + "==" + ] + ], + {} + ] + ], "animation-range-visual-test.html": [ "f675f5108aec2ef2eb27793efca6e7e6a88f3324", [ @@ -308695,8 +308784,8 @@ "3d01bccf55dd9c20e361551bc924d5c9353c503e", [] ], - "css-highlight-painting-underline-offset-001.html.ini": [ - "d896e9be56260e2279d1a49c63df8d3c1b3ae586", + "css-target-text-decoration-001-ref.html": [ + "5e9ef64579800a922d225ab9ca458555fe067dcc", [] ], "custom-highlight-painting-001-ref.html": [ @@ -308803,6 +308892,12 @@ "3a713aa8440c5877253ce9f612f2c90515f9dd60", [] ], + "invalidation": { + "css-highlight-invalidation-001-ref.html": [ + "a5ec6a59ae0be99bfcefeca724445544bd6228f8", + [] + ] + }, "resources": { "iframe-code.html": [ "a4a1829be229acb4c0cf75cbb0e2885060741d3f", @@ -311763,10 +311858,6 @@ "bca9838edabd20e3a6c9b98a69d563c440e99146", [] ], - "clip-path-composition-expected.txt": [ - "c76588444a2deddcdd2219882830abeda7ebba11", - [] - ], "clip-path-composition.html.ini": [ "63fd6cb46bcc10fd8e58c38d5ab10dfccc4d798f", [] @@ -312287,10 +312378,6 @@ "21bb32713d08c06bc9eae692ad5fe5b4fb34ca41", [] ], - "interpolation-expected.txt": [ - "4f0218d613ce911ce46e2be2433c3f84c0369282", - [] - ], "interpolation.html.ini": [ "1686045ef7f0d5d67fbf05d0995730194b23d751", [] @@ -313194,7 +313281,7 @@ [] ], "clip-path-valid-expected.txt": [ - "c00ad998536c7f5224e9140f94cbd7bd6a59e069", + "d7f4dc810f36f3a815a21ccb5f7df2780ccac9ac", [] ], "clip-path-valid.html.ini": [ @@ -318223,10 +318310,6 @@ [] ], "animation": { - "shape-outside-composition-expected.txt": [ - "7a02a8306e2916e23ea5d888fdad221f9faf0d34", - [] - ], "shape-outside-composition.html.ini": [ "f5b9906d2a34c9477caa8b6bcd28b44e072fe355", [] @@ -318236,18 +318319,10 @@ [] ] }, - "basic-shape-circle-ellipse-serialization-expected.txt": [ - "8c2294cd11b366d5e88b3a64f0984f8f9b81fcf4", - [] - ], "basic-shape-circle-ellipse-serialization.html.ini": [ "bf9694aa1fd487ea9cc4321672f48647b014b3f4", [] ], - "basic-shape-interpolation-expected.txt": [ - "ae91524d1773a43e3c4179686cadb667b6efd3e4", - [] - ], "basic-shape-interpolation.html.ini": [ "93eb6d16258433d658c347e483fd7458a91d7939", [] @@ -318262,7 +318337,7 @@ [] ], "shape-outside-valid-expected.txt": [ - "666f1b37c4daaa050a00cace41e03ed0c292007b", + "69e88ee65db9e059e9c79691f16404e23d6cabd4", [] ], "shape-outside-valid.html.ini": [ @@ -319086,18 +319161,10 @@ "cd490849bfe3d3edcb90dd7cc0a586ee3bbae0e9", [] ], - "shape-outside-circle-000-expected.txt": [ - "830cb460a2a496c3596e0c5d6b1e55d6aaea7367", - [] - ], "shape-outside-circle-000.html.ini": [ "978a2d77acda88e78707cb06bc9d3f6627f1f6a0", [] ], - "shape-outside-circle-001-expected.txt": [ - "acde659e9b9f0419f029a0be6c52e98747cfee6f", - [] - ], "shape-outside-circle-001.html.ini": [ "93fb1e94f31a763baa3308fe68a6c6e66186bcee", [] @@ -319106,24 +319173,16 @@ "1ee78fe1865c3d9b9cf5ffdc219d9c2105604e99", [] ], - "shape-outside-circle-005-expected.txt": [ - "9bcd96e96fadecbafccf41c31b149480226e3386", - [] - ], "shape-outside-circle-005.html.ini": [ "3a52245f7472c561309c969e2418cb933416afc0", [] ], - "shape-outside-circle-006-expected.txt": [ - "839fcf2138d15f32e7a3d86dd354949eddfc958a", - [] - ], "shape-outside-circle-006.html.ini": [ "cb8668338525fa43ef62f493b57607a764715262", [] ], "shape-outside-circle-010-expected.txt": [ - "b64a71cdb0ab893d5f27397a3c1466b53b028725", + "e2abdf5e940c8a31209de57e6ca29d522a8a3093", [] ], "shape-outside-circle-010.html.ini": [ @@ -319142,18 +319201,10 @@ "bffebd1ab4f0a9e8c910d4e83843ef6d283b81e6", [] ], - "shape-outside-ellipse-000-expected.txt": [ - "a256a39bb8472adcc0551d02600f9041fd469bfd", - [] - ], "shape-outside-ellipse-000.html.ini": [ "06e9e9a8527a635b17c83c245a83df2c18e9261e", [] ], - "shape-outside-ellipse-001-expected.txt": [ - "ecd3cf20fb0b99391baaf407df63972d92cb67a8", - [] - ], "shape-outside-ellipse-001.html.ini": [ "4388a41d67e4d57e1a736ba1ed7ce90ad83017d5", [] @@ -319162,24 +319213,16 @@ "694a2e2fe93aef7105b1c517ca0375f1e89ab80a", [] ], - "shape-outside-ellipse-005-expected.txt": [ - "1696c446d48f8f4d1578dc10dffa10b642fe6fb0", - [] - ], "shape-outside-ellipse-005.html.ini": [ "f8d3c7eca05dfb301ba77db7ea6aa89a678a75a6", [] ], - "shape-outside-ellipse-006-expected.txt": [ - "ad019d39d99f5a825bd45fc3ed04915f7ed7ea0d", - [] - ], "shape-outside-ellipse-006.html.ini": [ "19f2a244dda8c2e4326ff089a6bb7c9eab8817d3", [] ], "shape-outside-ellipse-010-expected.txt": [ - "d3d48dffde5c196dcd886fcdfdbb5f40c2fa9dab", + "417d17e728319e2955dd36c7cb771b6703ca2eda", [] ], "shape-outside-ellipse-010.html.ini": [ @@ -319240,7 +319283,7 @@ ], "support": { "parsing-utils.js": [ - "b7c637746e0ef5cf48187156a462cb1b0ba588d9", + "354a64b53f538b2b1e8366b30961034e4b5d7fdd", [] ] } @@ -354120,6 +354163,10 @@ ] }, "inheritance": { + "document-write.https.window.js.headers": [ + "e007de4d7bfd8bd5a26b503f338e1da696ddb941", + [] + ], "javascript-url-expected.txt": [ "d7f8cf94ccfbfa0c951e65b2ccd6334fcdeb65ed", [] @@ -354127,7 +354174,25 @@ "javascript-url.html.ini": [ "480ab80927fb4cf7c52aa671ee1db60a737dc75a", [] - ] + ], + "resources": { + "document-write.html": [ + "7a6ff3118eb268f9ca98d794477fb968a2005db7", + [] + ], + "document-write.html.headers": [ + "e007de4d7bfd8bd5a26b503f338e1da696ddb941", + [] + ], + "iframe-with-about-blank-iframe.html": [ + "b3f51252332f8d83f1371619293ba0bcd57633ae", + [] + ], + "iframe-with-about-blank-iframe.html.headers": [ + "e007de4d7bfd8bd5a26b503f338e1da696ddb941", + [] + ] + } }, "origin-keyed-agent-clusters": { "1-iframe": { @@ -374370,7 +374435,7 @@ [] ], "turtledove.idl": [ - "8add667b57509d3ec86ff214de6ee7380721fe18", + "f5867e995a8d19efb967e4bccee0eccb011665f8", [] ], "ua-client-hints.idl": [ @@ -374530,7 +374595,7 @@ [] ], "webrtc-encoded-transform.idl": [ - "59710bf46c2e3b57f09aaacccb80eb2c48f33406", + "6dd2ba3fffa0072136dabf9826299c40d4557dc2", [] ], "webrtc-ice.idl": [ @@ -384634,6 +384699,10 @@ [] ], "css": { + "animation-inactive-outside-range-ref.html": [ + "ea3215e359084b790f460f8d4537c08d353b5aaf", + [] + ], "animation-range-visual-test-ref.html": [ "c246f7f1b0a541aa3eb3cbdd01efd57d3018d5b9", [] @@ -454752,7 +454821,7 @@ ] ], "clip-path-composition.html": [ - "2275ae70a330e06214f3c612acdba186efde99cd", + "42c5988e045d6f1d5913c403a5a98a662a565680", [ null, {} @@ -454810,7 +454879,7 @@ ] ], "interpolation.html": [ - "da3981feed6ed681ee4a7d88b7ecd167b9fd5c7b", + "f580de9c76951a977a88da4375f61bb00bd77de5", [ null, {} @@ -454907,7 +454976,7 @@ ] ], "clip-path-valid.html": [ - "895cdfacac6cc8ac56e67738aed53e55be7b2fcf", + "fd268b429163854ecc5b64db8afc06ba0209f4b3", [ null, {} @@ -459338,7 +459407,7 @@ ] ], "shape-outside-composition.html": [ - "0115148ec1adde1a32b1c1fb4b3c33ea8b56ece0", + "c1c29f1aa94880265d9d7329b16bdddcdba5146c", [ null, {} @@ -459353,14 +459422,14 @@ ] }, "basic-shape-circle-ellipse-serialization.html": [ - "5e4842d234f6af393a5ee04fa604a63f6db5cae1", + "715593d47b1330a325c6ba526f350f1bd7f2c3da", [ null, {} ] ], "basic-shape-interpolation.html": [ - "beea230697f0da8359447e6034835ba5766a9e24", + "5617ea28634e1e2f167b9e3e2c133b555ee4a8d8", [ null, {} @@ -459445,7 +459514,7 @@ ] ], "shape-outside-valid.html": [ - "c48974406b2cd18a851a62fc125ff7c6bd10a171", + "e5587c6b233a0c94568447777e95533ecbb50b29", [ null, {} @@ -459571,7 +459640,7 @@ ] ], "shape-outside-circle-000.html": [ - "a13570c1ff2ec6154c617922e65a84352c493be9", + "e2c735b3bbfe22938403eec2d13277edf14ee852", [ null, {} @@ -459613,7 +459682,7 @@ ] ], "shape-outside-circle-006.html": [ - "2fe988d626847cefd1d1a3a669cec701a2373e7a", + "15308ed9d1242331ff767bc03fa2a94ec160afab", [ null, {} @@ -459641,7 +459710,7 @@ ] ], "shape-outside-circle-010.html": [ - "6d6c11a7071569ef1bb0e71c8bdd740fd8b6a94d", + "609632e11ac9a37eaa3bd4c27f78b69cf4620dfb", [ null, {} @@ -459669,7 +459738,7 @@ ] ], "shape-outside-ellipse-000.html": [ - "532f794448cc8585dc69ee439ba576828e81f8a5", + "d74ed97a7667993932d4b3440c45bf18b1185615", [ null, {} @@ -459711,7 +459780,7 @@ ] ], "shape-outside-ellipse-006.html": [ - "4bd75a445a65d8923e0c3cd2c414bf81af192c24", + "69cd8aca78b17f88d2c3fa4bb547f2228b025dae", [ null, {} @@ -459739,7 +459808,7 @@ ] ], "shape-outside-ellipse-010.html": [ - "07cd1e593b75dac5054e08e82d3cd1885a883277", + "430d2621baff6b8f1381a988b2b04cde5c4f281e", [ null, {} @@ -520766,6 +520835,20 @@ {} ] ], + "document-write.https.window.js": [ + "39dc3b1cc21f643344ec603123b49ba95709125a", + [ + "html/browsers/origin/inheritance/document-write.https.window.html", + { + "script_metadata": [ + [ + "script", + "/common/get-host-info.sub.js" + ] + ] + } + ] + ], "javascript-url.html": [ "7dfb1130ce5a6c8e3c0f506900620fe87b17ec4e", [ @@ -644495,7 +644578,7 @@ ] ], "setParameters-encodings.https.html": [ - "ac04ca55fb1f34ee51641bb05048de0bff0d57ea", + "86274a0c5a3da8b05c852e7b421951b90eb6e290", [ null, {
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-stream.any-expected.txt b/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-stream.any-expected.txt deleted file mode 100644 index d45fbc01..0000000 --- a/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-stream.any-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Blob.stream() -PASS Blob.stream() empty Blob -PASS Blob.stream() non-unicode input -PASS Blob.stream() garbage collection of blob shouldn't break streamconsumption -FAIL Reading Blob.stream() with BYOB reader promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-stream.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-stream.any.worker-expected.txt deleted file mode 100644 index d45fbc01..0000000 --- a/third_party/blink/web_tests/external/wpt/FileAPI/blob/Blob-stream.any.worker-expected.txt +++ /dev/null
@@ -1,8 +0,0 @@ -This is a testharness.js-based test. -PASS Blob.stream() -PASS Blob.stream() empty Blob -PASS Blob.stream() non-unicode input -PASS Blob.stream() garbage collection of blob shouldn't break streamconsumption -FAIL Reading Blob.stream() with BYOB reader promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/resources/header-util.sub.js b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/header-util.sub.js index c38e5aa..bb5a634 100644 --- a/third_party/blink/web_tests/external/wpt/browsing-topics/resources/header-util.sub.js +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/header-util.sub.js
@@ -1,4 +1,4 @@ -const EMPTY_TOPICS_HEADER = 't=(), p=P000000000000000000000000000'; +const EMPTY_TOPICS_HEADER = '();p=P0000000000000000000000000000000'; function test_topics_iframe_navigation_header( test, has_browsing_topics_attribute, is_same_origin, expect_topics_header_available_func) {
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any-expected.txt deleted file mode 100644 index 949d29d8..0000000 --- a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -PASS Read empty text response's body as readableStream -PASS Read empty blob response's body as readableStream -PASS Read blob response's body as readableStream with mode=undefined -PASS Read text response's body as readableStream with mode=undefined -PASS Read URLSearchParams response's body as readableStream with mode=undefined -PASS Read array buffer response's body as readableStream with mode=undefined -PASS Read form data response's body as readableStream with mode=undefined -FAIL Read blob response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read text response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read URLSearchParams response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read array buffer response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read form data response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -PASS Getting an error Response stream -PASS Getting a redirect Response stream -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.serviceworker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.serviceworker-expected.txt deleted file mode 100644 index 949d29d8..0000000 --- a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.serviceworker-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -PASS Read empty text response's body as readableStream -PASS Read empty blob response's body as readableStream -PASS Read blob response's body as readableStream with mode=undefined -PASS Read text response's body as readableStream with mode=undefined -PASS Read URLSearchParams response's body as readableStream with mode=undefined -PASS Read array buffer response's body as readableStream with mode=undefined -PASS Read form data response's body as readableStream with mode=undefined -FAIL Read blob response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read text response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read URLSearchParams response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read array buffer response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read form data response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -PASS Getting an error Response stream -PASS Getting a redirect Response stream -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.sharedworker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.sharedworker-expected.txt deleted file mode 100644 index 949d29d8..0000000 --- a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.sharedworker-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -PASS Read empty text response's body as readableStream -PASS Read empty blob response's body as readableStream -PASS Read blob response's body as readableStream with mode=undefined -PASS Read text response's body as readableStream with mode=undefined -PASS Read URLSearchParams response's body as readableStream with mode=undefined -PASS Read array buffer response's body as readableStream with mode=undefined -PASS Read form data response's body as readableStream with mode=undefined -FAIL Read blob response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read text response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read URLSearchParams response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read array buffer response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read form data response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -PASS Getting an error Response stream -PASS Getting a redirect Response stream -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.worker-expected.txt deleted file mode 100644 index 949d29d8..0000000 --- a/third_party/blink/web_tests/external/wpt/fetch/api/response/response-consume-stream.any.worker-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -PASS Read empty text response's body as readableStream -PASS Read empty blob response's body as readableStream -PASS Read blob response's body as readableStream with mode=undefined -PASS Read text response's body as readableStream with mode=undefined -PASS Read URLSearchParams response's body as readableStream with mode=undefined -PASS Read array buffer response's body as readableStream with mode=undefined -PASS Read form data response's body as readableStream with mode=undefined -FAIL Read blob response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read text response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read URLSearchParams response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read array buffer response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -FAIL Read form data response's body as readableStream with mode=byob Failed to execute 'getReader' on 'ReadableStream': Cannot use a BYOB reader with a non-byte stream -PASS Getting an error Response stream -PASS Getting a redirect Response stream -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/turtledove.idl b/third_party/blink/web_tests/external/wpt/interfaces/turtledove.idl index 8add667..f5867e9 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/turtledove.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/turtledove.idl
@@ -95,6 +95,7 @@ interface InterestGroupReportingScriptRunnerGlobalScope : InterestGroupScriptRunnerGlobalScope { undefined sendReportTo(DOMString url); + undefined registerAdBeacon(record<DOMString, USVString> map); }; dictionary AdRender {
diff --git a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-encoded-transform.idl b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-encoded-transform.idl index 59710bf4..6dd2ba3f 100644 --- a/third_party/blink/web_tests/external/wpt/interfaces/webrtc-encoded-transform.idl +++ b/third_party/blink/web_tests/external/wpt/interfaces/webrtc-encoded-transform.idl
@@ -27,7 +27,7 @@ typedef (SmallCryptoKeyID or bigint) CryptoKeyID; [Exposed=(Window,DedicatedWorker)] -interface SFrameTransform { +interface SFrameTransform : EventTarget { constructor(optional SFrameTransformOptions options = {}); Promise<undefined> setEncryptionKey(CryptoKey key, optional CryptoKeyID keyID); attribute EventHandler onerror;
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/fetch-blob.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/fetch-blob.html index 7f8d557..098a5a51 100644 --- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/fetch-blob.html +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/fetch-blob.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>Same-origin prerendering can access localStorage</title> +<title>Same-origin prerendering can access blobs</title> <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restrictions.html b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restrictions.html index 5019d4b2..1990dfa 100644 --- a/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restrictions.html +++ b/third_party/blink/web_tests/external/wpt/speculation-rules/prerender/restrictions.html
@@ -1,5 +1,5 @@ <!DOCTYPE html> -<title>Same-origin prerendering can access localStorage</title> +<title>Same-origin prerendering cannot access some APIs</title> <meta name="timeout" content="long"> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script>
diff --git a/third_party/blink/web_tests/external/wpt/webnn/split.https.any-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/split.https.any-expected.txt deleted file mode 100644 index 8d0f56b..0000000 --- a/third_party/blink/web_tests/external/wpt/webnn/split.https.any-expected.txt +++ /dev/null
@@ -1,11 +0,0 @@ -This is a testharness.js-based test. -FAIL split float32 1D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 2D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 3D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 4D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 5D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 4D tensor array splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 4D tensor number splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 5D tensor array splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webnn/split.https.any.worker-expected.txt b/third_party/blink/web_tests/external/wpt/webnn/split.https.any.worker-expected.txt deleted file mode 100644 index 58bd0e0..0000000 --- a/third_party/blink/web_tests/external/wpt/webnn/split.https.any.worker-expected.txt +++ /dev/null
@@ -1,19 +0,0 @@ -This is a testharness.js-based test. -FAIL split float32 1D tensor number splits default options / sync builder[operationName] is not a function -FAIL split float32 2D tensor number splits default options / sync builder[operationName] is not a function -FAIL split float32 3D tensor number splits default options / sync builder[operationName] is not a function -FAIL split float32 4D tensor number splits default options / sync builder[operationName] is not a function -FAIL split float32 5D tensor number splits default options / sync builder[operationName] is not a function -FAIL split float32 4D tensor array splits default options / sync builder[operationName] is not a function -FAIL split float32 4D tensor number splits options.axis / sync builder[operationName] is not a function -FAIL split float32 5D tensor array splits options.axis / sync builder[operationName] is not a function -FAIL split float32 1D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 2D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 3D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 4D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 5D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 4D tensor array splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 4D tensor number splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -FAIL split float32 5D tensor array splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: builder[operationName] is not a function" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.js b/third_party/blink/web_tests/external/wpt/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.js new file mode 100644 index 0000000..320803a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/back-forward-cache-with-closed-webrtc-connection.https.window.js
@@ -0,0 +1,19 @@ +// META: title=Testing BFCache support for page with closed WebRTC connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webrtc-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openThenCloseWebRTC(rc1); + // The page should be eligible for BFCache because the WebRTC connection is closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); +});
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js b/third_party/blink/web_tests/external/wpt/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js new file mode 100644 index 0000000..4a4807d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/back-forward-cache-with-open-webrtc-connection.https.window.js
@@ -0,0 +1,20 @@ +// META: title=Testing BFCache support for page with open WebRTC connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webrtc-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openWebRTC(rc1); + // The page should not be eligible for BFCache because of open WebRTC connection. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredFromBFCache(rc1, ['WebRTC']); +});
diff --git a/third_party/blink/web_tests/external/wpt/webrtc/resources/webrtc-test-helpers.sub.js b/third_party/blink/web_tests/external/wpt/webrtc/resources/webrtc-test-helpers.sub.js new file mode 100644 index 0000000..48882b30 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webrtc/resources/webrtc-test-helpers.sub.js
@@ -0,0 +1,79 @@ +// SDP copied from JSEP Example 7.1 +// It contains two media streams with different ufrags +// to test if candidate is added to the correct stream +const sdp = `v=0 +o=- 4962303333179871722 1 IN IP4 0.0.0.0 +s=- +t=0 0 +a=ice-options:trickle +a=group:BUNDLE a1 v1 +a=group:LS a1 v1 +m=audio 10100 UDP/TLS/RTP/SAVPF 96 0 8 97 98 +c=IN IP4 203.0.113.100 +a=mid:a1 +a=sendrecv +a=rtpmap:96 opus/48000/2 +a=rtpmap:0 PCMU/8000 +a=rtpmap:8 PCMA/8000 +a=rtpmap:97 telephone-event/8000 +a=rtpmap:98 telephone-event/48000 +a=maxptime:120 +a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid +a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level +a=msid:47017fee-b6c1-4162-929c-a25110252400 f83006c5-a0ff-4e0a-9ed9-d3e6747be7d9 +a=ice-ufrag:ETEn +a=ice-pwd:OtSK0WpNtpUjkY4+86js7ZQl +a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04:BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2 +a=setup:actpass +a=dtls-id:1 +a=rtcp:10101 IN IP4 203.0.113.100 +a=rtcp-mux +a=rtcp-rsize +m=video 10102 UDP/TLS/RTP/SAVPF 100 101 +c=IN IP4 203.0.113.100 +a=mid:v1 +a=sendrecv +a=rtpmap:100 VP8/90000 +a=rtpmap:101 rtx/90000 +a=fmtp:101 apt=100 +a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid +a=rtcp-fb:100 ccm fir +a=rtcp-fb:100 nack +a=rtcp-fb:100 nack pli +a=msid:47017fee-b6c1-4162-929c-a25110252400 f30bdb4a-5db8-49b5-bcdc-e0c9a23172e0 +a=ice-ufrag:BGKk +a=ice-pwd:mqyWsAjvtKwTGnvhPztQ9mIf +a=fingerprint:sha-256 19:E2:1C:3B:4B:9F:81:E6:B8:5C:F4:A5:A8:D8:73:04:BB:05:2F:70:9F:04:A9:0E:05:E9:26:33:E8:70:88:A2 +a=setup:actpass +a=dtls-id:1 +a=rtcp:10103 IN IP4 203.0.113.100 +a=rtcp-mux +a=rtcp-rsize +`; + +const sessionDesc = { type: 'offer', sdp }; +const candidate = { + candidate: 'candidate:1 1 udp 2113929471 203.0.113.100 10100 typ host', + sdpMid: 'a1', + sdpMLineIndex: 0, + usernameFragment: 'ETEn' +}; + +// Opens a new WebRTC connection. +async function openWebRTC(remoteContextHelper) { + await remoteContextHelper.executeScript(async (sessionDesc, candidate) => { + const testRTCPeerConnection = new RTCPeerConnection(); + await testRTCPeerConnection.setRemoteDescription(sessionDesc); + await testRTCPeerConnection.addIceCandidate(candidate); + }, [sessionDesc, candidate]); +} + +// Opens a new WebRTC connection and then close it. +async function openThenCloseWebRTC(remoteContextHelper) { + await remoteContextHelper.executeScript(async (sessionDesc, candidate) => { + const testRTCPeerConnection = new RTCPeerConnection(); + await testRTCPeerConnection.setRemoteDescription(sessionDesc); + await testRTCPeerConnection.addIceCandidate(candidate); + testRTCPeerConnection.close(); + }, [sessionDesc, candidate]); +}
diff --git a/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-closed-websocket-connection.window.js b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-closed-websocket-connection.window.js new file mode 100644 index 0000000..30b8e63 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-closed-websocket-connection.window.js
@@ -0,0 +1,20 @@ +// META: title=Testing BFCache support for page with closed WebSocket connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: script=resources/websockets-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openThenCloseWebSocket(rc1); + // The page should be eligible for BFCache because the WebSocket connection has been closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); +});
diff --git a/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-open-websocket-connection.window.js b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-open-websocket-connection.window.js new file mode 100644 index 0000000..2baf38f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/websockets/back-forward-cache-with-open-websocket-connection.window.js
@@ -0,0 +1,21 @@ +// META: title=Testing BFCache support for page with open WebSocket connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=/websockets/constants.sub.js +// META: script=resources/websockets-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openWebSocket(rc1); + // The page should not be eligible for BFCache because of open WebSocket connection. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ false); + await assertNotRestoredFromBFCache(rc1, ['WebSocket']); +});
diff --git a/third_party/blink/web_tests/external/wpt/websockets/resources/websockets-test-helpers.sub.js b/third_party/blink/web_tests/external/wpt/websockets/resources/websockets-test-helpers.sub.js new file mode 100644 index 0000000..2680670 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/websockets/resources/websockets-test-helpers.sub.js
@@ -0,0 +1,25 @@ +// The file including this must also include `/websockets/constants.sub.js to +// pick up the necessary constants. + +// Opens a new WebSocket connection. +async function openWebSocket(remoteContextHelper) { + let return_value = await remoteContextHelper.executeScript((domain) => { + return new Promise((resolve) => { + var webSocketInNotRestoredReasonsTests = new WebSocket(domain + '/echo'); + webSocketInNotRestoredReasonsTests.onopen = () => { resolve(42); }; + }); + }, [SCHEME_DOMAIN_PORT]); + assert_equals(return_value, 42); +} + +// Opens a new WebSocket connection and then close it. +async function openThenCloseWebSocket(remoteContextHelper) { + let return_value = await remoteContextHelper.executeScript((domain) => { + return new Promise((resolve) => { + var testWebSocket = new WebSocket(domain + '/echo'); + testWebSocket.onopen = () => { testWebSocket.close() }; + testWebSocket.onclose = () => { resolve(42) }; + }); + }, [SCHEME_DOMAIN_PORT]); + assert_equals(return_value, 42); +}
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-closed-webtransport-connection.https.window.js b/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-closed-webtransport-connection.https.window.js new file mode 100644 index 0000000..5cc7e93 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-closed-webtransport-connection.https.window.js
@@ -0,0 +1,20 @@ +// META: title=Testing BFCache support for page with closed WebTransport connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webtransport-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openThenCloseWebTransport(rc1); + // The page should be eligible for BFCache because the WebTransport connection is closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); +});
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-open-webtransport-connection.https.window-expected.txt b/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-open-webtransport-connection.https.window-expected.txt new file mode 100644 index 0000000..dbe6390 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-open-webtransport-connection.https.window-expected.txt
@@ -0,0 +1,4 @@ +This is a testharness.js-based test. +NOTRUN Testing BFCache support for page with open WebTransport connection. BFCache not supported. +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-open-webtransport-connection.https.window.js b/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-open-webtransport-connection.https.window.js new file mode 100644 index 0000000..5d5143a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/webtransport/back-forward-cache-with-open-webtransport-connection.https.window.js
@@ -0,0 +1,25 @@ +// META: title=Testing BFCache support for page with open WebTransport connection. +// META: script=/common/dispatcher/dispatcher.js +// META: script=/common/get-host-info.sub.js +// META: script=/common/utils.js +// META: script=/html/browsers/browsing-the-web/back-forward-cache/resources/rc-helper.js +// META: script=/html/browsers/browsing-the-web/remote-context-helper/resources/remote-context-helper.js +// META: script=resources/webtransport-test-helpers.sub.js + +'use strict'; + +promise_test(async t => { + const rcHelper = new RemoteContextHelper(); + + // Open a window with noopener so that BFCache will work. + const rc1 = await rcHelper.addWindow( + /*config=*/ null, /*options=*/ { features: 'noopener' }); + await openWebTransport(rc1); + // The page should be eligible for BFCache and the WebTransport connection + // should be closed. + await assertBFCacheEligibility(rc1, /*shouldRestoreFromBFCache=*/ true); + await rc1.executeScript(async () => { + assert_false(window.testWebTransport === undefined); + await window.testWebTransport.closed; + }); +});
diff --git a/third_party/blink/web_tests/external/wpt/webtransport/resources/webtransport-test-helpers.sub.js b/third_party/blink/web_tests/external/wpt/webtransport/resources/webtransport-test-helpers.sub.js index 9f9127b..3678869 100644 --- a/third_party/blink/web_tests/external/wpt/webtransport/resources/webtransport-test-helpers.sub.js +++ b/third_party/blink/web_tests/external/wpt/webtransport/resources/webtransport-test-helpers.sub.js
@@ -110,3 +110,24 @@ return buffer; } + +// Opens a new WebTransport connection. +async function openWebTransport(remoteContextHelper) { + const url = webtransport_url('custom-response.py?:status=200'); + await remoteContextHelper.executeScript((url) => { + window.testWebTransport = new WebTransport(url); + return window.testWebTransport.ready; + }, [url]); +} + +// Opens a new WebTransport connection and then close it. +async function openThenCloseWebTransport(remoteContextHelper) { + const url = webtransport_url('custom-response.py?:status=200'); + await remoteContextHelper.executeScript((url) => { + window.testWebTransport = new WebTransport(url); + return window.testWebTransport.ready.then(async () => { + window.testWebTransport.close(); + await window.testWebTransport.closed; + }); + }, [url]); +}
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/css-inline-sourcemap.js b/third_party/blink/web_tests/http/tests/devtools/sources/css-inline-sourcemap.js index 022751e..7b17fca 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/css-inline-sourcemap.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/css-inline-sourcemap.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`The test verifies that source maps are loaded if specified inside style tag.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.loadHTML(`
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled.js b/third_party/blink/web_tests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled.js index 3dfdd95..41e13b1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/css-sourcemaps-toggle-enabled.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Verify that CSS sourcemap enabling and disabling adds/removes sourcemap sources.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); var sourcesNavigator = new Sources.NetworkNavigatorView();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt index 94719b1..29f7c54 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-expected.txt
@@ -3,17 +3,17 @@ Set timer for test function. Script execution paused. Call stack: - 0) testFunction (debugger-step-in.js:17) + 0) testFunction (debugger-step-in.js:20) Stepping into... Script execution resumed. Script execution paused. Call stack: - 0) testFunction (debugger-step-in.js:18) + 0) testFunction (debugger-step-in.js:21) Stepping into... Script execution resumed. Script execution paused. Call stack: - 0) d (debugger-step-in.js:12) - 1) testFunction (debugger-step-in.js:18) + 0) d (debugger-step-in.js:15) + 1) testFunction (debugger-step-in.js:21) Script execution resumed.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script-expected.txt index f5c3a3e..c2be0950 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script-expected.txt
@@ -2,5 +2,5 @@ Set timer for test function. Call stack: - 0) testFunction (debugger-step-in-ignore-injected-script.js:14) + 0) testFunction (debugger-step-in-ignore-injected-script.js:17)
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script.js index 048ca14..01982e8 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in-ignore-injected-script.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Tests that stepInto doesn't pause in InjectedScriptSource.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function testFunction()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in.js index 6c6ce25..04785dc 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-in.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Tests "step in" functionality in debugger.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function d()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts-expected.txt index 87c89ce..64cf5f9 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts-expected.txt
@@ -2,9 +2,9 @@ Set timer for test function. Call stack: - 0) callback1 (debugger-step-into-across-timeouts.js:19) + 0) callback1 (debugger-step-into-across-timeouts.js:22) [setTimeout] - 0) testFunction (debugger-step-into-across-timeouts.js:13) + 0) testFunction (debugger-step-into-across-timeouts.js:16) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> @@ -12,11 +12,11 @@ Executing StepInto... Executing StepInto... Call stack: - 0) callback2 (debugger-step-into-across-timeouts.js:24) + 0) callback2 (debugger-step-into-across-timeouts.js:27) [setTimeout] - 0) callback1 (debugger-step-into-across-timeouts.js:18) + 0) callback1 (debugger-step-into-across-timeouts.js:21) [setTimeout] - 0) testFunction (debugger-step-into-across-timeouts.js:13) + 0) testFunction (debugger-step-into-across-timeouts.js:16) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts.js index 89b85b4..1e7e597 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-across-timeouts.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepInto will stop inside next timeout handler.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function testFunction()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js index 165b239..11ec769 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-custom-element-callbacks.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Tests that stepping into custom element methods will lead to a pause in the callbacks.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(`
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-document-write.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-document-write.js index c7b2ff6..5c42282 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-document-write.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-document-write.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepInto will step into inlined scripts created by document.write().\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.navigatePromise( 'resources/debugger-step-into-document-write.html')
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-event-listener.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-event-listener.js index 629f883..3c4f68c4 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-event-listener.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-event-listener.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that stepping into dispatchEvent() method will lead to a pause in the first event listener.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.loadHTML(` <div id="myDiv"></div>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-inlined-scripts.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-inlined-scripts.js index a0d56da..d28e2c4 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-inlined-scripts.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-into-inlined-scripts.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepInto will step through inlined scripts.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.navigatePromise( 'resources/debugger-step-into-inlined-scripts.html');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts-expected.txt index a9b53c64..e5d31b4d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts-expected.txt
@@ -2,20 +2,20 @@ Set timer for test function. Call stack: - 0) callback1 (debugger-step-out-across-timeouts.js:19) + 0) callback1 (debugger-step-out-across-timeouts.js:22) [setTimeout] - 0) testFunction (debugger-step-out-across-timeouts.js:13) + 0) testFunction (debugger-step-out-across-timeouts.js:16) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Executing StepOut... Call stack: - 0) callback2 (debugger-step-out-across-timeouts.js:25) + 0) callback2 (debugger-step-out-across-timeouts.js:28) [setTimeout] - 0) callback1 (debugger-step-out-across-timeouts.js:18) + 0) callback1 (debugger-step-out-across-timeouts.js:21) [setTimeout] - 0) testFunction (debugger-step-out-across-timeouts.js:13) + 0) testFunction (debugger-step-out-across-timeouts.js:16) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts.js index f6eb79c..31cdca8 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-across-timeouts.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepOut will stop inside next timeout handler.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function testFunction()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks-expected.txt index 24ed720..94cf1b1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks-expected.txt
@@ -2,52 +2,7 @@ Set timer for test function. Call stack: - 0) FooElement (debugger-step-out-custom-element-callbacks.js:23) - 1) testFunction (debugger-step-out-custom-element-callbacks.js:41) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepOut... -Call stack: - 0) testFunction (debugger-step-out-custom-element-callbacks.js:42) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepInto... -Call stack: - 0) attributeChangedCallback (debugger-step-out-custom-element-callbacks.js:36) - 1) testFunction (debugger-step-out-custom-element-callbacks.js:42) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepOut... -Call stack: - 0) testFunction (debugger-step-out-custom-element-callbacks.js:43) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepInto... -Call stack: - 0) connectedCallback (debugger-step-out-custom-element-callbacks.js:27) - 1) testFunction (debugger-step-out-custom-element-callbacks.js:43) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepOut... -Call stack: - 0) testFunction (debugger-step-out-custom-element-callbacks.js:44) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepInto... -Call stack: - 0) disconnectedCallback (debugger-step-out-custom-element-callbacks.js:30) + 0) FooElement (debugger-step-out-custom-element-callbacks.js:26) 1) testFunction (debugger-step-out-custom-element-callbacks.js:44) [setTimeout] 0) scheduleTestFunction <omitted> @@ -60,6 +15,51 @@ 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> +Executing StepInto... +Call stack: + 0) attributeChangedCallback (debugger-step-out-custom-element-callbacks.js:39) + 1) testFunction (debugger-step-out-custom-element-callbacks.js:45) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepOut... +Call stack: + 0) testFunction (debugger-step-out-custom-element-callbacks.js:46) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepInto... +Call stack: + 0) connectedCallback (debugger-step-out-custom-element-callbacks.js:30) + 1) testFunction (debugger-step-out-custom-element-callbacks.js:46) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepOut... +Call stack: + 0) testFunction (debugger-step-out-custom-element-callbacks.js:47) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepInto... +Call stack: + 0) disconnectedCallback (debugger-step-out-custom-element-callbacks.js:33) + 1) testFunction (debugger-step-out-custom-element-callbacks.js:47) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepOut... +Call stack: + 0) testFunction (debugger-step-out-custom-element-callbacks.js:48) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + [page] Invoked constructor. [page] Invoked attributeChangedCallback. [page] Invoked connectedCallback.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js index 482658c..58f2a03 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-custom-element-callbacks.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Tests stepping out from custom element callbacks.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(`
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-document-write.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-document-write.js index b546dce7..704fe85e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-document-write.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-document-write.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepOut will skip inlined scripts created by document.write().\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); var numberOfStepOut = 5;
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener-expected.txt index 1f53e52..28c8f81 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener-expected.txt
@@ -2,51 +2,51 @@ Set timer for test function. Call stack: - 0) inner (debugger-step-out-event-listener.js:33) - 1) testFunction (debugger-step-out-event-listener.js:39) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepInto... -Executing StepInto... -Executing StepInto... -Call stack: - 0) fooEventHandler1 (debugger-step-out-event-listener.js:22) - 1) inner (debugger-step-out-event-listener.js:34) - 2) testFunction (debugger-step-out-event-listener.js:39) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepOut... -Call stack: - 0) fooEventHandler2 (debugger-step-out-event-listener.js:26) - 1) inner (debugger-step-out-event-listener.js:34) - 2) testFunction (debugger-step-out-event-listener.js:39) - [setTimeout] - 0) scheduleTestFunction <omitted> - <... skipped remaining frames ...> - -Executing StepOut... -Call stack: 0) inner (debugger-step-out-event-listener.js:36) - 1) testFunction (debugger-step-out-event-listener.js:39) + 1) testFunction (debugger-step-out-event-listener.js:42) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepInto... +Executing StepInto... +Executing StepInto... +Call stack: + 0) fooEventHandler1 (debugger-step-out-event-listener.js:25) + 1) inner (debugger-step-out-event-listener.js:37) + 2) testFunction (debugger-step-out-event-listener.js:42) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepOut... +Call stack: + 0) fooEventHandler2 (debugger-step-out-event-listener.js:29) + 1) inner (debugger-step-out-event-listener.js:37) + 2) testFunction (debugger-step-out-event-listener.js:42) + [setTimeout] + 0) scheduleTestFunction <omitted> + <... skipped remaining frames ...> + +Executing StepOut... +Call stack: + 0) inner (debugger-step-out-event-listener.js:39) + 1) testFunction (debugger-step-out-event-listener.js:42) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Set timer for test function. Call stack: - 0) inner (debugger-step-out-event-listener.js:33) - 1) testFunction (debugger-step-out-event-listener.js:39) + 0) inner (debugger-step-out-event-listener.js:36) + 1) testFunction (debugger-step-out-event-listener.js:42) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Executing StepOut... Call stack: - 0) testFunction (debugger-step-out-event-listener.js:40) + 0) testFunction (debugger-step-out-event-listener.js:43) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js index 5a3fa1b0..46aebf1 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-event-listener.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that stepping out of an event listener will lead to a pause in the next event listener.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.loadHTML(` <div id="myDiv"></div>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt index 4c3afbe..b9e38359 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out-expected.txt
@@ -3,12 +3,12 @@ Set timer for test function. Script execution paused. Call stack: - 0) d (debugger-step-out.js:12) - 1) testFunction (debugger-step-out.js:17) + 0) d (debugger-step-out.js:15) + 1) testFunction (debugger-step-out.js:20) Stepping out... Script execution resumed. Script execution paused. Call stack: - 0) testFunction (debugger-step-out.js:18) + 0) testFunction (debugger-step-out.js:21) Script execution resumed.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out.js index f382967b..0207c33 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-out.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Tests "step out" functionality in debugger.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function d()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts-expected.txt index b741caa..901d6df 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts-expected.txt
@@ -2,9 +2,9 @@ Set timer for test function. Call stack: - 0) callback1 (debugger-step-over-across-timeouts.js:19) + 0) callback1 (debugger-step-over-across-timeouts.js:22) [setTimeout] - 0) testFunction (debugger-step-over-across-timeouts.js:13) + 0) testFunction (debugger-step-over-across-timeouts.js:16) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> @@ -12,11 +12,11 @@ Executing StepOver... Executing StepOver... Call stack: - 0) callback2 (debugger-step-over-across-timeouts.js:24) + 0) callback2 (debugger-step-over-across-timeouts.js:27) [setTimeout] - 0) callback1 (debugger-step-over-across-timeouts.js:18) + 0) callback1 (debugger-step-over-across-timeouts.js:21) [setTimeout] - 0) testFunction (debugger-step-over-across-timeouts.js:13) + 0) testFunction (debugger-step-over-across-timeouts.js:16) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts.js index 82947914..4939a90 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-across-timeouts.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepOver will stop inside next timeout handler.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function testFunction()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-document-write.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-document-write.js index 63ef2031..20f610c 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-document-write.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-document-write.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepOver will skip inlined scripts created by document.write().\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.navigatePromise( 'resources/debugger-step-over-document-write.html');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt index 79815e7..3157791 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-expected.txt
@@ -3,19 +3,19 @@ Set timer for test function. Script execution paused. Call stack: - 0) d (debugger-step-over.js:17) - 1) testFunction (debugger-step-over.js:23) + 0) d (debugger-step-over.js:20) + 1) testFunction (debugger-step-over.js:26) Stepping over... Script execution resumed. Script execution paused. Call stack: - 0) d (debugger-step-over.js:18) - 1) testFunction (debugger-step-over.js:23) + 0) d (debugger-step-over.js:21) + 1) testFunction (debugger-step-over.js:26) Stepping over... Script execution resumed. Script execution paused. Call stack: - 0) d (debugger-step-over.js:19) - 1) testFunction (debugger-step-over.js:23) + 0) d (debugger-step-over.js:22) + 1) testFunction (debugger-step-over.js:26) Script execution resumed.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-inlined-scripts.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-inlined-scripts.js index e855b50..79450e6 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-inlined-scripts.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over-inlined-scripts.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger StepOver will step through inlined scripts.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.navigatePromise( 'resources/debugger-step-over-inlined-scripts.html');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over.js index 35a40e7..69c9bde 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-over.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Tests "step over" functionality in debugger.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function f()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises-expected.txt index 2134860f..a653925c56 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises-expected.txt
@@ -2,54 +2,54 @@ Set timer for test function. Call stack: - 0) p1 (debugger-step-through-promises.js:19) + 0) p1 (debugger-step-through-promises.js:22) [Promise.then] - 0) testFunction (debugger-step-through-promises.js:16) + 0) testFunction (debugger-step-through-promises.js:19) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Executing StepInto... Call stack: - 0) p1 (debugger-step-through-promises.js:20) + 0) p1 (debugger-step-through-promises.js:23) [Promise.then] - 0) testFunction (debugger-step-through-promises.js:16) + 0) testFunction (debugger-step-through-promises.js:19) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Executing StepInto... Call stack: - 0) p2 (debugger-step-through-promises.js:24) + 0) p2 (debugger-step-through-promises.js:27) [Promise.then] - 0) testFunction (debugger-step-through-promises.js:21) + 0) testFunction (debugger-step-through-promises.js:24) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Executing StepOver... Call stack: - 0) p2 (debugger-step-through-promises.js:24) + 0) p2 (debugger-step-through-promises.js:27) [Promise.then] - 0) testFunction (debugger-step-through-promises.js:21) + 0) testFunction (debugger-step-through-promises.js:24) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Executing StepOver... Call stack: - 0) p3 (debugger-step-through-promises.js:29) + 0) p3 (debugger-step-through-promises.js:32) [Promise.then] - 0) testFunction (debugger-step-through-promises.js:26) + 0) testFunction (debugger-step-through-promises.js:29) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...> Executing StepOver... Call stack: - 0) p3 (debugger-step-through-promises.js:29) + 0) p3 (debugger-step-through-promises.js:32) [Promise.then] - 0) testFunction (debugger-step-through-promises.js:26) + 0) testFunction (debugger-step-through-promises.js:29) [setTimeout] 0) scheduleTestFunction <omitted> <... skipped remaining frames ...>
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises.js index 3b6c3191..fb2d4541 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/debugger-step-through-promises.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Tests that debugger will step through Promise handlers while not stepping into V8 internal scripts.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.loadHTML(` <input type="button" onclick="testFunction()" value="Test">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners-expected.txt b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners-expected.txt index d8799920..edd9626 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners-expected.txt +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners-expected.txt
@@ -4,26 +4,26 @@ Running: testClickBreakpoint Script execution paused. Call stack: - 0) listener3 (step-through-event-listeners.js:24) - 1) addListenerAndClick (step-through-event-listeners.js:33) + 0) listener3 (step-through-event-listeners.js:27) + 1) addListenerAndClick (step-through-event-listeners.js:36) 2) (:1) Script execution resumed. Script execution paused. Call stack: - 0) listener1 (step-through-event-listeners.js:16) - 1) addListenerAndClick (step-through-event-listeners.js:33) + 0) listener1 (step-through-event-listeners.js:19) + 1) addListenerAndClick (step-through-event-listeners.js:36) 2) (:1) Script execution resumed. Script execution paused. Call stack: - 0) listener2 (step-through-event-listeners.js:20) - 1) addListenerAndClick (step-through-event-listeners.js:33) + 0) listener2 (step-through-event-listeners.js:23) + 1) addListenerAndClick (step-through-event-listeners.js:36) 2) (:1) Script execution resumed. Script execution paused. Call stack: - 0) listener3 (step-through-event-listeners.js:24) - 1) addListenerAndClick (step-through-event-listeners.js:33) + 0) listener3 (step-through-event-listeners.js:27) + 1) addListenerAndClick (step-through-event-listeners.js:36) 2) (:1) Script execution resumed.
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners.js b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners.js index d3a57bd..bf8742e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/debugger-step/step-through-event-listeners.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Test that debugger will pause in all event listeners when corresponding breakpoint is set. Bug 77331.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadLegacyModule('panels/browser_debugger'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.loadLegacyModule('panels/browser_debugger'); await TestRunner.showPanel('sources'); await TestRunner.loadHTML(` <input type="button" id="test">
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/dont-diverge-script-evaluated-twice.js b/third_party/blink/web_tests/http/tests/devtools/sources/dont-diverge-script-evaluated-twice.js index d10eb01..4688c281 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/dont-diverge-script-evaluated-twice.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/dont-diverge-script-evaluated-twice.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Checks that script evaluated twice with different source and the same sourceURL won't be diverged from VM.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); const scriptSource = '239\n//# sourceURL=test.js';
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.js b/third_party/blink/web_tests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.js index 1cced35..c37ac08a 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/event-listener-breakpoints-script-fst-stmt-for-module.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Tests event listener breakpoint to break on the first statement of new modules.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadLegacyModule('panels/browser_debugger'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.loadLegacyModule('panels/browser_debugger'); await TestRunner.showPanel('sources'); await TestRunner.evaluateInPagePromise(` function testFunction()
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js b/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js index 785ce0f..080b76f 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/inline-styles-scripts-locations.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Bindings should only generate locations for an inline script (style) if the location is inside of the inline script (style).\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.navigatePromise('../bindings/resources/inline-style.html');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled.js b/third_party/blink/web_tests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled.js index 332f7db..faae6fe0 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/js-sourcemaps-toggle-enabled.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Verify that JavaScript sourcemap enabling and disabling adds/removes sourcemap sources.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); var sourcesNavigator = new Sources.NetworkNavigatorView();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/navigator-view-content-scripts.js b/third_party/blink/web_tests/http/tests/devtools/sources/navigator-view-content-scripts.js index 9710313..e36e21e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/navigator-view-content-scripts.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/navigator-view-content-scripts.js
@@ -2,10 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( `Verify that removal of one of the multiple projects, all of which are associated with the same frame, doesn't lead navigator to discard the frame treenode.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); var rootURL = 'http://localhost:8080/LayoutTests/inspector/debugger/';
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/sass-highlighter.js b/third_party/blink/web_tests/http/tests/devtools/sources/sass-highlighter.js index 023bae4ab..a0417294 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/sass-highlighter.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/sass-highlighter.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Verify that highlighter type for SCSS file loaded via sourceMap is correct.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.addStylesheetTag('resources/empty.css');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/search-config.js b/third_party/blink/web_tests/http/tests/devtools/sources/search-config.js index bbb3eb6..d4f81eb 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/search-config.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/search-config.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; + (async function() { TestRunner.addResult(`Tests search query parsing.\n`); await TestRunner.loadLegacyModule('search');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/snippet-eval-uses-repl-mode.js b/third_party/blink/web_tests/http/tests/devtools/sources/snippet-eval-uses-repl-mode.js index c486c7e..b6bed5e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/snippet-eval-uses-repl-mode.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/snippet-eval-uses-repl-mode.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; + (async function() { TestRunner.addResult('Tests that snippet scripts are evaluated in REPL mode\n');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/snippet-module.js b/third_party/blink/web_tests/http/tests/devtools/sources/snippet-module.js index c4f4bdc..802667b 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/snippet-module.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/snippet-module.js
@@ -2,11 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {ConsoleTestRunner} from 'console_test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult( 'Verifies that modules can be loaded via import() in snippets\n'); - await TestRunner.loadLegacyModule('console'); await TestRunner.loadTestModule('console_test_runner'); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('console'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); const sourceCode = `
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/snippet-overrides.js b/third_party/blink/web_tests/http/tests/devtools/sources/snippet-overrides.js index 99d014b..60428b4 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/snippet-overrides.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/snippet-overrides.js
@@ -2,11 +2,14 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; +import {BindingsTestRunner} from 'bindings_test_runner'; + (async function() { TestRunner.addResult( 'Verifies that snippets still map when local overrides is on.\n'); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); - await TestRunner.loadTestModule('bindings_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await BindingsTestRunner.createOverrideProject('file:///tmp');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/sourcemap-hot-reload.js b/third_party/blink/web_tests/http/tests/devtools/sources/sourcemap-hot-reload.js index 8512974..dfca1ff 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/sourcemap-hot-reload.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/sourcemap-hot-reload.js
@@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; + (async function() { TestRunner.addResult(`Tests that sourcemap sources are updated when a new sourcemap is added`); var contents = [
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-extension-names.js b/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-extension-names.js index b54c7b59..b3cbaa7d 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-extension-names.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-extension-names.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`The test verifies that extension names are resolved properly in navigator view.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); var contentScriptsNavigatorView = new Sources.ContentScriptsNavigatorView();
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-focus-editor-on-select.js b/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-focus-editor-on-select.js index ef9bb9b1..288c9880 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-focus-editor-on-select.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/sources-panel-focus-editor-on-select.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Verifies that text editor has focus after panel re-selecting.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.addScriptTag('resources/script.js');
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-highlight.js b/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-highlight.js index 001214b..773ee8e 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-highlight.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-highlight.js
@@ -1,3 +1,5 @@ + +import {TestRunner} from 'test_runner'; (async function() { TestRunner.addResult(`Tests that network-loaded UISourceCodes are highlighted according to their HTTP header`); TestRunner.addResult(`mime type instead of their extension. crbug.com/411863\n`);
diff --git a/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-metadata.js b/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-metadata.js index c48d320..dca7ae8 100644 --- a/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-metadata.js +++ b/third_party/blink/web_tests/http/tests/devtools/sources/ui-source-code-metadata.js
@@ -2,9 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import {TestRunner} from 'test_runner'; +import {SourcesTestRunner} from 'sources_test_runner'; + (async function() { TestRunner.addResult(`Verify that network UISourceCode has metadata.\n`); - await TestRunner.loadLegacyModule('sources'); await TestRunner.loadTestModule('sources_test_runner'); + await TestRunner.loadLegacyModule('sources'); await TestRunner.showPanel('sources'); await TestRunner.addStylesheetTag('resources/style.css');
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt index cf97c09..ffa1c504 100644 --- a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt +++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 408 tests; 282 PASS, 126 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 408 tests; 285 PASS, 123 FAIL, 0 TIMEOUT, 0 NOTRUN. FAIL idl_test setup promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented" PASS idl_test validation PASS Partial interface MLContext: original interface defined @@ -252,7 +252,7 @@ FAIL MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions) assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing FAIL MLGraphBuilder interface: operation softsign(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing FAIL MLGraphBuilder interface: operation softsign() assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing -FAIL MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) assert_own_property: interface prototype object missing non-static operation expected property "split" missing +PASS MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) FAIL MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions) assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing FAIL MLGraphBuilder interface: operation tanh(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing FAIL MLGraphBuilder interface: operation tanh() assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing @@ -397,8 +397,8 @@ FAIL MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type assert_inherits: property "softsign" not found in prototype chain -FAIL MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type assert_inherits: property "split" not found in prototype chain -FAIL MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError assert_inherits: property "split" not found in prototype chain +PASS MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type +PASS MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError FAIL MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: calling squeeze(MLOperand, optional MLSqueezeOptions) on builder with too few arguments must throw TypeError assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "tanh(MLOperand)" with the proper type assert_inherits: property "tanh" not found in prototype chain
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt index 230c9eb..248e56b62a 100644 --- a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/idlharness.https.any.worker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 414 tests; 281 PASS, 133 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 414 tests; 284 PASS, 130 FAIL, 0 TIMEOUT, 0 NOTRUN. FAIL idl_test setup promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented" PASS idl_test validation PASS Partial interface MLContext: original interface defined @@ -257,7 +257,7 @@ FAIL MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions) assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing FAIL MLGraphBuilder interface: operation softsign(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing FAIL MLGraphBuilder interface: operation softsign() assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing -FAIL MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) assert_own_property: interface prototype object missing non-static operation expected property "split" missing +PASS MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) FAIL MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions) assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing FAIL MLGraphBuilder interface: operation tanh(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing FAIL MLGraphBuilder interface: operation tanh() assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing @@ -403,8 +403,8 @@ FAIL MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type assert_inherits: property "softsign" not found in prototype chain -FAIL MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type assert_inherits: property "split" not found in prototype chain -FAIL MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError assert_inherits: property "split" not found in prototype chain +PASS MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type +PASS MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError FAIL MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: calling squeeze(MLOperand, optional MLSqueezeOptions) on builder with too few arguments must throw TypeError assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "tanh(MLOperand)" with the proper type assert_inherits: property "tanh" not found in prototype chain
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/split.https.any-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/split.https.any-expected.txt new file mode 100644 index 0000000..e16a29e --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/split.https.any-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +FAIL split float32 1D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 2D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 3D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor array splits default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented" +FAIL split float32 4D tensor number splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor array splits options.axis / async promise_test: Unhandled rejection with value: object "NotSupportedError: Not implemented" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/mac/external/wpt/webnn/split.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/split.https.any.worker-expected.txt new file mode 100644 index 0000000..54e2ebd9 --- /dev/null +++ b/third_party/blink/web_tests/platform/mac/external/wpt/webnn/split.https.any.worker-expected.txt
@@ -0,0 +1,19 @@ +This is a testharness.js-based test. +FAIL split float32 1D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 2D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 3D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 4D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 5D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 4D tensor array splits default options / sync Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented +FAIL split float32 4D tensor number splits options.axis / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 5D tensor array splits options.axis / sync Failed to execute 'buildSync' on 'MLGraphBuilder': Not implemented +FAIL split float32 1D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 2D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 3D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor array splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +FAIL split float32 4D tensor number splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor array splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt index c14426d7..4d3387b 100644 --- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt +++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 408 tests; 282 PASS, 126 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 408 tests; 285 PASS, 123 FAIL, 0 TIMEOUT, 0 NOTRUN. FAIL idl_test setup promise_test: Unhandled rejection with value: object "NotSupportedError: The input layout nchw is not supported." PASS idl_test validation PASS Partial interface MLContext: original interface defined @@ -252,7 +252,7 @@ FAIL MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions) assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing FAIL MLGraphBuilder interface: operation softsign(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing FAIL MLGraphBuilder interface: operation softsign() assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing -FAIL MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) assert_own_property: interface prototype object missing non-static operation expected property "split" missing +PASS MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) FAIL MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions) assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing FAIL MLGraphBuilder interface: operation tanh(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing FAIL MLGraphBuilder interface: operation tanh() assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing @@ -397,8 +397,8 @@ FAIL MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type assert_inherits: property "softsign" not found in prototype chain -FAIL MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type assert_inherits: property "split" not found in prototype chain -FAIL MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError assert_inherits: property "split" not found in prototype chain +PASS MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type +PASS MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError FAIL MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: calling squeeze(MLOperand, optional MLSqueezeOptions) on builder with too few arguments must throw TypeError assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "tanh(MLOperand)" with the proper type assert_inherits: property "tanh" not found in prototype chain
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt index 3a04951..52c542c 100644 --- a/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt +++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/idlharness.https.any.worker-expected.txt
@@ -1,5 +1,5 @@ This is a testharness.js-based test. -Found 414 tests; 281 PASS, 133 FAIL, 0 TIMEOUT, 0 NOTRUN. +Found 414 tests; 284 PASS, 130 FAIL, 0 TIMEOUT, 0 NOTRUN. FAIL idl_test setup promise_test: Unhandled rejection with value: object "NotSupportedError: Failed to execute 'buildSync' on 'MLGraphBuilder': The input layout nchw is not supported." PASS idl_test validation PASS Partial interface MLContext: original interface defined @@ -257,7 +257,7 @@ FAIL MLGraphBuilder interface: operation softplus(optional MLSoftplusOptions) assert_own_property: interface prototype object missing non-static operation expected property "softplus" missing FAIL MLGraphBuilder interface: operation softsign(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing FAIL MLGraphBuilder interface: operation softsign() assert_own_property: interface prototype object missing non-static operation expected property "softsign" missing -FAIL MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) assert_own_property: interface prototype object missing non-static operation expected property "split" missing +PASS MLGraphBuilder interface: operation split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) FAIL MLGraphBuilder interface: operation squeeze(MLOperand, optional MLSqueezeOptions) assert_own_property: interface prototype object missing non-static operation expected property "squeeze" missing FAIL MLGraphBuilder interface: operation tanh(MLOperand) assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing FAIL MLGraphBuilder interface: operation tanh() assert_own_property: interface prototype object missing non-static operation expected property "tanh" missing @@ -403,8 +403,8 @@ FAIL MLGraphBuilder interface: builder must inherit property "softsign(MLOperand)" with the proper type assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: calling softsign(MLOperand) on builder with too few arguments must throw TypeError assert_inherits: property "softsign" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "softsign()" with the proper type assert_inherits: property "softsign" not found in prototype chain -FAIL MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type assert_inherits: property "split" not found in prototype chain -FAIL MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError assert_inherits: property "split" not found in prototype chain +PASS MLGraphBuilder interface: builder must inherit property "split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions)" with the proper type +PASS MLGraphBuilder interface: calling split(MLOperand, (unsigned long or sequence<unsigned long>), optional MLSplitOptions) on builder with too few arguments must throw TypeError FAIL MLGraphBuilder interface: builder must inherit property "squeeze(MLOperand, optional MLSqueezeOptions)" with the proper type assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: calling squeeze(MLOperand, optional MLSqueezeOptions) on builder with too few arguments must throw TypeError assert_inherits: property "squeeze" not found in prototype chain FAIL MLGraphBuilder interface: builder must inherit property "tanh(MLOperand)" with the proper type assert_inherits: property "tanh" not found in prototype chain
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/split.https.any-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/split.https.any-expected.txt new file mode 100644 index 0000000..d6fb33ad --- /dev/null +++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/split.https.any-expected.txt
@@ -0,0 +1,11 @@ +This is a testharness.js-based test. +FAIL split float32 1D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 2D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 3D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor array splits default options / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (split) is not supported." +FAIL split float32 4D tensor number splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor array splits options.axis / async promise_test: Unhandled rejection with value: object "NotSupportedError: The operator (split) is not supported." +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/platform/win/external/wpt/webnn/split.https.any.worker-expected.txt b/third_party/blink/web_tests/platform/win/external/wpt/webnn/split.https.any.worker-expected.txt new file mode 100644 index 0000000..028dca8 --- /dev/null +++ b/third_party/blink/web_tests/platform/win/external/wpt/webnn/split.https.any.worker-expected.txt
@@ -0,0 +1,19 @@ +This is a testharness.js-based test. +FAIL split float32 1D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 2D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 3D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 4D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 5D tensor number splits default options / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 4D tensor array splits default options / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (split) is not supported. +FAIL split float32 4D tensor number splits options.axis / sync Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence. +FAIL split float32 5D tensor array splits options.axis / sync Failed to execute 'buildSync' on 'MLGraphBuilder': The operator (split) is not supported. +FAIL split float32 1D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 2D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 3D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor number splits default options / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 4D tensor array splits default options / async promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +FAIL split float32 4D tensor number splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: Failed to execute 'split' on 'MLGraphBuilder': The provided value cannot be converted to a sequence." +FAIL split float32 5D tensor array splits options.axis / async promise_test: Unhandled rejection with value: object "TypeError: builder.build is not a function" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/README.md b/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/README.md deleted file mode 100644 index e7fe283..0000000 --- a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/README.md +++ /dev/null
@@ -1 +0,0 @@ -Test origin trial support for AnonymousIframe.
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/control.https.window-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/control.https.window-expected.txt deleted file mode 100644 index a4641ef5..0000000 --- a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/control.https.window-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -PASS Credentialless iframe is disabled by default -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/cookies.https.window-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/cookies.https.window-expected.txt deleted file mode 100644 index 22168ff..0000000 --- a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/cookies.https.window-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -PASS cookies -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/meta-tag.https.window-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/meta-tag.https.window-expected.txt deleted file mode 100644 index 28f521e..0000000 --- a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/meta-tag.https.window-expected.txt +++ /dev/null
@@ -1,4 +0,0 @@ -This is a testharness.js-based test. -PASS Credentialless iframe is enabled using meta tag -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/third_party.https.window-expected.txt b/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/third_party.https.window-expected.txt deleted file mode 100644 index 2e53c78..0000000 --- a/third_party/blink/web_tests/virtual/anonymous-iframe-origin-trial/wpt_internal/origin_trials/anonymous-iframe/third_party.https.window-expected.txt +++ /dev/null
@@ -1,5 +0,0 @@ -This is a testharness.js-based test. -PASS Credentialless iframe is enabled from a third party (first party POV) -PASS Credentialless iframe is enabled from a third party (third party POV) -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 b4ea454..1e03707 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
@@ -1192,6 +1192,7 @@ [Worker] method sigmoid [Worker] method slice [Worker] method softmax +[Worker] method split [Worker] method sub [Worker] method transpose [Worker] interface MLOperand
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 ae3ce84..e09fe7d 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
@@ -5552,6 +5552,7 @@ method sigmoid method slice method softmax + method split method sub method transpose interface MLModelLoader
diff --git a/third_party/ipcz/include/ipcz/ipcz.h b/third_party/ipcz/include/ipcz/ipcz.h index b6621ac..6f24302 100644 --- a/third_party/ipcz/include/ipcz/ipcz.h +++ b/third_party/ipcz/include/ipcz/ipcz.h
@@ -622,59 +622,16 @@ // the connecting node will be delegated to the connectee. #define IPCZ_CONNECT_NODE_TO_ALLOCATION_DELEGATE IPCZ_FLAG_BIT(3) -// Optional limits provided by IpczPutOptions for Put() or IpczBeginPutOptions -// for BeginPut(). -struct IPCZ_ALIGN(8) IpczPutLimits { - // The exact size of this structure in bytes. Must be set accurately before - // passing the structure to any API functions. - size_t size; - - // Specifies the maximum number of unread parcels to allow in a portal's - // queue. If a Put() or BeginPut() call specifying this limit would cause the - // receiver's number of number of queued unread parcels to exceed this value, - // the call will fail with IPCZ_RESULT_RESOURCE_EXHAUSTED. - size_t max_queued_parcels; - - // Specifies the maximum number of data bytes to allow in a portal's queue. - // If a Put() or BeginPut() call specifying this limit would cause the number - // of data bytes across all queued unread parcels to exceed this value, the - // call will fail with IPCZ_RESULT_RESOURCE_EXHAUSTED. - size_t max_queued_bytes; -}; - -// Options given to Put() to modify its default behavior. -struct IPCZ_ALIGN(8) IpczPutOptions { - // The exact size of this structure in bytes. Must be set accurately before - // passing the structure to Put(). - size_t size; - - // Optional limits to apply when determining if the Put() should be completed. - const struct IpczPutLimits* limits; -}; - // See BeginPut() and the IPCZ_BEGIN_PUT_* flags described below. typedef uint32_t IpczBeginPutFlags; // Indicates that the caller is willing to produce less data than originally // requested by their `*num_bytes` argument to BeginPut(). If the implementation -// would prefer a smaller chunk of data or if the requested size would exceed -// limits specified in the call's corresponding IpczPutLimits, passing this flag -// may allow the call to succeed while returning a smaller acceptable value in -// `*num_bytes`, rather than simply failing the call with -// IPCZ_RESULT_RESOURCE_EXHAUSTED. +// would prefer a smaller chunk of data, passing this flag may allow the call to +// succeed while returning a smaller acceptable value in `*num_bytes`, rather +// than simply failing the call with IPCZ_RESULT_RESOURCE_EXHAUSTED. #define IPCZ_BEGIN_PUT_ALLOW_PARTIAL IPCZ_FLAG_BIT(0) -// Options given to BeginPut() to modify its default behavior. -struct IPCZ_ALIGN(8) IpczBeginPutOptions { - // The exact size of this structure in bytes. Must be set accurately before - // passing the structure to BeginPut(). - size_t size; - - // Optional limits to apply when determining if the BeginPut() should be - // completed. - const struct IpczPutLimits* limits; -}; - // See EndPut() and the IPCZ_END_PUT_* flags described below. typedef uint32_t IpczEndPutFlags; @@ -820,13 +777,6 @@ // The number of unretrieved bytes (across all unretrieved parcels) queued on // this portal. size_t num_local_bytes; - - // The number of unretrieved parcels queued on the opposite portal. - size_t num_remote_parcels; - - // The number of unretrieved bytes (across all unretrieved parcels) queued on - // the opposite portal. - size_t num_remote_bytes; }; // Flags given to IpczTrapConditions to indicate which types of conditions a @@ -871,24 +821,10 @@ // IpczTrapConditions. Level-triggered. #define IPCZ_TRAP_ABOVE_MIN_LOCAL_BYTES IPCZ_FLAG_BIT(4) -// Triggers a trap event whenever the number of parcels queued for retrieval on -// the opposite portal drops below the threshold given by `max_remote_parcels` -// IpczTrapConditions. Level-triggered. -#define IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS IPCZ_FLAG_BIT(5) - -// Triggers a trap event whenever the number of bytes queued for retrieval on -// the opposite portal drops below the threshold given by `max_remote_bytes` in -// IpczTrapConditions. Level-triggered. -#define IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES IPCZ_FLAG_BIT(6) - // Triggers a trap event whenever the number of locally available parcels // increases by any amount. Edge-triggered. #define IPCZ_TRAP_NEW_LOCAL_PARCEL IPCZ_FLAG_BIT(7) -// Triggers a trap event whenever the number of queued remote parcels decreases -// by any amount. Edge-triggered. -#define IPCZ_TRAP_CONSUMED_REMOTE_PARCEL IPCZ_FLAG_BIT(8) - // Indicates that the trap event is being fired from within the extent of an // ipcz API call (i.e., as opposed to being fired from within the extent of an // incoming driver transport notification.) For example if a trap is monitoring @@ -918,14 +854,6 @@ // See IPCZ_TRAP_ABOVE_MIN_LOCAL_BYTES. If that flag is not set in `flags`, // this field is ignored. size_t min_local_bytes; - - // See IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS. If that flag is not set in `flags`, - // this field is ignored. - size_t max_remote_parcels; - - // See IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES. If that flag is not set in `flags`, - // this field is ignored. - size_t max_remote_bytes; }; // Structure passed to each IpczTrapEventHandler invocation with details about @@ -1035,11 +963,6 @@ // Nodes which will be interconnected must use the same or compatible driver // implementations. // - // `driver_node` is a driver-side handle to assign to the node throughout its - // lifetime. This handle provides the driver with additional context when ipcz - // makes driver API calls pertaining to a specific node. May be - // IPCZ_INVALID_DRIVER_HANDLE if not used by the driver. - // // If `flags` contains IPCZ_CREATE_NODE_AS_BROKER then the node will act as // the broker in its cluster of connected nodes. See details on that flag // description above. @@ -1061,7 +984,6 @@ // lock-free 32-bit and 64-bit atomics. IpczResult(IPCZ_API* CreateNode)( const struct IpczDriver* driver, // in - IpczDriverHandle driver_node, // in IpczCreateNodeFlags flags, // in const struct IpczCreateNodeOptions* options, // in IpczHandle* node); // out @@ -1257,8 +1179,6 @@ // // `flags` is unused and must be IPCZ_NO_FLAGS. // - // `options` may be null. - // // If this call fails (returning anything other than IPCZ_RESULT_OK), any // provided handles remain property of the caller. If it succeeds, their // ownership is assumed by ipcz. @@ -1271,6 +1191,8 @@ // writing. In such cases, a two-phase put operation can be used instead, by // calling BeginPut() and EndPut() as defined below. // + // `options` is ignored and must be null. + // // Returns: // // IPCZ_RESULT_OK if the provided data and handles were successfully placed @@ -1278,24 +1200,19 @@ // // IPCZ_RESULT_INVALID_ARGUMENT if `portal` is invalid, `data` is null but // `num_bytes` is non-zero, `handles` is null but `num_handles` is - // non-zero, `options` is non-null but invalid, one of the handles in - // `handles` is equal to `portal` or its (local) opposite if - // applicable, or if any handle in `handles` is invalid or not - // serializable. - // - // IPCZ_RESULT_RESOURCE_EXHAUSTED if `options->limits` is non-null and at - // least one of the specified limits would be violated by the - // successful completion of this call. + // non-zero, one of the handles in `handles` is equal to `portal` or + // its (local) opposite if applicable, or if any handle in `handles` is + // invalid or not serializable. // // IPCZ_RESULT_NOT_FOUND if it is known that the opposite portal has // already been closed and anything put into this portal would be lost. - IpczResult(IPCZ_API* Put)(IpczHandle portal, // in - const void* data, // in - size_t num_bytes, // in - const IpczHandle* handles, // in - size_t num_handles, // in - uint32_t flags, // in - const struct IpczPutOptions* options); // in + IpczResult(IPCZ_API* Put)(IpczHandle portal, // in + const void* data, // in + size_t num_bytes, // in + const IpczHandle* handles, // in + size_t num_handles, // in + uint32_t flags, // in + const void* options); // in // BeginPut() // ========== @@ -1310,17 +1227,16 @@ // of `*num_bytes` conveys the actual capacity available for writing at // `data`. // - // Limits provided to BeginPut() elicit similar behavior to Put(), with the - // exception that `flags` may specify IPCZ_BEGIN_PUT_ALLOW_PARTIAL to allow - // BeginPut() to succeed even the caller's suggested value of - // `*num_bytes` would cause the portal to exceed the maximum queued byte limit - // given by `options->limits`. In that case BeginPut() may update `*num_bytes` - // to reflect the remaining capacity of the portal, allowing the caller to - // commit at least some portion of their data with EndPut(). + // `flags` may specify IPCZ_BEGIN_PUT_ALLOW_PARTIAL to allow the + // implementation to select a smaller data size than the input value of + // `*num_bytes` if it might have a good reason to do so (e.g. performance or + // resource limitations). // // Handles to transmit within a two-phase put are provided when committing the // operation with EndPut(). // + // `options` is ignored and must be null. + // // Returns: // // IPCZ_RESULT_OK if the two-phase put operation has been successfully @@ -1331,8 +1247,7 @@ // set in `flags`) the capacity requested by the input value of // `*num_bytes`. // - // IPCZ_RESULT_INVALID_ARGUMENT if `portal` is invalid, `data` is null, or - // options is non-null but invalid. + // IPCZ_RESULT_INVALID_ARGUMENT if `portal` is invalid or `data` is null. // // IPCZ_RESULT_RESOURCE_EXHAUSTED if completing the put with the number of // bytes specified by `*num_bytes` would cause the portal to exceed the @@ -1342,12 +1257,11 @@ // // IPCZ_RESULT_NOT_FOUND if it is known that the opposite portal has // already been closed and anything put into this portal would be lost. - IpczResult(IPCZ_API* BeginPut)( - IpczHandle portal, // in - IpczBeginPutFlags flags, // in - const struct IpczBeginPutOptions* options, // in - size_t* num_bytes, // in/out - void** data); // out + IpczResult(IPCZ_API* BeginPut)(IpczHandle portal, // in + IpczBeginPutFlags flags, // in + const void* options, // in + size_t* num_bytes, // in/out + void** data); // out // EndPut() // ========
diff --git a/third_party/ipcz/src/BUILD.gn b/third_party/ipcz/src/BUILD.gn index 75928d5b..3af9916 100644 --- a/third_party/ipcz/src/BUILD.gn +++ b/third_party/ipcz/src/BUILD.gn
@@ -389,7 +389,6 @@ "ipcz/sequenced_queue_test.cc", "merge_portals_test.cc", "parcel_test.cc", - "queueing_test.cc", "reference_drivers/sync_reference_driver_test.cc", "remote_portal_test.cc", "trap_test.cc",
diff --git a/third_party/ipcz/src/api.cc b/third_party/ipcz/src/api.cc index 97f82394..417e76e 100644 --- a/third_party/ipcz/src/api.cc +++ b/third_party/ipcz/src/api.cc
@@ -31,7 +31,6 @@ } IpczResult CreateNode(const IpczDriver* driver, - IpczDriverHandle driver_node, IpczCreateNodeFlags flags, const IpczCreateNodeOptions* options, IpczHandle* node) { @@ -67,7 +66,7 @@ auto node_ptr = ipcz::MakeRefCounted<ipcz::Node>( (flags & IPCZ_CREATE_NODE_AS_BROKER) != 0 ? ipcz::Node::Type::kBroker : ipcz::Node::Type::kNormal, - *driver, driver_node, options); + *driver, options); *node = ipcz::Node::ReleaseAsHandle(std::move(node_ptr)); return IPCZ_RESULT_OK; } @@ -155,40 +154,31 @@ const IpczHandle* handles, size_t num_handles, uint32_t flags, - const IpczPutOptions* options) { + const void* options) { ipcz::Portal* portal = ipcz::Portal::FromHandle(portal_handle); if (!portal) { return IPCZ_RESULT_INVALID_ARGUMENT; } return portal->Put( absl::MakeSpan(static_cast<const uint8_t*>(data), num_bytes), - absl::MakeSpan(handles, num_handles), - options ? options->limits : nullptr); + absl::MakeSpan(handles, num_handles)); } IpczResult BeginPut(IpczHandle portal_handle, IpczBeginPutFlags flags, - const IpczBeginPutOptions* options, + const void* options, size_t* num_bytes, void** data) { ipcz::Portal* portal = ipcz::Portal::FromHandle(portal_handle); if (!portal || !data) { return IPCZ_RESULT_INVALID_ARGUMENT; } - if (options && options->size < sizeof(IpczBeginPutOptions)) { - return IPCZ_RESULT_INVALID_ARGUMENT; - } - - const IpczPutLimits* limits = options ? options->limits : nullptr; - if (limits && limits->size < sizeof(IpczPutLimits)) { - return IPCZ_RESULT_INVALID_ARGUMENT; - } size_t dummy_num_bytes = 0; if (!num_bytes) { num_bytes = &dummy_num_bytes; } - return portal->BeginPut(flags, limits, *num_bytes, *data); + return portal->BeginPut(flags, *num_bytes, *data); } IpczResult EndPut(IpczHandle portal_handle,
diff --git a/third_party/ipcz/src/api_test.cc b/third_party/ipcz/src/api_test.cc index 1eb5b3b..1636f69 100644 --- a/third_party/ipcz/src/api_test.cc +++ b/third_party/ipcz/src/api_test.cc
@@ -28,20 +28,18 @@ // Null driver. EXPECT_EQ(IPCZ_RESULT_INVALID_ARGUMENT, - ipcz().CreateNode(nullptr, IPCZ_INVALID_DRIVER_HANDLE, - IPCZ_NO_FLAGS, nullptr, &node)); + ipcz().CreateNode(nullptr, IPCZ_NO_FLAGS, nullptr, &node)); // Null output handle. - EXPECT_EQ(IPCZ_RESULT_INVALID_ARGUMENT, - ipcz().CreateNode(&kDefaultDriver, IPCZ_INVALID_DRIVER_HANDLE, - IPCZ_NO_FLAGS, nullptr, nullptr)); + EXPECT_EQ( + IPCZ_RESULT_INVALID_ARGUMENT, + ipcz().CreateNode(&kDefaultDriver, IPCZ_NO_FLAGS, nullptr, nullptr)); } TEST_F(APITest, CreateNode) { IpczHandle node; EXPECT_EQ(IPCZ_RESULT_OK, - ipcz().CreateNode(&kDefaultDriver, IPCZ_INVALID_DRIVER_HANDLE, - IPCZ_NO_FLAGS, nullptr, &node)); + ipcz().CreateNode(&kDefaultDriver, IPCZ_NO_FLAGS, nullptr, &node)); EXPECT_EQ(IPCZ_RESULT_OK, ipcz().Close(node, IPCZ_NO_FLAGS, nullptr)); } @@ -158,8 +156,6 @@ EXPECT_EQ(0u, status.flags & IPCZ_PORTAL_STATUS_DEAD); EXPECT_EQ(0u, status.num_local_parcels); EXPECT_EQ(0u, status.num_local_bytes); - EXPECT_EQ(0u, status.num_remote_parcels); - EXPECT_EQ(0u, status.num_remote_bytes); Close(b); EXPECT_EQ(IPCZ_RESULT_OK, @@ -340,11 +336,6 @@ EXPECT_EQ(IPCZ_RESULT_INVALID_ARGUMENT, ipcz().BeginPut(a, IPCZ_NO_FLAGS, nullptr, &num_bytes, nullptr)); - // Invalid options. - IpczBeginPutOptions options = {.size = 0}; - EXPECT_EQ(IPCZ_RESULT_INVALID_ARGUMENT, - ipcz().BeginPut(a, IPCZ_NO_FLAGS, &options, &num_bytes, &data)); - // Start a put transaction to test EndPut(). EXPECT_EQ(IPCZ_RESULT_OK, ipcz().BeginPut(a, IPCZ_NO_FLAGS, nullptr, &num_bytes, &data));
diff --git a/third_party/ipcz/src/ipcz/buffer_pool_test.cc b/third_party/ipcz/src/ipcz/buffer_pool_test.cc index a009ffe1..ee21cb21 100644 --- a/third_party/ipcz/src/ipcz/buffer_pool_test.cc +++ b/third_party/ipcz/src/ipcz/buffer_pool_test.cc
@@ -27,8 +27,7 @@ private: const Ref<Node> node_{ MakeRefCounted<Node>(Node::Type::kBroker, - reference_drivers::kSyncReferenceDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; + reference_drivers::kSyncReferenceDriver)}; }; TEST_F(BufferPoolTest, AddBlockBuffer) {
diff --git a/third_party/ipcz/src/ipcz/message_test.cc b/third_party/ipcz/src/ipcz/message_test.cc index ee85d11..5257ba2 100644 --- a/third_party/ipcz/src/ipcz/message_test.cc +++ b/third_party/ipcz/src/ipcz/message_test.cc
@@ -120,9 +120,8 @@ private: ::testing::StrictMock<test::MockDriver> driver_; - const Ref<Node> node_{MakeRefCounted<Node>(Node::Type::kNormal, - test::kMockDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; + const Ref<Node> node_{ + MakeRefCounted<Node>(Node::Type::kNormal, test::kMockDriver)}; const Ref<DriverTransport> transport_{MakeRefCounted<DriverTransport>( DriverObject(test::kMockDriver, kTransportHandle))}; std::queue<ReceivedMessage> received_messages_;
diff --git a/third_party/ipcz/src/ipcz/node.cc b/third_party/ipcz/src/ipcz/node.cc index e5979e6f..c8639cd 100644 --- a/third_party/ipcz/src/ipcz/node.cc +++ b/third_party/ipcz/src/ipcz/node.cc
@@ -91,12 +91,8 @@ Node::Node(Type type, const IpczDriver& driver, - IpczDriverHandle driver_node, const IpczCreateNodeOptions* options) - : type_(type), - driver_(driver), - driver_node_(driver_node), - options_(CopyOrUseDefaultOptions(options)) { + : type_(type), driver_(driver), options_(CopyOrUseDefaultOptions(options)) { if (type_ == Type::kBroker) { // Only brokers assign their own names. assigned_name_ = GenerateRandomName();
diff --git a/third_party/ipcz/src/ipcz/node.h b/third_party/ipcz/src/ipcz/node.h index c343789..e988cf2 100644 --- a/third_party/ipcz/src/ipcz/node.h +++ b/third_party/ipcz/src/ipcz/node.h
@@ -51,17 +51,13 @@ }; // Constructs a new node of the given `type`, using `driver` to support IPC. - // Note that `driver` must outlive the Node. `driver_node` is an arbitrary - // driver-specific handle that may be used for additional context when - // interfacing with the driver regarding this node. + // Note that `driver` must outlive the Node. Node(Type type, const IpczDriver& driver, - IpczDriverHandle driver_node, const IpczCreateNodeOptions* options = nullptr); Type type() const { return type_; } const IpczDriver& driver() const { return driver_; } - IpczDriverHandle driver_node() const { return driver_node_; } const IpczCreateNodeOptions& options() const { return options_; } // APIObject: @@ -196,7 +192,6 @@ const Type type_; const IpczDriver& driver_; - const IpczDriverHandle driver_node_; const IpczCreateNodeOptions options_; absl::Mutex mutex_;
diff --git a/third_party/ipcz/src/ipcz/node_connector_test.cc b/third_party/ipcz/src/ipcz/node_connector_test.cc index 1d822d6f..90d9f243 100644 --- a/third_party/ipcz/src/ipcz/node_connector_test.cc +++ b/third_party/ipcz/src/ipcz/node_connector_test.cc
@@ -27,13 +27,11 @@ class NodeConnectorTest : public test::Test { protected: Ref<Node> CreateBrokerNode() { - return MakeRefCounted<Node>(Node::Type::kBroker, kDriver, - IPCZ_INVALID_DRIVER_HANDLE); + return MakeRefCounted<Node>(Node::Type::kBroker, kDriver); } Ref<Node> CreateNonBrokerNode() { - return MakeRefCounted<Node>(Node::Type::kNormal, kDriver, - IPCZ_INVALID_DRIVER_HANDLE); + return MakeRefCounted<Node>(Node::Type::kNormal, kDriver); } Ref<Portal> CreatePortal(Ref<Node> node) {
diff --git a/third_party/ipcz/src/ipcz/node_link_memory_test.cc b/third_party/ipcz/src/ipcz/node_link_memory_test.cc index 5871d3f..7f38837 100644 --- a/third_party/ipcz/src/ipcz/node_link_memory_test.cc +++ b/third_party/ipcz/src/ipcz/node_link_memory_test.cc
@@ -85,12 +85,10 @@ } private: - const Ref<Node> node_a_{MakeRefCounted<Node>(Node::Type::kBroker, - kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; - const Ref<Node> node_b_{MakeRefCounted<Node>(Node::Type::kNormal, - kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; + const Ref<Node> node_a_{ + MakeRefCounted<Node>(Node::Type::kBroker, kTestDriver)}; + const Ref<Node> node_b_{ + MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver)}; Ref<NodeLink> link_a_; Ref<NodeLink> link_b_; }; @@ -273,8 +271,8 @@ .size = sizeof(options), .memory_flags = IPCZ_MEMORY_FIXED_PARCEL_CAPACITY, }; - const Ref<Node> node_c{MakeRefCounted<Node>( - Node::Type::kNormal, kTestDriver, IPCZ_INVALID_DRIVER_HANDLE, &options)}; + const Ref<Node> node_c{ + MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver, &options)}; node_c->SetAssignedName(kOtherTestNonBrokerName); auto links = ConnectNodes(node_a(), node_c);
diff --git a/third_party/ipcz/src/ipcz/node_link_test.cc b/third_party/ipcz/src/ipcz/node_link_test.cc index 29c26eb..9d5cff2 100644 --- a/third_party/ipcz/src/ipcz/node_link_test.cc +++ b/third_party/ipcz/src/ipcz/node_link_test.cc
@@ -57,10 +57,8 @@ using NodeLinkTest = testing::Test; TEST_F(NodeLinkTest, BasicTransmission) { - Ref<Node> node0 = MakeRefCounted<Node>(Node::Type::kBroker, kDriver, - IPCZ_INVALID_DRIVER_HANDLE); - Ref<Node> node1 = MakeRefCounted<Node>(Node::Type::kNormal, kDriver, - IPCZ_INVALID_DRIVER_HANDLE); + Ref<Node> node0 = MakeRefCounted<Node>(Node::Type::kBroker, kDriver); + Ref<Node> node1 = MakeRefCounted<Node>(Node::Type::kNormal, kDriver); // The choice of OperationContext is arbitrary and irrelevant for this test. const OperationContext context{OperationContext::kTransportNotification};
diff --git a/third_party/ipcz/src/ipcz/node_test.cc b/third_party/ipcz/src/ipcz/node_test.cc index 20ebb84..1f3caa6 100644 --- a/third_party/ipcz/src/ipcz/node_test.cc +++ b/third_party/ipcz/src/ipcz/node_test.cc
@@ -64,15 +64,12 @@ node_link->Activate(); } - const Ref<Node> broker_{MakeRefCounted<Node>(Node::Type::kBroker, - kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; - const Ref<Node> node_a_{MakeRefCounted<Node>(Node::Type::kNormal, - kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; - const Ref<Node> node_b_{MakeRefCounted<Node>(Node::Type::kNormal, - kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; + const Ref<Node> broker_{ + MakeRefCounted<Node>(Node::Type::kBroker, kTestDriver)}; + const Ref<Node> node_a_{ + MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver)}; + const Ref<Node> node_b_{ + MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver)}; }; TEST_F(NodeTest, EstablishExistingLinks) { @@ -180,8 +177,8 @@ TEST_F(NodeTest, EstablishLinkFailureWithoutBrokerLink) { // A node with no broker link can't be introduced to anyone. bool failed = false; - const Ref<Node> node_c = MakeRefCounted<Node>( - Node::Type::kNormal, kTestDriver, IPCZ_INVALID_DRIVER_HANDLE); + const Ref<Node> node_c = + MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver); EXPECT_TRUE(broker().GetLink(kNodeAName)); node_c->EstablishLink(kNodeAName, [&](NodeLink* link) { EXPECT_FALSE(link);
diff --git a/third_party/ipcz/src/ipcz/portal.cc b/third_party/ipcz/src/ipcz/portal.cc index c4b50157..d9a5b3b 100644 --- a/third_party/ipcz/src/ipcz/portal.cc +++ b/third_party/ipcz/src/ipcz/portal.cc
@@ -78,8 +78,7 @@ } IpczResult Portal::Put(absl::Span<const uint8_t> data, - absl::Span<const IpczHandle> handles, - const IpczPutLimits* limits) { + absl::Span<const IpczHandle> handles) { std::vector<Ref<APIObject>> objects; if (!ValidateAndAcquireObjectsForTransitFrom(*this, handles, objects)) { return IPCZ_RESULT_INVALID_ARGUMENT; @@ -89,10 +88,6 @@ return IPCZ_RESULT_NOT_FOUND; } - if (limits && router_->GetOutboundCapacityInBytes(*limits) < data.size()) { - return IPCZ_RESULT_RESOURCE_EXHAUSTED; - } - Parcel parcel; const IpczResult allocate_result = router_->AllocateOutboundParcel( data.size(), /*allow_partial=*/false, parcel); @@ -118,20 +113,9 @@ } IpczResult Portal::BeginPut(IpczBeginPutFlags flags, - const IpczPutLimits* limits, size_t& num_data_bytes, void*& data) { const bool allow_partial = (flags & IPCZ_BEGIN_PUT_ALLOW_PARTIAL) != 0; - if (limits) { - size_t max_num_data_bytes = router_->GetOutboundCapacityInBytes(*limits); - if (max_num_data_bytes < num_data_bytes) { - num_data_bytes = max_num_data_bytes; - if (!allow_partial || max_num_data_bytes == 0) { - return IPCZ_RESULT_RESOURCE_EXHAUSTED; - } - } - } - if (router_->IsPeerClosed()) { return IPCZ_RESULT_NOT_FOUND; }
diff --git a/third_party/ipcz/src/ipcz/portal.h b/third_party/ipcz/src/ipcz/portal.h index 174c6409..4fd064e 100644 --- a/third_party/ipcz/src/ipcz/portal.h +++ b/third_party/ipcz/src/ipcz/portal.h
@@ -49,10 +49,8 @@ IpczResult Merge(Portal& other); IpczResult Put(absl::Span<const uint8_t> data, - absl::Span<const IpczHandle> handles, - const IpczPutLimits* limits); + absl::Span<const IpczHandle> handles); IpczResult BeginPut(IpczBeginPutFlags flags, - const IpczPutLimits* limits, size_t& num_data_bytes, void*& data); IpczResult CommitPut(const void* data,
diff --git a/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc b/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc index d5a2243a..69c14d57 100644 --- a/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc +++ b/third_party/ipcz/src/ipcz/ref_counted_fragment_test.cc
@@ -159,8 +159,7 @@ } TEST_F(RefCountedFragmentTest, Free) { - auto node = MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE); + auto node = MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver); DriverMemoryWithMapping buffer = NodeLinkMemory::AllocateMemory(kTestDriver); auto memory = NodeLinkMemory::Create(std::move(node), std::move(buffer.mapping));
diff --git a/third_party/ipcz/src/ipcz/router.cc b/third_party/ipcz/src/ipcz/router.cc index 8035fa16..77263bb 100644 --- a/third_party/ipcz/src/ipcz/router.cc +++ b/third_party/ipcz/src/ipcz/router.cc
@@ -205,33 +205,6 @@ Flush(context, kForceProxyBypassAttempt); } -size_t Router::GetOutboundCapacityInBytes(const IpczPutLimits& limits) { - if (limits.max_queued_bytes == 0 || limits.max_queued_parcels == 0) { - return 0; - } - - const OperationContext context{OperationContext::kAPICall}; - absl::MutexLock lock(&mutex_); - if (status_.num_remote_parcels >= limits.max_queued_parcels || - status_.num_remote_bytes >= limits.max_queued_bytes) { - return 0; - } - - if (outbound_parcels_.GetNumAvailableElements() >= - limits.max_queued_parcels - status_.num_remote_parcels) { - return 0; - } - - const size_t num_bytes_pending = - outbound_parcels_.GetTotalAvailableElementSize(); - const size_t available_capacity = - limits.max_queued_bytes - status_.num_remote_bytes; - if (num_bytes_pending >= available_capacity) { - return 0; - } - return available_capacity - num_bytes_pending; -} - bool Router::AcceptInboundParcel(const OperationContext& context, Parcel& parcel) { TrapEventDispatcher dispatcher; @@ -309,8 +282,6 @@ status_.flags |= IPCZ_PORTAL_STATUS_PEER_CLOSED | IPCZ_PORTAL_STATUS_DEAD; } - status_.num_remote_bytes = 0; - status_.num_remote_parcels = 0; traps_.UpdatePortalStatus( context, status_, TrapSet::UpdateReason::kPeerClosed, dispatcher); } @@ -366,8 +337,6 @@ status_.flags |= IPCZ_PORTAL_STATUS_PEER_CLOSED | IPCZ_PORTAL_STATUS_DEAD; } - status_.num_remote_parcels = 0; - status_.num_remote_bytes = 0; traps_.UpdatePortalStatus(context, status_, TrapSet::UpdateReason::kPeerClosed, dispatcher); } @@ -599,8 +568,6 @@ descriptor.num_bytes_consumed); if (descriptor.peer_closed) { router->is_peer_closed_ = true; - router->status_.num_remote_parcels = 0; - router->status_.num_remote_bytes = 0; if (!router->inbound_parcels_.SetFinalSequenceLength( descriptor.closed_peer_sequence_length)) { return nullptr;
diff --git a/third_party/ipcz/src/ipcz/router.h b/third_party/ipcz/src/ipcz/router.h index 28d163337..6d8cdd5 100644 --- a/third_party/ipcz/src/ipcz/router.h +++ b/third_party/ipcz/src/ipcz/router.h
@@ -109,16 +109,6 @@ void SetOutwardLink(const OperationContext& context, const Ref<RouterLink> link); - // Returns a best-effort estimation of the maximum parcel size (in bytes) that - // can be sent outward from this router without the receiving portal exceeding - // any of the specified `limits`. - size_t GetOutboundCapacityInBytes(const IpczPutLimits& limits); - - // Returns the maximum inbound parcel size (in bytes) that can be accepted by - // this router's inbound parcel queue without that queue exceeding any of the - // specified `limits`. - size_t GetInboundCapacityInBytes(const IpczPutLimits& limits); - // Accepts an inbound parcel from the outward edge of this router, either to // queue it for retrieval or forward it further inward. `source` indicates // whether the parcel is arriving as a direct result of some local ipcz API
diff --git a/third_party/ipcz/src/ipcz/router_link_test.cc b/third_party/ipcz/src/ipcz/router_link_test.cc index 36c23ff..7676daf 100644 --- a/third_party/ipcz/src/ipcz/router_link_test.cc +++ b/third_party/ipcz/src/ipcz/router_link_test.cc
@@ -117,12 +117,10 @@ } private: - const Ref<Node> node_a_{MakeRefCounted<Node>(Node::Type::kBroker, - kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; - const Ref<Node> node_b_{MakeRefCounted<Node>(Node::Type::kNormal, - kTestDriver, - IPCZ_INVALID_DRIVER_HANDLE)}; + const Ref<Node> node_a_{ + MakeRefCounted<Node>(Node::Type::kBroker, kTestDriver)}; + const Ref<Node> node_b_{ + MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver)}; Ref<NodeLink> node_link_a_; Ref<NodeLink> node_link_b_; };
diff --git a/third_party/ipcz/src/ipcz/trap_set.cc b/third_party/ipcz/src/ipcz/trap_set.cc index c0d26cd..c0619d5c 100644 --- a/third_party/ipcz/src/ipcz/trap_set.cc +++ b/third_party/ipcz/src/ipcz/trap_set.cc
@@ -37,14 +37,6 @@ status.num_local_bytes > conditions.min_local_bytes) { event_flags |= IPCZ_TRAP_ABOVE_MIN_LOCAL_BYTES; } - if ((conditions.flags & IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS) && - status.num_remote_parcels < conditions.max_remote_parcels) { - event_flags |= IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS; - } - if ((conditions.flags & IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES) && - status.num_remote_bytes < conditions.max_remote_bytes) { - event_flags |= IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES; - } if ((conditions.flags & IPCZ_TRAP_NEW_LOCAL_PARCEL) && reason == TrapSet::UpdateReason::kNewLocalParcel) { event_flags |= IPCZ_TRAP_NEW_LOCAL_PARCEL; @@ -52,14 +44,6 @@ return event_flags; } -bool NeedRemoteParcels(IpczTrapConditionFlags flags) { - return (flags & IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS) != 0; -} - -bool NeedRemoteBytes(IpczTrapConditionFlags flags) { - return (flags & IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES) != 0; -} - } // namespace TrapSet::TrapSet() = default; @@ -102,12 +86,6 @@ } traps_.emplace_back(conditions, handler, context); - if (NeedRemoteParcels(conditions.flags)) { - ++num_traps_monitoring_remote_parcels_; - } - if (NeedRemoteBytes(conditions.flags)) { - ++num_traps_monitoring_remote_bytes_; - } return IPCZ_RESULT_OK; } @@ -130,12 +108,6 @@ } dispatcher.DeferEvent(trap.handler, trap.context, flags, status); it = traps_.erase(it); - if (NeedRemoteParcels(flags)) { - --num_traps_monitoring_remote_parcels_; - } - if (NeedRemoteBytes(flags)) { - --num_traps_monitoring_remote_bytes_; - } } } @@ -150,8 +122,6 @@ last_known_status_); } traps_.clear(); - num_traps_monitoring_remote_parcels_ = 0; - num_traps_monitoring_remote_bytes_ = 0; } TrapSet::Trap::Trap(IpczTrapConditions conditions,
diff --git a/third_party/ipcz/src/ipcz/trap_set.h b/third_party/ipcz/src/ipcz/trap_set.h index a772796..7a341c8d 100644 --- a/third_party/ipcz/src/ipcz/trap_set.h +++ b/third_party/ipcz/src/ipcz/trap_set.h
@@ -34,11 +34,6 @@ // A previously queued inbound parcel has been fully or partially retrieved // by the application. kLocalParcelConsumed, - - // A remote peer has changed state in a way that may be interesting to a - // trap in the set; for example, parcels may have been consumed from the - // remote queue. - kRemoteActivity, }; TrapSet(); @@ -50,18 +45,6 @@ bool empty() const { return traps_.empty(); } - // Indicates whether any installed traps in this set require monitoring of - // remote queue state. - bool need_remote_parcels() const { - return num_traps_monitoring_remote_parcels_ > 0; - } - bool need_remote_bytes() const { - return num_traps_monitoring_remote_bytes_ > 0; - } - bool need_remote_state() const { - return need_remote_parcels() || need_remote_bytes(); - } - // Returns the set of trap condition flags within `conditions` that would be // raised right now if a trap were installed to watch for them, given // `current_status` as the status of the portal being watched. If this returns @@ -110,8 +93,6 @@ using TrapList = absl::InlinedVector<Trap, 4>; TrapList traps_; - size_t num_traps_monitoring_remote_parcels_ = 0; - size_t num_traps_monitoring_remote_bytes_ = 0; IpczPortalStatus last_known_status_ = {.size = sizeof(last_known_status_)}; };
diff --git a/third_party/ipcz/src/queueing_test.cc b/third_party/ipcz/src/queueing_test.cc deleted file mode 100644 index 089e9df..0000000 --- a/third_party/ipcz/src/queueing_test.cc +++ /dev/null
@@ -1,275 +0,0 @@ -// Copyright 2022 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include <limits> -#include <string> - -#include "ipcz/ipcz.h" -#include "test/multinode_test.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/abseil-cpp/absl/synchronization/notification.h" - -namespace ipcz { -namespace { - -using QueueingTestNode = test::TestNode; -using QueueingTest = test::MultinodeTest<QueueingTestNode>; - -MULTINODE_TEST_NODE(QueueingTestNode, RemoteQueueFeedbackClient) { - IpczHandle b = ConnectToBroker(); - - // Wait for the first parcel to arrive. - EXPECT_EQ(IPCZ_RESULT_OK, - WaitForConditions(b, {.flags = IPCZ_TRAP_ABOVE_MIN_LOCAL_PARCELS, - .min_local_parcels = 0})); - - // Send and ack and wait for another parcel to arrive. - absl::Notification new_parcel_arrived; - EXPECT_EQ(IPCZ_RESULT_OK, - Trap(b, {.flags = IPCZ_TRAP_NEW_LOCAL_PARCEL}, - [&](const IpczTrapEvent&) { new_parcel_arrived.Notify(); })); - EXPECT_EQ(IPCZ_RESULT_OK, Put(b, "ok")); - new_parcel_arrived.WaitForNotification(); - - std::string data; - EXPECT_EQ(IPCZ_RESULT_OK, Get(b, &data)); - EXPECT_EQ("1234", data); - - std::string ack; - EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(b, &ack)); - EXPECT_EQ("ok", ack); - - EXPECT_EQ(IPCZ_RESULT_OK, WaitForConditionFlags(b, IPCZ_TRAP_PEER_CLOSED)); - Close(b); -} - -// Disabled because remote queue state monitoring has been temporarily dropped -// from ipcz to improve performance. See https://crbug.com/1383754. -MULTINODE_TEST(QueueingTest, DISABLED_RemoteQueueFeedback) { - // Exercises operations which rely on feedback from the remote peer regarding - // its inbound parcel queue state. - IpczHandle c = SpawnTestNode<RemoteQueueFeedbackClient>(); - - // This trap can only be set while the remote portal appears to be non-empty. - const IpczTrapConditions all_bytes_consumed = { - .size = sizeof(all_bytes_consumed), - .flags = IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES, - .max_remote_bytes = 1, - }; - EXPECT_EQ(IPCZ_RESULT_FAILED_PRECONDITION, - Trap(c, all_bytes_consumed, [&](const auto&) {})); - - // Send 4 bytes and wait for acknowledgement that the parcel was received. - std::string ack; - EXPECT_EQ(IPCZ_RESULT_OK, Put(c, "1234")); - EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(c, &ack)); - EXPECT_EQ("ok", ack); - - // Now these operations should always fail due to the specified limits. - EXPECT_EQ(IPCZ_RESULT_RESOURCE_EXHAUSTED, - PutWithLimits(c, {.max_queued_parcels = 1}, "meh")); - EXPECT_EQ(IPCZ_RESULT_RESOURCE_EXHAUSTED, - PutWithLimits(c, {.max_queued_bytes = 4}, "?")); - - // Now we should be able to install traps for both queued parcels and bytes on - // the remote side. - absl::Notification consumed_parcels; - const IpczTrapConditions all_parcels_consumed = { - .size = sizeof(all_parcels_consumed), - .flags = IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS, - .max_remote_parcels = 1, - }; - EXPECT_EQ( - IPCZ_RESULT_OK, - Trap(c, all_parcels_consumed, [&](const IpczTrapEvent& event) { - EXPECT_TRUE(event.condition_flags & IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS); - consumed_parcels.Notify(); - })); - - absl::Notification consumed_bytes; - EXPECT_EQ( - IPCZ_RESULT_OK, - Trap(c, all_bytes_consumed, [&](const IpczTrapEvent& event) { - EXPECT_TRUE(event.condition_flags & IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES); - consumed_bytes.Notify(); - })); - - // Ack back to the client so it will read its queue. Then we can wait for both - // traps to notify. - EXPECT_EQ(IPCZ_RESULT_OK, Put(c, "ok")); - consumed_parcels.WaitForNotification(); - consumed_bytes.WaitForNotification(); - - // And now this Put operation should succeed. - EXPECT_EQ(IPCZ_RESULT_OK, - PutWithLimits(c, {.max_queued_parcels = 1, .max_queued_bytes = 4}, - "meh!")); - - Close(c); -} - -MULTINODE_TEST_NODE(QueueingTestNode, TwoPhaseQueueingClient) { - IpczHandle b = ConnectToBroker(); - WaitForDirectRemoteLink(b); - EXPECT_EQ(IPCZ_RESULT_OK, Put(b, "go")); - - EXPECT_EQ(IPCZ_RESULT_OK, - WaitForConditions(b, {.flags = IPCZ_TRAP_ABOVE_MIN_LOCAL_PARCELS, - .min_local_parcels = 0})); - size_t num_bytes; - const void* data; - EXPECT_EQ(IPCZ_RESULT_OK, ipcz().BeginGet(b, IPCZ_NO_FLAGS, nullptr, &data, - &num_bytes, nullptr)); - - // The producer should only have been able to put 3 out of its 4 bytes. - EXPECT_EQ("ipc", - std::string_view(reinterpret_cast<const char*>(data), num_bytes)); - EXPECT_EQ(IPCZ_RESULT_OK, - ipcz().EndGet(b, num_bytes, 0, IPCZ_NO_FLAGS, nullptr, nullptr)); - - Close(b); -} - -// Disabled because remote queue state monitoring has been temporarily dropped -// from ipcz to improve performance. See https://crbug.com/1383754. -MULTINODE_TEST(QueueingTest, DISABLED_TwoPhaseQueueing) { - IpczHandle c = SpawnTestNode<TwoPhaseQueueingClient>(); - WaitForDirectRemoteLink(c); - - std::string message; - EXPECT_EQ(IPCZ_RESULT_OK, WaitToGet(c, &message)); - EXPECT_EQ("go", message); - - const IpczPutLimits limits = { - .size = sizeof(limits), - .max_queued_parcels = 1, - .max_queued_bytes = 3, - }; - - size_t num_bytes = 4; - void* data; - const IpczBeginPutOptions options = {.size = sizeof(options), - .limits = &limits}; - EXPECT_EQ(IPCZ_RESULT_OK, ipcz().BeginPut(c, IPCZ_BEGIN_PUT_ALLOW_PARTIAL, - &options, &num_bytes, &data)); - - // There should not be enough space for all 4 bytes. - EXPECT_EQ(3u, num_bytes); - memcpy(data, "ipc", 3); - EXPECT_EQ(IPCZ_RESULT_OK, ipcz().EndPut(c, data, num_bytes, nullptr, 0, - IPCZ_NO_FLAGS, nullptr)); - - EXPECT_EQ(IPCZ_RESULT_OK, WaitForConditionFlags(c, IPCZ_TRAP_PEER_CLOSED)); - Close(c); -} - -MULTINODE_TEST_NODE(QueueingTestNode, TwoPhaseFeedbackClient) { - IpczHandle b = ConnectToBroker(); - WaitForDirectRemoteLink(b); - - EXPECT_EQ(IPCZ_RESULT_OK, - WaitForConditions(b, {.flags = IPCZ_TRAP_ABOVE_MIN_LOCAL_PARCELS, - .min_local_parcels = 0})); - size_t num_bytes; - const void* data; - EXPECT_EQ(IPCZ_RESULT_OK, ipcz().BeginGet(b, IPCZ_NO_FLAGS, nullptr, &data, - &num_bytes, nullptr)); - - EXPECT_EQ("hello?", - std::string_view(reinterpret_cast<const char*>(data), num_bytes)); - EXPECT_EQ(IPCZ_RESULT_OK, - ipcz().EndGet(b, num_bytes, 0, IPCZ_NO_FLAGS, nullptr, nullptr)); - Close(b); -} - -// TODO(https://crbug.com/1361670): Fix flakiness and re-enable this test. -MULTINODE_TEST(QueueingTest, DISABLED_TwoPhaseFeedback) { - IpczHandle c = SpawnTestNode<TwoPhaseFeedbackClient>(); - WaitForDirectRemoteLink(c); - EXPECT_EQ(IPCZ_RESULT_OK, Put(c, "hello?")); - EXPECT_EQ(IPCZ_RESULT_OK, - WaitForConditions(c, {.flags = IPCZ_TRAP_BELOW_MAX_REMOTE_PARCELS, - .max_remote_parcels = 1})); - Close(c); -} - -constexpr size_t kStressTestPortalCapacity = 256; -constexpr size_t kStressTestPayloadSize = 4 * 1024 * 1024; - -MULTINODE_TEST_NODE(QueueingTestNode, RemoteQueueFeedbackStressTestClient) { - IpczHandle b = ConnectToBroker(); - - size_t bytes_received = 0; - while (bytes_received < kStressTestPayloadSize) { - // Consistency check: ensure that the portal never has more than - // kStressTestPortalCapacity bytes available to retrieve. Otherwise limits - // were not properly enforced by the sender. - IpczPortalStatus status = {.size = sizeof(status)}; - EXPECT_EQ(IPCZ_RESULT_OK, - ipcz().QueryPortalStatus(b, IPCZ_NO_FLAGS, nullptr, &status)); - EXPECT_LE(status.num_local_bytes, kStressTestPortalCapacity); - - const void* data; - size_t num_bytes; - const IpczResult begin_result = - ipcz().BeginGet(b, IPCZ_NO_FLAGS, nullptr, &data, &num_bytes, nullptr); - if (begin_result == IPCZ_RESULT_OK) { - bytes_received += num_bytes; - EXPECT_EQ(std::string_view(static_cast<const char*>(data), num_bytes), - std::string(num_bytes, '!')); - EXPECT_EQ(IPCZ_RESULT_OK, ipcz().EndGet(b, num_bytes, 0, IPCZ_NO_FLAGS, - nullptr, nullptr)); - continue; - } - - ASSERT_EQ(IPCZ_RESULT_UNAVAILABLE, begin_result); - WaitForConditions( - b, {.flags = IPCZ_TRAP_ABOVE_MIN_LOCAL_BYTES, .min_local_bytes = 0}); - } - - Close(b); -} - -// Disabled because remote queue state monitoring has been temporarily dropped -// from ipcz to improve performance. See https://crbug.com/1383754. -MULTINODE_TEST(QueueingTest, DISABLED_RemoteQueueFeedbackStressTest) { - IpczHandle c = SpawnTestNode<RemoteQueueFeedbackStressTestClient>(); - - size_t bytes_remaining = kStressTestPayloadSize; - while (bytes_remaining) { - void* data; - size_t capacity = bytes_remaining; - const IpczPutLimits limits = { - .size = sizeof(limits), - .max_queued_parcels = std::numeric_limits<size_t>::max(), - .max_queued_bytes = kStressTestPortalCapacity, - }; - const IpczBeginPutOptions options = { - .size = sizeof(options), - .limits = &limits, - }; - const IpczResult begin_result = ipcz().BeginPut( - c, IPCZ_BEGIN_PUT_ALLOW_PARTIAL, &options, &capacity, &data); - if (begin_result == IPCZ_RESULT_OK) { - size_t num_bytes = std::min(bytes_remaining, capacity); - bytes_remaining -= num_bytes; - memset(data, '!', num_bytes); - EXPECT_EQ(IPCZ_RESULT_OK, ipcz().EndPut(c, data, num_bytes, nullptr, 0, - IPCZ_NO_FLAGS, nullptr)); - continue; - } - ASSERT_EQ(IPCZ_RESULT_RESOURCE_EXHAUSTED, begin_result); - - EXPECT_EQ( - IPCZ_RESULT_OK, - WaitForConditions(c, {.flags = IPCZ_TRAP_BELOW_MAX_REMOTE_BYTES, - .max_remote_bytes = kStressTestPortalCapacity})); - } - - WaitForConditionFlags(c, IPCZ_TRAP_PEER_CLOSED); - Close(c); -} - -} // namespace -} // namespace ipcz
diff --git a/third_party/ipcz/src/test/multinode_test.cc b/third_party/ipcz/src/test/multinode_test.cc index 3c157b48..8f9ca93 100644 --- a/third_party/ipcz/src/test/multinode_test.cc +++ b/third_party/ipcz/src/test/multinode_test.cc
@@ -324,8 +324,7 @@ GetDetails().is_broker ? IPCZ_CREATE_NODE_AS_BROKER : IPCZ_NO_FLAGS; ABSL_ASSERT(node_ == IPCZ_INVALID_HANDLE); const IpczResult result = - ipcz().CreateNode(&test_driver_->GetIpczDriver(), - IPCZ_INVALID_DRIVER_HANDLE, flags, nullptr, &node_); + ipcz().CreateNode(&test_driver_->GetIpczDriver(), flags, nullptr, &node_); ABSL_ASSERT(result == IPCZ_RESULT_OK); }
diff --git a/third_party/ipcz/src/test/test_base.cc b/third_party/ipcz/src/test/test_base.cc index 50dcd2a..c70c5e7 100644 --- a/third_party/ipcz/src/test/test_base.cc +++ b/third_party/ipcz/src/test/test_base.cc
@@ -23,8 +23,7 @@ const IpczDriver& driver, IpczCreateNodeFlags flags, IpczHandle& handle) { - const IpczResult result = ipcz.CreateNode(&driver, IPCZ_INVALID_DRIVER_HANDLE, - flags, nullptr, &handle); + const IpczResult result = ipcz.CreateNode(&driver, flags, nullptr, &handle); ASSERT_EQ(IPCZ_RESULT_OK, result); } @@ -79,20 +78,6 @@ handles.size(), IPCZ_NO_FLAGS, nullptr); } -IpczResult TestBase::PutWithLimits(IpczHandle portal, - const IpczPutLimits& limits, - std::string_view message, - absl::Span<IpczHandle> handles) { - IpczPutLimits sized_limits = limits; - sized_limits.size = sizeof(sized_limits); - const IpczPutOptions options = { - .size = sizeof(options), - .limits = &sized_limits, - }; - return ipcz().Put(portal, message.data(), message.size(), handles.data(), - handles.size(), IPCZ_NO_FLAGS, &options); -} - IpczResult TestBase::Get(IpczHandle portal, std::string* message, absl::Span<IpczHandle> handles) {
diff --git a/third_party/ipcz/src/test/test_base.h b/third_party/ipcz/src/test/test_base.h index 8540644..19a7a33c 100644 --- a/third_party/ipcz/src/test/test_base.h +++ b/third_party/ipcz/src/test/test_base.h
@@ -42,10 +42,6 @@ IpczResult Put(IpczHandle portal, std::string_view message, absl::Span<IpczHandle> handles = {}); - IpczResult PutWithLimits(IpczHandle portal, - const IpczPutLimits& limits, - std::string_view message, - absl::Span<IpczHandle> handles = {}); // Shorthand for ipcz Get() to retrieve the next available parcel from // `portal`.If no parcel is available, or any other condition prevents Get()
diff --git a/third_party/node/PRESUBMIT.py b/third_party/node/PRESUBMIT.py index 5f0c982..c769720 100644 --- a/third_party/node/PRESUBMIT.py +++ b/third_party/node/PRESUBMIT.py
@@ -19,6 +19,6 @@ if any(f for f in files if f.startswith('clean_json_attrs')): tests = [path.join(cwd, 'clean_json_attrs_test.py')] return input_api.canned_checks.RunUnitTests( - input_api, output_api, tests, run_on_python2=False) + input_api, output_api, tests) return []
diff --git a/third_party/sqlite/PRESUBMIT.py b/third_party/sqlite/PRESUBMIT.py index fef4358b..1d79b48 100644 --- a/third_party/sqlite/PRESUBMIT.py +++ b/third_party/sqlite/PRESUBMIT.py
@@ -18,9 +18,6 @@ output_api, input_api.os_path.join(this_dir, 'scripts'), files_to_check=['.*unittest.py$'], - env=None, - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + env=None)) return results
diff --git a/tools/PRESUBMIT.py b/tools/PRESUBMIT.py index d20f393..9161e843 100644 --- a/tools/PRESUBMIT.py +++ b/tools/PRESUBMIT.py
@@ -4,10 +4,6 @@ PRESUBMIT_VERSION = '2.0.0' -# This line is 'magic' in that git-cl looks for it to decide whether to -# use Python3 instead of Python2 when running the code in this file. -USE_PYTHON3 = True - def CheckPythonTests(input_api, output_api): return input_api.RunTests( @@ -15,7 +11,4 @@ input_api, output_api, input_api.PresubmitLocalPath(), - files_to_check=[r'.+_(?:unit)?test\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + files_to_check=[r'.+_(?:unit)?test\.py$']))
diff --git a/tools/android/checkxmlstyle/PRESUBMIT.py b/tools/android/checkxmlstyle/PRESUBMIT.py index f4c3aba..4a34c0b 100644 --- a/tools/android/checkxmlstyle/PRESUBMIT.py +++ b/tools/android/checkxmlstyle/PRESUBMIT.py
@@ -9,9 +9,6 @@ """ -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): return _CommonChecks(input_api, output_api) @@ -23,9 +20,6 @@ def _CommonChecks(input_api, output_api): result = [] result.extend( - input_api.canned_checks.RunUnitTests(input_api, - output_api, - ['./checkxmlstyle_test.py'], - run_on_python2=False, - run_on_python3=True)) + input_api.canned_checks.RunUnitTests(input_api, output_api, + ['./checkxmlstyle_test.py'])) return result
diff --git a/tools/android/customtabs_benchmark/scripts/PRESUBMIT.py b/tools/android/customtabs_benchmark/scripts/PRESUBMIT.py index b416af6f..3b2f173f 100644 --- a/tools/android/customtabs_benchmark/scripts/PRESUBMIT.py +++ b/tools/android/customtabs_benchmark/scripts/PRESUBMIT.py
@@ -9,9 +9,6 @@ """ -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): output = [] # These tests don't run on Windows and give verbose and cryptic failure
diff --git a/tools/android/dependency_analysis/PRESUBMIT.py b/tools/android/dependency_analysis/PRESUBMIT.py index afe3b479..cc4b2ce 100644 --- a/tools/android/dependency_analysis/PRESUBMIT.py +++ b/tools/android/dependency_analysis/PRESUBMIT.py
@@ -8,19 +8,13 @@ """ -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): checks = input_api.canned_checks.GetUnitTestsRecursively( input_api, output_api, input_api.PresubmitLocalPath(), files_to_check=[r'.+_unittest\.py$'], - files_to_skip=[], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + files_to_skip=[]) return input_api.RunTests(checks, False)
diff --git a/tools/android/infobar_deprecation/PRESUBMIT.py b/tools/android/infobar_deprecation/PRESUBMIT.py index 4b77833..d952a37 100644 --- a/tools/android/infobar_deprecation/PRESUBMIT.py +++ b/tools/android/infobar_deprecation/PRESUBMIT.py
@@ -6,14 +6,10 @@ Runs Python unit tests in /tools/android/infobar_deprecation on upload. """ -USE_PYTHON3 = True - def CheckChangeOnUpload(input_api, output_api): result = [] result.extend( - input_api.canned_checks.RunUnitTests(input_api, - output_api, - ['./infobar_deprecation_test.py'], - run_on_python2=False)) + input_api.canned_checks.RunUnitTests(input_api, output_api, + ['./infobar_deprecation_test.py'])) return result
diff --git a/tools/android/native_lib_memory/PRESUBMIT.py b/tools/android/native_lib_memory/PRESUBMIT.py index 0d83089..d435fd2 100644 --- a/tools/android/native_lib_memory/PRESUBMIT.py +++ b/tools/android/native_lib_memory/PRESUBMIT.py
@@ -9,9 +9,6 @@ """ -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): output = [] files_to_skip = []
diff --git a/tools/android/python_utils/PRESUBMIT.py b/tools/android/python_utils/PRESUBMIT.py index 9d79f84..2cf847e 100644 --- a/tools/android/python_utils/PRESUBMIT.py +++ b/tools/android/python_utils/PRESUBMIT.py
@@ -8,7 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' @@ -23,8 +22,6 @@ output_api, input_api.PresubmitLocalPath(), files_to_check=[r'.+_unittest\.py$'], - files_to_skip=[], - run_on_python2=False, - run_on_python3=True) + files_to_skip=[]) return input_api.RunTests(checks, False)
diff --git a/tools/android/test_health/PRESUBMIT.py b/tools/android/test_health/PRESUBMIT.py index d13448f..6bd6eb2 100644 --- a/tools/android/test_health/PRESUBMIT.py +++ b/tools/android/test_health/PRESUBMIT.py
@@ -9,7 +9,6 @@ import pathlib -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' @@ -26,9 +25,7 @@ output_api, input_api.PresubmitLocalPath(), files_to_check=[r'.+_unittest\.py$'], - files_to_skip=[], - run_on_python2=False, - run_on_python3=True) + files_to_skip=[]) return input_api.RunTests(checks, False)
diff --git a/tools/binary_size/PRESUBMIT.py b/tools/binary_size/PRESUBMIT.py index 0064a08..7b57d4f 100644 --- a/tools/binary_size/PRESUBMIT.py +++ b/tools/binary_size/PRESUBMIT.py
@@ -8,7 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' @@ -32,10 +31,7 @@ output_api, input_api.PresubmitLocalPath(), files_to_check=[r'.+_test\.py$'], - files_to_skip=[], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + files_to_skip=[]) output.extend(input_api.RunTests(py_tests, False)) return output
diff --git a/tools/checkperms/PRESUBMIT.py b/tools/checkperms/PRESUBMIT.py index cd5d173..648589cc 100644 --- a/tools/checkperms/PRESUBMIT.py +++ b/tools/checkperms/PRESUBMIT.py
@@ -9,18 +9,14 @@ """ -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): output = [] output.extend( input_api.canned_checks.RunPylint(input_api, output_api, version='2.7')) # Run it like if it were a unit test. output.extend( - input_api.canned_checks.RunUnitTests(input_api, - output_api, ['./checkperms.py'], - run_on_python2=False)) + input_api.canned_checks.RunUnitTests(input_api, output_api, + ['./checkperms.py'])) return output
diff --git a/tools/checkteamtags/PRESUBMIT.py b/tools/checkteamtags/PRESUBMIT.py index 99f00bf5..1dfd911 100644 --- a/tools/checkteamtags/PRESUBMIT.py +++ b/tools/checkteamtags/PRESUBMIT.py
@@ -9,9 +9,6 @@ """ -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): return _CommonChecks(input_api, output_api)
diff --git a/tools/clang/plugins/RawPtrHelpers.cpp b/tools/clang/plugins/RawPtrHelpers.cpp index 3414028c..5c8e4e76 100644 --- a/tools/clang/plugins/RawPtrHelpers.cpp +++ b/tools/clang/plugins/RawPtrHelpers.cpp
@@ -118,14 +118,14 @@ isInGeneratedLocation(), isInLocationListedInFilterFile(options.paths_to_exclude), isFieldDeclListedInFilterFile(options.fields_to_exclude), - ImplicitFieldDeclaration()); + ImplicitFieldDeclaration(), isObjCSynthesize()); } else { return anyOf(isExpansionInSystemHeader(), isInExternCContext(), isRawPtrExclusionAnnotated(), isInThirdPartyLocation(), isInGeneratedLocation(), isInLocationListedInFilterFile(options.paths_to_exclude), isFieldDeclListedInFilterFile(options.fields_to_exclude), - ImplicitFieldDeclaration(), + ImplicitFieldDeclaration(), isObjCSynthesize(), hasDescendant(StackAllocatedQualType( options.stack_allocated_predicate))); }
diff --git a/tools/clang/plugins/RawPtrHelpers.h b/tools/clang/plugins/RawPtrHelpers.h index ed09b28..04d85a90 100644 --- a/tools/clang/plugins/RawPtrHelpers.h +++ b/tools/clang/plugins/RawPtrHelpers.h
@@ -198,6 +198,12 @@ } } +// Matches Objective-C @synthesize field declaration. +AST_MATCHER(clang::Decl, isObjCSynthesize) { + const auto* ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(&Node); + return ivar_decl && ivar_decl->getSynthesize(); +} + // Matches field declarations that do not explicitly appear in the source // code: // 1. fields of classes generated by the compiler to back capturing lambdas,
diff --git a/tools/clang/plugins/RawPtrManualPathsToIgnore.h b/tools/clang/plugins/RawPtrManualPathsToIgnore.h index b50c4b2..351145d 100644 --- a/tools/clang/plugins/RawPtrManualPathsToIgnore.h +++ b/tools/clang/plugins/RawPtrManualPathsToIgnore.h
@@ -35,6 +35,10 @@ // win:pe_image target that uses this file does not depend on base/. "base/no_destructor.h", + // Can't depend on //base, pointers/references under this directory can't be + // rewritten. + "testing/rust_gtest_interop/", + // Exclude - deprecated and contains legacy C++ and pre-C++11 code. "ppapi/",
diff --git a/tools/clang/plugins/tests/raw_ptr_fields_objc.flags b/tools/clang/plugins/tests/raw_ptr_fields_objc.flags new file mode 100644 index 0000000..31530c7 --- /dev/null +++ b/tools/clang/plugins/tests/raw_ptr_fields_objc.flags
@@ -0,0 +1 @@ +--target=arm64-apple-macosx -Xclang -plugin-arg-find-bad-constructs -Xclang check-raw-ptr-fields -Wobjc-root-class
diff --git a/tools/clang/plugins/tests/raw_ptr_fields_objc.mm b/tools/clang/plugins/tests/raw_ptr_fields_objc.mm new file mode 100644 index 0000000..87e95a9 --- /dev/null +++ b/tools/clang/plugins/tests/raw_ptr_fields_objc.mm
@@ -0,0 +1,14 @@ +// 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. + +__attribute__((objc_root_class)) +@interface MyInterface {} +@property(readonly) int* p; +@end + +@implementation MyInterface +// @synthesize will automatically declares `int* _p`. +// The plugin should explicitly exclude a synthesized field from the check. +@synthesize p; +@end
diff --git a/tools/clang/plugins/tests/raw_ptr_fields_objc.txt b/tools/clang/plugins/tests/raw_ptr_fields_objc.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tools/clang/plugins/tests/raw_ptr_fields_objc.txt
diff --git a/tools/clang/pylib/clang/PRESUBMIT.py b/tools/clang/pylib/clang/PRESUBMIT.py index df54e08f..34dbacf 100644 --- a/tools/clang/pylib/clang/PRESUBMIT.py +++ b/tools/clang/pylib/clang/PRESUBMIT.py
@@ -3,18 +3,12 @@ # found in the LICENSE file. -USE_PYTHON3 = True - - def CheckChangeOnCommit(input_api, output_api): results = [] # Run the unit tests. results.extend( - input_api.canned_checks.RunUnitTestsInDirectory(input_api, - output_api, - '.', [r'^.+_test\.py$'], - run_on_python2=False, - skip_shebang_check=True)) + input_api.canned_checks.RunUnitTestsInDirectory(input_api, output_api, + '.', [r'^.+_test\.py$'])) return results
diff --git a/tools/clang/pylib/clang/plugin_testing.py b/tools/clang/pylib/clang/plugin_testing.py index 2c0beb76..868fc1e 100755 --- a/tools/clang/pylib/clang/plugin_testing.py +++ b/tools/clang/pylib/clang/plugin_testing.py
@@ -55,7 +55,7 @@ passing = [] failing = [] - tests = glob.glob('*.cpp') + tests = glob.glob('*.cpp') + glob.glob('*.mm') for test in tests: sys.stdout.write('Testing %s... ' % test) test_name, _ = os.path.splitext(test)
diff --git a/tools/clang/scripts/package.py b/tools/clang/scripts/package.py index be0e2386..00858cc3 100755 --- a/tools/clang/scripts/package.py +++ b/tools/clang/scripts/package.py
@@ -208,7 +208,7 @@ '--no-git', # Just run locally, don't upload anything. '--clang-git-hash=' + args.revision ] - subprocess.call(cmd) + subprocess.run(cmd, check=True) # This needs to happen after upload_revision.py modifies update.py. from update import PACKAGE_VERSION, RELEASE_VERSION, STAMP_FILE
diff --git a/tools/code_coverage/js_source_maps/create_js_source_maps/PRESUBMIT.py b/tools/code_coverage/js_source_maps/create_js_source_maps/PRESUBMIT.py index e0d126e..5fc2b9b 100644 --- a/tools/code_coverage/js_source_maps/create_js_source_maps/PRESUBMIT.py +++ b/tools/code_coverage/js_source_maps/create_js_source_maps/PRESUBMIT.py
@@ -8,7 +8,6 @@ """ import sys -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' @@ -34,11 +33,8 @@ def CheckUnittests(input_api, output_api): - results = input_api.canned_checks.RunUnitTests( - input_api, - output_api, [ - input_api.os_path.join(input_api.PresubmitLocalPath(), 'test', - 'create_js_source_maps_test.py') - ], - run_on_python2=False) + results = input_api.canned_checks.RunUnitTests(input_api, output_api, [ + input_api.os_path.join(input_api.PresubmitLocalPath(), 'test', + 'create_js_source_maps_test.py') + ]) return results
diff --git a/tools/cygprofile/PRESUBMIT.py b/tools/cygprofile/PRESUBMIT.py index 5dbf70c..068a339 100644 --- a/tools/cygprofile/PRESUBMIT.py +++ b/tools/cygprofile/PRESUBMIT.py
@@ -9,9 +9,6 @@ """ -USE_PYTHON3 = True - - def CommonChecks(input_api, output_api): output = [] files_to_skip = [] @@ -25,13 +22,9 @@ # messages. if input_api.sys.platform != 'win32': output.extend( - input_api.canned_checks.RunUnitTests( - input_api, - output_api, [ - input_api.os_path.join(input_api.PresubmitLocalPath(), - 'run_tests') - ], - run_on_python2=False)) + input_api.canned_checks.RunUnitTests(input_api, output_api, [ + input_api.os_path.join(input_api.PresubmitLocalPath(), 'run_tests') + ])) return output
diff --git a/tools/disable_tests/PRESUBMIT.py b/tools/disable_tests/PRESUBMIT.py index 1462f6f0..8ce8b6ed 100644 --- a/tools/disable_tests/PRESUBMIT.py +++ b/tools/disable_tests/PRESUBMIT.py
@@ -7,8 +7,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def _CommonChecks(input_api, output_api): results = [] @@ -22,10 +20,7 @@ output_api, input_api.os_path.join(input_api.PresubmitLocalPath()), files_to_check=[r'.+_test\.py$'], - files_to_skip=['integration_test.py'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + files_to_skip=['integration_test.py'])) # integration_test.py uses subcommands, so we can't use the standard unit test # presubmit API to run it. @@ -35,7 +30,6 @@ cmd=['integration_test.py', 'run'], kwargs={}, message=output_api.PresubmitError, - python3=True, )) results.extend(input_api.RunTests(commands))
diff --git a/tools/find_runtime_symbols/PRESUBMIT.py b/tools/find_runtime_symbols/PRESUBMIT.py index 2f2c4428..09bd687 100644 --- a/tools/find_runtime_symbols/PRESUBMIT.py +++ b/tools/find_runtime_symbols/PRESUBMIT.py
@@ -10,8 +10,6 @@ import sys -USE_PYTHON3 = True - def CommonChecks(input_api, output_api): def join(*args): @@ -33,9 +31,7 @@ input_api, output_api, input_api.os_path.join(input_api.PresubmitLocalPath(), 'tests'), - files_to_check=[r'.+_test\.py$'], - run_on_python2=False, - skip_shebang_check=True)) + files_to_check=[r'.+_test\.py$'])) return output
diff --git a/tools/grit/PRESUBMIT.py b/tools/grit/PRESUBMIT.py index c3028c6..91cb8a2 100644 --- a/tools/grit/PRESUBMIT.py +++ b/tools/grit/PRESUBMIT.py
@@ -8,20 +8,14 @@ details on the presubmit API built into gcl. """ -USE_PYTHON3 = True - def RunUnittests(input_api, output_api): presubmit_path = input_api.PresubmitLocalPath() - return input_api.canned_checks.RunUnitTests( - input_api, - output_api, [ - input_api.os_path.join('grit', 'test_suite_all.py'), - input_api.os_path.join(input_api.PresubmitLocalPath(), - 'preprocess_if_expr_test.py') - ], - run_on_python2=False, - skip_shebang_check=True) + return input_api.canned_checks.RunUnitTests(input_api, output_api, [ + input_api.os_path.join('grit', 'test_suite_all.py'), + input_api.os_path.join(input_api.PresubmitLocalPath(), + 'preprocess_if_expr_test.py') + ]) def CheckChangeOnUpload(input_api, output_api):
diff --git a/tools/idl_parser/PRESUBMIT.py b/tools/idl_parser/PRESUBMIT.py index 69ac9de..f9d52fa 100644 --- a/tools/idl_parser/PRESUBMIT.py +++ b/tools/idl_parser/PRESUBMIT.py
@@ -2,19 +2,13 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True CHECK_FILES = [r'^.+_test\.py$'] def _RunTests(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=CHECK_FILES, - run_on_python2=False, - skip_shebang_check=True) + input_api, output_api, '.', files_to_check=CHECK_FILES) def CheckChangeOnUpload(input_api, output_api):
diff --git a/tools/infra/PRESUBMIT.py b/tools/infra/PRESUBMIT.py index 512cb706..152f9065 100644 --- a/tools/infra/PRESUBMIT.py +++ b/tools/infra/PRESUBMIT.py
@@ -22,10 +22,7 @@ output_api, input_api.os_path.join(input_api.PresubmitLocalPath()), files_to_check=[r'.+_unittest\.py$'], - files_to_skip=[], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + files_to_skip=[])) results.extend(input_api.RunTests(commands)) return results
diff --git a/tools/json_data_generator/PRESUBMIT.py b/tools/json_data_generator/PRESUBMIT.py index 8f5313a..4ead6d2 100644 --- a/tools/json_data_generator/PRESUBMIT.py +++ b/tools/json_data_generator/PRESUBMIT.py
@@ -8,7 +8,6 @@ """ import os -USE_PYTHON3 = True TEST_PATTERNS = [r'.+_test.py$'] @@ -21,13 +20,7 @@ env['PYTHONPATH'] = input_api.os_path.pathsep.join((pythonpath)) return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=TEST_PATTERNS, - env=env, - run_on_python2=False, - skip_shebang_check=True) + input_api, output_api, '.', files_to_check=TEST_PATTERNS, env=env) def CheckChangeOnUpload(input_api, output_api):
diff --git a/tools/json_schema_compiler/PRESUBMIT.py b/tools/json_schema_compiler/PRESUBMIT.py index cf1502e..ad70639 100644 --- a/tools/json_schema_compiler/PRESUBMIT.py +++ b/tools/json_schema_compiler/PRESUBMIT.py
@@ -11,7 +11,6 @@ import sys FILE_PATTERN = [ r'.+_test.py$' ] -USE_PYTHON3 = True def _CheckExterns(input_api, output_api): @@ -28,15 +27,13 @@ def CheckChangeOnUpload(input_api, output_api): ret = input_api.canned_checks.RunUnitTestsInDirectory( - input_api, output_api, '.', files_to_check=FILE_PATTERN, - run_on_python2=False) + input_api, output_api, '.', files_to_check=FILE_PATTERN) ret += _CheckExterns(input_api, output_api) return ret def CheckChangeOnCommit(input_api, output_api): ret = input_api.canned_checks.RunUnitTestsInDirectory( - input_api, output_api, '.', files_to_check=FILE_PATTERN, - run_on_python2=False) + input_api, output_api, '.', files_to_check=FILE_PATTERN) ret += _CheckExterns(input_api, output_api) return ret
diff --git a/tools/json_to_struct/PRESUBMIT.py b/tools/json_to_struct/PRESUBMIT.py index 5cfc3f8..a301e40d 100644 --- a/tools/json_to_struct/PRESUBMIT.py +++ b/tools/json_to_struct/PRESUBMIT.py
@@ -8,23 +8,14 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True ALLOWEDLIST = [r'.+_test.py$'] def CheckChangeOnUpload(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=ALLOWEDLIST, - run_on_python2=False) + input_api, output_api, '.', files_to_check=ALLOWEDLIST) def CheckChangeOnCommit(input_api, output_api): return input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=ALLOWEDLIST, - run_on_python2=False) + input_api, output_api, '.', files_to_check=ALLOWEDLIST)
diff --git a/tools/licenses/PRESUBMIT.py b/tools/licenses/PRESUBMIT.py index d20f393..985a497b 100644 --- a/tools/licenses/PRESUBMIT.py +++ b/tools/licenses/PRESUBMIT.py
@@ -6,7 +6,6 @@ # This line is 'magic' in that git-cl looks for it to decide whether to # use Python3 instead of Python2 when running the code in this file. -USE_PYTHON3 = True def CheckPythonTests(input_api, output_api): @@ -15,7 +14,4 @@ input_api, output_api, input_api.PresubmitLocalPath(), - files_to_check=[r'.+_(?:unit)?test\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + files_to_check=[r'.+_(?:unit)?test\.py$']))
diff --git a/tools/linux/PRESUBMIT.py b/tools/linux/PRESUBMIT.py index 7edf2a0..02ce536 100644 --- a/tools/linux/PRESUBMIT.py +++ b/tools/linux/PRESUBMIT.py
@@ -8,7 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True import sys @@ -33,9 +32,7 @@ input_api, output_api, input_api.os_path.join(input_api.PresubmitLocalPath(), 'tests'), - files_to_check=[r'.+_tests\.py$'], - run_on_python2=False, - skip_shebang_check=True)) + files_to_check=[r'.+_tests\.py$'])) return output
diff --git a/tools/mb/PRESUBMIT.py b/tools/mb/PRESUBMIT.py index 26d29d5..fef2264 100644 --- a/tools/mb/PRESUBMIT.py +++ b/tools/mb/PRESUBMIT.py
@@ -38,12 +38,8 @@ def CheckTests(input_api, output_api): glob = input_api.os_path.join(input_api.PresubmitLocalPath(), '*_test.py') - tests = input_api.canned_checks.GetUnitTests(input_api, - output_api, - input_api.glob(glob), - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + tests = input_api.canned_checks.GetUnitTests(input_api, output_api, + input_api.glob(glob)) return input_api.RunTests(tests) @@ -68,13 +64,9 @@ # Run the MB unittests. tests.extend( - input_api.canned_checks.GetUnitTestsInDirectory(input_api, - output_api, + input_api.canned_checks.GetUnitTestsInDirectory(input_api, output_api, '.', - [r'^.+_unittest\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + [r'^.+_unittest\.py$'])) # Validate the format of the mb_config.pyl file. cmd = [input_api.python3_executable, 'mb.py', 'validate']
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index 24b961c..e65d030 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -889,6 +889,7 @@ 'chromeos-betty-pi-arc-finch-smoke-chrome': 'chromeos_betty-pi-arc_dchecks_reclient', 'chromeos-brya-chrome-skylab-fyi': 'chromeos_brya_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-jacuzzi-chrome-skylab-fyi': 'chromeos_jacuzzi_include_unwind_tables_official_dchecks_skylab_reclient', + 'chromeos-kevin-chrome-skylab-fyi': 'chromeos_kevin_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-octopus-chrome-skylab-fyi': 'chromeos_octopus_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-trogdor-chrome-skylab-fyi': 'chromeos_trogdor_include_unwind_tables_official_dchecks_skylab_reclient', 'chromeos-volteer-chrome-skylab-fyi': 'chromeos_volteer_include_unwind_tables_official_dchecks_skylab_reclient', @@ -2269,6 +2270,10 @@ 'also_build_lacros_chrome_for_architecture_arm', ], + 'chromeos_kevin_include_unwind_tables_official_dchecks_skylab_reclient': [ + 'chromeos_device_reclient', 'kevin', 'include_unwind_tables', 'official', 'dcheck_always_on', 'is_skylab', + ], + 'chromeos_kevin_include_unwind_tables_official_reclient': [ 'chromeos_kevin_reclient', 'include_unwind_tables', 'official', ],
diff --git a/tools/mb/mb_config_expectations/internal.chromeos.fyi.json b/tools/mb/mb_config_expectations/internal.chromeos.fyi.json index 302d675..b48a2610 100644 --- a/tools/mb/mb_config_expectations/internal.chromeos.fyi.json +++ b/tools/mb/mb_config_expectations/internal.chromeos.fyi.json
@@ -52,6 +52,18 @@ "use_remoteexec": true } }, + "chromeos-kevin-chrome-skylab-fyi": { + "args_file": "//build/args/chromeos/kevin.gni", + "gn_args": { + "dcheck_always_on": true, + "exclude_unwind_tables": false, + "is_chrome_branded": true, + "is_chromeos_device": true, + "is_official_build": true, + "is_skylab": true, + "use_remoteexec": true + } + }, "chromeos-octopus-chrome-skylab-fyi": { "args_file": "//build/args/chromeos/octopus.gni", "gn_args": {
diff --git a/tools/media_engagement_preload/PRESUBMIT.py b/tools/media_engagement_preload/PRESUBMIT.py index 899b6af..d9de17b 100644 --- a/tools/media_engagement_preload/PRESUBMIT.py +++ b/tools/media_engagement_preload/PRESUBMIT.py
@@ -5,10 +5,6 @@ """Chromium presubmit script for src/tools/media_engagement_preload.""" -# This line is 'magic' in that git-cl looks for it to decide whether to -# use Python3 instead of Python2 when running the code in this file. -USE_PYTHON3 = True - def _RunMakeDafsaTests(input_api, output_api): """Runs unittest for make_dafsa if any related file has been modified.""" @@ -22,9 +18,7 @@ input_api, output_api, input_api.PresubmitLocalPath(), - files_to_check=['.*test\.py$'], - run_on_python2=False, - skip_shebang_check=True)) + files_to_check=['.*test\.py$'])) def CheckChangeOnUpload(input_api, output_api):
diff --git a/tools/metrics/PRESUBMIT.py b/tools/metrics/PRESUBMIT.py index f499189d..dd2c719d 100644 --- a/tools/metrics/PRESUBMIT.py +++ b/tools/metrics/PRESUBMIT.py
@@ -7,7 +7,6 @@ for more details on the presubmit API built into gcl. """ -USE_PYTHON3 = True UKM_XML = 'ukm.xml' ENUMS_XML = 'enums.xml'
diff --git a/tools/metrics/actions/PRESUBMIT.py b/tools/metrics/actions/PRESUBMIT.py index 656566e..daeb1b4 100644 --- a/tools/metrics/actions/PRESUBMIT.py +++ b/tools/metrics/actions/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def CheckChange(input_api, output_api): """Checks that actions.xml is up to date and pretty-printed."""
diff --git a/tools/metrics/histograms/PRESUBMIT.py b/tools/metrics/histograms/PRESUBMIT.py index 6e3b880..d682c8a 100644 --- a/tools/metrics/histograms/PRESUBMIT.py +++ b/tools/metrics/histograms/PRESUBMIT.py
@@ -7,7 +7,6 @@ for more details on the presubmit API built into depot_tools. """ -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0'
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index df76bf7..5c04d3a0 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -13636,11 +13636,6 @@ <int value="1" label="Top Frame Origin Present"/> </enum> -<enum name="BooleanTranslate"> - <int value="0" label="Not Translated"/> - <int value="1" label="Translated"/> -</enum> - <enum name="BooleanUnavailable"> <int value="0" label="Available"/> <int value="1" label="Unavailable"/> @@ -25870,6 +25865,7 @@ <int value="8" label="Composited Not Axis Aligned - 3d Transform"/> <int value="9" label="Composited Not Axis Aligned - Shear Transform"/> <int value="10" label="Composited Not Axis Aligned - Rotated Transform"/> + <int value="11" label="Composited Feature Disabled"/> </enum> <enum name="DeleteBrowsingDataAction"> @@ -31263,6 +31259,8 @@ <int value="18" label="Low DriveFS free space quota"/> <int value="19" label="Video encoder does not support reconfiguration"/> <int value="20" label="Stop screen recording keyboard shortcut"/> + <int value="21" label="Game dashboard stop recording button"/> + <int value="22" label="Game toolbar stop recording button"/> </enum> <enum name="EnhancedBookmarkViewMode"> @@ -32990,6 +32988,7 @@ <int value="1109" label="DataUrlInSvgUseEnabled"/> <int value="1110" label="RSAKeyUsageForLocalAnchorsEnabled"/> <int value="1111" label="BeforeunloadEventCancelByPreventDefaultEnabled"/> + <int value="1112" label="PolicyTestPageEnabled"/> </enum> <enum name="EnterprisePoliciesSources"> @@ -37224,6 +37223,14 @@ <int value="1" label="Failed to move the file to the .Trash/info folder"/> </enum> +<enum name="FailToShowHomeSurfaceReason"> + <int value="0" label="Fail to create a NTP Tab"/> + <int value="1" label="Fail to find a NTP Tab"/> + <int value="2" label="Not a native page"/> + <int value="3" label="Not a NTP native page"/> + <int value="4" label="The native page is frozen"/> +</enum> + <enum name="FallbackDNSTestResult"> <int value="0" label="Success"/> <int value="1" label="Failure"/> @@ -38222,7 +38229,7 @@ <int value="342" label="PrefixedPerformanceSetResourceTimingBufferSize"/> <int value="343" label="EventSrcElement"/> <int value="344" label="EventCancelBubble"/> - <int value="345" label="EventPath"/> + <int value="345" label="OBSOLETE_EventPath"/> <int value="346" label="EventClipboardData"/> <int value="347" label="NodeIteratorDetach"/> <int value="348" label="AttrNodeValue"/> @@ -41959,9 +41966,9 @@ <int value="3915" label="ClientHintsPrefersColorScheme"/> <int value="3916" label="OverscrollBehaviorWillBeFixed"/> <int value="3917" label="ControlledWorkerWillBeUncontrolled"/> - <int value="3918" label="ARIATouchpassthroughAttribute"/> + <int value="3918" label="OBSOLETE_kARIATouchpassthroughAttribute"/> <int value="3919" label="ARIAVirtualcontentAttribute"/> - <int value="3920" label="AccessibilityTouchPassthroughSet"/> + <int value="3920" label="OBSOLETE_kAccessibilityTouchPassthroughSet"/> <int value="3921" label="TextFragmentBlockedByForceLoadAtTop"/> <int value="3922" label="OBSOLETE_UrnDocumentAccessedCookies"/> <int value="3923" label="FontFaceAscentOverride"/> @@ -42944,6 +42951,20 @@ <int value="2" label="BrowserObservedSignIn"/> </enum> +<enum name="FedCmUserInfoStatus"> + <int value="0" label="Success"/> + <int value="1" label="Caller is not same origin with config URL"/> + <int value="2" label="Caller is not an iframe"/> + <int value="3" label="Config URL is not potentially trustworthy"/> + <int value="4" label="FedCM is disabled"/> + <int value="5" label="IDP Sign-in Status is signed out"/> + <int value="6" label="Not a returning user"/> + <int value="7" label="Invalid config or well known"/> + <int value="8" label="Invalid accounts response"/> + <int value="9" label="No returning user from accounts response"/> + <int value="10" label="Request is destroyed"/> +</enum> + <enum name="FederatedClientEvent"> <int value="0" label="kExampleReceived"/> <int value="1" label="kGetExampleIteratorError"/> @@ -58948,7 +58969,6 @@ label="JourneysOnDeviceClusteringContentClustering:enabled"/> <int value="-2048927838" label="AutoplayWhitelistSettings:enabled"/> <int value="-2048873628" label="UseToastManager:enabled"/> - <int value="-2048829250" label="LanguagePacksInOobe:disabled"/> <int value="-2048732429" label="enable-alternative-services"/> <int value="-2048679945" label="NTPOfflinePageDownloadSuggestions:disabled"/> <int value="-2048395454" label="ChromeDuetLabeled:disabled"/> @@ -59061,7 +59081,6 @@ <int value="-2004882388" label="AutofillPruneSuggestions:enabled"/> <int value="-2004862295" label="FedCmUserInfo:disabled"/> <int value="-2004231189" label="AppNotificationStatusMessaging:disabled"/> - <int value="-2003893779" label="SpeakOnMuteEnabled:enabled"/> <int value="-2003354337" label="enable-search-button-in-omnibox-for-str-or-iip"/> <int value="-2003097010" label="TerminalSftp:enabled"/> @@ -59952,8 +59971,6 @@ <int value="-1535694535" label="PageInfoPerformanceHints:enabled"/> <int value="-1535608870" label="JourneysLabel:enabled"/> <int value="-1534970225" label="FilesArchivemount:disabled"/> - <int value="-1533977596" - label="AutofillManualFallbackAndroid_LAUNCHED:disabled"/> <int value="-1533450851" label="EnablePerDeskZOrder:enabled"/> <int value="-1533258008" label="CalculateNativeWinOcclusion:enabled"/> <int value="-1532720464" label="WellKnownChangePassword:enabled"/> @@ -61164,7 +61181,6 @@ <int value="-918618075" label="enable-service-worker"/> <int value="-917218910" label="FirstPartyVietnameseInput:enabled"/> <int value="-916780902" label="ExternalPciDevicesAllowed:enabled"/> - <int value="-915442560" label="kAllowDevtoolsInSystemUI:disabled"/> <int value="-915328316" label="CupsIppPrintingBackend:disabled"/> <int value="-915035507" label="ArcPrintSpoolerExperiment:enabled"/> <int value="-914210146" label="enable-web-based-signin"/> @@ -61525,6 +61541,7 @@ label="AutofillSuggestVirtualCardsOnIncompleteForm:enabled"/> <int value="-726567328" label="disable-virtual-keyboard"/> <int value="-726485467" label="FilesArchivemount:enabled"/> + <int value="-726176676" label="AudioHFPNbsWarning:disabled"/> <int value="-725264428" label="CompositingBasedThrottling:enabled"/> <int value="-723224470" label="enable-password-force-saving:enabled"/> <int value="-722474177" label="browser-side-navigation:disabled"/> @@ -61737,7 +61754,6 @@ <int value="-616508634" label="DisableCryptAuthV1DeviceSync:enabled"/> <int value="-616414905" label="ThumbnailCacheRefactor:disabled"/> <int value="-615974325" label="ArcMouseWheelSmoothScroll:disabled"/> - <int value="-615899374" label="LanguagePacksInOobe:enabled"/> <int value="-615254902" label="SystemJapanesePhysicalTyping:enabled"/> <int value="-614223913" label="ClickToCallContextMenuForSelectedText:enabled"/> @@ -62802,6 +62818,7 @@ <int value="-43566818" label="WebRtcApmDownmixCaptureAudioMethod:disabled"/> <int value="-43428597" label="ClickToCallDetectionV2:enabled"/> <int value="-42175674" label="ShareUsageRankingFixedMore:disabled"/> + <int value="-41548966" label="AutocorrectUseReplaceSurroundingText:disabled"/> <int value="-41460305" label="InfobarScrollOptimization:disabled"/> <int value="-41254374" label="WebRtcMetronomeTaskQueue:enabled"/> <int value="-40935502" label="ContextualSuggestionsSlimPeekUI:enabled"/> @@ -62813,8 +62830,6 @@ <int value="-36007541" label="DataRetentionPoliciesDisableSyncTypesNeeded:enabled"/> <int value="-35745997" label="TabSearch:enabled"/> - <int value="-35618901" - label="AutofillManualFallbackAndroid_LAUNCHED:enabled"/> <int value="-35528548" label="LensImageFormatOptimizations:disabled"/> <int value="-35388407" label="AshNewSystemMenu:disabled"/> <int value="-35256214" label="InterestFeedNoticeCardAutoDismiss:enabled"/> @@ -62927,7 +62942,6 @@ <int value="15614295" label="Portals:enabled"/> <int value="15872227" label="OmniboxDiscardTemporaryInputOnTabSwitch:disabled"/> - <int value="16804822" label="SpeakOnMuteEnabled:disabled"/> <int value="18571458" label="VmPerBootShaderCache:disabled"/> <int value="19629326" label="OmniboxExperimentalKeywordMode:enabled"/> <int value="19815558" label="EnableSettingsShortcutSearch:disabled"/> @@ -62984,6 +62998,7 @@ label="FeatureNotificationGuideSkipCheckForLowEngagedUsers:enabled"/> <int value="48159177" label="reduced-referrer-granularity"/> <int value="48666910" label="ClipboardHistoryLongpress:disabled"/> + <int value="48850808" label="AutocorrectUseReplaceSurroundingText:enabled"/> <int value="50643563" label="MBIMode:enabled"/> <int value="51793504" label="protect-sync-credential-on-reauth:disabled"/> <int value="52150780" label="OsSettingsPolymer3:disabled"/> @@ -63276,6 +63291,7 @@ <int value="204042068" label="AllowEapDefaultCasWithoutSubjectVerification:disabled"/> <int value="204560750" label="HomeButtonWithText:enabled"/> + <int value="205375645" label="AudioHFPNbsWarning:enabled"/> <int value="205426997" label="BackGestureActivityTabProvider:enabled"/> <int value="207326879" label="NearbySharingReceiveWifiCredentials:enabled"/> <int value="207907053" @@ -63466,6 +63482,7 @@ <int value="307543404" label="disable-team-drives"/> <int value="307670929" label="enable-ambient-authentication-in-guest-session"/> + <int value="308941571" label="PrintPreviewDiscoveredPrinters:enabled"/> <int value="309795366" label="ScrollUnification:disabled"/> <int value="309861115" label="AutofillEnableNewCardArtAndNetworkImages:enabled"/> @@ -63853,7 +63870,6 @@ <int value="511179195" label="ShoppingAssist:disabled"/> <int value="511392922" label="SharedClipboardReceiver:enabled"/> <int value="512143128" label="LacrosOnly:enabled"/> - <int value="512376582" label="RecoverFromNeverSaveAndroid_LAUNCHED:disabled"/> <int value="512508240" label="WebViewExtraHeadersSameDomainOnly:disabled"/> <int value="513258875" label="WinrtSensorsImplementation:disabled"/> <int value="513356954" label="InstantTethering:disabled"/> @@ -64234,6 +64250,7 @@ <int value="717020975" label="ForceOffTextAutosizing:disabled"/> <int value="717591093" label="UrlLoaderSyncClient:disabled"/> <int value="717827121" label="ChromeSharingHub:disabled"/> + <int value="717913871" label="PeripheralCustomization:disabled"/> <int value="719267310" label="KeepAliveRendererForKeepaliveRequests:disabled"/> <int value="719614898" label="LensEnableRegionSearchOnPdfViewer:enabled"/> @@ -64945,6 +64962,7 @@ label="SafeBrowsingkRealTimeUrlLookupEnterpriseGaEndpoint:enabled"/> <int value="1107293950" label="WebUIBrandingUpdate:disabled"/> <int value="1107543566" label="enable-one-copy"/> + <int value="1108200393" label="PeripheralCustomization:enabled"/> <int value="1108663108" label="disable-device-discovery-notifications"/> <int value="1109907837" label="PrefetchMainResourceNetworkIsolationKey:enabled"/> @@ -65041,7 +65059,6 @@ <int value="1158333871" label="QueryTilesEnableQueryEditing:enabled"/> <int value="1159760152" label="ContextMenuSearchAndShopWithGoogleLens:disabled"/> - <int value="1159984590" label="kAllowDevtoolsInSystemUI:enabled"/> <int value="1161822401" label="LoginDetection:enabled"/> <int value="1162420462" label="ShelfLauncherNudge:disabled"/> <int value="1162622865" label="EarlyCodeCache:disabled"/> @@ -65771,6 +65788,7 @@ <int value="1544413751" label="PasswordStrengthIndicator:enabled"/> <int value="1544561349" label="PdfUseSkiaRenderer:disabled"/> <int value="1546652609" label="SharingHubDesktopOmnibox:disabled"/> + <int value="1547049944" label="ScalableIph:enabled"/> <int value="1548776701" label="AllBookmarks:disabled"/> <int value="1548942246" label="PassiveDocumentEventListeners:disabled"/> <int value="1550865563" label="AnimatedImageDragShadow:enabled"/> @@ -66259,7 +66277,6 @@ <int value="1800375282" label="UseDMSAAForTiles:disabled"/> <int value="1800509458" label="DriveFsChromeNetworking:disabled"/> <int value="1800603694" label="DXGIWaitableSwapChain:disabled"/> - <int value="1800633942" label="RecoverFromNeverSaveAndroid_LAUNCHED:enabled"/> <int value="1801297618" label="HelpAppAutoTriggerInstallDialog:disabled"/> <int value="1801585504" label="ContextMenuShopWithGoogleLens:enabled"/> <int value="1802821192" label="VCBackgroundReplace:disabled"/> @@ -66423,6 +66440,7 @@ <int value="1872768755" label="BackgroundResourceFetch:disabled"/> <int value="1872897574" label="AutofillEnableRankingFormulaCreditCards:disabled"/> + <int value="1873476339" label="ScalableIph:disabled"/> <int value="1873688130" label="ExperimentalAccessibilityDictationMoreCommands:disabled"/> <int value="1874050287" label="UploadOfficeToCloud:enabled"/> @@ -66811,6 +66829,7 @@ <int value="2078599705" label="ShelfAppScaling:enabled"/> <int value="2078879219" label="CryptAuthV2DeviceActivityStatusUseConnectivity:disabled"/> + <int value="2079094073" label="PrintPreviewDiscoveredPrinters:disabled"/> <int value="2079658706" label="IncreasedCmdBufferParseSlice:disabled"/> <int value="2079672348" label="ExperimentalKeyboardLockUI:disabled"/> <int value="2080666644" @@ -78266,6 +78285,7 @@ label="Keyboard: Switch Top Row Keys Between Function Keys And Chrome Actions"/> <int value="442" label="Keyboard: Remap Keys"/> + <int value="443" label="Charging sounds: On/Off"/> <int value="500" label="Open Wallpaper"/> <int value="501" label="Ambient Mode On/Off"/> <int value="502" label="Ambient Mode Source"/> @@ -79952,7 +79972,33 @@ </int> </enum> +<enum name="PartnerCustomizationProviderDelegate"> + <int value="0" label="None valid"/> + <int value="1" label="Phenotype config"/> + <int value="2" label="GService flag"/> + <int value="3" label="Preload APK"/> +</enum> + +<enum name="PartnerCustomizationUsage"> + <int value="0" label="Homepage"/> + <int value="1" label="Bookmarks"/> + <int value="2" label="Incognito"/> +</enum> + +<enum name="PartnerDelegateUnusedReason"> + <int value="0" label="Phenotype: before Android Pie"/> + <int value="1" label="Phenotype: flag can't commit"/> + <int value="2" label="Phenotype: config empty"/> + <int value="3" label="GServices: get timestamp exception"/> + <int value="4" label="GServices: timestamp missing"/> + <int value="5" label="PreloadApk: can't resolve provider"/> + <int value="6" label="PreloadApk: not system provider"/> +</enum> + <enum name="PartnerHomepageCustomizationDelegate"> + <obsolete> + Deprecated as of 2023-05. Use PartnerCustomizationProviderDelegate. + </obsolete> <int value="0" label="Phenotype config"/> <int value="1" label="GService flag"/> <int value="2" label="Preload APK"/> @@ -82719,6 +82765,7 @@ <enum name="PersonalizationSearchConceptId"> <int value="0" label="kPersonalization"/> <int value="100" label="kChangeWallpaper"/> + <int value="101" label="kTimeOfDayWallpaper"/> <int value="200" label="kChangeDeviceAccountImage"/> <int value="300" label="kAmbientMode"/> <int value="301" label="kAmbientModeChooseSource"/> @@ -82726,6 +82773,7 @@ <int value="303" label="kAmbientModeGooglePhotos"/> <int value="304" label="kAmbientModeArtGallery"/> <int value="305" label="kAmbientModeTurnOn"/> + <int value="306" label="kAmbientModeTimeOfDay"/> <int value="400" label="kDarkMode"/> <int value="401" label="kDarkModeSchedule"/> <int value="402" label="kDarkModeTurnOff"/> @@ -86570,6 +86618,14 @@ <int value="4" label="Printer provider Web Store app launched"/> </enum> +<enum name="PrinterSettingsUserAction"> + <int value="0" label="Add printer manually"/> + <int value="1" label="Save printer"/> + <int value="2" label="Edit printer"/> + <int value="3" label="Remove printer"/> + <int value="4" label="Click help link"/> +</enum> + <enum name="PrinterSetupResult"> <int value="0" label="Fatal Error"/> <int value="1" label="Success"/> @@ -93915,6 +93971,15 @@ <int value="2" label="Network error"/> </enum> +<enum name="SecondaryActivity"> + <int value="0" label="Download"/> + <int value="1" label="Bookmark"/> + <int value="2" label="FirstRun"/> + <int value="3" label="LightWeightFirstRun"/> + <int value="4" label="History"/> + <int value="5" label="Settings"/> +</enum> + <enum name="SecondaryGoogleAccountUsagePolicyFetchStatus"> <int value="0" label="UnknownError"/> <int value="1" label="Success"/> @@ -95395,6 +95460,13 @@ <int value="5" label="Creation of the exit event mutex failed."/> </enum> +<enum name="SetWallpaperResult"> + <int value="0" label="Success"/> + <int value="1" label="Permission Denied"/> + <int value="2" label="Network Error"/> + <int value="3" label="Decoding Error"/> +</enum> + <enum name="SevenZipResult"> <int value="0" label="Unknown"/> <int value="1" label="Success"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 146706c..ff4b170 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -56,6 +56,13 @@ <variant name="Waived" summary="strongest binding of Waived"/> </variants> +<variants name="CustomizationDelegate"> + <variant name="GService" summary="GService"/> + <variant name="None" summary="None-valid"/> + <variant name="Phenotype" summary="Phenotype/Heterodyne"/> + <variant name="PreloadApk" summary="Preload-APK"/> +</variants> + <variants name="MessageIdentifiers"> <variant name=".AboutThisSite"/> <variant name=".AddToHomescreenIPH"/> @@ -578,6 +585,16 @@ </summary> </histogram> +<histogram name="Android.BackPress.SecondaryActivity" enum="SecondaryActivity" + expires_after="2023-11-05"> + <owner>lazzzis@chromium.org</owner> + <owner>src/chrome/browser/back_press/android/OWNERS</owner> + <summary> + Records the secondary activity which intercepts the back press when the user + does the Backpress gesture and it's not handled by the system. + </summary> +</histogram> + <histogram name="Android.BindingManger.ConnectionsDroppedDueToMaxSize" units="connections" expires_after="2023-10-22"> <owner>ckitagawa@chromium.org</owner> @@ -2611,7 +2628,7 @@ </histogram> <histogram name="Android.Omnibox.UsedSuggestionFromCache" enum="Boolean" - expires_after="2022-09-04"> + expires_after="2023-11-12"> <owner>ender@chromium.org</owner> <owner>jdonnelly@chromium.org</owner> <owner>mpearson@chromium.org</owner> @@ -2705,6 +2722,74 @@ </summary> </histogram> +<histogram name="Android.PartnerCustomization.DelegateConflict" enum="Boolean" + expires_after="2023-09-01"> + <owner>donnd@chromium.org</owner> + <owner>wenyufu@chromium.org</owner> + <summary> + Records whether a delegate confict occurred due to starting up multiple + async background tasks that use different delegates. Recorded when a partner + customization delegate is changed from one kind of delegate to another. + Recorded at startup. + </summary> +</histogram> + +<histogram name="Android.PartnerCustomization.DelegateUnusedReason" + enum="PartnerDelegateUnusedReason" expires_after="2023-09-01"> + <owner>donnd@chromium.org</owner> + <owner>wenyufu@chromium.org</owner> + <summary> + Records a reason that a delegate could not be used for partner + customization. Multiple records can be written when more than one delegate + is tried and fails during a single initialization session. Recorded when a + partner customization delegate tries to initialize but fails. Delegates may + lazily initialize, so having one succeed may cause another to be skipped and + the skipped one's potential failure would not be recorded. Trying to use the + PreloadApk delegate is only done when actually needed so these numbers + should reflect actual usage attempts. + </summary> +</histogram> + +<histogram + name="Android.PartnerCustomization.TryFailedDuration.{CustomizationDelegate}" + units="ms" expires_after="2023-09-01"> + <owner>donnd@chromium.org</owner> + <owner>wenyufu@chromium.org</owner> + <summary> + Records the amount of time it took for the {CustomizationDelegate} delegate + to run in the async task that does partner customization. Recorded when the + task completes but was unable to use the delegate for some reason - see + DelegateUnusedReason histogram for some possible reasons. Trying to use the + PreloadApk delegate is only done when actually needed so these numbers + should reflect actual usage attempts. + </summary> +</histogram> + +<histogram + name="Android.PartnerCustomization.TrySucceededDuration.{CustomizationDelegate}" + units="ms" expires_after="2023-09-01"> + <owner>donnd@chromium.org</owner> + <owner>wenyufu@chromium.org</owner> + <summary> + Records the amount of time it took for the {CustomizationDelegate} delegate + to run in the async task that does partner customization. Recorded when the + task completes successfully and a delegate providing customizations is + found. Trying to use the PreloadApk delegate is only done when actually + needed so these numbers should reflect actual usage attempts. + </summary> +</histogram> + +<histogram name="Android.PartnerCustomization.Usage" + enum="PartnerCustomizationUsage" expires_after="2023-09-01"> + <owner>donnd@chromium.org</owner> + <owner>wenyufu@chromium.org</owner> + <summary> + Records which customization usage is being invoked, at the time it is + requested. The possible usages include a custom Homepage URL, suppressing + incognito, etc. + </summary> +</histogram> + <histogram name="Android.PartnerCustomizationInitializedBeforeInitialTab" enum="Boolean" expires_after="2023-11-12"> <owner>wenyufu@chromium.org</owner> @@ -2717,14 +2802,15 @@ </summary> </histogram> -<histogram name="Android.PartnerHomepageCustomization.Delegate" - enum="PartnerHomepageCustomizationDelegate" expires_after="M120"> +<histogram name="Android.PartnerHomepageCustomization.Delegate2" + enum="PartnerCustomizationProviderDelegate" expires_after="M120"> <owner>donnd@chromium.org</owner> <owner>twellington@chromium.org</owner> <owner>wenyufu@chromium.org</owner> <summary> Records which delegate will be used to provide the home page URL that is - needed for a custom provider's home page. Recorded at startup on Android. + needed for a custom provider's customization. Recorded at startup on + Android. </summary> </histogram>
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml index 1bc413c..586a4ea 100644 --- a/tools/metrics/histograms/metadata/apps/histograms.xml +++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -2030,7 +2030,7 @@ <histogram name="Apps.ContextMenuShowSourceV2{AppUIComponent}{TabletOrClamshellMode}" - enum="MenuSourceType" expires_after="2023-06-01"> + enum="MenuSourceType" expires_after="2023-12-01"> <owner>wcwang@chromium.org</owner> <owner>mmourgos@chromium.org</owner> <owner>tbarzic@chromium.org</owner> @@ -2044,7 +2044,7 @@ <histogram name="Apps.ContextMenuUserJourneyTimeV2{AppUIComponent}{TabletOrClamshellMode}" - units="ms" expires_after="2023-06-01"> + units="ms" expires_after="2023-12-01"> <owner>wcwang@chromium.org</owner> <owner>mmourgos@chromium.org</owner> <owner>tbarzic@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index 67e928f..dd14e9a6 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -6880,6 +6880,19 @@ </summary> </histogram> +<histogram name="Ash.Wallpaper.{WallpaperType}.Result" + enum="SetWallpaperResult" expires_after="2024-06-01"> + <owner>jasontt@chromium.org</owner> + <owner>assistive-eng@google.com</owner> + <summary> + Tracks the result of user's attempt to set a wallpaper. Recorded when a user + selects a wallpaper from the personalization hub. + </summary> + <token key="WallpaperType"> + <variant name="Online"/> + </token> +</histogram> + <histogram name="Ash.Window.AnimationSmoothness.CrossFade" units="%" expires_after="2023-11-12"> <owner>sammiequon@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index a8481de2..08bf5fb 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -1364,6 +1364,16 @@ </summary> </histogram> +<histogram name="Blink.FedCm.UserInfo.Status" enum="FedCmUserInfoStatus" + expires_after="2023-11-30"> + <owner>npm@chromium.org</owner> + <owner>web-identity-eng@google.com</owner> + <summary> + Records the status of a getUserInfo() call. Records once per request when + the request is completed, right before running the callback. + </summary> +</histogram> + <histogram name="Blink.FedCm.WebContentsVisible" enum="Boolean" expires_after="2023-11-19"> <owner>yigu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml index 3a5ba65..4c6d8d5 100644 --- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml +++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -73,6 +73,20 @@ </summary> </histogram> +<histogram + name="Bookmarks.AttachedBar.CurrentTab.TimeToFirstVisuallyNonEmptyPaint" + units="ms" expires_after="2024-01-31"> + <owner>tluk@chromium.org</owner> + <owner>chrome-cros@google.com</owner> + <component>UI>Browser>Bookmarks</component> + <summary> + Tracks the time between when the user first launches a bookmark from the + attached bookmark bar into the current tab to when we receive the first + visually non-empty paint. Emitted after the WebContents in the browser has + been notified of the non-empty paint. + </summary> +</histogram> + <histogram name="Bookmarks.AverageNodeSize" units="Bytes" expires_after="2023-10-08"> <owner>wylieb@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/browser/histograms.xml b/tools/metrics/histograms/metadata/browser/histograms.xml index 0709f8a..a419165 100644 --- a/tools/metrics/histograms/metadata/browser/histograms.xml +++ b/tools/metrics/histograms/metadata/browser/histograms.xml
@@ -164,6 +164,24 @@ </token> </histogram> +<histogram name="Browser.ERP.FilteredOutEvents" units="BooleanFiltered" + expires_after="2024-05-23"> + <owner>lbaraz@chromium.org</owner> + <owner>cros-reporting-team@google.com</owner> + <summary> + Records whether an event is filtered out by FilteredReportQueue. + </summary> +</histogram> + +<histogram name="Browser.ERP.RateLimitedEvents" units="BooleanAccepted" + expires_after="2024-05-23"> + <owner>lbaraz@chromium.org</owner> + <owner>cros-reporting-team@google.com</owner> + <summary> + Records whether an event is accepted by ReportQueue rate limiter. + </summary> +</histogram> + <histogram name="Browser.ERP.RecordsPerUpload" units="records" expires_after="2024-01-31"> <owner>jrhilke@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/cras/histograms.xml b/tools/metrics/histograms/metadata/cras/histograms.xml index 3ddbee98..253a378 100644 --- a/tools/metrics/histograms/metadata/cras/histograms.xml +++ b/tools/metrics/histograms/metadata/cras/histograms.xml
@@ -75,7 +75,7 @@ </summary> </histogram> -<histogram name="Cras.BusyloopLength" units="units" expires_after="2023-02-12"> +<histogram name="Cras.BusyloopLength" units="units" expires_after="2024-06-01"> <owner>yuhsuan@chromium.org</owner> <owner>chromeos-audio@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/file/histograms.xml b/tools/metrics/histograms/metadata/file/histograms.xml index f33c1d5..2f514da4 100644 --- a/tools/metrics/histograms/metadata/file/histograms.xml +++ b/tools/metrics/histograms/metadata/file/histograms.xml
@@ -1135,6 +1135,7 @@ ChromeOS File Browser: The time it took to complete user search request. </summary> <token key="Source"> + <variant name="DocumentsProvider"/> <variant name="Drive"/> <variant name="Local"/> <variant name="Removable"/>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml index c7d61fa5..b49e396 100644 --- a/tools/metrics/histograms/metadata/gpu/histograms.xml +++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -1378,6 +1378,18 @@ </summary> </histogram> +<histogram name="GPU.SharedImage.IsNewMultiplanarFormat" units="Boolean" + expires_after="2023-12-01"> + <owner>hitawala@chromium.org</owner> + <owner>vasilyt@chromium.org</owner> + <summary> + Tracks the multiplanar format used for creating shared image with + GpuMemoryBuffers. Result is a bool that checks if the format is a new + multiplanar shared image format or legacy multiplanar buffer format. This is + logged once per CreateSharedImage with GpuMemoryBuffer call. + </summary> +</histogram> + <histogram name="GPU.SoftwareRendering" enum="BooleanSoftwareRendering" expires_after="2023-11-12"> <owner>zmo@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/memory/histograms.xml b/tools/metrics/histograms/metadata/memory/histograms.xml index de3592e..aa04e7e 100644 --- a/tools/metrics/histograms/metadata/memory/histograms.xml +++ b/tools/metrics/histograms/metadata/memory/histograms.xml
@@ -107,7 +107,7 @@ </histogram> <histogram name="HeapProfiling.InProcess.Enabled{Process}" - enum="BooleanEnabled" expires_after="2023-06-05"> + enum="BooleanEnabled" expires_after="2024-06-05"> <owner>joenotcharles@google.com</owner> <owner>chrome-memory@google.com</owner> <summary> @@ -118,7 +118,7 @@ </histogram> <histogram name="HeapProfiling.InProcess.SamplesPerSnapshot{Process}" - units="samples" expires_after="2023-06-05"> + units="samples" expires_after="2024-06-05"> <owner>joenotcharles@google.com</owner> <owner>chrome-memory@google.com</owner> <summary> @@ -130,7 +130,7 @@ <histogram name="HeapProfiling.InProcess.SnapshotInterval.{Platform}.{RecordingTime}{Process}" - units="ms" expires_after="2023-06-05"> + units="ms" expires_after="2024-06-05"> <owner>joenotcharles@google.com</owner> <owner>chrome-memory@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml index 44e4d69b..4b500c6 100644 --- a/tools/metrics/histograms/metadata/new_tab_page/histograms.xml +++ b/tools/metrics/histograms/metadata/new_tab_page/histograms.xml
@@ -698,6 +698,17 @@ </summary> </histogram> +<histogram name="NewTabPage.FailToShowHomeSurfaceUI" + enum="FailToShowHomeSurfaceReason" expires_after="2023-10-22"> + <owner>hanxi@chromium.org</owner> + <owner>xinyiji@chromium.org</owner> + <summary> + Records the reason of why failed to show a home surface UI on the chosen + NTP. Logged in cold or warm startup when failed to show the home surface UI. + This histogram is recorded on tablets only. + </summary> +</histogram> + <histogram name="NewTabPage.FeedPositionSegmentationResult" enum="FeedPositionSegmentationResult" expires_after="2023-09-10"> <owner>hanxi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/optimization/histograms.xml b/tools/metrics/histograms/metadata/optimization/histograms.xml index a04b2d1..bc81611 100644 --- a/tools/metrics/histograms/metadata/optimization/histograms.xml +++ b/tools/metrics/histograms/metadata/optimization/histograms.xml
@@ -75,6 +75,8 @@ <variant name="SegmentationVoice" summary="Segmentation: Voice user"/> <variant name="TextClassifier" summary="Smart text selection"/> <variant name="TextEmbedder" summary="Generic Text Embedding"/> + <variant name="VisualSearchClassification" + summary="Classifies images on the page"/> <variant name="WebAppInstallationPromo" summary="PWA: Show web app installation promotion"/> </variants>
diff --git a/tools/metrics/histograms/metadata/others/histograms.xml b/tools/metrics/histograms/metadata/others/histograms.xml index c275014..38db7de 100644 --- a/tools/metrics/histograms/metadata/others/histograms.xml +++ b/tools/metrics/histograms/metadata/others/histograms.xml
@@ -5105,15 +5105,6 @@ </summary> </histogram> -<histogram name="Downgrade.Type" enum="UserDataDowngradeType" - expires_after="2021-08-09"> - <owner>grt@chromium.org</owner> - <summary> - The type of User Data downgrade detected, if any. The "none" - bucket is not reported. - </summary> -</histogram> - <histogram name="Downgrade.UserDataDirMove.FailureCount" units="count" expires_after="2020-12-31"> <obsolete> @@ -14215,22 +14206,6 @@ <token key="Target" variants="VoiceIntentTargetVariant"/> </histogram> -<histogram name="Web.CurrentOriginEqualsLastCommittedOrigin" - enum="BooleanEqual" expires_after="2023-11-17"> - <owner>ajuma@chromium.org</owner> - <owner>gambard@chromium.org</owner> - <summary> - [iOS] Reports URL matches between the return value from the WebState's - GetLastCommittedURL and GetCurrentURL methods. It is expected the origins - will be equal to confirm that GetCurrentURL can now be replaced with - GetLastCommittedURL. This will be called each time WebStateImpl:: - GetCurrentURL(URLVerificationTrustLevel* trust_level) is called, which is an - old method of obtaining the url and trust level. The trust level was only - relevant with UIWebView, so this method is only called from code which has - not yet been updated since UIWebView was removed. - </summary> -</histogram> - <histogram name="WebContentsObserver.{Method}" units="ms" expires_after="2023-07-28"> <owner>cduvall@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml index 7ea6361..3c9c38f 100644 --- a/tools/metrics/histograms/metadata/platform/histograms.xml +++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -1340,6 +1340,15 @@ </summary> </histogram> +<histogram name="Platform.Missive.StorageDegradationAmount" units="KiB" + expires_after="2024-05-31"> + <owner>lbaraz@google.com</owner> + <owner>cros-reporting-team@google.com</owner> + <summary> + Total amount of space freed by controlled degradation performed by Storage. + </summary> +</histogram> + <histogram name="Platform.Missive.StorageQueueGenerationIdReset" enum="Boolean" expires_after="2024-01-31"> <owner>vshenvi@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/printing/histograms.xml b/tools/metrics/histograms/metadata/printing/histograms.xml index a30230b..b878f3cc 100644 --- a/tools/metrics/histograms/metadata/printing/histograms.xml +++ b/tools/metrics/histograms/metadata/printing/histograms.xml
@@ -352,6 +352,15 @@ </summary> </histogram> +<histogram name="Printing.CUPS.SettingsUserAction" + enum="PrinterSettingsUserAction" expires_after="2024-05-30"> + <owner>gavinwill@chromium.org</owner> + <owner>cros-peripherals@google.com</owner> + <summary> + Records the action a user takes on the OS Printer settings page. + </summary> +</histogram> + <histogram name="Printing.CUPS.TotalNetworkPrintersCount" units="printers" expires_after="2023-11-12"> <owner>bmgordon@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/quickoffice/histograms.xml b/tools/metrics/histograms/metadata/quickoffice/histograms.xml index 0b6b9edf..88fb166 100644 --- a/tools/metrics/histograms/metadata/quickoffice/histograms.xml +++ b/tools/metrics/histograms/metadata/quickoffice/histograms.xml
@@ -23,7 +23,7 @@ <histograms> <histogram name="Quickoffice.csvFormattedCellCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -33,7 +33,7 @@ </histogram> <histogram name="Quickoffice.csvNonEmptyCellCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -43,7 +43,7 @@ </histogram> <histogram name="Quickoffice.csvSheetCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -53,7 +53,7 @@ </histogram> <histogram name="Quickoffice.docPageCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -62,7 +62,7 @@ </histogram> <histogram name="Quickoffice.docParagraphCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -72,7 +72,7 @@ </histogram> <histogram name="Quickoffice.docSectionCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -81,7 +81,7 @@ </histogram> <histogram name="Quickoffice.docxPageCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -90,7 +90,7 @@ </histogram> <histogram name="Quickoffice.docxParagraphCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -99,7 +99,7 @@ </histogram> <histogram name="Quickoffice.docxSectionCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -108,7 +108,7 @@ </histogram> <histogram name="Quickoffice.ErrorTypes" enum="QuickofficeErrorTypes" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -121,7 +121,7 @@ </histogram> <histogram name="Quickoffice.FileFormat" enum="QuickofficeFileFormat" - expires_after="2023-09-03"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -132,7 +132,7 @@ </histogram> <histogram name="Quickoffice.pptMasterCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -142,7 +142,7 @@ </histogram> <histogram name="Quickoffice.pptSlideCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -152,7 +152,7 @@ </histogram> <histogram name="Quickoffice.pptxMasterCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -162,7 +162,7 @@ </histogram> <histogram name="Quickoffice.pptxSlideCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -171,7 +171,7 @@ </histogram> <histogram name="Quickoffice.xlsFormattedCellCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -181,7 +181,7 @@ </histogram> <histogram name="Quickoffice.xlsNonEmptyCellCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -191,7 +191,7 @@ </histogram> <histogram name="Quickoffice.xlsSheetCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -201,7 +201,7 @@ </histogram> <histogram name="Quickoffice.xlsxFormattedCellCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -211,7 +211,7 @@ </histogram> <histogram name="Quickoffice.xlsxNonEmptyCellCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary> @@ -221,7 +221,7 @@ </histogram> <histogram name="Quickoffice.xlsxSheetCount" units="units" - expires_after="2023-07-01"> + expires_after="2024-07-01"> <owner>joelhockey@google.com</owner> <owner>quickoffice-chrome-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/search/histograms.xml b/tools/metrics/histograms/metadata/search/histograms.xml index 2b58235..49fffdf 100644 --- a/tools/metrics/histograms/metadata/search/histograms.xml +++ b/tools/metrics/histograms/metadata/search/histograms.xml
@@ -1762,6 +1762,9 @@ <histogram name="Search.TemplateURL.Events" enum="SearchTemplateURLEvent" expires_after="2023-05-01"> + <obsolete> + Expired and removed 05/2023. + </obsolete> <owner>tommycli@chromium.org</owner> <owner>chrome-omnibox-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/security/histograms.xml b/tools/metrics/histograms/metadata/security/histograms.xml index d5f90d8..303ff5ab 100644 --- a/tools/metrics/histograms/metadata/security/histograms.xml +++ b/tools/metrics/histograms/metadata/security/histograms.xml
@@ -1024,7 +1024,7 @@ <histogram name="SiteIsolation.ReusePendingOrCommittedSite.TimeSinceReusableProcessDestroyed" - units="ms" expires_after="2023-06-25"> + units="ms" expires_after="2023-12-20"> <owner>jessemckenna@google.com</owner> <owner>olivierli@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/sync/histograms.xml b/tools/metrics/histograms/metadata/sync/histograms.xml index d409c984..7afc69ad 100644 --- a/tools/metrics/histograms/metadata/sync/histograms.xml +++ b/tools/metrics/histograms/metadata/sync/histograms.xml
@@ -230,7 +230,7 @@ </histogram> <histogram name="Sync.BookmarksModelMetadataCorruptionReason" - enum="SyncBookmarkModelMetadataCorruptionReason" expires_after="2023-07-09"> + enum="SyncBookmarkModelMetadataCorruptionReason" expires_after="2024-07-09"> <owner>rushans@google.com</owner> <owner>mastiz@chromium.org</owner> <component>Services>Sync</component>
diff --git a/tools/metrics/histograms/metadata/translate/histograms.xml b/tools/metrics/histograms/metadata/translate/histograms.xml index 1f7f388..fb3227d 100644 --- a/tools/metrics/histograms/metadata/translate/histograms.xml +++ b/tools/metrics/histograms/metadata/translate/histograms.xml
@@ -272,16 +272,6 @@ </summary> </histogram> -<histogram name="Translate.ModifyOriginalLang" units="units" - expires_after="2023-10-15"> - <owner>megjablon@google.com</owner> - <owner>chrome-language@google.com</owner> - <summary> - The number of times the source language in the translate infobar has been - changed. - </summary> -</histogram> - <histogram name="Translate.NeverTranslateLang" units="units" expires_after="2023-10-08"> <owner>megjablon@google.com</owner> @@ -606,17 +596,6 @@ </summary> </histogram> -<histogram name="Translate.Translate.AMPCacheURL" enum="BooleanTranslate" - expires_after="2023-11-12"> - <owner>sclittle@google.com</owner> - <owner>megjablon@google.com</owner> - <owner>chrome-language@google.com</owner> - <summary> - The number of times the translate button was clicked in the translate - infobar for a page that is likely an AMP Cache URL. - </summary> -</histogram> - <histogram name="Translate.TranslateAssistContentResult" enum="TranslateAssistContentResult" expires_after="2022-06-30"> <owner>jds@chromium.org</owner>
diff --git a/tools/metrics/structured/PRESUBMIT.py b/tools/metrics/structured/PRESUBMIT.py index 21fb32a..f49353c 100644 --- a/tools/metrics/structured/PRESUBMIT.py +++ b/tools/metrics/structured/PRESUBMIT.py
@@ -8,7 +8,6 @@ for more details on the presubmit API built into gcl. """ -USE_PYTHON3 = True STRUCTURED_XML = 'structured.xml' STRUCTURED_OLD_XML = 'structured.old.xml'
diff --git a/tools/metrics/ukm/PRESUBMIT.py b/tools/metrics/ukm/PRESUBMIT.py index 50a0ec5..5da75c0 100644 --- a/tools/metrics/ukm/PRESUBMIT.py +++ b/tools/metrics/ukm/PRESUBMIT.py
@@ -8,7 +8,6 @@ for more details on the presubmit API built into gcl. """ -USE_PYTHON3 = True UKM_XML = 'ukm.xml'
diff --git a/tools/oobe/DIR_METADATA b/tools/oobe/DIR_METADATA new file mode 100644 index 0000000..ef707ba --- /dev/null +++ b/tools/oobe/DIR_METADATA
@@ -0,0 +1,20 @@ +# Metadata information for this directory. +# +# For more information on DIR_METADATA files, see: +# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/README.md +# +# For the schema of this file, see Metadata message: +# https://source.chromium.org/chromium/infra/infra/+/HEAD:go/src/infra/tools/dirmd/proto/dir_metadata.proto + +# ChromeOS > Software > OOBE +buganizer { + component_id: 1263090 +} + +# ChromeOS Pubblic Tracker > UI > OOBE +buganizer_public { + component_id: 1263509 +} + +team_email: "cros-oobe@google.com" +os: CHROME_OS
diff --git a/tools/oobe/OWNERS b/tools/oobe/OWNERS new file mode 100644 index 0000000..7fe9b37b --- /dev/null +++ b/tools/oobe/OWNERS
@@ -0,0 +1,2 @@ +bohdanty@google.com +dkuzmin@google.com
diff --git a/tools/oobe/generate_screen_template.py b/tools/oobe/generate_screen_template.py new file mode 100755 index 0000000..54304470 --- /dev/null +++ b/tools/oobe/generate_screen_template.py
@@ -0,0 +1,401 @@ +#!/usr/bin/env python3 +# 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. +"""Generate sample ChromeOS OOBE screen with a given name. + +Screen will implement all needed interfaces on the C++ side and will be included +in the corresponding BUILD files. + +Script will generate sample JS and HTML files that user will be able to display +in the OOBE's WebView. Corresponding BUILD files will be updated. + +If --no-webview flag is specified previous step will be skipped. + +After generation is complete user still needs to manually insert screen into the +OOBE's wizard controller flow and add WebView content to the screens.js file. + +usage: generate_screen_template.py [-h] [--no-webview] name + +positional arguments: + name Name of a new screen. Expected to be in the camel case + (e.g. MarketingOptIn). No "Screen" suffix is needed. + +options: + -h, --help show this help message and exit + --no-webview Indicates whether user wants to skip creation of JS/HTML files. + (default: False) +""" + +import argparse +import logging +import os +import re +import subprocess +import sys + +# Configure logging with timestamp and log level. +logging.basicConfig(level=logging.INFO, + format="[%(asctime)s:%(levelname)s] %(message)s") + +if __name__ == '__main__': + # Need to add directories with other scripts to the PATH variable to be able + # to use them inside the tools/oobe folder. + sys.path.append(os.path.abspath(os.path.join(sys.path[0], '..'))) +import sort_sources + + +def GetGitRoot() -> str: + """Retrieves absolute path to the repository root. + + Returns: + An absolute path to the repository root in utf-8. + """ + job = subprocess.Popen(['git', 'rev-parse', '--show-toplevel'], + stdout=subprocess.PIPE) + out, err = job.communicate() + if job.returncode != 0: + logging.error('Error getting a git root: %s', err.decode('utf-8')) + sys.exit(1) + return out.decode('utf-8').strip() + + +GIT_ROOT = GetGitRoot() +SCREEN_GN_FILE_PATH = os.path.join(GIT_ROOT, 'chrome/browser/ash/BUILD.gn') +HANDLER_GN_FILE_PATH = os.path.join(GIT_ROOT, 'chrome/browser/ui/BUILD.gn') +WEBVIEW_JS_LIBRARY_GN_FILE_PATH = os.path.join( + GIT_ROOT, 'chrome/browser/resources/chromeos/login/screens/common/BUILD.gn') +WEBVIEW_GN_FILE_PATH = os.path.join( + GIT_ROOT, 'chrome/browser/resources/chromeos/login/BUILD.gn') + + +def IsCamelCase(screen_name: str) -> bool: + """Checks whether new screen's name is in the camel case. + + Args: + screen_name: A string that represents new screen name. + + Returns: + A boolean value that represents whether given screen name is in the camel + case. + """ + return re.match('^([A-Z][a-z]+)+$', screen_name) + + +def GetScreenNameWords(screen_name: str) -> list[str]: + """Breaks camel-case screen name into the words. + + Splits given camel case string into the logical lexems thath will be used to + substitute new screen's name inside the generated C++/JS files. + + Args: + screen_name: A string that represents new screen name in camel case. + + Returns: + An array of strings that represent logical lexems in a given camel case + screen name. + """ + return re.sub('([A-Z][a-z]+)', r' \1', re.sub('([A-Z]+)', r' \1', + screen_name)).split() + + +def FindAndReplace(name_words: list[str], file_path: str): + """Applies set of replace rules to a file. + + Reads content of a file from a given path and applies set of replace rules + to it's content. Overrides file content in the end. + + Args: + name_words: An array of strings that represents logical lexems of a new + screen's name. + file_path: An absolute path to a file. + """ + rules = [ + # Update placeholder class camel case name to the corresponding new + # screen's name. E.g. `class PlaceholderScreen`` will become + # `class MyNewScreen`.` + lambda content: re.sub('Placeholder', ''.join(name_words), content), + + # Update include guards. + lambda content: re.sub('PLACEHOLDER', '_'.join( + word.upper() for word in name_words), content), + + # Update include paths for both screen and handler. This simple substitute + # should be sufficient because new CPP files will be in the same folder + # with their copies. + lambda content: re.sub('placeholder_screen', ('_'.join( + word.lower() for word in name_words) + '_screen'), content), + + # Update screen id inside the handler and element id inside the JS file. + lambda content: re.sub('placeholder', '-'.join( + word.lower() for word in name_words), content) + ] + + with open(file_path, encoding='utf-8') as f: + content = f.read() + for rule in rules: + content = rule(content) + + with open(file_path, mode='w', encoding='utf-8', newline='\n') as f: + f.write(content) + + logging.info('Updated source file: %s', file_path) + + +def UpdateGnFile(name_words: list[str], gn_file_path: str): + """Updates given GN file with the new include rules. + + Tries to find one of the RegEx rules in each line of the GN file and inserts + new lines right after it. Sorts sources of the update GN file. + + Args: + name_words: An array of strings that represents logical lexems of a new + screen's name. + gn_file_path: An absolute path to a GN file. + """ + with open(gn_file_path, encoding='utf-8') as f: + content = f.readlines() + + result = [] + for line in content: + result.append(line) + is_cpp_include = re.search(r'placeholder_screen.*\.h', line) + is_js_include = re.search(r'placeholder.js', line) + if is_cpp_include or is_js_include: + new_file = re.sub('placeholder', + '_'.join(word.lower() for word in name_words), line) + if is_cpp_include: + result.append(re.sub('\.h', '.cc', new_file)) + result.append(new_file) + + with open(gn_file_path, mode='w', encoding='utf-8', newline='\n') as f: + f.writelines(result) + + # Currently, works only with the CPP includes. + sort_sources.ProcessFile(gn_file_path, should_confirm=False) + + logging.info('Updated GN file: %s', gn_file_path) + + +def UpdateWebviewGnFile(name_words: list[str], gn_file_path: str): + """Updates WebView GN file. + + It does the following steps; + 1) If ":placeholder" rule found it adds new rule right after it. + 2) If "js_library("placeholder")" rule found function copies it's content, + replaces all needed names and pastes result right after an original rule. + 3) If "placeholder.js" rule found it adds new rule right after it. + + This function doesn't sort sources order inside the GN file, as sort_sources + doesn't support JS files yet. + + Args: + name_words: An array of strings that represents logical lexems of a new + screen's name. + gn_file_path: An absolute path to a GN file. + """ + with open(gn_file_path, encoding='utf-8') as f: + content = f.readlines() + + result = [] + inside_closure_rule = False + closure = [] + for line in content: + result.append(line) + if inside_closure_rule: + closure.append(line) + if re.match('}', line): + inside_closure_rule = False + result.append('\n') + for closure_line in closure: + if re.search('placeholder', closure_line): + result.append( + re.sub('placeholder', + '_'.join(word.lower() for word in name_words), + closure_line)) + else: + result.append(closure_line) + else: + if re.search(':placeholder', line) or re.search(r'"placeholder.js"', + line): + result.append( + re.sub(r'placeholder', + '_'.join(word.lower() for word in name_words), line)) + elif re.search(r'js_library\("placeholder"\)', line): + inside_closure_rule = True + closure.append(line) + + with open(gn_file_path, mode='w', encoding='utf-8', newline='\n') as f: + f.writelines(result) + + logging.info('Updated GN file: %s', gn_file_path) + + +def FindPlacholderFilesPaths(globs: list[str]) -> list[str]: + """Finds placeholder files inside git repository with the git grep. + + Args: + globs: List of strings that represents expected file extensions. + + Returns: + An array of string paths to the placeholder files. + + Raises: + Exception if subprocess failed. + """ + job = subprocess.Popen( + ['git', 'grep', '-E', '--name-only', 'PlaceholderScreen', '--'] + globs, + stdout=subprocess.PIPE, + cwd=GIT_ROOT) + out, err = job.communicate() + if job.returncode != 0: + raise Exception(f'Error executing git grep: {err.decode("utf-8")}') + + return [path.decode('utf-8') for path in out.splitlines()] + + +def CopyPlaceholderFile(path: str, new_file_path: str): + """Executes cp command to create a copy of the placeholder file. + + Args: + path: Path to the original plachoolder file. + new_file_path: Path to a new file. + + Raises: + Exception if subprocess failed. + """ + job = subprocess.Popen(['cp', path, new_file_path], cwd=GIT_ROOT) + _, err = job.communicate() + if job.returncode != 0: + raise Exception(f'Error copying files: {err.decode("utf-8")}') + + logging.info('Created new file: %s', new_file_path) + + +def GenerateCppFiles(name_words: list[str]): + """Generates header and source files for screen and handler classes. + + This function does the following operations: + 1) Copy content of the PlaceholderScreen class, which implements all needed + intefaces, into a new files with a given screen name. + 2) Do a series of find and replace operations to move + includes/header guards/class names/etc to a new name. + 3) Add new files to the corresponding BUILD.gn files, sort build list to + preserve a right order. + + Args: + name_words: An array of strings that represents logical lexems of a new + screen's name. + """ + cpp_globs = ['*.cc', '*.h'] + paths = FindPlacholderFilesPaths(cpp_globs) + assert ( + len(paths) == 4 + ), 'There should be only 4 CPP files to copy (screen/handler .h and .cc)' + + for path in paths: + new_file_path = re.sub('placeholder', + '_'.join(s.lower() for s in name_words), path) + + CopyPlaceholderFile(path, new_file_path) + + FindAndReplace(name_words, os.path.join(GIT_ROOT, new_file_path)) + + cpp_gn_files = [SCREEN_GN_FILE_PATH, HANDLER_GN_FILE_PATH] + for name in cpp_gn_files: + UpdateGnFile(name_words, name) + + +def GenerateWebviewFiles(name_words: list[str]): + """Generates JS and HTML files for a new screen. + + This function does the following operations: + 1) Copy content of the placeholder.js and placeholder.html files + 2) Do a find and replace operations over new JS file. + 3) Add JS file to the corresponding BUILD.gn file, generate closure rule + for it. + + JS BUILD.gn rules currently will not be sorted, as sort_sources doesn't + support those extensions. + + Args: + name_words: An array of strings that represents logical lexems of a new + screen's name. + """ + webview_globs = ['*.js'] + paths = FindPlacholderFilesPaths(webview_globs) + + assert (len(paths) == 1), 'Only 1 JS file should be found' + + # HTML file doesn't contain any words that could be used verify it's + # correctness, so we can generate it's path from the corresponding JS file. + paths.append(re.sub(r'\.js', '.html', paths[0])) + + for path in paths: + new_file_path = re.sub('placeholder', + '_'.join(s.lower() for s in name_words), path) + + CopyPlaceholderFile(path, new_file_path) + + if new_file_path[-3:] == '.js': + FindAndReplace(name_words, os.path.join(GIT_ROOT, new_file_path)) + + UpdateGnFile(name_words, WEBVIEW_GN_FILE_PATH) + UpdateWebviewGnFile(name_words, WEBVIEW_JS_LIBRARY_GN_FILE_PATH) + + +def GenerateScreen(name_words: list[str], no_webview: bool): + """Executes new screen generation flow. + + Args: + name_words: An array of strings that represents logical lexems of a new + screen's name. + no_webview: True if WebView files should not be generated. + """ + logging.info('Generating screen and handler files') + GenerateCppFiles(name_words) + if no_webview: + logging.info('--no-webview flag is specified, skipping WebView generation') + return + logging.info('Generating WebView files') + GenerateWebviewFiles(name_words) + + +def main(): + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter) + parser.add_argument( + 'name', + help="""Name of a new screen. Expected to be in the camel case + (e.g. MarketingOptIn). No "Screen" suffix is needed.""") + parser.add_argument( + '--no-webview', + help='Indicates whether user wants to skip creation of JS/HTML files.', + action='store_true') + + options = parser.parse_args() + if not IsCamelCase(options.name): + logging.error('Screen name must be in the camel case') + parser.print_help() + return 1 + screen_name_words = GetScreenNameWords(options.name) + if screen_name_words[-1].lower() == 'screen': + logging.error( + '"Screen" suffix is not needed, it will be added automatically') + parser.print_help() + return 1 + + # Catching all kinds of errors here to generate non-zero exit code. + # This might be used in future to add a test to the CQ to verify that script + # works properly. + try: + GenerateScreen(screen_name_words, options.no_webview) + except Exception as ex: + logging.error(str(ex)) + return 1 + + return 0 + + +if __name__ == '__main__': + sys.exit(main())
diff --git a/tools/origin_trials/PRESUBMIT.py b/tools/origin_trials/PRESUBMIT.py index 880dfa7..b4e86bf0 100644 --- a/tools/origin_trials/PRESUBMIT.py +++ b/tools/origin_trials/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def _CommonChecks(input_api, output_api): results = [] @@ -16,12 +14,9 @@ # Run the generate_token unittests. results.extend( - input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', [r'^.+_unittest\.py$'], - run_on_python2=not USE_PYTHON3, - run_on_python3=USE_PYTHON3)) + input_api.canned_checks.RunUnitTestsInDirectory(input_api, output_api, + '.', + [r'^.+_unittest\.py$'])) return results
diff --git a/tools/perf/PRESUBMIT.py b/tools/perf/PRESUBMIT.py index fc1ce15b..c585327 100644 --- a/tools/perf/PRESUBMIT.py +++ b/tools/perf/PRESUBMIT.py
@@ -12,8 +12,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - def _CommonChecks(input_api, output_api, block_on_failure=False): """Performs common checks that vary between commit and upload.
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index 3b748f2c..8c0cd90 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -69,9 +69,9 @@ resource_sizes_trichrome_google,"agrieve@chromium.org, jbudorick@chromium.org",Build,https://chromium.googlesource.com/chromium/src/+/HEAD/tools/binary_size/README.md#resource_sizes_py, speedometer,"cbruni@chromium.org, vahl@chromium.org",Blink>JavaScript,https://browserbench.org/Speedometer,all speedometer-future,"cbruni@chromium.org, vahl@chromium.org",Blink>JavaScript,https://browserbench.org/Speedometer,all -speedometer2,"cbruni@chromium.org, vahl@chromium.org",Blink>JavaScript,https://browserbench.org/Speedometer2.0,all -speedometer2-future,"cbruni@chromium.org, vahl@chromium.org",Blink>JavaScript,https://browserbench.org/Speedometer2.0,all -speedometer2-minormc,omerkatz@chromium.org,Blink>JavaScript>GarbageCollection,https://browserbench.org/Speedometer2.0,all +speedometer2,"cbruni@chromium.org, vahl@chromium.org",Blink>JavaScript,https://browserbench.org/Speedometer2.1,all +speedometer2-future,"cbruni@chromium.org, vahl@chromium.org",Blink>JavaScript,https://browserbench.org/Speedometer2.1,all +speedometer2-minormc,omerkatz@chromium.org,Blink>JavaScript>GarbageCollection,https://browserbench.org/Speedometer2.1,all startup.mobile,"pasko@chromium.org, lizeb@chromium.org",Speed>Metrics>SystemHealthRegressions,, sync_performance_tests,mastiz@chromium.org,Services>Sync,https://chromium.googlesource.com/chromium/src/+/HEAD/components/sync/README.md, system_health.common_desktop,"charliea@chromium.org, sullivan@chromium.org, tdresser@chromium.org, chrome-speed-metrics-dev@chromium.org",Speed>Metrics>SystemHealthRegressions,https://bit.ly/system-health-benchmarks,"2016,2018,2019,2020,2021,accessibility,emerging_market,health_check,images,infinite_scroll,international,javascript_heavy,keyboard_input,scroll,tabs_switching,wasm,webgl"
diff --git a/tools/perf/benchmarks/speedometer2.py b/tools/perf/benchmarks/speedometer2.py index 4482b31..dec387c 100644 --- a/tools/perf/benchmarks/speedometer2.py +++ b/tools/perf/benchmarks/speedometer2.py
@@ -131,7 +131,6 @@ """Speedometer2.0 benchmark. Explicitly named version.""" - # TODO(cbruni): update source folder name to speedometer20 here. _SOURCE_DIR = os.path.join(_PERF_TEST_DIR, 'speedometer20') @classmethod @@ -163,8 +162,8 @@ @benchmark.Info(emails=['cbruni@chromium.org', 'vahl@chromium.org'], component='Blink>JavaScript', - documentation_url='https://browserbench.org/Speedometer2.0') -class Speedometer2(Speedometer20): + documentation_url='https://browserbench.org/Speedometer2.1') +class Speedometer2(Speedometer21): """The latest version of the Speedometer2 benchmark.""" @classmethod def GetStoryClass(cls): @@ -177,7 +176,7 @@ @benchmark.Info(emails=['cbruni@chromium.org', 'vahl@chromium.org'], component='Blink>JavaScript', - documentation_url='https://browserbench.org/Speedometer2.0') + documentation_url='https://browserbench.org/Speedometer2.1') class V8Speedometer2Future(Speedometer2): """The latest Speedometer2 benchmark with the V8 flag --future. @@ -194,7 +193,7 @@ @benchmark.Info(emails=['omerkatz@chromium.org'], component='Blink>JavaScript>GarbageCollection', - documentation_url='https://browserbench.org/Speedometer2.0') + documentation_url='https://browserbench.org/Speedometer2.1') class Speedometer2MinorMC(Speedometer2): """The latest Speedometer2 benchmark with the MinorMC flag.
diff --git a/tools/perf/contrib/PRESUBMIT.py b/tools/perf/contrib/PRESUBMIT.py index 3b081b4c..c79933b3 100644 --- a/tools/perf/contrib/PRESUBMIT.py +++ b/tools/perf/contrib/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def _CommonChecks(input_api, output_api): """Performs common checks, which includes running pylint."""
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index cd0a56e..0c459d1d 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,24 +5,24 @@ "full_remote_path": "perfetto-luci-artifacts/v34.0/linux-arm64/trace_processor_shell" }, "win": { - "hash": "349a8e51c5e0d58bddeee497f4bc77b878e8ac4b", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/770cd78332f9fa4addf45187d116f5bb31bc260a/trace_processor_shell.exe" + "hash": "785a0142235398f5003b8c6eeb05caa4c8310ea9", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/922cf5c76a1ef4eb6fd120d86af5fe54389913f2/trace_processor_shell.exe" }, "linux_arm": { "hash": "336a42cb9ec3c417e13a97816271fec10cdf67e5", "full_remote_path": "perfetto-luci-artifacts/v34.0/linux-arm/trace_processor_shell" }, "mac": { - "hash": "edb17698f680883e316b298426dd0dfd785e64dc", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/53002b30d2f05f6c267012ce2abf3c5fbd4e9e35/trace_processor_shell" + "hash": "261d7d935c038f25d30033a2f33b92f08da248f6", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/922cf5c76a1ef4eb6fd120d86af5fe54389913f2/trace_processor_shell" }, "mac_arm64": { "hash": "c32364e05e22cdf82ee0866aedd11c0e2050809c", "full_remote_path": "perfetto-luci-artifacts/v34.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "086752445a515ef40fd270cdde071d551cd1d830", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/53002b30d2f05f6c267012ce2abf3c5fbd4e9e35/trace_processor_shell" + "hash": "1f2baf3ecdb136072fb52cb0f6a81e7f38403c4f", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/922cf5c76a1ef4eb6fd120d86af5fe54389913f2/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/polymer/PRESUBMIT.py b/tools/polymer/PRESUBMIT.py index d5ecd013..2b42724 100644 --- a/tools/polymer/PRESUBMIT.py +++ b/tools/polymer/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - def RunPolymerTests(input_api, output_api): presubmit_path = input_api.PresubmitLocalPath() @@ -17,10 +15,7 @@ 'html_to_js_test.py', 'html_to_wrapper_test.py', 'css_to_wrapper_test.py' ] tests = [input_api.os_path.join(presubmit_path, s) for s in sources] - return input_api.canned_checks.RunUnitTests(input_api, - output_api, - tests, - run_on_python2=False) + return input_api.canned_checks.RunUnitTests(input_api, output_api, tests) def _CheckChangeOnUploadOrCommit(input_api, output_api):
diff --git a/tools/resources/PRESUBMIT.py b/tools/resources/PRESUBMIT.py index f07a4a35..02b7013 100644 --- a/tools/resources/PRESUBMIT.py +++ b/tools/resources/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def CheckChangeOnUpload(*args): return _CommonChecks(*args) @@ -20,9 +18,6 @@ if any(f for f in files if f.startswith('svgo_presubmit')): tests = [path.join(cwd, 'svgo_presubmit_test.py')] - return input_api.canned_checks.RunUnitTests(input_api, - output_api, - tests, - run_on_python2=False) + return input_api.canned_checks.RunUnitTests(input_api, output_api, tests) return []
diff --git a/tools/tracing/PRESUBMIT.py b/tools/tracing/PRESUBMIT.py index 4e70ce9..46c19449 100644 --- a/tools/tracing/PRESUBMIT.py +++ b/tools/tracing/PRESUBMIT.py
@@ -8,7 +8,6 @@ """ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True def RunUnittests(input_api, output_api): @@ -21,12 +20,7 @@ results.extend( input_api.canned_checks.RunUnitTestsInDirectory( - input_api, - output_api, - '.', - files_to_check=[r'.+_unittest\.py$'], - run_on_python2=not USE_PYTHON3, - skip_shebang_check=True)) + input_api, output_api, '.', files_to_check=[r'.+_unittest\.py$'])) return results
diff --git a/tools/traffic_annotation/scripts/update_annotations_doc.py.vpython3 b/tools/traffic_annotation/scripts/update_annotations_doc.py.vpython3 index f27b26c..08e2793 100644 --- a/tools/traffic_annotation/scripts/update_annotations_doc.py.vpython3 +++ b/tools/traffic_annotation/scripts/update_annotations_doc.py.vpython3
@@ -96,8 +96,8 @@ > wheel: < - name: "infra/python/wheels/requests-py2_py3" - version: "version:2.26.0" + name: "infra/python/wheels/requests-py3" + version: "version:2.31.0" > wheel: <
diff --git a/tools/translation/PRESUBMIT.py b/tools/translation/PRESUBMIT.py index f105bf81..7d7e3ae 100644 --- a/tools/translation/PRESUBMIT.py +++ b/tools/translation/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def _CommonChecks(input_api, output_api): results = [] @@ -16,20 +14,11 @@ # Run unittests. tests = input_api.canned_checks.GetUnitTestsInDirectory( - input_api, - output_api, - '.', [r'^.+_unittest\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True) + input_api, output_api, '.', [r'^.+_unittest\.py$']) tests.extend( - input_api.canned_checks.GetUnitTestsInDirectory(input_api, - output_api, + input_api.canned_checks.GetUnitTestsInDirectory(input_api, output_api, 'helper', - [r'^.+_unittest\.py$'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + [r'^.+_unittest\.py$'])) results.extend(input_api.RunTests(tests)) return results
diff --git a/tools/typescript/PRESUBMIT.py b/tools/typescript/PRESUBMIT.py index 7727a393..f365afb 100644 --- a/tools/typescript/PRESUBMIT.py +++ b/tools/typescript/PRESUBMIT.py
@@ -7,7 +7,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' @@ -27,10 +26,7 @@ presubmit_path = input_api.PresubmitLocalPath() sources = ['ts_library_test.py'] tests = [input_api.os_path.join(presubmit_path, s) for s in sources] - return input_api.canned_checks.RunUnitTests(input_api, - output_api, - tests, - run_on_python2=False) + return input_api.canned_checks.RunUnitTests(input_api, output_api, tests) def CheckStyleESLint(input_api, output_api):
diff --git a/tools/vim/PRESUBMIT.py b/tools/vim/PRESUBMIT.py index 55d2784..ebcbc63 100644 --- a/tools/vim/PRESUBMIT.py +++ b/tools/vim/PRESUBMIT.py
@@ -6,8 +6,6 @@ Runs Python unit tests in /tools/vim/tests on upload. """ -USE_PYTHON3 = True - def CheckChangeOnUpload(input_api, output_api): results = [] @@ -28,10 +26,7 @@ any([input_api.re.match(r'tests(/|\\)',f) for f in affected_files]): results += input_api.RunTests( input_api.canned_checks.GetUnitTests( - input_api, - output_api, ['tests/chromium.ycm_extra_conf_unittest.py'], - run_on_python2=False, - run_on_python3=True, - skip_shebang_check=True)) + input_api, output_api, + ['tests/chromium.ycm_extra_conf_unittest.py'])) return results
diff --git a/tools/web_dev_style/PRESUBMIT.py b/tools/web_dev_style/PRESUBMIT.py index 64dcdb9..9d2b7e4 100644 --- a/tools/web_dev_style/PRESUBMIT.py +++ b/tools/web_dev_style/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - def CheckChangeOnUpload(*args): return _CommonChecks(*args) @@ -16,7 +14,4 @@ def _CommonChecks(input_api, output_api): tests = ['test_suite.py'] - return input_api.canned_checks.RunUnitTests(input_api, - output_api, - tests, - run_on_python2=False) + return input_api.canned_checks.RunUnitTests(input_api, output_api, tests)
diff --git a/ui/accessibility/PRESUBMIT.py b/ui/accessibility/PRESUBMIT.py index 0c55215..5a41047 100644 --- a/ui/accessibility/PRESUBMIT.py +++ b/ui/accessibility/PRESUBMIT.py
@@ -8,8 +8,6 @@ import os import re -USE_PYTHON3 = True - AX_MOJOM = 'ui/accessibility/ax_enums.mojom' AUTOMATION_IDL = 'extensions/common/api/automation.idl'
diff --git a/ui/accessibility/ax_enum_util.cc b/ui/accessibility/ax_enum_util.cc index 2da56a9..1301beb 100644 --- a/ui/accessibility/ax_enum_util.cc +++ b/ui/accessibility/ax_enum_util.cc
@@ -1744,7 +1744,7 @@ return "isPageBreakingObject"; case ax::mojom::BoolAttribute::kHasAriaAttribute: return "hasAriaAttribute"; - case ax::mojom::BoolAttribute::kTouchPassthrough: + case ax::mojom::BoolAttribute::OBSOLETE_kTouchPassthrough: return "touchPassthrough"; case ax::mojom::BoolAttribute::kLongClickable: return "longClickable"; @@ -1797,8 +1797,8 @@ return ax::mojom::BoolAttribute::kIsPageBreakingObject; } else if (bool_attribute == "kHasAriaAttribute") { return ax::mojom::BoolAttribute::kHasAriaAttribute; - } else if (bool_attribute == "kTouchPassthrough") { - return ax::mojom::BoolAttribute::kTouchPassthrough; + } else if (bool_attribute == "OBSOLETE_kTouchPassthrough") { + return ax::mojom::BoolAttribute::OBSOLETE_kTouchPassthrough; } else if (bool_attribute == "kLongClickable") { return ax::mojom::BoolAttribute::kLongClickable; } else {
diff --git a/ui/accessibility/ax_enums.mojom b/ui/accessibility/ax_enums.mojom index fe740a5..81141ab 100644 --- a/ui/accessibility/ax_enums.mojom +++ b/ui/accessibility/ax_enums.mojom
@@ -865,10 +865,8 @@ // True if the node has any ARIA attributes set. kHasAriaAttribute = 19, - // This element allows touches to be passed through when a screen reader - // is in touch exploration mode, e.g. a virtual keyboard normally - // behaves this way. - kTouchPassthrough = 20, + // OBSOLETE - Do no use. + OBSOLETE_kTouchPassthrough = 20, // A hint to clients that the node is long clickable. [MinVersion=1] kLongClickable = 21,
diff --git a/ui/accessibility/ax_node_data.cc b/ui/accessibility/ax_node_data.cc index 2f811137..819ddcd 100644 --- a/ui/accessibility/ax_node_data.cc +++ b/ui/accessibility/ax_node_data.cc
@@ -1857,7 +1857,7 @@ case ax::mojom::BoolAttribute::kHasAriaAttribute: result += " has_aria_attribute=" + value; break; - case ax::mojom::BoolAttribute::kTouchPassthrough: + case ax::mojom::BoolAttribute::OBSOLETE_kTouchPassthrough: result += " touch_passthrough=" + value; break; case ax::mojom::BoolAttribute::kLongClickable:
diff --git a/ui/accessibility/ax_node_position_fuzzer.cc b/ui/accessibility/ax_node_position_fuzzer.cc index f38cce7c..935a2c07 100644 --- a/ui/accessibility/ax_node_position_fuzzer.cc +++ b/ui/accessibility/ax_node_position_fuzzer.cc
@@ -70,7 +70,7 @@ raw_ptr<ui::AXTree> tree_; const ui::AXNodeID max_id_; - FuzzerData& fuzzer_data_; + const raw_ref<FuzzerData> fuzzer_data_; }; AXNodePositionFuzzerGenerator::AXNodePositionFuzzerGenerator( @@ -80,9 +80,9 @@ : tree_(tree), max_id_(max_id), fuzzer_data_(fuzzer_data) {} TestPositionType AXNodePositionFuzzerGenerator::CreateNewPosition() { - return CreateNewPosition(fuzzer_data_.NextByte(), fuzzer_data_.NextByte(), - GeneratePositionKind(fuzzer_data_.NextByte()), - GenerateTextAffinity(fuzzer_data_.NextByte())); + return CreateNewPosition(fuzzer_data_->NextByte(), fuzzer_data_->NextByte(), + GeneratePositionKind(fuzzer_data_->NextByte()), + GenerateTextAffinity(fuzzer_data_->NextByte())); } TestPositionType AXNodePositionFuzzerGenerator::CreateNewPosition( @@ -158,7 +158,7 @@ TestPositionType AXNodePositionFuzzerGenerator::GenerateNextPosition( TestPositionType& current_position, TestPositionType& previous_position) { - switch (fuzzer_data_.NextByte() % 55) { + switch (fuzzer_data_->NextByte() % 55) { case 0: default: return CreateNewPosition(); @@ -176,11 +176,11 @@ return current_position->AsDomSelectionPosition(); case 7: return current_position->AsUnignoredPosition( - GenerateAdjustmentBehavior(fuzzer_data_.NextByte())); + GenerateAdjustmentBehavior(fuzzer_data_->NextByte())); case 8: return current_position->CreateAncestorPosition( previous_position->GetAnchor(), - GenerateMoveDirection(fuzzer_data_.NextByte())); + GenerateMoveDirection(fuzzer_data_->NextByte())); case 9: return current_position->CreatePositionAtStartOfAnchor(); case 10: @@ -194,11 +194,11 @@ case 14: return current_position->CreatePositionAtEndOfContent(); case 15: - return current_position->CreateChildPositionAt(fuzzer_data_.NextByte() % + return current_position->CreateChildPositionAt(fuzzer_data_->NextByte() % 10); case 16: return current_position->CreateParentPosition( - GenerateMoveDirection(fuzzer_data_.NextByte())); + GenerateMoveDirection(fuzzer_data_->NextByte())); case 17: return current_position->CreateNextLeafTreePosition(); case 18: @@ -213,121 +213,121 @@ return current_position->AsLeafTextPositionAfterCharacter(); case 23: return current_position->CreatePreviousCharacterPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 24: return current_position->CreateNextWordStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 25: return current_position->CreatePreviousWordStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 26: return current_position->CreateNextWordEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 27: return current_position->CreatePreviousWordEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 28: return current_position->CreateNextLineStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 29: return current_position->CreatePreviousLineStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 30: return current_position->CreateNextLineEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 31: return current_position->CreatePreviousLineEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 32: return current_position->CreateNextFormatStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 33: return current_position->CreatePreviousFormatStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 34: return current_position->CreateNextFormatEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 35: return current_position->CreatePreviousFormatEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 36: return current_position->CreateNextSentenceStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 37: return current_position->CreatePreviousSentenceStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 38: return current_position->CreateNextSentenceEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 39: return current_position->CreatePreviousSentenceEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 40: return current_position->CreateNextParagraphStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 41: return current_position ->CreateNextParagraphStartPositionSkippingEmptyParagraphs( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 42: return current_position->CreatePreviousParagraphStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 43: return current_position ->CreatePreviousParagraphStartPositionSkippingEmptyParagraphs( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 44: return current_position->CreateNextParagraphEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 45: return current_position->CreatePreviousParagraphEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 46: return current_position->CreateNextPageStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 47: return current_position->CreatePreviousPageStartPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 48: return current_position->CreateNextPageEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 49: return current_position->CreatePreviousPageEndPosition( - GenerateMovementOptions(fuzzer_data_.NextByte(), - fuzzer_data_.NextByte())); + GenerateMovementOptions(fuzzer_data_->NextByte(), + fuzzer_data_->NextByte())); case 52: return current_position->CreateNextAnchorPosition(); case 53: return current_position->CreatePreviousAnchorPosition(); case 54: return current_position->LowestCommonAncestorPosition( - *previous_position, GenerateMoveDirection(fuzzer_data_.NextByte())); + *previous_position, GenerateMoveDirection(fuzzer_data_->NextByte())); } }
diff --git a/ui/accessibility/platform/BUILD.gn b/ui/accessibility/platform/BUILD.gn index c9777e07..7b3d41de 100644 --- a/ui/accessibility/platform/BUILD.gn +++ b/ui/accessibility/platform/BUILD.gn
@@ -243,6 +243,8 @@ "inspect/ax_tree_indexer_mac.h", ] + configs += [ "//build/config/compiler:enable_arc" ] + frameworks = [ "AppKit.framework", "Foundation.framework",
diff --git a/ui/accessibility/platform/ax_event_intent_mac.h b/ui/accessibility/platform/ax_event_intent_mac.h index 7e714be..bf128c8 100644 --- a/ui/accessibility/platform/ax_event_intent_mac.h +++ b/ui/accessibility/platform/ax_event_intent_mac.h
@@ -135,7 +135,7 @@ AXTextSelection selection); // Constructs an editing intent. - AXTextStateChangeIntent(AXTextEditType edit); + explicit AXTextStateChangeIntent(AXTextEditType edit); AXTextStateChangeIntent(const AXTextStateChangeIntent& intent);
diff --git a/ui/accessibility/platform/ax_event_intent_mac.mm b/ui/accessibility/platform/ax_event_intent_mac.mm index a6169800..de8d4ba9 100644 --- a/ui/accessibility/platform/ax_event_intent_mac.mm +++ b/ui/accessibility/platform/ax_event_intent_mac.mm
@@ -7,6 +7,10 @@ #include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_event_intent.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { // static @@ -107,7 +111,7 @@ break; } - return AXTextSelection(direction, granularity, /* focus_change */ false); + return AXTextSelection(direction, granularity, /*focus_change=*/false); } AXTextSelection::AXTextSelection() = default; @@ -133,7 +137,7 @@ AXTextStateChangeType::kSelectionMove, AXTextSelection(AXTextSelectionDirection::kDiscontiguous, AXTextSelectionGranularity::kUnknown, - /* focus_change */ true)); + /*focus_change=*/true)); } // static @@ -143,7 +147,7 @@ AXTextStateChangeType::kSelectionMove, AXTextSelection(AXTextSelectionDirection::kDiscontiguous, AXTextSelectionGranularity::kUnknown, - /* focus_change */ false)); + /*focus_change=*/false)); } AXTextStateChangeIntent::AXTextStateChangeIntent() = default;
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.h b/ui/accessibility/platform/ax_platform_node_cocoa.h index c28aea7..e2e6297 100644 --- a/ui/accessibility/platform/ax_platform_node_cocoa.h +++ b/ui/accessibility/platform/ax_platform_node_cocoa.h
@@ -5,32 +5,25 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_COCOA_H_ #define UI_ACCESSIBILITY_PLATFORM_AX_PLATFORM_NODE_COCOA_H_ -#include <memory> - #import <Accessibility/Accessibility.h> #import <Cocoa/Cocoa.h> #include "base/component_export.h" -#include "base/mac/scoped_nsobject.h" #include "ui/accessibility/ax_enums.mojom-forward.h" namespace ui { - class AXPlatformNodeBase; class AXPlatformNodeDelegate; - -struct AXAnnouncementSpec { - AXAnnouncementSpec(); - ~AXAnnouncementSpec(); - - base::scoped_nsobject<NSString> announcement; - base::scoped_nsobject<NSWindow> window; - bool is_polite; -}; - } // namespace ui COMPONENT_EXPORT(AX_PLATFORM) +@interface AXAnnouncementSpec : NSObject +@property(nonatomic, readonly) NSString* announcement; +@property(nonatomic, readonly) NSWindow* window; +@property(nonatomic, readonly) BOOL polite; +@end + +COMPONENT_EXPORT(AX_PLATFORM) @interface AXPlatformNodeCocoa : NSAccessibilityElement <NSAccessibility, AXCustomContentProvider> @@ -75,17 +68,15 @@ @property(nonatomic, readonly) ui::AXPlatformNodeDelegate* nodeDelegate; // Returns the data necessary to queue an NSAccessibility announcement if -// |eventType| should be announced, or nullptr otherwise. -- (std::unique_ptr<ui::AXAnnouncementSpec>)announcementForEvent: - (ax::mojom::Event)eventType; +// |eventType| should be announced, or nil otherwise. +- (AXAnnouncementSpec*)announcementForEvent:(ax::mojom::Event)eventType; // Ask the system to announce |announcementText|. This is debounced to happen // at most every |kLiveRegionDebounceMillis| per node, with only the most // recent announcement text read, to account for situations with multiple // notifications happening one after another (for example, results for // find-in-page updating rapidly as they come in from subframes). -- (void)scheduleLiveRegionAnnouncement: - (std::unique_ptr<ui::AXAnnouncementSpec>)announcement; +- (void)scheduleLiveRegionAnnouncement:(AXAnnouncementSpec*)announcement; - (id)AXWindow;
diff --git a/ui/accessibility/platform/ax_platform_node_cocoa.mm b/ui/accessibility/platform/ax_platform_node_cocoa.mm index a04de4d..16de7b84 100644 --- a/ui/accessibility/platform/ax_platform_node_cocoa.mm +++ b/ui/accessibility/platform/ax_platform_node_cocoa.mm
@@ -5,6 +5,7 @@ #import "ui/accessibility/platform/ax_platform_node_cocoa.h" #import <Cocoa/Cocoa.h> +#include <Foundation/Foundation.h> #include "base/logging.h" #include "base/mac/foundation_util.h" @@ -27,19 +28,32 @@ #import "ui/gfx/mac/coordinate_conversion.h" #include "ui/strings/grit/ax_strings.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + using AXRange = ui::AXPlatformNodeDelegate::AXRange; -namespace ui { +@interface AXAnnouncementSpec () -AXAnnouncementSpec::AXAnnouncementSpec() = default; -AXAnnouncementSpec::~AXAnnouncementSpec() = default; +@property(nonatomic, strong) NSString* announcement; +@property(nonatomic, strong) NSWindow* window; +@property(nonatomic, assign) BOOL polite; -} // namespace ui +@end + +@implementation AXAnnouncementSpec + +@synthesize announcement = _announcement; +@synthesize window = _window; +@synthesize polite = _polite; + +@end namespace { // Same length as web content/WebKit. -static int kLiveRegionDebounceMillis = 20; +int kLiveRegionDebounceMillis = 20; using RoleMap = std::map<ax::mojom::Role, NSString*>; using EventMap = std::map<ax::mojom::Event, NSString*>; @@ -236,7 +250,7 @@ @implementation AXPlatformNodeCocoa { // This field is not a raw_ptr<> because it requires @property rewrite. RAW_PTR_EXCLUSION ui::AXPlatformNodeBase* _node; // Weak. Retains us. - std::unique_ptr<ui::AXAnnouncementSpec> _pendingAnnouncement; + AXAnnouncementSpec* __strong _pendingAnnouncement; } @synthesize node = _node; @@ -329,9 +343,9 @@ break; } - // On Mac OS X, the accessible name of an object is exposed as its - // title if it comes from visible text, and as its description - // otherwise, but never both. + // On macOS, the accessible name of an object is exposed as its title if it + // comes from visible text, and as its description otherwise, but never both. + // // Note: a placeholder is often visible text, but since it aids in data entry // it is similar to accessibilityValue, and thus cannot be exposed either in // accessibilityTitle or in accessibilityLabel. @@ -785,7 +799,7 @@ // Add annotation information int leafTextLength = leafTextRange.GetText().length(); DCHECK_LE(static_cast<unsigned long>(anchorStartOffset + leafTextLength), - [attributedString length]); + attributedString.length); NSRange leafRange = NSMakeRange(anchorStartOffset, leafTextLength); CollectAncestorRoles(*anchor, ancestor_roles); @@ -821,16 +835,15 @@ // TODO(crbug.com/958811): Implement NSAccessibilityVisibleNameKey. if (text_attrs.font_size != ui::AXTextAttributes::kUnsetValue) { - [fontAttributes setValue:@(text_attrs.font_size) - forKey:NSAccessibilityFontSizeKey]; + fontAttributes[NSAccessibilityFontSizeKey] = @(text_attrs.font_size); } if (text_attrs.HasTextStyle(ax::mojom::TextStyle::kBold)) { - [fontAttributes setValue:@YES forKey:@"AXFontBold"]; + fontAttributes[@"AXFontBold"] = @YES; } if (text_attrs.HasTextStyle(ax::mojom::TextStyle::kItalic)) { - [fontAttributes setValue:@YES forKey:@"AXFontItalic"]; + fontAttributes[@"AXFontItalic"] = @YES; } [attributedString addAttribute:NSAccessibilityFontTextAttribute @@ -913,24 +926,24 @@ return base::SysUTF8ToNSString(_node->GetName()); } -- (std::unique_ptr<ui::AXAnnouncementSpec>)announcementForEvent: - (ax::mojom::Event)eventType { +- (AXAnnouncementSpec*)announcementForEvent:(ax::mojom::Event)eventType { // Only alerts and live region changes should be announced. DCHECK(eventType == ax::mojom::Event::kAlert || eventType == ax::mojom::Event::kLiveRegionChanged); std::string liveStatus = _node->GetStringAttribute(ax::mojom::StringAttribute::kLiveStatus); // If live status is explicitly set to off, don't announce. - if (liveStatus == "off") - return nullptr; + if (liveStatus == "off") { + return nil; + } NSString* name = [self getName]; NSString* announcementText = - [name length] > 0 - ? name - : base::SysUTF16ToNSString(_node->GetTextContentUTF16()); - if ([announcementText length] == 0) - return nullptr; + name.length > 0 ? name + : base::SysUTF16ToNSString(_node->GetTextContentUTF16()); + if (announcementText.length == 0) { + return nil; + } const std::string& description = _node->GetStringAttribute(ax::mojom::StringAttribute::kDescription); @@ -942,34 +955,31 @@ base::SysUTF8ToNSString(description)]; } - auto announcement = std::make_unique<ui::AXAnnouncementSpec>(); - announcement->announcement = - base::scoped_nsobject<NSString>([announcementText retain]); - announcement->window = - base::scoped_nsobject<NSWindow>([[self AXWindow] retain]); - announcement->is_polite = liveStatus != "assertive"; - return announcement; + AXAnnouncementSpec* spec = [[AXAnnouncementSpec alloc] init]; + spec.announcement = announcementText; + spec.window = [self AXWindow]; + spec.polite = liveStatus != "assertive"; + return spec; } -- (void)scheduleLiveRegionAnnouncement: - (std::unique_ptr<ui::AXAnnouncementSpec>)announcement { +- (void)scheduleLiveRegionAnnouncement:(AXAnnouncementSpec*)announcement { if (_pendingAnnouncement) { // An announcement is already in flight, so just reset the contents. This is // threadsafe because the dispatch is on the main queue. - _pendingAnnouncement = std::move(announcement); + _pendingAnnouncement = announcement; return; } - _pendingAnnouncement = std::move(announcement); + _pendingAnnouncement = announcement; dispatch_after( kLiveRegionDebounceMillis * NSEC_PER_MSEC, dispatch_get_main_queue(), ^{ - if (!_pendingAnnouncement) { + if (!self->_pendingAnnouncement) { return; } - PostAnnouncementNotification(_pendingAnnouncement->announcement, - _pendingAnnouncement->window, - _pendingAnnouncement->is_polite); - _pendingAnnouncement.reset(); + PostAnnouncementNotification(self->_pendingAnnouncement.announcement, + self->_pendingAnnouncement.window, + self->_pendingAnnouncement.polite); + self->_pendingAnnouncement = nil; }); } @@ -983,8 +993,9 @@ } - (id)accessibilityHitTest:(NSPoint)point { - if (!NSPointInRect(point, [self boundsInScreen])) + if (!NSPointInRect(point, self.boundsInScreen)) { return nil; + } for (id child in [[self AXChildren] reverseObjectEnumerator]) { if (!NSPointInRect(point, [child accessibilityFrame])) @@ -1012,8 +1023,7 @@ if (!_node) return @[]; - base::scoped_nsobject<NSMutableArray> axActions( - [[NSMutableArray alloc] init]); + NSMutableArray* axActions = [NSMutableArray array]; const ActionList& action_list = GetActionList(); // VoiceOver expects the "press" action to be first. Note that some roles @@ -1027,7 +1037,7 @@ if (AlsoUseShowMenuActionForDefaultAction(*_node)) [axActions addObject:NSAccessibilityShowMenuAction]; - return axActions.autorelease(); + return axActions; } - (void)accessibilityPerformAction:(NSString*)action { @@ -1092,10 +1102,9 @@ ]; // Required for all text, including protected textfields. NSString* const kTextAttributes = NSAccessibilityPlaceholderValueAttribute; - base::scoped_nsobject<NSMutableArray> axAttributes( - [[NSMutableArray alloc] init]); - [axAttributes addObjectsFromArray:kAllRoleAttributes]; + NSMutableArray* axAttributes = + [NSMutableArray arrayWithArray:kAllRoleAttributes]; ax::mojom::Role role = _node->GetRole(); switch (role) { case ax::mojom::Role::kTextField: @@ -1292,7 +1301,7 @@ if ([self titleUIElement]) [axAttributes addObject:NSAccessibilityTitleUIElementAttribute]; - return axAttributes.autorelease(); + return axAttributes; } - (NSArray*)accessibilityParameterizedAttributeNames { @@ -1342,8 +1351,11 @@ return nil; // Return nil when detached. Even for ax::mojom::Role. SEL selector = NSSelectorFromString(attribute); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" if ([self respondsToSelector:selector]) return [self performSelector:selector]; +#pragma clang diagnostic pop return nil; } @@ -1353,8 +1365,11 @@ return nil; SEL selector = NSSelectorFromString([attribute stringByAppendingString:@":"]); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" if ([self respondsToSelector:selector]) return [self performSelector:selector withObject:parameter]; +#pragma clang diagnostic pop return nil; } @@ -1524,7 +1539,7 @@ if (![self instanceActive]) return nil; - NSMutableArray* elements = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* elements = [NSMutableArray array]; for (ui::AXNodeID id : _node->GetIntListAttribute(ax::mojom::IntListAttribute::kDetailsIds)) { AXPlatformNodeCocoa* node = [self fromNodeID:id]; @@ -1532,14 +1547,14 @@ [elements addObject:node]; } - return [elements count] ? elements : nil; + return elements.count ? elements : nil; } - (NSArray*)AXDOMClassList { if (![self instanceActive]) return nil; - NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* ret = [NSMutableArray array]; std::string classes; if (_node->GetStringAttribute(ax::mojom::StringAttribute::kClassName, @@ -1673,9 +1688,7 @@ if (!container) return nil; - NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; - [ret addObject:container->GetNativeViewAccessible()]; - return ret; + return @[ container->GetNativeViewAccessible() ]; } - (NSString*)AXPopupValue { @@ -1877,7 +1890,7 @@ const auto checkedState = static_cast<ax::mojom::CheckedState>( _node->GetIntAttribute(ax::mojom::IntAttribute::kCheckedState)); if (checkedState == ax::mojom::CheckedState::kTrue) { - return @"\xE2\x9C\x93"; // UTF-8 for unicode 0x2713, "check mark" + return @"\u2713"; // "check mark" } return @""; @@ -2009,8 +2022,8 @@ // We potentially need to add text attributes to the whole text content // because a spelling mistake might start or end outside the given range. NSMutableAttributedString* attributedTextContent = - [[[NSMutableAttributedString alloc] - initWithString:base::SysUTF16ToNSString(textContent)] autorelease]; + [[NSMutableAttributedString alloc] + initWithString:base::SysUTF16ToNSString(textContent)]; if (!_node->IsText()) { AXRange axRange(_node->GetDelegate()->CreateTextPositionAt(0), _node->GetDelegate()->CreateTextPositionAt( @@ -2027,11 +2040,12 @@ return nil; NSString* text = base::SysUTF16ToNSString(axRange.GetText()); - if ([text length] == 0) + if (text.length == 0) { return nil; + } NSMutableAttributedString* attributedText = - [[[NSMutableAttributedString alloc] initWithString:text] autorelease]; + [[NSMutableAttributedString alloc] initWithString:text]; // Currently, we only decorate the attributed string with misspelling // and annotation information. [self addTextAnnotationsIn:&axRange to:attributedText]; @@ -2094,7 +2108,7 @@ if (![self instanceActive]) return nil; - // Mac OS X wants static text exposed in AXValue. + // macOS wants static text exposed in AXValue. if (ui::IsNameExposedInAXValueForRole([self internalRole])) return @""; @@ -2345,7 +2359,7 @@ NSArray* rows = [self accessibilityRows]; // accessibilityRows returns an empty array unless instanceActive does, // not exist, so we do not need to check if rows is nil at this time. - NSMutableArray* selectedRows = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* selectedRows = [NSMutableArray array]; for (id row in rows) { if ([[row accessibilitySelected] boolValue]) { [selectedRows addObject:row]; @@ -2362,7 +2376,7 @@ ui::AXPlatformNodeDelegate* delegate = _node->GetDelegate(); DCHECK(delegate); - NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* ret = [NSMutableArray array]; // If this is a table, return all column headers. ax::mojom::Role role = _node->GetRole(); @@ -2522,30 +2536,28 @@ if (!_node) return 0; - return - [[self AXLineForIndex:[NSNumber numberWithInteger:index]] integerValue]; + return [[self AXLineForIndex:@(index)] integerValue]; } - (NSRange)accessibilityRangeForIndex:(NSInteger)index { if (!_node) return NSMakeRange(0, 0); - return [[self AXRangeForIndex:[NSNumber numberWithInteger:index]] rangeValue]; + return [[self AXRangeForIndex:@(index)] rangeValue]; } - (NSRange)accessibilityStyleRangeForIndex:(NSInteger)index { if (!_node) return NSMakeRange(0, 0); - return [[self AXStyleRangeForIndex:[NSNumber numberWithInteger:index]] - rangeValue]; + return [[self AXStyleRangeForIndex:@(index)] rangeValue]; } - (NSRange)accessibilityRangeForLine:(NSInteger)line { if (!_node) return NSMakeRange(0, 0); - return [[self AXRangeForLine:[NSNumber numberWithInteger:line]] rangeValue]; + return [[self AXRangeForLine:@(line)] rangeValue]; } - (NSRange)accessibilityRangeForPosition:(NSPoint)point { @@ -2746,30 +2758,27 @@ return nil; } -static NSDictionary* createMathSubSupScriptsPair( - AXPlatformNodeCocoa* subscript, - AXPlatformNodeCocoa* superscript) { - AXPlatformNodeCocoa* nodes[2]; - NSString* keys[2]; - NSUInteger count = 0; +namespace { + +NSDictionary* CreateMathSubSupScriptsPair(AXPlatformNodeCocoa* subscript, + AXPlatformNodeCocoa* superscript) { + NSMutableDictionary* dictionary = [NSMutableDictionary dictionary]; if (subscript) { - nodes[count] = subscript; - keys[count] = NSAccessibilityMathSubscriptAttribute; - count++; + dictionary[NSAccessibilityMathSubscriptAttribute] = subscript; } if (superscript) { - nodes[count] = superscript; - keys[count] = NSAccessibilityMathSuperscriptAttribute; - count++; + dictionary[NSAccessibilityMathSuperscriptAttribute] = superscript; } - return [[NSDictionary alloc] initWithObjects:nodes forKeys:keys count:count]; + return dictionary; } +} // namespace + - (NSArray*)AXMathPostscripts { if (![self instanceActive] || _node->GetRole() != ax::mojom::Role::kMathMLMultiscripts) return nil; - NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* ret = [NSMutableArray array]; bool foundBaseElement = false; AXPlatformNodeCocoa* subscript = nullptr; for (AXPlatformNodeCocoa* child in [self AXChildren]) { @@ -2784,7 +2793,7 @@ continue; } AXPlatformNodeCocoa* superscript = child; - [ret addObject:createMathSubSupScriptsPair(subscript, superscript)]; + [ret addObject:CreateMathSubSupScriptsPair(subscript, superscript)]; subscript = nullptr; } return [ret count] ? ret : nil; @@ -2794,7 +2803,7 @@ if (![self instanceActive] || _node->GetRole() != ax::mojom::Role::kMathMLMultiscripts) return nil; - NSMutableArray* ret = [[[NSMutableArray alloc] init] autorelease]; + NSMutableArray* ret = [NSMutableArray array]; bool foundPrescriptDelimiter = false; AXPlatformNodeCocoa* subscript = nullptr; for (AXPlatformNodeCocoa* child in [self AXChildren]) { @@ -2808,7 +2817,7 @@ continue; } AXPlatformNodeCocoa* superscript = child; - [ret addObject:createMathSubSupScriptsPair(subscript, superscript)]; + [ret addObject:CreateMathSubSupScriptsPair(subscript, superscript)]; subscript = nullptr; } return [ret count] ? ret : nil;
diff --git a/ui/accessibility/platform/ax_platform_node_mac.h b/ui/accessibility/platform/ax_platform_node_mac.h index c6d2d13..563bcc94 100644 --- a/ui/accessibility/platform/ax_platform_node_mac.h +++ b/ui/accessibility/platform/ax_platform_node_mac.h
@@ -7,15 +7,17 @@ #import <Cocoa/Cocoa.h> +#include <memory> + #include "base/component_export.h" -#include "base/mac/scoped_nsobject.h" #include "ui/accessibility/platform/ax_platform_node_base.h" @class AXPlatformNodeCocoa; namespace ui { -class AXPlatformNodeMac : public AXPlatformNodeBase { +class COMPONENT_EXPORT(AX_PLATFORM) AXPlatformNodeMac + : public AXPlatformNodeBase { public: ~AXPlatformNodeMac() override; AXPlatformNodeMac(const AXPlatformNodeMac&) = delete; @@ -30,15 +32,9 @@ void Destroy() override; bool IsPlatformCheckable() const override; - AXPlatformNodeCocoa* GetNativeWrapper() const { return native_node_.get(); } - - base::scoped_nsobject<AXPlatformNodeCocoa> ReleaseNativeWrapper() { - return std::move(native_node_); - } - - void SetNativeWrapper(AXPlatformNodeCocoa* native_node) { - return native_node_.reset(native_node); - } + AXPlatformNodeCocoa* GetNativeWrapper() const; + AXPlatformNodeCocoa* ReleaseNativeWrapper(); + void SetNativeWrapper(AXPlatformNodeCocoa* native_node); protected: AXPlatformNodeMac(); @@ -48,10 +44,11 @@ PlatformAttributeList* attributes) override; private: - base::scoped_nsobject<AXPlatformNodeCocoa> native_node_; - friend AXPlatformNode* AXPlatformNode::Create( AXPlatformNodeDelegate* delegate); + + struct ObjCStorage; + std::unique_ptr<ObjCStorage> objc_storage_; }; // Convenience function to determine whether an internal object role should
diff --git a/ui/accessibility/platform/ax_platform_node_mac.mm b/ui/accessibility/platform/ax_platform_node_mac.mm index c95135e..5747307d 100644 --- a/ui/accessibility/platform/ax_platform_node_mac.mm +++ b/ui/accessibility/platform/ax_platform_node_mac.mm
@@ -7,6 +7,10 @@ #include "base/strings/sys_string_conversions.h" #include "ui/accessibility/platform/ax_platform_node_cocoa.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace { using RoleMap = std::map<ax::mojom::Role, NSString*>; @@ -59,15 +63,19 @@ return nullptr; } -AXPlatformNodeMac::AXPlatformNodeMac() = default; +struct AXPlatformNodeMac::ObjCStorage { + AXPlatformNodeCocoa* __strong native_node; +}; +AXPlatformNodeMac::AXPlatformNodeMac() + : objc_storage_(std::make_unique<ObjCStorage>()) {} AXPlatformNodeMac::~AXPlatformNodeMac() = default; void AXPlatformNodeMac::Destroy() { - if (native_node_) { - [native_node_ detach]; - // Also, nullify smart pointer to make accidental use-after-free impossible. - native_node_.reset(); + if (objc_storage_->native_node) { + [objc_storage_->native_node detach]; + // Also, clear the pointer to make accidental use-after-free impossible. + objc_storage_->native_node = nil; } AXPlatformNodeBase::Destroy(); } @@ -83,10 +91,26 @@ return AXPlatformNodeBase::IsPlatformCheckable(); } +AXPlatformNodeCocoa* AXPlatformNodeMac::GetNativeWrapper() const { + return objc_storage_->native_node; +} + +AXPlatformNodeCocoa* AXPlatformNodeMac::ReleaseNativeWrapper() { + AXPlatformNodeCocoa* native_node = objc_storage_->native_node; + objc_storage_->native_node = nil; + return native_node; +} + +void AXPlatformNodeMac::SetNativeWrapper(AXPlatformNodeCocoa* native_node) { + objc_storage_->native_node = native_node; +} + gfx::NativeViewAccessible AXPlatformNodeMac::GetNativeViewAccessible() { - if (!native_node_) - native_node_.reset([[AXPlatformNodeCocoa alloc] initWithNode:this]); - return native_node_.get(); + if (!objc_storage_->native_node) { + objc_storage_->native_node = + [[AXPlatformNodeCocoa alloc] initWithNode:this]; + } + return objc_storage_->native_node; } void AXPlatformNodeMac::NotifyAccessibilityEvent(ax::mojom::Event event_type) { @@ -98,8 +122,9 @@ // regular NSAccessibility notification system. if (event_type == ax::mojom::Event::kAlert || event_type == ax::mojom::Event::kLiveRegionChanged) { - if (auto announcement = [native_node_ announcementForEvent:event_type]) { - [native_node_ scheduleLiveRegionAnnouncement:std::move(announcement)]; + if (AXAnnouncementSpec* announcement = + [objc_storage_->native_node announcementForEvent:event_type]) { + [objc_storage_->native_node scheduleLiveRegionAnnouncement:announcement]; } return; } @@ -107,14 +132,14 @@ ax::mojom::Role role = GetRole(); if (ui::IsMenuItem(role)) { // On Mac, map menu item selection to a focus event. - NotifyMacEvent(native_node_, ax::mojom::Event::kFocus); + NotifyMacEvent(objc_storage_->native_node, ax::mojom::Event::kFocus); return; } else if (ui::IsListItem(role)) { if (const AXPlatformNodeBase* container = GetSelectionContainer()) { if (container->GetRole() == ax::mojom::Role::kListBox && !container->HasState(ax::mojom::State::kMultiselectable) && GetDelegate()->GetFocus() == GetNativeViewAccessible()) { - NotifyMacEvent(native_node_, ax::mojom::Event::kFocus); + NotifyMacEvent(objc_storage_->native_node, ax::mojom::Event::kFocus); return; } } @@ -123,12 +148,12 @@ // Otherwise, use mappings between ax::mojom::Event and NSAccessibility // notifications from the EventMap above. - NotifyMacEvent(native_node_, event_type); + NotifyMacEvent(objc_storage_->native_node, event_type); } void AXPlatformNodeMac::AnnounceText(const std::u16string& text) { PostAnnouncementNotification(base::SysUTF16ToNSString(text), - [native_node_ AXWindow], false); + [objc_storage_->native_node AXWindow], false); } bool IsNameExposedInAXValueForRole(ax::mojom::Role role) {
diff --git a/ui/accessibility/platform/ax_private_webkit_constants_mac.h b/ui/accessibility/platform/ax_private_webkit_constants_mac.h index dd96ad70..295b0967 100644 --- a/ui/accessibility/platform/ax_private_webkit_constants_mac.h +++ b/ui/accessibility/platform/ax_private_webkit_constants_mac.h
@@ -6,6 +6,7 @@ #define UI_ACCESSIBILITY_PLATFORM_AX_PRIVATE_WEBKIT_CONSTANTS_MAC_H_ #import <Cocoa/Cocoa.h> + #include "base/component_export.h" namespace ui {
diff --git a/ui/accessibility/platform/ax_private_webkit_constants_mac.mm b/ui/accessibility/platform/ax_private_webkit_constants_mac.mm index 0ca130e..2521cac 100644 --- a/ui/accessibility/platform/ax_private_webkit_constants_mac.mm +++ b/ui/accessibility/platform/ax_private_webkit_constants_mac.mm
@@ -4,6 +4,10 @@ #include "ui/accessibility/platform/ax_private_webkit_constants_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { const char* ToString(AXTextStateChangeType type) {
diff --git a/ui/accessibility/platform/ax_utils_mac.h b/ui/accessibility/platform/ax_utils_mac.h index e572c54..0b5c9df 100644 --- a/ui/accessibility/platform/ax_utils_mac.h +++ b/ui/accessibility/platform/ax_utils_mac.h
@@ -10,9 +10,9 @@ #include "base/component_export.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" -namespace ui { +@class AXPlatformNodeCocoa; -class AXPlatformNodeCocoa; +namespace ui { // An AXTextMarker is used by applications like Chrome to store a position in // the accessibility tree's text representation. It is a data structure whose @@ -48,7 +48,7 @@ // Returns the AXTextMarker representing the position within the given node. COMPONENT_EXPORT(AX_PLATFORM) -id AXTextMarkerFrom(const AXPlatformNodeCocoa* anchor, +id AXTextMarkerFrom(AXPlatformNodeCocoa* anchor, int offset, ax::mojom::TextAffinity affinity);
diff --git a/ui/accessibility/platform/ax_utils_mac.mm b/ui/accessibility/platform/ax_utils_mac.mm index 41acc06..b9f9b8b 100644 --- a/ui/accessibility/platform/ax_utils_mac.mm +++ b/ui/accessibility/platform/ax_utils_mac.mm
@@ -4,45 +4,51 @@ #include "ui/accessibility/platform/ax_utils_mac.h" +#include <CoreFoundation/CoreFoundation.h> +#include <Foundation/Foundation.h> + #include "base/mac/scoped_cftyperef.h" #include "ui/accessibility/ax_range.h" #include "ui/accessibility/platform/ax_platform_node_base.h" #include "ui/accessibility/platform/ax_platform_node_cocoa.h" #include "ui/accessibility/platform/ax_platform_node_delegate.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { bool IsAXTextMarker(id object) { - if (object == nil) + if (object == nil) { return false; - - AXTextMarkerRef cf_text_marker = static_cast<AXTextMarkerRef>(object); - DCHECK(cf_text_marker); - return CFGetTypeID(cf_text_marker) == AXTextMarkerGetTypeID(); + } + return CFGetTypeID((__bridge CFTypeRef)object) == AXTextMarkerGetTypeID(); } bool IsAXTextMarkerRange(id object) { - if (object == nil) + if (object == nil) { return false; - - AXTextMarkerRangeRef cf_marker_range = - static_cast<AXTextMarkerRangeRef>(object); - DCHECK(cf_marker_range); - return CFGetTypeID(cf_marker_range) == AXTextMarkerRangeGetTypeID(); + } + return CFGetTypeID((__bridge CFTypeRef)object) == + AXTextMarkerRangeGetTypeID(); } AXPlatformNodeDelegate::AXPosition AXTextMarkerToAXPosition(id text_marker) { - if (!IsAXTextMarker(text_marker)) + if (!IsAXTextMarker(text_marker)) { return AXNodePosition::CreateNullPosition(); + } - AXTextMarkerRef cf_text_marker = static_cast<AXTextMarkerRef>(text_marker); + AXTextMarkerRef cf_text_marker = (__bridge AXTextMarkerRef)text_marker; if (AXTextMarkerGetLength(cf_text_marker) != - sizeof(AXPlatformNodeDelegate::SerializedPosition)) + sizeof(AXPlatformNodeDelegate::SerializedPosition)) { return AXNodePosition::CreateNullPosition(); + } const UInt8* source_buffer = AXTextMarkerGetBytePtr(cf_text_marker); - if (!source_buffer) + if (!source_buffer) { return AXNodePosition::CreateNullPosition(); + } return AXNodePosition::Unserialize( *reinterpret_cast<const AXPlatformNodeDelegate::SerializedPosition*>( @@ -56,20 +62,21 @@ } AXTextMarkerRangeRef cf_marker_range = - static_cast<AXTextMarkerRangeRef>(text_marker_range); + (__bridge AXTextMarkerRangeRef)text_marker_range; - base::ScopedCFTypeRef<AXTextMarkerRef> start_marker( - AXTextMarkerRangeCopyStartMarker(cf_marker_range)); - base::ScopedCFTypeRef<AXTextMarkerRef> end_marker( - AXTextMarkerRangeCopyEndMarker(cf_marker_range)); - if (!start_marker.get() || !end_marker.get()) + id start_marker = + CFBridgingRelease(AXTextMarkerRangeCopyStartMarker(cf_marker_range)); + id end_marker = + CFBridgingRelease(AXTextMarkerRangeCopyEndMarker(cf_marker_range)); + if (!start_marker || !end_marker) { return AXPlatformNodeDelegate::AXRange(); + } // |AXPlatformNodeDelegate::AXRange| takes ownership of its anchor and focus. AXPlatformNodeDelegate::AXPosition anchor = - AXTextMarkerToAXPosition(static_cast<id>(start_marker.get())); + AXTextMarkerToAXPosition(start_marker); AXPlatformNodeDelegate::AXPosition focus = - AXTextMarkerToAXPosition(static_cast<id>(end_marker.get())); + AXTextMarkerToAXPosition(end_marker); return AXPlatformNodeDelegate::AXRange(std::move(anchor), std::move(focus)); } @@ -77,10 +84,9 @@ // AXTextMarkerCreate is a system function that makes a copy of the data // buffer given to it. AXPlatformNodeDelegate::SerializedPosition serialized = position->Serialize(); - AXTextMarkerRef cf_text_marker = AXTextMarkerCreate( + return CFBridgingRelease(AXTextMarkerCreate( kCFAllocatorDefault, reinterpret_cast<const UInt8*>(&serialized), - sizeof(AXPlatformNodeDelegate::SerializedPosition)); - return [static_cast<id>(cf_text_marker) autorelease]; + sizeof(AXPlatformNodeDelegate::SerializedPosition))); } id AXRangeToAXTextMarkerRange(AXPlatformNodeDelegate::AXRange range) { @@ -96,15 +102,14 @@ kCFAllocatorDefault, reinterpret_cast<const UInt8*>(&serialized_focus), sizeof(AXPlatformNodeDelegate::SerializedPosition))); - AXTextMarkerRangeRef cf_marker_range = - AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker); - return [static_cast<id>(cf_marker_range) autorelease]; + return CFBridgingRelease( + AXTextMarkerRangeCreate(kCFAllocatorDefault, start_marker, end_marker)); } -id AXTextMarkerFrom(const AXPlatformNodeCocoa* anchor, +id AXTextMarkerFrom(AXPlatformNodeCocoa* anchor, int offset, ax::mojom::TextAffinity affinity) { - AXPlatformNode* anchor_platform_node = [static_cast<id>(anchor) node]; + AXPlatformNode* anchor_platform_node = anchor.node; AXPlatformNodeDelegate* anchor_node = anchor_platform_node->GetDelegate(); AXPlatformNodeDelegate::AXPosition position = anchor_node->CreateTextPositionAt(offset, affinity); @@ -112,20 +117,19 @@ } id AXTextMarkerRangeFrom(id start_textmarker, id end_textmarker) { - AXTextMarkerRangeRef cf_marker_range = AXTextMarkerRangeCreate( - kCFAllocatorDefault, static_cast<AXTextMarkerRef>(start_textmarker), - static_cast<AXTextMarkerRef>(end_textmarker)); - return [static_cast<id>(cf_marker_range) autorelease]; + return CFBridgingRelease(AXTextMarkerRangeCreate( + kCFAllocatorDefault, (__bridge AXTextMarkerRef)start_textmarker, + (__bridge AXTextMarkerRef)end_textmarker)); } id AXTextMarkerRangeStart(id text_marker_range) { - return static_cast<id>(AXTextMarkerRangeCopyStartMarker( - static_cast<AXTextMarkerRangeRef>(text_marker_range))); + return CFBridgingRelease(AXTextMarkerRangeCopyStartMarker( + (__bridge AXTextMarkerRangeRef)text_marker_range)); } id AXTextMarkerRangeEnd(id text_marker_range) { - return static_cast<id>(AXTextMarkerRangeCopyEndMarker( - static_cast<AXTextMarkerRangeRef>(text_marker_range))); + return CFBridgingRelease(AXTextMarkerRangeCopyEndMarker( + (__bridge AXTextMarkerRangeRef)text_marker_range)); } } // namespace ui
diff --git a/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.h b/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.h index 2f3ec4f5..2c3ec04 100644 --- a/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.h +++ b/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.h
@@ -9,6 +9,10 @@ #include "base/memory/raw_ptr.h" #include "ui/accessibility/platform/inspect/ax_tree_indexer_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { class AXElementWrapper; @@ -107,7 +111,7 @@ gfx::NativeViewAccessible LineIndexToNode( const std::u16string line_index) const; - const id node; + id __strong node; // Map between AXUIElement objects and their DOMIds/accessible tree // line numbers. Owned by the caller and outlives this object.
diff --git a/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm b/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm index c0b0a5a..db66358 100644 --- a/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm +++ b/ui/accessibility/platform/inspect/ax_call_statement_invoker_mac.mm
@@ -12,6 +12,10 @@ #include "ui/accessibility/platform/inspect/ax_inspect_utils_mac.h" #include "ui/accessibility/platform/inspect/ax_property_node.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { // Template specialization of AXOptional<id>::ToString(). @@ -93,7 +97,7 @@ // Case 2: try to get target from the tree indexer. The target may refer to // an accessible element by DOM id or by a line number (:LINE_NUM format) in // a result accessible tree. The tree indexer keeps the mappings between - // accesible elements and their DOM ids and line numbers. + // accessible elements and their DOM ids and line numbers. if (!target) target = indexer_->NodeBy(property_node.name_or_value); @@ -165,7 +169,7 @@ } if (AXElementWrapper::IsValidElement(target)) - return InvokeForAXElement({target}, property_node); + return InvokeForAXElement(AXElementWrapper{target}, property_node); if (IsAXTextMarkerRange(target)) { return InvokeForAXTextMarkerRange(target, property_node); @@ -283,7 +287,7 @@ optional_arg_selector ? ax_element.Invoke<BOOL, SEL>(selector, *optional_arg_selector) : ax_element.Invoke<BOOL>(selector); - return AXOptionalNSObject([NSNumber numberWithBool:return_value]); + return AXOptionalNSObject(@(return_value)); } if (property_node.name_or_value == "setAccessibilityFocused")
diff --git a/ui/accessibility/platform/inspect/ax_element_wrapper_mac.h b/ui/accessibility/platform/inspect/ax_element_wrapper_mac.h index c803de0..59060eb 100644 --- a/ui/accessibility/platform/inspect/ax_element_wrapper_mac.h +++ b/ui/accessibility/platform/inspect/ax_element_wrapper_mac.h
@@ -13,12 +13,16 @@ #include "ui/accessibility/platform/inspect/ax_inspect.h" #include "ui/accessibility/platform/inspect/ax_optional.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { // Optional tri-state id object. using AXOptionalNSObject = AXOptional<id>; -// A wrapper around AXUIElement or NSAccessibilityElement object. +// A wrapper around either AXUIElement or NSAccessibilityElement object. class COMPONENT_EXPORT(AX_PLATFORM) AXElementWrapper final { public: // Returns true if the object is either NSAccessibilityElement or @@ -39,7 +43,7 @@ // BrowserAccessibilityCocoa). static std::string DOMIdOf(const id node); - AXElementWrapper(const id node) : node_(node) {} + explicit AXElementWrapper(const id node) : node_(node) {} // Returns true if the object is either an NSAccessibilityElement or // AXUIElement. @@ -150,7 +154,7 @@ // Converts the given value and the error object into AXOptional object. AXOptionalNSObject ToOptional(id, AXError, const std::string& message) const; - const id node_; + id __strong node_; }; } // namespace ui
diff --git a/ui/accessibility/platform/inspect/ax_element_wrapper_mac.mm b/ui/accessibility/platform/inspect/ax_element_wrapper_mac.mm index c95a42e0..1e6dbe4a 100644 --- a/ui/accessibility/platform/inspect/ax_element_wrapper_mac.mm +++ b/ui/accessibility/platform/inspect/ax_element_wrapper_mac.mm
@@ -4,16 +4,25 @@ #include "ui/accessibility/platform/inspect/ax_element_wrapper_mac.h" +#include <CoreFoundation/CoreFoundation.h> +#include <Foundation/Foundation.h> + #include <ostream> +#include "base/apple/bridging.h" #include "base/containers/fixed_flat_set.h" #include "base/debug/stack_trace.h" #include "base/functional/callback.h" #include "base/logging.h" +#include "base/mac/scoped_cftyperef.h" #include "base/strings/pattern.h" #include "base/strings/sys_string_conversions.h" #include "ui/accessibility/platform/ax_private_attributes_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + // error: 'accessibilityAttributeNames' is deprecated: first deprecated in // macOS 10.10 - Use the NSAccessibility protocol methods instead (see // NSAccessibilityProtocols.h @@ -22,8 +31,6 @@ namespace ui { -using base::SysNSStringToUTF8; - constexpr char kUnsupportedObject[] = "Only AXUIElementRef and BrowserAccessibilityCocoa are supported."; @@ -32,20 +39,24 @@ return AXElementWrapper(node).IsValidElement(); } +// static bool AXElementWrapper::IsNSAccessibilityElement(const id node) { return AXElementWrapper(node).IsNSAccessibilityElement(); } +// static bool AXElementWrapper::IsAXUIElement(const id node) { return AXElementWrapper(node).IsAXUIElement(); } +// static NSArray* AXElementWrapper::ChildrenOf(const id node) { return AXElementWrapper(node).Children(); } // Returns DOM id of a given node (either AXUIElement or // BrowserAccessibilityCocoa). +// static std::string AXElementWrapper::DOMIdOf(const id node) { return AXElementWrapper(node).DOMId(); } @@ -59,7 +70,7 @@ } bool AXElementWrapper::IsAXUIElement() const { - return CFGetTypeID(node_) == AXUIElementGetTypeID(); + return CFGetTypeID((__bridge CFTypeRef)node_) == AXUIElementGetTypeID(); } id AXElementWrapper::AsId() const { @@ -76,11 +87,13 @@ return [node_ children]; if (IsAXUIElement()) { - CFTypeRef children_ref; - if ((AXUIElementCopyAttributeValue(static_cast<AXUIElementRef>(node_), - kAXChildrenAttribute, &children_ref)) == - kAXErrorSuccess) - return static_cast<NSArray*>(children_ref); + base::ScopedCFTypeRef<CFTypeRef> children_ref; + if ((AXUIElementCopyAttributeValue( + (__bridge AXUIElementRef)node_, kAXChildrenAttribute, + children_ref.InitializeInto())) == kAXErrorSuccess) { + return base::apple::CFToNSOwnershipCast( + (CFArrayRef)children_ref.release()); + } return nil; } @@ -101,11 +114,11 @@ } id value = *GetAttributeValue(NSAccessibilitySizeAttribute); - if (value && CFGetTypeID(value) == AXValueGetTypeID()) { - AXValueType type = AXValueGetType(static_cast<AXValueRef>(value)); + if (value && CFGetTypeID((__bridge CFTypeRef)value) == AXValueGetTypeID()) { + AXValueType type = AXValueGetType((__bridge AXValueRef)value); if (type == kAXValueCGSizeType) { NSSize size; - if (AXValueGetValue(static_cast<AXValueRef>(value), type, &size)) { + if (AXValueGetValue((__bridge AXValueRef)value, type, &size)) { return size; } } @@ -118,35 +131,36 @@ return [node_ accessibilityFrame].origin; } - if (!IsAXUIElement()) { - NOTREACHED() - << "Only AXUIElementRef and BrowserAccessibilityCocoa are supported."; - return NSMakePoint(0, 0); - } - - id value = *GetAttributeValue(NSAccessibilityPositionAttribute); - if (value && CFGetTypeID(value) == AXValueGetTypeID()) { - AXValueType type = AXValueGetType(static_cast<AXValueRef>(value)); - if (type == kAXValueCGPointType) { - NSPoint point; - if (AXValueGetValue(static_cast<AXValueRef>(value), type, &point)) { - return point; + if (IsAXUIElement()) { + id value = *GetAttributeValue(NSAccessibilityPositionAttribute); + if (value && CFGetTypeID((__bridge CFTypeRef)value) == AXValueGetTypeID()) { + AXValueType type = AXValueGetType((__bridge AXValueRef)value); + if (type == kAXValueCGPointType) { + NSPoint point; + if (AXValueGetValue((__bridge AXValueRef)value, type, &point)) { + return point; + } } } } + + NOTREACHED() + << "Only AXUIElementRef and BrowserAccessibilityCocoa are supported."; return NSMakePoint(0, 0); } NSArray* AXElementWrapper::AttributeNames() const { - if (IsNSAccessibilityElement()) + if (IsNSAccessibilityElement()) { return [node_ accessibilityAttributeNames]; + } if (IsAXUIElement()) { - CFArrayRef attributes_ref; + base::ScopedCFTypeRef<CFArrayRef> attributes_ref; AXError result = AXUIElementCopyAttributeNames( - static_cast<AXUIElementRef>(node_), &attributes_ref); - if (AXSuccess(result, "AXAttributeNamesOf")) - return static_cast<NSArray*>(attributes_ref); + (__bridge AXUIElementRef)node_, attributes_ref.InitializeInto()); + if (AXSuccess(result, "AXAttributeNamesOf")) { + return base::apple::CFToNSOwnershipCast(attributes_ref.release()); + } return nil; } @@ -156,15 +170,17 @@ } NSArray* AXElementWrapper::ParameterizedAttributeNames() const { - if (IsNSAccessibilityElement()) + if (IsNSAccessibilityElement()) { return [node_ accessibilityParameterizedAttributeNames]; + } if (IsAXUIElement()) { - CFArrayRef attributes_ref; + base::ScopedCFTypeRef<CFArrayRef> attributes_ref; AXError result = AXUIElementCopyParameterizedAttributeNames( - static_cast<AXUIElementRef>(node_), &attributes_ref); - if (AXSuccess(result, "AXParameterizedAttributeNamesOf")) - return static_cast<NSArray*>(attributes_ref); + (__bridge AXUIElementRef)node_, attributes_ref.InitializeInto()); + if (AXSuccess(result, "AXParameterizedAttributeNamesOf")) { + return base::apple::CFToNSOwnershipCast(attributes_ref.release()); + } return nil; } @@ -175,16 +191,17 @@ AXOptionalNSObject AXElementWrapper::GetAttributeValue( NSString* attribute) const { - if (IsNSAccessibilityElement()) + if (IsNSAccessibilityElement()) { return AXOptionalNSObject([node_ accessibilityAttributeValue:attribute]); + } if (IsAXUIElement()) { - CFTypeRef value_ref; + base::ScopedCFTypeRef<CFTypeRef> value_ref; AXError result = AXUIElementCopyAttributeValue( - static_cast<AXUIElementRef>(node_), static_cast<CFStringRef>(attribute), - &value_ref); + (__bridge AXUIElementRef)node_, (__bridge CFStringRef)attribute, + value_ref.InitializeInto()); return ToOptional( - static_cast<id>(value_ref), result, + (__bridge id)value_ref.get(), result, "AXGetAttributeValue(" + base::SysNSStringToUTF8(attribute) + ")"); } @@ -199,22 +216,20 @@ forParameter:parameter]); if (IsAXUIElement()) { - // Convert NSValue parameter to CFTypeRef if needed. - CFTypeRef parameter_ref = static_cast<CFTypeRef>(parameter); + base::ScopedCFTypeRef<CFTypeRef> parameter_ref(CFBridgingRetain(parameter)); if ([parameter isKindOfClass:[NSValue class]] && - !strcmp([static_cast<NSValue*>(parameter) objCType], - @encode(NSRange))) { - NSRange range = [static_cast<NSValue*>(parameter) rangeValue]; - parameter_ref = AXValueCreate(kAXValueTypeCFRange, &range); + !strcmp([parameter objCType], @encode(NSRange))) { + NSRange range = [parameter rangeValue]; + parameter_ref.reset(AXValueCreate(kAXValueTypeCFRange, &range)); } // Get value. - CFTypeRef value_ref; + base::ScopedCFTypeRef<CFTypeRef> value_ref; AXError result = AXUIElementCopyParameterizedAttributeValue( - static_cast<AXUIElementRef>(node_), static_cast<CFStringRef>(attribute), - parameter_ref, &value_ref); + (__bridge AXUIElementRef)node_, (__bridge CFStringRef)attribute, + parameter_ref, value_ref.InitializeInto()); - return ToOptional(static_cast<id>(value_ref), result, + return ToOptional((__bridge id)value_ref.get(), result, "GetParameterizedAttributeValue(" + base::SysNSStringToUTF8(attribute) + ")"); } @@ -245,8 +260,11 @@ NSSelectorFromString(base::SysUTF8ToNSString(selector_string + ":")); NSString* argument = base::SysUTF8ToNSString(argument_string); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" if ([node_ respondsToSelector:selector]) return [node_ performSelector:selector withObject:argument]; +#pragma clang diagnostic pop return absl::nullopt; } @@ -257,9 +275,9 @@ } if (IsAXUIElement()) { - AXUIElementSetAttributeValue(static_cast<AXUIElementRef>(node_), - static_cast<CFStringRef>(attribute), - static_cast<CFTypeRef>(value)); + AXUIElementSetAttributeValue((__bridge AXUIElementRef)node_, + (__bridge CFStringRef)attribute, + (__bridge CFTypeRef)value); return; } @@ -272,10 +290,12 @@ return [node_ accessibilityActionNames]; if (IsAXUIElement()) { - CFArrayRef attributes_ref; - if ((AXUIElementCopyActionNames(static_cast<AXUIElementRef>(node_), - &attributes_ref)) == kAXErrorSuccess) - return static_cast<NSArray*>(attributes_ref); + base::ScopedCFTypeRef<CFArrayRef> attributes_ref; + if ((AXUIElementCopyActionNames((__bridge AXUIElementRef)node_, + attributes_ref.InitializeInto())) == + kAXErrorSuccess) { + return base::apple::CFToNSOwnershipCast(attributes_ref.release()); + } return nil; } @@ -291,8 +311,8 @@ } if (IsAXUIElement()) { - AXUIElementPerformAction(static_cast<AXUIElementRef>(node_), - static_cast<CFStringRef>(action)); + AXUIElementPerformAction((__bridge AXUIElementRef)node_, + (__bridge CFStringRef)action); return; }
diff --git a/ui/accessibility/platform/inspect/ax_event_recorder_mac.mm b/ui/accessibility/platform/inspect/ax_event_recorder_mac.mm index f20644c..95638f1d 100644 --- a/ui/accessibility/platform/inspect/ax_event_recorder_mac.mm +++ b/ui/accessibility/platform/inspect/ax_event_recorder_mac.mm
@@ -9,6 +9,7 @@ #include <algorithm> #include <string> +#include "base/apple/bridging.h" #include "base/logging.h" #include "base/mac/foundation_util.h" #include "base/mac/scoped_cftyperef.h" @@ -19,6 +20,10 @@ #include "ui/accessibility/platform/inspect/ax_inspect_utils_mac.h" #include "ui/accessibility/platform/inspect/ax_tree_formatter_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { // Callback function registered using AXObserverCreate. @@ -34,9 +39,9 @@ AXEventRecorderMac::AXEventRecorderMac(base::ProcessId pid, const AXTreeSelector& selector) : observer_run_loop_source_(nullptr) { - AXUIElementRef node = nil; + base::ScopedCFTypeRef<AXUIElementRef> node; if (pid) { - node = AXUIElementCreateApplication(pid); + node.reset(AXUIElementCreateApplication(pid)); if (!node) { LOG(FATAL) << "Failed to get AXUIElement for pid " << pid; } @@ -54,12 +59,12 @@ } // Get an AXUIElement for the Chrome application. - application_.reset(node); + application_ = std::move(node); if (!application_.get()) LOG(FATAL) << "Failed to create AXUIElement for application."; // Add the notifications we care about to the observer. - static NSArray* notifications = [@[ + static NSArray* notifications = @[ @"AXAutocorrectionOccurred", @"AXElementBusyChanged", @"AXExpandedChanged", @@ -103,7 +108,7 @@ NSAccessibilityWindowMiniaturizedNotification, NSAccessibilityWindowMovedNotification, NSAccessibilityWindowResizedNotification, - ] retain]; + ]; for (NSString* notification : notifications) { AddNotification(notification); @@ -122,7 +127,7 @@ void AXEventRecorderMac::AddNotification(NSString* notification) { AXObserverAddNotification(observer_ref_, application_, - base::mac::NSToCFCast(notification), this); + base::apple::NSToCFPtrCast(notification), this); } void AXEventRecorderMac::EventReceived(AXUIElementRef element, @@ -135,7 +140,7 @@ AXTreeFormatter::kFiltersDefaultSet); std::string element_str = - formatter.FormatTree(formatter.BuildNode(static_cast<id>(element))); + formatter.FormatTree(formatter.BuildNode((__bridge id)element)); // Element dumps contain a new line character at the end, remove it. if (!element_str.empty() && element_str.back() == '\n') { @@ -157,33 +162,27 @@ if (user_info == nil) return {}; - std::vector<std::string> serialized_info; - CFDictionaryApplyFunction( - user_info, - [](const void* raw_key, const void* raw_value, void* context) { - auto* key = static_cast<NSString*>(raw_key); - auto* value = static_cast<NSObject*>(raw_value); - auto* serialized_info = static_cast<std::vector<std::string>*>(context); - std::string value_string; - if ([key isEqual:NSAccessibilityTextStateChangeTypeKey]) { - value_string = ToString(static_cast<AXTextStateChangeType>( - [static_cast<NSNumber*>(value) intValue])); - } else if ([key isEqual:NSAccessibilityTextSelectionDirection]) { - value_string = ToString(static_cast<AXTextSelectionDirection>( - [static_cast<NSNumber*>(value) intValue])); - } else if ([key isEqual:NSAccessibilityTextSelectionGranularity]) { - value_string = ToString(static_cast<AXTextSelectionGranularity>( - [static_cast<NSNumber*>(value) intValue])); - } else if ([key isEqual:NSAccessibilityTextEditType]) { - value_string = ToString(static_cast<AXTextEditType>( - [static_cast<NSNumber*>(value) intValue])); - } else { - return; - } - serialized_info->push_back(base::SysNSStringToUTF8(key) + "=" + - value_string); - }, - &serialized_info); + __block std::vector<std::string> serialized_info; + [base::apple::CFToNSPtrCast(user_info) enumerateKeysAndObjectsUsingBlock:^( + id key, id value, BOOL* stop) { + std::string value_string; + if ([key isEqual:NSAccessibilityTextStateChangeTypeKey]) { + value_string = + ToString(static_cast<AXTextStateChangeType>([value intValue])); + } else if ([key isEqual:NSAccessibilityTextSelectionDirection]) { + value_string = + ToString(static_cast<AXTextSelectionDirection>([value intValue])); + } else if ([key isEqual:NSAccessibilityTextSelectionGranularity]) { + value_string = + ToString(static_cast<AXTextSelectionGranularity>([value intValue])); + } else if ([key isEqual:NSAccessibilityTextEditType]) { + value_string = ToString(static_cast<AXTextEditType>([value intValue])); + } else { + return; + } + serialized_info.push_back(base::SysNSStringToUTF8(key) + "=" + + value_string); + }]; // Always sort the info so that we don't depend on CFDictionary for // consistent output ordering.
diff --git a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h index eaa46518b..c5abbd3b 100644 --- a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h +++ b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.h
@@ -5,10 +5,11 @@ #ifndef UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_INSPECT_UTILS_MAC_H_ #define UI_ACCESSIBILITY_PLATFORM_INSPECT_AX_INSPECT_UTILS_MAC_H_ -#import <Cocoa/Cocoa.h> +#include <ApplicationServices/ApplicationServices.h> #include "base/component_export.h" #include "base/functional/callback_forward.h" +#include "base/mac/scoped_cftyperef.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "ui/accessibility/platform/inspect/ax_inspect.h" @@ -24,17 +25,20 @@ // Return AXElement in a tree by a given criteria. using AXFindCriteria = base::RepeatingCallback<bool(const AXUIElementRef)>; COMPONENT_EXPORT(AX_PLATFORM) -AXUIElementRef FindAXUIElement(const AXUIElementRef node, - const AXFindCriteria& criteria); +base::ScopedCFTypeRef<AXUIElementRef> FindAXUIElement( + const AXUIElementRef node, + const AXFindCriteria& criteria); // Returns AXUIElement and its application process id by a given tree selector. COMPONENT_EXPORT(AX_PLATFORM) -std::pair<AXUIElementRef, int> FindAXUIElement(const AXTreeSelector&); +std::pair<base::ScopedCFTypeRef<AXUIElementRef>, int> FindAXUIElement( + const AXTreeSelector&); // Returns AXUIElement for a window having title matching the given pattern. COMPONENT_EXPORT(AX_PLATFORM) -AXUIElementRef FindAXWindowChild(AXUIElementRef parent, - const std::string& pattern); +base::ScopedCFTypeRef<AXUIElementRef> FindAXWindowChild( + AXUIElementRef parent, + const std::string& pattern); } // namespace ui
diff --git a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm index 127f0b0..5b64e5eb 100644 --- a/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm +++ b/ui/accessibility/platform/inspect/ax_inspect_utils_mac.mm
@@ -4,17 +4,26 @@ #include "ui/accessibility/platform/inspect/ax_inspect_utils_mac.h" +#include <CoreGraphics/CoreGraphics.h> + #include <ostream> +#include "base/apple/bridging.h" #include "base/containers/fixed_flat_set.h" #include "base/debug/stack_trace.h" #include "base/functional/callback.h" #include "base/logging.h" +#include "base/mac/foundation_util.h" +#include "base/memory/scoped_policy.h" #include "base/strings/pattern.h" #include "base/strings/sys_string_conversions.h" #include "ui/accessibility/platform/ax_private_attributes_mac.h" #include "ui/accessibility/platform/inspect/ax_element_wrapper_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + // error: 'accessibilityAttributeNames' is deprecated: first deprecated in // macOS 10.10 - Use the NSAccessibility protocol methods instead (see // NSAccessibilityProtocols.h @@ -23,112 +32,106 @@ namespace ui { -using base::SysNSStringToUTF8; +namespace { const char kChromeTitle[] = "Google Chrome"; const char kChromiumTitle[] = "Chromium"; const char kFirefoxTitle[] = "Firefox"; const char kSafariTitle[] = "Safari"; -struct NSStringComparator { - bool operator()(NSString* lhs, NSString* rhs) const { - return [lhs compare:rhs] == NSOrderedAscending; - } -}; - -bool IsValidAXAttribute(const std::string& attribute) { - // static local to avoid a global static constructor. - static auto kValidAttributes = base::MakeFixedFlatSet<NSString*>( - {NSAccessibilityAccessKeyAttribute, - NSAccessibilityARIAAtomicAttribute, - NSAccessibilityARIABusyAttribute, - NSAccessibilityARIAColumnCountAttribute, - NSAccessibilityARIAColumnIndexAttribute, - NSAccessibilityARIACurrentAttribute, - NSAccessibilityARIALiveAttribute, - NSAccessibilityARIAPosInSetAttribute, - NSAccessibilityARIARelevantAttribute, - NSAccessibilityARIARowCountAttribute, - NSAccessibilityARIARowIndexAttribute, - NSAccessibilityARIASetSizeAttribute, - NSAccessibilityAutocompleteValueAttribute, - NSAccessibilityBlockQuoteLevelAttribute, - NSAccessibilityBrailleLabelAttribute, - NSAccessibilityBrailleRoleDescription, - NSAccessibilityChromeAXNodeIdAttribute, - NSAccessibilityColumnHeaderUIElementsAttribute, - NSAccessibilityDescriptionAttribute, - NSAccessibilityDetailsElementsAttribute, - NSAccessibilityDOMClassList, - NSAccessibilityDropEffectsAttribute, - NSAccessibilityElementBusyAttribute, - NSAccessibilityFocusableAncestorAttribute, - NSAccessibilityGrabbedAttribute, - NSAccessibilityHasPopupAttribute, - NSAccessibilityInvalidAttribute, - NSAccessibilityIsMultiSelectable, - NSAccessibilityKeyShortcutsValueAttribute, - NSAccessibilityLoadedAttribute, - NSAccessibilityLoadingProgressAttribute, - NSAccessibilityMathFractionNumeratorAttribute, - NSAccessibilityMathFractionDenominatorAttribute, - NSAccessibilityMathRootRadicandAttribute, - NSAccessibilityMathRootIndexAttribute, - NSAccessibilityMathBaseAttribute, - NSAccessibilityMathSubscriptAttribute, - NSAccessibilityMathSuperscriptAttribute, - NSAccessibilityMathUnderAttribute, - NSAccessibilityMathOverAttribute, - NSAccessibilityMathPostscriptsAttribute, - NSAccessibilityMathPrescriptsAttribute, - NSAccessibilityOwnsAttribute, - NSAccessibilityPopupValueAttribute, - NSAccessibilityRequiredAttribute, - NSAccessibilityRoleDescriptionAttribute, - NSAccessibilitySelectedAttribute, - NSAccessibilitySizeAttribute, - NSAccessibilityTitleAttribute, - NSAccessibilityTitleUIElementAttribute, - NSAccessibilityURLAttribute, - NSAccessibilityVisitedAttribute}, - NSStringComparator()); - - return kValidAttributes.contains(base::SysUTF8ToNSString(attribute)); -} - NSArray* AXChildrenOf(const id node) { return AXElementWrapper(node).Children(); } -std::string GetDOMId(const id node) { - return AXElementWrapper(node).DOMId(); +} // namespace + +bool IsValidAXAttribute(const std::string& attribute) { + static NSSet<NSString*>* valid_attributes = [NSSet setWithArray:@[ + NSAccessibilityAccessKeyAttribute, + NSAccessibilityARIAAtomicAttribute, + NSAccessibilityARIABusyAttribute, + NSAccessibilityARIAColumnCountAttribute, + NSAccessibilityARIAColumnIndexAttribute, + NSAccessibilityARIACurrentAttribute, + NSAccessibilityARIALiveAttribute, + NSAccessibilityARIAPosInSetAttribute, + NSAccessibilityARIARelevantAttribute, + NSAccessibilityARIARowCountAttribute, + NSAccessibilityARIARowIndexAttribute, + NSAccessibilityARIASetSizeAttribute, + NSAccessibilityAutocompleteValueAttribute, + NSAccessibilityBlockQuoteLevelAttribute, + NSAccessibilityBrailleLabelAttribute, + NSAccessibilityBrailleRoleDescription, + NSAccessibilityChromeAXNodeIdAttribute, + NSAccessibilityColumnHeaderUIElementsAttribute, + NSAccessibilityDescriptionAttribute, + NSAccessibilityDetailsElementsAttribute, + NSAccessibilityDOMClassList, + NSAccessibilityDropEffectsAttribute, + NSAccessibilityElementBusyAttribute, + NSAccessibilityFocusableAncestorAttribute, + NSAccessibilityGrabbedAttribute, + NSAccessibilityHasPopupAttribute, + NSAccessibilityInvalidAttribute, + NSAccessibilityIsMultiSelectable, + NSAccessibilityKeyShortcutsValueAttribute, + NSAccessibilityLoadedAttribute, + NSAccessibilityLoadingProgressAttribute, + NSAccessibilityMathFractionNumeratorAttribute, + NSAccessibilityMathFractionDenominatorAttribute, + NSAccessibilityMathRootRadicandAttribute, + NSAccessibilityMathRootIndexAttribute, + NSAccessibilityMathBaseAttribute, + NSAccessibilityMathSubscriptAttribute, + NSAccessibilityMathSuperscriptAttribute, + NSAccessibilityMathUnderAttribute, + NSAccessibilityMathOverAttribute, + NSAccessibilityMathPostscriptsAttribute, + NSAccessibilityMathPrescriptsAttribute, + NSAccessibilityOwnsAttribute, + NSAccessibilityPopupValueAttribute, + NSAccessibilityRequiredAttribute, + NSAccessibilityRoleDescriptionAttribute, + NSAccessibilitySelectedAttribute, + NSAccessibilitySizeAttribute, + NSAccessibilityTitleAttribute, + NSAccessibilityTitleUIElementAttribute, + NSAccessibilityURLAttribute, + NSAccessibilityVisitedAttribute, + ]]; + + return [valid_attributes containsObject:base::SysUTF8ToNSString(attribute)]; } -AXUIElementRef FindAXUIElement(const AXUIElementRef node, - const AXFindCriteria& criteria) { - if (criteria.Run(node)) - return node; +base::ScopedCFTypeRef<AXUIElementRef> FindAXUIElement( + const AXUIElementRef node, + const AXFindCriteria& criteria) { + if (criteria.Run(node)) { + return base::ScopedCFTypeRef<AXUIElementRef>(node, + base::scoped_policy::RETAIN); + } - NSArray* children = AXChildrenOf(static_cast<id>(node)); + NSArray* children = AXChildrenOf((__bridge id)node); for (id child in children) { - AXUIElementRef found = - FindAXUIElement(static_cast<AXUIElementRef>(child), criteria); - if (found != nil) + base::ScopedCFTypeRef<AXUIElementRef> found = + FindAXUIElement((__bridge AXUIElementRef)child, criteria); + if (found != nil) { return found; + } } - return nil; + return base::ScopedCFTypeRef<AXUIElementRef>(); } -std::pair<AXUIElementRef, int> FindAXUIElement(const AXTreeSelector& selector) { +std::pair<base::ScopedCFTypeRef<AXUIElementRef>, int> FindAXUIElement( + const AXTreeSelector& selector) { if (selector.widget) { - return {AXUIElementCreateApplication(selector.widget), selector.widget}; + return {base::ScopedCFTypeRef<AXUIElementRef>( + AXUIElementCreateApplication(selector.widget)), + selector.widget}; } - NSArray* windows = static_cast<NSArray*>(CGWindowListCopyWindowInfo( - kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, - kCGNullWindowID)); - std::string title; if (selector.types & AXTreeSelector::Chrome) title = kChromeTitle; @@ -139,32 +142,40 @@ else if (selector.types & AXTreeSelector::Safari) title = kSafariTitle; else - return {nil, 0}; + return {base::ScopedCFTypeRef<AXUIElementRef>(), 0}; + + NSArray* windows = + base::apple::CFToNSOwnershipCast(CGWindowListCopyWindowInfo( + kCGWindowListOptionOnScreenOnly | kCGWindowListExcludeDesktopElements, + kCGNullWindowID)); for (NSDictionary* window_info in windows) { - int pid = - [static_cast<NSNumber*>([window_info objectForKey:@"kCGWindowOwnerPID"]) - intValue]; - std::string window_name = SysNSStringToUTF8(static_cast<NSString*>( - [window_info objectForKey:@"kCGWindowOwnerName"])); + int pid = base::mac::ObjCCast<NSNumber>(window_info[@"kCGWindowOwnerPID"]) + .intValue; + std::string window_name = base::SysNSStringToUTF8( + base::mac::ObjCCast<NSString>(window_info[@"kCGWindowOwnerName"])); - AXUIElementRef node = nil; + base::ScopedCFTypeRef<AXUIElementRef> node; // Application pre-defined selectors match or application title exact match. - bool appTitleMatch = window_name == selector.pattern; - if (window_name == title || appTitleMatch) - node = AXUIElementCreateApplication(pid); + bool app_title_match = window_name == selector.pattern; + if (window_name == title || app_title_match) { + node.reset(AXUIElementCreateApplication(pid)); + } // Window title match. Application contain an AXWindow accessible object as // a first child, which accessible name contain a window title. For example: // 'Inbox (2) - asurkov@igalia.com - Gmail'. - if (!selector.pattern.empty() && !appTitleMatch) { - if (!node) - node = AXUIElementCreateApplication(pid); + if (!selector.pattern.empty() && !app_title_match) { + if (!node) { + node.reset(AXUIElementCreateApplication(pid)); + } - AXUIElementRef window = FindAXWindowChild(node, selector.pattern); - if (window) + base::ScopedCFTypeRef<AXUIElementRef> window = + FindAXWindowChild(node, selector.pattern); + if (window) { node = window; + } } // ActiveTab selector. @@ -173,10 +184,10 @@ node, base::BindRepeating([](const AXUIElementRef node) { // Only active tab in exposed in browsers, thus find first // AXWebArea role. - AXElementWrapper ax_node(static_cast<id>(node)); + AXElementWrapper ax_node((__bridge id)node); NSString* role = *ax_node.GetAttributeValue(NSAccessibilityRoleAttribute); - return SysNSStringToUTF8(role) == "AXWebArea"; + return base::SysNSStringToUTF8(role) == "AXWebArea"; })); } @@ -184,28 +195,33 @@ if (node) return {node, pid}; } - return {nil, 0}; + return {base::ScopedCFTypeRef<AXUIElementRef>(), 0}; } -AXUIElementRef FindAXWindowChild(AXUIElementRef parent, - const std::string& pattern) { - NSArray* children = AXChildrenOf(static_cast<id>(parent)); - if ([children count] == 0) - return nil; +base::ScopedCFTypeRef<AXUIElementRef> FindAXWindowChild( + AXUIElementRef parent, + const std::string& pattern) { + NSArray* children = AXChildrenOf((__bridge id)parent); + if (children.count == 0) { + return base::ScopedCFTypeRef<AXUIElementRef>(); + } - id window = [children objectAtIndex:0]; + id window = children.firstObject; AXElementWrapper ax_window(window); NSString* role = *ax_window.GetAttributeValue(NSAccessibilityRoleAttribute); - if (SysNSStringToUTF8(role) != "AXWindow") - return nil; + if (base::SysNSStringToUTF8(role) != "AXWindow") { + return base::ScopedCFTypeRef<AXUIElementRef>(); + } NSString* window_title = *ax_window.GetAttributeValue(NSAccessibilityTitleAttribute); - if (base::MatchPattern(SysNSStringToUTF8(window_title), pattern)) - return static_cast<AXUIElementRef>(window); + if (base::MatchPattern(base::SysNSStringToUTF8(window_title), pattern)) { + return base::ScopedCFTypeRef<AXUIElementRef>( + (__bridge AXUIElementRef)window, base::scoped_policy::RETAIN); + } - return nil; + return base::ScopedCFTypeRef<AXUIElementRef>(); } } // namespace ui
diff --git a/ui/accessibility/platform/inspect/ax_transform_mac.mm b/ui/accessibility/platform/inspect/ax_transform_mac.mm index 7bcf2ea..fa8915d 100644 --- a/ui/accessibility/platform/inspect/ax_transform_mac.mm +++ b/ui/accessibility/platform/inspect/ax_transform_mac.mm
@@ -4,6 +4,7 @@ #include "ui/accessibility/platform/inspect/ax_transform_mac.h" +#include "base/mac/foundation_util.h" #include "base/strings/sys_string_conversions.h" #include "ui/accessibility/ax_range.h" #include "ui/accessibility/platform/ax_platform_node.h" @@ -14,6 +15,10 @@ #include "ui/accessibility/platform/inspect/ax_element_wrapper_mac.h" #include "ui/accessibility/platform/inspect/ax_inspect_utils.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace ui { constexpr char kHeightDictKey[] = "h"; @@ -30,73 +35,75 @@ } // NSArray - if ([value isKindOfClass:[NSArray class]]) { - return base::Value(AXNSArrayToBaseValue((NSArray*)value, indexer)); + if (NSArray* array = base::mac::ObjCCast<NSArray>(value)) { + return base::Value(AXNSArrayToBaseValue(value, indexer)); } // AXCustomContent if (@available(macOS 11.0, *)) { - if ([value isKindOfClass:[AXCustomContent class]]) { - return base::Value(AXCustomContentToBaseValue((AXCustomContent*)value)); + if (AXCustomContent* custom_content = + base::mac::ObjCCast<AXCustomContent>(value)) { + return base::Value(AXCustomContentToBaseValue(custom_content)); } } // NSDictionary - if ([value isKindOfClass:[NSDictionary class]]) { - return base::Value( - AXNSDictionaryToBaseValue((NSDictionary*)value, indexer)); + if (NSDictionary* dictionary = base::mac::ObjCCast<NSDictionary>(value)) { + return base::Value(AXNSDictionaryToBaseValue(dictionary, indexer)); } // NSNumber - if ([value isKindOfClass:[NSNumber class]]) { - return base::Value([value intValue]); + if (NSNumber* number = base::mac::ObjCCast<NSNumber>(value)) { + return base::Value(number.intValue); } // NSRange, NSSize - if ([value isKindOfClass:[NSValue class]]) { - if (0 == strcmp([value objCType], @encode(NSRange))) { - return base::Value(AXNSRangeToBaseValue([value rangeValue])); + if (NSValue* ns_value = base::mac::ObjCCast<NSValue>(value)) { + if (0 == strcmp(ns_value.objCType, @encode(NSRange))) { + return base::Value(AXNSRangeToBaseValue(ns_value.rangeValue)); } - if (0 == strcmp([value objCType], @encode(NSSize))) { - return base::Value(AXNSSizeToBaseValue([value sizeValue])); + if (0 == strcmp(ns_value.objCType, @encode(NSSize))) { + return base::Value(AXNSSizeToBaseValue(ns_value.sizeValue)); } } // NSAttributedString - if ([value isKindOfClass:[NSAttributedString class]]) { - return NSAttributedStringToBaseValue((NSAttributedString*)value, indexer); + if (NSAttributedString* attr_string = + base::mac::ObjCCast<NSAttributedString>(value)) { + return NSAttributedStringToBaseValue(attr_string, indexer); } // CGColorRef - if (CFGetTypeID(value) == CGColorGetTypeID()) { - return base::Value(CGColorRefToBaseValue(static_cast<CGColorRef>(value))); + if (CFGetTypeID((__bridge CFTypeRef)value) == CGColorGetTypeID()) { + return base::Value(CGColorRefToBaseValue((__bridge CGColorRef)value)); } // AXValue - if (CFGetTypeID(value) == AXValueGetTypeID()) { - AXValueType type = AXValueGetType(static_cast<AXValueRef>(value)); + if (CFGetTypeID((__bridge CFTypeRef)value) == AXValueGetTypeID()) { + AXValueRef ax_value = (__bridge AXValueRef)value; + AXValueType type = AXValueGetType(ax_value); switch (type) { case kAXValueCGPointType: { NSPoint point; - if (AXValueGetValue(static_cast<AXValueRef>(value), type, &point)) { + if (AXValueGetValue(ax_value, type, &point)) { return base::Value(AXNSPointToBaseValue(point)); } } break; case kAXValueCGSizeType: { NSSize size; - if (AXValueGetValue(static_cast<AXValueRef>(value), type, &size)) { + if (AXValueGetValue(ax_value, type, &size)) { return base::Value(AXNSSizeToBaseValue(size)); } } break; case kAXValueCGRectType: { NSRect rect; - if (AXValueGetValue(static_cast<AXValueRef>(value), type, &rect)) { + if (AXValueGetValue(ax_value, type, &rect)) { return base::Value(AXNSRectToBaseValue(rect)); } } break; case kAXValueCFRangeType: { NSRange range; - if (AXValueGetValue(static_cast<AXValueRef>(value), type, &range)) { + if (AXValueGetValue(ax_value, type, &range)) { return base::Value(AXNSRangeToBaseValue(range)); } } break; @@ -111,8 +118,9 @@ } // AXTextMarkerRange - if (IsAXTextMarkerRange(value)) + if (IsAXTextMarkerRange(value)) { return AXTextMarkerRangeToBaseValue(value, indexer); + } // Accessible object if (AXElementWrapper::IsValidElement(value)) { @@ -131,23 +139,27 @@ base::Value AXPositionToBaseValue( const AXPlatformNodeDelegate::AXPosition& position, const AXTreeIndexerMac* indexer) { - if (position->IsNullPosition()) + if (position->IsNullPosition()) { return AXNilToBaseValue(); + } const AXPlatformTreeManager* manager = static_cast<AXPlatformTreeManager*>(position->GetManager()); - if (!manager) + if (!manager) { return AXNilToBaseValue(); + } AXPlatformNode* platform_node_anchor = manager->GetPlatformNodeFromTree(position->anchor_id()); - if (!platform_node_anchor) + if (!platform_node_anchor) { return AXNilToBaseValue(); + } AXPlatformNodeCocoa* cocoa_anchor = static_cast<AXPlatformNodeCocoa*>( platform_node_anchor->GetNativeViewAccessible()); - if (!cocoa_anchor) + if (!cocoa_anchor) { return AXNilToBaseValue(); + } std::string affinity; switch (position->affinity()) { @@ -162,13 +174,14 @@ break; } - base::Value::Dict value; - value.Set(AXMakeSetKey(AXMakeOrderedKey("anchor", 0)), - AXElementToBaseValue(static_cast<id>(cocoa_anchor), indexer)); - value.Set(AXMakeSetKey(AXMakeOrderedKey("offset", 1)), - position->text_offset()); - value.Set(AXMakeSetKey(AXMakeOrderedKey("affinity", 2)), - AXMakeConst(affinity)); + base::Value::Dict value = + base::Value::Dict() + .Set(AXMakeSetKey(AXMakeOrderedKey("anchor", 0)), + AXElementToBaseValue(static_cast<id>(cocoa_anchor), indexer)) + .Set(AXMakeSetKey(AXMakeOrderedKey("offset", 1)), + position->text_offset()) + .Set(AXMakeSetKey(AXMakeOrderedKey("affinity", 2)), + AXMakeConst(affinity)); return base::Value(std::move(value)); } @@ -181,13 +194,16 @@ const AXTreeIndexerMac* indexer) { AXPlatformNodeDelegate::AXRange ax_range = AXTextMarkerRangeToAXRange(text_marker_range); - if (ax_range.IsNull()) + if (ax_range.IsNull()) { return AXNilToBaseValue(); + } - base::Value::Dict value; - value.Set("anchor", - AXPositionToBaseValue(ax_range.anchor()->Clone(), indexer)); - value.Set("focus", AXPositionToBaseValue(ax_range.focus()->Clone(), indexer)); + base::Value::Dict value = + base::Value::Dict() + .Set("anchor", + AXPositionToBaseValue(ax_range.anchor()->Clone(), indexer)) + .Set("focus", + AXPositionToBaseValue(ax_range.focus()->Clone(), indexer)); return base::Value(std::move(value)); } @@ -196,7 +212,7 @@ __block base::Value::Dict result; [attr_string - enumerateAttributesInRange:NSMakeRange(0, [attr_string length]) + enumerateAttributesInRange:NSMakeRange(0, attr_string.length) options: NSAttributedStringEnumerationLongestEffectiveRangeNotRequired usingBlock:^(NSDictionary* attrs, NSRange nsRange, @@ -210,7 +226,7 @@ }]; result.Set(std::string(base::SysNSStringToUTF8( - [[attr_string string] + [attr_string.string substringWithRange:nsRange])), std::move(base_attrs)); }]; @@ -232,15 +248,17 @@ base::Value::List AXNSArrayToBaseValue(NSArray* node_array, const AXTreeIndexerMac* indexer) { base::Value::List list; - for (NSUInteger i = 0; i < [node_array count]; i++) - list.Append(AXNSObjectToBaseValue([node_array objectAtIndex:i], indexer)); + for (id item in node_array) { + list.Append(AXNSObjectToBaseValue(item, indexer)); + } return list; } base::Value::Dict AXCustomContentToBaseValue(AXCustomContent* content) { - base::Value::Dict value; - value.Set("label", base::SysNSStringToUTF16(content.label)); - value.Set("value", base::SysNSStringToUTF16(content.value)); + base::Value::Dict value = + base::Value::Dict() + .Set("label", base::SysNSStringToUTF16(content.label)) + .Set("value", base::SysNSStringToUTF16(content.value)); return value; } @@ -256,40 +274,41 @@ } base::Value::Dict AXNSPointToBaseValue(NSPoint point_value) { - base::Value::Dict point; - point.Set(kXCoordDictKey, static_cast<int>(point_value.x)); - point.Set(kYCoordDictKey, static_cast<int>(point_value.y)); + base::Value::Dict point = + base::Value::Dict() + .Set(kXCoordDictKey, static_cast<int>(point_value.x)) + .Set(kYCoordDictKey, static_cast<int>(point_value.y)); return point; } base::Value::Dict AXNSSizeToBaseValue(NSSize size_value) { - base::Value::Dict size; - size.Set(AXMakeOrderedKey(kWidthDictKey, 0), - static_cast<int>(size_value.width)); - size.Set(AXMakeOrderedKey(kHeightDictKey, 1), - static_cast<int>(size_value.height)); + base::Value::Dict size = base::Value::Dict() + .Set(AXMakeOrderedKey(kWidthDictKey, 0), + static_cast<int>(size_value.width)) + .Set(AXMakeOrderedKey(kHeightDictKey, 1), + static_cast<int>(size_value.height)); return size; } base::Value::Dict AXNSRectToBaseValue(NSRect rect_value) { - base::Value::Dict rect; - rect.Set(AXMakeOrderedKey(kXCoordDictKey, 0), - static_cast<int>(rect_value.origin.x)); - rect.Set(AXMakeOrderedKey(kYCoordDictKey, 1), - static_cast<int>(rect_value.origin.y)); - rect.Set(AXMakeOrderedKey(kWidthDictKey, 2), - static_cast<int>(rect_value.size.width)); - rect.Set(AXMakeOrderedKey(kHeightDictKey, 3), - static_cast<int>(rect_value.size.height)); + base::Value::Dict rect = base::Value::Dict() + .Set(AXMakeOrderedKey(kXCoordDictKey, 0), + static_cast<int>(rect_value.origin.x)) + .Set(AXMakeOrderedKey(kYCoordDictKey, 1), + static_cast<int>(rect_value.origin.y)) + .Set(AXMakeOrderedKey(kWidthDictKey, 2), + static_cast<int>(rect_value.size.width)) + .Set(AXMakeOrderedKey(kHeightDictKey, 3), + static_cast<int>(rect_value.size.height)); return rect; } base::Value::Dict AXNSRangeToBaseValue(NSRange node_range) { - base::Value::Dict range; - range.Set(AXMakeOrderedKey(kRangeLocDictKey, 0), - static_cast<int>(node_range.location)); - range.Set(AXMakeOrderedKey(kRangeLenDictKey, 1), - static_cast<int>(node_range.length)); + base::Value::Dict range = base::Value::Dict() + .Set(AXMakeOrderedKey(kRangeLocDictKey, 0), + static_cast<int>(node_range.location)) + .Set(AXMakeOrderedKey(kRangeLenDictKey, 1), + static_cast<int>(node_range.length)); return range; }
diff --git a/ui/accessibility/platform/inspect/ax_tree_formatter_mac.mm b/ui/accessibility/platform/inspect/ax_tree_formatter_mac.mm index d721c05..94fe665 100644 --- a/ui/accessibility/platform/inspect/ax_tree_formatter_mac.mm +++ b/ui/accessibility/platform/inspect/ax_tree_formatter_mac.mm
@@ -4,6 +4,8 @@ #include "ui/accessibility/platform/inspect/ax_tree_formatter_mac.h" +#include <string> + #include "base/files/file_path.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" @@ -19,16 +21,15 @@ #include "ui/accessibility/platform/inspect/ax_script_instruction.h" #include "ui/accessibility/platform/inspect/ax_transform_mac.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + // This file uses the deprecated NSObject accessibility interface. // TODO(crbug.com/948844): Migrate to the new NSAccessibility interface. #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" -using base::StringPrintf; -using base::SysNSStringToUTF8; -using base::SysNSStringToUTF16; -using std::string; - namespace ui { namespace { @@ -47,13 +48,13 @@ void AXTreeFormatterMac::AddDefaultFilters( std::vector<AXPropertyFilter>* property_filters) { - static NSArray* default_attributes = [@[ + static NSArray* default_attributes = @[ @"AXAutocompleteValue", @"AXDescription", @"AXRole", @"AXSubrole", @"AXTitle", @"AXTitleUIElement", @"AXValue" - ] retain]; + ]; for (NSString* attribute : default_attributes) { - AddPropertyFilter(property_filters, SysNSStringToUTF8(attribute)); + AddPropertyFilter(property_filters, base::SysNSStringToUTF8(attribute)); } if (show_ids()) { @@ -69,7 +70,7 @@ base::Value::Dict AXTreeFormatterMac::BuildTreeForSelector( const AXTreeSelector& selector) const { - AXUIElementRef node = nil; + base::ScopedCFTypeRef<AXUIElementRef> node; std::tie(node, std::ignore) = FindAXUIElement(selector); if (node == nil) { return base::Value::Dict(); @@ -79,7 +80,7 @@ base::Value::Dict AXTreeFormatterMac::BuildTreeForAXUIElement( AXUIElementRef node) const { - return BuildTree(static_cast<id>(node)); + return BuildTree((__bridge id)node); } base::Value::Dict AXTreeFormatterMac::BuildTree(const id root) const { @@ -101,13 +102,13 @@ std::string AXTreeFormatterMac::EvaluateScript( const AXTreeSelector& selector, const AXInspectScenario& scenario) const { - AXUIElementRef root = nil; + base::ScopedCFTypeRef<AXUIElementRef> root; std::tie(root, std::ignore) = FindAXUIElement(selector); if (!root) return ""; std::string result = - EvaluateScript(static_cast<id>(root), scenario.script_instructions, 0, + EvaluateScript((__bridge id)root.get(), scenario.script_instructions, 0, scenario.script_instructions.size()); return result; @@ -207,7 +208,8 @@ base::Value::List child_dict_list; for (id child in children) { base::Value::Dict child_dict; - RecursiveBuildTree({child}, root_rect, indexer, &child_dict); + RecursiveBuildTree(AXElementWrapper{child}, root_rect, indexer, + &child_dict); child_dict_list.Append(std::move(child_dict)); } dict->Set(kChildrenDictAttr, std::move(child_dict_list)); @@ -226,7 +228,7 @@ NSArray* attributes = ax_element.AttributeNames(); for (NSString* attribute : attributes) { dict->SetByDottedPath( - SysNSStringToUTF8(attribute), + base::SysNSStringToUTF8(attribute), AXNSObjectToBaseValue(*ax_element.GetAttributeValue(attribute), indexer)); } @@ -279,17 +281,19 @@ std::string line; // AXRole and AXSubrole have own formatting and should be listed upfront. - std::string role_attr = SysNSStringToUTF8(NSAccessibilityRoleAttribute); + std::string role_attr = base::SysNSStringToUTF8(NSAccessibilityRoleAttribute); const std::string* value = dict.FindString(role_attr); if (value) { WriteAttribute(true, *value, &line); } - std::string subrole_attr = SysNSStringToUTF8(NSAccessibilitySubroleAttribute); + std::string subrole_attr = + base::SysNSStringToUTF8(NSAccessibilitySubroleAttribute); value = dict.FindString(subrole_attr); if (value) { - WriteAttribute(false, - StringPrintf("%s=%s", subrole_attr.c_str(), value->c_str()), - &line); + WriteAttribute( + false, + base::StringPrintf("%s=%s", subrole_attr.c_str(), value->c_str()), + &line); } // Expose all other attributes. @@ -308,10 +312,10 @@ // Write formatted value. std::string formatted_value = AXFormatValue(item.second); - WriteAttribute( - false, - StringPrintf("%s=%s", item.first.c_str(), formatted_value.c_str()), - &line); + WriteAttribute(false, + base::StringPrintf("%s=%s", item.first.c_str(), + formatted_value.c_str()), + &line); } return line;
diff --git a/ui/accessibility/platform/inspect/ax_tree_indexer_mac.h b/ui/accessibility/platform/inspect/ax_tree_indexer_mac.h index ee04f566..47933d17 100644 --- a/ui/accessibility/platform/inspect/ax_tree_indexer_mac.h +++ b/ui/accessibility/platform/inspect/ax_tree_indexer_mac.h
@@ -10,14 +10,13 @@ namespace ui { -// // NSAccessibilityElement or AXUIElement accessible node comparator. struct AXNodeComparator { constexpr bool operator()(const gfx::NativeViewAccessible& lhs, const gfx::NativeViewAccessible& rhs) const { if (AXElementWrapper::IsAXUIElement(lhs)) { DCHECK(AXElementWrapper::IsAXUIElement(rhs)); - return CFHash(lhs) < CFHash(rhs); + return CFHash((__bridge CFTypeRef)lhs) < CFHash((__bridge CFTypeRef)rhs); } DCHECK(AXElementWrapper::IsNSAccessibilityElement(lhs)); DCHECK(AXElementWrapper::IsNSAccessibilityElement(rhs));
diff --git a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java index d28db9d..c8ecde7 100644 --- a/ui/android/java/src/org/chromium/ui/base/EventForwarder.java +++ b/ui/android/java/src/org/chromium/ui/base/EventForwarder.java
@@ -388,6 +388,14 @@ int eventAction = event.getActionMasked(); + // Ignore ACTION_HOVER_ENTER & ACTION_HOVER_EXIT because every mouse-down on Android + // follows a hover-exit and is followed by a hover-enter. https://crbug.com/715114 + // filed on distinguishing actual hover enter/exit from these bogus ones. + if (eventAction == MotionEvent.ACTION_HOVER_ENTER + || eventAction == MotionEvent.ACTION_HOVER_EXIT) { + return false; + } + // For mousedown and mouseup events, we use ACTION_BUTTON_PRESS // and ACTION_BUTTON_RELEASE respectively because they provide // info about the changed-button.
diff --git a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java index b0eadd8f..ad26e5a8 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -24,7 +24,6 @@ import android.view.View; import android.view.Window; import android.view.WindowManager; -import android.view.accessibility.AccessibilityManager; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; @@ -38,7 +37,6 @@ import org.chromium.base.Log; import org.chromium.base.ObserverList; import org.chromium.base.PackageManagerUtils; -import org.chromium.base.StrictModeContext; import org.chromium.base.UnownedUserDataHost; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -78,29 +76,6 @@ private KeyboardVisibilityDelegate mKeyboardVisibilityDelegate = KeyboardVisibilityDelegate.getInstance(); - private class TouchExplorationMonitor { - // Listener that tells us when touch exploration is enabled or disabled. - private AccessibilityManager.TouchExplorationStateChangeListener mTouchExplorationListener; - - TouchExplorationMonitor() { - mTouchExplorationListener = - new AccessibilityManager.TouchExplorationStateChangeListener() { - @Override - public void onTouchExplorationStateChanged(boolean enabled) { - mIsTouchExplorationEnabled = - mAccessibilityManager.isTouchExplorationEnabled(); - refreshWillNotDraw(); - } - }; - mAccessibilityManager.addTouchExplorationStateChangeListener(mTouchExplorationListener); - } - - void destroy() { - mAccessibilityManager.removeTouchExplorationStateChangeListener( - mTouchExplorationListener); - } - } - // Native pointer to the c++ WindowAndroid object. private long mNativeWindowAndroid; private final DisplayAndroid mDisplayAndroid; @@ -120,19 +95,10 @@ private HashSet<Animator> mAnimationsOverContent = new HashSet<>(); private View mAnimationPlaceholderView; - // System accessibility service. - private final AccessibilityManager mAccessibilityManager; - /** A mechanism for observing and updating the application window's bottom inset. */ private ApplicationViewportInsetSupplier mApplicationBottomInsetSupplier = new ApplicationViewportInsetSupplier(); - // Whether touch exploration is enabled. - private boolean mIsTouchExplorationEnabled; - - // A class that monitors the touch exploration state. - private TouchExplorationMonitor mTouchExplorationMonitor; - private AndroidPermissionDelegate mPermissionDelegate; // Note that this state lives in Java, rather than in the native BeginFrameSource because @@ -242,12 +208,6 @@ // Multiple refresh rate support is only available on M+. recomputeSupportedRefreshRates(); - // Temporary solution for flaky tests, see https://crbug.com/767624 for context - try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) { - mAccessibilityManager = - (AccessibilityManager) ContextUtils.getApplicationContext().getSystemService( - Context.ACCESSIBILITY_SERVICE); - } // Configuration.isDisplayServerWideColorGamut must be queried from the window's context. // Because of crbug.com/756180, many devices report true for isScreenWideColorGamut in // 8.0.0, even when they don't actually support wide color gamut. @@ -677,9 +637,6 @@ } mUnownedUserDataHost.destroy(); - - if (mTouchExplorationMonitor != null) mTouchExplorationMonitor.destroy(); - mApplicationBottomInsetSupplier.destroy(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S_V2) { @@ -749,12 +706,6 @@ */ public void setAnimationPlaceholderView(View view) { mAnimationPlaceholderView = view; - - // The accessibility focus ring also gets clipped by the SurfaceView 'hole', so - // make sure the animation placeholder view is in place if touch exploration is on. - mIsTouchExplorationEnabled = mAccessibilityManager.isTouchExplorationEnabled(); - refreshWillNotDraw(); - mTouchExplorationMonitor = new TouchExplorationMonitor(); } /** @@ -824,7 +775,9 @@ animation.start(); // When the first animation starts, make the placeholder 'draw' itself. - refreshWillNotDraw(); + if (mAnimationPlaceholderView.willNotDraw()) { + mAnimationPlaceholderView.setWillNotDraw(false); + } // When the last animation ends, remove the placeholder view, // returning to the default optimized state. @@ -833,7 +786,9 @@ public void onAnimationEnd(Animator animation) { animation.removeListener(this); mAnimationsOverContent.remove(animation); - refreshWillNotDraw(); + if (mAnimationsOverContent.isEmpty()) { + mAnimationPlaceholderView.setWillNotDraw(true); + } } }); } @@ -860,19 +815,6 @@ } /** - * Update whether the placeholder is 'drawn' based on whether an animation is running - * or touch exploration is enabled - if either of those are true, we call - * setWillNotDraw(false) to ensure that the animation is drawn over the SurfaceView, - * and otherwise we call setWillNotDraw(true). - */ - private void refreshWillNotDraw() { - boolean willNotDraw = !mIsTouchExplorationEnabled && mAnimationsOverContent.isEmpty(); - if (mAnimationPlaceholderView.willNotDraw() != willNotDraw) { - mAnimationPlaceholderView.setWillNotDraw(willNotDraw); - } - } - - /** * As long as there are still animations which haven't ended, this will return false. * @return True if all known animations have ended. */
diff --git a/ui/android/java/src/org/chromium/ui/widget/ToastManager.java b/ui/android/java/src/org/chromium/ui/widget/ToastManager.java index 0513cdb1..ca26ef8e 100644 --- a/ui/android/java/src/org/chromium/ui/widget/ToastManager.java +++ b/ui/android/java/src/org/chromium/ui/widget/ToastManager.java
@@ -52,7 +52,7 @@ private Toast mToast; static boolean isEnabled() { - if (Boolean.FALSE.equals(sIsEnabled) || !LibraryLoader.getInstance().isInitialized()) { + if (Boolean.FALSE.equals(sIsEnabled) || !LibraryLoader.getInstance().isLoaded()) { return false; } if (sIsEnabled == null) {
diff --git a/ui/base/ime/PRESUBMIT.py b/ui/base/ime/PRESUBMIT.py index 8984ddf..12b19a7 100644 --- a/ui/base/ime/PRESUBMIT.py +++ b/ui/base/ime/PRESUBMIT.py
@@ -11,8 +11,6 @@ import filecmp import os -USE_PYTHON3 = True - CHARACTER_COMPOSER_DATA_SOURCES=['character_composer_sequences.txt'] CHARACTER_COMPOSER_DATA_HEADER='character_composer_data.h' CHARACTER_COMPOSER_DATA_GENERATOR='generate_character_composer_data.py'
diff --git a/ui/base/ime/ash/PRESUBMIT.py b/ui/base/ime/ash/PRESUBMIT.py index 4926919..f15d972 100644 --- a/ui/base/ime/ash/PRESUBMIT.py +++ b/ui/base/ime/ash/PRESUBMIT.py
@@ -3,7 +3,6 @@ # found in the LICENSE file. PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True def CheckTastIsRequested(input_api, output_api): """Checks that the user did add the tast trybot to the description
diff --git a/ui/chromeos/styles/PRESUBMIT.py b/ui/chromeos/styles/PRESUBMIT.py index a109ed79..94eb5896 100644 --- a/ui/chromeos/styles/PRESUBMIT.py +++ b/ui/chromeos/styles/PRESUBMIT.py
@@ -3,7 +3,6 @@ # found in the LICENSE file. PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True TEST_PATTERNS = [r'.+_test.py$'] # Regex patterns which identify all source json5 files we currently use in @@ -38,9 +37,7 @@ input_api, output_api, '.', - files_to_check=TEST_PATTERNS, - run_on_python2=False, - skip_shebang_check=True) + files_to_check=TEST_PATTERNS) finally: sys.path = old_sys_path return results
diff --git a/ui/chromeos/styles/cros_sys_colors.json5 b/ui/chromeos/styles/cros_sys_colors.json5 index 51b9246..a5c3bb69 100644 --- a/ui/chromeos/styles/cros_sys_colors.json5 +++ b/ui/chromeos/styles/cros_sys_colors.json5
@@ -549,6 +549,22 @@ generate_per_mode: true, }, + /* + * Some GM2 assets are "elevated" meaning they have slightly different + * colors to improve contrast on their elevated surfaces in dark mode. + * Updating these assets to GM3 poses a issue as they need to render with + * elevated colors when the kJelly flag is OFF but with sys illo tokens when + * the jelly flag is ON. To support this we map sys illo references for + * assets on elevated surfaces to the following elevated sys token set. + * These colors are identical to their non elevated counterparts when the + * jelly flag is ON but when the flag is off they get remapped to the + * correct GM2 eleavted token. + */ + 'illo.elevated.color1.1': '$cros.sys.illo.color1.1', + 'illo.elevated.color1.2': '$cros.sys.illo.color1.2', + 'illo.elevated.base': '$cros.sys.illo.base', + 'illo.elevated.secondary': '$cros.sys.illo.secondary', + /* Icon colors. */ 'file-ms-excel': '#16a765', 'file-ms-word': '#4986e7',
diff --git a/ui/color/PRESUBMIT.py b/ui/color/PRESUBMIT.py index 01bf33e..330ff4d0 100644 --- a/ui/color/PRESUBMIT.py +++ b/ui/color/PRESUBMIT.py
@@ -8,8 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True - INCLUDE_CPP_FILES_ONLY = ( r'.*\.(cc|h)$', )
diff --git a/ui/file_manager/PRESUBMIT.py b/ui/file_manager/PRESUBMIT.py index 2706421..44b3e66 100644 --- a/ui/file_manager/PRESUBMIT.py +++ b/ui/file_manager/PRESUBMIT.py
@@ -2,7 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' TEST_PATTERNS = [r'.+_test.py$'] @@ -20,9 +19,7 @@ input_api, output_api, 'base', - files_to_check=TEST_PATTERNS, - run_on_python2=False, - skip_shebang_check=True) + files_to_check=TEST_PATTERNS) def ChecksCommon(input_api, output_api):
diff --git a/ui/file_manager/base/gn/PRESUBMIT.py b/ui/file_manager/base/gn/PRESUBMIT.py index dc57b4d..914340289 100644 --- a/ui/file_manager/base/gn/PRESUBMIT.py +++ b/ui/file_manager/base/gn/PRESUBMIT.py
@@ -9,7 +9,6 @@ import sys -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0'
diff --git a/ui/file_manager/file_manager/background/js/volume_info_impl.js b/ui/file_manager/file_manager/background/js/volume_info_impl.js index 398174c..a064c010 100644 --- a/ui/file_manager/file_manager/background/js/volume_info_impl.js +++ b/ui/file_manager/file_manager/background/js/volume_info_impl.js
@@ -5,7 +5,7 @@ import {assert} from 'chrome://resources/ash/common/assert.js'; import {FakeEntryImpl} from '../../common/js/files_app_entry_types.js'; -import {str} from '../../common/js/util.js'; +import {str, util} from '../../common/js/util.js'; import {VolumeManagerCommon} from '../../common/js/volume_manager_types.js'; import {FakeEntry, FilesAppEntry} from '../../externs/files_app_entry_interfaces.js'; import {VolumeInfo} from '../../externs/volume_info.js'; @@ -79,10 +79,12 @@ this.fakeEntries_ = {}; if (volumeType === VolumeManagerCommon.VolumeType.DRIVE) { - this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_OFFLINE] = - new FakeEntryImpl( - str('DRIVE_OFFLINE_COLLECTION_LABEL'), - VolumeManagerCommon.RootType.DRIVE_OFFLINE); + if (!util.isDriveFsBulkPinningEnabled()) { + this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_OFFLINE] = + new FakeEntryImpl( + str('DRIVE_OFFLINE_COLLECTION_LABEL'), + VolumeManagerCommon.RootType.DRIVE_OFFLINE); + } this.fakeEntries_[VolumeManagerCommon.RootType.DRIVE_SHARED_WITH_ME] = new FakeEntryImpl(
diff --git a/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css b/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css index 0f6724e..6deccea 100644 --- a/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css +++ b/ui/file_manager/file_manager/foreground/css/file_manager_gm3.css
@@ -753,13 +753,13 @@ } .dialog-header.files-ng cr-toggle { - --cr-toggle-checked-bar-color: var(--cros-sys-primary); + --cr-toggle-checked-bar-color: var(--cros-sys-primary_container); /* bar color above already defines the opacity, so use 100% here */ --cr-toggle-checked-bar-opacity: 100%; - --cr-toggle-checked-button-color: var(--cros-sys-on_primary); + --cr-toggle-checked-button-color: var(--cros-sys-primary); --cr-toggle-checked-ripple-color: transparent; --cr-toggle-unchecked-bar-color: var(--cros-sys-secondary); - --cr-toggle-unchecked-button-color: var(--cros-sys-on_secondary); + --cr-toggle-unchecked-button-color: var(--cros-sys-surface_variant); --cr-toggle-unchecked-ripple-color: transparent; --cr-toggle-box-shadow: var(--cros-elevation-1-shadow); --cr-toggle-ripple-diameter: 32px; @@ -932,7 +932,7 @@ html.focus-outline-visible .dialog-footer div.select > div.options:not(:hover) option.selected::after { border: 2px solid var(--cros-sys-focus_ring); - border-radius: 4px; + border-radius: 8px; content: ''; height: 32px; /* option height - 2 x border width */ left: 0; @@ -1731,7 +1731,6 @@ -webkit-mask-size: 16px 16px; background-color: currentColor; height: 24px; - margin-inline-end: 14px; margin-inline-start: auto; padding-inline-start: 8px; width: 24px; @@ -2031,11 +2030,14 @@ .table-row-cell > .dateholder { display: flex; + margin-inline-end: 14px; } .table-row-cell > .dateholder > .date { flex: 1 1; overflow: hidden; + text-overflow: ellipsis; + white-space: pre; } .table-row-cell > .dateholder > .dlp-managed-icon {
diff --git a/ui/file_manager/file_manager/foreground/css/menu_gm3.css b/ui/file_manager/file_manager/foreground/css/menu_gm3.css index dd4ad2d..2d20d676 100644 --- a/ui/file_manager/file_manager/foreground/css/menu_gm3.css +++ b/ui/file_manager/file_manager/foreground/css/menu_gm3.css
@@ -155,7 +155,7 @@ html.focus-outline-visible cr-menu.files-menu > cr-menu-item:not([disabled])[selected]::before { border: 2px solid var(--cros-sys-focus_ring); - border-radius: 4px; + border-radius: 8px; content: ''; height: 100%; left: 0;
diff --git a/ui/file_manager/file_manager/foreground/images/files/ui/cloud_done.svg b/ui/file_manager/file_manager/foreground/images/files/ui/cloud_done.svg index 8411584..c33f796 100644 --- a/ui/file_manager/file_manager/foreground/images/files/ui/cloud_done.svg +++ b/ui/file_manager/file_manager/foreground/images/files/ui/cloud_done.svg
@@ -1 +1 @@ -<svg id="cloud_done" width="12" height="12" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip)"><path d="M6 1a5 5 0 110 10A5 5 0 016 1zm0-1a6 6 0 100 12A6 6 0 006 0z" fill="var(--xf-icon-base-color, #fff)"/><path d="M6 11A5 5 0 106 1a5 5 0 000 10z" fill="#00885E"/><path d="M5.269 7.93a.58.58 0 01-.42-.18l-1.2-1.2a.6.6 0 01.84-.85l.78.78 2.24-2.23a.594.594 0 11.84.84l-2.65 2.66a.61.61 0 01-.43.18z" fill="#FEFBFF"/></g><defs><clipPath id="clip"><path fill="#fff" d="M0 0h12v12H0z"/></clipPath></defs></svg> +<svg id="cloud_done" width="12" height="12" fill="none" xmlns="http://www.w3.org/2000/svg"><g clip-path="url(#clip)"><path d="M6 1a5 5 0 110 10A5 5 0 016 1zm0-1a6 6 0 100 12A6 6 0 006 0z" fill="var(--xf-icon-base-color, #fff)"/><path d="M6 11A5 5 0 106 1a5 5 0 000 10z" fill="var(--xf-icon-positive-color, #00885E)"/><path d="M5.269 7.93a.58.58 0 01-.42-.18l-1.2-1.2a.6.6 0 01.84-.85l.78.78 2.24-2.23a.594.594 0 11.84.84l-2.65 2.66a.61.61 0 01-.43.18z" fill="#FEFBFF"/></g><defs><clipPath id="clip"><path fill="#fff" d="M0 0h12v12H0z"/></clipPath></defs></svg>
diff --git a/ui/file_manager/file_manager/foreground/js/directory_contents.js b/ui/file_manager/file_manager/foreground/js/directory_contents.js index 7aae923..a8f0694 100644 --- a/ui/file_manager/file_manager/foreground/js/directory_contents.js +++ b/ui/file_manager/file_manager/foreground/js/directory_contents.js
@@ -398,14 +398,29 @@ */ makeReadEntriesRecursivelyPromise_( folder, modifiedTimestamp, category, maxResults) { + // A promise that resolves to an entry if it is modified after cutoffDate or + // null, otherwise. Used to filter entries by modified time. If we fail to + // get metadata for an entry we return it without comparison, to be on the + // safe side. + const newDateFilterPromise = (entry, cutoffDate) => new Promise(resolve => { + entry.getMetadata( + (metadata) => { + resolve(metadata.modificationTime > cutoffDate ? entry : null); + }, + () => { + resolve(entry); + }); + }); return new Promise((resolve, reject) => { + metrics.startInterval('Search.DocumentsProvider.Latency'); const collectedEntries = []; + let workLeft = 1; util.readEntriesRecursively( folder, + // More entries found callback. (entries) => { const filtered = entries.filter(entry => { - const name = entry.name.toLowerCase(); - if (name.indexOf(this.query_) < 0) { + if (entry.name.toLowerCase().indexOf(this.query_) < 0) { return false; } if (category !== chrome.fileManagerPrivate.FileCategory.ALL) { @@ -418,19 +433,38 @@ if (modifiedTimestamp === 0) { collectedEntries.push(...filtered); } else { - filtered.map(entry => { - entry.getMetadata(metadata => { - if (metadata.modificationTime.getTime() > modifiedTimestamp) { - collectedEntries.push(entry); - } - }); - }); + workLeft += filtered.length; + const cutoff = new Date(modifiedTimestamp); + Promise + .all(filtered.map( + entry => newDateFilterPromise(entry, cutoff))) + .then((modified) => { + collectedEntries.push(...modified.filter(e => e !== null)); + workLeft -= modified.length; + if (workLeft <= 0) { + metrics.recordInterval( + 'Search.DocumentsProvider.Latency'); + resolve(collectedEntries); + } + }); } }, + // All entries read callback. () => { - resolve(collectedEntries); + if (--workLeft <= 0) { + metrics.recordInterval('Search.DocumentsProvider.Latency'); + resolve(collectedEntries); + } }, - reject, + // Error callback. + () => { + if (!this.cancelled_ && collectedEntries.length >= maxResults) { + resolve(collectedEntries); + } else { + reject(); + } + }, + // Should stop callback. () => { return collectedEntries.length >= maxResults || this.cancelled_; });
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js index ddbecdc8..c23b2d32 100644 --- a/ui/file_manager/file_manager/foreground/js/file_manager.js +++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -756,28 +756,32 @@ } /** - * Retrieve the bulk pinning progress and populate the store. Then subscribe - * to any future updates to ensure the store is kept up to date. + * Subscribes to bulk-pinning events to ensure the store is kept up to date. + * Also tries to retrieve a first bulk pinning progress to populate the store. + * Does nothing if bulk-pinning is disabled. * @private */ async initBulkPinning_() { if (!util.isDriveFsBulkPinningEnabled()) { return; } - let progress = null; - try { - progress = await getBulkPinProgress(); - } catch (e) { - console.error('Failed to get bulk pin progress:', e); - return; - } - if (!progress) { - return; - } - this.store_.dispatch(updateBulkPinProgress(progress)); + + const promise = getBulkPinProgress(); + chrome.fileManagerPrivate.onBulkPinProgress.addListener((progress) => { + console.debug('Got bulk-pinning event:', progress); this.store_.dispatch(updateBulkPinProgress(progress)); }); + + try { + const progress = await promise; + if (progress) { + console.debug('Got initial bulk-pinning state:', progress); + this.store_.dispatch(updateBulkPinProgress(progress)); + } + } catch (e) { + console.error('Cannot get initial bulk-pinning state:', e); + } } /**
diff --git a/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts b/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts index 66586153a..921894c 100644 --- a/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts +++ b/ui/file_manager/file_manager/widgets/xf_breadcrumb.ts
@@ -570,7 +570,7 @@ :host-context(.focus-outline-visible) #elider-menu button:focus::after { border: 2px solid var(--cros-sys-focus_ring); - border-radius: 4px; + border-radius: 8px; content: ''; height: 32px; /* option height - 2 x border width */ left: 0;
diff --git a/ui/file_manager/file_manager/widgets/xf_cloud_panel.ts b/ui/file_manager/file_manager/widgets/xf_cloud_panel.ts index 05fa172..1881643 100644 --- a/ui/file_manager/file_manager/widgets/xf_cloud_panel.ts +++ b/ui/file_manager/file_manager/widgets/xf_cloud_panel.ts
@@ -173,6 +173,7 @@ return html`<cr-action-menu> <div class="body"> <div class="static progress" id="progress-preparing"> + <files-spinner></files-spinner> ${str('DRIVE_PREPARING_TO_SYNC')} </div> <div id="progress-state"> @@ -319,10 +320,17 @@ } #progress-preparing { - align-self: start; + flex-direction: row; padding-bottom: 20px; } + #progress-preparing files-spinner { + height: 20px; + margin: 0; + margin-inline-end: 8px; + width: 20px; + } + progress::-webkit-progress-bar { background-color: var(--cros-sys-highlight_shape); border-radius: 10px;
diff --git a/ui/file_manager/file_manager/widgets/xf_icon.ts b/ui/file_manager/file_manager/widgets/xf_icon.ts index 2b0d0a0..f7bf728 100644 --- a/ui/file_manager/file_manager/widgets/xf_icon.ts +++ b/ui/file_manager/file_manager/widgets/xf_icon.ts
@@ -113,6 +113,7 @@ :host { --xf-icon-color: var(--cros-sys-on_surface); --xf-icon-base-color: var(--cros-sys-app_base); + --xf-icon-positive-color: var(--cros-sys-positive); display: inline-block; }
diff --git a/ui/file_manager/file_manager/widgets/xf_select.ts b/ui/file_manager/file_manager/widgets/xf_select.ts index 813ed05a..1cddf7b 100644 --- a/ui/file_manager/file_manager/widgets/xf_select.ts +++ b/ui/file_manager/file_manager/widgets/xf_select.ts
@@ -167,8 +167,8 @@ const alignment = this.menuAlignment || 'center'; return html`<cr-action-menu> ${this.options.map((option, index) => { - const checked = this.selectedOption_!.value === option.value; - return html` + const checked = this.selectedOption_!.value === option.value; + return html` <cr-button class="dropdown-item dropdown-item-${alignment}" role="menuitemcheckbox" @@ -180,7 +180,7 @@ <div class='dropdown-filler'></div> <div slot='suffix-icon' class='selected-icon'></div> </cr-button>`; - })} + })} </cr-action-menu>`; } @@ -482,7 +482,7 @@ :host-context(.focus-outline-visible) cr-action-menu cr-button:focus::after { border: 2px solid var(--cros-sys-focus_ring); - border-radius: 4px; + border-radius: 8px; content: ''; height: 32px; /* option height - 2 x border width */ left: 0;
diff --git a/ui/file_manager/integration_tests/file_manager/search.js b/ui/file_manager/integration_tests/file_manager/search.js index 835c94e..9079aa4 100644 --- a/ui/file_manager/integration_tests/file_manager/search.js +++ b/ui/file_manager/integration_tests/file_manager/search.js
@@ -1027,14 +1027,17 @@ * files exposed via Documents Provider. */ testcase.searchDocumentsProviderWithRecencyOptions = async () => { - const recentHello = ENTRIES.hello.cloneWith({ - nameText: 'hello-recent.txt', - lastModifiedTime: getDateWithDayDiff(3), - targetPath: 'hello-recent.txt', - }); + const recentHellos = []; + for (let i = 0; i < 10; ++i) { + recentHellos.push(ENTRIES.hello.cloneWith({ + nameText: `hello-recent-${i}.txt`, + lastModifiedTime: getDateWithDayDiff(4 - (i % 3)), + targetPath: `hello-recent-${i}.txt`, + })); + } await addEntries( ['documents_provider'], - COMPLEX_DOCUMENTS_PROVIDER_ENTRY_SET.concat([recentHello])); + COMPLEX_DOCUMENTS_PROVIDER_ENTRY_SET.concat(recentHellos)); const appId = await setupAndWaitUntilReady(RootPath.DOWNLOADS); @@ -1046,18 +1049,17 @@ // Search the DocumentsProvider for files with "hello" in their name. await remoteCall.typeSearchText(appId, 'hello'); - await remoteCall.waitForFiles(appId, TestEntryInfo.getExpectedRows([ - ENTRIES.hello, - recentHello, - ])); + // Expect the original hello and recent hello files to be present. + await remoteCall.waitForFiles( + appId, + TestEntryInfo.getExpectedRows(recentHellos.concat([ENTRIES.hello]))); // Click the fourth button, which is "Last week" option. chrome.test.assertTrue( !!await remoteCall.selectSearchOption(appId, 'recency', 4), 'Failed to click "Last week" recency selector'); - // Expect only the recent hello file to be found. - await remoteCall.waitForFiles(appId, TestEntryInfo.getExpectedRows([ - recentHello, - ])); + // Expect all rececent hello files to be present. + await remoteCall.waitForFiles( + appId, TestEntryInfo.getExpectedRows(recentHellos)); };
diff --git a/ui/gfx/PRESUBMIT.py b/ui/gfx/PRESUBMIT.py index 724d23d..3c650e4 100644 --- a/ui/gfx/PRESUBMIT.py +++ b/ui/gfx/PRESUBMIT.py
@@ -10,8 +10,6 @@ PRESUBMIT_VERSION = '2.0.0' -USE_PYTHON3 = True - def CheckChange(input_api, output_api): import sys old_sys_path = sys.path[:]
diff --git a/ui/gl/dc_layer_tree.cc b/ui/gl/dc_layer_tree.cc index ee74435e..bbdf7bd68 100644 --- a/ui/gl/dc_layer_tree.cc +++ b/ui/gl/dc_layer_tree.cc
@@ -454,8 +454,10 @@ visual_subtrees_[i]->container_visual(), FALSE, nullptr); } - dc_layer_tree_->AddDelegatedInkVisualToTreeIfNeeded( - root_surface_visual.Get()); + if (root_surface_visual) { + dc_layer_tree_->AddDelegatedInkVisualToTreeIfNeeded( + root_surface_visual.Get()); + } needs_commit = true; }
diff --git a/ui/linux/linux_ui_factory.cc b/ui/linux/linux_ui_factory.cc index 0f29a8b..5555ff3 100644 --- a/ui/linux/linux_ui_factory.cc +++ b/ui/linux/linux_ui_factory.cc
@@ -127,7 +127,7 @@ } // namespace -BASE_FEATURE(kAllowQt, "AllowQt", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kAllowQt, "AllowQt", base::FEATURE_ENABLED_BY_DEFAULT); LinuxUi* GetDefaultLinuxUi() { auto* linux_ui = GetDefaultLinuxUiAndTheme();
diff --git a/ui/ozone/platform/wayland/host/wayland_cursor.cc b/ui/ozone/platform/wayland/host/wayland_cursor.cc index 13e3dde4..d323113 100644 --- a/ui/ozone/platform/wayland/host/wayland_cursor.cc +++ b/ui/ozone/platform/wayland/host/wayland_cursor.cc
@@ -153,14 +153,15 @@ } DCHECK(pointer_); - wl_pointer_set_cursor(pointer_->wl_object(), pointer_enter_serial->value, - pointer_surface_.get(), hotspot_x_dip, hotspot_y_dip); wl_surface_damage(pointer_surface_.get(), 0, 0, buffer_width, buffer_height); // Note: should the offset be non-zero, use wl_surface_offset() to set it. wl_surface_attach(pointer_surface_.get(), buffer, 0, 0); wl_surface_commit(pointer_surface_.get()); + wl_pointer_set_cursor(pointer_->wl_object(), pointer_enter_serial->value, + pointer_surface_.get(), hotspot_x_dip, hotspot_y_dip); + connection_->Flush(); }
diff --git a/ui/resources/PRESUBMIT.py b/ui/resources/PRESUBMIT.py index e19c694..0ba2745 100644 --- a/ui/resources/PRESUBMIT.py +++ b/ui/resources/PRESUBMIT.py
@@ -10,9 +10,6 @@ for the rules we're checking against here. """ -USE_PYTHON3 = True - - def CheckChangeOnUpload(input_api, output_api): return _CommonChecks(input_api, output_api)
diff --git a/ui/views/BUILD.gn b/ui/views/BUILD.gn index be0ebe3..416497c 100644 --- a/ui/views/BUILD.gn +++ b/ui/views/BUILD.gn
@@ -1169,6 +1169,22 @@ } } +if (is_mac) { + # TODO(https://crbug.com/1280317): Merge back into views_unittests once all + # .mm files are ARCed. + source_set("views_unittests_arc") { + testonly = true + sources = [ "widget/ax_native_widget_mac_unittest.mm" ] + configs += [ "//build/config/compiler:enable_arc" ] + deps = [ + ":views", + "//testing/gtest", + "//ui/accessibility", + "//ui/views:test_support", + ] + } +} + test("views_unittests") { use_xvfb = use_xvfb_in_this_config @@ -1406,7 +1422,6 @@ "controls/native/native_view_host_mac_unittest.mm", "controls/tabbed_pane/tabbed_pane_accessibility_mac_unittest.mm", "view_unittest_mac.mm", - "widget/ax_native_widget_mac_unittest.mm", "widget/native_widget_mac_unittest.mm", "widget/sublevel_manager_mac_unittest.mm", ] @@ -1415,6 +1430,7 @@ sources -= [ "controls/native/native_view_host_unittest.cc" ] public_deps = [ + ":views_unittests_arc", "//components/remote_cocoa/app_shim", "//ui/accelerated_widget_mac", ]
diff --git a/ui/views/PRESUBMIT.py b/ui/views/PRESUBMIT.py index ab86ae50..59b52f4 100644 --- a/ui/views/PRESUBMIT.py +++ b/ui/views/PRESUBMIT.py
@@ -8,7 +8,6 @@ for more details about the presubmit API built into depot_tools. """ -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' INCLUDE_CPP_FILES_ONLY = (
diff --git a/ui/views/bubble/bubble_dialog_delegate_view.cc b/ui/views/bubble/bubble_dialog_delegate_view.cc index 33b13a8..19a7ff06 100644 --- a/ui/views/bubble/bubble_dialog_delegate_view.cc +++ b/ui/views/bubble/bubble_dialog_delegate_view.cc
@@ -108,12 +108,20 @@ return anchor ? anchor->GetNativeTheme() : Widget::GetNativeTheme(); } + using Widget::GetPrimaryWindowWidget; + Widget* GetPrimaryWindowWidget() override { Widget* const anchor = GetAnchorWidget(); return anchor ? anchor->GetPrimaryWindowWidget() : Widget::GetPrimaryWindowWidget(); } + const ui::ColorProvider* GetColorProvider() const override { + const Widget* const primary = GetPrimaryWindowWidget(); + return (primary && primary != this) ? primary->GetColorProvider() + : Widget::GetColorProvider(); + } + private: const Widget* GetAnchorWidget() const { // TODO(pbos): Could this use Widget::parent() instead of anchor_widget()?
diff --git a/ui/views/controls/button/toggle_button.cc b/ui/views/controls/button/toggle_button.cc index c403fbb2f..d6289c5 100644 --- a/ui/views/controls/button/toggle_button.cc +++ b/ui/views/controls/button/toggle_button.cc
@@ -369,6 +369,10 @@ return accepts_events_; } +int ToggleButton::GetVisualHorizontalMargin() const { + return kTrackHorizontalMargin - kThumbInset; +} + void ToggleButton::AddLayerToRegion(ui::Layer* layer, views::LayerRegion region) { // Ink-drop layers should go above/below the ThumbView.
diff --git a/ui/views/controls/button/toggle_button.h b/ui/views/controls/button/toggle_button.h index 04f4d6e..caf1432 100644 --- a/ui/views/controls/button/toggle_button.h +++ b/ui/views/controls/button/toggle_button.h
@@ -52,6 +52,10 @@ void SetAcceptsEvents(bool accepts_events); bool GetAcceptsEvents() const; + // Gets the horizontal margin between the rounded edge of the thumb and the + // edge of the view. + int GetVisualHorizontalMargin() const; + // views::View: void AddLayerToRegion(ui::Layer* layer, LayerRegion region) override; void RemoveLayerFromRegions(ui::Layer* layer) override;
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 0b1b6174..c7a50f5 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -1134,9 +1134,12 @@ MenuItemView* menu_item = GetMenuItemAt(source, event.location()); bool over_empty_menu = false; if (!menu_item) { - // See if we're over an empty menu. + // See if we're over an empty menu. `GetMenuItemAt` fails in this case + // because it uses `GetEventHandlerForPoint`, which requires an enabled + // `View`, while `EmptyMenuMenuItem`s are disabled. + // `GetTooltipHandlerForPoint` does not have this restriction. menu_item = AsViewClass<EmptyMenuMenuItem>( - source->GetEventHandlerForPoint(event.location())); + source->GetTooltipHandlerForPoint(event.location())); if (menu_item) over_empty_menu = true; }
diff --git a/ui/views/controls/textfield/textfield_unittest.cc b/ui/views/controls/textfield/textfield_unittest.cc index 6e8e7ba4..4e6595f 100644 --- a/ui/views/controls/textfield/textfield_unittest.cc +++ b/ui/views/controls/textfield/textfield_unittest.cc
@@ -3819,6 +3819,8 @@ EXPECT_LT(test_api_->GetDisplayOffsetX(), 0); } +// TODO(b/271058426): Rewrite these long press drag selection tests using +// ui::test::EventGenerator. TEST_F(TextfieldTest, LongPressDragLTR_Forward) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures( @@ -3957,74 +3959,46 @@ EXPECT_EQ(range, gfx::Range(13, 0)); } -TEST_F(TextfieldTest, DoubleTapDown) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - /*enabled_features=*/{::features::kTouchTextEditingRedesign}, - /*disabled_features=*/{}); - +TEST_F(TextfieldTest, DoubleTapSelection) { InitTextfield(); textfield_->SetText(u"Hello string world"); + + // Perform a double tap. + const gfx::Point kTapPoint = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(2), GetCursorYForTesting()}); + event_generator_->GestureTapAt(kTapPoint); + event_generator_->GestureTapAt(kTapPoint); + + // Check that nearest word is selected and that touch selection has been + // activated. gfx::Range range; - - // Second tap down in a repeated tap sequence should select word but not show - // touch selection handles. - ui::GestureEventDetails tap_down_details(ui::ET_GESTURE_TAP_DOWN); - tap_down_details.set_tap_down_count(2); - ui::GestureEvent tap_down = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), tap_down_details); - textfield_->OnGestureEvent(&tap_down); textfield_->GetEditableSelectionRange(&range); EXPECT_EQ(range, gfx::Range(0, 5)); - EXPECT_FALSE(test_api_->touch_selection_controller()); - - // After tap, word should still be selected and touch selection handles should - // appear. - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP); - tap_details.set_tap_count(2); - ui::GestureEvent tap = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), tap_details); - textfield_->OnGestureEvent(&tap); - textfield_->GetEditableSelectionRange(&range); - EXPECT_EQ(range, gfx::Range(0, 5)); + EXPECT_EQ(textfield_->GetSelectedText(), u"Hello"); EXPECT_TRUE(test_api_->touch_selection_controller()); } -TEST_F(TextfieldTest, TripleTapDown) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - /*enabled_features=*/{::features::kTouchTextEditingRedesign}, - /*disabled_features=*/{}); - +TEST_F(TextfieldTest, TripleTapSelection) { InitTextfield(); textfield_->SetText(u"Hello string world"); + + // Perform a triple tap. + const gfx::Point kTapPoint = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(2), GetCursorYForTesting()}); + event_generator_->GestureTapAt(kTapPoint); + event_generator_->GestureTapAt(kTapPoint); + event_generator_->GestureTapAt(kTapPoint); + + // Check that all text is selected and that touch selection has been + // activated. gfx::Range range; - - // Third tap down in a repeated tap sequence should select all text. - ui::GestureEventDetails tap_down_details(ui::ET_GESTURE_TAP_DOWN); - tap_down_details.set_tap_down_count(3); - ui::GestureEvent tap_down = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), tap_down_details); - textfield_->OnGestureEvent(&tap_down); textfield_->GetEditableSelectionRange(&range); EXPECT_EQ(range, gfx::Range(0, 18)); - EXPECT_FALSE(test_api_->touch_selection_controller()); - - // After tap, text should still be selected and touch selection handles should - // appear. - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP); - tap_details.set_tap_count(3); - ui::GestureEvent tap = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), tap_details); - textfield_->OnGestureEvent(&tap); - textfield_->GetEditableSelectionRange(&range); - EXPECT_EQ(range, gfx::Range(0, 18)); + EXPECT_EQ(textfield_->GetSelectedText(), u"Hello string world"); EXPECT_TRUE(test_api_->touch_selection_controller()); } -// TODO(b/271058426): Rewrite these gesture tests using -// ui::test::EventGenerator. -TEST_F(TextfieldTest, DoubleTapDrag) { +TEST_F(TextfieldTest, DoublePressDragSelection) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures( /*enabled_features=*/{::features::kTouchTextEditingRedesign}, @@ -4032,30 +4006,23 @@ InitTextfield(); textfield_->SetText(u"Hello string world"); + + // Perform a double press and drag movement. + const gfx::Point kDragStart = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(2), GetCursorYForTesting()}); + const gfx::Point kDragEnd = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(10), GetCursorYForTesting()}); + event_generator_->GestureTapAt(kDragStart); + event_generator_->GestureScrollSequence(kDragStart, kDragEnd, + /*duration=*/base::Milliseconds(50), + /*steps=*/5); + + // Check that text is selected between the word boundaries around the start + // and end of the drag movement. gfx::Range range; - - // Second tap down in a repeated tap sequence should select word. - ui::GestureEventDetails tap_down_details(ui::ET_GESTURE_TAP_DOWN); - tap_down_details.set_tap_down_count(2); - ui::GestureEvent tap_down = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), tap_down_details); - textfield_->OnGestureEvent(&tap_down); - textfield_->GetEditableSelectionRange(&range); - EXPECT_EQ(range, gfx::Range(0, 5)); - - // Dragging should expand the selection. - ui::GestureEvent scroll_begin = CreateTestGestureEvent( - GetCursorPositionX(2), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_BEGIN, 1, 0)); - textfield_->OnGestureEvent(&scroll_begin); - EXPECT_EQ(range, gfx::Range(0, 5)); - - ui::GestureEvent scroll_update = CreateTestGestureEvent( - GetCursorPositionX(10), GetCursorYForTesting(), - ui::GestureEventDetails(ui::ET_GESTURE_SCROLL_UPDATE)); - textfield_->OnGestureEvent(&scroll_update); textfield_->GetEditableSelectionRange(&range); EXPECT_EQ(range, gfx::Range(0, 12)); + EXPECT_EQ(textfield_->GetSelectedText(), u"Hello string"); } #endif @@ -4181,38 +4148,9 @@ } #endif // BUILDFLAG(IS_CHROMEOS_ASH) -class TextfieldTouchSelectionTest : public TextfieldTest { - protected: - // Simulates a complete tap. - void Tap(const gfx::Point& point) { - ui::GestureEvent begin = CreateTestGestureEvent( - point.x(), point.y(), ui::GestureEventDetails(ui::ET_GESTURE_BEGIN)); - textfield_->OnGestureEvent(&begin); - - ui::GestureEvent tap_down = CreateTestGestureEvent( - point.x(), point.y(), ui::GestureEventDetails(ui::ET_GESTURE_TAP_DOWN)); - textfield_->OnGestureEvent(&tap_down); - - ui::GestureEvent show_press = CreateTestGestureEvent( - point.x(), point.y(), - ui::GestureEventDetails(ui::ET_GESTURE_SHOW_PRESS)); - textfield_->OnGestureEvent(&show_press); - - ui::GestureEventDetails tap_details(ui::ET_GESTURE_TAP); - tap_details.set_tap_count(1); - ui::GestureEvent tap = - CreateTestGestureEvent(point.x(), point.y(), tap_details); - textfield_->OnGestureEvent(&tap); - - ui::GestureEvent end = CreateTestGestureEvent( - point.x(), point.y(), ui::GestureEventDetails(ui::ET_GESTURE_END)); - textfield_->OnGestureEvent(&end); - } -}; - // Touch selection and dragging currently only works for chromeos. #if BUILDFLAG(IS_CHROMEOS_ASH) -TEST_F(TextfieldTouchSelectionTest, TouchSelectionAndDraggingTest) { +TEST_F(TextfieldTest, TouchSelectionAndDraggingTest) { InitTextfield(); textfield_->SetText(u"hello world"); EXPECT_FALSE(test_api_->touch_selection_controller()); @@ -4263,66 +4201,67 @@ } #endif -TEST_F(TextfieldTouchSelectionTest, TouchSelectionInUnfocusableTextfield) { +// No touch on desktop Mac. Tracked in http://crbug.com/445520. +#if !BUILDFLAG(IS_MAC) +TEST_F(TextfieldTest, TapOnSelection) { InitTextfield(); textfield_->SetText(u"hello world"); - gfx::Point touch_point(GetCursorPositionX(2), 0); + + // Select a range and check that touch selection handles are not present and + // that the correct range is selected. + constexpr gfx::Range kSelectionRange(2, 7); + textfield_->SetEditableSelectionRange(kSelectionRange); + gfx::Range range; + textfield_->GetEditableSelectionRange(&range); + EXPECT_FALSE(test_api_->touch_selection_controller()); + EXPECT_EQ(range, kSelectionRange); + + // Tap on the selection and check that touch selection handles are shown, but + // the selection range is not modified. + constexpr gfx::Range kTapRange(5, 5); + const gfx::Rect kTapRect = + GetCursorBounds(gfx::SelectionModel(kTapRange, gfx::CURSOR_FORWARD)); + const gfx::Point kTapPoint = + views::View::ConvertPointToScreen(textfield_, kTapRect.CenterPoint()); + event_generator_->GestureTapAt(kTapPoint); + textfield_->GetEditableSelectionRange(&range); + EXPECT_TRUE(test_api_->touch_selection_controller()); + EXPECT_EQ(range, kSelectionRange); + + // Tap again on the selection and check that touch selection handles are still + // present and that the selection is changed to a cursor at the tap location. + // We advance the clock before tapping again to avoid the tap being treated as + // a double tap. + event_generator_->AdvanceClock(base::Milliseconds(1000)); + event_generator_->GestureTapAt(kTapPoint); + textfield_->GetEditableSelectionRange(&range); + EXPECT_TRUE(test_api_->touch_selection_controller()); + EXPECT_EQ(range, kTapRange); +} + +TEST_F(TextfieldTest, TouchSelectionInUnfocusableTextfield) { + InitTextfield(); + textfield_->SetText(u"hello world"); // Disable textfield and tap on it. Touch text selection should not get // activated. textfield_->SetEnabled(false); - Tap(touch_point); + const gfx::Point kTapPoint = views::View::ConvertPointToScreen( + textfield_, {GetCursorPositionX(2), GetCursorYForTesting()}); + event_generator_->GestureTapAt(kTapPoint); EXPECT_FALSE(test_api_->touch_selection_controller()); textfield_->SetEnabled(true); // Make textfield unfocusable and tap on it. Touch text selection should not // get activated. textfield_->SetFocusBehavior(View::FocusBehavior::NEVER); - Tap(touch_point); + event_generator_->GestureTapAt(kTapPoint); EXPECT_FALSE(textfield_->HasFocus()); EXPECT_FALSE(test_api_->touch_selection_controller()); textfield_->SetFocusBehavior(View::FocusBehavior::ALWAYS); } - -// No touch on desktop Mac. Tracked in http://crbug.com/445520. -#if BUILDFLAG(IS_MAC) -#define MAYBE_TapOnSelection DISABLED_TapOnSelection -#else -#define MAYBE_TapOnSelection TapOnSelection #endif -TEST_F(TextfieldTouchSelectionTest, MAYBE_TapOnSelection) { - InitTextfield(); - textfield_->SetText(u"hello world"); - gfx::Range sel_range(2, 7); - gfx::Range tap_range(5, 5); - gfx::Rect tap_rect = - GetCursorBounds(gfx::SelectionModel(tap_range, gfx::CURSOR_FORWARD)); - gfx::Point tap_point = tap_rect.CenterPoint(); - - // Select range |sel_range| and check if touch selection handles are not - // present and correct range is selected. - textfield_->SetEditableSelectionRange(sel_range); - gfx::Range range; - textfield_->GetEditableSelectionRange(&range); - EXPECT_FALSE(test_api_->touch_selection_controller()); - EXPECT_EQ(sel_range, range); - - // Tap on selection and check if touch selectoin handles are shown, but - // selection range is not modified. - Tap(tap_point); - textfield_->GetEditableSelectionRange(&range); - EXPECT_TRUE(test_api_->touch_selection_controller()); - EXPECT_EQ(sel_range, range); - - // Tap again on selection and check if touch selection handles are still - // present and selection is changed to a cursor at tap location. - Tap(tap_point); - textfield_->GetEditableSelectionRange(&range); - EXPECT_TRUE(test_api_->touch_selection_controller()); - EXPECT_EQ(tap_range, range); -} - TEST_F(TextfieldTest, MoveCaret) { InitTextfield(); textfield_->SetText(u"hello world");
diff --git a/ui/views/widget/ax_native_widget_mac_unittest.mm b/ui/views/widget/ax_native_widget_mac_unittest.mm index 1075c0f..40dac631 100644 --- a/ui/views/widget/ax_native_widget_mac_unittest.mm +++ b/ui/views/widget/ax_native_widget_mac_unittest.mm
@@ -24,6 +24,10 @@ #include "ui/views/test/widget_test.h" #include "ui/views/widget/widget.h" +#if !defined(__has_feature) || !__has_feature(objc_arc) +#error "This file requires ARC support." +#endif + namespace views { namespace { @@ -164,9 +168,8 @@ // on a retained accessibility object after the source view is deleted. TEST_F(AXNativeWidgetMacTest, Lifetime) { Textfield* view = AddChildTextfield(widget()->GetContentsView()->size()); - base::scoped_nsobject<NSObject> ax_node(view->GetNativeViewAccessible(), - base::scoped_policy::RETAIN); - id<NSAccessibility> ax_obj = ToNSAccessibility(ax_node.get()); + NSObject* ax_node = view->GetNativeViewAccessible(); + id<NSAccessibility> ax_obj = ToNSAccessibility(ax_node); EXPECT_TRUE(AXObjectHandlesSelector(ax_obj, @selector(accessibilityValue))); EXPECT_NSEQ(kTestStringValue, ax_obj.accessibilityValue); @@ -190,12 +193,11 @@ // The only usually available array attribute is AXChildren, so go up a level // to the Widget to test that a bit. The default implementation just gets the // attribute normally and returns its size (if it's an array). - base::scoped_nsprotocol<id<NSAccessibility>> ax_parent( - ax_obj.accessibilityParent, base::scoped_policy::RETAIN); + id<NSAccessibility> ax_parent = ax_obj.accessibilityParent; // There are two children: a NativeFrameView and the TextField. - EXPECT_EQ(2u, ax_parent.get().accessibilityChildren.count); - EXPECT_EQ(ax_node.get(), ax_parent.get().accessibilityChildren[1]); + EXPECT_EQ(2u, ax_parent.accessibilityChildren.count); + EXPECT_EQ(ax_node, ax_parent.accessibilityChildren[1]); // If it is not an array, the default implementation throws an exception, so // it's impossible to test these methods further on |ax_node|, apart from the @@ -230,7 +232,7 @@ // The Widget is currently still around, but the TextField should be gone, // leaving just the NativeFrameView. - EXPECT_EQ(1u, ax_parent.get().accessibilityChildren.count); + EXPECT_EQ(1u, ax_parent.accessibilityChildren.count); } // Check that potentially keyboard-focusable elements are always leaf nodes. @@ -687,8 +689,8 @@ EXPECT_TRUE(ax_node); // Create a native Cocoa NSSecureTextField to compare against. - base::scoped_nsobject<NSSecureTextField> cocoa_secure_textfield( - [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 10, 10)]); + NSSecureTextField* cocoa_secure_textfield = + [[NSSecureTextField alloc] initWithFrame:NSMakeRect(0, 0, 10, 10)]; const SEL expected_supported_selectors[] = { @selector(accessibilityValue), @@ -702,7 +704,7 @@ for (auto* sel : expected_supported_selectors) { EXPECT_TRUE(AXObjectHandlesSelector(ax_node, sel)); - EXPECT_TRUE(AXObjectHandlesSelector(cocoa_secure_textfield.get(), sel)); + EXPECT_TRUE(AXObjectHandlesSelector(cocoa_secure_textfield, sel)); } // TODO(https://crbug.com/939965): This should assert the same behavior of
diff --git a/ui/webui/resources/PRESUBMIT.py b/ui/webui/resources/PRESUBMIT.py index 361b6ad3..d1375b7 100644 --- a/ui/webui/resources/PRESUBMIT.py +++ b/ui/webui/resources/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. - -USE_PYTHON3 = True PRESUBMIT_VERSION = '2.0.0' def CheckForTranslations(input_api, output_api):
diff --git a/ui/webui/resources/cr_components/app_management/BUILD.gn b/ui/webui/resources/cr_components/app_management/BUILD.gn index c40126fd..8c9e4f3 100644 --- a/ui/webui/resources/cr_components/app_management/BUILD.gn +++ b/ui/webui/resources/cr_components/app_management/BUILD.gn
@@ -56,16 +56,13 @@ }, ] traits_headers = [ - "//ui/webui/resources/cr_components/app_management/app_management_mojom_traits.h", "//components/services/app_service/public/cpp/app_types.h", "//components/services/app_service/public/cpp/permission.h", "//components/services/app_service/public/cpp/run_on_os_login_types.h", + "//ui/webui/resources/cr_components/app_management/app_management_mojom_traits.h", ] traits_sources = [ "//ui/webui/resources/cr_components/app_management/app_management_mojom_traits.cc" ] - traits_public_deps = [ - "//components/services/app_service/public/cpp:app_types", - "//components/services/app_service/public/cpp:run_on_os_login", - ] + traits_public_deps = [ "//components/services/app_service" ] }, ] }
diff --git a/ui/webui/resources/cr_components/history_clusters/url_visit.html b/ui/webui/resources/cr_components/history_clusters/url_visit.html index ffb61ce..795dd21 100644 --- a/ui/webui/resources/cr_components/history_clusters/url_visit.html +++ b/ui/webui/resources/cr_components/history_clusters/url_visit.html
@@ -150,11 +150,11 @@ <cr-icon-button class="hide-visit-icon" title$="[[i18n('hideFromCluster')]]" on-click="onHideSelfButtonClick_" - hidden="[[!showHideVisitIcon_]]"></cr-icon-button> + hidden="[[!fromPersistence]]"></cr-icon-button> <cr-icon-button id="actionMenuButton" class="icon-more-vert" title$="[[i18n('actionMenuDescription')]]" aria-haspopup="menu" on-click="onActionMenuButtonClick_" - hidden="[[!showActionMenuButton_]]"> + hidden="[[!allowDeletingHistory_]]"> </cr-icon-button> </div> </div> @@ -162,10 +162,6 @@ <cr-lazy-render id="actionMenu"> <template> <cr-action-menu role-description="[[i18n('actionMenuDescription')]]"> - <button id="hideSelfButton" class="dropdown-item" hidden="[[!showHideVisitMenu_]]" - on-click="onHideSelfButtonClick_"> - [[i18n('hideFromCluster')]] - </button> <button id="removeSelfButton" class="dropdown-item" hidden="[[!allowDeletingHistory_]]" on-click="onRemoveSelfButtonClick_"> [[i18n('removeFromHistory')]]
diff --git a/ui/webui/resources/cr_components/history_clusters/url_visit.ts b/ui/webui/resources/cr_components/history_clusters/url_visit.ts index 6975fd6..5a88a04 100644 --- a/ui/webui/resources/cr_components/history_clusters/url_visit.ts +++ b/ui/webui/resources/cr_components/history_clusters/url_visit.ts
@@ -84,25 +84,6 @@ }, /** - * True when the hide-visits feature is enabled, not showing the hide - * visits icon, and the visit is hide-able (i.e. belongs to a persisted - * cluster). - */ - showHideVisitMenu_: { - type: Boolean, - computed: 'computeShowHideVisitMenu_(fromPersistence)', - }, - - /** - * Similar to `showHideVisitMenu_`, but showing the icon instead of the - * menu button. - */ - showHideVisitIcon_: { - type: Boolean, - computed: 'computeShowHideVisitIcon_(fromPersistence)', - }, - - /** * Usually this is true, but this can be false if deleting history is * prohibited by Enterprise policy. */ @@ -112,15 +93,6 @@ }, /** - * The action menu is hidden when the menu would be empty; i.e., both the - * hide visits and delete visits buttons are disabled. - */ - showActionMenuButton_: { - type: Boolean, - computed: 'computeShowActionMenuButton_(showHideVisitMenu_)', - }, - - /** * Debug info for the visit. */ debugInfo_: { @@ -167,10 +139,7 @@ visit: URLVisit; fromPersistence: boolean; private annotations_: string[]; - private showHideVisitMenu_: boolean; - private showHideVisitIcon_: boolean; private allowDeletingHistory_: boolean; - private showActionMenuButton_: boolean; private debugInfo_: string; private inSidePanel_: boolean; private unusedTitle_: string; @@ -271,24 +240,6 @@ .map((id: string) => loadTimeData.getString(id)); } - private computeShowHideVisitMenu_(_fromPersistence: boolean): boolean { - // Show the hide menu item if the visit is hide-able and the hide icon is - // hidden. - return this.fromPersistence && - loadTimeData.getBoolean('isHideVisitsEnabled') && - !loadTimeData.getBoolean('isHideVisitsIconEnabled'); - } - - private computeShowHideVisitIcon_(_fromPersistence: boolean): boolean { - return this.fromPersistence && - loadTimeData.getBoolean('isHideVisitsIconEnabled'); - } - - private computeShowActionMenuButton_(_showHideVisitMenu: boolean): boolean { - // Show the menu if either the hide or delete button is visible. - return this.showHideVisitMenu_ || this.allowDeletingHistory_; - } - private computeDebugInfo_(_visit: URLVisit): string { if (!loadTimeData.getBoolean('isHistoryClustersDebug')) { return '';
diff --git a/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css b/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css index 0f15e7d0..6c64a6e 100644 --- a/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css +++ b/ui/webui/resources/cr_elements/chromeos/cros_color_overrides.css
@@ -288,7 +288,7 @@ --cr-toggle-checked-button-color: var(--cros-sys-primary); --cr-toggle-checked-ripple-color: var(--cros-sys-hover_on_prominent); --cr-toggle-unchecked-bar-color: var(--cros-sys-secondary); - --cr-toggle-unchecked-button-color: var(--cros-sys-on_secondary); + --cr-toggle-unchecked-button-color: var(--cros-sys-surface_variant); --cr-toggle-unchecked-ripple-color: var(--cros-sys-hover_on_prominent); /* TODO(b/266837484) Replace with cros.sys.app-elevation1 when available */ --cr-toggle-box-shadow: var(--cros-elevation-1-shadow);
diff --git a/ui/webui/resources/cr_elements/cr_shared_vars.css b/ui/webui/resources/cr_elements/cr_shared_vars.css index 34f88ac..dec9556 100644 --- a/ui/webui/resources/cr_elements/cr_shared_vars.css +++ b/ui/webui/resources/cr_elements/cr_shared_vars.css
@@ -283,6 +283,8 @@ --cr-fallback-color-state-ripple-neutral-on-subtle: rgba( var(--cr-fallback-color-state-on-subtle-rgb), .08); + --cr-fallback-color-base-container: rgba(105, 145, 214, .12); + /* States */ --cr-hover-background-color: var(--color-sys-state-hover, rgba(var(--cr-fallback-color-on-surface-rgb), .08)); @@ -329,5 +331,6 @@ var(--cr-fallback-color-state-on-subtle-rgb), .10); --cr-fallback-color-state-ripple-neutral-on-subtle: rgba( var(--cr-fallback-color-state-on-subtle-rgb), .16); + --cr-fallback-color-base-container: rgba(40, 40, 40, 1); } }
diff --git a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html index bbfc14e..6e97b2e2 100644 --- a/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html +++ b/ui/webui/resources/cr_elements/cr_toolbar/cr_toolbar_search_field.html
@@ -1,7 +1,5 @@ <style include="cr-shared-style cr-icons"> :host { - align-items: center; - display: flex; height: 40px; transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1), width 150ms cubic-bezier(0.4, 0, 0.2, 1); @@ -213,14 +211,14 @@ :host-context([chrome-refresh-2023]):host(:not([narrow])) #background { background: var(--cr-toolbar-search-field-background, var(--color-toolbar-search-field-background, - var(--cr-fallback-color-surface))); + var(--cr-fallback-color-base-container))); border: 2px solid transparent; border-radius: inherit; display: block; inset: 0; pointer-events: none; position: absolute; - z-index: -1; + z-index: 0; } :host-context([chrome-refresh-2023].focus-outline-visible):host( @@ -243,6 +241,7 @@ :host-context([chrome-refresh-2023]):host(:hover) #stateBackground { background: var(--color-toolbar-search-field-background-hover, var(--cr-hover-background-color)); + z-index: 1; } :host(:not([narrow]):not([showing-search])) #icon { @@ -292,36 +291,49 @@ display: block; --paper-ripple-opacity: 1; } + + #content { + align-items: center; + display: flex; + height: 100%; + } + + :host-context([chrome-refresh-2023]) #content { + position: relative; + z-index: 2; + } </style> <div id="background"></div> <div id="stateBackground"></div> - <template is="dom-if" id="spinnerTemplate"> - <paper-spinner-lite active="[[isSpinnerShown_]]"> - </paper-spinner-lite> - </template> - <cr-icon-button id="icon" iron-icon="cr:search" title="[[label]]" dir="ltr" - tabindex$="[[computeIconTabIndex_(narrow, hasSearchText)]]" - aria-hidden$="[[computeIconAriaHidden_(narrow, hasSearchText)]]" - on-click="onSearchIconClicked_" disabled="[[disabled]]"> - </cr-icon-button> - <div id="searchTerm"> - <label id="prompt" for="searchInput" aria-hidden="true">[[label]]</label> - <input id="searchInput" - aria-labelledby="prompt" - autocapitalize="off" - autocomplete="off" - type="search" - on-input="onSearchTermInput" - on-search="onSearchTermSearch" - on-keydown="onSearchTermKeydown_" - on-focus="onInputFocus_" - on-blur="onInputBlur_" - autofocus$="[[autofocus]]" - spellcheck="false" - disabled="[[disabled]]"> + <div id="content"> + <template is="dom-if" id="spinnerTemplate"> + <paper-spinner-lite active="[[isSpinnerShown_]]"> + </paper-spinner-lite> + </template> + <cr-icon-button id="icon" iron-icon="cr:search" title="[[label]]" dir="ltr" + tabindex$="[[computeIconTabIndex_(narrow, hasSearchText)]]" + aria-hidden$="[[computeIconAriaHidden_(narrow, hasSearchText)]]" + on-click="onSearchIconClicked_" disabled="[[disabled]]"> + </cr-icon-button> + <div id="searchTerm"> + <label id="prompt" for="searchInput" aria-hidden="true">[[label]]</label> + <input id="searchInput" + aria-labelledby="prompt" + autocapitalize="off" + autocomplete="off" + type="search" + on-input="onSearchTermInput" + on-search="onSearchTermSearch" + on-keydown="onSearchTermKeydown_" + on-focus="onInputFocus_" + on-blur="onInputBlur_" + autofocus$="[[autofocus]]" + spellcheck="false" + disabled="[[disabled]]"> + </div> + <template is="dom-if" if="[[hasSearchText]]"> + <cr-icon-button id="clearSearch" iron-icon="cr:cancel" + title="[[clearLabel]]" on-click="clearSearch_" + disabled="[[disabled]]"></cr-icon-button> + </template> </div> - <template is="dom-if" if="[[hasSearchText]]"> - <cr-icon-button id="clearSearch" iron-icon="cr:cancel" - title="[[clearLabel]]" on-click="clearSearch_" - disabled="[[disabled]]"></cr-icon-button> - </template>
diff --git a/ui/webui/resources/tools/PRESUBMIT.py b/ui/webui/resources/tools/PRESUBMIT.py index bda3597..7ea1dc0 100644 --- a/ui/webui/resources/tools/PRESUBMIT.py +++ b/ui/webui/resources/tools/PRESUBMIT.py
@@ -2,9 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - - def _CheckChangeOnUploadOrCommit(input_api, output_api): results = [] webui_sources = set( @@ -20,8 +17,7 @@ presubmit_path = input_api.PresubmitLocalPath() sources = ['generate_grd_test.py', 'minify_js_test.py', 'bundle_js_test.py'] tests = [input_api.os_path.join(presubmit_path, s) for s in sources] - return input_api.canned_checks.RunUnitTests( - input_api, output_api, tests, run_on_python2=False) + return input_api.canned_checks.RunUnitTests(input_api, output_api, tests) def CheckChangeOnUpload(input_api, output_api):
diff --git a/weblayer/browser/android/javatests/skew/PRESUBMIT.py b/weblayer/browser/android/javatests/skew/PRESUBMIT.py index 878d0be..fd2af196 100644 --- a/weblayer/browser/android/javatests/skew/PRESUBMIT.py +++ b/weblayer/browser/android/javatests/skew/PRESUBMIT.py
@@ -2,8 +2,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -USE_PYTHON3 = True - import inspect import os import sys
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java index bae6aa4..a2c3098 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java +++ b/weblayer/browser/java/org/chromium/weblayer_private/TabImpl.java
@@ -33,8 +33,8 @@ import org.chromium.base.annotations.JNINamespace; import org.chromium.base.annotations.NativeMethods; import org.chromium.base.supplier.ObservableSupplier; -import org.chromium.components.autofill.AutofillActionModeCallback; import org.chromium.components.autofill.AutofillProvider; +import org.chromium.components.autofill.AutofillSelectionMenuItemProvider; import org.chromium.components.browser_ui.display_cutout.DisplayCutoutController; import org.chromium.components.browser_ui.media.MediaSessionHelper; import org.chromium.components.browser_ui.widget.InsetObserverView; @@ -371,7 +371,7 @@ mAutofillProvider = null; } if (selectionController != null) { - selectionController.setNonSelectionActionModeCallback(null); + selectionController.setNonSelectionAdditionalMenuItemProvider(null); } } else { if (mAutofillProvider == null) { @@ -387,8 +387,8 @@ mBrowser.getBrowserFragment().getViewAndroidDelegateContainerView()); mAutofillProvider.setWebContents(mWebContents); if (selectionController != null) { - selectionController.setNonSelectionActionModeCallback( - new AutofillActionModeCallback( + selectionController.setNonSelectionAdditionalMenuItemProvider( + new AutofillSelectionMenuItemProvider( mBrowser.getContext(), mAutofillProvider)); } }
diff --git a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py index 87a65b6..9d91afdc 100644 --- a/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py +++ b/weblayer/browser/java/org/chromium/weblayer_private/interfaces/PRESUBMIT.py
@@ -15,8 +15,6 @@ import sys import tempfile -USE_PYTHON3 = True - _INCOMPATIBLE_API_ERROR_STRING = """You have made an incompatible API change. Generally this means one of the following: A function has been removed.
diff --git a/weblayer/public/java/PRESUBMIT.py b/weblayer/public/java/PRESUBMIT.py index 6332f62..afd416c 100644 --- a/weblayer/public/java/PRESUBMIT.py +++ b/weblayer/public/java/PRESUBMIT.py
@@ -12,8 +12,6 @@ import sys import tempfile -USE_PYTHON3 = True - _WEBLAYER_PUBLIC_MANIFEST_PATH=os.path.join("weblayer", "public", "java", "AndroidManifest.xml")