diff --git a/.clang-tidy b/.clang-tidy index 431f88a4..6f64169 100644 --- a/.clang-tidy +++ b/.clang-tidy
@@ -71,4 +71,9 @@ # https://clang.llvm.org/extra/clang-tidy/checks/misc/include-cleaner.html - key: misc-include-cleaner.IgnoreHeaders value: (gmock/gmock|gtest/gtest|third_party|build/linux/debian).* + + ExtraArgs: + # b/382774818: disable unknown pragma warnings until we can figure out why + # unknown pragmas are being warned about. + - -Wno-unknown-pragmas ...
diff --git a/AUTHORS b/AUTHORS index 7556783d7..08171a5 100644 --- a/AUTHORS +++ b/AUTHORS
@@ -1675,6 +1675,7 @@ Estimote, Inc. <*@estimote.com> Google Inc. <*@google.com> Grammarly, Inc. <*@grammarly.com> +Here Inc. <*@here.io> Hewlett-Packard Development Company, L.P. <*@hp.com> HyperConnect Inc. <*@hpcnt.com> IBM Inc. <*@*.ibm.com>
diff --git a/DEPS b/DEPS index fee2a015..3e765c58 100644 --- a/DEPS +++ b/DEPS
@@ -276,11 +276,11 @@ # 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': '5dc66d651f301de4c5700ffc5e692a63b1435056', + 'src_internal_revision': 'c9e37b18db937312ecc32ef93d2b370258c2035b', # 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': '472faa80deaf1f357b285b38360a63d8f03484c6', + 'skia_revision': '77f4941092ac586c9a6db4e477203cf7e2f4633b', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. @@ -288,7 +288,7 @@ # 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': 'fbaaeb7b83bce2a6ec8519b4d7f990f0e2feb839', + 'angle_revision': '1a8d771208818689521fa1746211435d4eb9d476', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -300,7 +300,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling BoringSSL # and whatever else without interference from each other. - 'boringssl_revision': '281352b8c65da0831269ab4c6614d3b431a6e93d', + 'boringssl_revision': '5a2194f43d8801335e4b20040156686eb4247b22', # 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. @@ -348,15 +348,15 @@ # 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': '86d6f8ee6130eb3d6a43db7ac883c7d39df1c158', + 'catapult_revision': 'b3934f5a9aa01f3a1a1421db86ba0da90b601020', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling chromium_variations # and whatever else without interference from each other. - 'chromium_variations_revision': '18d4fbe9a192d85aa079810a063f63f6a37f2de9', + 'chromium_variations_revision': '0fcd7c5b11aca584c5c03b2af870c9f3af6c631c', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. - 'crossbench_revision': 'a6013e985a417f6b0a721b1455a6fff3c70410e4', + 'crossbench_revision': '1b41ed2574ef931f2d1157ebb153c9d552f69670', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libFuzzer # and whatever else without interference from each other. @@ -372,7 +372,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': 'd79204f9f7ad19bf39cedba661b2fcebdf3e368a', + 'devtools_frontend_revision': '585254f2d2596090823c971b90d4fd321011b01c', # 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. @@ -396,7 +396,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': '6b0812ec42b723b52efa7a8294a841c0299e8de8', + 'dawn_revision': '68ff61cfd4c1384a7a305e0c30c608aedaba95d3', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -424,7 +424,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libavif # and whatever else without interference from each other. - 'libavif_revision': '7cc2ffc34e4db627f8392a055649704d99d444a8', + 'libavif_revision': 'e9a27bc6a84f01b6670c05c301c445f33a464992', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling crabbyavif # and whatever else without interference from each other. @@ -496,7 +496,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling llvm-libc # and whatever else without interference from each other. - 'llvm_libc_revision': 'b0c04a4ce44caf3bcb5dffc315d7cc58c20f4ba7', + 'llvm_libc_revision': '039fea2058d14b408637a931b36a717169617227', # If you change this, also update the libc++ revision in # //buildtools/deps_revisions.gni. @@ -784,10 +784,10 @@ 'condition': 'non_git_source', 'objects': [ { - 'object_name': 'ebd90b44f16134e47ba772b349418c9d5b701d40', - 'sha256sum': 'a1a9388fb8ac7549617250bad43a71cf71084de060c46d0e66ae1d844d441600', - 'size_bytes': 9090812, - 'generation': 1733245676031215, + 'object_name': '59332695e189485e2e2b06e60e4d49d3d54b8e92', + 'sha256sum': 'a40ca106fa4d6b25cd0a3bb1c74991666ae91e9b5335799f1243da41f6d782ab', + 'size_bytes': 9100683, + 'generation': 1736178718186041, 'output_file': 'node_modules.tar.gz', }, ], @@ -1439,12 +1439,12 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'c0f9cfa5836eb7aedcef22bb09fa19001ed59c35', + 'f9c09c54dcfa04880a60179b519ee0866babdcbc', 'condition': 'checkout_android and checkout_src_internal', }, 'src/docs/website': { - 'url': Var('chromium_git') + '/website.git' + '@' + '228b145cbe593cd326f9e1f4d038476e18745519', + 'url': Var('chromium_git') + '/website.git' + '@' + '4d214097ba7305ec2b3f2dfcf0aa4fd2104c960a', }, 'src/ios/third_party/earl_grey2/src': { @@ -1598,7 +1598,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'hed62mh6OgdqejEpv68I9aWfPEbNarJBHejKazMdkWEC', + 'version': 'gUjEawxv5mQO8yfbuC8W-rx4V3zYE-4LTWggXpZHI4sC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1625,7 +1625,7 @@ 'packages': [ { 'package': 'chromium/third_party/android_build_tools/aapt2', - 'version': 'JPmxYHMZl4VH2Umf2-flGSdTVHtNDdFBmXd7v1Gs7EoC', + 'version': '_lNsOL_GGlXLOIMGtrbMOqNd7TQHabaP1q8SlvUpFbMC', }, ], 'condition': 'checkout_android and non_git_source', @@ -1904,7 +1904,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' + '@' + '249badca44938d6d13d343e99744f1b0e280b919', + 'url': Var('chromium_git') + '/chromiumos/chromite.git' + '@' + 'bcc0e90690a83cc09d4bc39860cf152a47b38347', 'condition': 'checkout_chromeos', }, @@ -1934,7 +1934,7 @@ 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '58625e82c685426d441be5b422c9ad88e4867d20', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '93954a51a1c0c113bd057704c883e3de0d20db31', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -2187,7 +2187,7 @@ 'packages': [ { 'package': 'chromium/third_party/kotlinc', - 'version': 'HckNA1Q54JBiHrpY1gP5qblVCdeuVmGsiGCdv1XjqywC', + 'version': 'YrBSUjA4zjPf3DhU2SYlqamxAAQiM2WIeZftsDSjqTAC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2210,7 +2210,7 @@ Var('chromium_git') + '/external/libaddressinput.git' + '@' + 'e8712e415627f22d0b00ebee8db99547077f39bd', 'src/third_party/libaom/source/libaom': - Var('aomedia_git') + '/aom.git' + '@' + '76df9967c206eb1200f5ecb1fd928a3d88c2648d', + Var('aomedia_git') + '/aom.git' + '@' + '0c13a5d54053f82bf8500b421b5cdefb1cc1b3ed', 'src/third_party/libavif/src': Var('chromium_git') + '/external/github.com/AOMediaCodec/libavif.git' + '@' + Var('libavif_revision'), @@ -2436,7 +2436,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('android_git') + '/platform/external/perfetto.git' + '@' + 'aa335456a8b3c7fb70ec60f6c6f4c455c7efdcf3', + Var('android_git') + '/platform/external/perfetto.git' + '@' + '2473cc95bc0d2d0c3c240be49ce4c2d0dc48edd4', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -2632,7 +2632,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'q_wvk54XItTBlBNQMHkS4NRMp-tapPW97M292KTXHrsC', + 'version': 'U3Jf_ewWOZyxa6vyO3wjNIgm8XIz1yFk-4k3-wqDL44C', }, ], 'condition': 'checkout_android and non_git_source', @@ -2800,13 +2800,13 @@ Var('chromium_git') + '/external/khronosgroup/webgl.git' + '@' + '450cceb587613ac1469c5a131fac15935c99e0e7', 'src/third_party/webgpu-cts/src': - Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '3faf2bf1b08d4fcad605450a53b24a4ddd5f46d2', + Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + 'd3fec1ffa922e8da4a5cf6da9fd77190ea8c23cf', 'src/third_party/webpagereplay': Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'), 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'd7b2f8560a4980111501dd8c0bdf19ae86287e41', + Var('webrtc_git') + '/src.git' + '@' + 'cbe304455fe0ae24622252ef8a0707a555fa5caf', # 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.
diff --git a/android_webview/browser/aw_field_trials.cc b/android_webview/browser/aw_field_trials.cc index e1dc1bc8..1ca5b37 100644 --- a/android_webview/browser/aw_field_trials.cc +++ b/android_webview/browser/aw_field_trials.cc
@@ -289,4 +289,7 @@ // WebView. aw_feature_overrides.DisableFeature( base::features::kPartitionAllocMemoryTagging); + + // Disable Topics on WebView. + aw_feature_overrides.DisableFeature(blink::features::kBrowsingTopics); }
diff --git a/ash/app_list/views/search_box_view.cc b/ash/app_list/views/search_box_view.cc index 03684ef..a835b8c 100644 --- a/ash/app_list/views/search_box_view.cc +++ b/ash/app_list/views/search_box_view.cc
@@ -832,11 +832,10 @@ views::ImageButton::STATE_NORMAL, ui::ImageModel::FromVectorIcon( chromeos::kAssistantIcon, button_icon_color, GetSearchBoxIconSize())); - // TODO(crbug.com/380089265): set Assistant new entry point icon. - assistant_new_entry_point_button()->SetImageModel( - views::ImageButton::STATE_NORMAL, - ui::ImageModel::FromVectorIcon( - chromeos::kAssistantIcon, button_icon_color, GetSearchBoxIconSize())); + + // Image model of `assistant_new_entry_point_button()` is set in + // `SearchBoxViewBase::SetShowAssistantNewEntryPointButton`. + if (filter_button()) { filter_button()->SetImageModel( views::ImageButton::STATE_NORMAL,
diff --git a/ash/public/cpp/accelerators.h b/ash/public/cpp/accelerators.h index 0673274..b7d81a0 100644 --- a/ash/public/cpp/accelerators.h +++ b/ash/public/cpp/accelerators.h
@@ -456,11 +456,9 @@ kToggleDoNotDisturbAcceleratorDataLength = std::size(kToggleDoNotDisturbAcceleratorData); -// TODO(385364574): Replace this fake temporary keycode with actual keycode. ASH_PUBLIC_EXPORT inline constexpr AcceleratorData kToggleCameraAllowedAcceleratorData[] = { - {true, ui::VKEY_F23, - ui::EF_COMMAND_DOWN | ui::EF_SHIFT_DOWN | ui::EF_ALT_DOWN, + {true, ui::VKEY_CAMERA_ACCESS_TOGGLE, ui::EF_NONE, AcceleratorAction::kToggleCameraAllowed}, }; ASH_PUBLIC_EXPORT inline constexpr size_t
diff --git a/ash/search_box/BUILD.gn b/ash/search_box/BUILD.gn index f497dd2..976748a 100644 --- a/ash/search_box/BUILD.gn +++ b/ash/search_box/BUILD.gn
@@ -19,6 +19,7 @@ "//ash/strings", "//ash/style", "//base", + "//chromeos/ash/services/assistant/public/cpp", "//skia", "//ui/base", "//ui/base/ime",
diff --git a/ash/search_box/search_box_view_base.cc b/ash/search_box/search_box_view_base.cc index c39351d..987515ef 100644 --- a/ash/search_box/search_box_view_base.cc +++ b/ash/search_box/search_box_view_base.cc
@@ -18,6 +18,7 @@ #include "base/functional/callback_forward.h" #include "base/memory/raw_ptr.h" #include "base/strings/strcat.h" +#include "chromeos/ash/services/assistant/public/cpp/assistant_browser_delegate.h" #include "third_party/skia/include/core/SkPath.h" #include "ui/base/ime/text_input_flags.h" #include "ui/base/l10n/l10n_util.h" @@ -29,6 +30,7 @@ #include "ui/gfx/color_palette.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/image_util.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/animation/animation_builder.h" #include "ui/views/animation/flood_fill_ink_drop_ripple.h" @@ -895,6 +897,30 @@ CHECK(assistant_new_entry_point_button_); show_assistant_new_entry_point_button_ = show; assistant_new_entry_point_button_->SetVisible(show); + + if (show && assistant_new_entry_point_button_ + ->GetImage(views::ImageButton::STATE_NORMAL) + .isNull()) { + // `AssistantBrowserDelegate::Get` has `DCHECK`. It's not allowed to call if + // `AssistantBrowserDelegate` is not available, and that is the case for + // some tests. Query resource id only if visibility is determined to be + // visible. Querying visibility requires access to + // `AssistantBrowserDelegate`. It means that the delegate is available. + assistant::AssistantBrowserDelegate* assistant_browser_delegate = + assistant::AssistantBrowserDelegate::Get(); + CHECK(assistant_browser_delegate); + + // Assistant new entry point icon includes margins. Use button size + // instead of search box icon size, which contains margins, to avoid + // having duplicated margins. + assistant_new_entry_point_button()->SetImageModel( + views::ImageButton::STATE_NORMAL, + ui::ImageModel::FromImage(gfx::ResizedImage( + ui::ResourceBundle::GetSharedInstance().GetImageNamed( + assistant_browser_delegate->GetNewEntryPointIconResourceId()), + assistant_new_entry_point_button_->GetPreferredSize()))); + } + UpdateButtonsVisibility(); }
diff --git a/ash/webui/common/resources/BUILD.gn b/ash/webui/common/resources/BUILD.gn index c19ea50a..82205716 100644 --- a/ash/webui/common/resources/BUILD.gn +++ b/ash/webui/common/resources/BUILD.gn
@@ -39,7 +39,6 @@ "network/network_list_item.js", "network/network_password_input.js", "network/network_property_list_mojo.js", - "network/network_proxy_exclusions.js", "network/sim_lock_dialogs.js", "network/apn_detail_dialog.js", "network/apn_selection_dialog_list_item.js", @@ -111,6 +110,7 @@ "network/network_nameservers.ts", "network/network_list.ts", "network/network_proxy.ts", + "network/network_proxy_exclusions.ts", "network/network_proxy_input.ts", "network/network_select.ts", "network/network_siminfo.ts", @@ -468,7 +468,6 @@ "network/network_nameservers.html.js", "network/network_proxy.html.js", "network/network_proxy_exclusions.html.js", - "network/network_proxy_exclusions.js", "network/network_proxy_input.html.js", "network/network_select.html.js", "network/network_shared.css.js",
diff --git a/ash/webui/common/resources/cellular_setup/OWNERS b/ash/webui/common/resources/cellular_setup/OWNERS index 6277183..3d1084ae 100644 --- a/ash/webui/common/resources/cellular_setup/OWNERS +++ b/ash/webui/common/resources/cellular_setup/OWNERS
@@ -1,4 +1,3 @@ chadduffin@chromium.org -gordonseto@google.com hsuregan@chromium.org khorimoto@chromium.org
diff --git a/ash/webui/common/resources/network/BUILD.gn b/ash/webui/common/resources/network/BUILD.gn index 8349756..8d3810c 100644 --- a/ash/webui/common/resources/network/BUILD.gn +++ b/ash/webui/common/resources/network/BUILD.gn
@@ -28,7 +28,6 @@ ":network_listener_behavior", ":network_password_input", ":network_property_list_mojo", - ":network_proxy_exclusions", ":onc_mojo", ":sim_lock_dialogs", ] @@ -197,14 +196,6 @@ ] } -js_library("network_proxy_exclusions") { - deps = [ - "//ash/webui/common/resources:i18n_behavior", - "//third_party/polymer/v3_0/components-chromium/iron-flex-layout:iron-flex-layout-classes", - "//third_party/polymer/v3_0/components-chromium/polymer:polymer_bundled", - ] -} - js_library("onc_mojo") { deps = [ "//ash/webui/common/resources:assert",
diff --git a/ash/webui/common/resources/network/network_proxy_exclusions.js b/ash/webui/common/resources/network/network_proxy_exclusions.ts similarity index 65% rename from ash/webui/common/resources/network/network_proxy_exclusions.js rename to ash/webui/common/resources/network/network_proxy_exclusions.ts index 9f0bd88..d249056 100644 --- a/ash/webui/common/resources/network/network_proxy_exclusions.js +++ b/ash/webui/common/resources/network/network_proxy_exclusions.ts
@@ -12,23 +12,17 @@ import '//resources/polymer/v3_0/iron-flex-layout/iron-flex-layout-classes.js'; import './network_shared.css.js'; -import {I18nBehavior, I18nBehaviorInterface} from '//resources/ash/common/i18n_behavior.js'; -import {mixinBehaviors, PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; +import {I18nMixin} from '//resources/ash/common/cr_elements/i18n_mixin.js'; +import {PolymerElement} from '//resources/polymer/v3_0/polymer/polymer_bundled.min.js'; import {getTemplate} from './network_proxy_exclusions.html.js'; -/** - * @constructor - * @extends {PolymerElement} - * @implements {I18nBehaviorInterface} - */ -const NetworkProxyExclusionsElementBase = - mixinBehaviors([I18nBehavior], PolymerElement); +const NetworkProxyExclusionsElementBase = I18nMixin(PolymerElement); -/** @polymer */ -class NetworkProxyExclusionsElement extends NetworkProxyExclusionsElementBase { +export class NetworkProxyExclusionsElement extends + NetworkProxyExclusionsElementBase { static get is() { - return 'network-proxy-exclusions'; + return 'network-proxy-exclusions' as const; } static get template() { return getTemplate(); @@ -44,7 +38,6 @@ /** * The list of exclusions. - * @type {!Array<string>} */ exclusions: { type: Array, @@ -56,12 +49,10 @@ }; } - /** - * Event triggered when an item is removed. - * @param {!{model: !{index: number}}} event - * @private - */ - onRemoveTap_(event) { + editable: boolean; + exclusions: string[]; + + private onRemoveTap_(event: {model: {index: number}}): void { const index = event.model.index; this.splice('exclusions', index, 1); this.dispatchEvent(new CustomEvent( @@ -69,5 +60,11 @@ } } +declare global { + interface HTMLElementTagNameMap { + [NetworkProxyExclusionsElement.is]: NetworkProxyExclusionsElement; + } +} + customElements.define( NetworkProxyExclusionsElement.is, NetworkProxyExclusionsElement);
diff --git a/base/BUILD.gn b/base/BUILD.gn index 1072bc4c..5d8029a 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1831,6 +1831,8 @@ "win/event_trace_controller.h", "win/event_trace_provider.cc", "win/event_trace_provider.h", + "win/hardware_check.cc", + "win/hardware_check.h", "win/hstring_reference.cc", "win/hstring_reference.h", "win/i18n.cc", @@ -1866,6 +1868,7 @@ "win/scoped_co_mem.h", "win/scoped_com_initializer.cc", "win/scoped_com_initializer.h", + "win/scoped_gdi_object.cc", "win/scoped_gdi_object.h", "win/scoped_handle.cc", "win/scoped_handle.h", @@ -1947,6 +1950,7 @@ "propsys.lib", "setupapi.lib", "shcore.lib", + "tbs.lib", "userenv.lib", "wbemuuid.lib", "winmm.lib", @@ -3730,6 +3734,7 @@ "win/event_trace_consumer_unittest.cc", "win/event_trace_controller_unittest.cc", "win/event_trace_provider_unittest.cc", + "win/hardware_check_unittest.cc", "win/hstring_reference_unittest.cc", "win/i18n_unittest.cc", "win/map_unittest.cc",
diff --git a/base/allocator/partition_allocator/src/partition_alloc/spinning_mutex.cc b/base/allocator/partition_allocator/src/partition_alloc/spinning_mutex.cc index 91eda73..6740cd49 100644 --- a/base/allocator/partition_allocator/src/partition_alloc/spinning_mutex.cc +++ b/base/allocator/partition_allocator/src/partition_alloc/spinning_mutex.cc
@@ -142,8 +142,28 @@ #elif PA_BUILDFLAG(IS_APPLE) +// TODO(verwaest): We should use the constants from the header, but they aren't +// exposed until macOS 15. +#define OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION 0x00010000 +#define OS_UNFAIR_LOCK_ADAPTIVE_SPIN 0x00040000 + +typedef uint32_t os_unfair_lock_options_t; + +extern "C" { +void __attribute__((weak)) +os_unfair_lock_lock_with_options(os_unfair_lock* lock, + os_unfair_lock_options_t); +} + void SpinningMutex::LockSlow() { - return os_unfair_lock_lock(&unfair_lock_); + if (os_unfair_lock_lock_with_options) { + const os_unfair_lock_options_t options = + static_cast<os_unfair_lock_options_t>( + OS_UNFAIR_LOCK_DATA_SYNCHRONIZATION | OS_UNFAIR_LOCK_ADAPTIVE_SPIN); + os_unfair_lock_lock_with_options(&unfair_lock_, options); + } else { + os_unfair_lock_lock(&unfair_lock_); + } } #elif PA_BUILDFLAG(IS_POSIX)
diff --git a/base/android/java/src/org/chromium/base/FeatureList.java b/base/android/java/src/org/chromium/base/FeatureList.java index a78bf7f..e4e01dc 100644 --- a/base/android/java/src/org/chromium/base/FeatureList.java +++ b/base/android/java/src/org/chromium/base/FeatureList.java
@@ -234,7 +234,7 @@ */ @VisibleForTesting @Deprecated - public static void removeAllTestOverrides() { + static void removeAllTestOverrides() { overwriteTestValues(null); } @@ -262,7 +262,7 @@ * @param replace if true, replaces existing overrides; otherwise preserve them */ @Deprecated - public static void mergeTestValues(TestValues testValuesToMerge, boolean replace) { + static void mergeTestValues(TestValues testValuesToMerge, boolean replace) { TestValues newTestValues = new TestValues(); if (sTestFeatures != null) { newTestValues.merge(sTestFeatures, /* replace= */ true);
diff --git a/base/android/java/src/org/chromium/base/Log.java b/base/android/java/src/org/chromium/base/Log.java index da4b5e1..8a8c06f 100644 --- a/base/android/java/src/org/chromium/base/Log.java +++ b/base/android/java/src/org/chromium/base/Log.java
@@ -46,7 +46,7 @@ /** Returns a formatted log message, using the supplied format and arguments. */ private static String formatLog( - String messageTemplate, @Nullable Throwable tr, @Nullable Object... params) { + String messageTemplate, @Nullable Throwable tr, @Nullable Object @Nullable [] params) { if ((params != null) && ((tr == null && params.length > 0) || params.length > 1)) { messageTemplate = String.format(Locale.US, messageTemplate, params); } @@ -88,7 +88,7 @@ * @param args Arguments referenced by the format specifiers in the format string. If the last * one is a {@link Throwable}, its trace will be printed. */ - public static void v(String tag, String messageTemplate, Object... args) { + public static void v(String tag, String messageTemplate, @Nullable Object @Nullable ... args) { if (!isLoggable(tag, VERBOSE)) return; Throwable tr = getThrowableToLog(args); @@ -111,7 +111,7 @@ * @param args Arguments referenced by the format specifiers in the format string. If the last * one is a {@link Throwable}, its trace will be printed. */ - public static void d(String tag, String messageTemplate, Object... args) { + public static void d(String tag, String messageTemplate, @Nullable Object @Nullable ... args) { if (!isLoggable(tag, DEBUG)) return; Throwable tr = getThrowableToLog(args); @@ -134,7 +134,7 @@ * @param args Arguments referenced by the format specifiers in the format string. If the last * one is a {@link Throwable}, its trace will be printed. */ - public static void i(String tag, String messageTemplate, Object... args) { + public static void i(String tag, String messageTemplate, @Nullable Object... args) { Throwable tr = getThrowableToLog(args); String message = formatLog(messageTemplate, tr, args); tag = normalizeTag(tag); @@ -901,7 +901,7 @@ return android.util.Log.getStackTraceString(tr); } - private static @Nullable Throwable getThrowableToLog(Object[] args) { + private static @Nullable Throwable getThrowableToLog(@Nullable Object @Nullable [] args) { if (args == null || args.length == 0) return null; Object lastArg = args[args.length - 1];
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java index b6089206..e233378 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildConnectionAllocator.java
@@ -87,7 +87,7 @@ // Runnable which will be called when allocator wants to allocate a new connection, but does // not have any more free slots. May be null. - private final Runnable mFreeSlotCallback; + private final @Nullable Runnable mFreeSlotCallback; private final Queue<Runnable> mPendingAllocations = new ArrayDeque<>(); @@ -129,7 +129,7 @@ public static ChildConnectionAllocator create( Context context, Handler launcherHandler, - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String packageName, String serviceClassName, String numChildServicesManifestKey, @@ -224,7 +224,7 @@ * instead of being retrieved from the AndroidManifest.xml. */ public static FixedSizeAllocatorImpl createFixedForTesting( - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String packageName, String serviceClassName, int serviceCount, @@ -245,7 +245,7 @@ public static VariableSizeAllocatorImpl createVariableSizeForTesting( Handler launcherHandler, String packageName, - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String serviceClassName, boolean bindToCaller, boolean bindAsExternalService, @@ -266,7 +266,7 @@ public static Android10WorkaroundAllocatorImpl createWorkaroundForTesting( Handler launcherHandler, String packageName, - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String serviceClassName, boolean bindToCaller, boolean bindAsExternalService, @@ -285,7 +285,7 @@ private ChildConnectionAllocator( Handler launcherHandler, - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String packageName, String serviceClassName, @Nullable String fallbackServiceClassName, @@ -440,7 +440,7 @@ private FixedSizeAllocatorImpl( Handler launcherHandler, - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String packageName, String serviceClassName, boolean bindToCaller, @@ -554,7 +554,7 @@ // Note |serviceClassName| includes the service suffix. private VariableSizeAllocatorImpl( Handler launcherHandler, - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String packageName, String serviceClassName, @Nullable String fallbackServiceClassName, @@ -668,7 +668,7 @@ private Android10WorkaroundAllocatorImpl( Handler launcherHandler, - Runnable freeSlotCallback, + @Nullable Runnable freeSlotCallback, String packageName, String serviceClassName, boolean bindToCaller,
diff --git a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java index 86b41ad..6327a9c 100644 --- a/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java +++ b/base/android/java/src/org/chromium/base/process_launcher/ChildProcessLauncher.java
@@ -101,10 +101,10 @@ private final ChildConnectionAllocator mConnectionAllocator; // The IBinder interfaces provided to the created service. - private final List<IBinder> mClientInterfaces; + private final @Nullable List<IBinder> mClientInterfaces; - // A binder box which can be used by the child to unpack additional binders. May be null. - private final IBinder mBinderBox; + // A binder box which can be used by the child to unpack additional binders. + private final @Nullable IBinder mBinderBox; // The actual service connection. Set once we have connected to the service. Volatile as it is // accessed from threads other than the Launcher thread. @@ -128,8 +128,8 @@ String[] commandLine, FileDescriptorInfo[] filesToBeMapped, ChildConnectionAllocator connectionAllocator, - List<IBinder> clientInterfaces, - IBinder binderBox) { + @Nullable List<IBinder> clientInterfaces, + @Nullable IBinder binderBox) { assert connectionAllocator != null; mLauncherHandler = launcherHandler; isRunningOnLauncherThread(); @@ -294,11 +294,11 @@ return connection == null ? NULL_PROCESS_HANDLE : connection.getPid(); } - public List<IBinder> getClientInterfaces() { + public @Nullable List<IBinder> getClientInterfaces() { return mClientInterfaces; } - public IBinder getBinderBox() { + public @Nullable IBinder getBinderBox() { return mBinderBox; }
diff --git a/base/linux_util.cc b/base/linux_util.cc index a3e83f4..a3fe988 100644 --- a/base/linux_util.cc +++ b/base/linux_util.cc
@@ -22,6 +22,7 @@ #include "base/files/file_util.h" #include "base/files/scoped_file.h" #include "base/strings/safe_sprintf.h" +#include "base/strings/span_printf.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "base/strings/string_tokenizer.h" @@ -183,7 +184,7 @@ std::vector<char> syscall_data(expected_data.size()); for (pid_t tid : tids) { char buf[256]; - snprintf(buf, sizeof(buf), "/proc/%d/task/%d/syscall", pid, tid); + base::SpanPrintf(buf, "/proc/%d/task/%d/syscall", pid, tid); ScopedFD fd(open(buf, O_RDONLY)); if (!fd.is_valid()) { continue; @@ -212,7 +213,7 @@ for (pid_t tid : tids) { char buf[256]; - snprintf(buf, sizeof(buf), "/proc/%d/task/%d/status", pid, tid); + base::SpanPrintf(buf, "/proc/%d/task/%d/status", pid, tid); std::string status; if (!ReadFileToString(FilePath(buf), &status)) { return -1;
diff --git a/base/metrics/persistent_sample_map.cc b/base/metrics/persistent_sample_map.cc index 1d662f38..bdf1fff 100644 --- a/base/metrics/persistent_sample_map.cc +++ b/base/metrics/persistent_sample_map.cc
@@ -4,12 +4,15 @@ #include "base/metrics/persistent_sample_map.h" -#include "base/atomicops.h" +#include <atomic> +#include <type_traits> + #include "base/check_op.h" #include "base/containers/contains.h" #include "base/debug/crash_logging.h" #include "base/metrics/histogram_macros.h" #include "base/metrics/persistent_histogram_allocator.h" +#include "base/metrics/sample_map_iterator.h" #include "base/notreached.h" #include "base/numerics/safe_conversions.h" @@ -18,90 +21,11 @@ typedef HistogramBase::Count Count; typedef HistogramBase::Sample Sample; -namespace { - -// An iterator for going through a PersistentSampleMap. The logic here is -// identical to that of the iterator for SampleMap but with different data -// structures. Changes here likely need to be duplicated there. -template <typename T, typename I> -class IteratorTemplate : public SampleCountIterator { - public: - explicit IteratorTemplate(T& sample_counts) - : iter_(sample_counts.begin()), end_(sample_counts.end()) { - SkipEmptyBuckets(); - } - - ~IteratorTemplate() override; - - // SampleCountIterator: - bool Done() const override { return iter_ == end_; } - void Next() override { - DCHECK(!Done()); - ++iter_; - SkipEmptyBuckets(); - } - void Get(HistogramBase::Sample* min, - int64_t* max, - HistogramBase::Count* count) override; - - private: - void SkipEmptyBuckets() { - while (!Done() && subtle::NoBarrier_Load(iter_->second) == 0) { - ++iter_; - } - } - - I iter_; - const I end_; -}; - typedef std::map<HistogramBase::Sample, - raw_ptr<HistogramBase::Count, CtnExperimental>> + raw_ptr<std::atomic<HistogramBase::Count>, CtnExperimental>> SampleToCountMap; -typedef IteratorTemplate<const SampleToCountMap, - SampleToCountMap::const_iterator> - PersistentSampleMapIterator; -template <> -PersistentSampleMapIterator::~IteratorTemplate() = default; - -// Get() for an iterator of a PersistentSampleMap. -template <> -void PersistentSampleMapIterator::Get(Sample* min, int64_t* max, Count* count) { - DCHECK(!Done()); - *min = iter_->first; - *max = strict_cast<int64_t>(iter_->first) + 1; - // We have to do the following atomically, because even if the caller is using - // a lock, a separate process (that is not aware of this lock) may - // concurrently modify the value (note that iter_->second is a pointer to a - // sample count, which may live in shared memory). - *count = subtle::NoBarrier_Load(iter_->second); -} - -typedef IteratorTemplate<SampleToCountMap, SampleToCountMap::iterator> - ExtractingPersistentSampleMapIterator; - -template <> -ExtractingPersistentSampleMapIterator::~IteratorTemplate() { - // Ensure that the user has consumed all the samples in order to ensure no - // samples are lost. - DCHECK(Done()); -} - -// Get() for an extracting iterator of a PersistentSampleMap. -template <> -void ExtractingPersistentSampleMapIterator::Get(Sample* min, - int64_t* max, - Count* count) { - DCHECK(!Done()); - *min = iter_->first; - *max = strict_cast<int64_t>(iter_->first) + 1; - // We have to do the following atomically, because even if the caller is using - // a lock, a separate process (that is not aware of this lock) may - // concurrently modify the value (note that iter_->second is a pointer to a - // sample count, which may live in shared memory). - *count = subtle::NoBarrier_AtomicExchange(iter_->second, 0); -} +namespace { // This structure holds an entry for a PersistentSampleMap within a persistent // memory allocator. The "id" must be unique across all maps held by an @@ -113,9 +37,19 @@ // Expected size for 32/64-bit check. static constexpr size_t kExpectedInstanceSize = 16; - uint64_t id; // Unique identifier of owner. - Sample value; // The value for which this record holds a count. - Count count; // The count associated with the above value. + uint64_t id; // Unique identifier of owner. + Sample value; // The value for which this record holds a count. + std::atomic<Count> count; // The count associated with the above value. + + // `count` may operate inter-process and so must be lock-free. + static_assert(std::atomic<Count>::is_always_lock_free); + + // For backwards compatibility, `std::atomic<Count>` and `Count` must have + // the same memory layouts. If this ever changes, make sure to increment + // `kPersistentTypeId` above. + static_assert(std::is_standard_layout_v<std::atomic<Count>>); + static_assert(sizeof(std::atomic<Count>) == sizeof(Count)); + static_assert(alignof(std::atomic<Count>) == alignof(Count)); }; } // namespace @@ -132,17 +66,17 @@ // We have to do the following atomically, because even if the caller is using // a lock, a separate process (that is not aware of this lock) may // concurrently modify the value. - subtle::NoBarrier_AtomicIncrement(GetOrCreateSampleCountStorage(value), - count); + GetOrCreateSampleCountStorage(value)->fetch_add(count, + std::memory_order_relaxed); IncreaseSumAndCount(strict_cast<int64_t>(count) * value, count); } Count PersistentSampleMap::GetCount(Sample value) const { // Have to override "const" to make sure all samples have been loaded before // being able to know what value to return. - Count* count_pointer = + const std::atomic<Count>* const count_pointer = const_cast<PersistentSampleMap*>(this)->GetSampleCountStorage(value); - return count_pointer ? subtle::NoBarrier_Load(count_pointer) : 0; + return count_pointer ? count_pointer->load(std::memory_order_relaxed) : 0; } Count PersistentSampleMap::TotalCount() const { @@ -153,7 +87,7 @@ Count count = 0; for (const auto& entry : sample_counts_) { - count += subtle::NoBarrier_Load(entry.second); + count += entry.second->load(std::memory_order_relaxed); } return count; } @@ -163,14 +97,15 @@ // loaded before trying to iterate over the map. const_cast<PersistentSampleMap*>(this)->ImportSamples( /*until_value=*/std::nullopt); - return std::make_unique<PersistentSampleMapIterator>(sample_counts_); + return std::make_unique<SampleMapIterator<SampleToCountMap, false>>( + sample_counts_); } std::unique_ptr<SampleCountIterator> PersistentSampleMap::ExtractingIterator() { // Make sure all samples have been loaded before trying to iterate over the // map. ImportSamples(/*until_value=*/std::nullopt); - return std::make_unique<ExtractingPersistentSampleMapIterator>( + return std::make_unique<SampleMapIterator<SampleToCountMap, true>>( sample_counts_); } @@ -241,14 +176,14 @@ // We have to do the following atomically, because even if the caller is // using a lock, a separate process (that is not aware of this lock) may // concurrently modify the value. - subtle::Barrier_AtomicIncrement( - GetOrCreateSampleCountStorage(min), - (op == HistogramSamples::ADD) ? count : -count); + GetOrCreateSampleCountStorage(min)->fetch_add( + (op == HistogramSamples::ADD) ? count : -count, + std::memory_order_seq_cst); } return true; } -Count* PersistentSampleMap::GetSampleCountStorage(Sample value) { +std::atomic<Count>* PersistentSampleMap::GetSampleCountStorage(Sample value) { // If |value| is already in the map, just return that. auto it = sample_counts_.find(value); if (it != sample_counts_.end()) { @@ -259,9 +194,10 @@ return ImportSamples(/*until_value=*/value); } -Count* PersistentSampleMap::GetOrCreateSampleCountStorage(Sample value) { +std::atomic<Count>* PersistentSampleMap::GetOrCreateSampleCountStorage( + Sample value) { // Get any existing count storage. - Count* count_pointer = GetSampleCountStorage(value); + std::atomic<Count>* count_pointer = GetSampleCountStorage(value); if (count_pointer) { return count_pointer; } @@ -275,7 +211,7 @@ // full or corrupt. Instead, allocate the counter from the heap. This // sample will not be persistent, will not be shared, and will leak... // but it's better than crashing. - count_pointer = new Count(0); + count_pointer = new std::atomic<Count>(0); sample_counts_[value] = count_pointer; return count_pointer; } @@ -306,7 +242,8 @@ return records_.get(); } -Count* PersistentSampleMap::ImportSamples(std::optional<Sample> until_value) { +std::atomic<Count>* PersistentSampleMap::ImportSamples( + std::optional<Sample> until_value) { std::vector<PersistentMemoryAllocator::Reference> refs; PersistentSampleMapRecords* records = GetRecords(); while (!(refs = records->GetNextRecords(until_value)).empty()) {
diff --git a/base/metrics/persistent_sample_map.h b/base/metrics/persistent_sample_map.h index f8aec7f..8f955c25 100644 --- a/base/metrics/persistent_sample_map.h +++ b/base/metrics/persistent_sample_map.h
@@ -11,6 +11,7 @@ #include <stdint.h> +#include <atomic> #include <map> #include <memory> #include <optional> @@ -73,11 +74,12 @@ // Gets a pointer to a "count" corresponding to a given |value|. Returns NULL // if sample does not exist. - HistogramBase::Count* GetSampleCountStorage(HistogramBase::Sample value); + std::atomic<HistogramBase::Count>* GetSampleCountStorage( + HistogramBase::Sample value); // Gets a pointer to a "count" corresponding to a given |value|, creating // the sample (initialized to zero) if it does not already exists. - HistogramBase::Count* GetOrCreateSampleCountStorage( + std::atomic<HistogramBase::Count>* GetOrCreateSampleCountStorage( HistogramBase::Sample value); private: @@ -92,14 +94,14 @@ // currently available samples have been loaded. Pass a nullopt for // |until_value| to force the importing of all available samples (null will // always be returned in this case). - HistogramBase::Count* ImportSamples( + std::atomic<HistogramBase::Count>* ImportSamples( std::optional<HistogramBase::Sample> until_value); // All created/loaded sample values and their associated counts. The storage // for the actual Count numbers is owned by the |records_| object and its // underlying allocator. std::map<HistogramBase::Sample, - raw_ptr<HistogramBase::Count, CtnExperimental>> + raw_ptr<std::atomic<HistogramBase::Count>, CtnExperimental>> sample_counts_; // The allocator that manages histograms inside persistent memory. This is
diff --git a/base/metrics/sample_map_iterator.h b/base/metrics/sample_map_iterator.h index 56e66d3..1da0ea5 100644 --- a/base/metrics/sample_map_iterator.h +++ b/base/metrics/sample_map_iterator.h
@@ -7,19 +7,22 @@ #include <stdint.h> +#include <atomic> #include <type_traits> #include <utility> #include "base/check.h" +#include "base/memory/raw_ptr.h" #include "base/metrics/histogram_base.h" #include "base/metrics/histogram_samples.h" +#include "base/types/to_address.h" namespace base { // An iterator for going through a SampleMap. `MapT` is the underlying map type // that stores the counts. `support_extraction` should be true iff the caller -// wants this iterator to support extracting the values. -// TODO(pkasting): Combine with that for PersistentSampleMap. +// wants this iterator to support extracting the values. If the counts are +// pointers, accesses to them will be atomic; see `kUseAtomicOps` below. template <typename MapT, bool support_extraction> class SampleMapIterator : public SampleCountIterator { private: @@ -54,11 +57,6 @@ DCHECK(!Done()); *min = iter_->first; *max = int64_t{iter_->first} + 1; - // We do not have to do the following atomically -- if the caller needs - // thread safety, they should use a lock. And since this is in local memory, - // if a lock is used, we know the value would not be concurrently modified - // by a different process (in contrast to PersistentSampleMap, where the - // value in shared memory may be modified concurrently by a subprocess). if constexpr (support_extraction) { *count = Exchange(); } else { @@ -71,18 +69,37 @@ typename T::iterator, typename T::const_iterator>; + // If the counts are pointers, assume they may live in shared memory, which + // means accesses to them must be atomic, since other processes may attempt to + // concurrently modify their values. (Note that a lock wouldn't help here, + // since said other processes would not be aware of our lock.) If they are + // values, we don't bother with atomic ops; callers who want thread-safety can + // use locking. + static constexpr bool kUseAtomicOps = + IsPointerOrRawPtr<typename T::mapped_type>; + void SkipEmptyBuckets() { while (!Done() && Load() == 0) { ++iter_; } } - HistogramBase::Count Load() const { return iter_->second; } + HistogramBase::Count Load() const { + if constexpr (kUseAtomicOps) { + return iter_->second->load(std::memory_order_relaxed); + } else { + return iter_->second; + } + } HistogramBase::Count Exchange() const requires support_extraction { - return std::exchange(iter_->second, 0); + if constexpr (kUseAtomicOps) { + return iter_->second->exchange(0, std::memory_order_relaxed); + } else { + return std::exchange(iter_->second, 0); + } } I iter_;
diff --git a/base/process/process.h b/base/process/process.h index 2731161..bb97ed2 100644 --- a/base/process/process.h +++ b/base/process/process.h
@@ -298,6 +298,8 @@ #if BUILDFLAG(IS_APPLE) // Sets the priority of the current process to its default value. + // Ironically, non-App Nap compliant processes do not get this by default on + // Mac. static void SetCurrentTaskDefaultRole(); #endif // BUILDFLAG(IS_MAC)
diff --git a/base/process/process_mac.cc b/base/process/process_mac.cc index 9d0eb548..751311d 100644 --- a/base/process/process_mac.cc +++ b/base/process/process_mac.cc
@@ -24,12 +24,6 @@ namespace { -// Enables setting the task role of every child process to -// TASK_DEFAULT_APPLICATION. -BASE_FEATURE(kMacSetDefaultTaskRole, - "MacSetDefaultTaskRole", - FEATURE_ENABLED_BY_DEFAULT); - // Returns the `task_role_t` of the process whose task port is `task_port`. std::optional<task_role_t> GetTaskCategoryPolicyRole(mach_port_t task_port) { task_category_policy_data_t category_policy; @@ -231,10 +225,6 @@ // static void Process::SetCurrentTaskDefaultRole() { - if (!base::FeatureList::IsEnabled(kMacSetDefaultTaskRole)) { - return; - } - SetTaskCategoryPolicy(mach_task_self(), TASK_FOREGROUND_APPLICATION); // Set the QoS settings to tier 0, to match the default value given to App Nap
diff --git a/base/strings/string_util.h b/base/strings/string_util.h index 389aa0d..c965f1f 100644 --- a/base/strings/string_util.h +++ b/base/strings/string_util.h
@@ -4,11 +4,6 @@ // // This file defines utility functions for working with strings. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/40284755): Remove this and spanify to fix the errors. -#pragma allow_unsafe_buffers -#endif - #ifndef BASE_STRINGS_STRING_UTIL_H_ #define BASE_STRINGS_STRING_UTIL_H_ @@ -414,8 +409,8 @@ template <typename Char> requires(std::integral<Char>) constexpr bool IsAsciiWhitespace(Char c) { - // kWhitespaceASCII is a null-terminated string. - for (const char* cur = kWhitespaceASCII; *cur; ++cur) { + // SAFETY: kWhitespaceASCII is a NUL-terminated string. + for (const char* cur = kWhitespaceASCII; *cur; UNSAFE_BUFFERS(++cur)) { if (*cur == c) { return true; } @@ -504,8 +499,8 @@ template <typename Char> requires(sizeof(Char) > 1) constexpr bool IsUnicodeWhitespace(Char c) { - // kWhitespaceWide is a null-terminated string. - for (const auto* cur = kWhitespaceWide; *cur; ++cur) { + // SAFETY: kWhitespaceWide is a NUL-terminated string. + for (const auto* cur = kWhitespaceWide; *cur; UNSAFE_BUFFERS(++cur)) { if (static_cast<typename std::make_unsigned_t<wchar_t>>(*cur) == static_cast<typename std::make_unsigned_t<Char>>(c)) { return true;
diff --git a/base/strings/stringprintf.cc b/base/strings/stringprintf.cc index 0aa5558..71d77c5 100644 --- a/base/strings/stringprintf.cc +++ b/base/strings/stringprintf.cc
@@ -11,6 +11,7 @@ #include "base/logging.h" #include "base/scoped_clear_last_error.h" +#include "base/strings/span_printf.h" #include "base/strings/string_util.h" #include "build/build_config.h" @@ -32,7 +33,7 @@ va_copy(ap_copy, ap); base::ScopedClearLastError last_error; - int result = vsnprintf(stack_buf, std::size(stack_buf), format, ap_copy); + int result = VSpanPrintf(stack_buf, format, ap_copy); va_end(ap_copy); if (result >= 0 && static_cast<size_t>(result) < std::size(stack_buf)) { @@ -75,7 +76,7 @@ // NOTE: You can only use a va_list once. Since we're in a while loop, we // need to make a new copy each time so we don't use up the original. va_copy(ap_copy, ap); - result = vsnprintf(&mem_buf[0], mem_length, format, ap_copy); + result = VSpanPrintf(mem_buf, format, ap_copy); va_end(ap_copy); if ((result >= 0) && (static_cast<size_t>(result) < mem_length)) {
diff --git a/base/trace_event/memory_dump_manager.cc b/base/trace_event/memory_dump_manager.cc index f5b0ea7..0f6ec22 100644 --- a/base/trace_event/memory_dump_manager.cc +++ b/base/trace_event/memory_dump_manager.cc
@@ -19,7 +19,7 @@ #include "base/debug/stack_trace.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "base/strings/string_util.h" +#include "base/strings/span_printf.h" #include "base/task/sequenced_task_runner.h" #include "base/task/single_thread_task_runner.h" #include "base/threading/thread.h" @@ -307,7 +307,7 @@ void MemoryDumpManager::CreateProcessDump(const MemoryDumpRequestArgs& args, ProcessMemoryDumpCallback callback) { char guid_str[20]; - snprintf(guid_str, std::size(guid_str), "0x%" PRIx64, args.dump_guid); + base::SpanPrintf(guid_str, "0x%" PRIx64, args.dump_guid); TRACE_EVENT_NESTABLE_ASYNC_BEGIN1(kTraceCategory, "ProcessMemoryDump", TRACE_ID_LOCAL(args.dump_guid), "dump_guid", TRACE_STR_COPY(guid_str));
diff --git a/base/win/hardware_check.cc b/base/win/hardware_check.cc new file mode 100644 index 0000000..06c96b3 --- /dev/null +++ b/base/win/hardware_check.cc
@@ -0,0 +1,128 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/hardware_check.h" + +#include <windows.h> + +#include <tbs.h> + +#include <string_view> + +#include "base/cpu.h" +#include "base/files/file_path.h" +#include "base/path_service.h" +#include "base/strings/string_util.h" +#include "base/system/sys_info.h" +#include "base/win/registry.h" +#include "base/win/windows_version.h" +#include "build/build_config.h" + +namespace base::win { + +namespace { + +bool IsWin11SupportedProcessor(const CPU& cpu_info, + std::string_view vendor_name) { +#if defined(ARCH_CPU_X86_FAMILY) + if (vendor_name == "GenuineIntel") { + // Windows 11 is supported on Intel 8th Gen and higher models + // CPU model ID's can be referenced from the following file in + // the kernel source: arch/x86/include/asm/intel-family.h + if (cpu_info.family() != 0x06 || cpu_info.model() <= 0x5F || + (cpu_info.model() == 0x8E && + (cpu_info.stepping() < 9 || cpu_info.stepping() > 12)) || + (cpu_info.model() == 0x9E && + (cpu_info.stepping() < 10 || cpu_info.stepping() > 13))) { + return false; + } + return true; + } + + if (vendor_name == "AuthenticAMD") { + // Windows 11 is supported on AMD Zen+ and higher models + if (cpu_info.family() < 0x17 || + (cpu_info.family() == 0x17 && + (cpu_info.model() == 0x1 || cpu_info.model() == 0x11))) { + return false; + } + return true; + } +#elif defined(ARCH_CPU_ARM_FAMILY) + if (vendor_name == "Qualcomm Technologies Inc") { + // Windows 11 is supported on all Qualcomm models with the exception + // of 1st Gen Compute Platforms due to lack of TPM 2.0 + return true; + } +#else +#error Unsupported CPU architecture +#endif + return false; +} + +bool IsUEFISecureBootEnabled() { + static constexpr wchar_t kSecureBootRegPath[] = + L"SYSTEM\\CurrentControlSet\\Control\\SecureBoot\\State"; + + RegKey key; + auto result = + key.Open(HKEY_LOCAL_MACHINE, kSecureBootRegPath, KEY_QUERY_VALUE); + if (result != ERROR_SUCCESS) { + return false; + } + + DWORD secure_boot = 0; + result = key.ReadValueDW(L"UEFISecureBootEnabled", &secure_boot); + + return result == ERROR_SUCCESS && secure_boot == 1; +} + +bool IsTPM20Supported() { + TPM_DEVICE_INFO tpm_info{}; + + if (::Tbsi_GetDeviceInfo(sizeof(tpm_info), &tpm_info) != TBS_SUCCESS) { + return false; + } + + return tpm_info.tpmVersion >= TPM_VERSION_20; +} + +} // namespace + +bool IsWin11UpgradeEligible() { + static constexpr int64_t kMinTotalDiskSpace = 64 * 1024 * 1024; + static constexpr uint64_t kMinTotalPhysicalMemory = 4 * 1024 * 1024; + + static const bool is_win11_upgrade_eligible = [] { + if (!IsWin11SupportedProcessor( + CPU(), OSInfo::GetInstance()->processor_vendor_name())) { + return false; + } + + if (SysInfo::AmountOfPhysicalMemory() < kMinTotalPhysicalMemory) { + return false; + } + + FilePath system_path; + if (PathService::Get(DIR_SYSTEM, &system_path) && + SysInfo::AmountOfTotalDiskSpace( + FilePath(system_path.GetComponents()[0])) < kMinTotalDiskSpace) { + return false; + } + + if (!IsUEFISecureBootEnabled()) { + return false; + } + + if (!IsTPM20Supported()) { + return false; + } + + return true; + }(); + + return is_win11_upgrade_eligible; +} + +} // namespace base::win
diff --git a/base/win/hardware_check.h b/base/win/hardware_check.h new file mode 100644 index 0000000..5b0c85f0 --- /dev/null +++ b/base/win/hardware_check.h
@@ -0,0 +1,19 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef BASE_WIN_HARDWARE_CHECK_H_ +#define BASE_WIN_HARDWARE_CHECK_H_ + +#include "base/base_export.h" + +namespace base::win { + +// Returns true if the hardware supports Win11. It is intended to be called +// on OS versions below Win11 and validates against minimum requirements. +// This must be called from a context that allows I/O operations. +BASE_EXPORT bool IsWin11UpgradeEligible(); + +} // namespace base::win + +#endif // BASE_WIN_HARDWARE_CHECK_H_
diff --git a/base/win/hardware_check_unittest.cc b/base/win/hardware_check_unittest.cc new file mode 100644 index 0000000..5e58ef00 --- /dev/null +++ b/base/win/hardware_check_unittest.cc
@@ -0,0 +1,17 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/hardware_check.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace base::win { + +TEST(IsWin11UpgradeEligible, ExpectNoCrash) { + // It's not worthwhile to check the validity of the return value + // so just check for crashes. + IsWin11UpgradeEligible(); +} + +} // namespace base::win
diff --git a/base/win/scoped_gdi_object.cc b/base/win/scoped_gdi_object.cc new file mode 100644 index 0000000..224403e9 --- /dev/null +++ b/base/win/scoped_gdi_object.cc
@@ -0,0 +1,29 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/win/scoped_gdi_object.h" + +#include <windows.h> + +namespace base::win::internal { + +#define DEFINE_TRAIT_SPECIALIZATION(T) \ + template <> \ + void ScopedGDIObjectTraits<T>::Free(T object) { \ + ::DeleteObject(object); \ + } +DEFINE_TRAIT_SPECIALIZATION(HBITMAP) +DEFINE_TRAIT_SPECIALIZATION(HBRUSH) +DEFINE_TRAIT_SPECIALIZATION(HFONT) +DEFINE_TRAIT_SPECIALIZATION(HPEN) +DEFINE_TRAIT_SPECIALIZATION(HRGN) +#undef DEFINE_TRAIT_SPECIALIZATION + +// `HICON` must be freed via `::DestroyIcon()` instead. +template <> +void ScopedGDIObjectTraits<HICON>::Free(HICON object) { + ::DestroyIcon(object); +} + +} // namespace base::win::internal
diff --git a/base/win/scoped_gdi_object.h b/base/win/scoped_gdi_object.h index 2def58fc..6c64e8ac 100644 --- a/base/win/scoped_gdi_object.h +++ b/base/win/scoped_gdi_object.h
@@ -5,27 +5,36 @@ #ifndef BASE_WIN_SCOPED_GDI_OBJECT_H_ #define BASE_WIN_SCOPED_GDI_OBJECT_H_ -#include <windows.h> - +#include "base/base_export.h" #include "base/scoped_generic.h" +#include "base/types/always_false.h" +#include "base/win/win_handle_types.h" -namespace base { -namespace win { +namespace base::win { namespace internal { -template <class T> -struct ScopedGDIObjectTraits { +template <typename T> +struct BASE_EXPORT ScopedGDIObjectTraits { static T InvalidValue() { return nullptr; } - static void Free(T object) { DeleteObject(object); } + static void Free(T object) { + static_assert(base::AlwaysFalse<T>, "Explicitly forward-declare this T"); + } }; -// An explicit specialization for HICON because we have to call DestroyIcon() -// instead of DeleteObject() for HICON. -template <> -void inline ScopedGDIObjectTraits<HICON>::Free(HICON icon) { - DestroyIcon(icon); -} +// Forward-declare all used specializations and define them in the .cc file. +// This avoids pulling `<windows.h>` transiently into every file that +// `#include`s this one. +#define DECLARE_TRAIT_SPECIALIZATION(T) \ + template <> \ + void ScopedGDIObjectTraits<T>::Free(T object); +DECLARE_TRAIT_SPECIALIZATION(HBITMAP) +DECLARE_TRAIT_SPECIALIZATION(HBRUSH) +DECLARE_TRAIT_SPECIALIZATION(HFONT) +DECLARE_TRAIT_SPECIALIZATION(HICON) +DECLARE_TRAIT_SPECIALIZATION(HPEN) +DECLARE_TRAIT_SPECIALIZATION(HRGN) +#undef DECLARE_TRAIT_SPECIALIZATION } // namespace internal @@ -39,7 +48,6 @@ typedef ScopedGDIObject<HFONT> ScopedHFONT; typedef ScopedGDIObject<HICON> ScopedHICON; -} // namespace win -} // namespace base +} // namespace base::win #endif // BASE_WIN_SCOPED_GDI_OBJECT_H_
diff --git a/base/win/win_handle_types_list.inc b/base/win/win_handle_types_list.inc index 2241211..917c4b28 100644 --- a/base/win/win_handle_types_list.inc +++ b/base/win/win_handle_types_list.inc
@@ -12,14 +12,19 @@ // via specific pointee types declared in //base/win/windows_types.h // (e.g. `HDC` points to a fake/forward-declared `HDC__` struct). +CHROME_WINDOWS_HANDLE_TYPE(HBITMAP) +CHROME_WINDOWS_HANDLE_TYPE(HBRUSH) CHROME_WINDOWS_HANDLE_TYPE(HDC) CHROME_WINDOWS_HANDLE_TYPE(HDESK) +CHROME_WINDOWS_HANDLE_TYPE(HFONT) CHROME_WINDOWS_HANDLE_TYPE(HGLRC) CHROME_WINDOWS_HANDLE_TYPE(HICON) CHROME_WINDOWS_HANDLE_TYPE(HINSTANCE) CHROME_WINDOWS_HANDLE_TYPE(HKEY) CHROME_WINDOWS_HANDLE_TYPE(HKL) CHROME_WINDOWS_HANDLE_TYPE(HMENU) +CHROME_WINDOWS_HANDLE_TYPE(HPEN) +CHROME_WINDOWS_HANDLE_TYPE(HRGN) CHROME_WINDOWS_HANDLE_TYPE(HWINSTA) CHROME_WINDOWS_HANDLE_TYPE(HWND) CHROME_WINDOWS_HANDLE_TYPE(HMONITOR)
diff --git a/base/win/windows_version.cc b/base/win/windows_version.cc index 7ff3d8a0..42c07eb 100644 --- a/base/win/windows_version.cc +++ b/base/win/windows_version.cc
@@ -333,9 +333,9 @@ std::string OSInfo::processor_model_name() { if (processor_model_name_.empty()) { - const wchar_t kProcessorNameString[] = + static constexpr wchar_t kProcessorNameString[] = L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; - RegKey key(HKEY_LOCAL_MACHINE, kProcessorNameString, KEY_READ); + RegKey key(HKEY_LOCAL_MACHINE, kProcessorNameString, KEY_QUERY_VALUE); std::wstring value; key.ReadValue(L"ProcessorNameString", &value); processor_model_name_ = WideToUTF8(value); @@ -343,6 +343,18 @@ return processor_model_name_; } +std::string OSInfo::processor_vendor_name() { + if (processor_vendor_name_.empty()) { + static constexpr wchar_t kVendorNameString[] = + L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; + RegKey key(HKEY_LOCAL_MACHINE, kVendorNameString, KEY_QUERY_VALUE); + std::wstring value; + key.ReadValue(L"VendorIdentifier", &value); + processor_vendor_name_ = WideToUTF8(value); + } + return processor_vendor_name_; +} + bool OSInfo::IsWindowsNSku() const { switch (os_type_) { case PRODUCT_BUSINESS_N:
diff --git a/base/win/windows_version.h b/base/win/windows_version.h index 5c407873..ef242e6d1 100644 --- a/base/win/windows_version.h +++ b/base/win/windows_version.h
@@ -165,8 +165,9 @@ return allocation_granularity_; } - // Processor name as read from registry. + // Processor info as read from registry. std::string processor_model_name(); + std::string processor_vendor_name(); // Returns the "ReleaseId" (Windows 10 release number) from the registry. const std::string& release_id() const LIFETIME_BOUND { return release_id_; } @@ -246,6 +247,7 @@ WowProcessMachine wow_process_machine_; WowNativeMachine wow_native_machine_; std::string processor_model_name_; + std::string processor_vendor_name_; DWORD os_type_; };
diff --git a/build/config/unsafe_buffers_paths.txt b/build/config/unsafe_buffers_paths.txt index aed5efd..fc702d0 100644 --- a/build/config/unsafe_buffers_paths.txt +++ b/build/config/unsafe_buffers_paths.txt
@@ -74,11 +74,9 @@ -testing/iossim/ -third_party/ +third_party/blink/ -+third_party/pdfium/core/ -+third_party/pdfium/fpdfsdk/ -+third_party/pdfium/fxbarcode/ -+third_party/pdfium/fxjs/ -+third_party/pdfium/xfa/ ++third_party/pdfium/ +-third_party/pdfium/testing/ +-third_party/pdfium/third_party/ -tools/ -url/third_party/ -v8/
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn index 9928e76832..9d6474d 100644 --- a/build/config/win/BUILD.gn +++ b/build/config/win/BUILD.gn
@@ -445,6 +445,7 @@ "/DELAYLOAD:setupapi.dll", "/DELAYLOAD:shell32.dll", "/DELAYLOAD:shlwapi.dll", + "/DELAYLOAD:tbs.dll", "/DELAYLOAD:uiautomationcore.dll", "/DELAYLOAD:urlmon.dll", "/DELAYLOAD:user32.dll",
diff --git a/cc/BUILD.gn b/cc/BUILD.gn index c1eb289a..9d6c8405 100644 --- a/cc/BUILD.gn +++ b/cc/BUILD.gn
@@ -631,6 +631,8 @@ "test/stub_layer_tree_host_single_thread_client.h", "test/task_graph_runner_test_template.cc", "test/task_graph_runner_test_template.h", + "test/test_client_shared_image_interface.cc", + "test/test_client_shared_image_interface.h", "test/test_hooks.cc", "test/test_hooks.h", "test/test_layer_tree_frame_sink.cc", @@ -680,6 +682,7 @@ "//gpu/command_buffer/client:raster", "//gpu/command_buffer/common", "//gpu/ipc:gl_in_process_context", + "//gpu/ipc/common:test_support", "//gpu/ipc/service", "//gpu/skia_bindings", "//media",
diff --git a/cc/animation/keyframe_model.cc b/cc/animation/keyframe_model.cc index 9395290..daecfa9 100644 --- a/cc/animation/keyframe_model.cc +++ b/cc/animation/keyframe_model.cc
@@ -12,7 +12,7 @@ #include "base/memory/ptr_util.h" #include "base/numerics/safe_conversions.h" -#include "base/strings/string_util.h" +#include "base/strings/span_printf.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "cc/trees/target_property.h" @@ -140,8 +140,8 @@ void KeyframeModel::SetRunState(RunState new_run_state, base::TimeTicks monotonic_time) { char name_buffer[256]; - base::snprintf(name_buffer, sizeof(name_buffer), "%s-%d-%d", - curve()->TypeName(), TargetProperty(), group_); + base::SpanPrintf(name_buffer, "%s-%d-%d", curve()->TypeName(), + TargetProperty(), group_); bool is_waiting_to_start = run_state() == WAITING_FOR_TARGET_AVAILABILITY || run_state() == STARTING; @@ -165,8 +165,8 @@ } char state_buffer[256]; - base::snprintf(state_buffer, sizeof(state_buffer), "%s->%s", - old_run_state_name.c_str(), new_run_state_name.c_str()); + base::SpanPrintf(state_buffer, "%s->%s", old_run_state_name.c_str(), + new_run_state_name.c_str()); TRACE_EVENT_INSTANT2( "cc", "ElementAnimations::SetRunState", TRACE_EVENT_SCOPE_THREAD, "Name",
diff --git a/cc/layers/texture_layer_unittest.cc b/cc/layers/texture_layer_unittest.cc index 90849035..c74b6413 100644 --- a/cc/layers/texture_layer_unittest.cc +++ b/cc/layers/texture_layer_unittest.cc
@@ -674,9 +674,9 @@ !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; return std::make_unique<TestLayerTreeFrameSink>( compositor_context_provider, std::move(worker_context_provider), - gpu_memory_buffer_manager(), renderer_settings, &debug_settings_, - task_runner_provider(), synchronous_composite, disable_display_vsync, - refresh_rate); + /*shared_image_interface=*/nullptr, gpu_memory_buffer_manager(), + renderer_settings, &debug_settings_, task_runner_provider(), + synchronous_composite, disable_display_vsync, refresh_rate); } void AdvanceTestCase() { @@ -1505,9 +1505,10 @@ !HasImplThread() && !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; auto sink = std::make_unique<TestLayerTreeFrameSink>( - nullptr, nullptr, gpu_memory_buffer_manager(), renderer_settings, - &debug_settings_, task_runner_provider(), synchronous_composite, - disable_display_vsync, refresh_rate); + nullptr, nullptr, /*shared_image_interface=*/nullptr, + gpu_memory_buffer_manager(), renderer_settings, &debug_settings_, + task_runner_provider(), synchronous_composite, disable_display_vsync, + refresh_rate); frame_sink_ = sink.get(); num_frame_sinks_created_++; shared_image_interface_ = frame_sink_->GetSharedImageInterface();
diff --git a/cc/raster/raster_buffer_provider_unittest.cc b/cc/raster/raster_buffer_provider_unittest.cc index 72bda60..39ce1ad 100644 --- a/cc/raster/raster_buffer_provider_unittest.cc +++ b/cc/raster/raster_buffer_provider_unittest.cc
@@ -252,8 +252,8 @@ } ResourcePool::InUsePoolResource AllocateResource(const gfx::Size& size) { - return pool_->AcquireResource(size, viz::SinglePlaneFormat::kRGBA_8888, - gfx::ColorSpace()); + auto format = raster_buffer_provider_->GetFormat(); + return pool_->AcquireResource(size, format, gfx::ColorSpace()); } void AppendTask(unsigned id,
diff --git a/cc/test/DEPS b/cc/test/DEPS index 13da72d..b4130c0 100644 --- a/cc/test/DEPS +++ b/cc/test/DEPS
@@ -36,9 +36,8 @@ "layer_tree_test\.cc": [ "+gpu/config/gpu_switches.h", ], - "test_layer_tree_frame_sink\.h": [ + "test_layer_tree_frame_sink\.cc": [ "+gpu/command_buffer/service/shared_image/shared_image_manager.h", - "+gpu/command_buffer/service/sync_point_manager.h", "+gpu/command_buffer/service/scheduler.h", ], }
diff --git a/cc/test/fake_layer_tree_frame_sink.cc b/cc/test/fake_layer_tree_frame_sink.cc index 82ea47e1..be95c0e 100644 --- a/cc/test/fake_layer_tree_frame_sink.cc +++ b/cc/test/fake_layer_tree_frame_sink.cc
@@ -11,6 +11,7 @@ #include "base/memory/scoped_refptr.h" #include "base/task/single_thread_task_runner.h" #include "cc/test/fake_layer_context.h" +#include "cc/test/test_client_shared_image_interface.h" #include "cc/tiles/image_decode_cache_utils.h" #include "cc/trees/layer_tree_frame_sink_client.h" #include "cc/trees/raster_context_provider_wrapper.h" @@ -19,6 +20,9 @@ #include "components/viz/common/resources/returned_resource.h" #include "components/viz/test/begin_frame_args_test.h" #include "gpu/ipc/client/client_shared_image_interface.h" +#include "gpu/ipc/client/gpu_channel_host.h" +#include "gpu/ipc/common/gpu_channel.mojom.h" +#include "gpu/ipc/common/mock_gpu_channel.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -52,7 +56,8 @@ : nullptr, base::SingleThreadTaskRunner::GetCurrentDefault(), nullptr, - /*shared_image_interface=*/nullptr) { + base::MakeRefCounted<TestClientSharedImageInterface>( + base::MakeRefCounted<gpu::TestSharedImageInterface>())) { gpu_memory_buffer_manager_ = context_provider_ ? &test_gpu_memory_buffer_manager_ : nullptr; }
diff --git a/cc/test/layer_tree_pixel_test.cc b/cc/test/layer_tree_pixel_test.cc index 5c42dab..7cf5e20 100644 --- a/cc/test/layer_tree_pixel_test.cc +++ b/cc/test/layer_tree_pixel_test.cc
@@ -79,6 +79,8 @@ scoped_refptr<viz::RasterContextProvider>) { scoped_refptr<viz::TestInProcessContextProvider> compositor_context_provider; scoped_refptr<viz::TestInProcessContextProvider> worker_context_provider; + gpu::SharedImageInterface* shared_image_interface = nullptr; + if (!use_software_renderer()) { compositor_context_provider = base::MakeRefCounted<viz::TestInProcessContextProvider>( @@ -98,6 +100,7 @@ case TestRasterType::kBitmap: NOTREACHED(); } + worker_context_provider = base::MakeRefCounted<viz::TestInProcessContextProvider>( worker_ri_type, /*support_locking=*/true); @@ -114,9 +117,17 @@ } DCHECK_EQ(result, gpu::ContextResult::kSuccess); } else { + context_provider_sw_ = + base::MakeRefCounted<viz::TestInProcessContextProvider>( + viz::TestContextType::kSoftwareRaster, /*support_locking=*/false); + gpu::ContextResult result = context_provider_sw_->BindToCurrentSequence(); + DCHECK_EQ(result, gpu::ContextResult::kSuccess); + + shared_image_interface = context_provider_sw_->SharedImageInterface(); max_texture_size_ = layer_tree_host()->GetSettings().max_render_buffer_bounds_for_sw; } + static constexpr bool disable_display_vsync = false; bool synchronous_composite = !HasImplThread() && @@ -127,9 +138,9 @@ test_settings.dont_round_texture_sizes_for_pixel_tests = true; auto delegating_output_surface = std::make_unique<TestLayerTreeFrameSink>( compositor_context_provider, worker_context_provider, - gpu_memory_buffer_manager(), test_settings, &debug_settings_, - task_runner_provider(), synchronous_composite, disable_display_vsync, - refresh_rate); + shared_image_interface, gpu_memory_buffer_manager(), test_settings, + &debug_settings_, task_runner_provider(), synchronous_composite, + disable_display_vsync, refresh_rate); delegating_output_surface->SetEnlargePassTextureAmount( enlarge_texture_amount_); return delegating_output_surface;
diff --git a/cc/test/layer_tree_pixel_test.h b/cc/test/layer_tree_pixel_test.h index 52299eb..b8852fc 100644 --- a/cc/test/layer_tree_pixel_test.h +++ b/cc/test/layer_tree_pixel_test.h
@@ -30,6 +30,7 @@ namespace viz { class CopyOutputRequest; class CopyOutputResult; +class TestInProcessContextProvider; } namespace cc { @@ -137,6 +138,7 @@ int pending_texture_mailbox_callbacks_; gfx::Size enlarge_texture_amount_; int max_texture_size_ = 0; + scoped_refptr<viz::TestInProcessContextProvider> context_provider_sw_; // Used to create SkiaOutputSurfaceImpl. std::unique_ptr<base::test::ScopedFeatureList> scoped_feature_list_;
diff --git a/cc/test/layer_tree_test.cc b/cc/test/layer_tree_test.cc index fc5a06e..1fe4e00f 100644 --- a/cc/test/layer_tree_test.cc +++ b/cc/test/layer_tree_test.cc
@@ -82,6 +82,7 @@ bool use_software_renderer) : TestLayerTreeFrameSink(std::move(compositor_context_provider), std::move(worker_context_provider), + /*shared_image_interface=*/nullptr, gpu_memory_buffer_manager, renderer_settings, debug_settings, @@ -1257,11 +1258,17 @@ use_software_renderer()); } + gpu::SharedImageInterface* shared_image_interface = nullptr; + if (!compositor_context_provider) { + context_provider_sw_ = viz::TestContextProvider::CreateRaster(); + shared_image_interface = context_provider_sw_->SharedImageInterface(); + } + return std::make_unique<TestLayerTreeFrameSink>( compositor_context_provider, std::move(worker_context_provider), - gpu_memory_buffer_manager(), renderer_settings, &debug_settings_, - task_runner_provider(), synchronous_composite, disable_display_vsync, - refresh_rate, begin_frame_source_); + shared_image_interface, gpu_memory_buffer_manager(), renderer_settings, + &debug_settings_, task_runner_provider(), synchronous_composite, + disable_display_vsync, refresh_rate, begin_frame_source_); } std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController>
diff --git a/cc/test/layer_tree_test.h b/cc/test/layer_tree_test.h index b5c974b..039ff3f 100644 --- a/cc/test/layer_tree_test.h +++ b/cc/test/layer_tree_test.h
@@ -298,7 +298,7 @@ std::unique_ptr<TestTaskGraphRunner> task_graph_runner_; base::CancelableOnceClosure timeout_; base::OnceClosure quit_closure_; - scoped_refptr<viz::TestContextProvider> compositor_contexts_; + scoped_refptr<viz::TestContextProvider> context_provider_sw_; bool skip_allocate_initial_local_surface_id_ = false; viz::ParentLocalSurfaceIdAllocator allocator_; base::WeakPtr<LayerTreeTest> main_thread_weak_ptr_;
diff --git a/cc/test/test_client_shared_image_interface.cc b/cc/test/test_client_shared_image_interface.cc new file mode 100644 index 0000000..f15908c --- /dev/null +++ b/cc/test/test_client_shared_image_interface.cc
@@ -0,0 +1,44 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/test/test_client_shared_image_interface.h" + +#include <utility> + +namespace cc { + +TestGpuChannelHost::TestGpuChannelHost() + : GpuChannelHost(0 /* channel_id */, + gpu::GPUInfo(), + gpu::GpuFeatureInfo(), + gpu::SharedImageCapabilities(), + mojo::ScopedMessagePipeHandle( + mojo::MessagePipeHandle(mojo::kInvalidHandleValue))) {} + +TestGpuChannelHost::~TestGpuChannelHost() = default; + +gpu::mojom::GpuChannel& TestGpuChannelHost::GetGpuChannel() { + return gpu_channel_; +} + +TestClientSharedImageInterface::TestClientSharedImageInterface( + scoped_refptr<gpu::SharedImageInterface> shared_image_interface) + : gpu::ClientSharedImageInterface( + nullptr, + base::MakeRefCounted<TestGpuChannelHost>()), + shared_image_interface_(std::move(shared_image_interface)) {} + +TestClientSharedImageInterface::~TestClientSharedImageInterface() = default; + +gpu::SyncToken TestClientSharedImageInterface::GenVerifiedSyncToken() { + return shared_image_interface_->GenVerifiedSyncToken(); +} + +gpu::SharedImageInterface::SharedImageMapping +TestClientSharedImageInterface::CreateSharedImage( + const gpu::SharedImageInfo& si_info) { + return shared_image_interface_->CreateSharedImage(si_info); +} + +} // namespace cc
diff --git a/cc/test/test_client_shared_image_interface.h b/cc/test/test_client_shared_image_interface.h new file mode 100644 index 0000000..12c919e --- /dev/null +++ b/cc/test/test_client_shared_image_interface.h
@@ -0,0 +1,44 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_TEST_TEST_CLIENT_SHARED_IMAGE_INTERFACE_H_ +#define CC_TEST_TEST_CLIENT_SHARED_IMAGE_INTERFACE_H_ + +#include "gpu/command_buffer/client/shared_image_interface.h" +#include "gpu/ipc/client/client_shared_image_interface.h" +#include "gpu/ipc/client/gpu_channel_host.h" +#include "gpu/ipc/common/gpu_channel.mojom.h" +#include "gpu/ipc/common/mock_gpu_channel.h" +#include "mojo/public/cpp/system/platform_handle.h" + +namespace cc { + +class TestGpuChannelHost : public gpu::GpuChannelHost { + public: + TestGpuChannelHost(); + + gpu::mojom::GpuChannel& GetGpuChannel() override; + + protected: + ~TestGpuChannelHost() override; + gpu::MockGpuChannel gpu_channel_; +}; + +class TestClientSharedImageInterface : public gpu::ClientSharedImageInterface { + public: + TestClientSharedImageInterface( + scoped_refptr<gpu::SharedImageInterface> shared_image_interface); + gpu::SyncToken GenVerifiedSyncToken() override; + + gpu::SharedImageInterface::SharedImageMapping CreateSharedImage( + const gpu::SharedImageInfo& si_info) override; + + protected: + ~TestClientSharedImageInterface() override; + + scoped_refptr<gpu::SharedImageInterface> shared_image_interface_; +}; + +} // namespace cc +#endif // CC_TEST_TEST_CLIENT_SHARED_IMAGE_INTERFACE_H_
diff --git a/cc/test/test_layer_tree_frame_sink.cc b/cc/test/test_layer_tree_frame_sink.cc index e9afd71..d878c33 100644 --- a/cc/test/test_layer_tree_frame_sink.cc +++ b/cc/test/test_layer_tree_frame_sink.cc
@@ -12,19 +12,21 @@ #include "base/functional/bind.h" #include "base/task/single_thread_task_runner.h" +#include "cc/test/test_client_shared_image_interface.h" #include "cc/trees/layer_tree_frame_sink_client.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/task_runner_provider.h" #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" -#include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/service/display/direct_renderer.h" #include "components/viz/service/display/output_surface.h" #include "components/viz/service/display/overlay_processor_stub.h" #include "components/viz/service/display/skia_output_surface.h" #include "components/viz/service/frame_sinks/compositor_frame_sink_support.h" +#include "components/viz/test/test_gpu_service_holder.h" +#include "gpu/command_buffer/service/scheduler.h" +#include "gpu/command_buffer/service/shared_image/shared_image_manager.h" #include "gpu/ipc/client/client_shared_image_interface.h" -#include "mojo/public/cpp/system/platform_handle.h" namespace cc { @@ -33,6 +35,7 @@ TestLayerTreeFrameSink::TestLayerTreeFrameSink( scoped_refptr<viz::RasterContextProvider> compositor_context_provider, scoped_refptr<viz::RasterContextProvider> worker_context_provider, + scoped_refptr<gpu::SharedImageInterface> shared_image_interface, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const viz::RendererSettings& renderer_settings, const viz::DebugRendererSettings* const debug_settings, @@ -54,23 +57,26 @@ ? task_runner_provider->ImplThreadTaskRunner() : task_runner_provider->MainThreadTaskRunner(), gpu_memory_buffer_manager, - /*shared_image_interface=*/nullptr), + shared_image_interface + ? base::MakeRefCounted<TestClientSharedImageInterface>( + shared_image_interface) + : nullptr), synchronous_composite_(synchronous_composite), disable_display_vsync_(disable_display_vsync), renderer_settings_(renderer_settings), debug_settings_(debug_settings), refresh_rate_(refresh_rate), frame_sink_id_(kLayerTreeFrameSinkId), - shared_image_manager_( - std::make_unique<gpu::SharedImageManager>(/*thread_safe=*/true)), - sync_point_manager_(std::make_unique<gpu::SyncPointManager>()), - gpu_scheduler_( - std::make_unique<gpu::Scheduler>(sync_point_manager_.get())), parent_local_surface_id_allocator_( new viz::ParentLocalSurfaceIdAllocator), client_provided_begin_frame_source_(begin_frame_source), external_begin_frame_source_(this), - task_runner_provider_(task_runner_provider) { + task_runner_provider_(task_runner_provider), + shared_image_interface_provider_( + shared_image_interface + ? std::make_unique<viz::TestSharedImageInterfaceProvider>( + shared_image_interface) + : std::make_unique<viz::TestSharedImageInterfaceProvider>()) { parent_local_surface_id_allocator_->GenerateId(); } @@ -88,11 +94,11 @@ if (!LayerTreeFrameSink::BindToClient(client)) return false; - shared_bitmap_manager_ = std::make_unique<viz::TestSharedBitmapManager>(); frame_sink_manager_ = std::make_unique<viz::FrameSinkManagerImpl>( - viz::FrameSinkManagerImpl::InitParams(shared_bitmap_manager_.get())); + viz::FrameSinkManagerImpl::InitParams( + /*shared_bitmap_manager_.get()*/ nullptr)); frame_sink_manager_->SetSharedImageInterfaceProviderForTest( - &shared_image_interface_provider_); + shared_image_interface_provider_.get()); std::unique_ptr<viz::DisplayCompositorMemoryAndTaskController> display_controller; @@ -138,9 +144,19 @@ // gpu::GpuTaskSchedulerHelper alive for output surface to use, so there is no // need to pass in an gpu::GpuTaskSchedulerHelper here. + gpu::SharedImageManager* shared_image_manager = nullptr; + gpu::Scheduler* gpu_scheduler = nullptr; + + if (!LayerTreeFrameSink::context_provider()) { + viz::GpuServiceImpl* gpu_service = + viz::TestGpuServiceHolder::GetInstance()->gpu_service(); + shared_image_manager = gpu_service->shared_image_manager(); + gpu_scheduler = gpu_service->gpu_scheduler(); + } + display_ = std::make_unique<viz::Display>( - shared_bitmap_manager_.get(), shared_image_manager_.get(), - gpu_scheduler_.get(), renderer_settings_, debug_settings_, frame_sink_id_, + /*shared_bitmap_manager_.get()*/ nullptr, shared_image_manager, + gpu_scheduler, renderer_settings_, debug_settings_, frame_sink_id_, std::move(display_controller), std::move(display_output_surface), std::move(overlay_processor), std::move(scheduler), compositor_task_runner_); @@ -177,9 +193,6 @@ // SharedBitmapId that has been reported from the client. Since the client is // gone that memory can be freed. If we don't then it would leak. DebugScopedSetImplThread impl(task_runner_provider_); - for (const auto& id : owned_bitmaps_) - shared_bitmap_manager_->ChildDeletedSharedBitmap(id); - owned_bitmaps_.clear(); if (display_begin_frame_source_) { frame_sink_manager_->UnregisterBeginFrameSource( @@ -192,7 +205,6 @@ begin_frame_source_ = nullptr; parent_local_surface_id_allocator_ = nullptr; frame_sink_manager_ = nullptr; - shared_bitmap_manager_ = nullptr; test_client_ = nullptr; LayerTreeFrameSink::DetachFromClient(); } @@ -250,17 +262,10 @@ void TestLayerTreeFrameSink::DidAllocateSharedBitmap( base::ReadOnlySharedMemoryRegion region, const viz::SharedBitmapId& id) { - DebugScopedSetImplThread impl(task_runner_provider_); - bool ok = - shared_bitmap_manager_->ChildAllocatedSharedBitmap(region.Map(), id); - DCHECK(ok); - owned_bitmaps_.insert(id); } void TestLayerTreeFrameSink::DidDeleteSharedBitmap( const viz::SharedBitmapId& id) { - shared_bitmap_manager_->ChildDeletedSharedBitmap(id); - owned_bitmaps_.erase(id); } void TestLayerTreeFrameSink::DidReceiveCompositorFrameAck(
diff --git a/cc/test/test_layer_tree_frame_sink.h b/cc/test/test_layer_tree_frame_sink.h index ad95a20e..6cff357 100644 --- a/cc/test/test_layer_tree_frame_sink.h +++ b/cc/test/test_layer_tree_frame_sink.h
@@ -20,18 +20,9 @@ #include "components/viz/service/display/display.h" #include "components/viz/service/display/display_client.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" -#include "components/viz/service/frame_sinks/shared_image_interface_provider.h" -#include "components/viz/test/test_shared_bitmap_manager.h" #include "components/viz/test/test_shared_image_interface_provider.h" -#include "gpu/command_buffer/service/scheduler.h" -#include "gpu/command_buffer/service/shared_image/shared_image_manager.h" -#include "gpu/command_buffer/service/sync_point_manager.h" #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" -namespace gpu { -class Scheduler; -} // namespace gpu - namespace viz { class CompositorFrameSinkSupport; } // namespace viz @@ -73,6 +64,7 @@ TestLayerTreeFrameSink( scoped_refptr<viz::RasterContextProvider> compositor_context_provider, scoped_refptr<viz::RasterContextProvider> worker_context_provider, + scoped_refptr<gpu::SharedImageInterface> shared_image_interface, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const viz::RendererSettings& renderer_settings, const viz::DebugRendererSettings* debug_settings, @@ -140,7 +132,7 @@ viz::mojom::CompositorFrameSinkType* type) override; gpu::SharedImageInterface* GetSharedImageInterface() { - return shared_image_interface_provider_.GetSharedImageInterface(); + return shared_image_interface_provider_->GetSharedImageInterface(); } private: @@ -156,12 +148,6 @@ const double refresh_rate_; viz::FrameSinkId frame_sink_id_; - // TODO(danakj): These don't need to be stored in unique_ptrs when - // LayerTreeFrameSink is owned/destroyed on the compositor thread. - std::unique_ptr<viz::TestSharedBitmapManager> shared_bitmap_manager_; - std::unique_ptr<gpu::SharedImageManager> shared_image_manager_; - std::unique_ptr<gpu::SyncPointManager> sync_point_manager_; - std::unique_ptr<gpu::Scheduler> gpu_scheduler_; std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_; std::unique_ptr<viz::ParentLocalSurfaceIdAllocator> parent_local_surface_id_allocator_; @@ -179,7 +165,7 @@ nullptr; // Not owned. viz::ExternalBeginFrameSource external_begin_frame_source_; - // Uses surface_manager_, begin_frame_source_, shared_bitmap_manager_. + // Uses surface_manager_, begin_frame_source_. std::unique_ptr<viz::Display> display_; raw_ptr<TestLayerTreeFrameSinkClient> test_client_ = nullptr; @@ -187,12 +173,8 @@ raw_ptr<TaskRunnerProvider> task_runner_provider_; - // The set of SharedBitmapIds that have been reported as allocated to this - // interface. On closing this interface, the display compositor should drop - // ownership of the bitmaps with these ids to avoid leaking them. - std::set<viz::SharedBitmapId> owned_bitmaps_; - - viz::TestSharedImageInterfaceProvider shared_image_interface_provider_; + std::unique_ptr<viz::TestSharedImageInterfaceProvider> + shared_image_interface_provider_; base::WeakPtrFactory<TestLayerTreeFrameSink> weak_ptr_factory_{this}; };
diff --git a/cc/trees/layer_tree_host_perftest.cc b/cc/trees/layer_tree_host_perftest.cc index 64c420b6..4eb4d53 100644 --- a/cc/trees/layer_tree_host_perftest.cc +++ b/cc/trees/layer_tree_host_perftest.cc
@@ -58,9 +58,9 @@ !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; return std::make_unique<TestLayerTreeFrameSink>( compositor_context_provider, std::move(worker_context_provider), - gpu_memory_buffer_manager(), renderer_settings, &debug_settings_, - task_runner_provider(), synchronous_composite, disable_display_vsync, - refresh_rate); + /*shared_image_interface=*/nullptr, gpu_memory_buffer_manager(), + renderer_settings, &debug_settings_, task_runner_provider(), + synchronous_composite, disable_display_vsync, refresh_rate); } void BeginTest() override {
diff --git a/cc/trees/layer_tree_host_unittest.cc b/cc/trees/layer_tree_host_unittest.cc index 8d46ff29..7935c36 100644 --- a/cc/trees/layer_tree_host_unittest.cc +++ b/cc/trees/layer_tree_host_unittest.cc
@@ -4193,6 +4193,7 @@ base::RepeatingClosure invalidate_callback) : TestLayerTreeFrameSink(std::move(compositor_context_provider), std::move(worker_context_provider), + /*shared_image_interface=*/nullptr, gpu_memory_buffer_manager, renderer_settings, debug_settings, @@ -7051,9 +7052,9 @@ !layer_tree_host()->GetSettings().single_thread_proxy_scheduler; return std::make_unique<TestLayerTreeFrameSink>( compositor_context_provider, std::move(worker_context_provider), - gpu_memory_buffer_manager(), renderer_settings, &debug_settings_, - task_runner_provider(), synchronous_composite, disable_display_vsync, - refresh_rate); + /*shared_image_interface=*/nullptr, gpu_memory_buffer_manager(), + renderer_settings, &debug_settings_, task_runner_provider(), + synchronous_composite, disable_display_vsync, refresh_rate); } void BeginTest() override {
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabCardViewBinderUtils.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabCardViewBinderUtils.java index 1291211..7c60477c 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabCardViewBinderUtils.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabCardViewBinderUtils.java
@@ -4,6 +4,7 @@ package org.chromium.chrome.browser.tasks.tab_management; +import android.content.Context; import android.content.res.Resources; import android.view.Gravity; import android.view.View; @@ -76,5 +77,20 @@ } } + /** + * Checks that the text resolver is not null (unless the property is being unbound) in order to + * resolve the description string when requested by the respective view binders. If the text + * resolve is null return null. + * + * @param resolver The text resolver used for description string resolution. + * @param context The current context. + * @return The resolved content description string to be used in view binder updates. + */ + static @Nullable CharSequence resolveNullSafe( + @Nullable TextResolver resolver, Context context) { + if (resolver == null) return null; + return resolver.resolve(context); + } + private TabCardViewBinderUtils() {} }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java index a911ae4..4d06a5b 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabGridViewBinder.java
@@ -159,8 +159,13 @@ FrameLayout container = (FrameLayout) view.fastFindViewById(R.id.tab_group_color_view_container); TabCardViewBinderUtils.updateTabGroupColorView(container, provider); - } else if (TabProperties.CONTENT_DESCRIPTION_STRING == propertyKey) { - view.setContentDescription(model.get(TabProperties.CONTENT_DESCRIPTION_STRING)); + } else if (TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER == propertyKey) { + TextResolver contentDescriptionTextResolver = + model.get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER); + CharSequence contentDescriptionString = + TabCardViewBinderUtils.resolveNullSafe( + contentDescriptionTextResolver, view.getContext()); + view.setContentDescription(contentDescriptionString); } else if (TabProperties.GRID_CARD_SIZE == propertyKey) { final Size cardSize = model.get(TabProperties.GRID_CARD_SIZE); int height = cardSize.getHeight(); @@ -223,10 +228,15 @@ LargeMessageCardView.showPriceDropTooltip( priceCardView.findViewById(R.id.current_price)); } - } else if (TabProperties.ACTION_BUTTON_DESCRIPTION_STRING == propertyKey) { + } else if (TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER == propertyKey) { + TextResolver actionButtonDescriptionTextResolver = + model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER); + CharSequence actionButtonDescriptionString = + actionButtonDescriptionTextResolver == null + ? null + : actionButtonDescriptionTextResolver.resolve(view.getContext()); view.fastFindViewById(R.id.action_button) - .setContentDescription( - model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING)); + .setContentDescription(actionButtonDescriptionString); } else if (TabProperties.QUICK_DELETE_ANIMATION_STATUS == propertyKey) { ((TabGridView) view) .hideTabGridCardViewForQuickDelete(
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 7824a66b..723963a 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
@@ -8,7 +8,6 @@ import static org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.CARD_ALPHA; import static org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.CARD_TYPE; import static org.chromium.chrome.browser.tasks.tab_management.TabListModel.CardProperties.ModelType.TAB; -import static org.chromium.chrome.browser.tasks.tab_management.TabProperties.ACTION_BUTTON_DESCRIPTION_STRING; import static org.chromium.chrome.browser.tasks.tab_management.TabProperties.TAB_GROUP_COLOR_VIEW_PROVIDER; import static org.chromium.chrome.browser.tasks.tab_management.TabProperties.TAB_ID; import static org.chromium.chrome.browser.tasks.tab_management.TabProperties.THUMBNAIL_FETCHER; @@ -1346,23 +1345,25 @@ } private int getInsertionIndexOfTab(Tab tab, boolean onlyShowRelatedTabs) { - int index = TabList.INVALID_TAB_INDEX; - if (tab == null) return index; + if (tab == null) return TabList.INVALID_TAB_INDEX; + + int tabIndex = TabList.INVALID_TAB_INDEX; if (onlyShowRelatedTabs) { - if (mModelList.size() == 0) return TabList.INVALID_TAB_INDEX; - List<Tab> related = - getRelatedTabsForId(mModelList.get(0).model.get(TabProperties.TAB_ID)); - index = related.indexOf(tab); - if (index == -1) return TabList.INVALID_TAB_INDEX; + // Compute the index of the tab within the tab's group. + @Nullable PropertyModel model = mModelList.getFirstTabPropertyModel(); + if (model == null) return TabList.INVALID_TAB_INDEX; + + List<Tab> related = getRelatedTabsForId(model.get(TabProperties.TAB_ID)); + tabIndex = related.indexOf(tab); } else { - index = - mModelList.indexOfNthTabCard( - TabModelUtils.getTabIndexById( - mCurrentTabGroupModelFilterSupplier.get(), tab.getId())); - // TODO(wychen): the title (tab count in the group) is wrong when it's not the last - // tab added in the group. + // Compute the index of the tab out of all tabs. + tabIndex = + TabModelUtils.getTabIndexById( + mCurrentTabGroupModelFilterSupplier.get(), tab.getId()); } - return index; + // Get the position of the nth tab card ignoring any other CARD_TYPE entries present in the + // model list. + return mModelList.indexOfNthTabCard(tabIndex); } private int onTabAdded(Tab tab, boolean onlyShowRelatedTabs) { @@ -1902,70 +1903,84 @@ if (!mActionsOnAllRelatedTabs) return; boolean isInTabGroup = isTabInTabGroup(tab); int numOfRelatedTabs = getRelatedTabsForId(tab.getId()).size(); - if (isInTabGroup) { - String title = getLatestTitleForTab(tab, /* useDefault= */ false); - Resources res = mActivity.getResources(); - TabGroupModelFilter filter = mCurrentTabGroupModelFilterSupplier.get(); - @TabGroupColorId int colorId = filter.getTabGroupColorWithFallback(tab.getRootId()); - final @StringRes int colorDescRes = - ColorPickerUtils.getTabGroupColorPickerItemColorAccessibilityString(colorId); - String colorDesc = res.getString(colorDescRes); - if (ChromeFeatureList.isEnabled(ChromeFeatureList.DATA_SHARING) - && hasCollaboration(tab)) { - model.set( - TabProperties.CONTENT_DESCRIPTION_STRING, - title.isEmpty() - ? res.getQuantityString( - R.plurals.accessibility_expand_shared_tab_group_with_color, - numOfRelatedTabs, - numOfRelatedTabs, - colorDesc) - : res.getQuantityString( - R.plurals - .accessibility_expand_shared_tab_group_with_group_name_with_color, - numOfRelatedTabs, - title, - numOfRelatedTabs, - colorDesc)); - return; - } - model.set( - TabProperties.CONTENT_DESCRIPTION_STRING, - title.isEmpty() - ? res.getQuantityString( - R.plurals.accessibility_expand_tab_group_with_color, - numOfRelatedTabs, - numOfRelatedTabs, - colorDesc) - : res.getQuantityString( - R.plurals - .accessibility_expand_tab_group_with_group_name_with_color, - numOfRelatedTabs, - title, - numOfRelatedTabs, - colorDesc)); - } else { - model.set(TabProperties.CONTENT_DESCRIPTION_STRING, null); - } + TextResolver contentDescriptionResolver = + (context) -> { + String contentDescriptionString; + if (isInTabGroup) { + String title = getLatestTitleForTab(tab, /* useDefault= */ false); + Resources res = context.getResources(); + TabGroupModelFilter filter = mCurrentTabGroupModelFilterSupplier.get(); + @TabGroupColorId + int colorId = filter.getTabGroupColorWithFallback(tab.getRootId()); + final @StringRes int colorDescRes = + ColorPickerUtils.getTabGroupColorPickerItemColorAccessibilityString( + colorId); + String colorDesc = res.getString(colorDescRes); + if (ChromeFeatureList.isEnabled(ChromeFeatureList.DATA_SHARING) + && hasCollaboration(tab)) { + contentDescriptionString = + title.isEmpty() + ? res.getQuantityString( + R.plurals + .accessibility_expand_shared_tab_group_with_color, + numOfRelatedTabs, + numOfRelatedTabs, + colorDesc) + : res.getQuantityString( + R.plurals + .accessibility_expand_shared_tab_group_with_group_name_with_color, + numOfRelatedTabs, + title, + numOfRelatedTabs, + colorDesc); + } else { + contentDescriptionString = + title.isEmpty() + ? res.getQuantityString( + R.plurals + .accessibility_expand_tab_group_with_color, + numOfRelatedTabs, + numOfRelatedTabs, + colorDesc) + : res.getQuantityString( + R.plurals + .accessibility_expand_tab_group_with_group_name_with_color, + numOfRelatedTabs, + title, + numOfRelatedTabs, + colorDesc); + } + } else { + contentDescriptionString = null; + } + return contentDescriptionString; + }; + model.set(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER, contentDescriptionResolver); } private void updateActionButtonDescriptionString(Tab tab, PropertyModel model) { + TextResolver descriptionTextResolver; if (mActionsOnAllRelatedTabs) { boolean isInTabGroup = isTabInTabGroup(tab); int numOfRelatedTabs = getRelatedTabsForId(tab.getId()).size(); if (isInTabGroup) { String title = getLatestTitleForTab(tab, /* useDefault= */ false); - String descriptionString = - getActionButtonDescriptionString(numOfRelatedTabs, title, tab); - model.set(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING, descriptionString); + descriptionTextResolver = + getActionButtonDescriptionTextResolver(numOfRelatedTabs, title, tab); + model.set( + TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER, + descriptionTextResolver); return; } } - model.set( - ACTION_BUTTON_DESCRIPTION_STRING, - mActivity.getString(R.string.accessibility_tabstrip_btn_close_tab, tab.getTitle())); + descriptionTextResolver = + (context) -> { + return context.getString( + R.string.accessibility_tabstrip_btn_close_tab, tab.getTitle()); + }; + model.set(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER, descriptionTextResolver); } @VisibleForTesting @@ -2667,49 +2682,53 @@ tabGroupVisualDataDialogManager.showDialog(rootId, filter, dialogController); } - private String getActionButtonDescriptionString(int numOfRelatedTabs, String title, Tab tab) { - Resources res = mActivity.getResources(); + private TextResolver getActionButtonDescriptionTextResolver( + int numOfRelatedTabs, String title, Tab tab) { TabGroupModelFilter filter = mCurrentTabGroupModelFilterSupplier.get(); @TabGroupColorId int colorId = filter.getTabGroupColorWithFallback(tab.getRootId()); final @StringRes int colorDescRes = ColorPickerUtils.getTabGroupColorPickerItemColorAccessibilityString(colorId); - String colorDesc = res.getString(colorDescRes); - if (ChromeFeatureList.sTabGroupPaneAndroid.isEnabled()) { - String descriptionTitle = title; - if (TextUtils.isEmpty(descriptionTitle)) { - descriptionTitle = TabGroupTitleUtils.getDefaultTitle(mActivity, numOfRelatedTabs); - } - if (!ChromeFeatureList.isEnabled(ChromeFeatureList.DATA_SHARING) - || !hasCollaboration(tab)) { - return res.getString( - R.string - .accessibility_open_tab_group_overflow_menu_with_group_name_with_color, - descriptionTitle, - colorDesc); + String colorDesc = mActivity.getResources().getString(colorDescRes); + return (context) -> { + Resources res = context.getResources(); + if (ChromeFeatureList.sTabGroupPaneAndroid.isEnabled()) { + String descriptionTitle = title; + if (TextUtils.isEmpty(descriptionTitle)) { + descriptionTitle = + TabGroupTitleUtils.getDefaultTitle(mActivity, numOfRelatedTabs); + } + if (!ChromeFeatureList.isEnabled(ChromeFeatureList.DATA_SHARING) + || !hasCollaboration(tab)) { + return res.getString( + R.string + .accessibility_open_tab_group_overflow_menu_with_group_name_with_color, + descriptionTitle, + colorDesc); + } else { + return res.getString( + R.string + .accessibility_open_shared_tab_group_overflow_menu_with_group_name_with_color, + descriptionTitle, + colorDesc); + } } else { - return res.getString( - R.string - .accessibility_open_shared_tab_group_overflow_menu_with_group_name_with_color, - descriptionTitle, - colorDesc); + if (TextUtils.isEmpty(title)) { + return res.getQuantityString( + R.plurals.accessibility_close_tab_group_button_with_color, + numOfRelatedTabs, + numOfRelatedTabs, + colorDesc); + } else { + return res.getQuantityString( + R.plurals + .accessibility_close_tab_group_button_with_group_name_with_color, + numOfRelatedTabs, + title, + numOfRelatedTabs, + colorDesc); + } } - } else { - if (TextUtils.isEmpty(title)) { - return res.getQuantityString( - R.plurals.accessibility_close_tab_group_button_with_color, - numOfRelatedTabs, - numOfRelatedTabs, - colorDesc); - } else { - return res.getQuantityString( - R.plurals - .accessibility_close_tab_group_button_with_group_name_with_color, - numOfRelatedTabs, - title, - numOfRelatedTabs, - colorDesc); - } - } + }; } /** Check if the current tab group's tab representation is being shared. */
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java index b4047784b..59c958f 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModel.java
@@ -14,6 +14,7 @@ import android.util.Pair; import androidx.annotation.IntDef; +import androidx.annotation.Nullable; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabModel; @@ -65,6 +66,17 @@ return TabModel.INVALID_TAB_INDEX; } + /** Returns the property model of the first tab card or null if one does not exist. */ + public @Nullable PropertyModel getFirstTabPropertyModel() { + for (int i = 0; i < size(); i++) { + PropertyModel model = get(i).model; + if (model.get(CARD_TYPE) == TAB) { + return model; + } + } + return null; + } + /** * Find the Nth TAB card in the {@link TabListModel}. *
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModelUnitTest.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModelUnitTest.java index cba7e55..16fa6fd 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModelUnitTest.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListModelUnitTest.java
@@ -5,6 +5,8 @@ package org.chromium.chrome.browser.tasks.tab_management; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,4 +47,31 @@ assertEquals(TabModel.INVALID_TAB_INDEX, tabListModel.indexOfTabCardsOrInvalid(4)); assertEquals(TabModel.INVALID_TAB_INDEX, tabListModel.indexOfTabCardsOrInvalid(5)); } + + @Test + public void testGetFirstTabPropertyModel() { + TabListModel tabListModel = new TabListModel(); + assertNull(tabListModel.getFirstTabPropertyModel()); + + tabListModel.add(listItemWithType(ModelType.MESSAGE)); + assertNull(tabListModel.getFirstTabPropertyModel()); + + ListItem firstTabItem = listItemWithType(ModelType.TAB); + assertNotNull(firstTabItem.model); + tabListModel.add(firstTabItem); + assertEquals(firstTabItem.model, tabListModel.getFirstTabPropertyModel()); + + tabListModel.add(listItemWithType(ModelType.TAB)); + assertEquals(firstTabItem.model, tabListModel.getFirstTabPropertyModel()); + + tabListModel.clear(); + assertNull(tabListModel.getFirstTabPropertyModel()); + ListItem newFirstTabItem = listItemWithType(ModelType.TAB); + assertNotNull(newFirstTabItem.model); + tabListModel.add(newFirstTabItem); + assertEquals(newFirstTabItem.model, tabListModel.getFirstTabPropertyModel()); + + tabListModel.add(listItemWithType(ModelType.MESSAGE)); + assertEquals(newFirstTabItem.model, tabListModel.getFirstTabPropertyModel()); + } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java index 68aff42..e23b86d 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewBinder.java
@@ -189,10 +189,13 @@ view.getContext(), model.get(TabProperties.IS_INCOGNITO), /* isSelected= */ false)); - } else if (TabProperties.ACTION_BUTTON_DESCRIPTION_STRING == propertyKey) { - view.findViewById(R.id.end_button) - .setContentDescription( - model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING)); + } else if (TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER == propertyKey) { + TextResolver actionButtonDescriptionTextResolver = + model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER); + CharSequence actionButtonDescriptionString = + TabCardViewBinderUtils.resolveNullSafe( + actionButtonDescriptionTextResolver, view.getContext()); + view.findViewById(R.id.end_button).setContentDescription(actionButtonDescriptionString); } else if (TabProperties.TAB_CARD_LABEL_DATA == propertyKey) { updateTabCardLabel(view, model.get(TabProperties.TAB_CARD_LABEL_DATA)); }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java index 569cb017..e7371f4e 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabProperties.java
@@ -97,11 +97,11 @@ public static final WritableObjectPropertyKey<AccessibilityDelegate> ACCESSIBILITY_DELEGATE = new WritableObjectPropertyKey<>(); - public static final WritableObjectPropertyKey<String> CONTENT_DESCRIPTION_STRING = + public static final WritableObjectPropertyKey<TextResolver> CONTENT_DESCRIPTION_TEXT_RESOLVER = new WritableObjectPropertyKey<>(); - public static final WritableObjectPropertyKey<String> ACTION_BUTTON_DESCRIPTION_STRING = - new WritableObjectPropertyKey<>(); + public static final WritableObjectPropertyKey<TextResolver> + ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER = new WritableObjectPropertyKey<>(); public static final WritableObjectPropertyKey<ShoppingPersistedTabDataFetcher> SHOPPING_PERSISTED_TAB_DATA_FETCHER = new WritableObjectPropertyKey<>(true); @@ -153,8 +153,8 @@ URL_DOMAIN, ACCESSIBILITY_DELEGATE, CARD_TYPE, - CONTENT_DESCRIPTION_STRING, - ACTION_BUTTON_DESCRIPTION_STRING, + CONTENT_DESCRIPTION_TEXT_RESOLVER, + ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER, SHOPPING_PERSISTED_TAB_DATA_FETCHER, SHOULD_SHOW_PRICE_DROP_TOOLTIP, QUICK_DELETE_ANIMATION_STATUS, @@ -183,7 +183,7 @@ TAB_ACTION_BUTTON_DATA, TAB_CLICK_LISTENER, TAB_LONG_CLICK_LISTENER, - ACTION_BUTTON_DESCRIPTION_STRING, - CONTENT_DESCRIPTION_STRING, + ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER, + CONTENT_DESCRIPTION_TEXT_RESOLVER, }; }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java index 222401f..81ab80b 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/TabListViewHolderTest.java
@@ -640,7 +640,13 @@ Assert.assertNull(gridActionButton.getContentDescription()); String closeTabDescription = "Close tab"; - mGridModel.set(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING, closeTabDescription); + TextResolver actionButtonDescriptionTextResolver = + (context) -> { + return closeTabDescription; + }; + mGridModel.set( + TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER, + actionButtonDescriptionTextResolver); Assert.assertEquals(closeTabDescription, listActionButton.getContentDescription()); Assert.assertEquals(closeTabDescription, gridActionButton.getContentDescription());
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java index dba413c..99220950 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/TabListMediatorUnitTest.java
@@ -46,6 +46,7 @@ import android.app.Activity; import android.content.ComponentCallbacks; +import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; @@ -62,6 +63,7 @@ import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; +import androidx.test.core.app.ApplicationProvider; import com.google.protobuf.ByteString; @@ -84,7 +86,7 @@ import org.robolectric.annotation.LooperMode; import org.chromium.base.Callback; -import org.chromium.base.FeatureList; +import org.chromium.base.FeatureOverrides; import org.chromium.base.Token; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.shared_preferences.SharedPreferencesManager; @@ -251,8 +253,8 @@ TabProperties.TAB_ACTION_BUTTON_DATA, TabProperties.TAB_CLICK_LISTENER, TabProperties.TAB_LONG_CLICK_LISTENER, - TabProperties.CONTENT_DESCRIPTION_STRING, - TabProperties.ACTION_BUTTON_DESCRIPTION_STRING, + TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER, + TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER, TabProperties.IS_SELECTED, }; @@ -368,6 +370,7 @@ private String mNewDomain; private GURL mFaviconUrl; private Resources mResources; + private Context mContext; @Before public void setUp() { @@ -388,6 +391,7 @@ when(mServiceStatus.isAllowedToJoin()).thenReturn(true); mResources = spy(RuntimeEnvironment.application.getResources()); + mContext = ApplicationProvider.getApplicationContext(); when(mActivity.getResources()).thenReturn(mResources); when(mResources.getInteger(org.chromium.ui.R.integer.min_screen_width_bucket)) .thenReturn(1); @@ -2773,7 +2777,11 @@ mModelList.get(POSITION1).model.get(TabProperties.TITLE), equalTo(CUSTOMIZED_DIALOG_TITLE1)); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.CONTENT_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); } @@ -2796,7 +2804,11 @@ mModelList.get(POSITION1).model.get(TabProperties.TITLE), equalTo(CUSTOMIZED_DIALOG_TITLE1)); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.CONTENT_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); } @@ -3665,14 +3677,22 @@ // Reset with show quickly. assertThat(mMediator.resetWithListOfTabs(tabs, false), equalTo(true)); assertThat( - mModelList.get(POSITION2).model.get(TabProperties.CONTENT_DESCRIPTION_STRING), + mModelList + .get(POSITION2) + .model + .get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); // Reset without show quickly. mModelList.clear(); assertThat(mMediator.resetWithListOfTabs(tabs, false), equalTo(false)); assertThat( - mModelList.get(POSITION2).model.get(TabProperties.CONTENT_DESCRIPTION_STRING), + mModelList + .get(POSITION2) + .model + .get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); // Set group name. @@ -3684,7 +3704,11 @@ .getValue() .didChangeTabGroupTitle(TAB2_ID, CUSTOMIZED_DIALOG_TITLE1); assertThat( - mModelList.get(POSITION2).model.get(TabProperties.CONTENT_DESCRIPTION_STRING), + mModelList + .get(POSITION2) + .model + .get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); } @@ -3718,7 +3742,11 @@ // Check that a base group with no title has the correct content description. mMediator.resetWithListOfTabs(tabs, false); assertThat( - mModelList.get(POSITION2).model.get(TabProperties.CONTENT_DESCRIPTION_STRING), + mModelList + .get(POSITION2) + .model + .get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(emptyTitleTargetString)); String nonEmptyTitleTargetString = @@ -3734,7 +3762,11 @@ .getValue() .didChangeTabGroupTitle(TAB2_ID, CUSTOMIZED_DIALOG_TITLE1); assertThat( - mModelList.get(POSITION2).model.get(TabProperties.CONTENT_DESCRIPTION_STRING), + mModelList + .get(POSITION2) + .model + .get(TabProperties.CONTENT_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(nonEmptyTitleTargetString)); } @@ -3751,7 +3783,11 @@ mMediator.resetWithListOfTabs(tabs, false); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); // Create tab group. @@ -3763,7 +3799,11 @@ mMediator.resetWithListOfTabs(tabs, false); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); // Set group name. @@ -3774,7 +3814,11 @@ .getValue() .didChangeTabGroupTitle(TAB1_ID, CUSTOMIZED_DIALOG_TITLE1); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); } @@ -3789,7 +3833,11 @@ mMediator.resetWithListOfTabs(tabs, false); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); // Set group name. @@ -3800,7 +3848,11 @@ .getValue() .didChangeTabGroupTitle(TAB1_ID, CUSTOMIZED_DIALOG_TITLE1); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); } @@ -3815,7 +3867,11 @@ mMediator.resetWithListOfTabs(group1, false); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); // Set group name. @@ -3826,7 +3882,11 @@ .getValue() .didChangeTabGroupTitle(TAB1_ID, CUSTOMIZED_DIALOG_TITLE1); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); } @@ -3849,7 +3909,11 @@ mMediator.resetWithListOfTabs(group1, false); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); // Set group name. @@ -3862,7 +3926,11 @@ .getValue() .didChangeTabGroupTitle(TAB1_ID, CUSTOMIZED_DIALOG_TITLE1); assertThat( - mModelList.get(POSITION1).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION1) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(targetString)); } @@ -3892,7 +3960,11 @@ // Check that a base group with no title has the correct content description. mMediator.resetWithListOfTabs(group1, false); assertThat( - mModelList.get(POSITION2).model.get(TabProperties.ACTION_BUTTON_DESCRIPTION_STRING), + mModelList + .get(POSITION2) + .model + .get(TabProperties.ACTION_BUTTON_DESCRIPTION_TEXT_RESOLVER) + .resolve(mContext), equalTo(emptyTitleTargetString)); } @@ -4957,10 +5029,7 @@ } private static void setPriceTrackingEnabledForTesting(boolean value) { - FeatureList.TestValues testValues = new FeatureList.TestValues(); - testValues.addFeatureFlagOverride(ChromeFeatureList.PRICE_ANNOTATIONS, true); - FeatureList.mergeTestValues(testValues, /* replace= */ true); - + FeatureOverrides.enable(ChromeFeatureList.PRICE_ANNOTATIONS); PriceTrackingFeatures.setPriceAnnotationsEnabledForTesting(value); }
diff --git a/chrome/android/java/res/menu/main_menu.xml b/chrome/android/java/res/menu/main_menu.xml index bb7bc330..fc426080a 100644 --- a/chrome/android/java/res/menu/main_menu.xml +++ b/chrome/android/java/res/menu/main_menu.xml
@@ -82,6 +82,10 @@ <item android:id="@+id/page_zoom_id" android:title="@string/page_zoom_menu_title" android:icon="@drawable/ic_zoom" /> + <!-- Placeholder menu items to utilize the string; + so that we could start the translation early. --> + <item android:id="@+id/open_with_id" + android:title="@string/menu_open_with" /> <item android:id="@+id/share_row_menu_id" android:title="@null"> <menu>
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 0249226..6262d0c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -925,22 +925,44 @@ .onAvailable(manager -> mHubManagerSupplier.set(manager)); } - private @Nullable ObservableSupplier<Integer> getHubOverviewColorSupplier() { + private @NonNull ObservableSupplier<Integer> getHubOverviewColorSupplier() { // Prior to Hub creation we don't know what color to use. Default to the background color // since this shouldn't be visible. ObservableSupplierImpl<Integer> overviewColorSupplier = new ObservableSupplierImpl<>(SemanticColorUtils.getDefaultBgColor(this)); mHubManagerSupplier.onAvailable( (hubManager) -> { - ObservableSupplier<Pane> paneSupplier = - hubManager.getPaneManager().getFocusedPaneSupplier(); - Callback<Pane> paneObserver = - pane -> - overviewColorSupplier.set( - hubManager.getHubController().getBackgroundColor(pane)); - paneSupplier.addObserver(paneObserver); + ObservableSupplier<Integer> hubToolbarOverviewColorSupplier = + hubManager.getHubToolbarOverviewColorSupplier(); + Callback<Integer> hubToolbarOverviewColorObserver = overviewColorSupplier::set; + hubToolbarOverviewColorSupplier.addObserver(hubToolbarOverviewColorObserver); + + ObservableSupplier<Boolean> hubVisibilitySupplier = + hubManager.getHubVisibilitySupplier(); + + if (hubVisibilitySupplier.get() != null && hubVisibilitySupplier.get()) { + hubToolbarOverviewColorSupplier.addObserver( + hubToolbarOverviewColorObserver); + } + + Callback<Boolean> hubVisibilityObserver = + isVisible -> { + if (isVisible) { + hubToolbarOverviewColorSupplier.addObserver( + hubToolbarOverviewColorObserver); + } else { + hubToolbarOverviewColorSupplier.removeObserver( + hubToolbarOverviewColorObserver); + } + }; + hubVisibilitySupplier.addObserver(hubVisibilityObserver); + mCleanUpHubOverviewColorObserver = - () -> paneSupplier.removeObserver(paneObserver); + () -> { + hubVisibilitySupplier.removeObserver(hubVisibilityObserver); + hubToolbarOverviewColorSupplier.addObserver( + hubToolbarOverviewColorObserver); + }; }); return overviewColorSupplier; } @@ -1656,6 +1678,13 @@ .onAvailable( (profileProvider) -> { if (isActivityFinishingOrDestroyed()) return; + // The AuxiliarySearchControllerFactory#setIsTablet() must be called + // before creating the controller which checks + // AuxiliarySearchControllerFactory#isEnabled(). + AuxiliarySearchControllerFactory.getInstance() + .setIsTablet( + DeviceFormFactor.isWindowOnTablet( + getWindowAndroid())); mAuxiliarySearchController = AuxiliarySearchControllerFactory.getInstance() .createAuxiliarySearchController(
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java index eb5db72..c555c448 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/app/appmenu/AppMenuPropertiesDelegateImpl.java
@@ -498,6 +498,9 @@ menu.findItem(R.id.disable_price_tracking_menu_id), currentTab); + // TODO(crbug.com/370803107): Hide the placeholder menu items until implementation complete. + menu.findItem(R.id.open_with_id).setVisible(false); + // Don't allow either "chrome://" pages or interstitial pages to be shared, or when the // current tab is null. boolean showShare = isCurrentTabNotNull && mShareUtils.shouldEnableShare(currentTab);
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobar.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobar.java index 691767f2..088b3d94 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobar.java
@@ -13,6 +13,7 @@ import androidx.annotation.Nullable; +import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; import org.chromium.chrome.browser.browserservices.ui.TrustedWebActivityModel; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; @@ -30,7 +31,7 @@ public class DisclosureInfobar implements PropertyObservable.PropertyObserver<PropertyKey>, StartStopWithNativeObserver { private final Resources mResources; - private final SnackbarManager mSnackbarManager; + private final Supplier<SnackbarManager> mSnackbarManagerSupplier; private final TrustedWebActivityModel mModel; /** @@ -51,11 +52,11 @@ public DisclosureInfobar( Resources resources, - SnackbarManager snackbarManager, + Supplier<SnackbarManager> snackbarManagerSupplier, TrustedWebActivityModel model, ActivityLifecycleDispatcher lifecycleDispatcher) { mResources = resources; - mSnackbarManager = snackbarManager; + mSnackbarManagerSupplier = snackbarManagerSupplier; mModel = model; mModel.addObserver(this); lifecycleDispatcher.register(this); @@ -71,7 +72,7 @@ showIfNeeded(); break; case DISCLOSURE_STATE_NOT_SHOWN: - mSnackbarManager.dismissSnackbars(mSnackbarController); + mSnackbarManagerSupplier.get().dismissSnackbars(mSnackbarController); break; } } @@ -110,7 +111,7 @@ return; } - mSnackbarManager.showSnackbar(snackbar); + mSnackbarManagerSupplier.get().showSnackbar(snackbar); mModel.get(DISCLOSURE_EVENTS_CALLBACK).onDisclosureShown(); } }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbar.java b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbar.java index 793b8a0..73b2317 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbar.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbar.java
@@ -8,6 +8,7 @@ import androidx.annotation.Nullable; +import org.chromium.base.supplier.Supplier; import org.chromium.chrome.R; import org.chromium.chrome.browser.browserservices.ui.TrustedWebActivityModel; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; @@ -36,10 +37,10 @@ public DisclosureSnackbar( Resources resources, - SnackbarManager snackbarManager, + Supplier<SnackbarManager> snackbarManagerSupplier, TrustedWebActivityModel model, ActivityLifecycleDispatcher lifecycleDispatcher) { - super(resources, snackbarManager, model, lifecycleDispatcher); + super(resources, snackbarManagerSupplier, model, lifecycleDispatcher); mResources = resources; }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java index a5fd2cf..59df1aa8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/BaseCustomTabActivity.java
@@ -1334,7 +1334,7 @@ private DisclosureInfobar createDisclosureInfobar() { return new DisclosureInfobar( getResources(), - getSnackbarManager(), + this::getSnackbarManager, getTrustedWebActivityModel(), getLifecycleDispatcher()); } @@ -1342,7 +1342,7 @@ private DisclosureSnackbar createDisclosureSnackbar() { return new DisclosureSnackbar( getResources(), - getSnackbarManager(), + this::getSnackbarManager, getTrustedWebActivityModel(), getLifecycleDispatcher()); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabInputMethodWrapper.java b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabInputMethodWrapper.java index 55860a6..3ece6a5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabInputMethodWrapper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/customtabs/features/partialcustomtab/PartialCustomTabInputMethodWrapper.java
@@ -11,6 +11,7 @@ import android.view.inputmethod.CursorAnchorInfo; import org.chromium.base.Callback; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ImeAdapter; import org.chromium.content_public.browser.InputMethodManagerWrapper; import org.chromium.ui.base.WindowAndroid; @@ -69,7 +70,7 @@ } @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid) { mWrapper.onWindowAndroidChanged(newWindowAndroid); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java index 3ccc3f9f..b3fd18f8 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridge.java
@@ -244,7 +244,8 @@ onNotificationPreUnsubcribe(attributes); return false; } else if (NotificationConstants.ACTION_UNDO_UNSUBSCRIBE.equals(intent.getAction())) { - onNotificationUndoUnsubscribe(attributes); + restoreNotificationBackups( + attributes, NotificationConstants.EXTRA_NOTIFICATION_BACKUP_OF_ORIGINAL); return false; } else if (NotificationConstants.ACTION_COMMIT_UNSUBSCRIBE.equals(intent.getAction())) { // Cancel notification immediately so that the user perceives the action to have been @@ -256,6 +257,12 @@ BaseNotificationManagerProxyFactory.create(); notificationManager.cancel(attributes.notificationId, PLATFORM_ID); return true; + } else if (NotificationConstants.ACTION_SHOW_ORIGINAL_NOTIFICATION.equals( + intent.getAction())) { + restoreNotificationBackups( + attributes, + NotificationConstants.EXTRA_NOTIFICATION_BACKUP_FOR_SUSPICIOUS_VERDICT); + return false; } // All other intents handled from native. @@ -1401,15 +1408,48 @@ } /** - * Called when the user clicks the `ACTION_UNDO_UNSUBSCRIBE` button on the "provisionally - * unsubscribed" service notification. + * Called when the user clicks the `ACTION_COMMIT_UNSUBSCRIBE` button, expressly dismisses the + * "provisionally unsubscribed" service notification, or if the service notification times out. * - * <p>Restores the clicked notification and all other notifications from that origin. + * <p>Handles "unsubscribing", which in practice means resetting the permission for the origin, + * which will delete the notification channel, issue an FCM unsubscribe request, and cancel all + * notification, including the "Provisionally unsubscribed" service notification. * * @param identifyingAttributes Common attributes identifying a notification and its source. */ - private static void onNotificationUndoUnsubscribe( + private void onNotificationCommitUnsubscribe( NotificationIdentifyingAttributes identifyingAttributes) { + NotificationPlatformBridgeJni.get() + .onNotificationDisablePermission( + mNativeNotificationPlatformBridge, + NotificationPlatformBridge.this, + identifyingAttributes.notificationId, + identifyingAttributes.notificationType, + identifyingAttributes.origin, + identifyingAttributes.profileId, + identifyingAttributes.incognito); + var backups = + sOriginsWithProvisionallyRevokedPermissions.remove(identifyingAttributes.origin); + NotificationUmaTracker.getInstance() + .recordWasGlobalStatePreserved( + NotificationUmaTracker.GlobalStatePreservedActionSuffix.COMMIT, + backups != null); + } + + /** + * Called when the user clicks the `ACTION_UNDO_UNSUBSCRIBE` button on the "provisionally + * unsubscribed" service notification, or the `ACTION_SHOW_ORIGINAL_NOTIFICATION` button on the + * suspicious warning notification. + * + * <p>Restores the original notification. For undo subscribe only, also restores other + * notifications from that origin. + * + * @param identifyingAttributes Common attributes identifying a notification and its source. + * @param action The action that was clicked. + */ + private static void restoreNotificationBackups( + NotificationIdentifyingAttributes identifyingAttributes, + String extraNotificationBackupType) { var otherNotificationsBackups = sOriginsWithProvisionallyRevokedPermissions.remove(identifyingAttributes.origin); NotificationUmaTracker.getInstance() @@ -1434,16 +1474,14 @@ // If the tapped notification does not have a backup key in the metadata, it is // not a provisionally unsubscribed notification. Likely, the user clicked // "Undo" twice in quick succession, and we are already done. Bail out. - if (!tappedNotificationExtras.containsKey( - NotificationConstants.EXTRA_NOTIFICATION_BACKUP_OF_ORIGINAL)) { + if (!tappedNotificationExtras.containsKey(extraNotificationBackupType)) { return; } var originalNotificationBackup = (Notification) tappedNotificationExtras.getParcelable( - NotificationConstants - .EXTRA_NOTIFICATION_BACKUP_OF_ORIGINAL); + extraNotificationBackupType); // No backup means the original notification was quickly dismissed after the // user clicked "Unsubscribe". In this case we still want to cancel the @@ -1477,7 +1515,11 @@ /* notificationId= */ PLATFORM_ID))); } - if (otherNotificationsBackups == null) return; + // Only restore other notifications from that origin for undo subscribe action. + if (otherNotificationsBackups == null + || !extraNotificationBackupType.equals( + NotificationConstants.EXTRA_NOTIFICATION_BACKUP_OF_ORIGINAL)) + return; for (var entry : otherNotificationsBackups.entrySet()) { Notification.Builder builder = @@ -1503,35 +1545,6 @@ }); } - /** - * Called when the user clicks the `ACTION_COMMIT_UNSUBSCRIBE` button, expressly dismisses the - * "provisionally unsubscribed" service notification, or if the service notification times out. - * - * <p>Handles "unsubscribing", which in practice means resetting the permission for the origin, - * which will delete the notification channel, issue an FCM unsubscribe request, and cancel all - * notification, including the "Provisionally unsubscribed" service notification. - * - * @param identifyingAttributes Common attributes identifying a notification and its source. - */ - private void onNotificationCommitUnsubscribe( - NotificationIdentifyingAttributes identifyingAttributes) { - NotificationPlatformBridgeJni.get() - .onNotificationDisablePermission( - mNativeNotificationPlatformBridge, - NotificationPlatformBridge.this, - identifyingAttributes.notificationId, - identifyingAttributes.notificationType, - identifyingAttributes.origin, - identifyingAttributes.profileId, - identifyingAttributes.incognito); - var backups = - sOriginsWithProvisionallyRevokedPermissions.remove(identifyingAttributes.origin); - NotificationUmaTracker.getInstance() - .recordWasGlobalStatePreserved( - NotificationUmaTracker.GlobalStatePreservedActionSuffix.COMMIT, - backups != null); - } - /** Sets param value `isSuspicious` for displaying notification for testing. */ public void setIsSuspiciousParameterForTesting(boolean isSuspicious) { NotificationPlatformBridgeJni.get()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabGestureStateListener.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabGestureStateListener.java index 782a47c..634a28d2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/TabGestureStateListener.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/TabGestureStateListener.java
@@ -4,6 +4,8 @@ package org.chromium.chrome.browser.tab; +import static org.chromium.build.NullUtil.assumeNonNull; + import org.chromium.base.ObserverList.RewindableIterator; import org.chromium.content_public.browser.GestureListenerManager; import org.chromium.content_public.browser.GestureStateListener; @@ -43,6 +45,7 @@ @Override public void initWebContents(WebContents webContents) { GestureListenerManager manager = GestureListenerManager.fromWebContents(webContents); + assumeNonNull(manager); mGestureListener = new GestureStateListener() { @Override @@ -86,7 +89,7 @@ } private void onScrollingStateChanged() { - boolean scrolling = manager != null ? manager.isScrollInProgress() : false; + boolean scrolling = manager.isScrollInProgress(); RewindableIterator<TabObserver> observers = ((TabImpl) mTab).getTabObservers(); while (observers.hasNext()) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java index 0346aee..0ede9bf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorController.java
@@ -99,6 +99,9 @@ private float mNavigationBarScrimFraction; private final ObservableSupplier<EdgeToEdgeController> mEdgeToEdgeControllerSupplier; + private final @NonNull ObservableSupplier<Integer> mOverviewColorSupplier; + private final @NonNull Callback<Integer> mOnOverviewColorChanged = + color -> updateNavigationBarColor(); private final Callback<EdgeToEdgeController> mEdgeToEdgeRegisterChangeObserverCallback; private EdgeToEdgeController mEdgeToEdgeController; @Nullable private ChangeObserver mEdgeToEdgeChangeObserver; @@ -108,6 +111,7 @@ private TabObserver mTabObserver; @Nullable private @ColorInt Integer mBottomAttachedUiColor; private boolean mForceShowDivider; + private boolean mOverviewMode; private ValueAnimator mNavbarColorTransitionAnimation; private ObserverList<Observer> mObservers = new ObserverList<>(); @@ -140,6 +144,7 @@ * @param accessorySheetVisualStateSupplier Supplies an {@link * AccessorySheetVisualStateProvider} to watch for visual changes to the keyboard accessory * sheet. + * @param overviewColorSupplier Notifies when the overview color changes. * @param insetObserver An {@link InsetObserver} to listen for changes to the window insets. * @param edgeToEdgeManager Manages core edge-to-edge state and logic. */ @@ -158,6 +163,7 @@ @NonNull ObservableSupplier<AccessorySheetVisualStateProvider> accessorySheetVisualStateSupplier, + @NonNull ObservableSupplier<Integer> overviewColorSupplier, InsetObserver insetObserver, @NonNull EdgeToEdgeManager edgeToEdgeManager) { this( @@ -166,6 +172,7 @@ layoutManagerSupplier, fullscreenManager, edgeToEdgeControllerSupplier, + overviewColorSupplier, ChromeFeatureList.sNavBarColorMatchesTabBackground.isEnabled() ? new BottomAttachedUiObserver( bottomControlsStacker, @@ -186,6 +193,7 @@ ObservableSupplier<LayoutManager> layoutManagerSupplier, FullscreenManager fullscreenManager, ObservableSupplier<EdgeToEdgeController> edgeToEdgeControllerSupplier, + @NonNull ObservableSupplier<Integer> overviewColorSupplier, @Nullable BottomAttachedUiObserver bottomAttachedUiObserver) { assert Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1; @@ -254,6 +262,10 @@ }; mEdgeToEdgeControllerSupplier.addObserver(mEdgeToEdgeRegisterChangeObserverCallback); + mOverviewColorSupplier = overviewColorSupplier; + mOverviewColorSupplier.addObserver(mOnOverviewColorChanged); + mOverviewMode = false; + // TODO(crbug.com/40560014): Observe tab loads to restrict black bottom nav to // incognito NTP. @@ -269,6 +281,7 @@ if (mActiveTab != null) mActiveTab.removeObserver(mTabObserver); if (mLayoutManager != null) { mLayoutManager.removeObserver(mLayoutStateObserver); + mOverviewColorSupplier.removeObserver(mOnOverviewColorChanged); } if (mCallbackController != null) { mCallbackController.destroy(); @@ -312,12 +325,14 @@ public void onStartedShowing(@LayoutType int layoutType) { if (layoutType != LayoutType.TAB_SWITCHER) return; updateNavigationBarColor(); + enableOverviewMode(); } @Override public void onStartedHiding(@LayoutType int layoutType) { if (layoutType != LayoutType.TAB_SWITCHER) return; updateNavigationBarColor(); + disableOverviewMode(); } @Override @@ -514,35 +529,49 @@ @ColorInt private int getNavigationBarColor(boolean forceDarkNavigationBar) { - if (useBottomAttachedUiColor()) { + if (mOverviewMode && mOverviewColorSupplier.get() != null) { + return mOverviewColorSupplier.get(); + } else if (useBottomAttachedUiColor()) { return mBottomAttachedUiColor; - } - if (useActiveTabColor()) { + } else if (useActiveTabColor()) { return mActiveTab.getBackgroundColor(); + } else { + return forceDarkNavigationBar + ? mContext.getColor(R.color.toolbar_background_primary_dark) + : SemanticColorUtils.getBottomSystemNavColor(mWindow.getContext()); } - return forceDarkNavigationBar - ? mContext.getColor(R.color.toolbar_background_primary_dark) - : SemanticColorUtils.getBottomSystemNavColor(mWindow.getContext()); } @VisibleForTesting @ColorInt int getNavigationBarDividerColor(boolean forceDarkNavigationBar, boolean forceShowDivider) { - if (!forceShowDivider && useBottomAttachedUiColor()) { + if (mOverviewMode && mOverviewColorSupplier.get() != null) { + return mOverviewColorSupplier.get(); + } else if (!forceShowDivider && useBottomAttachedUiColor()) { return mBottomAttachedUiColor; - } - if (!forceShowDivider && useActiveTabColor()) { + } else if (!forceShowDivider && useActiveTabColor()) { return mActiveTab.getBackgroundColor(); + } else { + return forceDarkNavigationBar + ? mContext.getColor(R.color.bottom_system_nav_divider_color_light) + : SemanticColorUtils.getBottomSystemNavDividerColor(mWindow.getContext()); } - return forceDarkNavigationBar - ? mContext.getColor(R.color.bottom_system_nav_divider_color_light) - : SemanticColorUtils.getBottomSystemNavDividerColor(mWindow.getContext()); } private @ColorInt int applyCurrentScrimToColor(@ColorInt int color) { return ColorUtils.overlayColor(color, mDefaultScrimColor, mNavigationBarScrimFraction); } + @VisibleForTesting + void enableOverviewMode() { + mOverviewMode = true; + } + + @VisibleForTesting + void disableOverviewMode() { + mOverviewMode = false; + } + private boolean useBottomAttachedUiColor() { return ChromeFeatureList.sNavBarColorMatchesTabBackground.isEnabled() && mBottomAttachedUiColor != null;
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 70f3a274..0ec5551 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
@@ -362,7 +362,7 @@ @NonNull BackPressManager backPressManager, @Nullable Bundle savedInstanceState, @Nullable MultiInstanceManager multiInstanceManager, - @Nullable ObservableSupplier<Integer> overviewColorSupplier, + @NonNull ObservableSupplier<Integer> overviewColorSupplier, @Nullable View baseChromeLayout, @NonNull ManualFillingComponentSupplier manualFillingComponentSupplier, @NonNull EdgeToEdgeManager edgeToEdgeManager) { @@ -586,6 +586,7 @@ mManualFillingComponentSupplier .get() .getAccessorySheetVisualStateProvider(), + mOverviewColorSupplier, mInsetObserver, mEdgeToEdgeManager); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java index d347411..f7f07e9 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabbed_mode/TabbedSystemUiCoordinator.java
@@ -61,6 +61,7 @@ * @param accessorySheetVisualStateSupplier Supplies an {@link * AccessorySheetVisualStateProvider} to watch for visual changes to the keyboard accessory * sheet. + * @param overviewColorSupplier Notifies when the overview color changes. * @param insetObserver An {@link InsetObserver} to listen for changes to the window insets. * @param edgeToEdgeManager Manages core edge-to-edge state and logic. */ @@ -79,6 +80,7 @@ @NonNull ObservableSupplier<AccessorySheetVisualStateProvider> accessorySheetVisualStateSupplier, + @NonNull ObservableSupplier<Integer> overviewColorSupplier, InsetObserver insetObserver, @NonNull EdgeToEdgeManager edgeToEdgeManager) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) { @@ -97,6 +99,7 @@ bottomSheetController, omniboxSuggestionsVisualState, accessorySheetVisualStateSupplier, + overviewColorSupplier, insetObserver, edgeToEdgeManager); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemover.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemover.java index be959af4..2a18140 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemover.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemover.java
@@ -300,11 +300,18 @@ @Nullable SavedTabGroup savedTabGroup = tabGroupSyncService.getGroup(localTabGroupId); String collaborationId = savedTabGroup != null ? savedTabGroup.collaborationId : null; - if (!TabShareUtils.isCollaborationIdValid(collaborationId)) { + if (!TabShareUtils.isCollaborationIdValid(collaborationId) + || savedTabGroup.localId == null + || savedTabGroup.localId.tabGroupId == null) { return new CollaborationInfo(); } - String title = TabGroupTitleUtils.getDisplayableTitle(mContext, savedTabGroup); + TabGroupModelFilter filter = getTabGroupModelFilter(); + int rootId = filter.getRootIdFromStableId(savedTabGroup.localId.tabGroupId); + if (rootId == Tab.INVALID_TAB_ID) { + return new CollaborationInfo(); + } + String title = TabGroupTitleUtils.getDisplayableTitle(mContext, filter, rootId); CollaborationService collaborationService = getCollaborationService(); @MemberRole
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemoverUnitTest.java b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemoverUnitTest.java index ba0fcb9..657d329 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemoverUnitTest.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tabmodel/TabModelRemoverUnitTest.java
@@ -69,7 +69,9 @@ private static final String COLLABORATION_ID = "collaboration"; private static final String TAB_GROUP_TITLE = "My Title"; private static final LocalTabGroupId TAB_GROUP_1 = new LocalTabGroupId(new Token(1L, 2L)); + private static final int ROOT_ID_1 = 1; private static final LocalTabGroupId TAB_GROUP_2 = new LocalTabGroupId(new Token(2L, 3L)); + private static final int ROOT_ID_2 = 3; @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); @@ -93,7 +95,8 @@ private TabModelRemover mTabModelRemover; private InOrder mHandlerInOrder; private int mNextTabId; - private SavedTabGroup mSavedTabGroup; + private SavedTabGroup mSavedTabGroup1; + private SavedTabGroup mSavedTabGroup2; @Before public void setUp() { @@ -118,6 +121,11 @@ when(mTabGroupModelFilter.isIncognitoBranded()).thenReturn(false); when(mTabGroupModelFilter.getTabModel()).thenReturn(mTabModel); + when(mTabGroupModelFilter.getRootIdFromStableId(TAB_GROUP_1.tabGroupId)) + .thenReturn(ROOT_ID_1); + when(mTabGroupModelFilter.getRootIdFromStableId(TAB_GROUP_2.tabGroupId)) + .thenReturn(ROOT_ID_2); + when(mTabGroupModelFilter.getTabGroupTitle(anyInt())).thenReturn(TAB_GROUP_TITLE); doAnswer( invocation -> { @@ -135,10 +143,17 @@ () -> mTabGroupModelFilter); mHandlerInOrder = inOrder(mHandler); - mSavedTabGroup = new SavedTabGroup(); - mSavedTabGroup.title = TAB_GROUP_TITLE; - mSavedTabGroup.collaborationId = COLLABORATION_ID; - when(mTabGroupSyncService.getGroup(any(LocalTabGroupId.class))).thenReturn(mSavedTabGroup); + mSavedTabGroup1 = new SavedTabGroup(); + mSavedTabGroup1.localId = TAB_GROUP_1; + mSavedTabGroup1.title = TAB_GROUP_TITLE; + mSavedTabGroup1.collaborationId = COLLABORATION_ID; + when(mTabGroupSyncService.getGroup(TAB_GROUP_1)).thenReturn(mSavedTabGroup1); + + mSavedTabGroup2 = new SavedTabGroup(); + mSavedTabGroup2.localId = TAB_GROUP_2; + mSavedTabGroup2.title = TAB_GROUP_TITLE; + mSavedTabGroup2.collaborationId = COLLABORATION_ID; + when(mTabGroupSyncService.getGroup(TAB_GROUP_2)).thenReturn(mSavedTabGroup2); } @Test
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 82e3c45..ba74656 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
@@ -47,6 +47,7 @@ import org.chromium.chrome.browser.app.tabmodel.TabWindowManagerSingleton; import org.chromium.chrome.browser.back_press.BackPressManager; import org.chromium.chrome.browser.back_press.BackPressMetrics; +import org.chromium.chrome.browser.back_press.BackPressMetrics.NavigationDirection; import org.chromium.chrome.browser.back_press.BackPressMetrics.PredictiveGestureNavPhase; import org.chromium.chrome.browser.bookmarks.BookmarkModel; import org.chromium.chrome.browser.bookmarks.BookmarkModelObserver; @@ -175,6 +176,7 @@ import org.chromium.content_public.browser.NavigationController; import org.chromium.content_public.browser.NavigationEntry; import org.chromium.content_public.browser.NavigationHandle; +import org.chromium.content_public.browser.NavigationHistory; import org.chromium.content_public.browser.WebContents; import org.chromium.content_public.browser.back_forward_transition.AnimationStage; import org.chromium.net.NetError; @@ -188,6 +190,7 @@ import org.chromium.url.GURL; import java.util.List; +import java.util.Objects; /** * Contains logic for managing the toolbar visual component. This class manages the interactions @@ -334,6 +337,11 @@ private final View mProgressBarContainer; private @Nullable ObservableSupplier<Integer> mBookmarkBarHeightSupplier; + private String mLastUrl; + private String mCurrentUrl; + private int mLastIndex = -1; + private Tab mLastTab; + private static class TabObscuringCallback implements Callback<Boolean> { private final TabObscuringHandler mTabObscuringHandler; @@ -992,6 +1000,17 @@ mLocationBarModel.notifyUrlChanged(); return; } + // Switching tabs. + if (mLastTab != tab) { + NavigationHistory navigationHistory = + Objects.requireNonNull(tab.getWebContents()) + .getNavigationController() + .getNavigationHistory(); + // Reset mLastIndex to the index of the new tab we switched to. + mLastIndex = navigationHistory.getCurrentEntryIndex(); + // Update mLastTab. + mLastTab = tab; + } refreshSelectedTab(tab); onTabOrModelChanged(); @@ -1122,6 +1141,34 @@ Tab tab, NavigationHandle navigation) { onBackPressStateChanged(); if (navigation.hasCommitted() && !navigation.isSameDocument()) { + // Account for forward vs backward navigation. + NavigationHistory navigationHistory = + Objects.requireNonNull(tab.getWebContents()) + .getNavigationController() + .getNavigationHistory(); + + int currentIndex = navigationHistory.getCurrentEntryIndex(); + // 0: forward nav, 1: backward nav, 2: neither (tab switched). + @NavigationDirection + int direction = + currentIndex > mLastIndex + ? NavigationDirection.FORWARD + : currentIndex < mLastIndex + ? NavigationDirection.BACKWARD + : NavigationDirection.NEITHER; + String newUrl = navigation.getUrl().getSpec(); + + if (mLastUrl != null + && mLastUrl.equals(newUrl) + && !mLastUrl.equals(mCurrentUrl)) { + // Backfalsing detected, emit metrics. + BackPressMetrics.recordBackFalsing(direction); + } + // Update the URLs and index. + mLastUrl = mCurrentUrl; + mCurrentUrl = newUrl; + mLastIndex = currentIndex; + mToolbar.onNavigatedToDifferentPage(); maybeTriggerCacheRefreshForZeroSuggest(navigation.getUrl()); }
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 df6c7b2..29173959 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
@@ -333,6 +333,7 @@ private final boolean mIsIncognitoReauthPendingOnRestore; protected final ExpandedSheetHelper mExpandedBottomSheetHelper; protected final BottomControlsStacker mBottomControlsStacker; + @NonNull protected final ObservableSupplier<Integer> mOverviewColorSupplier; @Nullable private ContextualSearchObserver mReadAloudContextualSearchObserver; @Nullable private PageZoomCoordinator mPageZoomCoordinator; private AppMenuObserver mAppMenuObserver; @@ -344,7 +345,6 @@ private @Nullable EdgeToEdgeController mEdgeToEdgeController; private ComposedBrowserControlsVisibilityDelegate mAppBrowserControlsVisibilityDelegate; private @Nullable BoardingPassController mBoardingPassController; - private final @Nullable ObservableSupplier<Integer> mOverviewColorSupplier; private final @Nullable View mBaseChromeLayout; private final @NonNull EdgeToEdgeManager mEdgeToEdgeManager; private CommerceBottomSheetContentCoordinator mCommerceBottomSheetContentCoordinator; @@ -434,7 +434,7 @@ boolean initializeUiWithIncognitoColors, @Nullable BackPressManager backPressManager, @Nullable Bundle savedInstanceState, - @Nullable ObservableSupplier<Integer> overviewColorSupplier, + @NonNull ObservableSupplier<Integer> overviewColorSupplier, @Nullable View baseChromeLayout, @NonNull EdgeToEdgeManager edgeToEdgeManager) { mCallbackController = new CallbackController();
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java index 3839d9c4..84e6aad0 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/bookmarks/ReadingListTest.java
@@ -312,6 +312,11 @@ mBookmarkManagerCoordinator .getTestingDelegate() .searchForTesting(TEST_PAGE_TITLE_GOOGLE)); + + // Blocking wait to go from 4 items to post-search 2 items (search row and 1 item result). + // Just waitForStableRecyclerView has not been sufficient, see https://crbug.com/369092966. + CriteriaHelper.pollUiThread( + () -> Criteria.checkThat(mItemsContainer.getChildCount(), Matchers.is(2))); RecyclerViewTestUtils.waitForStableRecyclerView(mItemsContainer); // Delete the reading list page in search state.
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java index 8cab7d14..a0d9e5411 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/app/flags/ChromeCachedFlagsTest.java
@@ -56,7 +56,6 @@ ChromeFeatureList.sPostGetMyMemoryStateToBackground, ChromeFeatureList.sPrefetchBrowserInitiatedTriggers, ChromeFeatureList.sSafetyHubMagicStack, - ChromeFeatureList.sTraceBinderIpc, OmniboxFeatures.sAndroidHubSearch); /**
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/desktop_windowing/AppHeaderCoordinatorBrowserTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/desktop_windowing/AppHeaderCoordinatorBrowserTest.java index 6573bd57..26667b6 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/desktop_windowing/AppHeaderCoordinatorBrowserTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/desktop_windowing/AppHeaderCoordinatorBrowserTest.java
@@ -408,6 +408,29 @@ activity.getActivityTab().getWebContents(), "document.querySelector('input').blur()"); + // Verify that the root view bottom padding uses the nav bar bottom inset. + CriteriaHelper.pollUiThread( + () -> { + var navBarBottomInset = + insetObserver + .getLastRawWindowInsets() + .getInsets(WindowInsetsCompat.Type.navigationBars()) + .bottom; + Criteria.checkThat(rootView.getPaddingBottom(), Matchers.is(navBarBottomInset)); + }); + + // Dispatch window insets to simulate no overlap of the app window with the nav bar. + ThreadUtils.runOnUiThreadBlocking( + () -> { + insetObserver.onApplyWindowInsets( + rootView, + new WindowInsetsCompat.Builder() + .setInsets( + WindowInsetsCompat.Type.navigationBars(), + Insets.of(0, 0, 0, 0)) + .build()); + }); + // Verify that the root view bottom padding is reset. CriteriaHelper.pollUiThread( () -> Criteria.checkThat(rootView.getPaddingBottom(), Matchers.is(0)));
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java index 2b8b029..a0afdca8 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/fullscreen/FullscreenManagerTestUtils.java
@@ -56,7 +56,7 @@ dragEndY = tempDragStartY; } long downTime = SystemClock.uptimeMillis(); - TouchCommon.performDrag( + TouchCommon.performDragNoFling( testRule.getActivity(), dragX, dragX, dragStartY, dragEndY, 100, downTime); waitForBrowserControlsPosition(testRule, expectedPosition); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java index ef7a7bc3..0dfbdac7 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/gesturenav/NavigationHandlerTest.java
@@ -80,6 +80,10 @@ "Android.BackPress.IncorrectEdgeSwipe"; private static final String INCORRECT_EDGE_SWIPE_COUNT_CHAINED_HISTOGRAM = "Android.BackPress.IncorrectEdgeSwipe.CountChained"; + private static final String BACK_FALSING_HISTOGRAM = "Android.BackPress.Backfalsing"; + private static final int FORWARD_NAV = 0; + private static final int DIFFERENT_TAB = 2; + private static final boolean LEFT_EDGE = true; private static final boolean RIGHT_EDGE = false; @@ -393,6 +397,78 @@ @Test @SmallTest + public void testBackfalsingHappyPath() { + // URL A -> URL B -> URL A -> URL B should emit two metrics. + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + .expectIntRecord(BACK_FALSING_HISTOGRAM, FORWARD_NAV) + .expectIntRecord(BACK_FALSING_HISTOGRAM, FORWARD_NAV) + .build(); + + mActivityTestRule.loadUrl(UrlConstants.NTP_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.NTP_URL); + mActivityTestRule.loadUrl(UrlConstants.GOOGLE_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.GOOGLE_URL); + mActivityTestRule.loadUrl(UrlConstants.NTP_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.NTP_URL); + mActivityTestRule.loadUrl(UrlConstants.GOOGLE_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.GOOGLE_URL); + + histogramWatcher.assertExpected("Wrong histogram recording"); + } + + @Test + @SmallTest + public void testBackfalsingAllSameUrls() { + // URL A -> URL A -> URL A should not emit any metrics. + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder().expectNoRecords(BACK_FALSING_HISTOGRAM).build(); + + mActivityTestRule.loadUrl(UrlConstants.NTP_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.NTP_URL); + mActivityTestRule.loadUrl(UrlConstants.NTP_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.NTP_URL); + mActivityTestRule.loadUrl(UrlConstants.NTP_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.NTP_URL); + + histogramWatcher.assertExpected("Wrong histogram recording"); + } + + @Test + @SmallTest + public void testBackfalsingOpenNewTabs() { + HistogramWatcher histogramWatcher = + HistogramWatcher.newBuilder() + // url A -> url B -> open new tab to url A -> url B in that new tab + .expectIntRecord(BACK_FALSING_HISTOGRAM, DIFFERENT_TAB) + .expectIntRecord(BACK_FALSING_HISTOGRAM, FORWARD_NAV) + .build(); + + mActivityTestRule.loadUrl(UrlConstants.NTP_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.NTP_URL); + mActivityTestRule.loadUrl(UrlConstants.GOOGLE_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.GOOGLE_URL); + TabCreator tabCreator = + ThreadUtils.runOnUiThreadBlocking( + () -> mActivityTestRule.getActivity().getTabCreator(false)); + + Tab newTab = + ThreadUtils.runOnUiThreadBlocking( + () -> + tabCreator.createNewTab( + new LoadUrlParams( + UrlConstants.NTP_URL, PageTransition.LINK), + TabLaunchType.FROM_LINK, + currentTab())); + + ChromeTabUtils.waitForTabPageLoaded(newTab, UrlConstants.NTP_URL); + mActivityTestRule.loadUrl(UrlConstants.GOOGLE_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.GOOGLE_URL); + histogramWatcher.assertExpected("Wrong histogram recording"); + } + + @Test + @SmallTest @DisableIf.Device(DeviceFormFactor.TABLET) public void testIncorrectEdgeSwipes() { // Swipe incorrectly 3 times and correctly once. @@ -404,6 +480,7 @@ .build(); mActivityTestRule.loadUrl(UrlConstants.NTP_URL); + ChromeTabUtils.waitForTabPageLoaded(currentTab(), UrlConstants.NTP_URL); mNavUtils.swipeFromEdge(RIGHT_EDGE); mNavUtils.swipeFromEdge(RIGHT_EDGE); mNavUtils.swipeFromEdge(RIGHT_EDGE);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java index 368a91a0..775e2b3 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/notifications/NotificationPlatformBridgeTest.java
@@ -1141,6 +1141,57 @@ } /** + * Verifies that when `SHOW_WARNINGS_FOR_SUSPICIOUS_NOTIFICATIONS` is enabled, suspicious + * notifications are replaced by a warning and tapping the "Show Notification" button performs + * the show notification behaviour. + */ + @Test + @LargeTest + @Feature({"Browser", "Notifications"}) + @Features.EnableFeatures({ + ChromeFeatureList.NOTIFICATION_ONE_TAP_UNSUBSCRIBE, + ChromeFeatureList.SHOW_WARNINGS_FOR_SUSPICIOUS_NOTIFICATIONS + }) + @MinAndroidSdkLevel(Build.VERSION_CODES.P) + public void testNotificationShowWarningNotificationThenShowNotification() throws Exception { + mNotificationTestRule.setNotificationContentSettingForOrigin( + ContentSettingValues.ALLOW, mPermissionTestRule.getOrigin()); + Assert.assertEquals("\"granted\"", runJavaScript("Notification.permission")); + + NotificationPlatformBridge notificationBridge = + NotificationPlatformBridge.getInstanceForTests(); + Assert.assertNotNull(notificationBridge); + notificationBridge.setIsSuspiciousParameterForTesting(true); + + showAndGetNotification("MyNotification", "{body: 'Hello'}"); + mNotificationTestRule.waitForNotificationCount(1); + + // Check notification contents were replaced by a warning. + Notification warningNotification = + mNotificationTestRule.getNotificationEntries().get(0).getNotification(); + Assert.assertEquals( + "Possible spam", NotificationTestUtil.getExtraTitle(warningNotification)); + + // Click the "Show Notification" button. + Assert.assertEquals(2, warningNotification.actions.length); + PendingIntent showNotificationIntent = warningNotification.actions[1].actionIntent; + Assert.assertNotNull(showNotificationIntent); + showNotificationIntent.send(); + + // Wait for the original notification. + Notification restoredNotification = + mNotificationTestRule.waitForNotification().notification; + + Assert.assertEquals( + "MyNotification", NotificationTestUtil.getExtraTitle(restoredNotification)); + Assert.assertEquals("Hello", NotificationTestUtil.getExtraText(restoredNotification)); + + // Verify that the notification is silent once restored. + Assert.assertEquals( + Notification.GROUP_ALERT_SUMMARY, restoredNotification.getGroupAlertBehavior()); + } + + /** * Verifies that when `SHOW_WARNINGS_FOR_SUSPICIOUS_NOTIFICATIONS` is enabled, non-suspicious * notifications stay the same and are not replaced by the warning. */
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java index 3a97454..f8a298f 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/toolbar/LocationBarModelTest.java
@@ -5,6 +5,7 @@ package org.chromium.chrome.browser.toolbar; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; @@ -24,6 +25,7 @@ import org.junit.runner.RunWith; import org.chromium.base.ThreadUtils; +import org.chromium.base.supplier.Supplier; import org.chromium.base.test.params.ParameterAnnotations; import org.chromium.base.test.params.ParameterProvider; import org.chromium.base.test.params.ParameterSet; @@ -160,11 +162,17 @@ ChromeTabbedActivity activity = mActivityTestRule.getActivity(); LocationBarModel locationBarModel = activity.getToolbarManager().getLocationBarModelForTesting(); + Supplier<Boolean> isIncognitoSupplier = + activity.getToolbarManager() + .getTabSwitcherButtonCoordinatorForTesting() + .getIsIncognitoSupplier(); ToolbarDataProvider.Observer observer = new ToolbarDataProvider.Observer() { @Override public void onIncognitoStateChanged() { assertEquals(toIncognito, locationBarModel.isIncognito()); + assertNotNull(isIncognitoSupplier); + assertEquals(toIncognito, isIncognitoSupplier.get()); incognitoStateObserverCallCount.set(Integer.valueOf(1)); } };
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobarTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobarTest.java index 3fea9f2..67d0e11 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobarTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureInfobarTest.java
@@ -49,7 +49,7 @@ mInfobar = new DisclosureInfobar( RuntimeEnvironment.application.getResources(), - mSnackbarManager, + () -> mSnackbarManager, mModel, mLifecycleDispatcher); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbarTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbarTest.java index 7b953f4..58c7d30 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbarTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/browserservices/ui/view/DisclosureSnackbarTest.java
@@ -45,7 +45,7 @@ mModel.set(DISCLOSURE_EVENTS_CALLBACK, mCallback); new DisclosureSnackbar( RuntimeEnvironment.application.getResources(), - mSnackbarManager, + () -> mSnackbarManager, mModel, mLifecycleDispatcher); }
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java index f58bc9b..ba1bcda 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java
@@ -42,7 +42,6 @@ import org.robolectric.shadows.ShadowPackageManager; import org.chromium.base.ContextUtils; -import org.chromium.base.FeatureList.TestValues; import org.chromium.base.ResettersForTesting; import org.chromium.base.SysUtils; import org.chromium.base.shared_preferences.SharedPreferencesManager; @@ -192,8 +191,6 @@ private Resources mResources; - private final TestValues mTestValues = new TestValues(); - private static final String ANY_SUBDOMAIN_PATTERN = "[*.]"; private static final String GOOGLE_COM = "[*.]google.com/"; private ShadowPackageManager mShadowPackageManager;
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorControllerUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorControllerUnitTest.java index f057ca7..2dabd0c1 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorControllerUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tabbed_mode/TabbedNavigationBarColorControllerUnitTest.java
@@ -6,6 +6,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.when; @@ -79,6 +80,7 @@ @Mock private LayoutManager mLayoutManager; @Mock private FullscreenManager mFullscreenManager; private ObservableSupplierImpl<EdgeToEdgeController> mEdgeToEdgeControllerObservableSupplier; + private ObservableSupplierImpl<Integer> mOverviewColorSupplier; @Mock private EdgeToEdgeController mEdgeToEdgeController; @Mock private BottomAttachedUiObserver mBottomAttachedUiObserver; @Mock private Tab mTab; @@ -99,6 +101,7 @@ R.style.Theme_BrowserUI_DayNight); mLayoutManagerSupplier = new ObservableSupplierImpl<>(); mEdgeToEdgeControllerObservableSupplier = new ObservableSupplierImpl<>(); + mOverviewColorSupplier = new ObservableSupplierImpl<>(); when(mWindow.getContext()).thenReturn(mContext); when(mWindow.getDecorView()).thenReturn(mDecorView); @@ -114,6 +117,7 @@ mLayoutManagerSupplier, mFullscreenManager, mEdgeToEdgeControllerObservableSupplier, + mOverviewColorSupplier, mBottomAttachedUiObserver); mLayoutManagerSupplier.set(mLayoutManager); mEdgeToEdgeControllerObservableSupplier.set(mEdgeToEdgeController); @@ -323,6 +327,27 @@ (mRootViewSystemVisibility.getValue() & View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR)); } + @Test + public void testOverviewColorEnabled() { + mNavColorController.enableOverviewMode(); + + mOverviewColorSupplier.set(Color.BLUE); + assertWindowNavBarColor(Color.BLUE); + + mNavColorController.disableOverviewMode(); + } + + @Test + public void testOverviewModeDisabled() { + mNavColorController.enableOverviewMode(); + mOverviewColorSupplier.set(Color.BLUE); + assertWindowNavBarColor(Color.BLUE); + + mNavColorController.disableOverviewMode(); + mOverviewColorSupplier.set(Color.RED); + assertWindowNavBarColorNotEqual(Color.RED); + } + private void runColorUpdateAnimation() { // Run the color transition animation so color is applied to the window. ShadowLooper.idleMainLooper(); @@ -346,6 +371,13 @@ (int) mWindowColorCaptor.getValue()); } + private void assertWindowNavBarColorNotEqual(int color) { + assertNotEquals( + "The window (OS) nav bar color is equal.", + color, + (int) mWindowColorCaptor.getValue()); + } + private void assertNavBarDividerColor(int color) { assertNavBarDividerColor(color, /* forceShowDivider= */ false); }
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h index fc51c647..8ee5a57 100644 --- a/chrome/app/chrome_command_ids.h +++ b/chrome/app/chrome_command_ids.h
@@ -72,8 +72,7 @@ #define IDC_USE_SYSTEM_TITLE_BAR 34051 #endif -// TODO(crbug.com/40118868): Revisit the macro expression once build flag switch of lacros-chrome is complete. -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) +#if BUILDFLAG(IS_LINUX) #define IDC_RESTORE_WINDOW 34052 #endif @@ -86,7 +85,7 @@ #define IDC_WEB_APP_SETTINGS 34062 #define IDC_WEB_APP_MENU_APP_INFO 34063 -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Move window to other user commands #define IDC_VISIT_DESKTOP_OF_LRU_USER_2 34080 #define IDC_VISIT_DESKTOP_OF_LRU_USER_3 34081 @@ -511,7 +510,7 @@ #define IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS 52411 #define IDC_CONTENT_CONTEXT_ACCESSIBILITY_LABELS_TOGGLE_ONCE 52412 -#if BUILDFLAG(IS_CHROMEOS_ASH) +#if BUILDFLAG(IS_CHROMEOS) // Quick Answers context menu items. #define IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_ANSWER 52413 #define IDC_CONTENT_CONTEXT_QUICK_ANSWERS_INLINE_QUERY 52414
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 1851378..4381378 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd
@@ -1196,7 +1196,7 @@ clear the Chromium data in your account </message> <message name="IDS_SYNC_PASSPHRASE_DIALOG_BODY" desc=""> - Your data is encrypted with your passphrase. Enter it to use and save Chromium data in your Google account. + Your data is encrypted with your passphrase. Enter it to use and save Chromium data in your Google Account. </message> <message name="IDS_AVATAR_BUTTON_INTERCEPT_BUBBLE_CHROME_SIGNIN_ACCESSIBILITY_LABEL" desc="Accessibility label (read by the accessibility tools) of the avatar button when the Chromium Signin bubble is shown. The text implies that the expanded bubble underneath the button is closable by clicking on the button. The actual text is 'Sign in to Chromium?' with a bubble shown under it."> @@ -1254,6 +1254,9 @@ <message name="IDS_PROFILE_MENU_BROWSER_MANAGED_HEADER" desc="Disclaimer indicating that Chromium is managed"> Chromium is managed </message> + <message name="IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME" desc="Placeholder profile name, used when the user did not enter a name for their profile."> + Your Chromium + </message> <if expr="not use_titlecase"> <message name="IDS_PROFILE_MENU_SIGN_OUT_WHEN_SIGNIN_PENDING" desc="The text label of the Sign out of Chromium button in the Profile Menu when the user is in sign in pending state."> Remove account from Chromium
diff --git a/chrome/app/chromium_strings_grd/IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME.png.sha1 b/chrome/app/chromium_strings_grd/IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME.png.sha1 new file mode 100644 index 0000000..917f98de1 --- /dev/null +++ b/chrome/app/chromium_strings_grd/IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME.png.sha1
@@ -0,0 +1 @@ +9d066197d4593378e583550bff26105c1fcc36ce \ No newline at end of file
diff --git a/chrome/app/chromium_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1 b/chrome/app/chromium_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1 index f1bfc9b..a1ff932 100644 --- a/chrome/app/chromium_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1 +++ b/chrome/app/chromium_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1
@@ -1 +1 @@ -8e37738d4f94ab6fe523e6b40e7e73a1b9bd29cc \ No newline at end of file +6b589eb7cc2b6bb99f1f20d67034defc0c27532c \ No newline at end of file
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a053b76..5571529 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd
@@ -1377,7 +1377,7 @@ {NUM_PROFILES, plural, =1 {&Close this profile} other {&Close this profile (# windows)}} </message> <message name="IDS_MANAGE_GOOGLE_ACCOUNT" desc="The text label of the Manage Google account item"> - Manage your &Google account + Manage your &Google Account </message> <message name="IDS_OTHER_CHROME_PROFILES_TITLE" desc="The title of the Other Chrome profiles section"> Other Chrome profiles
diff --git a/chrome/app/generated_resources_grd/IDS_MANAGE_GOOGLE_ACCOUNT.png.sha1 b/chrome/app/generated_resources_grd/IDS_MANAGE_GOOGLE_ACCOUNT.png.sha1 index 4c4ff18..b5f4a23 100644 --- a/chrome/app/generated_resources_grd/IDS_MANAGE_GOOGLE_ACCOUNT.png.sha1 +++ b/chrome/app/generated_resources_grd/IDS_MANAGE_GOOGLE_ACCOUNT.png.sha1
@@ -1 +1 @@ -8b375ced377c641a49d14d4c9f4624fab1e2e664 \ No newline at end of file +20c3b4326fb28d2c1f2aae59ef2e2422fbe0ffe8 \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index fc50ccb..c9d9ba2d 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd
@@ -1150,7 +1150,7 @@ clear the Chrome data in your account </message> <message name="IDS_SYNC_PASSPHRASE_DIALOG_BODY" desc=""> - Your data is encrypted with your passphrase. Enter it to use and save Chrome data in your Google account. + Your data is encrypted with your passphrase. Enter it to use and save Chrome data in your Google Account. </message> <message name="IDS_AVATAR_BUTTON_INTERCEPT_BUBBLE_CHROME_SIGNIN_ACCESSIBILITY_LABEL" desc="Accessibility label (read by the accessibility tools) of the avatar button when the Chrome Signin bubble is shown. The text implies that the expanded bubble underneath the button is closable by clicking on the button. The actual text is 'Sign in to Chrome?' with a bubble shown under it."> @@ -1224,6 +1224,9 @@ <message name="IDS_PROFILE_MENU_BROWSER_MANAGED_HEADER" desc="Disclaimer indicating that Chrome is managed"> Chrome is managed </message> + <message name="IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME" desc="Placeholder profile name, used when the user did not enter a name for their profile."> + Your Chrome + </message> <if expr="not use_titlecase"> <message name="IDS_PROFILE_MENU_SIGN_OUT_WHEN_SIGNIN_PENDING" desc="The text label of the Sign out of Chrome button in the Profile Menu when the user is in sign in pending state."> Remove account from Chrome
diff --git a/chrome/app/google_chrome_strings_grd/IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME.png.sha1 new file mode 100644 index 0000000..917f98de1 --- /dev/null +++ b/chrome/app/google_chrome_strings_grd/IDS_PROFILE_MENU_PLACEHOLDER_PROFILE_NAME.png.sha1
@@ -0,0 +1 @@ +9d066197d4593378e583550bff26105c1fcc36ce \ No newline at end of file
diff --git a/chrome/app/google_chrome_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1 b/chrome/app/google_chrome_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1 index f1bfc9b..a1ff932 100644 --- a/chrome/app/google_chrome_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1 +++ b/chrome/app/google_chrome_strings_grd/IDS_SYNC_PASSPHRASE_DIALOG_BODY.png.sha1
@@ -1 +1 @@ -8e37738d4f94ab6fe523e6b40e7e73a1b9bd29cc \ No newline at end of file +6b589eb7cc2b6bb99f1f20d67034defc0c27532c \ No newline at end of file
diff --git a/chrome/app/shared_settings_strings.grdp b/chrome/app/shared_settings_strings.grdp index e4d3010..419f16b 100644 --- a/chrome/app/shared_settings_strings.grdp +++ b/chrome/app/shared_settings_strings.grdp
@@ -310,6 +310,9 @@ <message name="IDS_SETTINGS_ERROR_RECOVERABILITY_DEGRADED_FOR_PASSWORDS_USER_ERROR_DESCRIPTION" desc="Error description of a sync error header of desktop settings page that prompts the user to add recovery options."> To make sure you can always use the passwords in your Google Account, verify it's you </message> + <message name="IDS_SETTINGS_PEOPLE_ACCOUNT_AWARE_SIGNIN_ACCOUNT_ROW_SUBTITLE_WITH_EMAIL" desc="The subtitle of the avatar row shown to users who are signed in only to the web"> + To get your passwords and more on all your devices, sign in as <ph name="EMAIL">$1<ex>johndoe@gmail.com</ex></ph> + </message> <!-- Signout Subpage (strings used by the <settings-signout-dialog> element) --> <message name="IDS_SETTINGS_SYNC_DISCONNECT_CONFIRM" desc="The text to display on the button to confirm the user wishes to stop syncing.">
diff --git a/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_ACCOUNT_AWARE_SIGNIN_ACCOUNT_ROW_SUBTITLE_WITH_EMAIL.png.sha1 b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_ACCOUNT_AWARE_SIGNIN_ACCOUNT_ROW_SUBTITLE_WITH_EMAIL.png.sha1 new file mode 100644 index 0000000..c800a7c --- /dev/null +++ b/chrome/app/shared_settings_strings_grdp/IDS_SETTINGS_PEOPLE_ACCOUNT_AWARE_SIGNIN_ACCOUNT_ROW_SUBTITLE_WITH_EMAIL.png.sha1
@@ -0,0 +1 @@ +bf840ad22d6e01205a88dbf27c613a29598467f2 \ No newline at end of file
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index 4cb27dc..968f2f9 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -4708,8 +4708,6 @@ "nearby_sharing/nearby_share_logger.h", "nearby_sharing/nearby_share_metrics.cc", "nearby_sharing/nearby_share_metrics.h", - "nearby_sharing/nearby_share_profile_info_provider_impl.cc", - "nearby_sharing/nearby_share_profile_info_provider_impl.h", "nearby_sharing/nearby_share_settings.cc", "nearby_sharing/nearby_share_settings.h", "nearby_sharing/nearby_share_transfer_profiler.cc",
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 2c8b5c4..c39273d 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -8003,6 +8003,12 @@ kOsCrOS, FEATURE_VALUE_TYPE(features::kAccessibilityMagnifierFollowsChromeVox)}, + {"enable-accessibility-manifest-v3-enhanced-network-tts", + flag_descriptions::kAccessibilityManifestV3EnhancedNetworkTtsName, + flag_descriptions::kAccessibilityManifestV3EnhancedNetworkTtsDescription, + kOsCrOS, + FEATURE_VALUE_TYPE(features::kAccessibilityManifestV3EnhancedNetworkTts)}, + {"enable-accessibility-mousekeys", flag_descriptions::kAccessibilityMouseKeysName, flag_descriptions::kAccessibilityMouseKeysDescription, kOsCrOS, @@ -8829,6 +8835,10 @@ flag_descriptions::kFedCmIdPRegistrationDescription, kOsDesktop, FEATURE_VALUE_TYPE(features::kFedCmIdPRegistration)}, + {"fedcm-lightweight-mode", flag_descriptions::kFedCmLightweightModeName, + flag_descriptions::kFedCmLightweightModeDescription, kOsDesktop, + FEATURE_VALUE_TYPE(features::kFedCmLightweightMode)}, + {"fedcm-metrics-endpoint", flag_descriptions::kFedCmMetricsEndpointName, flag_descriptions::kFedCmMetricsEndpointDescription, kOsAll, FEATURE_VALUE_TYPE(features::kFedCmMetricsEndpoint)},
diff --git a/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc b/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc index cda6c95..f938592 100644 --- a/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc +++ b/chrome/browser/android/customtabs/tab_interaction_recorder_browsertest.cc
@@ -129,10 +129,6 @@ "/autofill/iframe_autocomplete_simple_form.html"); } - base::FilePath GetChromeTestDataDir() { - return base::FilePath(FILE_PATH_LITERAL("chrome/test/data")); - } - base::HistogramTester histogram_tester_; private:
diff --git a/chrome/browser/apps/guest_view/web_view_browsertest.cc b/chrome/browser/apps/guest_view/web_view_browsertest.cc index 97b9b6c5..f99247f 100644 --- a/chrome/browser/apps/guest_view/web_view_browsertest.cc +++ b/chrome/browser/apps/guest_view/web_view_browsertest.cc
@@ -5387,6 +5387,8 @@ } IN_PROC_BROWSER_TEST_P(WebViewAccessibilityTest, FocusAccessibility) { + SKIP_FOR_MPARCH(); // TODO(crbug.com/40202416): Enable test for MPArch. + content::ScopedAccessibilityModeOverride mode_override(ui::kAXModeComplete); LoadAppWithGuest("web_view/focus_accessibility"); content::WebContents* web_contents = GetFirstAppWindowWebContents();
diff --git a/chrome/browser/ash/accessibility/accessibility_manager.cc b/chrome/browser/ash/accessibility/accessibility_manager.cc index 76fdaed..d6474cf 100644 --- a/chrome/browser/ash/accessibility/accessibility_manager.cc +++ b/chrome/browser/ash/accessibility/accessibility_manager.cc
@@ -2281,7 +2281,8 @@ const bool enable_v3_manifest = base::CommandLine::ForCurrentProcess()->HasSwitch( - ::switches::kEnableExperimentalAccessibilityManifestV3); + ::switches::kEnableExperimentalAccessibilityManifestV3) || + ::features::IsAccessibilityManifestV3EnabledForEnhancedNetworkTts(); const base::FilePath::CharType* manifest_filename = enable_v3_manifest ? extension_misc::kEnhancedNetworkTtsManifestV3Filename : extension_misc::kEnhancedNetworkTtsManifestFilename;
diff --git a/chrome/browser/ash/app_list/arc/arc_app_icon.cc b/chrome/browser/ash/app_list/arc/arc_app_icon.cc index b0baf45..3385fdc 100644 --- a/chrome/browser/ash/app_list/arc/arc_app_icon.cc +++ b/chrome/browser/ash/app_list/arc/arc_app_icon.cc
@@ -16,7 +16,6 @@ #include "base/functional/bind.h" #include "base/lazy_instance.h" #include "base/memory/raw_ref.h" -#include "base/metrics/histogram_functions.h" #include "base/no_destructor.h" #include "base/ranges/algorithm.h" #include "base/task/thread_pool.h" @@ -752,17 +751,6 @@ image_skia.AddRepresentation(image_rep); image_skia.RemoveUnsupportedRepresentationsForScale(image_rep.scale()); - // TODO(crbug.com/40131344): Track the adaptive icon load time in a separate - // UMA. - if (icon_loaded_count_++ < 5) { - base::UmaHistogramTimes( - "Arc.IconLoadFromFileTime.uncompressedFirst5", - base::Time::Now() - incomplete_scale_factors[scale_factor]); - } else { - base::UmaHistogramTimes( - "Arc.IconLoadFromFileTime.uncompressedOthers", - base::Time::Now() - incomplete_scale_factors[scale_factor]); - } incomplete_scale_factors.erase(scale_factor); observer_->OnIconUpdated(this); } @@ -772,15 +760,6 @@ DCHECK_CURRENTLY_ON(content::BrowserThread::UI); compressed_images_[scale_factor] = std::move(data); - if (icon_loaded_count_++ < 5) { - base::UmaHistogramTimes( - "Arc.IconLoadFromFileTime.compressedFirst5", - base::Time::Now() - incomplete_scale_factors_[scale_factor]); - } else { - base::UmaHistogramTimes( - "Arc.IconLoadFromFileTime.compressedOthers", - base::Time::Now() - incomplete_scale_factors_[scale_factor]); - } incomplete_scale_factors_.erase(scale_factor); observer_->OnIconUpdated(this); }
diff --git a/chrome/browser/ash/app_list/search/omnibox/omnibox_util.cc b/chrome/browser/ash/app_list/search/omnibox/omnibox_util.cc index 20d51982..0318ef3 100644 --- a/chrome/browser/ash/app_list/search/omnibox/omnibox_util.cc +++ b/chrome/browser/ash/app_list/search/omnibox/omnibox_util.cc
@@ -11,6 +11,7 @@ #include "base/functional/callback_helpers.h" #include "base/logging.h" #include "base/notreached.h" +#include "base/strings/utf_string_conversions.h" #include "chrome/browser/ash/app_list/search/omnibox/omnibox_result.h" #include "components/bookmarks/browser/bookmark_model.h" #include "components/omnibox/browser/autocomplete_controller.h"
diff --git a/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactory.java b/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactory.java index 90fd100..8e4efa4 100644 --- a/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactory.java +++ b/chrome/browser/auxiliary_search/java/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactory.java
@@ -22,6 +22,9 @@ @Nullable private AuxiliarySearchHooks mHooksForTesting; + /** It tracks whether the current device is a tablet. */ + @Nullable private Boolean mIsTablet; + /** Static class that implements the initialization-on-demand holder idiom. */ private static class LazyHolder { static AuxiliarySearchControllerFactory sInstance = new AuxiliarySearchControllerFactory(); @@ -88,11 +91,13 @@ * Sets whether the device is a tablet. Note: this must be called before checking isEnabled(). */ public void setIsTablet(boolean isTablet) { - if (mHooksForTesting != null) { - mHooksForTesting.setIsTablet(isTablet); - } else if (mHooks != null) { - mHooks.setIsTablet(isTablet); - } + mIsTablet = isTablet || (mIsTablet != null && mIsTablet); + } + + /** Gets whether the device is a tablet. */ + public boolean isTablet() { + assert mIsTablet != null; + return mIsTablet; } private @Nullable AuxiliarySearchController createAuxiliarySearchControllerImp(
diff --git a/chrome/browser/auxiliary_search/junit/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactoryUnitTest.java b/chrome/browser/auxiliary_search/junit/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactoryUnitTest.java index 5b91724..73258bb1 100644 --- a/chrome/browser/auxiliary_search/junit/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactoryUnitTest.java +++ b/chrome/browser/auxiliary_search/junit/src/org/chromium/chrome/browser/auxiliary_search/AuxiliarySearchControllerFactoryUnitTest.java
@@ -140,13 +140,14 @@ @Test @SmallTest public void testSetIsTablet() { - AuxiliarySearchHooks hooksMock = Mockito.mock(AuxiliarySearchHooks.class); - mFactory.setHooksForTesting(hooksMock); + mFactory.setIsTablet(false); + assertFalse(mFactory.isTablet()); mFactory.setIsTablet(true); - verify(hooksMock).setIsTablet(eq(true)); + assertTrue(mFactory.isTablet()); + // Verifies the isTablet() never goes from true to false. mFactory.setIsTablet(false); - verify(hooksMock).setIsTablet(eq(false)); + assertTrue(mFactory.isTablet()); } }
diff --git a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java index fccfe50..f195366 100644 --- a/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java +++ b/chrome/browser/back_press/android/java/src/org/chromium/chrome/browser/back_press/BackPressMetrics.java
@@ -13,6 +13,7 @@ import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.components.browser_ui.widget.gesture.BackPressHandler.Type; import org.chromium.ui.UiUtils; +import org.chromium.ui.base.BackGestureEventSwipeEdge; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -33,6 +34,7 @@ "Android.BackPress.IncorrectEdgeSwipe"; private static final String INCORRECT_EDGE_SWIPE_COUNT_CHAINED_HISTOGRAM = "Android.BackPress.IncorrectEdgeSwipe.CountChained"; + private static final String BACK_FALSING_HISTOGRAM = "Android.BackPress.Backfalsing"; @IntDef({ PredictiveGestureNavPhase.ACTIVATED, @@ -48,8 +50,30 @@ int NUM_ENTRIES = 3; } + @IntDef({ + NavigationDirection.FORWARD, + NavigationDirection.BACKWARD, + NavigationDirection.NEITHER + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NavigationDirection { + int FORWARD = 0; + int BACKWARD = 1; + int NEITHER = 2; + + int NUM_ENTRIES = 3; + } + /** - * @param edge The edge from which the gesture is swiped from {@link BackEventCompat}. + * @param navigationDirection The direction of the navigation. + */ + public static void recordBackFalsing(@NavigationDirection int navigationDirection) { + RecordHistogram.recordEnumeratedHistogram( + BACK_FALSING_HISTOGRAM, navigationDirection, NavigationDirection.NUM_ENTRIES); + } + + /** + * @param edge The edge from which the gesture is swiped from {@link BackGestureEventSwipeEdge}. */ public static void recordIncorrectEdgeSwipe(int edge) { RecordHistogram.recordEnumeratedHistogram(INCORRECT_EDGE_SWIPE_HISTOGRAM, edge, 2);
diff --git a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc index 675adb3..fafb50a 100644 --- a/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc +++ b/chrome/browser/browsing_topics/browsing_topics_service_browsertest.cc
@@ -21,7 +21,6 @@ #include "chrome/browser/ui/browser.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" -#include "components/browsing_topics/browsing_topics_service.h" #include "components/browsing_topics/browsing_topics_service_impl.h" #include "components/browsing_topics/epoch_topics.h" #include "components/browsing_topics/test_util.h" @@ -623,6 +622,105 @@ base::CallbackListSubscription subscription_; }; +class BrowsingTopicsSubresourceRequestTest + : public BrowsingTopicsBrowserTest, + public ::testing::WithParamInterface<bool> { + public: + // If true, test the fetch option. If false, test the img attribute. + bool TestFetch() { return GetParam(); } + + std::string GetRelativePath() { + if (TestFetch()) { + return "/browsing_topics/page_with_custom_topics_header.html"; + } + + return "/browsing_topics/topics-writable-pixel.png"; + } + + std::string GetRedirectRelativePath() { + if (TestFetch()) { + return "/browsing_topics/page_with_custom_topics_header2.html"; + } + + return "/browsing_topics/topics-writable-pixel2.png"; + } + + bool ExecJsWithBrowsingTopicsTrue(GURL url) { + if (TestFetch()) { + return ExecJs( + web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {browsingTopics: true})", url)); + } + + return ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace(R"( + let img = document.createElement('img'); + img.src = $1; + img.browsingTopics = true; + img.decode() + .then(() => { + document.body.appendChild(img); + }) + )", + url.spec())); + } + + bool ExecJSWithBrowsingTopicsFalse(GURL url) { + if (TestFetch()) { + return ExecJs( + web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {browsingTopics: false})", url)); + } + + return ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace(R"( + let img = document.createElement('img'); + img.src = $1; + img.browsingTopics = false; + img.decode() + .then(() => { + document.body.appendChild(img); + }) + )", + url.spec())); + } + + bool ExecJsWithMissingBrowsingTopicsAttribute(GURL url) { + if (TestFetch()) { + return ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1)", url)); + } + + return ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace(R"( + let img = document.createElement('img'); + img.src = $1; + img.decode() + .then(() => { + document.body.appendChild(img); + }) + )", + url.spec())); + } + + int GetBrowsingTopicsApiActionType(bool observe) { + if (TestFetch()) { + if (observe) { + return 3; // kObserveViaFetchLikeApi + } + return 2; // kGetViaFetchLikeApi; + } + if (observe) { + return 7; // kObserveViaImgAttributeApi + } + return 6; // kGetViaImgAttributeApi + } +}; + +INSTANTIATE_TEST_SUITE_P(All, + BrowsingTopicsSubresourceRequestTest, + ::testing::Bool()); + IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, HasBrowsingTopicsService) { EXPECT_TRUE(browsing_topics_service()); } @@ -1163,24 +1261,19 @@ ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), new_url)); } -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchSameOrigin_TopicsEligible_SendTopics_HasNoObserveResponse) { +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + SameOrigin_TopicsEligible_SendTopics_HasNoObserveResponse) { GURL main_frame_url = https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - GURL fetch_url = https_server_.GetURL( - "a.test", "/browsing_topics/page_with_custom_topics_header.html"); + GURL resource_url = https_server_.GetURL("a.test", GetRelativePath()); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); - + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_TRUE(topics_header_value); EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteA); @@ -1191,23 +1284,22 @@ EXPECT_EQ(api_usage_contexts.size(), 1u); } -IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, FetchWithoutTopicsFlagSet) { +IN_PROC_BROWSER_TEST_P(BrowsingTopicsSubresourceRequestTest, + WithoutTopicsFlagSet) { GURL main_frame_url = https_server_.GetURL("b.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - GURL fetch_url = https_server_.GetURL( - "b.test", "/browsing_topics/page_with_custom_topics_header.html"); + GURL resource_url = https_server_.GetURL("b.test", GetRelativePath()); { - // Invoke fetch() without the `browsingTopics` flag. This request isn't - // eligible for topics. - EXPECT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1)", fetch_url))); + // Invoke fetch() or img without the `browsingTopics` flag. This request + // isn't eligible for topics. + + EXPECT_TRUE(ExecJsWithMissingBrowsingTopicsAttribute(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); // Expect no topics header as the request did not specify // {browsingTopics: true}. @@ -1215,15 +1307,12 @@ } { - // Invoke fetch() with the `browsingTopics` flag set to false. This request - // isn't eligible for topics. - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: false})", fetch_url))); + // Invoke fetch() or img with the `browsingTopics` flag set to false. This + // request isn't eligible for topics. + EXPECT_TRUE(ExecJSWithBrowsingTopicsFalse(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); // Expect no topics header as the request did not specify // {browsingTopics: true}. @@ -1231,25 +1320,21 @@ } } -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchSameOrigin_TopicsEligible_SendNoTopic_HasNoObserveResponse) { +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + SameOrigin_TopicsEligible_SendNoTopic_HasNoObserveResponse) { base::HistogramTester histogram_tester; GURL main_frame_url = https_server_.GetURL("b.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - GURL fetch_url = https_server_.GetURL( - "b.test", "/browsing_topics/page_with_custom_topics_header.html"); + GURL resource_url = https_server_.GetURL("b.test", GetRelativePath()); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); // Expect an empty header value as "b.test" did not observe the candidate // topics. @@ -1262,14 +1347,15 @@ content::GetBrowsingTopicsApiUsage(browsing_topics_site_data_manager()); EXPECT_EQ(api_usage_contexts.size(), 1u); - histogram_tester.ExpectUniqueSample(kBrowsingTopicsApiActionTypeHistogramId, - 2 /*kGetViaFetchLikeApi*/, - /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample( + kBrowsingTopicsApiActionTypeHistogramId, + GetBrowsingTopicsApiActionType(/*observe=*/false), + /*expected_bucket_count=*/1); } -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchSameOrigin_TopicsEligible_SendNoTopic_HasObserveResponse) { +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + SameOrigin_TopicsEligible_SendNoTopic_HasObserveResponse) { base::HistogramTester histogram_tester; GURL main_frame_url = @@ -1282,15 +1368,11 @@ "Observe-Browsing-Topics: ?1")); replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); - GURL fetch_url = https_server_.GetURL( - "b.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "b.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); // A new observation should have been recorded in addition to the pre-existing // one, as the response had the `Observe-Browsing-Topics: ?1` header and the @@ -1310,17 +1392,19 @@ // Expect a "get" event and an "observe" event respectively. histogram_tester.ExpectTotalCount(kBrowsingTopicsApiActionTypeHistogramId, /*expected_count=*/2); - histogram_tester.ExpectBucketCount(kBrowsingTopicsApiActionTypeHistogramId, - 2 /*kGetViaFetchLikeApi*/, - /*expected_count=*/1); - histogram_tester.ExpectBucketCount(kBrowsingTopicsApiActionTypeHistogramId, - 3 /*kObserveViaFetchLikeApi*/, - /*expected_count=*/1); + histogram_tester.ExpectBucketCount( + kBrowsingTopicsApiActionTypeHistogramId, + GetBrowsingTopicsApiActionType(/*observe=*/false), + /*expected_count=*/1); + histogram_tester.ExpectBucketCount( + kBrowsingTopicsApiActionTypeHistogramId, + GetBrowsingTopicsApiActionType(/*observe=*/true), + /*expected_count=*/1); } -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchSameOrigin_TopicsNotEligibleDueToUserSettings_HasObserveResponse) { +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + SameOrigin_TopicsNotEligibleDueToUserSettings_HasObserveResponse) { GURL main_frame_url = https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); @@ -1331,22 +1415,17 @@ "Observe-Browsing-Topics: ?1")); replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); - GURL fetch_url = https_server_.GetURL( - "a.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); CookieSettingsFactory::GetForProfile(browser()->profile()) - ->SetCookieSetting(fetch_url, CONTENT_SETTING_BLOCK); + ->SetCookieSetting(resource_url, CONTENT_SETTING_BLOCK); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); // When the request is ineligible for topics due to user settings, an empty // list of topics will be sent in the header. @@ -1360,9 +1439,9 @@ EXPECT_EQ(api_usage_contexts.size(), 1u); } -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchCrossOrigin_TopicsEligible_SendTopics_HasObserveResponse) { +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + CrossOrigin_TopicsEligible_SendTopics_HasObserveResponse) { GURL main_frame_url = https_server_.GetURL("b.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); @@ -1373,19 +1452,14 @@ "Observe-Browsing-Topics: ?1")); replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); - GURL fetch_url = https_server_.GetURL( - "a.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_TRUE(topics_header_value); EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteB); @@ -1406,28 +1480,31 @@ EXPECT_EQ(api_usage_contexts[1].hashed_context_domain, HashedDomain(1)); } -// On an insecure site (i.e. URL with http scheme), test fetch request with -// the `browsingTopics` set to true. Expect it to throw an exception. -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchCrossOrigin_TopicsNotEligibleDueToInsecureInitiatorContext) { +// On an insecure site (i.e. URL with http scheme), test a fetch or image +// request with the `browsingTopics` set to true. Expect it to throw an +// exception. +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + CrossOrigin_TopicsNotEligibleDueToInsecureInitiatorContext) { GURL main_frame_url = embedded_test_server()->GetURL( "b.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - GURL fetch_url = - https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); + GURL resource_url = https_server_.GetURL("a.test", GetRelativePath()); - content::EvalJsResult result = EvalJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url)); - - EXPECT_THAT(result.error, - testing::HasSubstr("browsingTopics: Topics operations are only " - "available in secure contexts.")); + if (TestFetch()) { + content::EvalJsResult result = EvalJs( + web_contents()->GetPrimaryMainFrame(), + content::JsReplace("fetch($1, {browsingTopics: true})", resource_url)); + EXPECT_THAT(result.error, + testing::HasSubstr("browsingTopics: Topics operations are only " + "available in secure contexts.")); + } else { + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); + } std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath("/browsing_topics/empty_page.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); // Expect no topics header as the request was not eligible for topics due to // insecure initiator context. @@ -1436,9 +1513,9 @@ // Only allow topics from origin c.test, and test fetch requests to b.test and // c.test to verify that only c.test gets them. -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchCrossOrigin_TopicsNotEligibleDueToPermissionsPolicyAgainstRequestOrigin) { +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + CrossOrigin_TopicsNotEligibleDueToPermissionsPolicyAgainstRequestOrigin) { base::StringPairs allowed_origin_replacement; allowed_origin_replacement.emplace_back( "{{ALLOWED_ORIGIN}}", https_server_.GetOrigin("c.test").Serialize()); @@ -1454,15 +1531,12 @@ { base::HistogramTester histogram_tester; - GURL fetch_url = - https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); + GURL resource_url = https_server_.GetURL("a.test", GetRelativePath()); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath("/browsing_topics/empty_page.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); // No topics header was sent, as the permissions policy denied it. EXPECT_FALSE(topics_header_value); @@ -1477,31 +1551,29 @@ { base::HistogramTester histogram_tester; - GURL fetch_url = - https_server_.GetURL("c.test", "/browsing_topics/empty_page.html"); + GURL resource_url = https_server_.GetURL("c.test", GetRelativePath()); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath("/browsing_topics/empty_page.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_TRUE(topics_header_value); - histogram_tester.ExpectUniqueSample(kBrowsingTopicsApiActionTypeHistogramId, - 2 /*kGetViaFetchLikeApi*/, - /*expected_bucket_count=*/1); + histogram_tester.ExpectUniqueSample( + kBrowsingTopicsApiActionTypeHistogramId, + GetBrowsingTopicsApiActionType(/*observe=*/false), + /*expected_bucket_count=*/1); } } -// On site b.test, test fetch request to a.test that gets redirected to c.test. -// The topics header should be calculated for them individually (i.e. given that -// only a.test has observed the candidate topics for site b.test, the request to -// a.test should have a non-empty topics header, while the redirected request to -// c.test should have an empty topics header.) -IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, - FetchCrossOriginWithRedirect) { +// On site b.test, test a fetch or image request to a.test that gets redirected +// to c.test. The topics header should be calculated for them individually (i.e. +// given that only a.test has observed the candidate topics for site b.test, the +// request to a.test should have a non-empty topics header, while the redirected +// request to c.test should have an empty topics header.) +IN_PROC_BROWSER_TEST_P(BrowsingTopicsSubresourceRequestTest, + CrossOriginWithRedirect) { base::HistogramTester histogram_tester; GURL main_frame_url = @@ -1517,9 +1589,7 @@ GURL redirect_url = https_server_.GetURL( "c.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header2.html", - redirect_replacement)); + GetRedirectRelativePath(), redirect_replacement)); base::StringPairs replacement; replacement.emplace_back( @@ -1529,27 +1599,21 @@ replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "Location: " + redirect_url.spec())); - GURL fetch_url = https_server_.GetURL( - "a.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); { std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_TRUE(topics_header_value); EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteB); } { std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header2.html"); + GetTopicsHeaderForRequestPath(GetRedirectRelativePath()); EXPECT_TRUE(topics_header_value); // An empty topics header value was sent, because "c.test" did not observe @@ -1580,22 +1644,24 @@ // and the redirect respectively. histogram_tester.ExpectTotalCount(kBrowsingTopicsApiActionTypeHistogramId, /*expected_count=*/4); - histogram_tester.ExpectBucketCount(kBrowsingTopicsApiActionTypeHistogramId, - 2 /*kGetViaFetchLikeApi*/, - /*expected_count=*/2); - histogram_tester.ExpectBucketCount(kBrowsingTopicsApiActionTypeHistogramId, - 3 /*kObserveViaFetchLikeApi*/, - /*expected_count=*/2); + histogram_tester.ExpectBucketCount( + kBrowsingTopicsApiActionTypeHistogramId, + GetBrowsingTopicsApiActionType(/*observe=*/false), + /*expected_count=*/2); + histogram_tester.ExpectBucketCount( + kBrowsingTopicsApiActionTypeHistogramId, + GetBrowsingTopicsApiActionType(/*observe=*/true), + /*expected_count=*/2); } -// On site b.test, test fetch request to a.test that gets redirected to c.test. -// The topics header eligibility should be checked for them individually (i.e. -// given that the declared policy on the page only allows origin c.test, the -// request to a.test should not have the topics header, while the redirected -// request to c.test should have the topics header.) -IN_PROC_BROWSER_TEST_F( - BrowsingTopicsBrowserTest, - FetchCrossOriginWithRedirect_InitialRequestTopicsNotEligibleDueToPermissionsPolicy) { +// On site b.test, test a fetch or image request to a.test that gets redirected +// to c.test. The topics header eligibility should be checked for them +// individually (i.e. given that the declared policy on the page only allows +// origin c.test, the request to a.test should not have the topics header, while +// the redirected request to c.test should have the topics header.) +IN_PROC_BROWSER_TEST_P( + BrowsingTopicsSubresourceRequestTest, + CrossOriginWithRedirect_InitialRequestTopicsNotEligibleDueToPermissionsPolicy) { base::StringPairs allowed_origin_replacement; allowed_origin_replacement.emplace_back( "{{ALLOWED_ORIGIN}}", https_server_.GetOrigin("c.test").Serialize()); @@ -1616,9 +1682,7 @@ GURL redirect_url = https_server_.GetURL( "c.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header2.html", - redirect_replacement)); + GetRedirectRelativePath(), redirect_replacement)); base::StringPairs replacement; replacement.emplace_back( @@ -1628,28 +1692,22 @@ replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "Location: " + redirect_url.spec())); - GURL fetch_url = https_server_.GetURL( - "a.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); { std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); // No topics header was sent, as the permissions policy denied it. EXPECT_FALSE(topics_header_value); } { std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header2.html"); + GetTopicsHeaderForRequestPath(GetRedirectRelativePath()); EXPECT_TRUE(topics_header_value); // An empty topics header value was sent, as "c.test" did not observe the @@ -1739,6 +1797,73 @@ } } +IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, UseCounter_Img_Unused) { + base::HistogramTester histogram_tester; + + GURL main_frame_url = + https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); + + GURL img_url = https_server_.GetURL( + "a.test", "/browsing_topics/topics-writable-pixel.png"); + + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + // Request an image with `browsingTopics` set to false. Expect no + // `kTopicsAPIImg` use counter. + EXPECT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace(R"( + let img = document.createElement('img'); + img.src = $1; + img.browsingTopics = false; + img.decode() + .then(() => { + document.body.appendChild(img); + }) + )", + img_url.spec()))); + + // Navigate away to flush use counters. + ASSERT_TRUE( + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); + + histogram_tester.ExpectBucketCount( + "Blink.UseCounter.Features", blink::mojom::WebFeature::kTopicsAPIImg, 0); +} + +IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, UseCounter_Img_Used) { + base::HistogramTester histogram_tester; + + GURL main_frame_url = + https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); + + GURL img_url = https_server_.GetURL( + "a.test", "/browsing_topics/topics-writable-pixel.png"); + ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); + + // Request an img with `browsingTopics` set to true. Expect one + // `kTopicsAPIImg` use counter. + EXPECT_TRUE(ExecJs(web_contents()->GetPrimaryMainFrame(), + content::JsReplace(R"( + let img = document.createElement('img'); + img.src = $1; + img.browsingTopics = true; + img.decode() + .then(() => { + document.body.appendChild(img); + }) + )", + img_url.spec()))); + + // Navigate away to flush use counters. + ASSERT_TRUE( + ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL))); + + histogram_tester.ExpectBucketCount( + "Blink.UseCounter.Features", blink::mojom::WebFeature::kTopicsAPIImg, 1); + histogram_tester.ExpectBucketCount( + "Blink.UseCounter.Features", blink::mojom::WebFeature::kTopicsAPIAll, 1); +} + // For a page that contains a static <iframe> with a "browsingtopics" // attribute, the iframe navigation request should be eligible for topics. IN_PROC_BROWSER_TEST_F(BrowsingTopicsBrowserTest, @@ -2463,6 +2588,24 @@ ~AttestationBrowsingTopicsBrowserTest() override = default; }; +class AttestationSubresourceRequestTest + : public BrowsingTopicsSubresourceRequestTest { + public: + void SetUpOnMainThread() override { + // This test suite tests Privacy Sandbox Attestations related behaviors, + // turn off the setting that makes all APIs considered attested. + BrowsingTopicsBrowserTest::SetUpOnMainThread(); + privacy_sandbox::PrivacySandboxAttestations::GetInstance() + ->SetAllPrivacySandboxAttestedForTesting(false); + } + + ~AttestationSubresourceRequestTest() override = default; +}; + +INSTANTIATE_TEST_SUITE_P(All, + AttestationSubresourceRequestTest, + ::testing::Bool()); + // Site a.test is attested for Topics, so it should receive a valid response. IN_PROC_BROWSER_TEST_F(AttestationBrowsingTopicsBrowserTest, AttestedSiteCanGetBrowsingTopicsViaDocumentAPI) { @@ -2542,8 +2685,8 @@ EXPECT_FALSE(console_observer.messages().empty()); } -IN_PROC_BROWSER_TEST_F(AttestationBrowsingTopicsBrowserTest, - FetchSameOrigin_TopicsEligible_SendTopics_SiteAttested) { +IN_PROC_BROWSER_TEST_P(AttestationSubresourceRequestTest, + SameOrigin_TopicsEligible_SendTopics_SiteAttested) { privacy_sandbox::PrivacySandboxAttestationsMap map; map.insert_or_assign( net::SchemefulSite(GURL("https://a.test")), @@ -2559,16 +2702,12 @@ https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - GURL fetch_url = https_server_.GetURL( - "a.test", "/browsing_topics/page_with_custom_topics_header.html"); + GURL resource_url = https_server_.GetURL("a.test", GetRelativePath()); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_TRUE(topics_header_value); EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteA); @@ -2576,8 +2715,8 @@ EXPECT_TRUE(console_observer.messages().empty()); } -IN_PROC_BROWSER_TEST_F(AttestationBrowsingTopicsBrowserTest, - FetchSameOrigin_TopicsEligible_SiteNotAttested) { +IN_PROC_BROWSER_TEST_P(AttestationSubresourceRequestTest, + SameOrigin_TopicsEligible_SiteNotAttested) { privacy_sandbox::PrivacySandboxAttestationsMap map; map.insert_or_assign( net::SchemefulSite(GURL("https://b.test")), @@ -2593,16 +2732,12 @@ https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - GURL fetch_url = https_server_.GetURL( - "a.test", "/browsing_topics/page_with_custom_topics_header.html"); + GURL resource_url = https_server_.GetURL("a.test", GetRelativePath()); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_EQ(topics_header_value, kExpectedHeaderValueForEmptyTopics); @@ -2610,9 +2745,8 @@ EXPECT_FALSE(console_observer.messages().empty()); } -IN_PROC_BROWSER_TEST_F( - AttestationBrowsingTopicsBrowserTest, - FetchSameOrigin_TopicsEligible_SiteAttested_MismatchedMap) { +IN_PROC_BROWSER_TEST_P(AttestationSubresourceRequestTest, + SameOrigin_TopicsEligible_SiteAttested_MismatchedMap) { privacy_sandbox::PrivacySandboxAttestationsMap map; map.insert_or_assign(net::SchemefulSite(GURL("https://a.test")), privacy_sandbox::PrivacySandboxAttestationsGatedAPISet{ @@ -2628,16 +2762,12 @@ https_server_.GetURL("a.test", "/browsing_topics/empty_page.html"); ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_frame_url)); - GURL fetch_url = https_server_.GetURL( - "a.test", "/browsing_topics/page_with_custom_topics_header.html"); + GURL resource_url = https_server_.GetURL("a.test", GetRelativePath()); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_EQ(topics_header_value, kExpectedHeaderValueForEmptyTopics); @@ -2647,9 +2777,9 @@ // Site a.test is attested, so when an x-origin request is made to it from // site b.test, a.test should still include a topics header. -IN_PROC_BROWSER_TEST_F( - AttestationBrowsingTopicsBrowserTest, - FetchCrossOrigin_TopicsEligible_SendTopics_HasObserveResponse_SiteAttested) { +IN_PROC_BROWSER_TEST_P( + AttestationSubresourceRequestTest, + CrossOrigin_TopicsEligible_SendTopics_HasObserveResponse_SiteAttested) { privacy_sandbox::PrivacySandboxAttestationsMap map; map.insert_or_assign( net::SchemefulSite(GURL("https://a.test")), @@ -2671,19 +2801,14 @@ "Observe-Browsing-Topics: ?1")); replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); - GURL fetch_url = https_server_.GetURL( - "a.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_TRUE(topics_header_value); EXPECT_EQ(*topics_header_value, kExpectedHeaderValueForSiteB); @@ -2708,8 +2833,8 @@ // Site a.test is not attested, so this should not generate a Topics header in a // x-origin fetch to site a.test. -IN_PROC_BROWSER_TEST_F(AttestationBrowsingTopicsBrowserTest, - FetchCrossOrigin_TopicsEligible_SiteNotAttested) { +IN_PROC_BROWSER_TEST_P(AttestationSubresourceRequestTest, + CrossOrigin_TopicsEligible_SiteNotAttested) { privacy_sandbox::PrivacySandboxAttestationsMap map; map.insert_or_assign( net::SchemefulSite(GURL("https://b.test")), @@ -2731,19 +2856,14 @@ "Observe-Browsing-Topics: ?1")); replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); - GURL fetch_url = https_server_.GetURL( - "a.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_EQ(topics_header_value, kExpectedHeaderValueForEmptyTopics); @@ -2757,11 +2877,11 @@ EXPECT_FALSE(console_observer.messages().empty()); } -// Site a.test is attested, but not for Topics, so the fetch request to a.test -// should not get a header. -IN_PROC_BROWSER_TEST_F( - AttestationBrowsingTopicsBrowserTest, - FetchCrossOrigin_TopicsEligible_SiteNotAttested_MismatchedMap) { +// Site a.test is attested, but not for Topics, so the fetch/img request to +// a.test should not get a header. +IN_PROC_BROWSER_TEST_P( + AttestationSubresourceRequestTest, + CrossOrigin_TopicsEligible_SiteNotAttested_MismatchedMap) { privacy_sandbox::PrivacySandboxAttestationsMap map; map.insert_or_assign(net::SchemefulSite(GURL("https://a.test")), privacy_sandbox::PrivacySandboxAttestationsGatedAPISet{ @@ -2783,19 +2903,14 @@ "Observe-Browsing-Topics: ?1")); replacement.emplace_back(std::make_pair("{{REDIRECT_HEADER}}", "")); - GURL fetch_url = https_server_.GetURL( - "a.test", net::test_server::GetFilePathWithReplacements( - "/browsing_topics/" - "page_with_custom_topics_header.html", - replacement)); + GURL resource_url = https_server_.GetURL( + "a.test", net::test_server::GetFilePathWithReplacements(GetRelativePath(), + replacement)); - EXPECT_TRUE(ExecJs( - web_contents()->GetPrimaryMainFrame(), - content::JsReplace("fetch($1, {browsingTopics: true})", fetch_url))); + EXPECT_TRUE(ExecJsWithBrowsingTopicsTrue(resource_url)); std::optional<std::string> topics_header_value = - GetTopicsHeaderForRequestPath( - "/browsing_topics/page_with_custom_topics_header.html"); + GetTopicsHeaderForRequestPath(GetRelativePath()); EXPECT_EQ(topics_header_value, kExpectedHeaderValueForEmptyTopics);
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index fba970c..a1a8e77 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc
@@ -343,6 +343,7 @@ #include "content/public/browser/child_process_security_policy.h" #include "content/public/browser/client_certificate_delegate.h" #include "content/public/browser/digital_identity_provider.h" +#include "content/public/browser/dips_delegate.h" #include "content/public/browser/file_url_loader.h" #include "content/public/browser/isolated_web_apps_policy.h" #include "content/public/browser/legacy_tech_cookie_issue_details.h" @@ -1474,6 +1475,15 @@ return web_contents->GetTargetNetwork(); } +ProfileSelections GetHumanProfileSelections() { + return ProfileSelections::Builder() + .WithRegular(ProfileSelection::kOwnInstance) + .WithGuest(ProfileSelection::kOffTheRecordOnly) + .WithSystem(ProfileSelection::kNone) + .WithAshInternals(ProfileSelection::kNone) + .Build(); +} + } // namespace // static @@ -8541,7 +8551,22 @@ std::unique_ptr<content::DipsDelegate> ChromeContentBrowserClient::CreateDipsDelegate() { - return ChromeDipsDelegate::Create(); + return std::make_unique<ChromeDipsDelegate>( + base::PassKey<ChromeContentBrowserClient>()); +} + +bool ChromeContentBrowserClient::ShouldEnableDips( + content::BrowserContext* browser_context) { + return ShouldBrowserContextEnableDips(browser_context); +} + +bool ShouldBrowserContextEnableDips(content::BrowserContext* browser_context) { + Profile* profile = Profile::FromBrowserContext(browser_context); + Profile* result = GetHumanProfileSelections().ApplyProfileSelection(profile); + // TODO: crbug.com/358137275 - Use CHECK() once we know it's safe. + DUMP_WILL_BE_CHECK(!result || result == profile) + << "ApplyProfileSelection() returned a different profile"; + return result == profile; } bool ChromeContentBrowserClient::ShouldSuppressAXLoadComplete(
diff --git a/chrome/browser/chrome_content_browser_client.h b/chrome/browser/chrome_content_browser_client.h index c470bea3..7e866a09 100644 --- a/chrome/browser/chrome_content_browser_client.h +++ b/chrome/browser/chrome_content_browser_client.h
@@ -1080,6 +1080,7 @@ #endif // BUILDFLAG(IS_CHROMEOS) std::unique_ptr<content::DipsDelegate> CreateDipsDelegate() override; + bool ShouldEnableDips(content::BrowserContext* browser_context) override; bool ShouldSuppressAXLoadComplete(content::RenderFrameHost* rfh) override; @@ -1363,4 +1364,8 @@ base::WeakPtrFactory<ChromeContentBrowserClient> weak_factory_{this}; }; +// The implementation of ChromeContentBrowserClient::ShouldEnableDips(), for use +// within //chrome. +bool ShouldBrowserContextEnableDips(content::BrowserContext* browser_context); + #endif // CHROME_BROWSER_CHROME_CONTENT_BROWSER_CLIENT_H_
diff --git a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.cc b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.cc index 88a91b2..049e3f1 100644 --- a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.cc +++ b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.cc
@@ -6,11 +6,8 @@ #include <limits> -#include "base/feature_list.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/profiles/profile.h" -#include "chrome/common/pref_names.h" -#include "components/prefs/pref_service.h" #include "components/reporting/metrics/sampler.h" #include "components/reporting/proto/synced/metric_data.pb.h" #include "content/public/browser/browser_task_traits.h" @@ -19,11 +16,6 @@ namespace reporting { -// static -BASE_FEATURE(kEnableNetworkBandwidthReporting, - "EnableNetworkBandwidthReporting", - base::FEATURE_ENABLED_BY_DEFAULT); - NetworkBandwidthSampler::NetworkBandwidthSampler( ::network::NetworkQualityTracker* network_quality_tracker, base::WeakPtr<Profile> profile) @@ -47,12 +39,6 @@ std::move(callback).Run(std::nullopt); return; } - if (!profile_->GetPrefs()->GetBoolean(::prefs::kInsightsExtensionEnabled) && - !base::FeatureList::IsEnabled(kEnableNetworkBandwidthReporting)) { - // Both policy and feature flag not set, so we return. - std::move(callback).Run(std::nullopt); - return; - } const auto downlink_speed_kbps = network_quality_tracker_->GetDownstreamThroughputKbps();
diff --git a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.h b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.h index 937ea58..c6c41c5c 100644 --- a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.h +++ b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler.h
@@ -5,7 +5,6 @@ #ifndef CHROME_BROWSER_CHROMEOS_REPORTING_NETWORK_NETWORK_BANDWIDTH_SAMPLER_H_ #define CHROME_BROWSER_CHROMEOS_REPORTING_NETWORK_NETWORK_BANDWIDTH_SAMPLER_H_ -#include "base/feature_list.h" #include "base/memory/raw_ptr.h" #include "base/memory/weak_ptr.h" #include "chrome/browser/profiles/profile.h" @@ -14,10 +13,6 @@ namespace reporting { -// Feature flag that controls network bandwidth reporting for affiliated -// ChromeOS users/devices and is used for phased rollout. -BASE_DECLARE_FEATURE(kEnableNetworkBandwidthReporting); - // Sampler used to collect network bandwidth information like download speed // (in kbps). This sampler relies on the `NetworkQualityTracker` defined in // the `NetworkService` to collect said metrics.
diff --git a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_ash_browsertest.cc b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_ash_browsertest.cc index d35ed2d2..cc8d456a4 100644 --- a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_ash_browsertest.cc +++ b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_ash_browsertest.cc
@@ -2,7 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/test/scoped_feature_list.h" #include "chrome/browser/ash/login/test/cryptohome_mixin.h" #include "chrome/browser/ash/login/test/user_auth_config.h" #include "chrome/browser/ash/policy/affiliation/affiliation_mixin.h" @@ -76,7 +75,6 @@ NetworkBandwidthSamplerBrowserTest() { // Initialize the MockClock. test::MockClock::Get(); - scoped_feature_list_.InitAndEnableFeature(kEnableNetworkBandwidthReporting); crypto_home_mixin_.MarkUserAsExisting(affiliation_mixin_.account_id()); crypto_home_mixin_.ApplyAuthConfig( affiliation_mixin_.account_id(), @@ -105,7 +103,6 @@ ::policy::DevicePolicyCrosTestHelper test_helper_; ::policy::AffiliationMixin affiliation_mixin_{&mixin_host_, &test_helper_}; ::ash::CryptohomeMixin crypto_home_mixin_{&mixin_host_}; - base::test::ScopedFeatureList scoped_feature_list_; ::ash::ScopedTestingCrosSettings scoped_testing_cros_settings_; };
diff --git a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_unittest.cc b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_unittest.cc index a38423d33..981ee03 100644 --- a/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_unittest.cc +++ b/chrome/browser/chromeos/reporting/network/network_bandwidth_sampler_unittest.cc
@@ -6,7 +6,6 @@ #include <optional> -#include "base/test/scoped_feature_list.h" #include "base/test/task_environment.h" #include "chrome/browser/browser_process.h" #include "chrome/common/pref_names.h" @@ -82,9 +81,6 @@ TEST_F(NetworkBandwidthSamplerTest, ReportsDownloadSpeedWhenFeatureFlagEnabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeature(kEnableNetworkBandwidthReporting); - UpdateDownloadSpeedKbps(kInitDownloadSpeedKbps); NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(), profile_->GetWeakPtr()); @@ -100,35 +96,6 @@ kInitDownloadSpeedKbps); } -TEST_F(NetworkBandwidthSamplerTest, DoesNotReportDownloadSpeedWhenPrefUnset) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(kEnableNetworkBandwidthReporting); - SetPrefValue(false); - UpdateDownloadSpeedKbps(kInitDownloadSpeedKbps); - NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(), - profile_->GetWeakPtr()); - - ::reporting::test::TestEvent<std::optional<MetricData>> test_event; - sampler.MaybeCollect(test_event.cb()); - const auto result = test_event.result(); - ASSERT_FALSE(result.has_value()); -} - -TEST_F(NetworkBandwidthSamplerTest, - DoesNotReportDownloadSpeedWhenFeatureFlagDisabled) { - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature(kEnableNetworkBandwidthReporting); - - UpdateDownloadSpeedKbps(kInitDownloadSpeedKbps); - NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(), - profile_->GetWeakPtr()); - - ::reporting::test::TestEvent<std::optional<MetricData>> test_event; - sampler.MaybeCollect(test_event.cb()); - const auto result = test_event.result(); - ASSERT_FALSE(result.has_value()); -} - TEST_F(NetworkBandwidthSamplerTest, DoesNotReportDownloadSpeedIfUnavailable) { SetPrefValue(true); NetworkBandwidthSampler sampler(g_browser_process->network_quality_tracker(),
diff --git a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java index 7cf40870..62f593a 100644 --- a/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java +++ b/chrome/browser/commerce/subscriptions/test/android/java/src/org/chromium/chrome/browser/subscriptions/CommerceSubscriptionsServiceUnitTest.java
@@ -28,7 +28,6 @@ import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; -import org.chromium.base.FeatureList; import org.chromium.base.FeatureOverrides; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.shared_preferences.SharedPreferencesManager; @@ -81,7 +80,6 @@ private SharedPreferencesManager mSharedPreferencesManager; private MockNotificationManagerProxy mMockNotificationManager; private PriceDropNotificationManager mPriceDropNotificationManager; - private FeatureList.TestValues mTestValues; @Before public void setUp() {
diff --git a/chrome/browser/dips/chrome_dips_delegate.cc b/chrome/browser/dips/chrome_dips_delegate.cc index 7b8a61a..0c163433 100644 --- a/chrome/browser/dips/chrome_dips_delegate.cc +++ b/chrome/browser/dips/chrome_dips_delegate.cc
@@ -15,19 +15,6 @@ #include "chrome/browser/profiles/profile_selections.h" #include "content/public/browser/dips_delegate.h" -namespace { - -ProfileSelections GetHumanProfileSelections() { - return ProfileSelections::Builder() - .WithRegular(ProfileSelection::kOwnInstance) - .WithGuest(ProfileSelection::kOffTheRecordOnly) - .WithSystem(ProfileSelection::kNone) - .WithAshInternals(ProfileSelection::kNone) - .Build(); -} - -} // namespace - static_assert(DIPSService::kDefaultRemoveMask == (chrome_browsing_data_remover::FILTERABLE_DATA_TYPES & ((content::BrowsingDataRemover::DATA_TYPE_CONTENT_END << 1) - @@ -35,22 +22,8 @@ "kDefaultRemoveMask must contain all the entries of " "FILTERABLE_DATA_TYPES that are known in //content"); -ChromeDipsDelegate::ChromeDipsDelegate(PassKey) {} - -// static -std::unique_ptr<content::DipsDelegate> ChromeDipsDelegate::Create() { - return std::make_unique<ChromeDipsDelegate>(PassKey()); -} - -bool ChromeDipsDelegate::ShouldEnableDips( - content::BrowserContext* browser_context) { - Profile* profile = Profile::FromBrowserContext(browser_context); - Profile* result = GetHumanProfileSelections().ApplyProfileSelection(profile); - // TODO: crbug.com/358137275 - Use CHECK() once we know it's safe. - DUMP_WILL_BE_CHECK(!result || result == profile) - << "ApplyProfileSelection() returned a different profile"; - return result == profile; -} +ChromeDipsDelegate::ChromeDipsDelegate( + base::PassKey<ChromeContentBrowserClient>) {} void ChromeDipsDelegate::OnDipsServiceCreated( content::BrowserContext* browser_context,
diff --git a/chrome/browser/dips/chrome_dips_delegate.h b/chrome/browser/dips/chrome_dips_delegate.h index bd8db69..a6fbd47e 100644 --- a/chrome/browser/dips/chrome_dips_delegate.h +++ b/chrome/browser/dips/chrome_dips_delegate.h
@@ -7,11 +7,10 @@ #include <stdint.h> -#include <memory> - #include "base/types/pass_key.h" #include "content/public/browser/dips_delegate.h" +class ChromeContentBrowserClient; class DIPSService; namespace content { @@ -20,18 +19,7 @@ class ChromeDipsDelegate : public content::DipsDelegate { public: - using PassKey = base::PassKey<ChromeDipsDelegate>; - - // The constructor takes a PassKey so that the factory method Create() can - // call std::make_unique() to create an instance, while other classes cannot. - explicit ChromeDipsDelegate(PassKey); - - // TODO(rtarpine): remove this and make clients call - // ContentBrowserClient::CreateDipsDelegate(), falling back on a default - // implementation if it returned null, once DIPS has moved to //content. - static std::unique_ptr<content::DipsDelegate> Create(); - - bool ShouldEnableDips(content::BrowserContext* browser_context) override; + explicit ChromeDipsDelegate(base::PassKey<ChromeContentBrowserClient>); void OnDipsServiceCreated(content::BrowserContext* browser_context, DIPSService* dips_service) override;
diff --git a/chrome/browser/dips/dips_browser_signin_detector_factory.cc b/chrome/browser/dips/dips_browser_signin_detector_factory.cc index 62c7103..1c6d656 100644 --- a/chrome/browser/dips/dips_browser_signin_detector_factory.cc +++ b/chrome/browser/dips/dips_browser_signin_detector_factory.cc
@@ -4,7 +4,7 @@ #include "chrome/browser/dips/dips_browser_signin_detector_factory.h" -#include "chrome/browser/dips/chrome_dips_delegate.h" +#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/dips/dips_browser_signin_detector.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" @@ -51,7 +51,7 @@ return nullptr; } - if (!ChromeDipsDelegate::Create()->ShouldEnableDips(context)) { + if (!ShouldBrowserContextEnableDips(context)) { return nullptr; }
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_features.cc b/chrome/browser/enterprise/connectors/analysis/content_analysis_features.cc index ebe2feeca..4895bf66 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_features.cc +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_features.cc
@@ -10,6 +10,10 @@ "StopRegisterFcmEnabled", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kEnableAsyncUploadAfterVerdict, + "EnableAsyncUploadAfterVerdict", + base::FEATURE_DISABLED_BY_DEFAULT); + bool IsStopRegisterFcmEnabled() { return base::FeatureList::IsEnabled(kStopRegisterFcmEnabled); }
diff --git a/chrome/browser/enterprise/connectors/analysis/content_analysis_features.h b/chrome/browser/enterprise/connectors/analysis/content_analysis_features.h index ab8b077..d0548cb 100644 --- a/chrome/browser/enterprise/connectors/analysis/content_analysis_features.h +++ b/chrome/browser/enterprise/connectors/analysis/content_analysis_features.h
@@ -12,6 +12,10 @@ // Controls whether Chrome can stop register fcm token. BASE_DECLARE_FEATURE(kStopRegisterFcmEnabled); +// Controls uploading scanned data even after a metadata verdict +// is received for content scans. +BASE_DECLARE_FEATURE(kEnableAsyncUploadAfterVerdict); + // Returns true if stop register fcm token is enabled. bool IsStopRegisterFcmEnabled();
diff --git a/chrome/browser/enterprise/watermark/watermark_browsertest.cc b/chrome/browser/enterprise/watermark/watermark_browsertest.cc index f3ec689..ea375a4 100644 --- a/chrome/browser/enterprise/watermark/watermark_browsertest.cc +++ b/chrome/browser/enterprise/watermark/watermark_browsertest.cc
@@ -79,9 +79,17 @@ } // namespace -// TODO(crbug.com/40261456): Fix and re-enable the test. +// The test is enabled only for Windows since this is the standard for pixel +// golden tests in general (single platform to account for variability in +// rendering). +#if BUILDFLAG(IS_WIN) +#define MAYBE_WatermarkShownAfterNavigation WatermarkShownAfterNavigation +#else +#define MAYBE_WatermarkShownAfterNavigation WatermarkShownAfterNavigation +#endif + IN_PROC_BROWSER_TEST_P(WatermarkBrowserTest, - DISABLED_WatermarkShownAfterNavigation) { + MAYBE_WatermarkShownAfterNavigation) { NavigateToTestPage(); ASSERT_TRUE(SetWatermark(GetParam())); ShowAndVerifyUi();
diff --git a/chrome/browser/extensions/api/scripting/scripting_api.cc b/chrome/browser/extensions/api/scripting/scripting_api.cc index 7526c98..eb5e3f0 100644 --- a/chrome/browser/extensions/api/scripting/scripting_api.cc +++ b/chrome/browser/extensions/api/scripting/scripting_api.cc
@@ -693,8 +693,7 @@ user_gesture() ? blink::mojom::UserActivationOption::kActivate : blink::mojom::UserActivationOption::kDoNotActivate, blink::mojom::PromiseResultOption::kAwait)), - frame_scope, frame_ids, - mojom::MatchOriginAsFallbackBehavior::kMatchForAboutSchemeAndClimbTree, + frame_scope, frame_ids, mojom::MatchOriginAsFallbackBehavior::kAlways, run_location, ScriptExecutor::DEFAULT_PROCESS, /* webview_src */ GURL(), base::BindOnce(&ScriptingExecuteScriptFunction::OnScriptExecuted, this)); @@ -818,8 +817,7 @@ mojom::CodeInjection::NewCss(mojom::CSSInjection::New( std::move(sources), ConvertStyleOriginToCSSOrigin(injection_.origin), mojom::CSSInjection::Operation::kAdd)), - frame_scope, frame_ids, - mojom::MatchOriginAsFallbackBehavior::kMatchForAboutSchemeAndClimbTree, + frame_scope, frame_ids, mojom::MatchOriginAsFallbackBehavior::kAlways, kCSSRunLocation, ScriptExecutor::DEFAULT_PROCESS, /* webview_src */ GURL(), base::BindOnce(&ScriptingInsertCSSFunction::OnCSSInserted, this)); @@ -896,8 +894,7 @@ mojom::CodeInjection::NewCss(mojom::CSSInjection::New( std::move(sources), ConvertStyleOriginToCSSOrigin(injection.origin), mojom::CSSInjection::Operation::kRemove)), - frame_scope, frame_ids, - mojom::MatchOriginAsFallbackBehavior::kMatchForAboutSchemeAndClimbTree, + frame_scope, frame_ids, mojom::MatchOriginAsFallbackBehavior::kAlways, kCSSRunLocation, ScriptExecutor::DEFAULT_PROCESS, /* webview_src */ GURL(), base::BindOnce(&ScriptingRemoveCSSFunction::OnCSSRemoved, this));
diff --git a/chrome/browser/extensions/api/scripting/scripting_apitest.cc b/chrome/browser/extensions/api/scripting/scripting_apitest.cc index 1be0c2b..b159acba 100644 --- a/chrome/browser/extensions/api/scripting/scripting_apitest.cc +++ b/chrome/browser/extensions/api/scripting/scripting_apitest.cc
@@ -130,6 +130,8 @@ embedded_test_server()->GetURL("a.com", "/iframe_cross_site.html")); OpenURLInNewTab( embedded_test_server()->GetURL("d.com", "/iframe_cross_site.html")); + OpenURLInNewTab( + embedded_test_server()->GetURL("e.com", "/iframe_sandboxed_srcdoc.html")); // From there, the test continues in the JS. ASSERT_TRUE(RunExtensionTest("scripting/sub_frames")) << message_; @@ -182,6 +184,8 @@ embedded_test_server()->GetURL("chromium.org", "/title2.html")); OpenURLInNewTab(embedded_test_server()->GetURL("subframes.example", "/iframe_cross_site.html")); + OpenURLInNewTab(embedded_test_server()->GetURL( + "subframes-sandboxed.example", "/iframe_sandboxed_srcdoc.html")); ASSERT_TRUE(RunExtensionTest("scripting/css_injection")) << message_; }
diff --git a/chrome/browser/extensions/api/web_request/web_request_apitest.cc b/chrome/browser/extensions/api/web_request/web_request_apitest.cc index ed32c8e..d604bb0 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -6744,7 +6744,7 @@ // it's active listeners should be removed. EventRouterInterceptorForStopListenerRemoval event_listener_removal_on_stop_interceptor( - profile(), previous_service_worker_id->render_process_id, ); + profile(), previous_service_worker_id->render_process_id); // Stop the extension's service worker. The worker listener, due to the // interceptor, will stay registered as an active listener. However,
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java index 5a0c74e..91874568 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/FeedFeaturesTest.java
@@ -22,7 +22,6 @@ import org.mockito.junit.MockitoRule; import org.mockito.quality.Strictness; -import org.chromium.base.FeatureList; import org.chromium.base.FeatureOverrides; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.DisabledTest; @@ -42,7 +41,6 @@ @Mock private Profile mProfile; @Mock private PrefService mPrefService; - private FeatureList.TestValues mParamsTestValues; private @StreamTabId int mPrefStoredTab; @Before
diff --git a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java index ad8be59..23934a7 100644 --- a/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java +++ b/chrome/browser/feed/android/java/src/org/chromium/chrome/browser/feed/webfeed/WebFeedFollowIntroControllerTest.java
@@ -33,7 +33,6 @@ import org.robolectric.shadows.ShadowLog; import org.chromium.base.Callback; -import org.chromium.base.FeatureList; import org.chromium.base.UserDataHost; import org.chromium.base.shared_preferences.SharedPreferencesManager; import org.chromium.base.supplier.ObservableSupplier; @@ -98,7 +97,6 @@ private EmptyTabObserver mEmptyTabObserver; private FakeClock mClock; private WebFeedFollowIntroController mWebFeedFollowIntroController; - private FeatureList.TestValues mBaseTestValues; private UserDataHost mTestUserDataHost; @Before
diff --git a/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler_unittest.cc b/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler_unittest.cc index 94544e1..03cb136 100644 --- a/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler_unittest.cc +++ b/chrome/browser/first_party_sets/first_party_sets_overrides_policy_handler_unittest.cc
@@ -97,7 +97,8 @@ EXPECT_TRUE( handler()->CheckPolicySettings(MakePolicyWithInput(input), &errors)); - EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest()), + EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest(), + policy::PolicyMap::MessageType::kWarning), u"Schema validation error: Unknown property: unknown"); } @@ -120,7 +121,8 @@ // CheckPolicySettings will return true, but output an unknown property error. EXPECT_TRUE( handler()->CheckPolicySettings(MakePolicyWithInput(input), &errors)); - EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest()), + EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest(), + policy::PolicyMap::MessageType::kWarning), GetPolicyError(u".replacements[0]: Schema validation error: " u"Unknown property: unknown")); } @@ -144,7 +146,8 @@ // CheckPolicySettings will return true, but output an unknown property error. EXPECT_TRUE( handler()->CheckPolicySettings(MakePolicyWithInput(input), &errors)); - EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest()), + EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest(), + policy::PolicyMap::MessageType::kWarning), GetPolicyError(u".additions[0]: Schema validation error: Unknown " u"property: unknown")); } @@ -363,7 +366,8 @@ // CheckPolicySettings returns true, and errors on the last unknown property. EXPECT_TRUE( handler()->CheckPolicySettings(MakePolicyWithInput(input), &errors)); - EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest()), + EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest(), + policy::PolicyMap::MessageType::kWarning), u"Schema validation error: Unknown property: unknown3"); } @@ -623,7 +627,8 @@ EXPECT_TRUE( handler()->CheckPolicySettings(MakePolicyWithInput(input), &errors)); - EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest()), + EXPECT_EQ(errors.GetErrorMessages(GetPolicyUnderTest(), + policy::PolicyMap::MessageType::kWarning), GetPolicyError(u".replacements[0].ccTLDs.https://not_in_set.test: " u"Schema validation error: This \"ccTLDs\" entry is " u"ignored since this key is not in the set.")); @@ -651,7 +656,8 @@ EXPECT_TRUE( handler()->CheckPolicySettings(MakePolicyWithInput(input), &errors)); EXPECT_EQ( - errors.GetErrorMessages(GetPolicyUnderTest()), + errors.GetErrorMessages(GetPolicyUnderTest(), + policy::PolicyMap::MessageType::kWarning), GetPolicyError(u".replacements[0].ccTLDs.https://primary1.test[0]: " u"Schema validation error: This \"ccTLD\" is ignored " u"since it differs from its key by more than eTLD."));
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index efa4a41..3db8c91 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -2343,6 +2343,11 @@ "expiry_milestone": 145 }, { + "name": "enable-accessibility-manifest-v3-enhanced-network-tts", + "owners": [ "spectranaut@igalia.com", "akihiroota@chromium.org", "//ui/accessibility/OWNERS" ], + "expiry_milestone": 145 + }, + { "name": "enable-accessibility-mousekeys", "owners": [ "zork@chromium.org", "//ash/accessibility/OWNERS" ], "expiry_milestone": 142 @@ -4495,6 +4500,11 @@ "expiry_milestone": 135 }, { + "name": "fedcm-lightweight-mode", + "owners": ["ekovac@google.com", "web-identity-eng@google.com"], + "expiry_milestone": 135 + }, + { "name": "fedcm-metrics-endpoint", "owners": ["yigu@chromium.org", "web-identity-eng@google.com"], "expiry_milestone": 135 @@ -7908,6 +7918,11 @@ "expiry_milestone": 135 }, { + "name": "set-up-list-without-sign-in-item", + "owners": [ "hiramahmood@google.com", "bling-get-set-up@google.com" ], + "expiry_milestone": 135 + }, + { "name": "settings-app-notification-settings", "owners": [ "yulunwu@chromium.org" ], "expiry_milestone": 96
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 3b3308e..5ee159ee 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -1949,6 +1949,11 @@ "Allows the FedCM API to send performance measurement to the metrics " "endpoint on the identity provider side. Requires FedCM to be enabled."; +const char kFedCmLightweightModeName[] = "FedCmLightweightMode"; +const char kFedCmLightweightModeDescription[] = + "Enables IdPs to store user profile information using the login status " + "API."; + const char kFedCmMultiIdpName[] = "FedCmMultiIdp"; const char kFedCmMultiIdpDescription[] = "Allows the FedCM API to request multiple identity providers " @@ -6682,6 +6687,12 @@ "Experimental migration of accessibility features from extension manifest " "v2 to v3. Likely to break accessibility access while experimental."; +const char kAccessibilityManifestV3EnhancedNetworkTtsName[] = + "Changes accessibility extension Enhanced Network TTS manifest v2 to v3."; +const char kAccessibilityManifestV3EnhancedNetworkTtsDescription[] = + "Experimental migration of Enhanced Network TTS from extension manifest " + "v2 to v3."; + const char kExperimentalAccessibilitySwitchAccessTextName[] = "Enable enhanced Switch Access text input."; const char kExperimentalAccessibilitySwitchAccessTextDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index ae1fe5f..65fe07f4c 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -1103,6 +1103,9 @@ extern const char kFedCmIdPRegistrationName[]; extern const char kFedCmIdPRegistrationDescription[]; +extern const char kFedCmLightweightModeName[]; +extern const char kFedCmLightweightModeDescription[]; + extern const char kFedCmMetricsEndpointName[]; extern const char kFedCmMetricsEndpointDescription[]; @@ -3888,6 +3891,9 @@ extern const char kExperimentalAccessibilityManifestV3Name[]; extern const char kExperimentalAccessibilityManifestV3Description[]; +extern const char kAccessibilityManifestV3EnhancedNetworkTtsName[]; +extern const char kAccessibilityManifestV3EnhancedNetworkTtsDescription[]; + extern const char kExperimentalAccessibilitySwitchAccessTextName[]; extern const char kExperimentalAccessibilitySwitchAccessTextDescription[];
diff --git a/chrome/browser/glic/BUILD.gn b/chrome/browser/glic/BUILD.gn index fbc99bb..4835de6 100644 --- a/chrome/browser/glic/BUILD.gn +++ b/chrome/browser/glic/BUILD.gn
@@ -4,6 +4,7 @@ source_set("glic") { sources = [ + "glic_cookie_synchronizer.h", "glic_focused_tab_manager.h", "glic_keyed_service.h", "glic_keyed_service_factory.h", @@ -23,6 +24,7 @@ "//chrome/browser/ui/tabs:tab_strip_model_observer", "//chrome/browser/ui/webui/glic:mojo_bindings", "//components/prefs", + "//components/signin/public/identity_manager:identity_manager", "//content/public/browser", "//ui/views:views", ] @@ -30,6 +32,7 @@ source_set("impl") { sources = [ + "glic_cookie_synchronizer.cc", "glic_focused_tab_manager.cc", "glic_keyed_service.cc", "glic_keyed_service_factory.cc", @@ -77,6 +80,7 @@ source_set("unit_tests") { testonly = true sources = [ + "glic_cookie_synchronizer_unittest.cc", "glic_enabling_unittest.cc", "glic_profile_manager_unittest.cc", ]
diff --git a/chrome/browser/glic/glic_cookie_synchronizer.cc b/chrome/browser/glic/glic_cookie_synchronizer.cc new file mode 100644 index 0000000..8637381 --- /dev/null +++ b/chrome/browser/glic/glic_cookie_synchronizer.cc
@@ -0,0 +1,125 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/glic/glic_cookie_synchronizer.h" + +#include <iterator> +#include <memory> +#include <string> +#include <utility> +#include <vector> + +#include "base/check.h" +#include "base/functional/bind.h" +#include "base/logging.h" +#include "components/signin/public/base/consent_level.h" +#include "components/signin/public/base/multilogin_parameters.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/storage_partition_config.h" +#include "google_apis/gaia/core_account_id.h" +#include "google_apis/gaia/gaia_auth_fetcher.h" +#include "url/gurl.h" + +namespace glic { + +GlicCookieSynchronizer::GlicCookieSynchronizer( + content::BrowserContext* context, + signin::IdentityManager* identity_manager) + : context_(context), identity_manager_(identity_manager) { + CHECK(context_); + // This storage partition must match the partition attribute in + // chrome/browser/resources/glic/glic.html: "persist:glicpart". + storage_partition_config_ = content::StoragePartitionConfig::Create( + context_, "glic", + /*partition_name=*/"glicpart", /*in_memory=*/false); +} + +GlicCookieSynchronizer::~GlicCookieSynchronizer() = default; + +std::unique_ptr<GaiaAuthFetcher> +GlicCookieSynchronizer::CreateGaiaAuthFetcherForPartition( + GaiaAuthConsumer* consumer, + const gaia::GaiaSource& source) { + return std::make_unique<GaiaAuthFetcher>( + consumer, source, + GetStoragePartition()->GetURLLoaderFactoryForBrowserProcess()); +} + +network::mojom::CookieManager* +GlicCookieSynchronizer::GetCookieManagerForPartition() { + return GetStoragePartition()->GetCookieManagerForBrowserProcess(); +} + +void GlicCookieSynchronizer::CopyCookiesToWebviewStoragePartition( + OnWebviewAuth callback) { + CHECK(!callback.is_null()); + callbacks_.push_back(std::move(callback)); + + if (cookie_loader_) { + // A request is in progress already. + return; + } + + if (!GetStoragePartition()) { + DLOG(ERROR) << "glic webview storage partition does not exist"; + CompleteAuth(false); + return; + } + + // We only need primary account authentication in the webview. + CoreAccountId primary_account_id = + identity_manager_->GetPrimaryAccountId(signin::ConsentLevel::kSignin); + if (primary_account_id.empty()) { + DLOG(ERROR) << "can't sync cookies, user not signed in"; + CompleteAuth(false); + return; + } + + cookie_loader_ = + identity_manager_->GetAccountsCookieMutator() + ->SetAccountsInCookieForPartition( + this, + {gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER, + {primary_account_id}}, + gaia::GaiaSource::kChrome, + base::BindOnce(&GlicCookieSynchronizer::OnAuthFinished, + GetWeakPtr())); +} + +void GlicCookieSynchronizer::OnAuthFinished( + signin::SetAccountsInCookieResult cookie_result) { + switch (cookie_result) { + case signin::SetAccountsInCookieResult::kSuccess: + CompleteAuth(/*is_success=*/true); + break; + case signin::SetAccountsInCookieResult::kTransientError: + CompleteAuth(/*is_success=*/false); + break; + case signin::SetAccountsInCookieResult::kPersistentError: + CompleteAuth(/*is_success=*/false); + break; + } +} + +void GlicCookieSynchronizer::CompleteAuth(bool is_success) { + cookie_loader_.reset(); + std::vector<base::OnceCallback<void(bool)>> callbacks; + std::swap(callbacks, callbacks_); + + for (auto i = std::make_move_iterator(callbacks.begin()); + i != std::make_move_iterator(callbacks.end()); ++i) { + (*i).Run(is_success); + } +} + +content::StoragePartition* GlicCookieSynchronizer::GetStoragePartition() { + content::StoragePartition* partition = + context_->GetStoragePartition(storage_partition_config_); + return partition; +} + +} // namespace glic
diff --git a/chrome/browser/glic/glic_cookie_synchronizer.h b/chrome/browser/glic/glic_cookie_synchronizer.h new file mode 100644 index 0000000..324e856 --- /dev/null +++ b/chrome/browser/glic/glic_cookie_synchronizer.h
@@ -0,0 +1,85 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_GLIC_GLIC_COOKIE_SYNCHRONIZER_H_ +#define CHROME_BROWSER_GLIC_GLIC_COOKIE_SYNCHRONIZER_H_ + +#include <memory> + +#include "base/functional/callback_forward.h" +#include "base/memory/raw_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/timer/timer.h" +#include "components/signin/public/identity_manager/accounts_cookie_mutator.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/storage_partition_config.h" + +namespace content { +class BrowserContext; +class StoragePartition; +} // namespace content + +namespace signin { +class IdentityManager; +enum class SetAccountsInCookieResult; +} // namespace signin + +namespace glic { + +// Helper to sync cookies to the webview storage partition. +class GlicCookieSynchronizer + : public signin::AccountsCookieMutator::PartitionDelegate { + public: + // Callback with authentication result. + // Called when webview authentication is finished. + using OnWebviewAuth = base::OnceCallback<void(bool)>; + + // The maximum number of retries attempted following a transient error. + static constexpr int kMaxRetries = 3; + + GlicCookieSynchronizer(content::BrowserContext* context, + signin::IdentityManager* identity_manager); + GlicCookieSynchronizer(const GlicCookieSynchronizer&) = delete; + GlicCookieSynchronizer& operator=(const GlicCookieSynchronizer&) = delete; + virtual ~GlicCookieSynchronizer(); + + void CopyCookiesToWebviewStoragePartition( + base::OnceCallback<void(bool)> callback); + + protected: + // Returns storage partition for this authentication request. + // visible for testing. + virtual content::StoragePartition* GetStoragePartition(); + + private: + base::WeakPtr<GlicCookieSynchronizer> GetWeakPtr() { + return weak_ptr_factory_.GetWeakPtr(); + } + // signin::AccountsCookieMutator::PartitionDelegate: + std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcherForPartition( + GaiaAuthConsumer* consumer, + const gaia::GaiaSource& source) override; + network::mojom::CookieManager* GetCookieManagerForPartition() override; + + // Handles the webview authentication result. + void OnAuthFinished(signin::SetAccountsInCookieResult cookie_result); + void CompleteAuth(bool is_success); + + // Storage partition configuration for this authentication request. + content::StoragePartitionConfig storage_partition_config_; + + const raw_ptr<content::BrowserContext> context_; + const raw_ptr<signin::IdentityManager> identity_manager_; + + std::vector<base::OnceCallback<void(bool)>> callbacks_; + std::unique_ptr<signin::AccountsCookieMutator::SetAccountsInCookieTask> + cookie_loader_; + + base::WeakPtrFactory<GlicCookieSynchronizer> weak_ptr_factory_{this}; +}; + +} // namespace glic + +#endif // CHROME_BROWSER_GLIC_GLIC_COOKIE_SYNCHRONIZER_H_
diff --git a/chrome/browser/glic/glic_cookie_synchronizer_unittest.cc b/chrome/browser/glic/glic_cookie_synchronizer_unittest.cc new file mode 100644 index 0000000..77f54db --- /dev/null +++ b/chrome/browser/glic/glic_cookie_synchronizer_unittest.cc
@@ -0,0 +1,202 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/glic/glic_cookie_synchronizer.h" + +#include <string> + +#include "base/memory/raw_ptr.h" +#include "base/run_loop.h" +#include "base/strings/stringprintf.h" +#include "base/test/bind.h" +#include "base/test/test_future.h" +#include "chrome/test/base/testing_profile.h" +#include "components/signin/public/base/consent_level.h" +#include "components/signin/public/base/test_signin_client.h" +#include "components/signin/public/identity_manager/identity_manager.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" +#include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h" +#include "components/sync_preferences/testing_pref_service_syncable.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/storage_partition.h" +#include "content/public/browser/storage_partition_config.h" +#include "content/public/test/browser_task_environment.h" +#include "content/public/test/test_storage_partition.h" +#include "google_apis/gaia/gaia_constants.h" +#include "google_apis/gaia/gaia_urls.h" +#include "services/network/public/mojom/cookie_manager.mojom.h" +#include "services/network/test/test_cookie_manager.h" +#include "services/network/test/test_url_loader_factory.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +namespace glic { + +namespace { + +constexpr char kTestAccountEmail[] = "user@test.com"; + +constexpr char kCookieResponseSuccess[] = R"( + { "status": "OK", + "cookies":[ + { + "name":"CookieName", + "value":"CookieValue", + "domain":".google.com", + "path":"/" + } + ] + })"; +constexpr char kCookieResponseRetry[] = R"( + { "status": "RETRY", + "cookies":[] + })"; +constexpr char kCookieResponseError[] = R"( + { "status": "ERROR", + "cookies":[] + })"; + +// Returns HTTP request response that will lead to the given `result`. +std::string GetResponseFromResult(signin::SetAccountsInCookieResult result) { + switch (result) { + case signin::SetAccountsInCookieResult::kSuccess: + return kCookieResponseSuccess; + case signin::SetAccountsInCookieResult::kTransientError: + return kCookieResponseRetry; + case signin::SetAccountsInCookieResult::kPersistentError: + return kCookieResponseError; + } +} + +class GlicCookieSynchronizerWithTestPartition : public GlicCookieSynchronizer { + public: + GlicCookieSynchronizerWithTestPartition( + content::BrowserContext* context, + signin::IdentityManager* identity_manager, + content::TestStoragePartition* test_storage_partition) + : GlicCookieSynchronizer(context, identity_manager), + test_storage_partition_(test_storage_partition) {} + + content::TestStoragePartition* GetStoragePartition() override { + return test_storage_partition_; + } + + private: + raw_ptr<content::TestStoragePartition> test_storage_partition_; +}; + +} // namespace + +class GlicCookieSynchronizerTest : public testing::Test { + public: + GlicCookieSynchronizerTest() = default; + ~GlicCookieSynchronizerTest() override = default; + + protected: + GlicCookieSynchronizer& cookie_synchronizer() { return cookie_synchronizer_; } + + // Sets the network response to the given result. Applies to all subsequent + // network requests. + void SetResponseForResult(signin::SetAccountsInCookieResult result) { + test_signin_client_.GetTestURLLoaderFactory()->AddResponse( + RequestURL().spec(), GetResponseFromResult(result)); + } + + GURL RequestURL() const { + return GaiaUrls::GetInstance()->oauth_multilogin_url().Resolve( + base::StringPrintf("?source=%s&reuseCookies=0", + GaiaConstants::kChromeSource)); + } + + void SetUp() override { + testing::Test::SetUp(); + + test_storage_partition_.set_cookie_manager_for_browser_process( + &test_cookie_manager_); + test_storage_partition_.set_url_loader_factory_for_browser_process( + test_signin_client_.GetTestURLLoaderFactory()); + + identity_test_env_.MakePrimaryAccountAvailable( + kTestAccountEmail, signin::ConsentLevel::kSignin); + identity_test_env_.SetAutomaticIssueOfAccessTokens(true); + } + + content::BrowserTaskEnvironment task_environment_; + + TestingProfile test_profile_; + + sync_preferences::TestingPrefServiceSyncable prefs_; + TestSigninClient test_signin_client_{&prefs_}; + signin::IdentityTestEnvironment identity_test_env_{ + /*test_url_loader_factory=*/nullptr, &prefs_, &test_signin_client_}; + + content::TestStoragePartition test_storage_partition_; + network::TestCookieManager test_cookie_manager_; + + GlicCookieSynchronizerWithTestPartition cookie_synchronizer_{ + &test_profile_, identity_test_env_.identity_manager(), + &test_storage_partition_}; +}; + +TEST_F(GlicCookieSynchronizerTest, AuthSuccess) { + base::test::TestFuture<bool> result; + SetResponseForResult(signin::SetAccountsInCookieResult::kSuccess); + + cookie_synchronizer().CopyCookiesToWebviewStoragePartition( + result.GetCallback()); + EXPECT_TRUE(result.Get()); +} + +TEST_F(GlicCookieSynchronizerTest, MultipleRequestsAtOnce) { + base::test::TestFuture<bool> result, result2; + SetResponseForResult(signin::SetAccountsInCookieResult::kSuccess); + + cookie_synchronizer().CopyCookiesToWebviewStoragePartition( + result.GetCallback()); + cookie_synchronizer().CopyCookiesToWebviewStoragePartition( + result2.GetCallback()); + EXPECT_TRUE(result.Get()); + EXPECT_TRUE(result2.Get()); +} + +TEST_F(GlicCookieSynchronizerTest, AuthPersistentFailure) { + base::test::TestFuture<bool> result; + SetResponseForResult(signin::SetAccountsInCookieResult::kPersistentError); + + cookie_synchronizer().CopyCookiesToWebviewStoragePartition( + result.GetCallback()); + EXPECT_FALSE(result.Get()); +} + +TEST_F(GlicCookieSynchronizerTest, AuthTransientSuccessOnRetry) { + // This test verifies that OAuthMultiloginHelper performs retries for us. + base::test::TestFuture<bool> result; + + int request_count = 0; + test_signin_client_.GetTestURLLoaderFactory()->SetInterceptor( + base::BindLambdaForTesting([&](const network::ResourceRequest& request) { + if (request.url != RequestURL()) { + return; + } + SetResponseForResult( + request_count++ == 0 + ? signin::SetAccountsInCookieResult::kTransientError + : signin::SetAccountsInCookieResult::kSuccess); + })); + + cookie_synchronizer().CopyCookiesToWebviewStoragePartition( + result.GetCallback()); + EXPECT_TRUE(result.Get()); +} + +TEST_F(GlicCookieSynchronizerTest, AuthTransientFailure_MaxRetry) { + base::test::TestFuture<bool> result; + SetResponseForResult(signin::SetAccountsInCookieResult::kTransientError); + + cookie_synchronizer().CopyCookiesToWebviewStoragePartition( + result.GetCallback()); + EXPECT_FALSE(result.Get()); +} + +} // namespace glic
diff --git a/chrome/browser/glic/glic_keyed_service.cc b/chrome/browser/glic/glic_keyed_service.cc index f8d2a9a..8d30df2 100644 --- a/chrome/browser/glic/glic_keyed_service.cc +++ b/chrome/browser/glic/glic_keyed_service.cc
@@ -22,11 +22,14 @@ namespace glic { GlicKeyedService::GlicKeyedService(content::BrowserContext* browser_context, + signin::IdentityManager* identity_manager, GlicProfileManager* profile_manager) : browser_context_(browser_context), window_controller_(Profile::FromBrowserContext(browser_context)), focused_tab_manager_(Profile::FromBrowserContext(browser_context), window_controller_), + cookie_synchronizer_(browser_context, identity_manager), + profile_manager_(profile_manager) { focused_tab_changed_subscription_ = focused_tab_manager_.AddFocusedTabChangedCallback(base::BindRepeating( @@ -157,4 +160,10 @@ return weak_ptr_factory_.GetWeakPtr(); } +void GlicKeyedService::SyncWebviewCookies( + mojom::PageHandler::SyncWebviewCookiesCallback callback) { + cookie_synchronizer_.CopyCookiesToWebviewStoragePartition( + std::move(callback)); +} + } // namespace glic
diff --git a/chrome/browser/glic/glic_keyed_service.h b/chrome/browser/glic/glic_keyed_service.h index 919b532..1f79761a 100644 --- a/chrome/browser/glic/glic_keyed_service.h +++ b/chrome/browser/glic/glic_keyed_service.h
@@ -9,6 +9,7 @@ #include "base/callback_list.h" #include "base/memory/raw_ptr.h" +#include "chrome/browser/glic/glic_cookie_synchronizer.h" #include "chrome/browser/glic/glic_focused_tab_manager.h" #include "chrome/browser/glic/glic_profile_configuration.h" #include "chrome/browser/glic/glic_window_controller.h" @@ -20,6 +21,10 @@ class BrowserContext; } // namespace content +namespace signin { +class IdentityManager; +} // namespace signin + namespace glic { class GlicFocusedTabManager; class GlicProfileManager; @@ -28,6 +33,7 @@ class GlicKeyedService : public KeyedService { public: explicit GlicKeyedService(content::BrowserContext* browser_context, + signin::IdentityManager* identity_manager, GlicProfileManager* profile_manager); GlicKeyedService(const GlicKeyedService&) = delete; GlicKeyedService& operator=(const GlicKeyedService&) = delete; @@ -71,6 +77,9 @@ bool include_viewport_screenshot, glic::mojom::WebClientHandler::GetContextFromFocusedTabCallback callback); + void SyncWebviewCookies( + mojom::PageHandler::SyncWebviewCookiesCallback callback); + base::WeakPtr<GlicKeyedService> GetWeakPtr(); private: @@ -81,6 +90,7 @@ GlicProfileConfiguration configuration_; GlicWindowController window_controller_; GlicFocusedTabManager focused_tab_manager_; + GlicCookieSynchronizer cookie_synchronizer_; // Unowned raw_ptr<GlicProfileManager> profile_manager_;
diff --git a/chrome/browser/glic/glic_keyed_service_factory.cc b/chrome/browser/glic/glic_keyed_service_factory.cc index 7fc041b..1bac944 100644 --- a/chrome/browser/glic/glic_keyed_service_factory.cc +++ b/chrome/browser/glic/glic_keyed_service_factory.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/glic/glic_keyed_service_factory.h" #include "chrome/browser/glic/glic_profile_manager.h" +#include "chrome/browser/signin/identity_manager_factory.h" +#include "extensions/browser/api/declarative/rules_registry_service.h" namespace glic { @@ -23,7 +25,13 @@ GlicKeyedServiceFactory::GlicKeyedServiceFactory() : ProfileKeyedServiceFactory("GlicKeyedService", - ProfileSelections::BuildForRegularProfile()) {} + ProfileSelections::BuildForRegularProfile()) { + // GlicKeyedService has an indirect dependency on the + // RulesRegistryService through extensions::TabHelper::WebContentsDestroyed + // when the glic web contents is destroyed. + DependsOn(extensions::RulesRegistryService::GetFactoryInstance()); + DependsOn(IdentityManagerFactory::GetInstance()); +} GlicKeyedServiceFactory::~GlicKeyedServiceFactory() = default; @@ -34,8 +42,11 @@ std::unique_ptr<KeyedService> GlicKeyedServiceFactory::BuildServiceInstanceForBrowserContext( content::BrowserContext* context) const { - return std::make_unique<GlicKeyedService>(context, - GlicProfileManager::GetInstance()); + return std::make_unique<GlicKeyedService>( + context, + IdentityManagerFactory::GetForProfile( + Profile::FromBrowserContext(context)), + GlicProfileManager::GetInstance()); } } // namespace glic
diff --git a/chrome/browser/glic/glic_profile_manager_unittest.cc b/chrome/browser/glic/glic_profile_manager_unittest.cc index 7f390cd..462707bf 100644 --- a/chrome/browser/glic/glic_profile_manager_unittest.cc +++ b/chrome/browser/glic/glic_profile_manager_unittest.cc
@@ -6,6 +6,7 @@ #include "chrome/browser/glic/glic_keyed_service.h" #include "chrome/test/base/testing_profile.h" +#include "components/signin/public/identity_manager/identity_test_environment.h" #include "content/public/test/browser_task_environment.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -16,16 +17,19 @@ class MockGlicKeyedService : public GlicKeyedService { public: MockGlicKeyedService(content::BrowserContext* browser_context, + signin::IdentityManager* identity_manager, GlicProfileManager* profile_manager) - : GlicKeyedService(browser_context, profile_manager) {} + : GlicKeyedService(browser_context, identity_manager, profile_manager) {} MOCK_METHOD(void, ClosePanel, (), (override)); }; TEST(GlicProfileManagerTest, OnUILaunching_SameProfile) { content::BrowserTaskEnvironment task_environment; GlicProfileManager profile_manager; + signin::IdentityTestEnvironment identity_test_environment; TestingProfile profile; - MockGlicKeyedService service(&profile, &profile_manager); + MockGlicKeyedService service( + &profile, identity_test_environment.identity_manager(), &profile_manager); profile_manager.OnUILaunching(&service); @@ -37,10 +41,15 @@ TEST(GlicProfileManagerTest, OnUILaunching_DifferentProfiles) { content::BrowserTaskEnvironment task_environment; GlicProfileManager profile_manager; + signin::IdentityTestEnvironment identity_test_environment; TestingProfile profile1; TestingProfile profile2; - MockGlicKeyedService service1(&profile1, &profile_manager); - MockGlicKeyedService service2(&profile2, &profile_manager); + MockGlicKeyedService service1(&profile1, + identity_test_environment.identity_manager(), + &profile_manager); + MockGlicKeyedService service2(&profile2, + identity_test_environment.identity_manager(), + &profile_manager); profile_manager.OnUILaunching(&service1);
diff --git a/chrome/browser/glic/guest_util_browsertest.cc b/chrome/browser/glic/guest_util_browsertest.cc index 55715c5..c67f6be 100644 --- a/chrome/browser/glic/guest_util_browsertest.cc +++ b/chrome/browser/glic/guest_util_browsertest.cc
@@ -7,6 +7,7 @@ #include "base/check_deref.h" #include "base/test/scoped_feature_list.h" #include "chrome/browser/profiles/profile_manager.h" +#include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_switches.h" @@ -16,6 +17,7 @@ #include "components/guest_view/browser/guest_view_base.h" #include "components/guest_view/browser/guest_view_manager_delegate.h" #include "components/guest_view/browser/test_guest_view_manager.h" +#include "components/signin/public/identity_manager/identity_test_utils.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" @@ -66,6 +68,16 @@ ~GuestUtilBrowserTest() override = default; + void SetUpOnMainThread() override { + InProcessBrowserTest::SetUpOnMainThread(); + + // A signed-in user is required for chrome://glic. + signin::IdentityManager* identity_manager = + IdentityManagerFactory::GetForProfile(browser()->profile()); + CoreAccountInfo account_info = SetPrimaryAccount( + identity_manager, "foo@gmail.com", signin::ConsentLevel::kSync); + } + void SetUpCommandLine(base::CommandLine* command_line) override { // Load blank page in glic guest view command_line->AppendSwitchASCII(::switches::kGlicGuestURL, "about:blank");
diff --git a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubManager.java b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubManager.java index 61ef6be..d10a18b 100644 --- a/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubManager.java +++ b/chrome/browser/hub/android/java/src/org/chromium/chrome/browser/hub/HubManager.java
@@ -43,4 +43,7 @@ /** Sets the app header height. */ void setAppHeaderHeight(int height); + + /** Gets the supplier providing the Hub Toolbar color. */ + ObservableSupplier<Integer> getHubToolbarOverviewColorSupplier(); }
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java index 85563906..cb3352d 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinator.java
@@ -64,6 +64,8 @@ * @param hubLayoutController The controller of the {@link HubLayout}. * @param currentTabSupplier The supplier of the current {@link Tab}. * @param menuButtonCoordinator Root component for the app menu. + * @param hubToolbarOverviewColorSupplier Notifies when the hub's toolbar overview color + * changes. * @param searchActivityClient A client for the search activity, used to launch search. */ public HubCoordinator( @@ -74,7 +76,8 @@ @NonNull HubLayoutController hubLayoutController, @NonNull ObservableSupplier<Tab> currentTabSupplier, @NonNull MenuButtonCoordinator menuButtonCoordinator, - @NonNull SearchActivityClient searchActivityClient) { + @NonNull SearchActivityClient searchActivityClient, + @NonNull ObservableSupplierImpl<Integer> hubToolbarOverviewColorSupplier) { Context context = containerView.getContext(); mBackPressStateChangeCallback = (ignored) -> updateHandleBackPressSupplier(); mPaneManager = paneManager; @@ -100,7 +103,8 @@ paneManager, menuButtonCoordinator, tracker, - searchActivityClient); + searchActivityClient, + hubToolbarOverviewColorSupplier); HubPaneHostView hubPaneHostView = mContainerView.findViewById(R.id.hub_pane_host); mHubPaneHostCoordinator =
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java index a70df05..0d864d8 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubCoordinatorUnitTest.java
@@ -68,6 +68,8 @@ @Mock private Tracker mTracker; @Mock private SearchActivityClient mSearchActivityClient; + private final ObservableSupplierImpl<Integer> mColorOverviewSupplier = + new ObservableSupplierImpl<>(); private ObservableSupplierImpl<Boolean> mHubVisibilitySupplier = new ObservableSupplierImpl<>(); private ObservableSupplierImpl<Boolean> mTabSwitcherBackPressSupplier = new ObservableSupplierImpl<>(); @@ -140,7 +142,8 @@ mHubLayoutController, mTabSupplier, mMenuButtonCoordinator, - mSearchActivityClient); + mSearchActivityClient, + mColorOverviewSupplier); ShadowLooper.runUiThreadTasks(); mRootView.getChildCount(); assertNotEquals(0, mRootView.getChildCount());
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubManagerImpl.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubManagerImpl.java index b5a5a225..9ced8cd 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubManagerImpl.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubManagerImpl.java
@@ -50,6 +50,8 @@ private final @NonNull MenuButtonCoordinator mMenuButtonCoordinator; private final @NonNull HubShowPaneHelper mHubShowPaneHelper; private final @NonNull SearchActivityClient mSearchActivityClient; + private final @NonNull ObservableSupplierImpl<Integer> mHubToolbarOverviewColorSupplier = + new ObservableSupplierImpl<>(null); // This is effectively NonNull and final once the HubLayout is initialized. private HubLayoutController mHubLayoutController; @@ -139,6 +141,11 @@ } @Override + public ObservableSupplier<Integer> getHubToolbarOverviewColorSupplier() { + return mHubToolbarOverviewColorSupplier; + } + + @Override public void setHubLayoutController(@NonNull HubLayoutController hubLayoutController) { assert mHubLayoutController == null : "setHubLayoutController should only be called once."; mHubLayoutController = hubLayoutController; @@ -206,7 +213,8 @@ mHubLayoutController, mTabSupplier, mMenuButtonCoordinator, - mSearchActivityClient); + mSearchActivityClient, + mHubToolbarOverviewColorSupplier); mBackPressManager.addHandler(mHubCoordinator, BackPressHandler.Type.HUB); Pane pane = mPaneManager.getFocusedPaneSupplier().get(); attachPaneDependencies(pane); @@ -220,6 +228,8 @@ mBackPressManager.removeHandler(mHubCoordinator); mHubCoordinator.destroy(); mHubCoordinator = null; + + mHubToolbarOverviewColorSupplier.set(null); } }
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java index 193240b1..41970d931 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarCoordinator.java
@@ -10,6 +10,7 @@ import androidx.annotation.NonNull; +import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.chrome.browser.toolbar.menu_button.MenuButton; import org.chromium.chrome.browser.toolbar.menu_button.MenuButtonCoordinator; import org.chromium.chrome.browser.ui.searchactivityutils.SearchActivityClient; @@ -30,6 +31,8 @@ * @param menuButtonCoordinator Root component for the app menu. * @param tracker Used to record user engagement events. * @param searchActivityClient A client for the search activity, used to launch search. + * @param hubToolbarOverviewColorSupplier Notifies when the hub's toolbar overview color + * changes. */ public HubToolbarCoordinator( @NonNull Activity activity, @@ -37,11 +40,18 @@ @NonNull PaneManager paneManager, @NonNull MenuButtonCoordinator menuButtonCoordinator, @NonNull Tracker tracker, - @NonNull SearchActivityClient searchActivityClient) { + @NonNull SearchActivityClient searchActivityClient, + @NonNull ObservableSupplierImpl<Integer> hubToolbarOverviewColorSupplier) { PropertyModel model = new PropertyModel.Builder(HubToolbarProperties.ALL_KEYS).build(); PropertyModelChangeProcessor.create(model, hubToolbarView, HubToolbarViewBinder::bind); mMediator = - new HubToolbarMediator(activity, model, paneManager, tracker, searchActivityClient); + new HubToolbarMediator( + activity, + model, + paneManager, + tracker, + searchActivityClient, + hubToolbarOverviewColorSupplier); mHubToolbarView = hubToolbarView; MenuButton menuButton = hubToolbarView.findViewById(R.id.menu_button_wrapper);
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediator.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediator.java index 348fd810..21a2960 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediator.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediator.java
@@ -15,6 +15,7 @@ import static org.chromium.chrome.browser.hub.HubToolbarProperties.SEARCH_LISTENER; import static org.chromium.chrome.browser.hub.HubToolbarProperties.SEARCH_LOUPE_VISIBLE; import static org.chromium.chrome.browser.hub.HubToolbarProperties.SHOW_ACTION_BUTTON_TEXT; +import static org.chromium.chrome.browser.hub.HubToolbarProperties.TOOLBAR_OVERVIEW_COLOR_SETTER; import android.content.ComponentCallbacks; import android.content.Context; @@ -29,6 +30,7 @@ import org.chromium.base.Callback; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.supplier.TransitiveObservableSupplier; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.hub.HubToolbarProperties.PaneButtonLookup; @@ -127,7 +129,8 @@ @NonNull PropertyModel propertyModel, @NonNull PaneManager paneManager, @NonNull Tracker tracker, - @NonNull SearchActivityClient searchActivityClient) { + @NonNull SearchActivityClient searchActivityClient, + @NonNull ObservableSupplierImpl<Integer> hubToolbarOverviewColorSupplier) { mContext = context; mPropertyModel = propertyModel; mPaneManager = paneManager; @@ -168,6 +171,7 @@ mComponentCallbacks.onConfigurationChanged(mContext.getResources().getConfiguration()); mContext.registerComponentCallbacks(mComponentCallbacks); } + mPropertyModel.set(TOOLBAR_OVERVIEW_COLOR_SETTER, hubToolbarOverviewColorSupplier::set); } /** Cleans up observers. */
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediatorUnitTest.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediatorUnitTest.java index 31a6744..d2a1d0c 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediatorUnitTest.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarMediatorUnitTest.java
@@ -108,6 +108,7 @@ mIncognitoTabSwitcherReferenceButtonDataSupplier2; private ObservableSupplierImpl<DisplayButtonData> mTabGroupsPaneReferenceButtonDataSupplier3; private ObservableSupplierImpl<DisplayButtonData> mBookmarksPaneReferenceButtonDataSupplier4; + private ObservableSupplierImpl<Integer> mOverviewColorSupplier; private PropertyModel mModel; @Before @@ -118,6 +119,7 @@ mIncognitoTabSwitcherReferenceButtonDataSupplier2 = new ObservableSupplierImpl<>(); mTabGroupsPaneReferenceButtonDataSupplier3 = new ObservableSupplierImpl<>(); mBookmarksPaneReferenceButtonDataSupplier4 = new ObservableSupplierImpl<>(); + mOverviewColorSupplier = new ObservableSupplierImpl<>(); mModel = new PropertyModel.Builder(HubToolbarProperties.ALL_KEYS).build(); mModel.addObserver(mPropertyObserver); @@ -173,7 +175,12 @@ HubToolbarMediator mediator = new HubToolbarMediator( - mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); assertTrue(mFocusedPaneSupplier.hasObservers()); mediator.destroy(); @@ -186,7 +193,13 @@ @Test @SmallTest public void testWithActionButtonData() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); mFocusedPaneSupplier.set(mTabSwitcherPane); mActionButtonSupplier.set(mFullButtonData); assertEquals(mFullButtonData, mModel.get(ACTION_BUTTON_DATA)); @@ -195,7 +208,13 @@ @Test @SmallTest public void testPaneSwitcherButtonData() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); List<FullButtonData> paneSwitcherButtonData = mModel.get(PANE_SWITCHER_BUTTON_DATA); assertEquals(2, paneSwitcherButtonData.size()); @@ -211,7 +230,13 @@ public void testNullPane() { when(mPaneManager.getPaneForId(PaneId.INCOGNITO_TAB_SWITCHER)).thenReturn(null); - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); List<FullButtonData> paneSwitcherButtonData = mModel.get(PANE_SWITCHER_BUTTON_DATA); assertEquals(1, paneSwitcherButtonData.size()); @@ -224,7 +249,13 @@ public void testPaneSwitcherButtonDataEventCount() { verify(mPropertyObserver, never()).onPropertyChanged(any(), eq(PANE_SWITCHER_BUTTON_DATA)); - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); verify(mPropertyObserver, times(1)).onPropertyChanged(any(), eq(PANE_SWITCHER_BUTTON_DATA)); mTabSwitcherReferenceButtonDataSupplier1.set(mDisplayButtonData); @@ -241,7 +272,13 @@ @SmallTest @DisableFeatures({ChromeFeatureList.TAB_SWITCHER_FULL_NEW_TAB_BUTTON}) public void testActionButtonHasText() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); assertFalse(mModel.get(SHOW_ACTION_BUTTON_TEXT)); mTabSwitcherReferenceButtonDataSupplier1.set(null); @@ -262,7 +299,13 @@ PaneId.TAB_GROUPS, PaneId.BOOKMARKS)); - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); // 4 buttons. assertFalse(mModel.get(SHOW_ACTION_BUTTON_TEXT)); @@ -296,7 +339,13 @@ mConfiguration.screenWidthDp = WIDE_SCREEN_WIDTH_DP; - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); // 4 buttons. assertFalse(mModel.get(SHOW_ACTION_BUTTON_TEXT)); @@ -320,7 +369,13 @@ @Test @SmallTest public void testPaneSwitcherIndex() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); assertEquals(-1, mModel.get(PANE_SWITCHER_INDEX)); mFocusedPaneSupplier.set(mTabSwitcherPane); @@ -349,7 +404,13 @@ @Test @SmallTest public void testHubColorScheme() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); mFocusedPaneSupplier.set(mTabSwitcherPane); assertEquals( new HubColorSchemeUpdate(HubColorScheme.DEFAULT, HubColorScheme.DEFAULT), @@ -369,7 +430,13 @@ @Test @SmallTest public void testMenuButtonVisibility() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); when(mIncognitoTabSwitcherPane.getMenuButtonVisible()).thenReturn(false); mFocusedPaneSupplier.set(mIncognitoTabSwitcherPane); assertFalse(mModel.get(MENU_BUTTON_VISIBLE)); @@ -387,7 +454,12 @@ public void testPaneButtonLookupCallback() { HubToolbarMediator mediator = new HubToolbarMediator( - mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); assertEquals(2, mModel.get(PANE_SWITCHER_BUTTON_DATA).size()); assertNull(mediator.getButton(PaneId.TAB_SWITCHER)); @@ -409,7 +481,13 @@ .thenReturn(ImmutableSet.of(PaneId.TAB_SWITCHER, PaneId.TAB_GROUPS)); when(mPaneManager.getPaneForId(PaneId.TAB_GROUPS)).thenReturn(mTabSwitcherPane); - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); List<FullButtonData> paneSwitcherButtonData = mModel.get(PANE_SWITCHER_BUTTON_DATA); assertEquals(2, paneSwitcherButtonData.size()); @@ -425,7 +503,13 @@ @Test @SmallTest public void testIsCurrentPaneIncognito() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); mFocusedPaneSupplier.set(mTabSwitcherPane); assertFalse(mModel.get(IS_INCOGNITO)); mFocusedPaneSupplier.set(mIncognitoTabSwitcherPane); @@ -445,7 +529,8 @@ mModel, mPaneManager, mTracker, - mSearchActivityClient); + mSearchActivityClient, + mOverviewColorSupplier); assertTrue(mModel.get(SEARCH_BOX_VISIBLE)); assertFalse(mModel.get(SEARCH_LOUPE_VISIBLE)); assertNotNull(mModel.get(SEARCH_LISTENER)); @@ -463,7 +548,8 @@ mModel, mPaneManager, mTracker, - mSearchActivityClient); + mSearchActivityClient, + mOverviewColorSupplier); assertFalse(mModel.get(SEARCH_BOX_VISIBLE)); assertTrue(mModel.get(SEARCH_LOUPE_VISIBLE)); assertNotNull(mModel.get(SEARCH_LISTENER)); @@ -473,7 +559,13 @@ @SmallTest @DisableFeatures(OmniboxFeatureList.ANDROID_HUB_SEARCH) public void testSearchBoxSetup_FlagNotEnabled() { - new HubToolbarMediator(mActivity, mModel, mPaneManager, mTracker, mSearchActivityClient); + new HubToolbarMediator( + mActivity, + mModel, + mPaneManager, + mTracker, + mSearchActivityClient, + mOverviewColorSupplier); assertFalse(mModel.get(SEARCH_BOX_VISIBLE)); assertFalse(mModel.get(SEARCH_LOUPE_VISIBLE)); assertNull(mModel.get(SEARCH_LISTENER)); @@ -490,7 +582,8 @@ mModel, mPaneManager, mTracker, - mSearchActivityClient); + mSearchActivityClient, + mOverviewColorSupplier); assertTrue(mModel.get(SEARCH_BOX_VISIBLE)); assertFalse(mModel.get(SEARCH_LOUPE_VISIBLE)); @@ -517,7 +610,8 @@ mModel, mPaneManager, mTracker, - mSearchActivityClient); + mSearchActivityClient, + mOverviewColorSupplier); assertFalse(mModel.get(SEARCH_BOX_VISIBLE)); assertTrue(mModel.get(SEARCH_LOUPE_VISIBLE)); @@ -542,7 +636,8 @@ mModel, mPaneManager, mTracker, - mSearchActivityClient); + mSearchActivityClient, + mOverviewColorSupplier); assertTrue(mModel.get(SEARCH_BOX_VISIBLE)); assertFalse(mModel.get(SEARCH_LOUPE_VISIBLE)); assertNotNull(mModel.get(SEARCH_LISTENER)); @@ -579,7 +674,8 @@ mModel, mPaneManager, mTracker, - mSearchActivityClient); + mSearchActivityClient, + mOverviewColorSupplier); assertFalse(mModel.get(SEARCH_BOX_VISIBLE)); assertTrue(mModel.get(SEARCH_LOUPE_VISIBLE)); assertNotNull(mModel.get(SEARCH_LISTENER));
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarProperties.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarProperties.java index f490a45..71f68fa 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarProperties.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarProperties.java
@@ -54,6 +54,9 @@ public static final WritableObjectPropertyKey<Callback<PaneButtonLookup>> PANE_BUTTON_LOOKUP_CALLBACK = new WritableObjectPropertyKey(); + public static final WritableObjectPropertyKey<Callback<Integer>> TOOLBAR_OVERVIEW_COLOR_SETTER = + new WritableObjectPropertyKey<>(); + static final PropertyKey[] ALL_KEYS = { ACTION_BUTTON_DATA, SHOW_ACTION_BUTTON_TEXT, @@ -66,5 +69,6 @@ SEARCH_LOUPE_VISIBLE, SEARCH_LISTENER, IS_INCOGNITO, + TOOLBAR_OVERVIEW_COLOR_SETTER, }; }
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java index f94dc7f..b2fae7c 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarView.java
@@ -50,6 +50,7 @@ private EditText mSearchBoxTextView; private ImageView mSearchLoupeView; + public Callback<Integer> mToolbarOverviewColorSetter; private OnTabSelectedListener mOnTabSelectedListener; private boolean mBlockTabSelectionCallback; private final AnimationHandler mColorBlendAnimatorHandler; @@ -60,6 +61,7 @@ super(context, attributeSet); mColorBlendAnimatorHandler = new AnimationHandler(); mAnimatorSetBuilder = new HubColorBlendAnimatorSetHelper(); + mToolbarOverviewColorSetter = (color) -> {}; } @Override @@ -200,6 +202,7 @@ ColorStateList.valueOf(interpolatedColor); ImageViewCompat.setImageTintList(mMenuButton, menuButtonColor); })); + // TODO(crbug.com/40948541): Updating the app menu color here is more correct and // should be done for code health. Menu Button Color is also set by // HubToolbarCoordinator. @@ -227,6 +230,14 @@ PANE_COLOR_BLEND_ANIMATION_DURATION_MS, colorScheme -> HubColors.getIconColor(context, colorScheme), this::updateSearchLoupeColor)); + + // We don't want to pass a method reference. Lambdas will ensure we run the most recent + // setter. + mAnimatorSetBuilder.registerBlend( + new SingleHubViewColorBlend( + PANE_COLOR_BLEND_ANIMATION_DURATION_MS, + colorScheme -> HubColors.getBackgroundColor(context, colorScheme), + color -> mToolbarOverviewColorSetter.onResult(color))); } private void updateTabIconTintInternal( @@ -265,6 +276,10 @@ mSearchLoupeView.setOnClickListener(v -> searchBarListener.run()); } + void setToolbarColorOverviewListener(Callback<Integer> colorSetter) { + mToolbarOverviewColorSetter = colorSetter; + } + void updateIncognitoElements(boolean isIncognito) { if (OmniboxFeatures.sAndroidHubSearch.isEnabled()) { updateSearchBoxElements(isIncognito);
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarViewBinder.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarViewBinder.java index 257e929ff..f3eb0d63 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarViewBinder.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/HubToolbarViewBinder.java
@@ -15,6 +15,7 @@ import static org.chromium.chrome.browser.hub.HubToolbarProperties.SEARCH_LISTENER; import static org.chromium.chrome.browser.hub.HubToolbarProperties.SEARCH_LOUPE_VISIBLE; import static org.chromium.chrome.browser.hub.HubToolbarProperties.SHOW_ACTION_BUTTON_TEXT; +import static org.chromium.chrome.browser.hub.HubToolbarProperties.TOOLBAR_OVERVIEW_COLOR_SETTER; import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; @@ -44,6 +45,8 @@ view.setSearchListener(model.get(SEARCH_LISTENER)); } else if (key == IS_INCOGNITO) { view.updateIncognitoElements(model.get(IS_INCOGNITO)); + } else if (key == TOOLBAR_OVERVIEW_COLOR_SETTER) { + view.setToolbarColorOverviewListener(model.get(TOOLBAR_OVERVIEW_COLOR_SETTER)); } } }
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProvider.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProvider.java index adb307b..d24688bb 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProvider.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProvider.java
@@ -267,19 +267,27 @@ assert mAnimationDataSupplier.hasValue(); - View toolbarView = mHubContainerView.findViewById(R.id.hub_toolbar); + @Nullable View toolbarView = mHubContainerView.findViewById(R.id.hub_toolbar); + RecordHistogram.recordBooleanHistogram( + "Android.Hub.ToolbarPresentOnAnimation", toolbarView != null); + boolean isShrink = mAnimationType == HubLayoutAnimationType.SHRINK_TAB; float initialAlpha = isShrink ? 0.0f : 1.0f; float finalAlpha = isShrink ? 1.0f : 0.0f; - ObjectAnimator fadeAnimator = - ObjectAnimator.ofFloat(toolbarView, View.ALPHA, initialAlpha, finalAlpha); - fadeAnimator.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN_INTERPOLATOR); - fadeAnimator.addUpdateListener( - animation -> { - if (animation.getAnimatedValue() instanceof Float animationAlpha) { - mOnAlphaChange.accept(animationAlpha); - } - }); + final @Nullable ObjectAnimator fadeAnimator; + if (toolbarView != null) { + fadeAnimator = + ObjectAnimator.ofFloat(toolbarView, View.ALPHA, initialAlpha, finalAlpha); + fadeAnimator.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN_INTERPOLATOR); + fadeAnimator.addUpdateListener( + animation -> { + if (animation.getAnimatedValue() instanceof Float animationAlpha) { + mOnAlphaChange.accept(animationAlpha); + } + }); + } else { + fadeAnimator = null; + } int searchBoxHeight = OmniboxFeatures.sAndroidHubSearch.isEnabled() @@ -332,14 +340,20 @@ }); AnimatorSet animatorSet = new AnimatorSet(); - animatorSet.playTogether(shrinkExpandAnimator, fadeAnimator, cornerAnimator); + if (fadeAnimator == null) { + animatorSet.playTogether(shrinkExpandAnimator, cornerAnimator); + } else { + animatorSet.playTogether(shrinkExpandAnimator, fadeAnimator, cornerAnimator); + } animatorSet.setDuration(mDurationMs); HubLayoutAnimationListener listener = new HubLayoutAnimationListener() { @Override public void beforeStart() { - toolbarView.setAlpha(initialAlpha); + if (toolbarView != null) { + toolbarView.setAlpha(initialAlpha); + } mOnAlphaChange.accept(initialAlpha); mHubContainerView.setVisibility(View.VISIBLE); mShrinkExpandImageView.setVisibility(View.VISIBLE); @@ -372,7 +386,9 @@ // Reset the toolbar to the default alpha of 1. For future animations this // will be updated again. At this point the Hub is either gone or visible // so the correct alpha is 1 regardless of the animation direction. - toolbarView.setAlpha(1.0f); + if (toolbarView != null) { + toolbarView.setAlpha(1.0f); + } mOnAlphaChange.accept(finalAlpha); } };
diff --git a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProviderUnitTest.java b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProviderUnitTest.java index 6d967e08..5b74e786 100644 --- a/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProviderUnitTest.java +++ b/chrome/browser/hub/internal/android/java/src/org/chromium/chrome/browser/hub/ShrinkExpandHubLayoutAnimatorProviderUnitTest.java
@@ -10,9 +10,11 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import static org.mockito.ArgumentMatchers.anyBoolean; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.atLeastOnce; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; @@ -35,7 +37,6 @@ import androidx.annotation.NonNull; import androidx.test.ext.junit.rules.ActivityScenarioRule; -import androidx.test.filters.SmallTest; import org.junit.Before; import org.junit.Rule; @@ -103,7 +104,6 @@ } @Test - @SmallTest public void testShrinkTab() { var watcher = HistogramWatcher.newBuilder() @@ -173,7 +173,6 @@ } @Test - @SmallTest public void testExpandTab() { var watcher = HistogramWatcher.newBuilder() @@ -243,7 +242,6 @@ } @Test - @SmallTest public void testNewTab() { HubLayoutAnimatorProvider animatorProvider = ShrinkExpandHubLayoutAnimationFactory.createNewTabAnimatorProvider( @@ -287,7 +285,6 @@ } @Test - @SmallTest public void testShrinkFallbackAnimationDueToTimeoutMissingData() { HubLayoutAnimatorProvider animatorProvider = ShrinkExpandHubLayoutAnimationFactory.createShrinkTabAnimatorProvider( @@ -314,7 +311,6 @@ } @Test - @SmallTest public void testShrinkFallbackAnimationDueToTimeoutMissingBitmap() { HubLayoutAnimatorProvider animatorProvider = ShrinkExpandHubLayoutAnimationFactory.createShrinkTabAnimatorProvider( @@ -353,7 +349,6 @@ } @Test - @SmallTest public void testShrinkFallbackAnimationViaSupplierData() { HubLayoutAnimatorProvider animatorProvider = ShrinkExpandHubLayoutAnimationFactory.createShrinkTabAnimatorProvider( @@ -392,7 +387,6 @@ } @Test - @SmallTest public void testExpandFallbackAnimationViaForcedToFinish() { HubLayoutAnimatorProvider animatorProvider = ShrinkExpandHubLayoutAnimationFactory.createExpandTabAnimatorProvider( @@ -417,7 +411,6 @@ } @Test - @SmallTest public void testNewTabFallbackAnimation() { HubLayoutAnimatorProvider animatorProvider = ShrinkExpandHubLayoutAnimationFactory.createNewTabAnimatorProvider( @@ -457,7 +450,6 @@ } @Test - @SmallTest public void testImageViewWeakRefBitmapCallback() { ImageViewWeakRefBitmapCallback weakRefCallback = new ImageViewWeakRefBitmapCallback(mImageViewMock, mRunnableMock); @@ -469,7 +461,6 @@ } @Test - @SmallTest public void testImageViewWeakRefBitmapCallbackGarbageCollection() { ImageView imageView = new ImageView(mActivity); WeakReference<ImageView> imageViewWeakRef = new WeakReference<>(imageView); @@ -497,7 +488,6 @@ } @Test - @SmallTest public void testImageViewWeakRefBitmapCallbackNoBitmapIfNoView() { ImageView imageView = new ImageView(mActivity); WeakReference<ImageView> imageViewWeakRef = new WeakReference<>(imageView); @@ -515,6 +505,45 @@ verify(mRunnableMock, never()).run(); } + @Test + public void testAnimationAfterDestroy() { + HubLayoutAnimatorProvider animatorProvider = + ShrinkExpandHubLayoutAnimationFactory.createNewTabAnimatorProvider( + mHubContainerView, + mAnimationDataSupplier, + Color.RED, + HUB_LAYOUT_EXPAND_NEW_TAB_DURATION_MS, + mOnAlphaChange); + + // Remove all views like a tear down/destroy would. + mHubContainerView.removeAllViews(); + + ShrinkExpandAnimationData data = + new ShrinkExpandAnimationData( + /* initialRect */ new Rect(100, 0, 101, 1), + /* finalRect= */ new Rect(10, 15, WIDTH - 10, HEIGHT - 15), + /* initialTopCornerRadius= */ 0, + /* initialBottomCornerRadius= */ 0, + /* finalTopCornerRadius= */ 0, + /* finalBottomCornerRadius= */ 0, + /* thumbnailSize= */ null, + /* useFallbackAnimation= */ false); + mAnimationDataSupplier.set(data); + + HubLayoutAnimationRunner runner = + HubLayoutAnimationRunnerFactory.createHubLayoutAnimationRunner(animatorProvider); + + mListener = mock(HubLayoutAnimationListener.class); + runner.addListener(mListener); + runner.runWithWaitForAnimatorTimeout(HUB_LAYOUT_TIMEOUT_MS); + + ShadowLooper.runUiThreadTasksIncludingDelayedTasks(); + + verify(mListener).beforeStart(); + verify(mListener).onEnd(anyBoolean()); + verify(mListener).afterEnd(); + } + private void setUpShrinkExpandListener( boolean isShrink, @NonNull ShrinkExpandImageView imageView,
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 50b2c90..4bee729 100644 --- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc +++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -104,6 +104,7 @@ #include "base/files/file_path.h" #include "base/path_service.h" +#include "base/win/hardware_check.h" #include "base/win/registry.h" #include "base/win/scoped_handle.h" #include "base/win/windows_version.h" @@ -860,6 +861,11 @@ base::UmaHistogramBoolean("Windows.ParallelDllLoadingEnabled", IsParallelDllLoadingEnabled()); RecordAppCompatMetrics(); + + if (base::win::OSInfo::Kernel32Version() < base::win::Version::WIN11) { + base::UmaHistogramBoolean("Windows.Win11UpgradeEligible", + base::win::IsWin11UpgradeEligible()); + } key_credential_manager_support::ReportKeyCredentialManagerSupport(); #endif // BUILDFLAG(IS_WIN)
diff --git a/chrome/browser/nearby_sharing/certificates/BUILD.gn b/chrome/browser/nearby_sharing/certificates/BUILD.gn index 4c0dc3f..790e3c7 100644 --- a/chrome/browser/nearby_sharing/certificates/BUILD.gn +++ b/chrome/browser/nearby_sharing/certificates/BUILD.gn
@@ -94,7 +94,6 @@ "//base/test:test_support", "//chrome/browser/nearby_sharing/client:test_support", "//chrome/browser/nearby_sharing/common", - "//chrome/browser/nearby_sharing/common:test_support", "//chrome/browser/nearby_sharing/contacts:test_support", "//chrome/browser/nearby_sharing/local_device_data:test_support", "//chromeos/ash/components/nearby/common/client",
diff --git a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc index 92988ef..456c02a 100644 --- a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc +++ b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.cc
@@ -13,12 +13,12 @@ std::unique_ptr<NearbyShareCertificateManager> FakeNearbyShareCertificateManager::Factory::CreateInstance( + std::string user_email, + const base::FilePath& profile_path, + PrefService* pref_service, NearbyShareLocalDeviceDataManager* local_device_data_manager, NearbyShareContactManager* contact_manager, - NearbyShareProfileInfoProvider* profile_info_provider, - PrefService* pref_service, leveldb_proto::ProtoDatabaseProvider* proto_database_provider, - const base::FilePath& profile_path, NearbyShareClientFactory* client_factory, const base::Clock* clock) { auto instance = std::make_unique<FakeNearbyShareCertificateManager>();
diff --git a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h index ac7e618..b73369c2 100644 --- a/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h +++ b/chrome/browser/nearby_sharing/certificates/fake_nearby_share_certificate_manager.h
@@ -19,8 +19,6 @@ #include "chrome/browser/nearby_sharing/certificates/nearby_share_private_certificate.h" #include "third_party/nearby/sharing/proto/rpc_resources.pb.h" -class NearbyShareProfileInfoProvider; - // A fake implementation of NearbyShareCertificateManager, along with a fake // factory, to be used in tests. class FakeNearbyShareCertificateManager : public NearbyShareCertificateManager { @@ -43,12 +41,12 @@ private: // NearbyShareCertificateManagerImpl::Factory: std::unique_ptr<NearbyShareCertificateManager> CreateInstance( + std::string user_email, + const base::FilePath& profile_path, + PrefService* pref_service, NearbyShareLocalDeviceDataManager* local_device_data_manager, NearbyShareContactManager* contact_manager, - NearbyShareProfileInfoProvider* profile_info_provider, - PrefService* pref_service, leveldb_proto::ProtoDatabaseProvider* proto_database_provider, - const base::FilePath& profile_path, NearbyShareClientFactory* client_factory, const base::Clock* clock) override;
diff --git a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc index b01c900..634e1a82 100644 --- a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc +++ b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.cc
@@ -23,7 +23,6 @@ #include "chrome/browser/nearby_sharing/client/nearby_share_client.h" #include "chrome/browser/nearby_sharing/common/nearby_share_features.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" -#include "chrome/browser/nearby_sharing/common/nearby_share_profile_info_provider.h" #include "chrome/browser/nearby_sharing/common/nearby_share_switches.h" #include "chromeos/ash/components/nearby/common/client/nearby_http_result.h" #include "chromeos/ash/components/nearby/common/scheduling/nearby_scheduler_factory.h" @@ -260,27 +259,27 @@ // static std::unique_ptr<NearbyShareCertificateManager> NearbyShareCertificateManagerImpl::Factory::Create( + std::string user_email, + const base::FilePath& profile_path, + PrefService* pref_service, NearbyShareLocalDeviceDataManager* local_device_data_manager, NearbyShareContactManager* contact_manager, - NearbyShareProfileInfoProvider* profile_info_provider, - PrefService* pref_service, leveldb_proto::ProtoDatabaseProvider* proto_database_provider, - const base::FilePath& profile_path, NearbyShareClientFactory* client_factory, const base::Clock* clock) { DCHECK(clock); if (test_factory_) { - return test_factory_->CreateInstance(local_device_data_manager, - contact_manager, profile_info_provider, - pref_service, proto_database_provider, - profile_path, client_factory, clock); + return test_factory_->CreateInstance( + std::move(user_email), profile_path, pref_service, + local_device_data_manager, contact_manager, proto_database_provider, + client_factory, clock); } return base::WrapUnique(new NearbyShareCertificateManagerImpl( - local_device_data_manager, contact_manager, profile_info_provider, - pref_service, proto_database_provider, profile_path, client_factory, - clock)); + std::move(user_email), profile_path, pref_service, + local_device_data_manager, contact_manager, proto_database_provider, + client_factory, clock)); } // static @@ -292,18 +291,18 @@ NearbyShareCertificateManagerImpl::Factory::~Factory() = default; NearbyShareCertificateManagerImpl::NearbyShareCertificateManagerImpl( + std::string user_email, + const base::FilePath& profile_path, + PrefService* pref_service, NearbyShareLocalDeviceDataManager* local_device_data_manager, NearbyShareContactManager* contact_manager, - NearbyShareProfileInfoProvider* profile_info_provider, - PrefService* pref_service, leveldb_proto::ProtoDatabaseProvider* proto_database_provider, - const base::FilePath& profile_path, NearbyShareClientFactory* client_factory, const base::Clock* clock) - : local_device_data_manager_(local_device_data_manager), - contact_manager_(contact_manager), - profile_info_provider_(profile_info_provider), + : user_email_(std::move(user_email)), pref_service_(pref_service), + local_device_data_manager_(local_device_data_manager), + contact_manager_(contact_manager), client_factory_(client_factory), clock_(clock), certificate_storage_(NearbyShareCertificateStorageImpl::Factory::Create( @@ -588,11 +587,12 @@ } std::optional<nearby::sharing::proto::EncryptedMetadata> metadata = - BuildMetadata(local_device_data_manager_->GetDeviceName(), - local_device_data_manager_->GetFullName(), - local_device_data_manager_->GetIconUrl(), - profile_info_provider_->GetProfileUserName(), - adapter_.get()); + BuildMetadata( + local_device_data_manager_->GetDeviceName(), + local_device_data_manager_->GetFullName(), + local_device_data_manager_->GetIconUrl(), + user_email_.empty() ? std::nullopt : std::optional(user_email_), + adapter_.get()); if (!metadata) { CD_LOG(WARNING, Feature::NS) << __func__
diff --git a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h index 22b8fd9..58f7ff9 100644 --- a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h +++ b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h
@@ -7,6 +7,7 @@ #include <memory> #include <optional> +#include <string> #include <vector> #include "base/files/file_path.h" @@ -31,7 +32,6 @@ class NearbyShareClient; class NearbyShareClientFactory; class NearbyShareLocalDeviceDataManager; -class NearbyShareProfileInfoProvider; class PrefService; namespace device { @@ -68,12 +68,12 @@ class Factory { public: static std::unique_ptr<NearbyShareCertificateManager> Create( + std::string user_email, + const base::FilePath& profile_path, + PrefService* pref_service, NearbyShareLocalDeviceDataManager* local_device_data_manager, NearbyShareContactManager* contact_manager, - NearbyShareProfileInfoProvider* profile_info_provider, - PrefService* pref_service, leveldb_proto::ProtoDatabaseProvider* proto_database_provider, - const base::FilePath& profile_path, NearbyShareClientFactory* client_factory, const base::Clock* clock = base::DefaultClock::GetInstance()); static void SetFactoryForTesting(Factory* test_factory); @@ -81,12 +81,12 @@ protected: virtual ~Factory(); virtual std::unique_ptr<NearbyShareCertificateManager> CreateInstance( + std::string user_email, + const base::FilePath& profile_path, + PrefService* pref_service, NearbyShareLocalDeviceDataManager* local_device_data_manager, NearbyShareContactManager* contact_manager, - NearbyShareProfileInfoProvider* profile_info_provider, - PrefService* pref_service, leveldb_proto::ProtoDatabaseProvider* proto_database_provider, - const base::FilePath& profile_path, NearbyShareClientFactory* client_factory, const base::Clock* clock) = 0; @@ -98,12 +98,12 @@ private: NearbyShareCertificateManagerImpl( + std::string user_email, + const base::FilePath& profile_path, + PrefService* pref_service, NearbyShareLocalDeviceDataManager* local_device_data_manager, NearbyShareContactManager* contact_manager, - NearbyShareProfileInfoProvider* profile_info_provider, - PrefService* pref_service, leveldb_proto::ProtoDatabaseProvider* proto_database_provider, - const base::FilePath& profile_path, NearbyShareClientFactory* client_factory, const base::Clock* clock); @@ -212,11 +212,14 @@ size_t certificate_count); base::OneShotTimer timer_; + + // User/Profile attributes. + const std::string user_email_; + const raw_ptr<PrefService> pref_service_; + raw_ptr<NearbyShareLocalDeviceDataManager> local_device_data_manager_ = nullptr; raw_ptr<NearbyShareContactManager> contact_manager_ = nullptr; - raw_ptr<NearbyShareProfileInfoProvider> profile_info_provider_ = nullptr; - raw_ptr<PrefService> pref_service_ = nullptr; raw_ptr<NearbyShareClientFactory> client_factory_ = nullptr; raw_ptr<const base::Clock> clock_; std::unique_ptr<NearbyShareCertificateStorage> certificate_storage_;
diff --git a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc index b3b1bbe..882f0747 100644 --- a/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl_unittest.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager_impl.h" +#include <string> +#include <utility> + #include "base/memory/raw_ptr.h" #include "base/strings/string_number_conversions.h" #include "base/test/metrics/histogram_tester.h" @@ -15,7 +18,6 @@ #include "chrome/browser/nearby_sharing/certificates/nearby_share_certificate_manager.h" #include "chrome/browser/nearby_sharing/certificates/test_util.h" #include "chrome/browser/nearby_sharing/client/fake_nearby_share_client.h" -#include "chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h" #include "chrome/browser/nearby_sharing/common/nearby_share_features.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.h" @@ -73,10 +75,6 @@ contact_manager_ = std::make_unique<FakeNearbyShareContactManager>(); - profile_info_provider_ = - std::make_unique<FakeNearbyShareProfileInfoProvider>(); - profile_info_provider_->set_profile_user_name(kTestProfileUserName); - pref_service_ = std::make_unique<TestingPrefServiceSimple>(); pref_service_->registry()->RegisterDictionaryPref( prefs::kNearbySharingSchedulerDownloadPublicCertificatesPrefName); @@ -113,11 +111,13 @@ void TearDown() override { cert_manager_->RemoveObserver(this); + cert_manager_.reset(); ash::nearby::NearbySchedulerFactory::SetFactoryForTesting(nullptr); NearbyShareCertificateStorageImpl::Factory::SetFactoryForTesting(nullptr); } - void InitCertificateManager(bool use_floss) { + void InitCertificateManager(bool use_floss, + std::string user_email = kTestProfileUserName) { if (use_floss) { scoped_feature_list_.InitWithFeatures( /*enabled_features=*/ @@ -126,9 +126,10 @@ } cert_manager_ = NearbyShareCertificateManagerImpl::Factory::Create( - local_device_data_manager_.get(), contact_manager_.get(), - profile_info_provider_.get(), pref_service_.get(), - /*proto_database_provider=*/nullptr, base::FilePath(), &client_factory_, + std::move(user_email), /*profile_path=*/base::FilePath(), + pref_service_.get(), local_device_data_manager_.get(), + contact_manager_.get(), + /*proto_database_provider=*/nullptr, &client_factory_, task_environment_.GetMockClock()); cert_manager_->AddObserver(this); @@ -499,7 +500,6 @@ std::unique_ptr<FakeNearbyShareLocalDeviceDataManager> local_device_data_manager_; std::unique_ptr<FakeNearbyShareContactManager> contact_manager_; - std::unique_ptr<FakeNearbyShareProfileInfoProvider> profile_info_provider_; std::unique_ptr<TestingPrefServiceSimple> pref_service_; std::unique_ptr<NearbyShareCertificateManager> cert_manager_; base::test::ScopedFeatureList scoped_feature_list_; @@ -863,13 +863,11 @@ TEST_P(NearbyShareCertificateManagerImplTest, RefreshPrivateCertificates_MissingAccountName) { - InitCertificateManager(/*use_floss=*/false); + // Full name is missing in local device data manager. + InitCertificateManager(/*use_floss=*/false, /*user_email=*/std::string()); cert_store_->ReplacePrivateCertificates( std::vector<NearbySharePrivateCertificate>()); - // Full name and icon URL are missing in local device data manager. - profile_info_provider_->set_profile_user_name(std::nullopt); - cert_manager_->Start(); HandlePrivateCertificateRefresh(/*expect_private_cert_refresh=*/true, /*expected_success=*/true);
diff --git a/chrome/browser/nearby_sharing/common/BUILD.gn b/chrome/browser/nearby_sharing/common/BUILD.gn index 5880e32..38c1bbb 100644 --- a/chrome/browser/nearby_sharing/common/BUILD.gn +++ b/chrome/browser/nearby_sharing/common/BUILD.gn
@@ -12,7 +12,6 @@ "nearby_share_features.h", "nearby_share_prefs.cc", "nearby_share_prefs.h", - "nearby_share_profile_info_provider.h", "nearby_share_resource_getter.cc", "nearby_share_resource_getter.h", "nearby_share_switches.cc", @@ -44,17 +43,6 @@ } } -source_set("test_support") { - testonly = true - - sources = [ - "fake_nearby_share_profile_info_provider.cc", - "fake_nearby_share_profile_info_provider.h", - ] - - deps = [ ":common" ] -} - source_set("unit_tests") { testonly = true @@ -62,7 +50,6 @@ deps = [ ":common", - ":test_support", "//base", "//base/test:test_support", "//build:branding_buildflags",
diff --git a/chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.cc b/chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.cc deleted file mode 100644 index b1d70c9..0000000 --- a/chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.cc +++ /dev/null
@@ -1,21 +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 "chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h" - -FakeNearbyShareProfileInfoProvider::FakeNearbyShareProfileInfoProvider() = - default; - -FakeNearbyShareProfileInfoProvider::~FakeNearbyShareProfileInfoProvider() = - default; - -std::optional<std::u16string> FakeNearbyShareProfileInfoProvider::GetGivenName() - const { - return given_name_; -} - -std::optional<std::string> -FakeNearbyShareProfileInfoProvider::GetProfileUserName() const { - return profile_user_name_; -}
diff --git a/chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h b/chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h deleted file mode 100644 index a9a506f..0000000 --- a/chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h +++ /dev/null
@@ -1,33 +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 CHROME_BROWSER_NEARBY_SHARING_COMMON_FAKE_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ -#define CHROME_BROWSER_NEARBY_SHARING_COMMON_FAKE_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_ - -#include "chrome/browser/nearby_sharing/common/nearby_share_profile_info_provider.h" - -class FakeNearbyShareProfileInfoProvider - : public NearbyShareProfileInfoProvider { - public: - FakeNearbyShareProfileInfoProvider(); - ~FakeNearbyShareProfileInfoProvider() override; - - // NearbyShareProfileInfoProvider: - std::optional<std::u16string> GetGivenName() const override; - std::optional<std::string> GetProfileUserName() const override; - - void set_given_name(const std::optional<std::u16string>& given_name) { - given_name_ = given_name; - } - void set_profile_user_name( - const std::optional<std::string>& profile_user_name) { - profile_user_name_ = profile_user_name; - } - - private: - std::optional<std::u16string> given_name_; - std::optional<std::string> profile_user_name_; -}; - -#endif // CHROME_BROWSER_NEARBY_SHARING_COMMON_FAKE_NEARBY_SHARE_PROFILE_INFO_PROVIDER_H_
diff --git a/chrome/browser/nearby_sharing/contacts/BUILD.gn b/chrome/browser/nearby_sharing/contacts/BUILD.gn index 5c3df8d7..df3493bf 100644 --- a/chrome/browser/nearby_sharing/contacts/BUILD.gn +++ b/chrome/browser/nearby_sharing/contacts/BUILD.gn
@@ -72,7 +72,6 @@ "//chrome/browser/nearby_sharing/client", "//chrome/browser/nearby_sharing/client:test_support", "//chrome/browser/nearby_sharing/common", - "//chrome/browser/nearby_sharing/common:test_support", "//chrome/browser/nearby_sharing/local_device_data:test_support", "//chromeos/ash/components/nearby/common/client", "//chromeos/ash/components/nearby/common/scheduling",
diff --git a/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.cc b/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.cc index b5cce61c..9b1fe507 100644 --- a/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.cc +++ b/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.cc
@@ -12,14 +12,12 @@ std::unique_ptr<NearbyShareContactManager> FakeNearbyShareContactManager::Factory::CreateInstance( + std::string user_email, PrefService* pref_service, NearbyShareClientFactory* http_client_factory, - NearbyShareLocalDeviceDataManager* local_device_data_manager, - NearbyShareProfileInfoProvider* profile_info_provider) { - latest_pref_service_ = pref_service; + NearbyShareLocalDeviceDataManager* local_device_data_manager) { latest_http_client_factory_ = http_client_factory; latest_local_device_data_manager_ = local_device_data_manager; - latest_profile_info_provider_ = profile_info_provider; auto instance = std::make_unique<FakeNearbyShareContactManager>(); instances_.push_back(instance.get());
diff --git a/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.h b/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.h index e52fd2e..b29deaa1 100644 --- a/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.h +++ b/chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_manager.h
@@ -17,8 +17,6 @@ class NearbyShareClientFactory; class NearbyShareLocalDeviceDataManager; -class NearbyShareProfileInfoProvider; -class PrefService; // A fake implementation of NearbyShareContactManager, along with a fake // factory, to be used in tests. Stores parameters input into @@ -42,8 +40,6 @@ return instances_; } - PrefService* latest_pref_service() const { return latest_pref_service_; } - NearbyShareClientFactory* latest_http_client_factory() const { return latest_http_client_factory_; } @@ -53,27 +49,20 @@ return latest_local_device_data_manager_; } - NearbyShareProfileInfoProvider* latest_profile_info_provider() const { - return latest_profile_info_provider_; - } - private: // NearbyShareContactManagerImpl::Factory: std::unique_ptr<NearbyShareContactManager> CreateInstance( + std::string user_email, PrefService* pref_service, NearbyShareClientFactory* http_client_factory, - NearbyShareLocalDeviceDataManager* local_device_data_manager, - NearbyShareProfileInfoProvider* profile_info_provider) override; + NearbyShareLocalDeviceDataManager* local_device_data_manager) override; std::vector<raw_ptr<FakeNearbyShareContactManager, VectorExperimental>> instances_; - raw_ptr<PrefService> latest_pref_service_ = nullptr; raw_ptr<NearbyShareClientFactory, DanglingUntriaged> latest_http_client_factory_ = nullptr; raw_ptr<NearbyShareLocalDeviceDataManager, DanglingUntriaged> latest_local_device_data_manager_ = nullptr; - raw_ptr<NearbyShareProfileInfoProvider, DanglingUntriaged> - latest_profile_info_provider_ = nullptr; }; FakeNearbyShareContactManager();
diff --git a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc index 7dfaf97..58d4e06 100644 --- a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc +++ b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.cc
@@ -12,7 +12,6 @@ #include "base/strings/string_number_conversions.h" #include "base/time/time.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" -#include "chrome/browser/nearby_sharing/common/nearby_share_profile_info_provider.h" #include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_downloader.h" #include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_downloader_impl.h" #include "chrome/browser/nearby_sharing/contacts/nearby_share_contacts_sorter.h" @@ -64,9 +63,9 @@ } nearby::sharing::proto::Contact CreateLocalContact( - const std::string& profile_user_name) { + const std::string& user_email) { nearby::sharing::proto::Contact contact; - contact.mutable_identifier()->set_account_name(profile_user_name); + contact.mutable_identifier()->set_account_name(user_email); // Always consider your own account a selected contact. contact.set_is_selected(true); return contact; @@ -174,18 +173,18 @@ // static std::unique_ptr<NearbyShareContactManager> NearbyShareContactManagerImpl::Factory::Create( + std::string user_email, PrefService* pref_service, NearbyShareClientFactory* http_client_factory, - NearbyShareLocalDeviceDataManager* local_device_data_manager, - NearbyShareProfileInfoProvider* profile_info_provider) { + NearbyShareLocalDeviceDataManager* local_device_data_manager) { if (test_factory_) { - return test_factory_->CreateInstance(pref_service, http_client_factory, - local_device_data_manager, - profile_info_provider); + return test_factory_->CreateInstance(std::move(user_email), pref_service, + http_client_factory, + local_device_data_manager); } return base::WrapUnique(new NearbyShareContactManagerImpl( - pref_service, http_client_factory, local_device_data_manager, - profile_info_provider)); + std::move(user_email), pref_service, http_client_factory, + local_device_data_manager)); } // static @@ -197,14 +196,14 @@ NearbyShareContactManagerImpl::Factory::~Factory() = default; NearbyShareContactManagerImpl::NearbyShareContactManagerImpl( + std::string user_email, PrefService* pref_service, NearbyShareClientFactory* http_client_factory, - NearbyShareLocalDeviceDataManager* local_device_data_manager, - NearbyShareProfileInfoProvider* profile_info_provider) - : pref_service_(pref_service), + NearbyShareLocalDeviceDataManager* local_device_data_manager) + : user_email_(std::move(user_email)), + pref_service_(pref_service), http_client_factory_(http_client_factory), local_device_data_manager_(local_device_data_manager), - profile_info_provider_(profile_info_provider), periodic_contact_upload_scheduler_( ash::nearby::NearbySchedulerFactory::CreatePeriodicScheduler( kContactUploadPeriod, @@ -321,16 +320,14 @@ // Enable cross-device self-share by adding your account to the list of // contacts. It is also marked as a selected contact. - std::optional<std::string> user_name = - profile_info_provider_->GetProfileUserName(); base::UmaHistogramBoolean("Nearby.Share.Contacts.CanGetProfileUserName", - user_name.has_value()); - if (!user_name) { + !user_email_.empty()); + if (user_email_.empty()) { CD_LOG(WARNING, Feature::NS) << __func__ << ": Profile user name is not valid; could not " << "add self to list of contacts to upload."; } else { - contacts_to_upload.push_back(CreateLocalContact(*user_name)); + contacts_to_upload.push_back(CreateLocalContact(user_email_)); } std::string contact_upload_hash = ComputeHash(contacts_to_upload);
diff --git a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.h b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.h index 81575bb..f383cc0b 100644 --- a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.h +++ b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl.h
@@ -20,7 +20,6 @@ class NearbyShareClientFactory; class NearbyShareContactDownloader; class NearbyShareLocalDeviceDataManager; -class NearbyShareProfileInfoProvider; class PrefService; namespace ash::nearby { @@ -50,19 +49,19 @@ class Factory { public: static std::unique_ptr<NearbyShareContactManager> Create( + std::string user_email, PrefService* pref_service, NearbyShareClientFactory* http_client_factory, - NearbyShareLocalDeviceDataManager* local_device_data_manager, - NearbyShareProfileInfoProvider* profile_info_provider); + NearbyShareLocalDeviceDataManager* local_device_data_manager); static void SetFactoryForTesting(Factory* test_factory); protected: virtual ~Factory(); virtual std::unique_ptr<NearbyShareContactManager> CreateInstance( + std::string user_email, PrefService* pref_service, NearbyShareClientFactory* http_client_factory, - NearbyShareLocalDeviceDataManager* local_device_data_manager, - NearbyShareProfileInfoProvider* profile_info_provider) = 0; + NearbyShareLocalDeviceDataManager* local_device_data_manager) = 0; private: static Factory* test_factory_; @@ -72,10 +71,10 @@ private: NearbyShareContactManagerImpl( + std::string user_email, PrefService* pref_service, NearbyShareClientFactory* http_client_factory, - NearbyShareLocalDeviceDataManager* local_device_data_manager, - NearbyShareProfileInfoProvider* profile_info_provider); + NearbyShareLocalDeviceDataManager* local_device_data_manager); // NearbyShareContactsManager: void DownloadContacts() override; @@ -110,11 +109,11 @@ const std::vector<nearby::sharing::proto::ContactRecord>& contacts, uint32_t num_unreachable_contacts_filtered_out); + std::string user_email_; raw_ptr<PrefService> pref_service_ = nullptr; raw_ptr<NearbyShareClientFactory> http_client_factory_ = nullptr; raw_ptr<NearbyShareLocalDeviceDataManager> local_device_data_manager_ = nullptr; - raw_ptr<NearbyShareProfileInfoProvider> profile_info_provider_ = nullptr; std::unique_ptr<ash::nearby::NearbyScheduler> periodic_contact_upload_scheduler_; std::unique_ptr<ash::nearby::NearbyScheduler>
diff --git a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc index 03750f2..4375e5f 100644 --- a/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/contacts/nearby_share_contact_manager_impl_unittest.cc
@@ -20,7 +20,6 @@ #include "base/containers/flat_set.h" #include "base/strings/string_number_conversions.h" #include "chrome/browser/nearby_sharing/client/fake_nearby_share_client.h" -#include "chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/nearby_sharing/contacts/fake_nearby_share_contact_downloader.h" #include "chrome/browser/nearby_sharing/contacts/nearby_share_contact_downloader.h" @@ -231,11 +230,10 @@ &scheduler_factory_); NearbyShareContactDownloaderImpl::Factory::SetFactoryForTesting( &downloader_factory_); - profile_info_provider_.set_profile_user_name(kTestProfileUserName); manager_ = NearbyShareContactManagerImpl::Factory::Create( - &pref_service_, &http_client_factory_, &local_device_data_manager_, - &profile_info_provider_); + kTestProfileUserName, &pref_service_, &http_client_factory_, + &local_device_data_manager_); manager_awaiter_ = std::make_unique<nearby_share::mojom::ContactManagerAsyncWaiter>( manager_.get()); @@ -493,7 +491,6 @@ sync_preferences::TestingPrefServiceSyncable pref_service_; FakeNearbyShareClientFactory http_client_factory_; FakeNearbyShareLocalDeviceDataManager local_device_data_manager_; - FakeNearbyShareProfileInfoProvider profile_info_provider_; ash::nearby::FakeNearbySchedulerFactory scheduler_factory_; FakeNearbyShareContactDownloader::Factory downloader_factory_; std::unique_ptr<NearbyShareContactManager> manager_;
diff --git a/chrome/browser/nearby_sharing/local_device_data/BUILD.gn b/chrome/browser/nearby_sharing/local_device_data/BUILD.gn index 836df24..3aeb80a0 100644 --- a/chrome/browser/nearby_sharing/local_device_data/BUILD.gn +++ b/chrome/browser/nearby_sharing/local_device_data/BUILD.gn
@@ -28,6 +28,7 @@ "//chromeos/ash/components/nearby/common/scheduling", "//components/cross_device/logging:logging", "//components/prefs", + "//components/user_manager", "//third_party/nearby:device_rpc_proto", "//third_party/nearby:rpc_resources_proto", "//ui/base", @@ -71,11 +72,11 @@ "//chrome/browser/nearby_sharing/client", "//chrome/browser/nearby_sharing/client:test_support", "//chrome/browser/nearby_sharing/common", - "//chrome/browser/nearby_sharing/common:test_support", "//chromeos/ash/components/nearby/common/client", "//chromeos/ash/components/nearby/common/scheduling", "//chromeos/ash/components/nearby/common/scheduling:test_support", "//components/sync_preferences:test_support", + "//components/user_manager:test_support", "//testing/gtest", "//third_party/nearby:device_rpc_proto", "//third_party/nearby:rpc_resources_proto",
diff --git a/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.cc b/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.cc index d6e4e526..4876ec1 100644 --- a/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.cc +++ b/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.cc
@@ -17,12 +17,9 @@ std::unique_ptr<NearbyShareLocalDeviceDataManager> FakeNearbyShareLocalDeviceDataManager::Factory::CreateInstance( - PrefService* pref_service, - NearbyShareClientFactory* http_client_factory, - NearbyShareProfileInfoProvider* profile_info_provider) { - latest_pref_service_ = pref_service; + user_manager::User& user, + NearbyShareClientFactory* http_client_factory) { latest_http_client_factory_ = http_client_factory; - latest_profile_info_provider_ = profile_info_provider; auto instance = std::make_unique<FakeNearbyShareLocalDeviceDataManager>( kDefaultDeviceName);
diff --git a/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.h b/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.h index 0c96368f..ae4fdf5 100644 --- a/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.h +++ b/chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_local_device_data_manager.h
@@ -17,8 +17,6 @@ #include "third_party/nearby/sharing/proto/rpc_resources.pb.h" class NearbyShareClientFactory; -class NearbyShareProfileInfoProvider; -class PrefService; // A fake implementation of NearbyShareLocalDeviceDataManager, along with a fake // factory, to be used in tests. @@ -41,31 +39,21 @@ return instances_; } - PrefService* latest_pref_service() const { return latest_pref_service_; } - NearbyShareClientFactory* latest_http_client_factory() const { return latest_http_client_factory_; } - NearbyShareProfileInfoProvider* latest_profile_info_provider() const { - return latest_profile_info_provider_; - } - protected: std::unique_ptr<NearbyShareLocalDeviceDataManager> CreateInstance( - PrefService* pref_service, - NearbyShareClientFactory* http_client_factory, - NearbyShareProfileInfoProvider* profile_info_provider) override; + user_manager::User& user, + NearbyShareClientFactory* http_client_factory) override; private: std::vector< raw_ptr<FakeNearbyShareLocalDeviceDataManager, VectorExperimental>> instances_; - raw_ptr<PrefService> latest_pref_service_ = nullptr; raw_ptr<NearbyShareClientFactory, DanglingUntriaged> latest_http_client_factory_ = nullptr; - raw_ptr<NearbyShareProfileInfoProvider, DanglingUntriaged> - latest_profile_info_provider_ = nullptr; }; struct UploadContactsCall {
diff --git a/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc b/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc index 9c58f10..4b15dbd8 100644 --- a/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc +++ b/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.cc
@@ -15,7 +15,6 @@ #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" -#include "chrome/browser/nearby_sharing/common/nearby_share_profile_info_provider.h" #include "chrome/browser/nearby_sharing/common/nearby_share_switches.h" #include "chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater.h" #include "chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater_impl.h" @@ -23,6 +22,7 @@ #include "chromeos/ash/components/nearby/common/scheduling/nearby_scheduler.h" #include "chromeos/ash/components/nearby/common/scheduling/nearby_scheduler_factory.h" #include "components/prefs/pref_service.h" +#include "components/user_manager/user.h" #include "ui/base/l10n/l10n_util.h" #include "ui/chromeos/devicetype_utils.h" @@ -66,16 +66,14 @@ // static std::unique_ptr<NearbyShareLocalDeviceDataManager> NearbyShareLocalDeviceDataManagerImpl::Factory::Create( - PrefService* pref_service, - NearbyShareClientFactory* http_client_factory, - NearbyShareProfileInfoProvider* profile_info_provider) { + user_manager::User& user, + NearbyShareClientFactory* http_client_factory) { if (test_factory_) { - return test_factory_->CreateInstance(pref_service, http_client_factory, - profile_info_provider); + return test_factory_->CreateInstance(user, http_client_factory); } - return base::WrapUnique(new NearbyShareLocalDeviceDataManagerImpl( - pref_service, http_client_factory, profile_info_provider)); + return base::WrapUnique( + new NearbyShareLocalDeviceDataManagerImpl(user, http_client_factory)); } // static @@ -87,11 +85,9 @@ NearbyShareLocalDeviceDataManagerImpl::Factory::~Factory() = default; NearbyShareLocalDeviceDataManagerImpl::NearbyShareLocalDeviceDataManagerImpl( - PrefService* pref_service, - NearbyShareClientFactory* http_client_factory, - NearbyShareProfileInfoProvider* profile_info_provider) - : pref_service_(pref_service), - profile_info_provider_(profile_info_provider), + user_manager::User& user, + NearbyShareClientFactory* http_client_factory) + : user_(user), device_data_updater_(NearbyShareDeviceDataUpdaterImpl::Factory::Create( GetId(), kUpdateDeviceDataTimeout, @@ -102,7 +98,7 @@ /*retry_failures=*/true, /*require_connectivity=*/true, prefs::kNearbySharingSchedulerDownloadDeviceDataPrefName, - pref_service_, + user_->GetProfilePrefs(), base::BindRepeating(&NearbyShareLocalDeviceDataManagerImpl:: OnDownloadDeviceDataRequested, base::Unretained(this)), @@ -112,8 +108,9 @@ ~NearbyShareLocalDeviceDataManagerImpl() = default; std::string NearbyShareLocalDeviceDataManagerImpl::GetId() { + auto* pref_service = user_->GetProfilePrefs(); std::string id = - pref_service_->GetString(prefs::kNearbySharingDeviceIdPrefName); + pref_service->GetString(prefs::kNearbySharingDeviceIdPrefName); if (!id.empty()) return id; @@ -125,45 +122,48 @@ id += kAlphaNumericChars[base::RandGenerator(kAlphaNumericChars.size())]; } - pref_service_->SetString(prefs::kNearbySharingDeviceIdPrefName, id); + pref_service->SetString(prefs::kNearbySharingDeviceIdPrefName, id); return id; } std::string NearbyShareLocalDeviceDataManagerImpl::GetDeviceName() const { - std::string device_name = - pref_service_->GetString(prefs::kNearbySharingDeviceNamePrefName); + std::string device_name = user_->GetProfilePrefs()->GetString( + prefs::kNearbySharingDeviceNamePrefName); return device_name.empty() ? GetDefaultDeviceName() : device_name; } std::optional<std::string> NearbyShareLocalDeviceDataManagerImpl::GetFullName() const { - if (pref_service_->FindPreference(prefs::kNearbySharingFullNamePrefName) + auto* pref_service = user_->GetProfilePrefs(); + if (pref_service->FindPreference(prefs::kNearbySharingFullNamePrefName) ->IsDefaultValue()) { return std::nullopt; } - return pref_service_->GetString(prefs::kNearbySharingFullNamePrefName); + return pref_service->GetString(prefs::kNearbySharingFullNamePrefName); } std::optional<std::string> NearbyShareLocalDeviceDataManagerImpl::GetIconUrl() const { - if (pref_service_->FindPreference(prefs::kNearbySharingIconUrlPrefName) + auto* pref_service = user_->GetProfilePrefs(); + if (pref_service->FindPreference(prefs::kNearbySharingIconUrlPrefName) ->IsDefaultValue()) { return std::nullopt; } - return pref_service_->GetString(prefs::kNearbySharingIconUrlPrefName); + return pref_service->GetString(prefs::kNearbySharingIconUrlPrefName); } std::optional<std::string> NearbyShareLocalDeviceDataManagerImpl::GetIconToken() const { - if (pref_service_->FindPreference(prefs::kNearbySharingIconTokenPrefName) + auto* pref_service = user_->GetProfilePrefs(); + if (pref_service->FindPreference(prefs::kNearbySharingIconTokenPrefName) ->IsDefaultValue()) { return std::nullopt; } - return pref_service_->GetString(prefs::kNearbySharingIconTokenPrefName); + return pref_service->GetString(prefs::kNearbySharingIconTokenPrefName); } nearby_share::mojom::DeviceNameValidationResult @@ -190,7 +190,8 @@ if (error != nearby_share::mojom::DeviceNameValidationResult::kValid) return error; - pref_service_->SetString(prefs::kNearbySharingDeviceNamePrefName, name); + user_->GetProfilePrefs()->SetString(prefs::kNearbySharingDeviceNamePrefName, + name); NotifyLocalDeviceDataChanged(/*did_device_name_change=*/true, /*did_full_name_change=*/false, @@ -237,18 +238,18 @@ std::string NearbyShareLocalDeviceDataManagerImpl::GetDefaultDeviceName() const { std::u16string device_type = ui::GetChromeOSDeviceName(); - std::optional<std::u16string> given_name = - profile_info_provider_->GetGivenName(); - if (!given_name) + std::u16string given_name = user_->GetGivenName(); + if (given_name.empty()) { return base::UTF16ToUTF8(device_type); + } std::string device_name = l10n_util::GetStringFUTF8( - IDS_NEARBY_DEFAULT_DEVICE_NAME, *given_name, device_type); + IDS_NEARBY_DEFAULT_DEVICE_NAME, given_name, device_type); if (device_name.length() <= kNearbyShareDeviceNameMaxLength) return device_name; std::string truncated_name = - GetTruncatedName(base::UTF16ToUTF8(*given_name), + GetTruncatedName(base::UTF16ToUTF8(given_name), device_name.length() - kNearbyShareDeviceNameMaxLength); return l10n_util::GetStringFUTF8(IDS_NEARBY_DEFAULT_DEVICE_NAME, base::UTF8ToUTF16(truncated_name), @@ -302,10 +303,12 @@ if (!response) return; + auto* pref_service = user_->GetProfilePrefs(); + bool did_full_name_change = response->person_name() != GetFullName(); if (did_full_name_change) { - pref_service_->SetString(prefs::kNearbySharingFullNamePrefName, - response->person_name()); + pref_service->SetString(prefs::kNearbySharingFullNamePrefName, + response->person_name()); } // NOTE(http://crbug.com/1211189): An icon URL can change without the @@ -322,12 +325,12 @@ bool did_icon_token_change = response->image_token() != GetIconToken(); bool did_icon_change = did_icon_url_change && did_icon_token_change; if (did_icon_url_change) { - pref_service_->SetString(prefs::kNearbySharingIconUrlPrefName, - response->image_url()); + pref_service->SetString(prefs::kNearbySharingIconUrlPrefName, + response->image_url()); } if (did_icon_token_change) { - pref_service_->SetString(prefs::kNearbySharingIconTokenPrefName, - response->image_token()); + pref_service->SetString(prefs::kNearbySharingIconTokenPrefName, + response->image_token()); } if (!did_full_name_change && !did_icon_change)
diff --git a/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h b/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h index 3e8d6fff..3d350ef 100644 --- a/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h +++ b/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl.h
@@ -11,7 +11,7 @@ #include <vector> #include "base/functional/callback.h" -#include "base/memory/raw_ptr.h" +#include "base/memory/raw_ref.h" #include "chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager.h" #include "chromeos/ash/services/nearby/public/mojom/nearby_share_settings.mojom.h" #include "third_party/nearby/sharing/proto/device_rpc.pb.h" @@ -19,13 +19,15 @@ class NearbyShareClientFactory; class NearbyShareDeviceDataUpdater; -class NearbyShareProfileInfoProvider; -class PrefService; namespace ash::nearby { class NearbyScheduler; } // namespace ash::nearby +namespace user_manager { +class User; +} // namespace user_manager + // Implementation of NearbyShareLocalDeviceDataManager that persists device data // in prefs. All RPC-related calls are guarded by a timeout, so callbacks are // guaranteed to be invoked. In addition to supporting on-demand device-data @@ -37,17 +39,15 @@ class Factory { public: static std::unique_ptr<NearbyShareLocalDeviceDataManager> Create( - PrefService* pref_service, - NearbyShareClientFactory* http_client_factory, - NearbyShareProfileInfoProvider* profile_info_provider); + user_manager::User& user, + NearbyShareClientFactory* http_client_factory); static void SetFactoryForTesting(Factory* test_factory); protected: virtual ~Factory(); virtual std::unique_ptr<NearbyShareLocalDeviceDataManager> CreateInstance( - PrefService* pref_service, - NearbyShareClientFactory* http_client_factory, - NearbyShareProfileInfoProvider* profile_info_provider) = 0; + user_manager::User& user, + NearbyShareClientFactory* http_client_factory) = 0; private: static Factory* test_factory_; @@ -57,9 +57,8 @@ private: NearbyShareLocalDeviceDataManagerImpl( - PrefService* pref_service, - NearbyShareClientFactory* http_client_factory, - NearbyShareProfileInfoProvider* profile_info_provider); + user_manager::User& user, + NearbyShareClientFactory* http_client_factory); // NearbyShareLocalDeviceDataManager: std::string GetId() override; @@ -103,8 +102,7 @@ const std::optional<nearby::sharing::proto::UpdateDeviceResponse>& response); - raw_ptr<PrefService> pref_service_ = nullptr; - raw_ptr<NearbyShareProfileInfoProvider> profile_info_provider_ = nullptr; + const raw_ref<user_manager::User> user_; std::unique_ptr<NearbyShareDeviceDataUpdater> device_data_updater_; std::unique_ptr<ash::nearby::NearbyScheduler> download_device_data_scheduler_; std::string default_device_name_;
diff --git a/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl_unittest.cc b/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl_unittest.cc index ff06472..041e84ee 100644 --- a/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/local_device_data/nearby_share_local_device_data_manager_impl_unittest.cc
@@ -12,7 +12,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" #include "chrome/browser/nearby_sharing/client/fake_nearby_share_client.h" -#include "chrome/browser/nearby_sharing/common/fake_nearby_share_profile_info_provider.h" #include "chrome/browser/nearby_sharing/common/nearby_share_prefs.h" #include "chrome/browser/nearby_sharing/local_device_data/fake_nearby_share_device_data_updater.h" #include "chrome/browser/nearby_sharing/local_device_data/nearby_share_device_data_updater.h" @@ -22,6 +21,9 @@ #include "chromeos/ash/components/nearby/common/scheduling/fake_nearby_scheduler_factory.h" #include "chromeos/ash/components/nearby/common/scheduling/nearby_scheduler_factory.h" #include "components/sync_preferences/testing_pref_service_syncable.h" +#include "components/user_manager/fake_user_manager.h" +#include "components/user_manager/scoped_user_manager.h" +#include "components/user_manager/user.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/abseil-cpp/absl/strings/ascii.h" #include "third_party/nearby/sharing/proto/device_rpc.pb.h" @@ -30,18 +32,20 @@ namespace { -const char kFakeDeviceName[] = "My Cool Chromebook"; -const char kFakeEmptyDeviceName[] = ""; -const char kFakeFullName[] = "Barack Obama"; -const char16_t kFakeGivenName[] = u"Barack"; -const char kFakeIconUrl[] = "https://www.google.com"; -const char kFakeIconUrl2[] = "https://www.google.com/2"; -const char kFakeIconToken[] = "token"; -const char kFakeIconToken2[] = "token2"; -const char kFakeInvalidDeviceName[] = "\xC0"; -const char kFakeTooLongDeviceName[] = "this string is 33 bytes in UTF-8!"; -const char16_t kFakeTooLongGivenName[] = u"this is a 33-byte string in utf-8"; -const char kFakeTooLongTruncatedDeviceName[] = +constexpr char kFakeEmail[] = "test@test"; +constexpr char kFakeDeviceName[] = "My Cool Chromebook"; +constexpr char kFakeEmptyDeviceName[] = ""; +constexpr char kFakeFullName[] = "Barack Obama"; +constexpr char16_t kFakeGivenName[] = u"Barack"; +constexpr char kFakeIconUrl[] = "https://www.google.com"; +constexpr char kFakeIconUrl2[] = "https://www.google.com/2"; +constexpr char kFakeIconToken[] = "token"; +constexpr char kFakeIconToken2[] = "token2"; +constexpr char kFakeInvalidDeviceName[] = "\xC0"; +constexpr char kFakeTooLongDeviceName[] = "this string is 33 bytes in UTF-8!"; +constexpr char16_t kFakeTooLongGivenName[] = + u"this is a 33-byte string in utf-8"; +constexpr char kFakeTooLongTruncatedDeviceName[] = "this is a 33-...'s Chrome device"; nearby::sharing::proto::UpdateDeviceResponse CreateResponse( @@ -106,17 +110,35 @@ ~NearbyShareLocalDeviceDataManagerImplTest() override = default; void SetUp() override { + fake_user_manager_.Reset(std::make_unique<user_manager::FakeUserManager>()); + user_ = fake_user_manager_->AddUser(AccountId::FromUserEmail(kFakeEmail)); + fake_user_manager_->UserLoggedIn( + user_->GetAccountId(), + user_manager::FakeUserManager::GetFakeUsernameHash( + user_->GetAccountId()), + /*browser_restart=*/false, + /*is_child=*/false); RegisterNearbySharingPrefs(pref_service_.registry()); + fake_user_manager_->OnUserProfileCreated(user_->GetAccountId(), + &pref_service_); ash::nearby::NearbySchedulerFactory::SetFactoryForTesting( &scheduler_factory_); NearbyShareDeviceDataUpdaterImpl::Factory::SetFactoryForTesting( &updater_factory_); - profile_info_provider()->set_given_name(kFakeGivenName); + fake_user_manager_->UpdateUserAccountData( + user_->GetAccountId(), user_manager::UserManager::UserAccountData( + /*display_name=*/u"", + /*given_name=*/kFakeGivenName, + /*locale=*/"")); } void TearDown() override { + manager_.reset(); ash::nearby::NearbySchedulerFactory::SetFactoryForTesting(nullptr); NearbyShareDeviceDataUpdaterImpl::Factory::SetFactoryForTesting(nullptr); + fake_user_manager_->OnUserProfileWillBeDestroyed(user_->GetAccountId()); + user_ = nullptr; + fake_user_manager_.Reset(); } // NearbyShareLocalDeviceDataManager::Observer: @@ -129,7 +151,7 @@ void CreateManager() { manager_ = NearbyShareLocalDeviceDataManagerImpl::Factory::Create( - &pref_service_, &http_client_factory_, &profile_info_provider_); + *user_, &http_client_factory_); manager_->AddObserver(this); ++num_manager_creations_; VerifyInitialization(); @@ -218,9 +240,6 @@ } NearbyShareLocalDeviceDataManager* manager() { return manager_.get(); } - FakeNearbyShareProfileInfoProvider* profile_info_provider() { - return &profile_info_provider_; - } const std::vector<ObserverNotification>& notifications() { return notifications_; } @@ -233,6 +252,11 @@ .fake_scheduler; } + user_manager::FakeUserManager& fake_user_manager() { + return *fake_user_manager_; + } + user_manager::User& user() { return *user_; } + private: void VerifyInitialization() { // Verify updater inputs. @@ -254,11 +278,14 @@ EXPECT_EQ(&pref_service_, device_data_scheduler_instance.pref_service); } + user_manager::TypedScopedUserManager<user_manager::FakeUserManager> + fake_user_manager_; + raw_ptr<user_manager::User> user_ = nullptr; + sync_preferences::TestingPrefServiceSyncable pref_service_; + size_t num_manager_creations_ = 0; std::vector<ObserverNotification> notifications_; - sync_preferences::TestingPrefServiceSyncable pref_service_; FakeNearbyShareClientFactory http_client_factory_; - FakeNearbyShareProfileInfoProvider profile_info_provider_; ash::nearby::FakeNearbySchedulerFactory scheduler_factory_; FakeNearbyShareDeviceDataUpdaterFactory updater_factory_; std::unique_ptr<NearbyShareLocalDeviceDataManager> manager_; @@ -283,14 +310,22 @@ TEST_F(NearbyShareLocalDeviceDataManagerImplTest, DefaultDeviceName) { CreateManager(); - // If given name is null, only return the device type. - profile_info_provider()->set_given_name(std::nullopt); + // If given name is empty, only return the device type. + fake_user_manager().UpdateUserAccountData( + user().GetAccountId(), user_manager::UserManager::UserAccountData( + /*display_name=*/u"", + /*given_name=*/u"", + /*locale=*/"")); EXPECT_EQ(base::UTF16ToUTF8(ui::GetChromeOSDeviceName()), manager()->GetDeviceName()); // Set given name and expect full default device name of the form // "<given name>'s <device type>." - profile_info_provider()->set_given_name(kFakeGivenName); + fake_user_manager().UpdateUserAccountData( + user().GetAccountId(), user_manager::UserManager::UserAccountData( + /*display_name=*/u"", + /*given_name=*/kFakeGivenName, + /*locale=*/"")); EXPECT_EQ( l10n_util::GetStringFUTF8(IDS_NEARBY_DEFAULT_DEVICE_NAME, kFakeGivenName, ui::GetChromeOSDeviceName()), @@ -298,7 +333,11 @@ // Make sure that when we use a given name that is very long we truncate // correctly. - profile_info_provider()->set_given_name(kFakeTooLongGivenName); + fake_user_manager().UpdateUserAccountData( + user().GetAccountId(), user_manager::UserManager::UserAccountData( + /*display_name=*/u"", + /*given_name=*/kFakeTooLongGivenName, + /*locale=*/"")); EXPECT_EQ(kFakeTooLongTruncatedDeviceName, manager()->GetDeviceName()); } @@ -318,7 +357,6 @@ TEST_F(NearbyShareLocalDeviceDataManagerImplTest, SetDeviceName) { CreateManager(); - profile_info_provider()->set_given_name(kFakeGivenName); std::string expected_default_device_name = l10n_util::GetStringFUTF8(IDS_NEARBY_DEFAULT_DEVICE_NAME, kFakeGivenName, ui::GetChromeOSDeviceName());
diff --git a/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.cc b/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.cc deleted file mode 100644 index d430f99..0000000 --- a/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.cc +++ /dev/null
@@ -1,33 +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 "chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.h" - -#include "chrome/browser/ash/profiles/profile_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "components/user_manager/user_manager.h" - -NearbyShareProfileInfoProviderImpl::NearbyShareProfileInfoProviderImpl( - Profile* profile) - : profile_(profile) {} - -NearbyShareProfileInfoProviderImpl::~NearbyShareProfileInfoProviderImpl() = - default; - -std::optional<std::u16string> NearbyShareProfileInfoProviderImpl::GetGivenName() - const { - const user_manager::User* user = - ash::ProfileHelper::Get()->GetUserByProfile(profile_); - if (!user) - return std::nullopt; - - std::u16string name = user->GetGivenName(); - return name.empty() ? std::nullopt : std::make_optional(name); -} - -std::optional<std::string> -NearbyShareProfileInfoProviderImpl::GetProfileUserName() const { - std::string name = profile_->GetProfileUserName(); - return name.empty() ? std::nullopt : std::make_optional(name); -}
diff --git a/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.h b/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.h deleted file mode 100644 index 0967053..0000000 --- a/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.h +++ /dev/null
@@ -1,33 +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 CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_PROFILE_INFO_PROVIDER_IMPL_H_ -#define CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_PROFILE_INFO_PROVIDER_IMPL_H_ - -#include "base/memory/raw_ptr.h" -#include "chrome/browser/nearby_sharing/common/nearby_share_profile_info_provider.h" - -class Profile; - -// An implementation of NearbyShareProfileInfoProfider that accesses the actual -// profile data. -class NearbyShareProfileInfoProviderImpl - : public NearbyShareProfileInfoProvider { - public: - explicit NearbyShareProfileInfoProviderImpl(Profile* profile); - NearbyShareProfileInfoProviderImpl( - const NearbyShareProfileInfoProviderImpl&) = delete; - NearbyShareProfileInfoProviderImpl& operator=( - const NearbyShareProfileInfoProviderImpl&) = delete; - ~NearbyShareProfileInfoProviderImpl() override; - - // NearbyShareProfileInfoProvider: - std::optional<std::u16string> GetGivenName() const override; - std::optional<std::string> GetProfileUserName() const override; - - private: - raw_ptr<Profile, DanglingUntriaged> profile_; -}; - -#endif // CHROME_BROWSER_NEARBY_SHARING_NEARBY_SHARE_PROFILE_INFO_PROVIDER_IMPL_H_
diff --git a/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl_unittest.cc deleted file mode 100644 index 0f98bf6e..0000000 --- a/chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl_unittest.cc +++ /dev/null
@@ -1,88 +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 <string> - -#include "chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.h" - -#include "base/memory/raw_ptr.h" -#include "base/strings/utf_string_conversions.h" -#include "chrome/test/base/testing_browser_process.h" -#include "chrome/test/base/testing_profile.h" -#include "chrome/test/base/testing_profile_manager.h" -#include "components/user_manager/fake_user_manager.h" -#include "components/user_manager/scoped_user_manager.h" -#include "components/user_manager/user_manager.h" -#include "content/public/test/browser_task_environment.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -const char16_t kFakeGivenName[] = u"Barack"; -const char kFakeProfileUserName[] = "test@gmail.com"; - -} // namespace - -class NearbyShareProfileInfoProviderImplTest : public ::testing::Test { - protected: - NearbyShareProfileInfoProviderImplTest() - : profile_manager_(TestingBrowserProcess::GetGlobal()), - user_manager_(new user_manager::FakeUserManager()), - enabler_(base::WrapUnique(user_manager_.get())) {} - ~NearbyShareProfileInfoProviderImplTest() override = default; - - void SetUp() override { ASSERT_TRUE(profile_manager_.SetUp()); } - - Profile* CreateProfile(const std::string& profile_user_name) { - account_id_ = AccountId::FromUserEmail(profile_user_name); - return profile_manager_.CreateTestingProfile(profile_user_name); - } - - void AddUser() { user_manager_->AddUser(account_id_); } - - void SetUserGivenName(const std::u16string& name) { - user_manager_->UpdateUserAccountData( - account_id_, user_manager::UserManager::UserAccountData( - /*display_name=*/std::u16string(), - /*given_name=*/name, - /*locale=*/std::string())); - } - - content::BrowserTaskEnvironment task_environment; - TestingProfileManager profile_manager_; - raw_ptr<user_manager::FakeUserManager, DanglingUntriaged> user_manager_ = - nullptr; - user_manager::ScopedUserManager enabler_; - AccountId account_id_; -}; - -TEST_F(NearbyShareProfileInfoProviderImplTest, GivenName) { - Profile* profile = CreateProfile(kFakeProfileUserName); - NearbyShareProfileInfoProviderImpl profile_info_provider(profile); - - // If no user, return std::nullopt. - EXPECT_FALSE(profile_info_provider.GetGivenName()); - - // If given name is empty, return std::nullopt. - AddUser(); - SetUserGivenName(std::u16string()); - EXPECT_FALSE(profile_info_provider.GetGivenName()); - - SetUserGivenName(kFakeGivenName); - EXPECT_EQ(kFakeGivenName, profile_info_provider.GetGivenName()); -} - -TEST_F(NearbyShareProfileInfoProviderImplTest, ProfileUserName) { - { - // If profile user name is empty, return std::nullopt. - Profile* profile = CreateProfile(std::string()); - NearbyShareProfileInfoProviderImpl profile_info_provider(profile); - EXPECT_FALSE(profile_info_provider.GetProfileUserName()); - } - { - Profile* profile = CreateProfile(kFakeProfileUserName); - NearbyShareProfileInfoProviderImpl profile_info_provider(profile); - EXPECT_EQ(kFakeProfileUserName, profile_info_provider.GetProfileUserName()); - } -}
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc index 177ed4b..b27ea29 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_factory.cc
@@ -112,7 +112,7 @@ // GetForBrowserContext() must be called after the initialization of // Profile initialization, because the service depends on its preferences. - const auto* user = + auto* user = ash::BrowserContextHelper::Get()->GetUserByBrowserContext(context); CHECK(user->is_profile_created()); @@ -121,7 +121,6 @@ ash::nearby::NearbyProcessManager* process_manager = ash::nearby::NearbyProcessManagerFactory::GetForProfile(profile); - PrefService* pref_service = profile->GetPrefs(); NotificationDisplayService* notification_display_service = NotificationDisplayServiceFactory::GetForProfile(profile); @@ -133,7 +132,7 @@ << __func__ << ": creating NearbySharingService for primary profile"; return std::make_unique<NearbySharingServiceImpl>( - pref_service, notification_display_service, profile, + *user, profile, notification_display_service, std::move(nearby_connections_manager), process_manager, std::make_unique<PowerClientChromeos>(), std::make_unique<WifiNetworkConfigurationHandler>());
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc index 916e7d6..be8ab94 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.cc
@@ -309,15 +309,15 @@ } // namespace NearbySharingServiceImpl::NearbySharingServiceImpl( - PrefService* prefs, - NotificationDisplayService* notification_display_service, + user_manager::User& user, Profile* profile, + NotificationDisplayService* notification_display_service, std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager, ash::nearby::NearbyProcessManager* process_manager, std::unique_ptr<PowerClient> power_client, std::unique_ptr<WifiNetworkConfigurationHandler> wifi_network_handler) - : prefs_(prefs), - profile_(profile), + : profile_(profile), + prefs_(profile_->GetPrefs()), nearby_connections_manager_(std::move(nearby_connections_manager)), process_manager_(process_manager), power_client_(std::move(power_client)), @@ -326,30 +326,27 @@ IdentityManagerFactory::GetForProfile(profile), profile->GetURLLoaderFactory(), &nearby_share_http_notifier_)), - profile_info_provider_( - std::make_unique<NearbyShareProfileInfoProviderImpl>(profile_)), local_device_data_manager_( NearbyShareLocalDeviceDataManagerImpl::Factory::Create( - prefs, - http_client_factory_.get(), - profile_info_provider_.get())), + user, + http_client_factory_.get())), contact_manager_(NearbyShareContactManagerImpl::Factory::Create( - prefs, + profile_->GetProfileUserName(), + prefs_, http_client_factory_.get(), - local_device_data_manager_.get(), - profile_info_provider_.get())), + local_device_data_manager_.get())), certificate_manager_(NearbyShareCertificateManagerImpl::Factory::Create( + profile_->GetProfileUserName(), + profile->GetPath(), + prefs_, local_device_data_manager_.get(), contact_manager_.get(), - profile_info_provider_.get(), - prefs, profile->GetDefaultStoragePartition()->GetProtoDatabaseProvider(), - profile->GetPath(), http_client_factory_.get())), transfer_profiler_(std::make_unique<NearbyShareTransferProfiler>()), logger_(std::make_unique<NearbyShareLogger>()), - settings_(prefs, local_device_data_manager_.get()), - feature_usage_metrics_(prefs), + settings_(prefs_, local_device_data_manager_.get()), + feature_usage_metrics_(prefs_), on_network_changed_delay_timer_( FROM_HERE, kProcessNetworkChangeTimerDelay, @@ -398,7 +395,7 @@ GetBluetoothAdapter(); nearby_notification_manager_ = std::make_unique<NearbyNotificationManager>( - notification_display_service, this, prefs, profile_); + notification_display_service, this, prefs_, profile_); net::NetworkChangeNotifier::AddNetworkChangeObserver(this);
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h index d5be8886..7a7f9dd 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl.h
@@ -38,7 +38,6 @@ #include "chrome/browser/nearby_sharing/nearby_notification_manager.h" #include "chrome/browser/nearby_sharing/nearby_share_feature_usage_metrics.h" #include "chrome/browser/nearby_sharing/nearby_share_logger.h" -#include "chrome/browser/nearby_sharing/nearby_share_profile_info_provider_impl.h" #include "chrome/browser/nearby_sharing/nearby_share_settings.h" #include "chrome/browser/nearby_sharing/nearby_share_transfer_profiler.h" #include "chrome/browser/nearby_sharing/nearby_sharing_service.h" @@ -74,6 +73,10 @@ class NearbySharingServiceImplTestBase; } +namespace user_manager { +class User; +} // namespace user_manager + // All methods should be called from the same sequence that created the service. class NearbySharingServiceImpl : public NearbySharingService, @@ -91,10 +94,10 @@ // fixed window before deciding not to restart the process. static constexpr int kMaxRecentNearbyProcessUnexpectedShutdownCount = 4; - explicit NearbySharingServiceImpl( - PrefService* prefs, - NotificationDisplayService* notification_display_service, + NearbySharingServiceImpl( + user_manager::User& user, Profile* profile, + NotificationDisplayService* notification_display_service, std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager, ash::nearby::NearbyProcessManager* process_manager, std::unique_ptr<PowerClient> power_client, @@ -448,8 +451,9 @@ void OnVisibilityReminderTimerFired(); base::TimeDelta GetTimeUntilNextVisibilityReminder(); - raw_ptr<PrefService> prefs_ = nullptr; raw_ptr<Profile> profile_; + raw_ptr<PrefService> prefs_ = nullptr; + std::unique_ptr<NearbyConnectionsManager> nearby_connections_manager_; raw_ptr<ash::nearby::NearbyProcessManager> process_manager_; std::unique_ptr<ash::nearby::NearbyProcessManager::NearbyProcessReference> @@ -466,7 +470,6 @@ std::unique_ptr<NearbyNotificationManager> nearby_notification_manager_; NearbyShareHttpNotifier nearby_share_http_notifier_; std::unique_ptr<NearbyShareClientFactory> http_client_factory_; - std::unique_ptr<NearbyShareProfileInfoProvider> profile_info_provider_; std::unique_ptr<NearbyShareLocalDeviceDataManager> local_device_data_manager_; std::unique_ptr<NearbyShareContactManager> contact_manager_; std::unique_ptr<NearbyShareCertificateManager> certificate_manager_;
diff --git a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc index 27d92779..ad6315f 100644 --- a/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc +++ b/chrome/browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc
@@ -66,6 +66,9 @@ #include "chromeos/ash/services/nearby/public/mojom/nearby_share_settings.mojom.h" #include "chromeos/constants/chromeos_features.h" #include "components/sync_preferences/testing_pref_service_syncable.h" +#include "components/user_manager/fake_user_manager.h" +#include "components/user_manager/scoped_user_manager.h" +#include "components/user_manager/user.h" #include "content/public/test/browser_task_environment.h" #include "device/bluetooth/bluetooth_adapter.h" #include "device/bluetooth/bluetooth_adapter_factory.h" @@ -301,7 +304,7 @@ constexpr base::TimeDelta kDelta = base::Milliseconds(100); -const char kProfileName[] = "profile_name"; +const char kProfileName[] = "profile_name@test"; const char kServiceId[] = "NearbySharing"; const char kDeviceName[] = "test_device_name"; const nearby_share::mojom::ShareTargetType kDeviceType = @@ -503,14 +506,17 @@ explicit NearbySharingServiceImplTestBase(size_t feature_mask) : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) { CreateFeatureList(feature_mask); - RegisterNearbySharingPrefs(prefs_.registry()); } ~NearbySharingServiceImplTestBase() override = default; void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); - ASSERT_TRUE(profile_manager_.SetUp()); + + fake_user_manager_.Reset(std::make_unique<user_manager::FakeUserManager>()); + profile_manager_ = std::make_unique<TestingProfileManager>( + TestingBrowserProcess::GetGlobal()); + ASSERT_TRUE(profile_manager_->SetUp()); network_notifier_ = net::test::MockNetworkChangeNotifier::Create(); NearbyShareLocalDeviceDataManagerImpl::Factory::SetFactoryForTesting( @@ -574,36 +580,54 @@ void TearDown() override { if (service_) { service_->Shutdown(); + service_.reset(); } if (profile_) { DownloadCoreServiceFactory::GetForBrowserContext(profile_) ->SetDownloadManagerDelegateForTesting(nullptr); + fake_user_manager_->OnUserProfileWillBeDestroyed( + AccountId::FromUserEmail(kProfileName)); profile_ = nullptr; } - profile_manager_.DeleteAllTestingProfiles(); - + profile_manager_->DeleteAllTestingProfiles(); + profile_manager_.reset(); NearbyShareLocalDeviceDataManagerImpl::Factory::SetFactoryForTesting( nullptr); NearbyShareContactManagerImpl::Factory::SetFactoryForTesting(nullptr); NearbyShareCertificateManagerImpl::Factory::SetFactoryForTesting(nullptr); FastInitiationAdvertiser::Factory::SetFactoryForTesting(nullptr); + + fake_user_manager_.Reset(); } void SetManagedEnabled(bool is_enabled) { - prefs_.SetManagedPref(prefs::kNearbySharingEnabledPrefName, + auto* prefs = profile_->GetTestingPrefService(); + prefs->SetManagedPref(prefs::kNearbySharingEnabledPrefName, std::make_unique<base::Value>(is_enabled)); ASSERT_TRUE( - prefs_.IsManagedPreference(prefs::kNearbySharingEnabledPrefName)); + prefs->IsManagedPreference(prefs::kNearbySharingEnabledPrefName)); } std::unique_ptr<NearbySharingServiceImpl> CreateService() { NearbySharingServiceFactory:: SetIsNearbyShareSupportedForBrowserContextForTesting(true); - profile_ = profile_manager_.CreateTestingProfile(kProfileName); - prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, true); + // Simulate user log-in. + auto* user = + fake_user_manager_->AddUser(AccountId::FromUserEmail(kProfileName)); + fake_user_manager_->UserLoggedIn( + user->GetAccountId(), + user_manager::FakeUserManager::GetFakeUsernameHash( + user->GetAccountId()), + /*browser_restart=*/false, + /*is_child=*/false); + profile_ = profile_manager_->CreateTestingProfile(kProfileName); + profile_->GetPrefs()->SetBoolean(prefs::kNearbySharingEnabledPrefName, + true); + fake_user_manager_->OnUserProfileCreated(user->GetAccountId(), + profile_->GetPrefs()); fake_nearby_connections_manager_ = new FakeNearbyConnectionsManager(); notification_tester_ = @@ -616,7 +640,7 @@ std::make_unique<FakeWifiNetworkConfigurationHandler>(); wifi_network_handler_ = wifi_network_handler.get(); auto service = std::make_unique<NearbySharingServiceImpl>( - &prefs_, notification_display_service, profile_, + *user, profile_, notification_display_service, base::WrapUnique(fake_nearby_connections_manager_.get()), &mock_nearby_process_manager_, std::move(power_client), std::move(wifi_network_handler)); @@ -633,7 +657,8 @@ } void SetVisibility(nearby_share::mojom::Visibility visibility) { - NearbyShareSettings settings(&prefs_, local_device_data_manager()); + NearbyShareSettings settings(profile_->GetPrefs(), + local_device_data_manager()); settings.SetVisibility(visibility); // This ensures that the change propagates through mojo and the observers @@ -642,12 +667,14 @@ } nearby_share::mojom::Visibility GetVisibility() { - NearbyShareSettings settings(&prefs_, local_device_data_manager()); + NearbyShareSettings settings(profile_->GetPrefs(), + local_device_data_manager()); return settings.GetVisibility(); } void SetIsEnabled(bool is_enabled) { - NearbyShareSettings settings(&prefs_, local_device_data_manager()); + NearbyShareSettings settings(profile_->GetPrefs(), + local_device_data_manager()); if (is_enabled) { settings.SetIsOnboardingComplete(is_enabled); } @@ -660,7 +687,8 @@ void SetFastInitiationNotificationState( nearby_share::mojom::FastInitiationNotificationState state) { - NearbyShareSettings settings(&prefs_, local_device_data_manager()); + NearbyShareSettings settings(profile_->GetPrefs(), + local_device_data_manager()); settings.SetFastInitiationNotificationState(state); // This ensures that the change propagates through mojo and the observers @@ -1543,9 +1571,11 @@ // ChromeDownloadManagerDelegate. std::unique_ptr<net::test::MockNetworkChangeNotifier> network_notifier_; content::BrowserTaskEnvironment task_environment_; - TestingProfileManager profile_manager_{TestingBrowserProcess::GetGlobal()}; - raw_ptr<Profile> profile_ = nullptr; - sync_preferences::TestingPrefServiceSyncable prefs_; + user_manager::TypedScopedUserManager<user_manager::FakeUserManager> + fake_user_manager_; + raw_ptr<user_manager::User> user_ = nullptr; + std::unique_ptr<TestingProfileManager> profile_manager_; + raw_ptr<TestingProfile> profile_ = nullptr; raw_ptr<FakeNearbyConnectionsManager, DanglingUntriaged> fake_nearby_connections_manager_ = nullptr; raw_ptr<FakePowerClient, DanglingUntriaged> power_client_ = nullptr; @@ -1725,7 +1755,7 @@ TEST_P(NearbySharingServiceImplTest, DisableNearbyShutdownConnections) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false); + profile_->GetPrefs()->SetBoolean(prefs::kNearbySharingEnabledPrefName, false); service_->FlushMojoForTesting(); EXPECT_TRUE(fake_nearby_connections_manager_->is_shutdown()); } @@ -2166,7 +2196,7 @@ testing::Range<size_t>(0, 1 << kTestFeatures.size()))); TEST_P(NearbySharingServiceImplTest, DisableFeatureSendSurfaceNotDiscovering) { - prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false); + profile_->GetPrefs()->SetBoolean(prefs::kNearbySharingEnabledPrefName, false); service_->FlushMojoForTesting(); SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); MockTransferUpdateCallback transfer_callback; @@ -2190,7 +2220,7 @@ SendSurfaceState::kForeground)); EXPECT_TRUE(fake_nearby_connections_manager_->IsDiscovering()); - prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false); + profile_->GetPrefs()->SetBoolean(prefs::kNearbySharingEnabledPrefName, false); service_->FlushMojoForTesting(); EXPECT_FALSE(fake_nearby_connections_manager_->IsDiscovering()); } @@ -2302,7 +2332,7 @@ BackgroundRegisterReceiveSurfaceIsAdvertisingSelectedContacts) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); SetVisibility(nearby_share::mojom::Visibility::kSelectedContacts); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kSelectedContacts)); MockTransferUpdateCallback callback; @@ -2433,8 +2463,9 @@ DataUsageChangedRegisterReceiveSurfaceRestartsAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger(prefs::kNearbySharingDataUsageName, - static_cast<int>(nearby_share::mojom::DataUsage::kOffline)); + profile_->GetPrefs()->SetInteger( + prefs::kNearbySharingDataUsageName, + static_cast<int>(nearby_share::mojom::DataUsage::kOffline)); service_->FlushMojoForTesting(); MockTransferUpdateCallback callback; NearbySharingService::StatusCodes result = service_->RegisterReceiveSurface( @@ -2444,8 +2475,9 @@ EXPECT_EQ(nearby_share::mojom::DataUsage::kOffline, fake_nearby_connections_manager_->advertising_data_usage()); - prefs_.SetInteger(prefs::kNearbySharingDataUsageName, - static_cast<int>(nearby_share::mojom::DataUsage::kOnline)); + profile_->GetPrefs()->SetInteger( + prefs::kNearbySharingDataUsageName, + static_cast<int>(nearby_share::mojom::DataUsage::kOnline)); service_->FlushMojoForTesting(); EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising()); EXPECT_EQ(nearby_share::mojom::DataUsage::kOnline, @@ -2456,7 +2488,7 @@ NearbySharingServiceImplTest, UnregisterForegroundReceiveSurfaceVisibilityAllContactsRestartAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kAllContacts)); service_->FlushMojoForTesting(); @@ -2606,7 +2638,7 @@ TEST_P(NearbySharingServiceImplTest, DisableFeatureReceiveSurfaceNotAdvertising) { - prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false); + profile_->GetPrefs()->SetBoolean(prefs::kNearbySharingEnabledPrefName, false); service_->FlushMojoForTesting(); SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); MockTransferUpdateCallback callback; @@ -2626,7 +2658,7 @@ EXPECT_EQ(result, NearbySharingService::StatusCodes::kOk); EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising()); - prefs_.SetBoolean(prefs::kNearbySharingEnabledPrefName, false); + profile_->GetPrefs()->SetBoolean(prefs::kNearbySharingEnabledPrefName, false); service_->FlushMojoForTesting(); EXPECT_FALSE(fake_nearby_connections_manager_->IsAdvertising()); EXPECT_TRUE(fake_nearby_connections_manager_->is_shutdown()); @@ -2635,8 +2667,9 @@ TEST_P(NearbySharingServiceImplTest, ForegroundReceiveSurfaceNoOneVisibilityIsAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName, - static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); + profile_->GetPrefs()->SetInteger( + prefs::kNearbySharingBackgroundVisibilityName, + static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); MockTransferUpdateCallback callback; NearbySharingService::StatusCodes result = service_->RegisterReceiveSurface( &callback, NearbySharingService::ReceiveSurfaceState::kForeground); @@ -2647,8 +2680,9 @@ TEST_P(NearbySharingServiceImplTest, BackgroundReceiveSurfaceNoOneVisibilityNotAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName, - static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); + profile_->GetPrefs()->SetInteger( + prefs::kNearbySharingBackgroundVisibilityName, + static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); service_->FlushMojoForTesting(); MockTransferUpdateCallback callback; NearbySharingService::StatusCodes result = service_->RegisterReceiveSurface( @@ -2661,7 +2695,7 @@ TEST_P(NearbySharingServiceImplTest, BackgroundReceiveSurfaceVisibilityToNoOneStopsAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kSelectedContacts)); service_->FlushMojoForTesting(); @@ -2671,8 +2705,9 @@ EXPECT_EQ(result, NearbySharingService::StatusCodes::kOk); EXPECT_TRUE(fake_nearby_connections_manager_->IsAdvertising()); - prefs_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName, - static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); + profile_->GetPrefs()->SetInteger( + prefs::kNearbySharingBackgroundVisibilityName, + static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); service_->FlushMojoForTesting(); EXPECT_FALSE(fake_nearby_connections_manager_->IsAdvertising()); EXPECT_FALSE(fake_nearby_connections_manager_->is_shutdown()); @@ -2681,8 +2716,9 @@ TEST_P(NearbySharingServiceImplTest, BackgroundReceiveSurfaceVisibilityToSelectedStartsAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger(prefs::kNearbySharingBackgroundVisibilityName, - static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); + profile_->GetPrefs()->SetInteger( + prefs::kNearbySharingBackgroundVisibilityName, + static_cast<int>(nearby_share::mojom::Visibility::kNoOne)); service_->FlushMojoForTesting(); MockTransferUpdateCallback callback; NearbySharingService::StatusCodes result = service_->RegisterReceiveSurface( @@ -2691,7 +2727,7 @@ EXPECT_FALSE(fake_nearby_connections_manager_->IsAdvertising()); EXPECT_FALSE(fake_nearby_connections_manager_->is_shutdown()); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kSelectedContacts)); service_->FlushMojoForTesting(); @@ -2701,7 +2737,7 @@ TEST_P(NearbySharingServiceImplTest, ForegroundReceiveSurfaceSelectedContactsVisibilityIsAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kSelectedContacts)); MockTransferUpdateCallback callback; @@ -2714,7 +2750,7 @@ TEST_P(NearbySharingServiceImplTest, BackgroundReceiveSurfaceSelectedContactsVisibilityIsAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kSelectedContacts)); MockTransferUpdateCallback callback; @@ -2727,7 +2763,7 @@ TEST_P(NearbySharingServiceImplTest, ForegroundReceiveSurfaceAllContactsVisibilityIsAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kAllContacts)); MockTransferUpdateCallback callback; @@ -2740,7 +2776,7 @@ TEST_P(NearbySharingServiceImplTest, BackgroundReceiveSurfaceAllContactsVisibilityNotAdvertising) { SetConnectionType(net::NetworkChangeNotifier::CONNECTION_WIFI); - prefs_.SetInteger( + profile_->GetPrefs()->SetInteger( prefs::kNearbySharingBackgroundVisibilityName, static_cast<int>(nearby_share::mojom::Visibility::kAllContacts)); MockTransferUpdateCallback callback;
diff --git a/chrome/browser/notifications/platform_notification_service_impl.cc b/chrome/browser/notifications/platform_notification_service_impl.cc index df1fb679..2329aa0f 100644 --- a/chrome/browser/notifications/platform_notification_service_impl.cc +++ b/chrome/browser/notifications/platform_notification_service_impl.cc
@@ -84,6 +84,11 @@ namespace { +constexpr char + kNotificationContentDetectionDisplayPersistentNotificationEventHistogram[] = + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent"; + #if BUILDFLAG(IS_CHROMEOS_ASH) constexpr char kNotificationResourceActionIconMemorySizeHistogram[] = @@ -161,6 +166,18 @@ size_t total_deleted_count_; }; +// The type of event when displaying a persistent notification. These values +// are persisted to logs. Entries should not be renumbered and numeric values +// should never be reused. +enum class DisplayPersistentNotificationEvents { + // The event logged when requesting to display a persistent notification. + kRequested = 0, + // The event logged when model checking and displaying the persistent + // notification have completed. + kFinished = 1, + kMaxValue = kFinished, +}; + } // namespace // static @@ -305,6 +322,9 @@ // and the method should return without calling `Display`. Otherwise, the // notification should be displayed below. if (is_show_warnings_for_suspicious_notifications_enabled) { + base::UmaHistogramEnumeration( + kNotificationContentDetectionDisplayPersistentNotificationEventHistogram, + DisplayPersistentNotificationEvents::kRequested); LogPersistentNotificationShownMetrics(notification_data, origin, notification.origin_url()); return; @@ -728,6 +748,9 @@ const message_center::Notification& notification, std::unique_ptr<PersistentNotificationMetadata> metadata, bool is_suspicious) { + base::UmaHistogramEnumeration( + kNotificationContentDetectionDisplayPersistentNotificationEventHistogram, + DisplayPersistentNotificationEvents::kFinished); metadata->is_suspicious = is_suspicious; NotificationDisplayServiceFactory::GetForProfile(profile_)->Display( NotificationHandler::Type::WEB_PERSISTENT, notification,
diff --git a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java index 330ddaf..6f7924e 100644 --- a/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java +++ b/chrome/browser/optimization_guide/android/java/src/org/chromium/chrome/browser/optimization_guide/OptimizationGuidePushNotificationManagerUnitTest.java
@@ -25,7 +25,7 @@ import org.mockito.junit.MockitoJUnit; import org.mockito.junit.MockitoRule; -import org.chromium.base.FeatureList; +import org.chromium.base.FeatureOverrides; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Batch; @@ -199,10 +199,7 @@ // Flag state cannot change within the same process instance, so this behavior does not // actually get triggered in real usage. - FeatureList.TestValues testValues = new FeatureList.TestValues(); - testValues.addFeatureFlagOverride( - ChromeFeatureList.OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS, false); - FeatureList.mergeTestValues(testValues, /* replace= */ true); + FeatureOverrides.disable(ChromeFeatureList.OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS); // Push another notification to trigger the clear. OptimizationGuidePushNotificationManager.onPushNotification(NOTIFICATION_WITH_PAYLOAD);
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 index 1569ba3..802f232 100644 --- 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
@@ -34,7 +34,6 @@ import org.mockito.MockitoAnnotations; import org.robolectric.annotation.Config; -import org.chromium.base.FeatureList; import org.chromium.base.FeatureOverrides; import org.chromium.base.supplier.Supplier; import org.chromium.base.test.BaseRobolectricTestRunner; @@ -141,7 +140,7 @@ @Test public void testOnFinishNativeInitializationEnabled_beforeNativeInit() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); mPartnerCustomizationsUma.onFinishNativeInitializationOrEnabled( mActivityLifecycleDispatcherMock, () -> mDidCall = true); NativeInitObserver observer = captureObserverFromLifecycleMock(); @@ -159,7 +158,7 @@ @Test public void testOnFinishNativeInitializationEnabled_beforeNativeInitDisabled() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); mPartnerCustomizationsUma.onFinishNativeInitializationOrEnabled( mActivityLifecycleDispatcherMock, () -> mDidCall = true); NativeInitObserver observer = captureObserverFromLifecycleMock(); @@ -519,7 +518,7 @@ @Test public void testCreateNtpIncorrectlyBeforeCustomization() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(NTP_INCORRECTLY, NOT_CACHED, SOME_DELEGATE); expectInitializationCompleted( @@ -544,7 +543,7 @@ @Test public void testCreateNtpCorrectlyBeforeCustomization() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(NTP_CORRECTLY, NOT_CACHED, SOME_DELEGATE); expectInitializationCompleted( @@ -569,7 +568,7 @@ @Test public void testCreateNtpUnknownBeforeCustomization() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(NTP_UNKNOWN, NOT_CACHED, SOME_DELEGATE); expectInitializationCompleted(builder, NOT_CACHED, SOME_DELEGATE, CANCELLED, UNUSED_TIME); @@ -592,7 +591,7 @@ @Test public void testCreatePartnerHomepageBeforeCustomization() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(PARTNER_CUSTOM_HOMEPAGE, NOT_CACHED, SOME_DELEGATE); expectInitializationCompleted( @@ -617,7 +616,7 @@ @Test public void testCreateOtherHomepageBeforeCustomization() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(OTHER_CUSTOM_HOMEPAGE, false, SOME_DELEGATE); expectInitializationCompleted( @@ -650,7 +649,7 @@ @Test public void testCreateNtpCorrectlyCached() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(NTP_CORRECTLY, CACHED, SOME_DELEGATE); expectInitializationCompleted( @@ -675,7 +674,7 @@ @Test public void testCreatePartnerHomepageCached() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(PARTNER_CUSTOM_HOMEPAGE, CACHED, SOME_DELEGATE); expectInitializationCompleted( @@ -700,7 +699,7 @@ @Test public void testCreateNtpCorrectlyAfterCustomization() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(NTP_CORRECTLY, NOT_CACHED, SOME_DELEGATE); expectInitializationCompleted( @@ -722,7 +721,7 @@ @Test public void testCreatePartnerHomepageAfterCustomization() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(PARTNER_CUSTOM_HOMEPAGE, NOT_CACHED, SOME_DELEGATE); expectInitializationCompleted( @@ -748,7 +747,7 @@ @Test public void testCreateInitialTabCalledBeforeCustomizationStarts() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder beforeStartedBuilder = HistogramWatcher.newBuilder() .expectNoRecords( @@ -785,7 +784,7 @@ @Test public void testCreateInitialTabCalledMultipleTimes() { // Unset test values so that FeatureList#isInitialized returns false. - FeatureList.removeAllTestOverrides(); + FeatureOverrides.removeAllIncludingAnnotations(); HistogramWatcher.Builder builder = expectCustomizationOutcome(PARTNER_CUSTOM_HOMEPAGE, NOT_CACHED, SOME_DELEGATE); expectInitializationCompleted(
diff --git a/chrome/browser/performance_manager/mechanisms/page_discarder.cc b/chrome/browser/performance_manager/mechanisms/page_discarder.cc index e993685e..bf949c6 100644 --- a/chrome/browser/performance_manager/mechanisms/page_discarder.cc +++ b/chrome/browser/performance_manager/mechanisms/page_discarder.cc
@@ -9,10 +9,13 @@ #include "base/functional/bind.h" #include "base/memory/weak_ptr.h" +#include "base/metrics/histogram_functions.h" +#include "base/not_fatal_until.h" #include "base/task/task_traits.h" #include "build/build_config.h" #include "chrome/browser/performance_manager/public/user_tuning/user_tuning_utils.h" #include "chrome/browser/resource_coordinator/tab_lifecycle_unit.h" +#include "chrome/browser/resource_coordinator/tab_lifecycle_unit_external.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" @@ -21,6 +24,7 @@ #include "content/public/browser/browser_thread.h" #include "content/public/browser/render_process_host.h" #include "content/public/browser/web_contents.h" +#include "third_party/abseil-cpp/absl/cleanup/cleanup.h" namespace performance_manager { namespace mechanism { @@ -31,6 +35,17 @@ using WebContentsAndPmf = std::pair<base::WeakPtr<content::WebContents>, uint64_t>; +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. +// LINT.IfChange(DiscardPageOnUIThreadOutcome) +enum class DiscardPageOnUIThreadOutcome { + kSuccess = 0, + kNoContents = 1, + kDiscardTabFailure = 2, + kMaxValue = kDiscardTabFailure +}; +// LINT.ThenChange(/tools/metrics/histograms/metadata/tab/enums.xml:DiscardPageOnUIThreadOutcome) + // Discards pages on the UI thread. Returns true if at least 1 page is // discarded. // TODO(crbug.com/40194498): Returns the remaining reclaim target so @@ -48,17 +63,37 @@ for (const auto& [contents, memory_footprint_estimate] : web_contents_and_pmf) { - if (!contents) + // On scope exit, `outcome` is reported to the histogram + // "Discarding.DiscardPageOnUIThreadOutcome". + std::optional<DiscardPageOnUIThreadOutcome> outcome; + absl::Cleanup record_discard_outcome = [&]() { + CHECK(outcome.has_value(), base::NotFatalUntil::M136); + if (outcome.has_value()) { + base::UmaHistogramEnumeration("Discarding.DiscardPageOnUIThreadOutcome", + outcome.value()); + } + }; + + if (!contents) { + outcome = DiscardPageOnUIThreadOutcome::kNoContents; continue; + } auto* lifecycle_unit = resource_coordinator::TabLifecycleUnitSource:: GetTabLifecycleUnitExternal(contents.get()); - if (!lifecycle_unit) + // This function is only called with `PageNode`s of type `kTab`, so there + // should be a LifecycleUnit. + CHECK(lifecycle_unit, base::NotFatalUntil::M136); + if (!lifecycle_unit) { continue; + } if (lifecycle_unit->DiscardTab(discard_reason, memory_footprint_estimate)) { + outcome = DiscardPageOnUIThreadOutcome::kSuccess; discard_events.emplace_back(base::TimeTicks::Now(), memory_footprint_estimate); + } else { + outcome = DiscardPageOnUIThreadOutcome::kDiscardTabFailure; } } return discard_events;
diff --git a/chrome/browser/policy/restricted_mgs_policy_provider_ash_browsertest.cc b/chrome/browser/policy/restricted_mgs_policy_provider_ash_browsertest.cc index 1ccd39d..5ffa231 100644 --- a/chrome/browser/policy/restricted_mgs_policy_provider_ash_browsertest.cc +++ b/chrome/browser/policy/restricted_mgs_policy_provider_ash_browsertest.cc
@@ -154,8 +154,9 @@ ash::EmbeddedPolicyTestServerMixin policy_test_server_mixin_{&mixin_host_}; }; +// TODO(crbug.com/387568360): Re-enable flaky test. IN_PROC_BROWSER_TEST_F(RestrictedMGSPolicyProviderAshBrowserTest, - DeviceRestrictedManagedGuestSessionDisabled) { + DISABLED_DeviceRestrictedManagedGuestSessionDisabled) { SetUpPolicy(/*restricted=*/false); ash::SessionStateWaiter(session_manager::SessionState::ACTIVE).Wait(); @@ -165,8 +166,9 @@ EXPECT_TRUE(expected_policy_map_.Equals(current_policy_map)); } +// TODO(crbug.com/387568360): Re-enable flaky test. IN_PROC_BROWSER_TEST_F(RestrictedMGSPolicyProviderAshBrowserTest, - DeviceRestrictedManagedGuestSessionEnabled) { + DISABLED_DeviceRestrictedManagedGuestSessionEnabled) { SetUpPolicy(/*restricted=*/true); ash::SessionStateWaiter(session_manager::SessionState::ACTIVE).Wait();
diff --git a/chrome/browser/policy/webhid_device_policy_handler_unittest.cc b/chrome/browser/policy/webhid_device_policy_handler_unittest.cc index 630b89c..ed7811ea 100644 --- a/chrome/browser/policy/webhid_device_policy_handler_unittest.cc +++ b/chrome/browser/policy/webhid_device_policy_handler_unittest.cc
@@ -333,6 +333,7 @@ const char* pref_name; const char* policy; const char16_t* expected_errors; + const char16_t* expected_warnings; const char* expected_pref; }; @@ -357,6 +358,9 @@ EXPECT_EQ(success, test_data.expected_pref != nullptr); EXPECT_EQ(test_data.expected_errors, errors.GetErrorMessages(test_data.policy_name)); + EXPECT_EQ(test_data.expected_warnings, + errors.GetErrorMessages(test_data.policy_name, + policy::PolicyMap::MessageType::kWarning)); EXPECT_FALSE(store_->GetValue(test_data.pref_name, /*result=*/nullptr)); @@ -386,6 +390,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesForUrls[0]: Schema validation error: " u"Missing or invalid required property: devices", "[]", @@ -403,6 +408,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesForUrls[0]: Schema validation error: " u"Missing or invalid required property: urls", "[]", @@ -424,6 +430,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesForUrls[0].devices[0]: Schema validation " u"error: Unknown property: serial_number", R"( @@ -456,6 +463,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesForUrls[0].devices[0].vendor_id: Schema " u"validation error: Invalid value for integer", R"( @@ -485,6 +493,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesForUrls[0].devices[0].product_id: Schema " u"validation error: Invalid value for integer", R"( @@ -513,6 +522,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesForUrls[0].devices[0]: Schema validation " u"error: Missing or invalid required property: vendor_id", R"( @@ -542,6 +552,7 @@ } ])", u"Error at WebHidAllowDevicesForUrls[0].urls[0]: Invalid URL.", + u"", R"( [ { @@ -573,6 +584,7 @@ } ])", u"Error at WebHidAllowDevicesForUrls[0].urls[0]: Invalid URL.", + u"", R"( [ { @@ -606,6 +618,7 @@ ])", u"Error at WebHidAllowDevicesForUrls[0].urls[0]: Invalid URL.\n" u"Error at WebHidAllowDevicesForUrls[0].urls[1]: Invalid URL.", + u"", R"( [ { @@ -637,10 +650,10 @@ ] } ])", + u"Error at WebHidAllowDevicesForUrls[0].urls[0]: Invalid URL.", u"Error at WebHidAllowDevicesForUrls[0].urls[0]: Schema validation " u"error: Policy type mismatch: expected: \"string\", actual: " - u"\"integer\".\nError at WebHidAllowDevicesForUrls[0].urls[0]: Invalid " - u"URL.", + u"\"integer\".", R"( [ { @@ -660,6 +673,7 @@ R"( [123] )", + u"", u"Error at WebHidAllowDevicesForUrls[0]: Schema validation error: " u"Policy type mismatch: expected: \"dictionary\", actual: \"integer\".", R"( @@ -677,6 +691,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0]: Schema " u"validation error: Missing or invalid required property: usages", "[]", @@ -694,6 +709,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0]: Schema " u"validation " u"error: Missing or invalid required property: urls", @@ -716,6 +732,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].usages[0]: " u"Schema " u"validation error: Unknown property: serial_number", @@ -749,6 +766,7 @@ ] } ])", + u"", u"Error at " u"WebHidAllowDevicesWithHidUsagesForUrls[0].usages[0].usage_page: " u"Schema validation error: Invalid value for integer", @@ -779,6 +797,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].usages[0].usage: " u"Schema validation error: Invalid value for integer", R"( @@ -807,6 +826,7 @@ ] } ])", + u"", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].usages[0]: Schema " u"validation error: Missing or invalid required property: usage_page", R"( @@ -837,6 +857,7 @@ ])", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].urls[0]: Invalid " u"URL.", + u"", R"( [ { @@ -869,6 +890,7 @@ ])", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].urls[0]: Invalid " u"URL.", + u"", R"( [ { @@ -904,6 +926,7 @@ u"URL.\n" u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].urls[1]: Invalid " u"URL.", + u"", R"( [ { @@ -935,10 +958,11 @@ ] } ])", + u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].urls[0]: Invalid " + u"URL.", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0].urls[0]: Schema " u"validation error: Policy type mismatch: expected: \"string\", " - u"actual: \"integer\".\nError at " - u"WebHidAllowDevicesWithHidUsagesForUrls[0].urls[0]: Invalid URL.", + u"actual: \"integer\".", R"( [ { @@ -958,6 +982,7 @@ R"( [123] )", + u"", u"Error at WebHidAllowDevicesWithHidUsagesForUrls[0]: Schema " u"validation error: Policy type mismatch: expected: \"dictionary\", " u"actual: \"integer\".",
diff --git a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc index 79f9984..bbc756d 100644 --- a/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc +++ b/chrome/browser/policy/webusb_allow_devices_for_urls_policy_handler_unittest.cc
@@ -362,7 +362,8 @@ u"Error at WebUsbAllowDevicesForUrls[0].devices[0]: Schema validation " u"error: Unknown property: serialNumber"; EXPECT_EQ(kExpected, - errors.GetErrorMessages(key::kWebUsbAllowDevicesForUrls)); + errors.GetErrorMessages(key::kWebUsbAllowDevicesForUrls, + PolicyMap::MessageType::kWarning)); } TEST_F(WebUsbAllowDevicesForUrlsPolicyHandlerTest, @@ -831,7 +832,8 @@ u"Error at WebUsbAllowDevicesForUrls[0]: Schema validation error: " u"Unknown property: unknown_top_level_property"; EXPECT_EQ(kExpected, - errors.GetErrorMessages(key::kWebUsbAllowDevicesForUrls)); + errors.GetErrorMessages(key::kWebUsbAllowDevicesForUrls, + PolicyMap::MessageType::kWarning)); EXPECT_FALSE( store_->GetValue(prefs::kManagedWebUsbAllowDevicesForUrls, nullptr));
diff --git a/chrome/browser/resources/ash/settings/lazy_load.ts b/chrome/browser/resources/ash/settings/lazy_load.ts index 7101f35..2596fae9 100644 --- a/chrome/browser/resources/ash/settings/lazy_load.ts +++ b/chrome/browser/resources/ash/settings/lazy_load.ts
@@ -45,6 +45,9 @@ import './os_apps_page/app_management_page/main_view.js'; import './os_apps_page/app_parental_controls/app_parental_controls_subpage.js'; import './os_apps_page/app_parental_controls/block_app_item.js'; +import './os_bluetooth_page/os_bluetooth_device_detail_subpage.js'; +import './os_bluetooth_page/os_bluetooth_devices_subpage.js'; +import './os_bluetooth_page/os_bluetooth_saved_devices_subpage.js'; import './os_search_page/google_assistant_subpage.js'; import './os_search_page/search_subpage.js'; import './os_people_page/fingerprint_list_subpage.js'; @@ -93,11 +96,6 @@ import './os_apps_page/app_management_page/plugin_vm_page/plugin_vm_detail_view.js'; import './os_apps_page/app_management_page/pwa_detail_view.js'; import './os_apps_page/app_management_page/sub_apps_item.js'; -import './os_bluetooth_page/os_bluetooth_change_device_name_dialog.js'; -import './os_bluetooth_page/os_bluetooth_device_detail_subpage.js'; -import './os_bluetooth_page/os_bluetooth_devices_subpage.js'; -import './os_bluetooth_page/os_paired_bluetooth_list.js'; -import './os_bluetooth_page/os_paired_bluetooth_list_item.js'; import './os_files_page/google_drive_subpage.js'; import './os_files_page/google_drive_confirmation_dialog.js'; import './os_files_page/google_drive_subpage.js';
diff --git a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_device_detail_subpage.ts b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_device_detail_subpage.ts index eb2ea54f..170d67ec 100644 --- a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_device_detail_subpage.ts +++ b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_bluetooth_device_detail_subpage.ts
@@ -9,11 +9,12 @@ */ import '../settings_shared.css.js'; +import 'chrome://resources/ash/common/bluetooth/bluetooth_device_battery_info.js'; import 'chrome://resources/ash/common/bluetooth/bluetooth_icon.js'; import 'chrome://resources/ash/common/cr_elements/policy/cr_tooltip_icon.js'; import './os_bluetooth_change_device_name_dialog.js'; +import './os_bluetooth_forget_device_dialog.js'; import './os_bluetooth_true_wireless_images.js'; -import 'chrome://resources/ash/common/bluetooth/bluetooth_device_battery_info.js'; import {BluetoothUiSurface, recordBluetoothUiSurfaceMetrics} from 'chrome://resources/ash/common/bluetooth/bluetooth_metrics_utils.js'; import {BatteryType} from 'chrome://resources/ash/common/bluetooth/bluetooth_types.js';
diff --git a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_saved_devices_list_item.ts b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_saved_devices_list_item.ts index a2739cf..dc37467e 100644 --- a/chrome/browser/resources/ash/settings/os_bluetooth_page/os_saved_devices_list_item.ts +++ b/chrome/browser/resources/ash/settings/os_bluetooth_page/os_saved_devices_list_item.ts
@@ -12,6 +12,7 @@ import '../os_settings_icons.html.js'; import 'chrome://resources/ash/common/cr_elements/cr_icon_button/cr_icon_button.js'; import 'chrome://resources/ash/common/cr_elements/cr_action_menu/cr_action_menu.js'; +import './os_remove_saved_device_dialog.js'; import {FastPairSavedDevicesUiEvent, recordSavedDevicesUiEventMetrics} from 'chrome://resources/ash/common/bluetooth/bluetooth_metrics_utils.js'; import type {CrActionMenuElement} from 'chrome://resources/ash/common/cr_elements/cr_action_menu/cr_action_menu.js';
diff --git a/chrome/browser/resources/ash/settings/os_settings.ts b/chrome/browser/resources/ash/settings/os_settings.ts index 98b4224..f6263f60 100644 --- a/chrome/browser/resources/ash/settings/os_settings.ts +++ b/chrome/browser/resources/ash/settings/os_settings.ts
@@ -60,16 +60,6 @@ import './os_apps_page/app_management_page/app_management_cros_shared_vars.css.js'; import './os_apps_page/app_notifications_page/mojo_interface_provider.js'; import './os_apps_page/os_apps_page.js'; -import './os_bluetooth_page/os_bluetooth_saved_devices_subpage.js'; -import './os_bluetooth_page/os_remove_saved_device_dialog.js'; -import './os_bluetooth_page/os_bluetooth_forget_device_dialog.js'; -import './os_bluetooth_page/os_bluetooth_true_wireless_images.js'; -import './os_bluetooth_page/os_bluetooth_pairing_dialog.js'; -import './os_bluetooth_page/os_bluetooth_page.js'; -import './os_bluetooth_page/os_bluetooth_summary.js'; -import './os_bluetooth_page/os_saved_devices_list.js'; -import './os_bluetooth_page/os_saved_devices_list_item.js'; -import './os_bluetooth_page/settings_fast_pair_constants.js'; import {ColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js';
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn index 322fa42..04b24d53 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/BUILD.gn
@@ -55,6 +55,7 @@ "background/braille/expanding_braille_translator.ts", "background/braille/liblouis.ts", "background/braille/pan_strategy.ts", + "background/braille/spans.ts", "background/chromevox.ts", "background/chromevox_range.ts", "background/chromevox_state.ts", @@ -162,7 +163,6 @@ "background/automation_object_constructor_installer.js", "background/braille/braille_input_handler.js", "background/braille/braille_translator_manager.js", - "background/braille/spans.js", "background/composite_tts.js", "background/editing/typing_echo.js", "background/event/desktop_automation_handler.js",
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/spans.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/spans.ts similarity index 72% rename from chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/spans.js rename to chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/spans.ts index aa7790e..a4344c60 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/spans.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/spans.ts
@@ -8,40 +8,37 @@ */ import {TestImportManager} from '/common/testing/test_import_manager.js'; -import {Spannable} from '../../common/spannable.js'; +import {SerializedAnnotation, Spannable} from '../../common/spannable.js'; import {LibLouis} from './liblouis.js'; /** Attached to the value region of a braille spannable. */ export class ValueSpan { - /** @param {number} offset The offset of the span into the value. */ - constructor(offset) { - /** - * The offset of the span into the value. - * @type {number} - */ + /** The offset of the span into the value. */ + offset: number; + + constructor(offset: number) { this.offset = offset; } /** * Creates a value span from a json serializable object. - * @param {!Object} obj The json serializable object to convert. - * @return {!ValueSpan} The value span. + * @param obj The json serializable object to convert. + * @return The value span. */ - static fromJson(obj) { + static fromJson(obj: SerializedAnnotation): ValueSpan { return new ValueSpan(obj.offset); } /** * Converts this object to a json serializable object. - * @return {!Object} The JSON representation. + * @return The JSON representation. */ - toJson() { + toJson(): SerializedAnnotation { return this; } } - Spannable.registerSerializableSpan( ValueSpan, 'ValueSpan', ValueSpan.fromJson, ValueSpan.prototype.toJson); @@ -60,8 +57,9 @@ * class. */ export class ExtraCellsSpan { + cells: ArrayBuffer; + constructor() { - /** @type {ArrayBuffer} */ this.cells = new Uint8Array(0).buffer; } } @@ -69,9 +67,9 @@ /** Indicates a text form during translation in Liblouis. */ export class BrailleTextStyleSpan { - /** @param {LibLouis.FormType} formType */ - constructor(formType) { - /** @type {LibLouis.FormType} */ + formType: LibLouis.FormType; + + constructor(formType: LibLouis.FormType) { this.formType = formType; } }
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/spannable.ts b/chrome/browser/resources/chromeos/accessibility/chromevox/common/spannable.ts index 016f7ac..7ced77e 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/spannable.ts +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/spannable.ts
@@ -7,7 +7,8 @@ */ import {TestImportManager} from '/common/testing/test_import_manager.js'; -type Annotation = any; +export type Annotation = any; +export type SerializedAnnotation = any; /** The serialized format of a spannable. */ export interface SerializedSpannable { @@ -360,8 +361,8 @@ */ static registerSerializableSpan( constructor: Function, name: string, - fromJson: (json: SerializedSpan) => Annotation, - toJson: () => SerializedSpan): void { + fromJson: (json: SerializedAnnotation) => Annotation, + toJson: () => SerializedAnnotation): void { const obj: SerializeInfo = {name, fromJson, toJson}; serializableSpansByName.set(name, obj); serializableSpansByConstructor.set(constructor, obj); @@ -429,14 +430,14 @@ /** Describes how to convert a span type to/from serializable json. */ interface SerializeInfo { name: string; - fromJson: (json: SerializedSpan) => Annotation; - toJson?: () => SerializedSpan; + fromJson: (json: SerializedAnnotation) => Annotation; + toJson?: () => SerializedAnnotation; } /** The format of a single annotation in a serialized spannable. */ interface SerializedSpan { type: string; - value: Annotation; + value: SerializedAnnotation; start: number; end: number; }
diff --git a/chrome/browser/resources/commerce/product_specifications/app.ts b/chrome/browser/resources/commerce/product_specifications/app.ts index 13d6679c..373f6ed9 100644 --- a/chrome/browser/resources/commerce/product_specifications/app.ts +++ b/chrome/browser/resources/commerce/product_specifications/app.ts
@@ -259,6 +259,7 @@ private callbackRouter_: PageCallbackRouter; private eventTracker_: EventTracker = new EventTracker(); private id_: Uuid|null = null; + private isWindowFocused_: boolean = true; private listenerIds_: number[] = []; private minLoadingAnimationMs_: number = 500; private pendingSetUpdate_: (() => void)|null = null; @@ -293,6 +294,8 @@ // TODO: b/358131415 - use listeners to update. Temporary workaround uses // window focus to update the feature state, to check signin. window.addEventListener('focus', async () => { + this.isWindowFocused_ = true; + const previousState = this.productSpecificationsFeatureState_; const {state} = await this.shoppingApi_.getProductSpecificationsFeatureState(); @@ -315,6 +318,10 @@ this.productSpecificationsFeatureState_ = state; }); + window.addEventListener('blur', () => { + this.isWindowFocused_ = false; + }); + this.eventTracker_.add( this, 'click', () => { @@ -352,6 +359,10 @@ this.minLoadingAnimationMs_ = 0; } + focusWindowForTesting() { + this.isWindowFocused_ = true; + } + private async loadTable_(state: ProductSpecificationsFeatureState) { // Don't load the table if access conditions are not met. if (!(state.isSyncingTabCompare && state.canLoadFullPageUi && @@ -782,6 +793,18 @@ } private async onSetUpdated_(set: ProductSpecificationsSet) { + // If the page does not have focus, schedule the update for later in case a + // newer update is received before the tab is focused. This prevents all + // updates from triggering at the same time, which may cause a flicker. + if (!this.isWindowFocused_) { + this.pendingSetUpdate_ = this.updateSet_.bind(this, set); + return; + } + + this.updateSet_(set); + } + + private async updateSet_(set: ProductSpecificationsSet) { if (this.showEmptyState_) { const tableIndex = this.comparisonTableDetails_.findIndex( table => table.uuid.value === set.uuid.value); @@ -791,18 +814,6 @@ } } - // If the page does not have focus, schedule the update for later in case a - // newer update is received before the tab is focused. This prevents all - // updates from triggering at the same time, which may cause a flicker. - if (!document.hasFocus()) { - this.pendingSetUpdate_ = this.updateSet_.bind(this, set); - return; - } - - this.updateSet_(set); - } - - private updateSet_(set: ProductSpecificationsSet) { if (set.uuid.value !== this.id_?.value) { return; }
diff --git a/chrome/browser/resources/commerce/product_specifications/description_citation.css b/chrome/browser/resources/commerce/product_specifications/description_citation.css index 0a80005..c1f050fb 100644 --- a/chrome/browser/resources/commerce/product_specifications/description_citation.css +++ b/chrome/browser/resources/commerce/product_specifications/description_citation.css
@@ -24,4 +24,54 @@ cr-tooltip { --paper-tooltip-duration-in: 0ms; --paper-tooltip-duration-out: 0ms; + --paper-tooltip-background: transparent; + --paper-tooltip-opacity: 1; + pointer-events: none; +} + +.citation { + background-color: var(--color-product-specifications-citation-popup-background); + box-shadow: var(--cr-card-shadow); + border-radius: var(--cr-card-border-radius); + line-height: 16px; + padding: 8px; + max-width: 220px; + min-width: 220px; + white-space: normal; +} + +.faviconContainer { + width: 16px; + height: 16px; + display: block; + padding-inline-end: 4px; +} + +.faviconContainer img { + height: 100%; + object-fit: contain; +} + +.header { + display: flex; + align-items: center; +} + +.url { + font-size: 12px; + font-weight: 500; + color: var(--color-product-specifications-citation-popup-title); +} + +.title { + font-size: 12px; + font-weight: 500; + color: var(--color-product-specifications-citation-popup-text); + margin-top: 8px; +} + +.previewText { + font-size: 11px; + color: var(--color-product-specifications-citation-popup-text); + margin-top: 8px; }
diff --git a/chrome/browser/resources/commerce/product_specifications/description_citation.html.ts b/chrome/browser/resources/commerce/product_specifications/description_citation.html.ts index 76763f1..c8795d7 100644 --- a/chrome/browser/resources/commerce/product_specifications/description_citation.html.ts +++ b/chrome/browser/resources/commerce/product_specifications/description_citation.html.ts
@@ -9,14 +9,27 @@ import {getAbbreviatedUrl} from './utils.js'; export function getHtml(this: DescriptionCitationElement) { + // clang-format off return html` <cr-button id="citation" class="tonal-button" @click="${this.openCitation_}" aria-label="${this.getAriaLabel_()}"> ${this.index} </cr-button><cr-tooltip id="tooltip" for="citation" - position="${TooltipPosition.TOP}" offset="8" animation-delay="0" + position="${TooltipPosition.TOP}" offset="0" animation-delay="0" fit-to-visible-bounds> - <span>${getAbbreviatedUrl(this.url)}</span> + <div class="citation"> + <div class="header"> + ${this.urlInfo.faviconUrl.url ? html` + <div class="faviconContainer"> + <img is="cr-auto-img" auto-src="${this.urlInfo.faviconUrl.url}"> + </div>` : ''} + <div class="url">${getAbbreviatedUrl(this.urlInfo.url.url)}</div> + </div> + <div class="title">${this.urlInfo.title}</div> + ${this.urlInfo.previewText ? html` + <div class="previewText">${this.urlInfo.previewText}</div>` : ''} + </div> </cr-tooltip>`; + // clang-format on }
diff --git a/chrome/browser/resources/commerce/product_specifications/description_citation.ts b/chrome/browser/resources/commerce/product_specifications/description_citation.ts index 48c213bd7..bcf74e66 100644 --- a/chrome/browser/resources/commerce/product_specifications/description_citation.ts +++ b/chrome/browser/resources/commerce/product_specifications/description_citation.ts
@@ -6,6 +6,7 @@ import 'chrome://resources/cr_elements/cr_button/cr_button.js'; import 'chrome://resources/cr_elements/cr_tooltip/cr_tooltip.js'; +import type {UrlInfo} from 'chrome://resources/cr_components/commerce/shopping_service.mojom-webui.js'; import type {CrTooltipElement} from 'chrome://resources/cr_elements/cr_tooltip/cr_tooltip.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js'; @@ -37,28 +38,29 @@ static override get properties() { return { - url: {type: String}, + urlInfo: {type: Object}, index: {type: Number}, citationCount: {type: Number}, productName: {type: String}, }; } - url: string = ''; + urlInfo: UrlInfo; index: number = 0; citationCount: number = 0; productName: string = ''; protected openCitation_() { this.$.tooltip.hide(); - OpenWindowProxyImpl.getInstance().openUrl(this.url); + OpenWindowProxyImpl.getInstance().openUrl(this.urlInfo.url.url); chrome.metricsPrivate.recordUserAction('Commerce.Compare.CitationClicked'); } protected getAriaLabel_(): string { return loadTimeData.getStringF( 'citationA11yLabel', this.index, this.citationCount, this.productName, - getAbbreviatedUrl(this.url)); + getAbbreviatedUrl(this.urlInfo?.url.url), this.urlInfo.title || '', + this.urlInfo.previewText || ''); } }
diff --git a/chrome/browser/resources/commerce/product_specifications/description_section.html.ts b/chrome/browser/resources/commerce/product_specifications/description_section.html.ts index 2f4d41d..d8b85ab 100644 --- a/chrome/browser/resources/commerce/product_specifications/description_section.html.ts +++ b/chrome/browser/resources/commerce/product_specifications/description_section.html.ts
@@ -24,7 +24,7 @@ ${this.description.summary.map((summaryItem, summaryIndex) => html` <span class="summary-text">${summaryItem.text}</span> ${summaryItem.urls.map((urlInfo, urlIndex) => html` - <description-citation url="${urlInfo.url.url}" + <description-citation .urlInfo=${urlInfo} index="${this.computeCitationIndex_(summaryIndex, urlIndex)}" citation-count="${this.citationCount}" product-name="${this.productName}">
diff --git a/chrome/browser/resources/glic/glic_api/glic_api.ts b/chrome/browser/resources/glic/glic_api/glic_api.ts index e562406..2cbe8f7 100644 --- a/chrome/browser/resources/glic/glic_api/glic_api.ts +++ b/chrome/browser/resources/glic/glic_api/glic_api.ts
@@ -131,6 +131,14 @@ // Returns the user profile information. getUserProfileInfo?(): Promise<UserProfileInfo>; + + // Update Google sign-in cookies for this client. Resolves after the cookies + // are successfully updated. Rejects if sign-in cookies cannot be updated. + // This should only be called if the web client detects that it is not + // signed-in, as Chrome will attempt to refresh cookies automatically in some + // circumstances. If this is called while a cookie refresh is already in + // progress, only one cookie refresh will take place. + refreshSignInCookies?(): Promise<void>; } // A panel can be in one of these three states.
diff --git a/chrome/browser/resources/glic/glic_api/glic_api_client.ts b/chrome/browser/resources/glic/glic_api/glic_api_client.ts index 1610eef..52fe949 100644 --- a/chrome/browser/resources/glic/glic_api/glic_api_client.ts +++ b/chrome/browser/resources/glic/glic_api/glic_api_client.ts
@@ -227,6 +227,14 @@ avatarIconImage && rgbaImageToBlob(avatarIconImage), }; } + + async refreshSignInCookies(): Promise<void> { + const result = await this.sender.requestWithResponse( + 'glicBrowserRefreshSignInCookies', {}); + if (!result.success) { + throw Error('refreshSignInCookies failed'); + } + } } // Returns a promise which resolves to the `GlicHostRegistry`. This promise
diff --git a/chrome/browser/resources/glic/glic_api/request_types.ts b/chrome/browser/resources/glic/glic_api/request_types.ts index 6c59586..7bedb31 100644 --- a/chrome/browser/resources/glic/glic_api/request_types.ts +++ b/chrome/browser/resources/glic/glic_api/request_types.ts
@@ -113,6 +113,12 @@ profileInfo?: UserProfileInfoPrivate, }, }; + glicBrowserRefreshSignInCookies: { + request: {}, + response: { + success: boolean, + }, + }; } // Types of requests to the GlicWebClient.
diff --git a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts index c4764bc..1ba56df 100644 --- a/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts +++ b/chrome/browser/resources/glic/glic_api_impl/glic_api_host.ts
@@ -252,6 +252,10 @@ } return {profileInfo}; } + + glicBrowserRefreshSignInCookies(): Promise<{success: boolean}> { + return this.handler.syncCookies(); + } } export class GlicApiHost implements PostMessageRequestHandler {
diff --git a/chrome/browser/resources/glic/main.ts b/chrome/browser/resources/glic/main.ts index 3b4dceb6..fdb8ec2 100644 --- a/chrome/browser/resources/glic/main.ts +++ b/chrome/browser/resources/glic/main.ts
@@ -62,4 +62,6 @@ } } -new GlicAppHostManager(); +// Blocking on cookie syncing here introduces latency, we should consider ways +// to avoid it. +browserProxy.handler.syncWebviewCookies().then(() => new GlicAppHostManager());
diff --git a/chrome/browser/resources/omnibox/BUILD.gn b/chrome/browser/resources/omnibox/BUILD.gn index 3333d83..9106786a 100644 --- a/chrome/browser/resources/omnibox/BUILD.gn +++ b/chrome/browser/resources/omnibox/BUILD.gn
@@ -7,10 +7,6 @@ build_webui("build") { grd_prefix = "omnibox" - # TODO(crbug.com/339686362): Remove this once `terser` (JS minifier) has been - # updated to support the new `with` syntax. - optimize = false - web_component_files = [ "ml/ml_calculator.ts", "ml/ml_chart.ts",
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html index cc616b2b..72a1b4f6 100644 --- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_dialog_notice_step.html
@@ -12,6 +12,12 @@ .banner { height: 140px; } + + .learn-more-title { + color: initial; + font-size: inherit; + font-weight: 500; + } </style> <div id="notice" hidden$="[[hideNoticePage_]]"> @@ -60,9 +66,9 @@ <div class="banner"> <img class="fledge-banner" alt=""> </div> - <div class="section cr-secondary-text"> + <h2 class="section learn-more-title"> $i18n{m1NoticeEEASiteSuggestedAdsTitle} - </div> + </h2> <div class="section cr-secondary-text"> $i18n{m1NoticeEEASiteSuggestedAdsDescription} </div> @@ -85,9 +91,9 @@ <li>$i18nRaw{m1NoticeEEASiteSuggestedAdsLearnMoreBullet2}</li> </ul> </privacy-sandbox-dialog-learn-more> - <div class="section cr-secondary-text"> + <h2 class="section learn-more-title"> $i18n{m1NoticeEEAAdMeasurementTitle} - </div> + </h2> <div class="section cr-secondary-text"> $i18n{m1NoticeEEAAdMeasurementDescription} </div>
diff --git a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_privacy_policy_dialog.css b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_privacy_policy_dialog.css index 781400f5..ac7f4a1 100644 --- a/chrome/browser/resources/privacy_sandbox/privacy_sandbox_privacy_policy_dialog.css +++ b/chrome/browser/resources/privacy_sandbox/privacy_sandbox_privacy_policy_dialog.css
@@ -20,6 +20,7 @@ position: absolute; z-index: -1; opacity: 0; + visibility: hidden; } :host([should-show]) iframe {
diff --git a/chrome/browser/resources/settings/people_page/people_page.ts b/chrome/browser/resources/settings/people_page/people_page.ts index cf2cf5e..f49caf5 100644 --- a/chrome/browser/resources/settings/people_page/people_page.ts +++ b/chrome/browser/resources/settings/people_page/people_page.ts
@@ -296,6 +296,9 @@ } private getSyncAndGoogleServicesSubtext_(): string { + if (loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled')) { + return ''; + } if (this.syncStatus && this.syncStatus.hasError && this.syncStatus.statusText) { return this.syncStatus.statusText;
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.html b/chrome/browser/resources/settings/people_page/sync_account_control.html index 2725bdba..31705ae2 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.html +++ b/chrome/browser/resources/settings/people_page/sync_account_control.html
@@ -166,7 +166,7 @@ syncStatus.statusAction, syncStatus.disabled)]] </div> <div class="secondary text-elide" - hidden="[[shouldShowSubtitleWithAccountInfoText_()]]"> + hidden="[[shouldHideSubtitleWithAccountInfoText_()]]"> [[getAccountLabel_( '$i18nPolymer{signedInTo}', '$i18nPolymer{syncingTo}', @@ -176,8 +176,9 @@ shownAccount_.isPrimaryAccount)]] </div> <div class="secondary" - hidden="[[!shouldShowSubtitleWithAccountInfoText_()]]"> - $i18nPolymer{accountAwareRowSubtitle} + hidden="[[!shouldHideSubtitleWithAccountInfoText_()]]"> + [[getAvatarSubtitleLabel_( + '$i18nPolymer{accountAwareRowSubtitle}')]] </div> </div> <cr-icon-button class="icon-arrow-dropdown cr-button-gap"
diff --git a/chrome/browser/resources/settings/people_page/sync_account_control.ts b/chrome/browser/resources/settings/people_page/sync_account_control.ts index e6a4b05f..bcc9463 100644 --- a/chrome/browser/resources/settings/people_page/sync_account_control.ts +++ b/chrome/browser/resources/settings/people_page/sync_account_control.ts
@@ -260,9 +260,40 @@ // not. This matters because showing account specific information needs to be // trimmed using ellipsis for potentially long texts, whereas fixed // information needs to be fully displayed regardless of the length. - private shouldShowSubtitleWithAccountInfoText_() { - return loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled') && - this.syncStatus.signedInState === SignedInState.WEB_ONLY_SIGNED_IN; + private shouldHideSubtitleWithAccountInfoText_() { + if (!loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled')) { + return false; + } + + if (this.syncStatus && + this.syncStatus.signedInState === SignedInState.SIGNED_IN_PAUSED && + this.syncStatus.hasError && this.syncStatus.statusText) { + return true; + } + + if (this.syncStatus.signedInState === SignedInState.WEB_ONLY_SIGNED_IN) { + return true; + } + + return false; + } + + + private getAvatarSubtitleLabel_(accountAwareRowSubtitle: string): string { + if (!loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled')) { + return ''; + } + + if (this.syncStatus.signedInState === SignedInState.WEB_ONLY_SIGNED_IN) { + return accountAwareRowSubtitle; + } + + if (this.syncStatus && + this.syncStatus.signedInState === SignedInState.SIGNED_IN_PAUSED && + this.syncStatus.hasError && this.syncStatus.statusText) { + return this.syncStatus.statusText; + } + return ''; } private getAccountAwareSigninButtonLabel_( @@ -334,9 +365,14 @@ accountName: string, syncErrorLabel: string, syncPasswordsOnlyErrorLabel: string, authErrorLabel: string, disabledLabel: string, webOnlySignedInAccountRowTitle: string): string { - if (loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled') && - this.syncStatus.signedInState === SignedInState.WEB_ONLY_SIGNED_IN) { - return webOnlySignedInAccountRowTitle; + if (loadTimeData.getBoolean('isImprovedSettingsUIOnDesktopEnabled')) { + if (this.syncStatus.signedInState === SignedInState.WEB_ONLY_SIGNED_IN) { + return webOnlySignedInAccountRowTitle; + } + if (this.syncStatus.signedInState === SignedInState.SIGNED_IN_PAUSED && + this.syncStatus.hasError) { + return accountName; + } } if (this.syncStatus.disabled) { @@ -397,6 +433,11 @@ return this.hideBanner || !!this.syncStatus && this.isSyncing_(); } + if (this.syncStatus && this.syncStatus.hasError && + this.syncStatus.statusText) { + return true; + } + switch (this.syncStatus.signedInState) { case SignedInState.SYNCING: case SignedInState.SIGNED_IN:
diff --git a/chrome/browser/resources/side_panel/bookmarks/BUILD.gn b/chrome/browser/resources/side_panel/bookmarks/BUILD.gn index da5c583..90addfaf 100644 --- a/chrome/browser/resources/side_panel/bookmarks/BUILD.gn +++ b/chrome/browser/resources/side_panel/bookmarks/BUILD.gn
@@ -31,6 +31,7 @@ "power_bookmarks_drag_manager.ts", "power_bookmarks_service.ts", "power_bookmarks_utils.ts", + "keyboard_arrow_navigation_service.ts", ] css_files = [ "power_bookmark_row.css" ]
diff --git a/chrome/browser/resources/side_panel/bookmarks/keyboard_arrow_navigation_service.ts b/chrome/browser/resources/side_panel/bookmarks/keyboard_arrow_navigation_service.ts new file mode 100644 index 0000000..d366b2b --- /dev/null +++ b/chrome/browser/resources/side_panel/bookmarks/keyboard_arrow_navigation_service.ts
@@ -0,0 +1,192 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +/** + * Navigates focus through nested elements given a HTMLElement parent + * node with child nodes with specific element types such as `div` or custom + * elements like `power-bookmark-row` + * + * This service can focus elements across shadow doms. + */ +export class KeyArrowNavigationService { + /** + * List of focusable HTMLElement nodes representing focusable elements in a + * flat format sorted by tab order. + */ + private elements_: HTMLElement[] = []; + private rootElement_!: HTMLElement; + private focusIndex_: number = 0; + private childrenQuerySelector_: string = ''; + + constructor(rootElement: HTMLElement, querySelector: string) { + this.rootElement_ = rootElement; + this.childrenQuerySelector_ = querySelector; + } + + private boundKeyArrowListener_ = this.handleKeyArrowEvent_.bind(this); + + /** + * Creates listeners for the root element. + * Invoke during setup. + */ + startListening() { + this.rootElement_.addEventListener('keydown', this.boundKeyArrowListener_); + } + + /** + * Cleans up any listeners created by the startListening method. + * Invoke during teardown. + */ + stopListening() { + this.rootElement_.removeEventListener( + 'keydown', this.boundKeyArrowListener_); + } + + /** + * Inserts elements to the `elements_` list next to the current `focusIndex_` + * position. + * + * @param parentElement parent node from which nested elements will be added + */ + addElementsWithin(parentElement: HTMLElement) { + const childElements = this.traverseElements_(parentElement); + + const newElements = [...this.elements_]; + const targetIndex = this.findElementIndex_(parentElement); + + // adding child elements to the right of the parent element + newElements.splice(targetIndex + 1, 0, ...childElements); + + this.elements_ = newElements; + } + + /** + * Collapses nested elements from a given HTMLElement node by traversing the + * given element to verify if any child elements have nested children and + * account for these when removing elements from the main elements list. + * + * @param parentElement parent node from which nested elements will be removed + */ + removeElementsWithin(parentElement: HTMLElement) { + const updatedElements = [...this.elements_]; + const numElementsToRemove = this.traverseElements_(parentElement).length; + const targetIndex = this.findElementIndex_(parentElement); + + updatedElements.splice(targetIndex + 1, numElementsToRemove); + this.elements_ = updatedElements; + } + + /** + * Used to manually focus on a specific element when the keyboard focus is + * currently on an element, and a click event focuses on a different element + * therefore having to move the `focusIndex` to the element being clicked. + * + * Returns false if no element was found. + * + * @param element Target element to focus on + */ + setCurrentFocusIndex(element: HTMLElement): boolean { + const newCurrentIndex = this.findElementIndex_(element); + + if (newCurrentIndex < 0) { + return false; + } + + this.focusIndex_ = newCurrentIndex; + return true; + } + + /** + * Rebuilds the navigation structure from an optional given element, if not + * it will default to the existing root node. + * + * @param rootElement + */ + rebuildNavigationElements(rootElement?: HTMLElement) { + this.elements_ = this.traverseElements_(rootElement || this.rootElement_); + } + + /** + * Returns the current focused element, may be used for testing. + * + * @returns the current focused element + */ + getElementAtFocusIndexForTesting(): HTMLElement { + return this.elements_[this.focusIndex_]; + } + + /** + * Returns the focusable elements list, may be used for testing. + * + * @returns HTML element list + */ + getElementsForTesting(): HTMLElement[] { + return [...this.elements_]; + } + + private handleKeyArrowEvent_(event: KeyboardEvent) { + const {key} = event; + + if (!(key === 'ArrowUp' || key === 'ArrowDown')) { + return; + } + + event.preventDefault(); + event.stopPropagation(); + + if (key === 'ArrowUp') { + this.moveFocus_(-1); + } + if (key === 'ArrowDown') { + this.moveFocus_(1); + } + } + + private moveFocus_(direction: -1|1) { + if (this.focusIndex_ + direction > this.elements_.length - 1) { + this.focusIndex_ = 0; + this.focusCurrentIndex_(); + return; + } + if (this.focusIndex_ + direction < 0) { + this.focusIndex_ = this.elements_.length - 1; + this.focusCurrentIndex_(); + return; + } + + this.focusIndex_ += direction; + this.focusCurrentIndex_(); + } + + private focusCurrentIndex_() { + this.elements_[this.focusIndex_].focus(); + } + + private findElementIndex_(element: HTMLElement): number { + return this.elements_.findIndex((elem) => elem === element); + } + + private traverseElements_(node: HTMLElement): HTMLElement[] { + const children = Array.from(node.shadowRoot!.querySelectorAll<HTMLElement>( + this.childrenQuerySelector_)); + let treeElements: HTMLElement[] = []; + + for (const childNode of children) { + const hasChildren = childNode.shadowRoot && + Array.from(childNode.shadowRoot.querySelectorAll<HTMLElement>( + this.childrenQuerySelector_)) + .length > 0; + + treeElements = hasChildren ? + [ + ...treeElements, + childNode, + ...this.traverseElements_(childNode as HTMLElement), + ] : + [...treeElements, childNode]; + } + + return treeElements; + } +}
diff --git a/chrome/browser/resources/side_panel/reading_list/reading_list_app.css b/chrome/browser/resources/side_panel/reading_list/reading_list_app.css index 35e57c0..43cc28cf 100644 --- a/chrome/browser/resources/side_panel/reading_list/reading_list_app.css +++ b/chrome/browser/resources/side_panel/reading_list/reading_list_app.css
@@ -11,12 +11,25 @@ * #include=mwb-element-shared-style-lit cr-hidden-style-lit sp-shared-style-lit * #css_wrapper_metadata_end */ +:host { + --sp-footer-height: 56px; +} + #content { display: flex; flex-direction: column; height: 100vh; } +cr-icon-button { + cursor: pointer; +} + +cr-lazy-list { + flex: 1; + scrollbar-gutter: stable; +} + /* Transition required to ensure focus highlight after button press. * See crbug/1358900. */ @@ -30,6 +43,17 @@ padding-block-start: var(--sp-body-padding); } -sp-heading { - margin: 8px 16px; +.sp-card { + display: flex; + height: calc(100% - var(--sp-footer-height) - 4 * var(--sp-body-padding)); + margin: var(--sp-body-padding); +} + +.sp-card sp-heading { + margin: 6px 0; + width: auto; +} + +sp-footer { + height: var(--sp-footer-height); }
diff --git a/chrome/browser/resources/side_panel/reading_list/reading_list_app.html.ts b/chrome/browser/resources/side_panel/reading_list/reading_list_app.html.ts index 456f47e..7346457 100644 --- a/chrome/browser/resources/side_panel/reading_list/reading_list_app.html.ts +++ b/chrome/browser/resources/side_panel/reading_list/reading_list_app.html.ts
@@ -4,6 +4,7 @@ import {html} from '//resources/lit/v3_0/lit.rollup.js'; +import type {ReadLaterEntry} from './reading_list.mojom-webui.js'; import type {ReadingListAppElement} from './reading_list_app.js'; export function getHtml(this: ReadingListAppElement) { @@ -16,35 +17,35 @@ heading="$i18n{emptyStateHeader}" body="${this.getEmptyStateSubheaderText_()}"> </sp-empty-state> - <div id="readingListList" class="sp-scroller sp-scroller-top-of-page" - @keydown="${this.onItemKeyDown_}" - ?hidden="${!this.shouldShowList_()}"> - <div class="sp-card" ?hidden="${!this.unreadItems_.length}"> + + <div class="sp-card" ?hidden="${!this.getAllItems_().length}"> + <cr-lazy-list id="readingListList" .items="${this.getAllItems_()}" + .itemSize="${this.itemSize_}" + .scrollTarget="${this.scrollTarget_}" + ?hidden="${!this.shouldShowList_()}" + @keydown="${this.onItemKeyDown_}" + @viewport-filled="${this.updateFocusedItem_}" + .restoreFocusElement="${this.focusedItem_}" + .template="${ + (item: ReadLaterEntry, index: number) => !item.url.url ? html` <sp-heading compact hide-back-button> - <h2 slot="heading">$i18n{unreadHeader}</h2> + <h2 slot="heading">${item.title}</h2> + <cr-icon-button slot="buttons" + data-title="${item.title}" + iron-icon="${this.getExpandButtonIcon_(item.title)}" + @click="${this.onExpandButtonClick_}"> + </cr-icon-button> </sp-heading> - ${this.unreadItems_.map((item, index) => html` - <reading-list-item data-url="${item.url.url}" data-index="${index}" - @focus="${this.onItemFocus_}" - aria-label="${this.ariaLabel_(item)}" class="unread-item" - .data="${item}" ?button-ripples="${this.buttonRipples}"> - </reading-list-item> - `)} - </div> - <div class="sp-cards-separator" ?hidden="${!this.shouldShowHr_()}"></div> - <div class="sp-card" ?hidden="${!this.readItems_.length}"> - <sp-heading compact hide-back-button> - <h2 slot="heading">$i18n{readHeader}</h2> - </sp-heading> - ${this.readItems_.map((item, index) => html` - <reading-list-item data-url="${item.url.url}" data-index="${index}" - @focus="${this.onItemFocus_}" - aria-label="${this.ariaLabel_(item)}" - .data="${item}" ?button-ripples="${this.buttonRipples}"> - </reading-list-item> - `)} - </div> + ` : + html` + <reading-list-item data-url="${item.url.url}" data-index="${index}" + @focus="${this.onItemFocus_}" + aria-label="${this.ariaLabel_(item)}" class="unread-item" + .data="${item}" ?button-ripples="${this.buttonRipples}"> + </reading-list-item>`}"> + </cr-lazy-list> </div> + <sp-footer ?pinned="${!this.isReadingListEmpty_()}"> <cr-button id="currentPageActionButton" class="floating-button" aria-label="${this.getCurrentPageActionButtonText_()}"
diff --git a/chrome/browser/resources/side_panel/reading_list/reading_list_app.ts b/chrome/browser/resources/side_panel/reading_list/reading_list_app.ts index dc581102..7d633de 100644 --- a/chrome/browser/resources/side_panel/reading_list/reading_list_app.ts +++ b/chrome/browser/resources/side_panel/reading_list/reading_list_app.ts
@@ -7,16 +7,19 @@ import 'chrome://read-later.top-chrome/shared/sp_heading.js'; import 'chrome://resources/cr_elements/cr_button/cr_button.js'; import 'chrome://resources/cr_elements/cr_icon/cr_icon.js'; +import 'chrome://resources/cr_elements/cr_icon_button/cr_icon_button.js'; +import 'chrome://resources/cr_elements/cr_lazy_list/cr_lazy_list.js'; import 'chrome://resources/cr_elements/icons.html.js'; import './reading_list_item.js'; import '/strings.m.js'; -import {ColorChangeUpdater} from '//resources/cr_components/color_change_listener/colors_css_updater.js'; +import {ColorChangeUpdater} from 'chrome://resources/cr_components/color_change_listener/colors_css_updater.js'; import {HelpBubbleMixinLit} from 'chrome://resources/cr_components/help_bubble/help_bubble_mixin_lit.js'; -import {CrSelectableMixin} from 'chrome://resources/cr_elements/cr_selectable_mixin.js'; +import type {CrLazyListElement} from 'chrome://resources/cr_elements/cr_lazy_list/cr_lazy_list.js'; import {assertNotReached} from 'chrome://resources/js/assert.js'; import {EventTracker} from 'chrome://resources/js/event_tracker.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; +import type {PropertyValues} from 'chrome://resources/lit/v3_0/lit.rollup.js'; import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js'; import type {ReadLaterEntriesByStatus, ReadLaterEntry} from './reading_list.mojom-webui.js'; @@ -25,17 +28,15 @@ import {ReadingListApiProxyImpl} from './reading_list_api_proxy.js'; import {getCss} from './reading_list_app.css.js'; import {getHtml} from './reading_list_app.html.js'; -import type {ReadingListItemElement} from './reading_list_item.js'; import {MARKED_AS_READ_UI_EVENT} from './reading_list_item.js'; const navigationKeys: Set<string> = new Set(['ArrowDown', 'ArrowUp']); -const ReadingListAppElementBase = - HelpBubbleMixinLit(CrSelectableMixin(CrLitElement)); +const ReadingListAppElementBase = HelpBubbleMixinLit(CrLitElement); export interface ReadingListAppElement { $: { - readingListList: HTMLElement, + readingListList: CrLazyListElement, }; } @@ -61,18 +62,34 @@ return { unreadItems_: {type: Array}, readItems_: {type: Array}, + focusedIndex_: {type: Number}, + focusedItem_: {type: Object}, currentPageActionButtonState_: {type: Number}, buttonRipples: {type: Boolean}, loadingContent_: {type: Boolean}, + itemSize_: {type: Number}, + scrollTarget_: {type: Object}, + unreadHeader_: {type: String}, + readHeader_: {type: String}, + unreadExpanded_: {type: Boolean}, + readExpanded_: {type: Boolean}, }; } protected unreadItems_: ReadLaterEntry[] = []; protected readItems_: ReadLaterEntry[] = []; + protected focusedIndex_: number = -1; + protected focusedItem_: HTMLElement|null = null; private currentPageActionButtonState_: CurrentPageActionButtonState = CurrentPageActionButtonState.kDisabled; buttonRipples: boolean = loadTimeData.getBoolean('useRipples'); protected loadingContent_: boolean = true; + protected itemSize_: number = 48; + protected scrollTarget_: HTMLElement|null = null; + private unreadHeader_: string = loadTimeData.getString('unreadHeader'); + private readHeader_: string = loadTimeData.getString('readHeader'); + private unreadExpanded_: boolean = true; + private readExpanded_: boolean = false; private apiProxy_: ReadingListApiProxy = ReadingListApiProxyImpl.getInstance(); private listenerIds_: number[] = []; @@ -83,9 +100,6 @@ super(); ColorChangeUpdater.forDocument().start(); - /** Property for CrSelectableMixin */ - this.attrForSelected = 'data-url'; - this.visibilityChangedListener_ = () => { // Refresh Reading List's list data when transitioning into a visible // state. @@ -110,6 +124,7 @@ (state: CurrentPageActionButtonState) => this.updateCurrentPageActionButton_(state))); + this.scrollTarget_ = this.$.readingListList; this.updateReadLaterEntries_(); this.apiProxy_.updateCurrentPageActionButtonState(); @@ -133,6 +148,23 @@ this.shadowRoot!, MARKED_AS_READ_UI_EVENT); } + override willUpdate(changedProperties: PropertyValues<this>) { + super.willUpdate(changedProperties); + + const changedPrivateProperties = + changedProperties as Map<PropertyKey, unknown>; + + if (changedPrivateProperties.has('unreadItems_') || + changedPrivateProperties.has('readItems_')) { + const listLength = this.getAllItems_().length; + if (this.focusedIndex_ >= listLength) { + this.focusedIndex_ = listLength - 1; + } else if (this.focusedIndex_ === -1 && listLength > 0) { + this.focusedIndex_ = 1; + } + } + } + override firstUpdated() { this.registerHelpBubble( ADD_CURRENT_TAB_ELEMENT_ID, '#currentPageActionButton'); @@ -144,20 +176,84 @@ } } - // Override `observeItems` from CrSelectableMixin. - override observeItems() { - // Turn off default observation logic in CrSelectableMixin. + override updated(changedProperties: PropertyValues<this>) { + super.updated(changedProperties); + + const changedPrivateProperties = + changedProperties as Map<PropertyKey, unknown>; + + if (changedPrivateProperties.has('focusedIndex_')) { + this.updateFocusedItem_(); + } } - // Override `queryItems` from CrSelectableMixin. - override queryItems() { - return Array.from(this.shadowRoot!.querySelectorAll('reading-list-item')); + getFocusedIndexForTesting() { + return this.focusedIndex_; } - // Override `queryMatchingItem` from CrSelectableMixin. - override queryMatchingItem(selector: string) { - return this.shadowRoot!.querySelector<HTMLElement>( - `reading-list-item${selector}`); + setExpandedForTesting() { + this.readExpanded_ = true; + this.unreadExpanded_ = true; + } + + protected updateFocusedItem_() { + this.focusedItem_ = this.focusedIndex_ === -1 ? + null : + this.querySelector<HTMLElement>( + `cr-lazy-list > *:nth-child(${this.focusedIndex_ + 1})`); + } + + protected getAllItems_(): ReadLaterEntry[] { + const allItems: ReadLaterEntry[] = []; + if (this.unreadItems_.length > 0) { + allItems.push(this.createHeaderEntry_(this.unreadHeader_)); + if (this.unreadExpanded_) { + allItems.push(...this.unreadItems_); + } + } + if (this.readItems_.length > 0) { + allItems.push(this.createHeaderEntry_(this.readHeader_)); + if (this.readExpanded_) { + allItems.push(...this.readItems_); + } + } + return allItems; + } + + private createHeaderEntry_(title: string): ReadLaterEntry { + return { + title: title, + url: {url: ''}, + displayUrl: '', + updateTime: 0n, + read: false, + displayTimeSinceUpdate: '', + }; + } + + protected getExpandButtonIcon_(title: string): string { + switch (title) { + case this.unreadHeader_: + return this.unreadExpanded_ ? 'cr:expand-less' : 'cr:expand-more'; + case this.readHeader_: + return this.readExpanded_ ? 'cr:expand-less' : 'cr:expand-more'; + default: + assertNotReached(); + } + } + + protected onExpandButtonClick_(e: Event) { + const title: string = (e.target as HTMLElement).dataset['title']!; + switch (title) { + case this.unreadHeader_: + this.unreadExpanded_ = !this.unreadExpanded_; + break; + case this.readHeader_: + this.readExpanded_ = !this.readExpanded_; + break; + default: + assertNotReached(); + } } /** @@ -178,13 +274,10 @@ this.updateReadingListItems_(entries); } - private async updateReadingListItems_(entries: ReadLaterEntriesByStatus) { + private updateReadingListItems_(entries: ReadLaterEntriesByStatus) { this.unreadItems_ = entries.unreadEntries; this.readItems_ = entries.readEntries; this.loadingContent_ = false; - - await this.updateComplete; - this.itemsChanged(); } private updateCurrentPageActionButton_(state: CurrentPageActionButtonState) { @@ -260,31 +353,55 @@ ); } - protected async onItemKeyDown_(e: KeyboardEvent) { if (e.shiftKey || !navigationKeys.has(e.key)) { return; } - switch (e.key) { - case 'ArrowDown': - this.selectNext(); - await this.updateComplete; - (this.selectedItem as ReadingListItemElement).focus(); - break; - case 'ArrowUp': - this.selectPrevious(); - await this.updateComplete; - (this.selectedItem as ReadingListItemElement).focus(); - break; - default: - assertNotReached(); - } - e.preventDefault(); e.stopPropagation(); + e.preventDefault(); + + // Skip focus traversal for the header of the first section. + const indicesToSkip = [0]; + if (this.unreadItems_.length > 0 && this.readItems_.length > 0) { + // If both sections are shown, skip the header of the second section too. + if (this.unreadExpanded_) { + indicesToSkip.push(this.unreadItems_.length + 1); + } else { + indicesToSkip.push(1); + } + } + const listLength = this.getAllItems_().length; + + // Identify the new focused index. + let newFocusedIndex = 0; + if (e.key === 'ArrowUp') { + newFocusedIndex = (this.focusedIndex_ + listLength - 1) % listLength; + while (indicesToSkip.includes(newFocusedIndex)) { + newFocusedIndex = (newFocusedIndex + listLength - 1) % listLength; + } + } else { + newFocusedIndex = (this.focusedIndex_ + 1) % listLength; + while (indicesToSkip.includes(newFocusedIndex)) { + newFocusedIndex = (newFocusedIndex + 1) % listLength; + } + } + this.focusedIndex_ = newFocusedIndex; + + const element = + await this.$.readingListList.ensureItemRendered(this.focusedIndex_); + element.focus(); } protected onItemFocus_(e: Event) { - this.selected = (e.currentTarget as ReadingListItemElement).dataset['url']!; + const renderedItems = + this.querySelectorAll<HTMLElement>('cr-lazy-list > *'); + const focusedIdx = Array.from(renderedItems).findIndex(item => { + return item === e.target || item.shadowRoot?.activeElement === e.target; + }); + + if (focusedIdx !== -1) { + this.focusedIndex_ = focusedIdx; + } } protected shouldShowHr_(): boolean {
diff --git a/chrome/browser/resources/tts_engine/background.ts b/chrome/browser/resources/tts_engine/background.ts index bf47e1e..ba4503ad 100644 --- a/chrome/browser/resources/tts_engine/background.ts +++ b/chrome/browser/resources/tts_engine/background.ts
@@ -25,14 +25,14 @@ if (version < CURRENT_VERSION_NUMBER) { // If the version is valid, update the download version. CURRENT_VERSION_NUMBER = version; + } + } else { + if (!version) { + console.info( + 'Found invalid version in version.json: ' + + 'versionNumber undefined'); } else { - if (!version) { - console.info( - 'Found invalid version in version.json: ' + - 'versionNumber undefined'); - } else { - console.info('Found invalid version in version.json: ' + version); - } + console.info('Found invalid version in version.json: ' + version); } } });
diff --git a/chrome/browser/resources/tts_engine/manifest.json b/chrome/browser/resources/tts_engine/manifest.json index 6475e3f2..a1163d0 100644 --- a/chrome/browser/resources/tts_engine/manifest.json +++ b/chrome/browser/resources/tts_engine/manifest.json
@@ -16,6 +16,6 @@ "webRequest", "webRequestBlocking" ], - "content_security_policy": "script-src 'self' 'wasm-eval' 'unsafe-eval' https://dl.google.com 'unsafe-inline' 'sha256-6GFr/PbTsH4+cJ0C9phPX+lGpsvyJrh3NNnT3bfDoh8='; object-src 'self'; connect-src *" + "content_security_policy": "script-src 'self' 'wasm-eval' 'unsafe-eval' https://dl.google.com 'unsafe-inline' 'sha256-RMSqHznNzfybAW99WZABbiusMDFL1dNKAedUmiUifxA=' 'sha256-6GFr/PbTsH4+cJ0C9phPX+lGpsvyJrh3NNnT3bfDoh8='; object-src 'self'; connect-src *" }
diff --git a/chrome/browser/safe_browsing/notification_content_detection_service_browsertest.cc b/chrome/browser/safe_browsing/notification_content_detection_service_browsertest.cc index fdd37e1..8b84e618 100644 --- a/chrome/browser/safe_browsing/notification_content_detection_service_browsertest.cc +++ b/chrome/browser/safe_browsing/notification_content_detection_service_browsertest.cc
@@ -436,6 +436,18 @@ EXPECT_FALSE( IsNotificationSuspicious(GetDisplayedPersistentNotifications()[0])); } + histogram_tester().ExpectTotalCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + 2); + histogram_tester().ExpectBucketCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + /*kRequested=*/0, 1); + histogram_tester().ExpectBucketCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + /*kFinished=*/1, 1); } IN_PROC_BROWSER_TEST_P( @@ -473,6 +485,18 @@ EXPECT_FALSE( IsNotificationSuspicious(GetDisplayedPersistentNotifications()[0])); } + histogram_tester().ExpectTotalCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + 2); + histogram_tester().ExpectBucketCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + /*kRequested=*/0, 1); + histogram_tester().ExpectBucketCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + /*kFinished=*/1, 1); } IN_PROC_BROWSER_TEST_P( @@ -494,6 +518,18 @@ EXPECT_EQ(GetDisplayedPersistentNotifications().size(), 1U); EXPECT_FALSE( IsNotificationSuspicious(GetDisplayedPersistentNotifications()[0])); + histogram_tester().ExpectTotalCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + 2); + histogram_tester().ExpectBucketCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + /*kRequested=*/0, 1); + histogram_tester().ExpectBucketCount( + "SafeBrowsing.NotificationContentDetection." + "DisplayPersistentNotificationEvent", + /*kFinished=*/1, 1); } } // namespace safe_browsing
diff --git a/chrome/browser/search_engines/android/javatests/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceScreenRenderTest.java b/chrome/browser/search_engines/android/javatests/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceScreenRenderTest.java index 7d57e06..5e6ed1a 100644 --- a/chrome/browser/search_engines/android/javatests/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceScreenRenderTest.java +++ b/chrome/browser/search_engines/android/javatests/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceScreenRenderTest.java
@@ -29,6 +29,7 @@ import org.mockito.quality.Strictness; import org.chromium.base.FeatureList; +import org.chromium.base.FeatureOverrides; import org.chromium.base.ThreadUtils; import org.chromium.base.test.BaseActivityTestRule; import org.chromium.base.test.params.ParameterAnnotations; @@ -44,14 +45,13 @@ import org.chromium.components.browser_ui.modaldialog.AppModalPresenter; import org.chromium.components.search_engines.FakeSearchEngineCountryDelegate; import org.chromium.components.search_engines.SearchEngineChoiceService; -import org.chromium.components.search_engines.test.util.SearchEnginesFeaturesTestUtil; +import org.chromium.components.search_engines.SearchEnginesFeatures; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.test.util.BlankUiTestActivity; import org.chromium.ui.test.util.NightModeTestUtils; import org.chromium.ui.test.util.NightModeTestUtils.NightModeParams; import java.util.List; -import java.util.Map; /** Render tests for {@link ChoiceDialogCoordinator} */ @RunWith(ParameterizedRunner.class) @@ -85,11 +85,12 @@ @Before public void setUp() { FeatureList.setDisableNativeForTesting(true); - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams( - Map.of( - "dialog_timeout_millis", "0", - // For the "pending" dialog mode to be enabled, this needs to be non-0. - "silent_pending_duration_millis", "1")); + FeatureOverrides.newBuilder() + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("dialog_timeout_millis", 0) + // For the "pending" dialog mode to be enabled, this needs to be non-0. + .param("silent_pending_duration_millis", 1) + .apply(); mActivityTestRule.launchActivity(null); mDialogManager = mActivityTestRule.getActivity().getModalDialogManager();
diff --git a/chrome/browser/search_engines/android/junit/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceDialogCoordinatorUnitTest.java b/chrome/browser/search_engines/android/junit/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceDialogCoordinatorUnitTest.java index 40e7592..4cfc95f 100644 --- a/chrome/browser/search_engines/android/junit/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceDialogCoordinatorUnitTest.java +++ b/chrome/browser/search_engines/android/junit/src/org/chromium/chrome/browser/search_engines/choice_screen/ChoiceDialogCoordinatorUnitTest.java
@@ -36,6 +36,7 @@ import org.mockito.quality.Strictness; import org.chromium.base.FakeTimeTestRule; +import org.chromium.base.FeatureOverrides; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Features; @@ -48,7 +49,6 @@ import org.chromium.chrome.browser.search_engines.choice_screen.ChoiceDialogMediator.LaunchChoiceScreenTapHandlingStatus; import org.chromium.components.search_engines.SearchEngineChoiceService; import org.chromium.components.search_engines.SearchEnginesFeatures; -import org.chromium.components.search_engines.test.util.SearchEnginesFeaturesTestUtil; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogManager.ModalDialogManagerObserver; @@ -58,7 +58,6 @@ import org.chromium.ui.modelutil.PropertyModel; import java.time.Duration; -import java.util.Map; @RunWith(BaseRobolectricTestRunner.class) @Features.EnableFeatures({SearchEnginesFeatures.CLAY_BLOCKING}) @@ -83,8 +82,10 @@ @Test public void testMaybeShow() { // For code coverage. - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams( - Map.of("enable_verbose_logging", "true")); + FeatureOverrides.newBuilder() + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("enable_verbose_logging", true) + .apply(); var histogramWatcher = HistogramWatcher.newBuilder() @@ -154,8 +155,10 @@ @Test public void testMaybeShow_doesNotShowInDarkLaunchMode() { - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams( - Map.of("is_dark_launch", "true")); + FeatureOverrides.newBuilder() + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("is_dark_launch", true) + .apply(); var histogramWatcher = HistogramWatcher.newBuilder() @@ -185,8 +188,10 @@ @Test public void testMaybeShow_doesNotShowEscapeHatch() { - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams( - Map.of("escape_hatch_block_limit", "1")); + FeatureOverrides.newBuilder() + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("escape_hatch_block_limit", 1) + .apply(); var shouldShowSupplier = new ObservableSupplierImpl<>(true); doReturn(shouldShowSupplier) .when(mSearchEngineChoiceService) @@ -254,8 +259,10 @@ @Test public void testMaybeShow_showsAndBlocksAfterDelayedApproval() { - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams( - Map.of("silent_pending_duration_millis", "24")); + FeatureOverrides.newBuilder() + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("silent_pending_duration_millis", 24) + .apply(); var pendingSupplier = new ObservableSupplierImpl<Boolean>(null); doReturn(pendingSupplier) @@ -309,8 +316,10 @@ @Test public void testMaybeShow_showsAndUnblocksAfterDelayedDisapproval() { - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams( - Map.of("silent_pending_duration_millis", "24")); + FeatureOverrides.newBuilder() + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("silent_pending_duration_millis", 24) + .apply(); var pendingSupplier = new ObservableSupplierImpl<Boolean>(null); doReturn(pendingSupplier) @@ -410,12 +419,11 @@ public void testMaybeShow_dismissesDialogAfterTimeout() { int timeoutDuration = 24_000; int silentPendingDuration = 1_000; - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams( - Map.ofEntries( - Map.entry("dialog_timeout_millis", Long.toString(timeoutDuration)), - Map.entry( - "silent_pending_duration_millis", - Long.toString(silentPendingDuration)))); + FeatureOverrides.newBuilder() + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("dialog_timeout_millis", timeoutDuration) + .param("silent_pending_duration_millis", silentPendingDuration) + .apply(); var pendingSupplier = new ObservableSupplierImpl<>(); doReturn(pendingSupplier)
diff --git a/chrome/browser/storage/shared_storage_browsertest.cc b/chrome/browser/storage/shared_storage_browsertest.cc index c276a98..70d3304f 100644 --- a/chrome/browser/storage/shared_storage_browsertest.cc +++ b/chrome/browser/storage/shared_storage_browsertest.cc
@@ -174,12 +174,6 @@ kAttestationsEnforcedMainHostEnrolled = 2, }; -#if BUILDFLAG(IS_ANDROID) -base::FilePath GetChromeTestDataDir() { - return base::FilePath(FILE_PATH_LITERAL("chrome/test/data")); -} -#endif - // With `WebContentsConsoleObserver`, we can only wait for the last message in a // group. base::RepeatingCallback<
diff --git a/chrome/browser/sync/sync_ui_util.cc b/chrome/browser/sync/sync_ui_util.cc index 78839c5..bd7f8f3 100644 --- a/chrome/browser/sync/sync_ui_util.cc +++ b/chrome/browser/sync/sync_ui_util.cc
@@ -59,7 +59,8 @@ #endif return {SyncStatusMessageType::kSyncError, status_label_string_id, - IDS_SYNC_RELOGIN_BUTTON, SyncStatusActionType::kReauthenticate}; + IDS_SYNC_RELOGIN_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kReauthenticate}; } SyncStatusLabels GetSyncStatusLabelsImpl( @@ -71,7 +72,8 @@ if (!service->HasSyncConsent()) { return {SyncStatusMessageType::kPreSynced, IDS_SYNC_EMPTY_STRING, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } // If local Sync were enabled, then the SyncService shouldn't report having a @@ -81,7 +83,7 @@ // First check if Chrome needs to be updated. if (service->RequiresClientUpgrade()) { return {SyncStatusMessageType::kSyncError, IDS_SYNC_UPGRADE_CLIENT, - IDS_SYNC_UPGRADE_CLIENT_BUTTON, + IDS_SYNC_UPGRADE_CLIENT_BUTTON, IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kUpgradeClient}; } @@ -95,7 +97,8 @@ if (auth_error.state() != GoogleServiceAuthError::NONE) { DCHECK(auth_error.IsPersistentError()); return {SyncStatusMessageType::kSyncError, IDS_SYNC_RELOGIN_ERROR, - IDS_SYNC_RELOGIN_BUTTON, SyncStatusActionType::kReauthenticate}; + IDS_SYNC_RELOGIN_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kReauthenticate}; } // Check if Sync is disabled by policy. @@ -105,7 +108,7 @@ // this case? return {SyncStatusMessageType::kSynced, IDS_SIGNED_IN_WITH_SYNC_DISABLED_BY_POLICY, IDS_SYNC_EMPTY_STRING, - SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; } // Check to see if sync has been disabled via the dashboard and needs to be @@ -114,7 +117,8 @@ if (service->GetUserSettings()->IsSyncFeatureDisabledViaDashboard()) { return {SyncStatusMessageType::kSyncError, IDS_SIGNED_IN_WITH_SYNC_STOPPED_VIA_DASHBOARD, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } #endif // BUILDFLAG(IS_CHROMEOS_ASH) @@ -126,7 +130,7 @@ // SyncStatusMessageType::kPasswordsOnlySyncError if only passwords are // encrypted as per IsEncryptEverythingEnabled(). return {SyncStatusMessageType::kSyncError, IDS_SYNC_STATUS_NEEDS_PASSWORD, - IDS_SYNC_STATUS_NEEDS_PASSWORD_BUTTON, + IDS_SYNC_STATUS_NEEDS_PASSWORD_BUTTON, IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kEnterPassphrase}; } @@ -137,6 +141,7 @@ ? SyncStatusMessageType::kSyncError : SyncStatusMessageType::kPasswordsOnlySyncError, IDS_SYNC_EMPTY_STRING, IDS_SYNC_STATUS_NEEDS_KEYS_BUTTON, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kRetrieveTrustedVaultKeys}; } @@ -146,18 +151,21 @@ service->GetUserSettings()->IsSyncEverythingEnabled() ? IDS_SYNC_ACCOUNT_SYNCING : IDS_SYNC_ACCOUNT_SYNCING_CUSTOM_DATA_TYPES, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } else { // Sync is still initializing. return {SyncStatusMessageType::kSynced, IDS_SYNC_EMPTY_STRING, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } } // If first setup is in progress, show an "in progress" message. if (service->IsSetupInProgress()) { return {SyncStatusMessageType::kPreSynced, IDS_SYNC_SETUP_IN_PROGRESS, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } // At this point we've ruled out all other cases - all that's left is a @@ -165,7 +173,7 @@ DCHECK(ShouldRequestSyncConfirmation(service)); return {SyncStatusMessageType::kSyncError, IDS_SYNC_SETTINGS_NOT_CONFIRMED, IDS_SYNC_ERROR_USER_MENU_CONFIRM_SYNC_SETTINGS_BUTTON, - SyncStatusActionType::kConfirmSyncSettings}; + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kConfirmSyncSettings}; } #if !BUILDFLAG(IS_ANDROID) @@ -217,7 +225,8 @@ if (!sync_service) { // This can happen if Sync is disabled via the command line. return {SyncStatusMessageType::kPreSynced, IDS_SYNC_EMPTY_STRING, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } DCHECK(identity_manager); CoreAccountInfo account_info = sync_service->GetAccountInfo(); @@ -245,6 +254,101 @@ } #if !BUILDFLAG(IS_ANDROID) +SyncStatusLabels GetSyncStatusLabelsForSettings( + const syncer::SyncService* service) { + // Check to see if sync has been disabled via the dashboard and needs to be + // set up once again. +#if BUILDFLAG(IS_CHROMEOS) + if (service->GetUserSettings()->IsSyncFeatureDisabledViaDashboard()) { + return {SyncStatusMessageType::kSyncError, + IDS_SIGNED_IN_WITH_SYNC_STOPPED_VIA_DASHBOARD, + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; + } +#endif // BUILDFLAG(IS_CHROMEOS) + + // If first setup is in progress, show an "in progress" message. + if (service->IsSetupInProgress()) { + return {SyncStatusMessageType::kPreSynced, IDS_SYNC_SETUP_IN_PROGRESS, + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; + } + + // At this point, there is no Sync error. + if (service->IsSyncFeatureActive()) { + return {SyncStatusMessageType::kSynced, + service->GetUserSettings()->IsSyncEverythingEnabled() + ? IDS_SYNC_ACCOUNT_SYNCING + : IDS_SYNC_ACCOUNT_SYNCING_CUSTOM_DATA_TYPES, + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; + } + + // Sync is still initializing. + return {SyncStatusMessageType::kSynced, IDS_SYNC_EMPTY_STRING, + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; +} + +SyncStatusLabels GetAvatarSyncErrorLabelsForSettings( + AvatarSyncErrorType error) { + // check flag disabled. + switch (error) { + case AvatarSyncErrorType::kSyncPaused: + // not sure what to return here; + case AvatarSyncErrorType::kTrustedVaultKeyMissingForPasswordsError: + return {SyncStatusMessageType::kPasswordsOnlySyncError, + IDS_SETTINGS_ERROR_PASSWORDS_USER_ERROR_DESCRIPTION, + IDS_SYNC_STATUS_NEEDS_KEYS_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kRetrieveTrustedVaultKeys}; + + case AvatarSyncErrorType:: + kTrustedVaultRecoverabilityDegradedForPasswordsError: + return { + SyncStatusMessageType::kPasswordsOnlySyncError, + IDS_SETTINGS_ERROR_RECOVERABILITY_DEGRADED_FOR_PASSWORDS_USER_ERROR_DESCRIPTION, + IDS_SYNC_STATUS_NEEDS_KEYS_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kRetrieveTrustedVaultKeys}; + + case AvatarSyncErrorType::kPassphraseError: + return {SyncStatusMessageType::kSyncError, + IDS_SETTINGS_ERROR_PASSPHRASE_USER_ERROR_DESCRIPTION, + IDS_SYNC_STATUS_NEEDS_PASSWORD_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kEnterPassphrase}; + + case AvatarSyncErrorType:: + kTrustedVaultRecoverabilityDegradedForEverythingError: + case AvatarSyncErrorType::kTrustedVaultKeyMissingForEverythingError: + return {SyncStatusMessageType::kSyncError, + IDS_SETTINGS_ERROR_TRUSTED_VAULT_USER_ERROR_DESCRIPTION, + IDS_SYNC_STATUS_NEEDS_PASSWORD_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kRetrieveTrustedVaultKeys}; + + case AvatarSyncErrorType::kUpgradeClientError: + return {SyncStatusMessageType::kSyncError, + IDS_SETTINGS_ERROR_UPGRADE_CLIENT_USER_ERROR_DESCRIPTION, + IDS_SYNC_UPGRADE_CLIENT_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kUpgradeClient}; + + case AvatarSyncErrorType::kSettingsUnconfirmedError: + return { + SyncStatusMessageType::kSyncError, IDS_SYNC_SETTINGS_NOT_CONFIRMED, + IDS_SYNC_ERROR_USER_MENU_CONFIRM_SYNC_SETTINGS_BUTTON, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kConfirmSyncSettings}; + + case AvatarSyncErrorType::kManagedUserUnrecoverableError: + return {SyncStatusMessageType::kSyncError, + IDS_SYNC_STATUS_UNRECOVERABLE_ERROR_NEEDS_SIGNOUT, + IDS_SYNC_RELOGIN_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kReauthenticate}; + + case AvatarSyncErrorType::kUnrecoverableError: + return {SyncStatusMessageType::kSyncError, + IDS_SYNC_STATUS_UNRECOVERABLE_ERROR, IDS_SYNC_RELOGIN_BUTTON, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kReauthenticate}; + } +} + std::optional<AvatarSyncErrorType> GetAvatarSyncErrorType(Profile* profile) { const syncer::SyncService* service = SyncServiceFactory::GetForProfile(profile);
diff --git a/chrome/browser/sync/sync_ui_util.h b/chrome/browser/sync/sync_ui_util.h index b8022ed0..07aee5f 100644 --- a/chrome/browser/sync/sync_ui_util.h +++ b/chrome/browser/sync/sync_ui_util.h
@@ -81,10 +81,12 @@ }; struct SyncStatusLabels { - SyncStatusMessageType message_type; - int status_label_string_id; - int button_string_id; - SyncStatusActionType action_type; + SyncStatusMessageType message_type = SyncStatusMessageType::kPreSynced; + int status_label_string_id = 0; + int button_string_id = 0; + // This will be empty when switches::kImprovedSettingsUIOnDesktop is disabled. + int secondary_button_string_id = 0; + SyncStatusActionType action_type = SyncStatusActionType::kNoAction; }; // Returns the high-level sync status by querying |sync_service| and @@ -104,6 +106,11 @@ SyncStatusMessageType GetSyncStatusMessageType(Profile* profile); #if !BUILDFLAG(IS_ANDROID) +SyncStatusLabels GetSyncStatusLabelsForSettings( + const syncer::SyncService* service); + +SyncStatusLabels GetAvatarSyncErrorLabelsForSettings(AvatarSyncErrorType error); + // Gets the error in the sync machinery (if any) that should be exposed to the // user through the titlebar avatar button. If std::nullopt is returned, this // does NOT mean sync-the-feature/sync-the-transport is enabled, simply that
diff --git a/chrome/browser/sync/sync_ui_util_unittest.cc b/chrome/browser/sync/sync_ui_util_unittest.cc index b8f3d13..9a0eacd 100644 --- a/chrome/browser/sync/sync_ui_util_unittest.cc +++ b/chrome/browser/sync/sync_ui_util_unittest.cc
@@ -25,10 +25,11 @@ namespace { -MATCHER_P4(SyncStatusLabelsMatch, +MATCHER_P5(SyncStatusLabelsMatch, message_type, status_label_string_id, button_string_id, + secondary_button_string_id, action_type, "") { if (arg.message_type != message_type) { @@ -43,6 +44,10 @@ *result_listener << "Wrong button string"; return false; } + if (arg.secondary_button_string_id != secondary_button_string_id) { + *result_listener << "Wrong button string"; + return false; + } if (arg.action_type != action_type) { *result_listener << "Wrong action type"; return false; @@ -87,20 +92,20 @@ service->SetInitialSyncFeatureSetupComplete(false); service->SetSetupInProgress(); return {SyncStatusMessageType::kPreSynced, IDS_SYNC_SETUP_IN_PROGRESS, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } case STATUS_CASE_SETUP_ERROR: { service->SetInitialSyncFeatureSetupComplete(false); service->SetHasUnrecoverableError(true); - return { - SyncStatusMessageType::kSyncError, + return {SyncStatusMessageType::kSyncError, #if !BUILDFLAG(IS_CHROMEOS_ASH) - IDS_SYNC_STATUS_UNRECOVERABLE_ERROR, + IDS_SYNC_STATUS_UNRECOVERABLE_ERROR, #else - IDS_SYNC_STATUS_UNRECOVERABLE_ERROR_NEEDS_SIGNOUT, + IDS_SYNC_STATUS_UNRECOVERABLE_ERROR_NEEDS_SIGNOUT, #endif - IDS_SYNC_RELOGIN_BUTTON, SyncStatusActionType::kReauthenticate - }; + IDS_SYNC_RELOGIN_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kReauthenticate}; } case STATUS_CASE_AUTH_ERROR: { test_environment->SetRefreshTokenForPrimaryAccount(); @@ -109,61 +114,67 @@ GoogleServiceAuthError(GoogleServiceAuthError::State::SERVICE_ERROR)); service->SetPersistentAuthError(); return {SyncStatusMessageType::kSyncError, IDS_SYNC_RELOGIN_ERROR, - IDS_SYNC_RELOGIN_BUTTON, SyncStatusActionType::kReauthenticate}; + IDS_SYNC_RELOGIN_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kReauthenticate}; } case STATUS_CASE_PROTOCOL_ERROR: { syncer::SyncStatus status; status.sync_protocol_error = {.action = syncer::UPGRADE_CLIENT}; service->SetDetailedSyncStatus(/*engine_available=*/false, status); return {SyncStatusMessageType::kSyncError, IDS_SYNC_UPGRADE_CLIENT, - IDS_SYNC_UPGRADE_CLIENT_BUTTON, + IDS_SYNC_UPGRADE_CLIENT_BUTTON, IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kUpgradeClient}; } case STATUS_CASE_CONFIRM_SYNC_SETTINGS: { service->SetInitialSyncFeatureSetupComplete(false); - return {SyncStatusMessageType::kSyncError, - IDS_SYNC_SETTINGS_NOT_CONFIRMED, - IDS_SYNC_ERROR_USER_MENU_CONFIRM_SYNC_SETTINGS_BUTTON, - SyncStatusActionType::kConfirmSyncSettings}; + return { + SyncStatusMessageType::kSyncError, IDS_SYNC_SETTINGS_NOT_CONFIRMED, + IDS_SYNC_ERROR_USER_MENU_CONFIRM_SYNC_SETTINGS_BUTTON, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kConfirmSyncSettings}; } case STATUS_CASE_PASSPHRASE_ERROR: { service->SetPassphraseRequired(); return {SyncStatusMessageType::kSyncError, IDS_SYNC_STATUS_NEEDS_PASSWORD, - IDS_SYNC_STATUS_NEEDS_PASSWORD_BUTTON, + IDS_SYNC_STATUS_NEEDS_PASSWORD_BUTTON, IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kEnterPassphrase}; } case STATUS_CASE_TRUSTED_VAULT_KEYS_ERROR: service->SetTrustedVaultKeyRequired(true); return {SyncStatusMessageType::kPasswordsOnlySyncError, IDS_SYNC_EMPTY_STRING, IDS_SYNC_STATUS_NEEDS_KEYS_BUTTON, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kRetrieveTrustedVaultKeys}; case STATUS_CASE_TRUSTED_VAULT_RECOVERABILITY_ERROR: service->SetTrustedVaultRecoverabilityDegraded(true); return {SyncStatusMessageType::kSynced, IDS_SYNC_ACCOUNT_SYNCING, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; case STATUS_CASE_SYNCED: { return {SyncStatusMessageType::kSynced, IDS_SYNC_ACCOUNT_SYNCING, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } case STATUS_CASE_SYNC_DISABLED_BY_POLICY: { service->SetAllowedByEnterprisePolicy(false); return {SyncStatusMessageType::kSynced, IDS_SIGNED_IN_WITH_SYNC_DISABLED_BY_POLICY, IDS_SYNC_EMPTY_STRING, - SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; } #if BUILDFLAG(IS_CHROMEOS_ASH) case STATUS_CASE_SYNC_RESET_FROM_DASHBOARD: { service->GetUserSettings()->SetSyncFeatureDisabledViaDashboard(true); return {SyncStatusMessageType::kSyncError, IDS_SIGNED_IN_WITH_SYNC_STOPPED_VIA_DASHBOARD, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } #endif // BUILDFLAG(IS_CHROMEOS_ASH) case NUMBER_OF_STATUS_CASES: NOTREACHED(); } return {SyncStatusMessageType::kPreSynced, IDS_SYNC_EMPTY_STRING, - IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction}; + IDS_SYNC_EMPTY_STRING, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kNoAction}; } // This test ensures that each distinctive SyncService status will return a @@ -185,6 +196,7 @@ SyncStatusLabelsMatch(expected_labels.message_type, expected_labels.status_label_string_id, expected_labels.button_string_id, + expected_labels.secondary_button_string_id, expected_labels.action_type)); } } @@ -213,6 +225,7 @@ /*is_user_clear_primary_account_allowed=*/true), SyncStatusLabelsMatch(SyncStatusMessageType::kSyncError, unrecoverable_error, IDS_SYNC_RELOGIN_BUTTON, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kReauthenticate)); // This time set action to SyncStatusActionType::kUpgradeClient. @@ -223,10 +236,10 @@ EXPECT_THAT( GetSyncStatusLabels(&service, environment.identity_manager(), /*is_user_clear_primary_account_allowed=*/true), - SyncStatusLabelsMatch(SyncStatusMessageType::kSyncError, - IDS_SYNC_UPGRADE_CLIENT, - IDS_SYNC_UPGRADE_CLIENT_BUTTON, - SyncStatusActionType::kUpgradeClient)); + SyncStatusLabelsMatch( + SyncStatusMessageType::kSyncError, IDS_SYNC_UPGRADE_CLIENT, + IDS_SYNC_UPGRADE_CLIENT_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kUpgradeClient)); } TEST(SyncUIUtilTest, ActionableProtocolErrorWithPassiveMessage) { @@ -247,10 +260,10 @@ EXPECT_THAT( GetSyncStatusLabels(&service, environment.identity_manager(), /*is_user_clear_primary_account_allowed=*/true), - SyncStatusLabelsMatch(SyncStatusMessageType::kSyncError, - IDS_SYNC_UPGRADE_CLIENT, - IDS_SYNC_UPGRADE_CLIENT_BUTTON, - SyncStatusActionType::kUpgradeClient)); + SyncStatusLabelsMatch( + SyncStatusMessageType::kSyncError, IDS_SYNC_UPGRADE_CLIENT, + IDS_SYNC_UPGRADE_CLIENT_BUTTON, IDS_SYNC_EMPTY_STRING, + SyncStatusActionType::kUpgradeClient)); } TEST(SyncUIUtilTest, SyncSettingsConfirmationNeededTest) { @@ -268,7 +281,7 @@ SyncStatusLabelsMatch( SyncStatusMessageType::kSyncError, IDS_SYNC_SETTINGS_NOT_CONFIRMED, IDS_SYNC_ERROR_USER_MENU_CONFIRM_SYNC_SETTINGS_BUTTON, - SyncStatusActionType::kConfirmSyncSettings)); + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kConfirmSyncSettings)); } // Errors in non-sync accounts should be ignored. @@ -292,6 +305,7 @@ /*is_user_clear_primary_account_allowed=*/true), SyncStatusLabelsMatch(SyncStatusMessageType::kSynced, IDS_SYNC_ACCOUNT_SYNCING, IDS_SYNC_EMPTY_STRING, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction)); // Add an error to the secondary account. @@ -306,6 +320,7 @@ /*is_user_clear_primary_account_allowed=*/true), SyncStatusLabelsMatch(SyncStatusMessageType::kSynced, IDS_SYNC_ACCOUNT_SYNCING, IDS_SYNC_EMPTY_STRING, + IDS_SYNC_EMPTY_STRING, SyncStatusActionType::kNoAction)); }
diff --git a/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java b/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java index d9639759..fbb91cd 100644 --- a/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java +++ b/chrome/browser/tab_resumption/junit/src/org/chromium/chrome/browser/tab_resumption/TabResumptionModuleEnablementUnitTest.java
@@ -21,7 +21,6 @@ import org.mockito.junit.MockitoRule; import org.robolectric.annotation.Config; -import org.chromium.base.FeatureList; import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.base.test.util.Features.DisableFeatures; import org.chromium.base.test.util.Features.EnableFeatures; @@ -46,7 +45,6 @@ @Mock private SyncService mSyncService; @Mock private IdentityManager mIdentityManager; @Mock private Profile mProfile; - private FeatureList.TestValues mFeatureListValues; @Before public void setUp() {
diff --git a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java index 83391cdcc..79a423cd 100644 --- a/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java +++ b/chrome/browser/tabmodel/android/java/src/org/chromium/chrome/browser/tabmodel/TabGroupTitleUtils.java
@@ -8,12 +8,10 @@ import android.content.SharedPreferences; import android.text.TextUtils; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.chromium.base.ContextUtils; import org.chromium.chrome.browser.tab.Tab; -import org.chromium.components.tab_group_sync.SavedTabGroup; import java.util.Objects; @@ -68,19 +66,6 @@ } /** - * Returns a displayable title for a given saved tab group. - * - * @param context To load resources from. - * @param savedTabGroup The {@link SavedTabGroup} to create a title from. - * @return A non-null string that can be shown to users. - */ - public static String getDisplayableTitle( - Context context, @NonNull SavedTabGroup savedTabGroup) { - if (!TextUtils.isEmpty(savedTabGroup.title)) return savedTabGroup.title; - return TabGroupTitleUtils.getDefaultTitle(context, savedTabGroup.savedTabs.size()); - } - - /** * This method stores tab group title with reference to {@code tabRootId}. Package protected as * all access should route through the {@link TabGroupModelFilter}. *
diff --git a/chrome/browser/themes/theme_service.cc b/chrome/browser/themes/theme_service.cc index 3803326..9e02bb7 100644 --- a/chrome/browser/themes/theme_service.cc +++ b/chrome/browser/themes/theme_service.cc
@@ -1032,3 +1032,7 @@ } return false; } + +void ThemeService::ResetThemeSyncableServiceForTest() { + theme_syncable_service_.reset(); +}
diff --git a/chrome/browser/themes/theme_service.h b/chrome/browser/themes/theme_service.h index 2371f399..d6d9e42 100644 --- a/chrome/browser/themes/theme_service.h +++ b/chrome/browser/themes/theme_service.h
@@ -242,6 +242,8 @@ // Don't create "Cached Theme.pak" in the extension directory, for testing. static void DisableThemePackForTesting(); + void ResetThemeSyncableServiceForTest(); + protected: // Set a custom default theme instead of the normal default theme. virtual void SetCustomDefaultTheme(
diff --git a/chrome/browser/themes/theme_syncable_service_unittest.cc b/chrome/browser/themes/theme_syncable_service_unittest.cc index 80c42f0..626ca2d 100644 --- a/chrome/browser/themes/theme_syncable_service_unittest.cc +++ b/chrome/browser/themes/theme_syncable_service_unittest.cc
@@ -2964,8 +2964,23 @@ pref_service_.GetBoolean(prefs::kSyncingThemePrefsMigratedToNonSyncing)); } -class ThemePrefsMigrationShouldReadPrefsTest : public ::testing::Test { +class ThemePrefsMigrationShouldReadPrefsTestBase : public ::testing::Test { public: + explicit ThemePrefsMigrationShouldReadPrefsTestBase(bool is_flag_enabled) { + if (is_flag_enabled) { + feature_list_.InitAndEnableFeature(syncer::kMoveThemePrefsToSpecifics); + } else { + feature_list_.InitAndDisableFeature(syncer::kMoveThemePrefsToSpecifics); + } + profile_ = std::make_unique<TestingProfile>(); + // TestingProfile init automatically leads to creation of + // ThemeSyncableService. To allow for more control for tests, reset the + // ThemeSyncableService instance. + theme_service()->ResetThemeSyncableServiceForTest(); + + prefs()->SetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs, true); + } + syncer::SyncDataList InitialPrefsSyncData() { syncer::SyncDataList initial_data; initial_data.push_back(CreateRemotePrefsSyncData( @@ -2981,6 +2996,14 @@ return initial_data; } + sync_preferences::TestingPrefServiceSyncable* prefs() { + return profile_->GetTestingPrefService(); + } + + ThemeService* theme_service() { + return ThemeServiceFactory::GetForProfile(profile_.get()); + } + protected: syncer::SyncData CreateRemotePrefsSyncData(const std::string& name, const base::Value& value) { @@ -2997,132 +3020,132 @@ syncer::DataType::PREFERENCES, name)); } + base::test::ScopedFeatureList feature_list_; content::BrowserTaskEnvironment task_environment_; - TestingProfile profile_; - ThemeService theme_service_{&profile_, GetThemeHelper()}; - raw_ptr<sync_preferences::TestingPrefServiceSyncable> prefs_ = - profile_.GetTestingPrefService(); std::unique_ptr<syncer::FakeSyncChangeProcessor> fake_change_processor_ = std::make_unique<syncer::FakeSyncChangeProcessor>(); + std::unique_ptr<TestingProfile> profile_; +}; + +class ThemePrefsMigrationShouldReadPrefsTestWithFlagDisabled + : public ThemePrefsMigrationShouldReadPrefsTestBase { + public: + ThemePrefsMigrationShouldReadPrefsTestWithFlagDisabled() + : ThemePrefsMigrationShouldReadPrefsTestBase(false) {} }; // Verifies that if kMoveThemePrefsToSpecifics feature flag is not set, the // migration flag is marked unset to allow migration again once the feature flag // is enabled again. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagDisabled, ClearShouldReadPrefFlagIfFeatureDisabled) { - base::test::ScopedFeatureList feature_list; - feature_list.InitAndDisableFeature(syncer::kMoveThemePrefsToSpecifics); - // Migration has run before. - prefs_->SetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs, false); + prefs()->SetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs, false); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); // Flag gets cleared to allow re-migration. - EXPECT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); } +class ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled + : public ThemePrefsMigrationShouldReadPrefsTestBase { + public: + ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled() + : ThemePrefsMigrationShouldReadPrefsTestBase(true) {} +}; + // Verifies that syncing prefs are read upon construction of // ThemeSyncableService if prefs sync has already started. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled, ShouldReadThemePrefsOnContructionIfPrefsAlreadySyncing) { - base::test::ScopedFeatureList feature_list( - syncer::kMoveThemePrefsToSpecifics); - - ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + ASSERT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); // Start prefs sync. syncer::SyncableService* pref_sync_service = - prefs_->GetSyncableService(syncer::PREFERENCES); + prefs()->GetSyncableService(syncer::PREFERENCES); ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing( syncer::PREFERENCES, InitialPrefsSyncData(), std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); - ASSERT_TRUE(prefs_->IsSyncing()); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); + ASSERT_TRUE(prefs()->IsSyncing()); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); // Syncing prefs were copied. - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kLight)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse), static_cast<int>(SK_ColorRED)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot)); } // Verifies that syncing theme prefs are read when prefs sync starts. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled, ShouldReadThemePrefsWhenPrefsStartSyncing) { - base::test::ScopedFeatureList feature_list( - syncer::kMoveThemePrefsToSpecifics); + ASSERT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - - ASSERT_FALSE(prefs_->IsSyncing()); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); + ASSERT_FALSE(prefs()->IsSyncing()); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); // Start prefs sync. syncer::SyncableService* pref_sync_service = - prefs_->GetSyncableService(syncer::PREFERENCES); + prefs()->GetSyncableService(syncer::PREFERENCES); ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing( syncer::PREFERENCES, InitialPrefsSyncData(), std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); // Syncing prefs have been copied. - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kLight)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse), static_cast<int>(SK_ColorRED)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot)); } // Verifies that syncing theme prefs are not read if they have already been read // before or if the migration flag has already been set. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled, ShouldNotReadThemePrefsIfAlreadyRead) { - base::test::ScopedFeatureList feature_list( - syncer::kMoveThemePrefsToSpecifics); - // Mark as already read. - prefs_->SetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs, false); + prefs()->SetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs, false); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); // Start prefs sync. syncer::SyncableService* pref_sync_service = - prefs_->GetSyncableService(syncer::PREFERENCES); + prefs()->GetSyncableService(syncer::PREFERENCES); ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing( syncer::PREFERENCES, InitialPrefsSyncData(), std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); // Prefs are unchanged. - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_NE(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kLight)); - EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse), + EXPECT_NE(prefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse), static_cast<int>(SK_ColorRED)); - EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), + EXPECT_NE(prefs()->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot)); } // Verifies that the migration flag is set and (thus) syncing prefs are not read // if the incoming ThemeSpecifics contains the new fields. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled, ShouldNotReadThemePrefsIfReadViaThemeSpecifics) { - base::test::ScopedFeatureList feature_list( - syncer::kMoveThemePrefsToSpecifics); + ASSERT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - - ASSERT_FALSE(prefs_->IsSyncing()); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); + ASSERT_FALSE(prefs()->IsSyncing()); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); sync_pb::ThemeSpecifics theme_specifics; theme_specifics.set_browser_color_scheme( @@ -3137,39 +3160,38 @@ ASSERT_FALSE(error.has_value()) << error.value().message(); // Migration flag is already set. - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kDark)); // Start prefs sync. syncer::SyncableService* pref_sync_service = - prefs_->GetSyncableService(syncer::PREFERENCES); + prefs()->GetSyncableService(syncer::PREFERENCES); ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing( syncer::PREFERENCES, InitialPrefsSyncData(), std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); // Syncing prefs have not been copied since ThemeSpecifics had the new fields. - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_NE(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kLight)); - EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse), + EXPECT_NE(prefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse), static_cast<int>(SK_ColorRED)); - EXPECT_NE(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), + EXPECT_NE(prefs()->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot)); } // Verifies that syncing theme prefs are read if the incoming ThemeSpecifics // didn't have the new fields. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled, ShouldReadThemePrefsIfThemeSpecificsDoesNotHaveNewFields) { - base::test::ScopedFeatureList feature_list( - syncer::kMoveThemePrefsToSpecifics); + ASSERT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - - ASSERT_FALSE(prefs_->IsSyncing()); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); + ASSERT_FALSE(prefs()->IsSyncing()); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); sync_pb::ThemeSpecifics theme_specifics; theme_specifics.mutable_autogenerated_color_theme()->set_color(SK_ColorBLUE); @@ -3180,47 +3202,47 @@ std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); - EXPECT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); // Start prefs sync. syncer::SyncableService* pref_sync_service = - prefs_->GetSyncableService(syncer::PREFERENCES); + prefs()->GetSyncableService(syncer::PREFERENCES); ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing( syncer::PREFERENCES, InitialPrefsSyncData(), std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); // Syncing prefs copied since ThemeSpecifics didn't have the new fields. - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kLight)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse), static_cast<int>(SK_ColorRED)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot)); } // Verifies that the incoming ThemeSpecifics overwrites the value copied from // the syncing theme prefs. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, ShouldPrioritizeThemeSpecifics) { - base::test::ScopedFeatureList feature_list( - syncer::kMoveThemePrefsToSpecifics); +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled, + ShouldPrioritizeThemeSpecifics) { + ASSERT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - - ASSERT_FALSE(prefs_->IsSyncing()); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); + ASSERT_FALSE(prefs()->IsSyncing()); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); // Start prefs sync. syncer::SyncableService* pref_sync_service = - prefs_->GetSyncableService(syncer::PREFERENCES); + prefs()->GetSyncableService(syncer::PREFERENCES); ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing( syncer::PREFERENCES, InitialPrefsSyncData(), std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kLight)); sync_pb::ThemeSpecifics theme_specifics; @@ -3233,24 +3255,24 @@ std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( fake_change_processor_.get()))); - EXPECT_FALSE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + EXPECT_FALSE( + prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); // Overwrites the theme set by prefs. - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorSchemeDoNotUse), static_cast<int>(ThemeService::BrowserColorScheme::kDark)); } // Regression test for crbug.com/375553464. -TEST_F(ThemePrefsMigrationShouldReadPrefsTest, +TEST_F(ThemePrefsMigrationShouldReadPrefsTestWithFlagEnabled, ShouldOnlyNotifyOnceUponReadingThemePrefs) { - base::test::ScopedFeatureList feature_list( - syncer::kMoveThemePrefsToSpecifics); + ASSERT_FALSE(prefs()->IsSyncing()); + ThemeSyncableService theme_syncable_service(profile_.get(), theme_service()); - ASSERT_FALSE(prefs_->IsSyncing()); - ThemeSyncableService theme_syncable_service(&profile_, &theme_service_); - - theme_service_.SetUserColorAndBrowserColorVariant( + theme_service()->SetUserColorAndBrowserColorVariant( SK_ColorBLUE, ui::mojom::BrowserColorVariant::kNeutral); + ASSERT_EQ(fake_change_processor_->changes().size(), 0u); + // Start themes sync. ASSERT_FALSE(theme_syncable_service.MergeDataAndStartSyncing( syncer::THEMES, MakeThemeDataList(sync_pb::ThemeSpecifics()), @@ -3258,15 +3280,15 @@ fake_change_processor_.get()))); ASSERT_EQ(fake_change_processor_->changes().size(), 1u); - ASSERT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse), + ASSERT_EQ(prefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse), static_cast<int>(SK_ColorBLUE)); - ASSERT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), + ASSERT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), static_cast<int>(ui::mojom::BrowserColorVariant::kNeutral)); - ASSERT_TRUE(prefs_->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); + ASSERT_TRUE(prefs()->GetBoolean(prefs::kShouldReadIncomingSyncingThemePrefs)); // Start prefs sync. syncer::SyncableService* pref_sync_service = - prefs_->GetSyncableService(syncer::PREFERENCES); + prefs()->GetSyncableService(syncer::PREFERENCES); ASSERT_FALSE(pref_sync_service->MergeDataAndStartSyncing( syncer::PREFERENCES, InitialPrefsSyncData(), std::make_unique<syncer::SyncChangeProcessorWrapperForTest>( @@ -3276,8 +3298,8 @@ fake_change_processor_->changes(), [](const auto& e) { return e.sync_data().GetSpecifics().has_theme(); })); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingUserColorDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingUserColorDoNotUse), static_cast<int>(SK_ColorRED)); - EXPECT_EQ(prefs_->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), + EXPECT_EQ(prefs()->GetInteger(prefs::kNonSyncingBrowserColorVariantDoNotUse), static_cast<int>(ui::mojom::BrowserColorVariant::kTonalSpot)); }
diff --git a/chrome/browser/tpcd/heuristics/opener_heuristic_service_factory.cc b/chrome/browser/tpcd/heuristics/opener_heuristic_service_factory.cc index 911a232e..be60f2f9 100644 --- a/chrome/browser/tpcd/heuristics/opener_heuristic_service_factory.cc +++ b/chrome/browser/tpcd/heuristics/opener_heuristic_service_factory.cc
@@ -6,7 +6,7 @@ #include "base/no_destructor.h" #include "base/types/pass_key.h" -#include "chrome/browser/dips/chrome_dips_delegate.h" +#include "chrome/browser/chrome_content_browser_client.h" #include "chrome/browser/privacy_sandbox/tracking_protection_settings_factory.h" #include "chrome/browser/tpcd/heuristics/opener_heuristic_service.h" #include "components/content_settings/core/common/features.h" @@ -42,7 +42,7 @@ // Enable the heuristic for the same profiles as DIPS -- profiles associated // with a human user. - if (!ChromeDipsDelegate::Create()->ShouldEnableDips(context)) { + if (!ShouldBrowserContextEnableDips(context)) { return nullptr; }
diff --git a/chrome/browser/tpcd/metadata/devtools_observer_browsertest.cc b/chrome/browser/tpcd/metadata/devtools_observer_browsertest.cc index d67967ef..2bb4b41 100644 --- a/chrome/browser/tpcd/metadata/devtools_observer_browsertest.cc +++ b/chrome/browser/tpcd/metadata/devtools_observer_browsertest.cc
@@ -274,7 +274,10 @@ } void WaitForCookieIssueAndCheck(std::string_view third_party_site, - std::string_view warning) { + std::string_view warning, + std::string_view exclusion) { + CHECK(warning.empty() || exclusion.empty()) + << "inclusion reason and exclusion reason should not co-exist"; auto is_cookie_issue = [](const base::Value::Dict& params) { const std::string* issue_code = params.FindStringByDottedPath("issue.code"); @@ -285,6 +288,9 @@ base::Value::Dict params = WaitForMatchingNotification( "Audits.issueAdded", base::BindRepeating(is_cookie_issue)); + std::string_view reason_name = + warning.empty() ? "cookieExclusionReasons" : "cookieWarningReasons"; + std::string_view reason_value = warning.empty() ? exclusion : warning; std::string partial_expected = content::JsReplace(R"({ "cookie": { @@ -292,10 +298,10 @@ "name": "name", "path": "/" }, - "cookieWarningReasons": [ $2 ], + $2: [ $3 ], "operation": "ReadCookie", })", - third_party_site, warning); + third_party_site, reason_name, reason_value); // Find relevant fields from cookieIssueDetails ASSERT_THAT(params.FindDictByDottedPath("issue.details.cookieIssueDetails"), @@ -370,10 +376,26 @@ IN_PROC_BROWSER_TEST_F(TpcdMetadataDevtoolsObserverBrowserTest, EmitsDevtoolsIssuesForExemption) { AddCookieAccess("a.test", "b.test", /*is_ad_tagged=*/false); - WaitForCookieIssueAndCheck("b.test", {"WarnDeprecationTrialMetadata"}); + WaitForCookieIssueAndCheck( + "b.test", /*warning=*/{"WarnDeprecationTrialMetadata"}, /*exclusion=*/{}); AddCookieAccess("a.test", "c.test", /*is_ad_tagged=*/false); - WaitForCookieIssueAndCheck("c.test", {"WarnDeprecationTrialMetadata"}); + WaitForCookieIssueAndCheck( + "c.test", /*warning=*/{"WarnDeprecationTrialMetadata"}, /*exclusion=*/{}); +} + +IN_PROC_BROWSER_TEST_F(TpcdMetadataDevtoolsObserverBrowserTest, + DevToolsDisableMetadata) { + SendCommandAsync("Network.enable"); + base::Value::Dict command_params; + command_params.Set("enableThirdPartyCookieRestriction", true); + command_params.Set("disableThirdPartyCookieMetadata", true); + command_params.Set("disableThirdPartyCookieHeuristics", false); + SendCommandSync("Network.setCookieControls", std::move(command_params)); + AddCookieAccess("a.test", "b.test", /*is_ad_tagged=*/false); + // Since the cookie is no longer exempted by metadata, + // ExcludeThirdPartyPhaseout cookie issue should be present. + WaitForCookieIssueAndCheck("b.test", {}, {"ExcludeThirdPartyPhaseout"}); } IN_PROC_BROWSER_TEST_F(TpcdMetadataDevtoolsObserverBrowserTest,
diff --git a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java index f9331a0..8657473 100644 --- a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java +++ b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinator.java
@@ -79,6 +79,7 @@ DesktopWindowHeuristicResult.UNKNOWN; private @WindowingMode int mWindowingMode = WindowingMode.UNKNOWN; private int mKeyboardInset; + private int mNavBarInset; /** * Instantiate the coordinator to handle drawing the tab strip into the captionBar area. @@ -110,7 +111,7 @@ mRootView = rootView; mBrowserControlsVisibilityDelegate = browserControlsVisibilityDelegate; mInsetObserver = insetObserver; - mInsetObserver.addInsetsConsumer(this, InsetConsumerSource.APP_HEADER_COORDINATOR_IME); + mInsetObserver.addInsetsConsumer(this, InsetConsumerSource.APP_HEADER_COORDINATOR_BOTTOM); mInsetsController = mRootView.getWindowInsetsController(); mActivityLifecycleDispatcher = activityLifecycleDispatcher; mActivityLifecycleDispatcher.register(this); @@ -313,7 +314,10 @@ private boolean maybeUpdateRootViewBottomPadding() { int rootViewBottomPadding = mRootView.getPaddingBottom(); // Pad the root view with IME bottom insets only if E2E is active. - int bottomInset = FALSE.equals(mEdgeToEdgeStateProvider.get()) ? 0 : mKeyboardInset; + int bottomInset = + FALSE.equals(mEdgeToEdgeStateProvider.get()) + ? 0 + : Math.max(mKeyboardInset, mNavBarInset); // If the root view is padded as needed already, return early. if (rootViewBottomPadding == bottomInset) return bottomInset != 0; @@ -358,12 +362,15 @@ public WindowInsetsCompat onApplyWindowInsets( @NonNull View view, @NonNull WindowInsetsCompat windowInsetsCompat) { mKeyboardInset = windowInsetsCompat.getInsets(WindowInsetsCompat.Type.ime()).bottom; + mNavBarInset = + windowInsetsCompat.getInsets(WindowInsetsCompat.Type.navigationBars()).bottom; boolean resizedRootView = maybeUpdateRootViewBottomPadding(); if (!resizedRootView) return windowInsetsCompat; // Consume IME insets if the root view has been adjusted. return new WindowInsetsCompat.Builder(windowInsetsCompat) .setInsets(WindowInsetsCompat.Type.ime(), Insets.NONE) + .setInsets(WindowInsetsCompat.Type.navigationBars(), Insets.NONE) .build(); } }
diff --git a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java index 15a86dc..abe720c7 100644 --- a/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java +++ b/chrome/browser/ui/android/desktop_windowing/java/src/org/chromium/chrome/browser/ui/desktop_windowing/AppHeaderCoordinatorUnitTest.java
@@ -72,6 +72,8 @@ private static final Rect WIDEST_UNOCCLUDED_RECT = new Rect(LEFT_BLOCK, 0, WINDOW_WIDTH - RIGHT_BLOCK, HEADER_HEIGHT); private static final int KEYBOARD_INSET = 736; + private static final int NAV_BAR_INSET = 128; + private static final int UNSPECIFIED_INSET = -1; private static final int APPEARANCE_LIGHT_CAPTION_BARS = 1 << 8; @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @@ -345,7 +347,7 @@ } @Test - public void noImeInsets() { + public void noImeOrNavBarInsets() { // Simulate switching to desktop windowing mode, without any bottom insets. setupWithLeftAndRightBoundingRect(); notifyInsetsRectObserver(); @@ -358,7 +360,7 @@ /* error= */ "DesktopWindowing should exit when no insets is supplied."); // Simulate overlapping keyboard. - var insets = applyWindowInsets(KEYBOARD_INSET); + var insets = applyWindowInsets(KEYBOARD_INSET, UNSPECIFIED_INSET); assertNotEquals( "Ime insets should not be consumed when root view is not adjusted.", Insets.NONE, @@ -368,7 +370,7 @@ // Simulate switching to desktop windowing mode. setupWithLeftAndRightBoundingRect(); notifyInsetsRectObserver(); - insets = applyWindowInsets(KEYBOARD_INSET); + insets = applyWindowInsets(KEYBOARD_INSET, UNSPECIFIED_INSET); assertEquals( "Ime insets should be consumed when root view is bottom-padded.", Insets.NONE, @@ -382,7 +384,7 @@ // Simulate switching out of desktop windowing mode. setupWithNoCaptionInsets(); notifyInsetsRectObserver(); - insets = applyWindowInsets(KEYBOARD_INSET); + insets = applyWindowInsets(KEYBOARD_INSET, UNSPECIFIED_INSET); assertNotEquals( "Ime insets should not be consumed when root view is not adjusted.", Insets.NONE, @@ -398,7 +400,7 @@ notifyInsetsRectObserver(); // Simulate overlapping keyboard. - var insets = applyWindowInsets(KEYBOARD_INSET); + var insets = applyWindowInsets(KEYBOARD_INSET, UNSPECIFIED_INSET); assertEquals( "Ime insets should be consumed when root view is adjusted.", Insets.NONE, @@ -409,7 +411,7 @@ mSpyRootView.getPaddingBottom()); // Simulate moving a desktop window that causes the keyboard inset to be updated. - insets = applyWindowInsets(KEYBOARD_INSET + 100); + insets = applyWindowInsets(KEYBOARD_INSET + 100, UNSPECIFIED_INSET); assertEquals( "Ime insets should be consumed when root view is adjusted.", Insets.NONE, @@ -421,6 +423,84 @@ } @Test + public void overlappingNavBar_SwitchToAndFromDesktopWindowingMode() { + verifyDesktopWindowingDisabled( + /* error= */ "Desktop windowing mode should be disabled initially."); + + // Simulate overlapping nav bar bottom inset. + var insets = applyWindowInsets(UNSPECIFIED_INSET, NAV_BAR_INSET); + assertNotEquals( + "Nav bar insets should not be consumed when root view is not adjusted.", + Insets.NONE, + insets.getInsets(WindowInsetsCompat.Type.navigationBars())); + assertEquals("Root view bottom should not be padded.", 0, mSpyRootView.getPaddingBottom()); + + // Simulate switching to desktop windowing mode. + setupWithLeftAndRightBoundingRect(); + notifyInsetsRectObserver(); + insets = applyWindowInsets(UNSPECIFIED_INSET, NAV_BAR_INSET); + assertEquals( + "Nav bar insets should be consumed when root view is bottom-padded.", + Insets.NONE, + insets.getInsets(WindowInsetsCompat.Type.ime())); + verifyDesktopWindowingEnabled(); + assertEquals( + "Root view bottom padding should be updated.", + NAV_BAR_INSET, + mSpyRootView.getPaddingBottom()); + + // Simulate switching out of desktop windowing mode. + setupWithNoCaptionInsets(); + notifyInsetsRectObserver(); + insets = applyWindowInsets(UNSPECIFIED_INSET, NAV_BAR_INSET); + assertNotEquals( + "Nav bar insets should not be consumed when root view is not adjusted.", + Insets.NONE, + insets.getInsets(WindowInsetsCompat.Type.navigationBars())); + assertEquals( + "Root view bottom padding should be reset.", 0, mSpyRootView.getPaddingBottom()); + } + + @Test + public void overlappingNavBar_MoveDesktopWindow() { + // Simulate switching to desktop windowing mode. + setupWithLeftAndRightBoundingRect(); + notifyInsetsRectObserver(); + + // Simulate overlapping nav bar bottom inset. + var insets = applyWindowInsets(UNSPECIFIED_INSET, NAV_BAR_INSET); + assertEquals( + "Nav bar insets should be consumed when root view is adjusted.", + Insets.NONE, + insets.getInsets(WindowInsetsCompat.Type.navigationBars())); + + // Simulate moving a desktop window that causes the nav bar inset to be updated. + insets = applyWindowInsets(UNSPECIFIED_INSET, NAV_BAR_INSET - 10); + assertEquals( + "Nav bar insets should be consumed when root view is adjusted.", + Insets.NONE, + insets.getInsets(WindowInsetsCompat.Type.navigationBars())); + assertEquals( + "Root view bottom padding should be updated.", + NAV_BAR_INSET - 10, + mSpyRootView.getPaddingBottom()); + } + + @Test + public void overlappingKeyboardAndNavBar() { + // Simulate switching to desktop windowing mode. + setupWithLeftAndRightBoundingRect(); + notifyInsetsRectObserver(); + + // Simulate overlapping keyboard and nav bar bottom insets. + var insets = applyWindowInsets(KEYBOARD_INSET, NAV_BAR_INSET); + assertEquals( + "Root view bottom padding should be updated.", + KEYBOARD_INSET, + mSpyRootView.getPaddingBottom()); + } + + @Test public void windowingModeHistogram_EnterFullScreen() { // Simulate starting in desktop windowing mode for an initial state. setupWithLeftAndRightBoundingRect(); @@ -594,10 +674,16 @@ assertFalse("Edge to edge should not be active.", mEdgeToEdgeStateProvider.get()); } - private WindowInsetsCompat applyWindowInsets(int keyboardInset) { + private WindowInsetsCompat applyWindowInsets(int keyboardInset, int navBarInset) { var windowInsetsBuilder = new WindowInsetsCompat.Builder(); - windowInsetsBuilder.setInsets( - WindowInsetsCompat.Type.ime(), Insets.of(0, 0, 0, keyboardInset)); + if (keyboardInset != UNSPECIFIED_INSET) { + windowInsetsBuilder.setInsets( + WindowInsetsCompat.Type.ime(), Insets.of(0, 0, 0, keyboardInset)); + } + if (navBarInset != UNSPECIFIED_INSET) { + windowInsetsBuilder.setInsets( + WindowInsetsCompat.Type.navigationBars(), Insets.of(0, 0, 0, navBarInset)); + } return mAppHeaderCoordinator.onApplyWindowInsets(mSpyRootView, windowInsetsBuilder.build()); } }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java index b67779cec..2872d69 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallback.java
@@ -135,9 +135,14 @@ } // Zero out (consume) the ime insets; we're applying them ourselves so no one else needs - // to consume them. + // to consume them. Additionally, we will also consume nav bar insets because we have at + // least one other inset consumer that might otherwise use the nav bar inset incorrectly + // when the ime is visible and only the ime insets are consumed here. This is based on the + // assumption that both the ime and nav bar are present at the bottom of the app window. + // TODO (crbug.com/388037271): Remove nav bar inset consumption. return new WindowInsetsCompat.Builder(windowInsetsCompat) .setInsets(WindowInsetsCompat.Type.ime(), Insets.NONE) + .setInsets(WindowInsetsCompat.Type.navigationBars(), Insets.NONE) .build(); }
diff --git a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java index 23255cc..2dc422c8 100644 --- a/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java +++ b/chrome/browser/ui/android/omnibox/java/src/org/chromium/chrome/browser/omnibox/DeferredIMEWindowInsetApplicationCallbackTest.java
@@ -79,6 +79,8 @@ WindowInsetsCompat modifiedInsets = mCallback.onApplyWindowInsets(mView, windowInsets); assertEquals(Insets.NONE, modifiedInsets.getInsets(WindowInsetsCompat.Type.ime())); + assertEquals( + Insets.NONE, modifiedInsets.getInsets(WindowInsetsCompat.Type.navigationBars())); verify(mUpdateRunnable, never()).run(); mCallback.onEnd(mAnimation);
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index ef875b69..a67bac9 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -4416,6 +4416,9 @@ <message name="IDS_MENU_SWITCH_OUT_OF_INCOGNITO" desc="Menu item for switching out of incognito."> Switch out of Incognito </message> + <message name="IDS_MENU_OPEN_WITH" desc="Menu item to open the content with another app."> + Open with… + </message> <!-- Bookmarks strings --> <message name="IDS_BOOKMARKS" desc="Title of the bookmarks page, which shows a list of the user's bookmarks. [CHAR_LIMIT=18]">
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_OPEN_WITH.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_OPEN_WITH.png.sha1 new file mode 100644 index 0000000..4cf25ff --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_MENU_OPEN_WITH.png.sha1
@@ -0,0 +1 @@ +2addbbf0e6837923402dd35617fa7b920b6be94d \ 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 cab9383..475eabf 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
@@ -2214,7 +2214,7 @@ public void onIncognitoStateChanged() { // Set the correct branded color scheme tinting for the {@link TabSwitcherDrawable} whenever // the incognito state changes. - setTabSwitcherDrawableColorScheme(isIncognitoBranded()); + setTabSwitcherDrawableColorScheme(); } @Override @@ -2225,6 +2225,10 @@ private void onTabCountChanged(int numberOfTabs) { mHomeButton.setEnabled(true); + setTabSwitcherDrawableColorScheme(); + } + + private void setTabSwitcherDrawableColorScheme() { if (getTabSwitcherButtonCoordinator() != null) { // In some use cases, isIncognitoBranded() will return a stale value for whether the // current view is in incognito. The mismatched value will result in the retrieval of @@ -2237,16 +2241,13 @@ if (isIncognitoSupplier != null) { isIncognito = isIncognitoSupplier.get(); } - setTabSwitcherDrawableColorScheme(isIncognito); - } - } - private void setTabSwitcherDrawableColorScheme(boolean isIncognito) { - @BrandedColorScheme - int overlayTabStackDrawableScheme = - OmniboxResourceProvider.getBrandedColorScheme( - getContext(), isIncognito, getTabThemeColor()); - getTabSwitcherButtonCoordinator().setBrandedColorScheme(overlayTabStackDrawableScheme); + @BrandedColorScheme + int overlayTabStackDrawableScheme = + OmniboxResourceProvider.getBrandedColorScheme( + getContext(), isIncognito, getTabThemeColor()); + getTabSwitcherButtonCoordinator().setBrandedColorScheme(overlayTabStackDrawableScheme); + } } /**
diff --git a/chrome/browser/ui/ash/assistant/BUILD.gn b/chrome/browser/ui/ash/assistant/BUILD.gn index 0526c125..73605542 100644 --- a/chrome/browser/ui/ash/assistant/BUILD.gn +++ b/chrome/browser/ui/ash/assistant/BUILD.gn
@@ -55,6 +55,7 @@ "//chromeos/ash/services/bluetooth_config/public/mojom", "//chromeos/dbus/power", "//chromeos/dbus/power:power_manager_proto", + "//chromeos/services/assistant/public/shared:new_entry_point_constants", "//components/language/core/browser", "//components/session_manager/core", "//content/public/browser",
diff --git a/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc b/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc index 42b414f..6a423a4 100644 --- a/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc +++ b/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.cc
@@ -45,6 +45,7 @@ #include "chromeos/ash/services/assistant/public/cpp/features.h" #include "chromeos/ash/services/assistant/public/mojom/assistant_audio_decoder.mojom.h" #include "chromeos/services/assistant/public/shared/constants.h" +#include "chromeos/services/assistant/public/shared/new_entry_point_constants.h" #include "components/session_manager/core/session_manager.h" #include "components/user_manager/user_manager.h" #include "content/public/browser/audio_service.h" @@ -323,6 +324,10 @@ apps::LaunchSource::kUnknown)); } +int AssistantBrowserDelegateImpl::GetNewEntryPointIconResourceId() { + return chromeos::assistant::kIconResourceId; +} + #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) void AssistantBrowserDelegateImpl::RequestLibassistantService( mojo::PendingReceiver<ash::libassistant::mojom::LibassistantService>
diff --git a/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.h b/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.h index df1a9fa..4df74529 100644 --- a/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.h +++ b/chrome/browser/ui/ash/assistant/assistant_browser_delegate_impl.h
@@ -71,6 +71,7 @@ base::expected<bool, AssistantBrowserDelegate::Error> IsNewEntryPointEligibleForPrimaryProfile() override; void OpenNewEntryPoint() override; + int GetNewEntryPointIconResourceId() override; #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) void RequestLibassistantService( mojo::PendingReceiver<ash::libassistant::mojom::LibassistantService>
diff --git a/chrome/browser/ui/autofill/address_bubbles_controller.cc b/chrome/browser/ui/autofill/address_bubbles_controller.cc index b94e4815..332c465 100644 --- a/chrome/browser/ui/autofill/address_bubbles_controller.cc +++ b/chrome/browser/ui/autofill/address_bubbles_controller.cc
@@ -10,12 +10,10 @@ #include <vector> #include "base/check.h" -#include "base/functional/bind.h" #include "base/memory/weak_ptr.h" #include "base/strings/string_util.h" #include "base/strings/utf_string_conversions.h" #include "base/types/optional_util.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/autofill/ui/ui_util.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/profiles/profile.h" @@ -34,8 +32,6 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/grit/theme_resources.h" #include "components/autofill/content/browser/content_autofill_client.h" -#include "components/autofill/core/browser/data_manager/addresses/address_data_manager.h" -#include "components/autofill/core/browser/data_manager/personal_data_manager.h" #include "components/autofill/core/browser/data_model/autofill_profile.h" #include "components/autofill/core/browser/field_types.h" #include "components/autofill/core/browser/ui/addresses/autofill_address_util.h" @@ -80,15 +76,14 @@ } #if BUILDFLAG(ENABLE_DICE_SUPPORT) -AutofillBubbleBase* ShowSignInPromo( - content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> move_address_callback) { +AutofillBubbleBase* ShowSignInPromo(content::WebContents* web_contents, + const AutofillProfile& autofill_profile) { // TODO(crbug.com/381390420): Expose the `AutofillBubbleHandler` in // `BrowserWindowInterface` and use that instead. return chrome::FindBrowserWithTab(web_contents) ->window() ->GetAutofillBubbleHandler() - ->ShowAddressSignInPromo(web_contents, std::move(move_address_callback)); + ->ShowAddressSignInPromo(web_contents, autofill_profile); } #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) @@ -285,34 +280,11 @@ return; } - // Prepare the move callback that is executed upon sign in. - auto move_address_callback = base::BindOnce( - [](const std::string& guid, content::WebContents* web_contents) { - AddressDataManager& address_data_manager = - PersonalDataManagerFactory::GetForBrowserContext( - web_contents->GetBrowserContext()) - ->address_data_manager(); - const AutofillProfile* autofill_profile = - address_data_manager.GetProfileByGUID(guid); - - // Do nothing if the address was not found, e.g. if it was deleted - // during the sign in process. - if (!autofill_profile) { - return; - } - - // At this point, the address should be local. - CHECK(!autofill_profile->IsAccountProfile()); - address_data_manager.MigrateProfileToAccount(*autofill_profile); - }, - autofill_profile.value().guid()); - // Close the current save bubble. HideBubble(); // Open the bubble with the sign in promo. - set_bubble_view( - ShowSignInPromo(web_contents(), std::move(move_address_callback))); + set_bubble_view(ShowSignInPromo(web_contents(), autofill_profile.value())); CHECK(bubble_view()); is_showing_sign_in_promo_ = true; UpdatePageActionIcon();
diff --git a/chrome/browser/ui/autofill/autofill_bubble_handler.h b/chrome/browser/ui/autofill/autofill_bubble_handler.h index a66fbf96..74ecab95 100644 --- a/chrome/browser/ui/autofill/autofill_bubble_handler.h +++ b/chrome/browser/ui/autofill/autofill_bubble_handler.h
@@ -19,6 +19,7 @@ } namespace autofill { +class AutofillProfile; class AutofillBubbleBase; class LocalCardMigrationBubbleController; class OfferNotificationBubbleController; @@ -86,8 +87,7 @@ #if BUILDFLAG(ENABLE_DICE_SUPPORT) virtual AutofillBubbleBase* ShowAddressSignInPromo( content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> - move_address_callback) = 0; + const AutofillProfile& autofill_profile) = 0; #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) // Opens an update address bubble. The bubble's lifecycle is controlled by its
diff --git a/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.cc b/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.cc index 42f1090..845e03ec 100644 --- a/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.cc +++ b/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.cc
@@ -4,98 +4,32 @@ #include "chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.h" -#include "base/containers/fixed_flat_map.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/signin/signin_ui_util.h" #include "chrome/browser/signin/signin_util.h" #include "chrome/browser/sync/sync_service_factory.h" #include "chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.h" -#include "chrome/browser/ui/browser_finder.h" #include "chrome/browser/ui/tabs/public/tab_interface.h" #include "chrome/common/buildflags.h" #include "components/prefs/pref_service.h" #include "components/signin/public/base/signin_switches.h" #include "components/sync/base/data_type.h" #include "components/sync/service/sync_service.h" -#include "components/sync/service/sync_service_observer.h" namespace { -// Modify this when sign in promos for other data types are added. -constexpr auto kAccessPointToDataTypeMap = - base::MakeFixedFlatMap<signin_metrics::AccessPoint, syncer::DataType>( - {{signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE, - syncer::PASSWORDS}, - {signin_metrics::AccessPoint::ACCESS_POINT_ADDRESS_BUBBLE, - syncer::CONTACT_INFO}}); -// Used for attaching the uploader to a profile. -const void* const kSignInPromoDataUploaderChecker = - &kSignInPromoDataUploaderChecker; - -// Used to perform the necessary preliminary checks to know whether we can -// proceed with the upload of the data to account store through the -// `move_callback`. Depending on the sync service's status, it may wait for the -// sync service to be initialized, which is necessary since we may have just -// signed in. -class SignInPromoDataUploaderChecker : public base::SupportsUserData::Data, - public syncer::SyncServiceObserver { - public: - explicit SignInPromoDataUploaderChecker( - content::WebContents* web_contents, - Profile* profile, - syncer::DataType data_type, - base::OnceCallback<void(content::WebContents*)> move_callback) - : web_contents_(web_contents->GetWeakPtr()), - profile_(profile->GetWeakPtr()), - data_type_(data_type), - move_callback_(std::move(move_callback)) { - syncer::SyncService* sync_service = - SyncServiceFactory::GetForProfile(profile_.get()); - - // If the data type is already available, move the data right away. If not, - // wait for the sync service to be activated. - if (sync_service->GetActiveDataTypes().Has(data_type_) && web_contents_) { - std::move(move_callback_).Run(web_contents_.get()); - profile_->RemoveUserData(kSignInPromoDataUploaderChecker); - return; - } - - sync_service_observer_.Observe(sync_service); +syncer::DataType GetDataTypeFromAccessPoint( + signin_metrics::AccessPoint access_point) { + switch (access_point) { + case signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE: + return syncer::PASSWORDS; + case signin_metrics::AccessPoint::ACCESS_POINT_ADDRESS_BUBBLE: + return syncer::CONTACT_INFO; + default: + NOTREACHED(); } - ~SignInPromoDataUploaderChecker() override = default; - - void OnStateChanged(syncer::SyncService* sync_service) override { - // Do nothing if the sync service is not ready yet. - if (sync_service->GetTransportState() != - syncer::SyncService::TransportState::ACTIVE) { - return; - } - - // If the data type is available in the sync service, move the data to the - // account store. If not, keep it in local storage. - if (sync_service->GetActiveDataTypes().Has(data_type_) && web_contents_) { - std::move(move_callback_).Run(web_contents_.get()); - } - - sync_service_observer_.Reset(); - profile_->RemoveUserData(kSignInPromoDataUploaderChecker); - } - - void OnSyncShutdown(syncer::SyncService* sync_service) override { - sync_service_observer_.Reset(); - profile_->RemoveUserData(kSignInPromoDataUploaderChecker); - } - - private: - const base::WeakPtr<content::WebContents> web_contents_; - const base::WeakPtr<Profile> profile_; - const syncer::DataType data_type_; - base::OnceCallback<void(content::WebContents*)> move_callback_; - - base::ScopedObservation<syncer::SyncService, syncer::SyncServiceObserver> - sync_service_observer_{this}; -}; +} } // namespace @@ -104,8 +38,8 @@ AutofillBubbleSignInPromoController::AutofillBubbleSignInPromoController( content::WebContents& web_contents, signin_metrics::AccessPoint access_point, - base::OnceCallback<void(content::WebContents*)> move_callback) - : move_callback_(std::move(move_callback)), + syncer::LocalDataItemModel::DataId data_id) + : data_id_(std::move(data_id)), web_contents_(web_contents.GetWeakPtr()), access_point_(access_point) {} @@ -127,25 +61,18 @@ signin_util::SignedInState signed_in_state = signin_util::GetSignedInState( IdentityManagerFactory::GetForProfile(profile)); - // Make sure the access point is valid. - CHECK(kAccessPointToDataTypeMap.contains(access_point_)); - syncer::DataType data_type = kAccessPointToDataTypeMap.at(access_point_); - auto maybe_move_data = base::BindOnce( - [](base::OnceCallback<void(content::WebContents*)> move_callback, - syncer::DataType data_type, content::WebContents* web_contents) { - Profile* profile = - Profile::FromBrowserContext(web_contents->GetBrowserContext()); - profile->SetUserData( - kSignInPromoDataUploaderChecker, - std::make_unique<SignInPromoDataUploaderChecker>( - web_contents, profile, data_type, std::move(move_callback))); + [](Profile* profile, syncer::DataType data_type, + syncer::LocalDataItemModel::DataId data_id) { + SyncServiceFactory::GetForProfile(profile) + ->SelectTypeAndMigrateLocalDataItemsWhenActive( + data_type, {std::move(data_id)}); }, - std::move(move_callback_), data_type); + profile, GetDataTypeFromAccessPoint(access_point_), std::move(data_id_)); // If the sign in was already successful, move the data directly. if (signed_in_state == signin_util::SignedInState::kSignedIn) { - std::move(maybe_move_data).Run(web_contents_.get()); + std::move(maybe_move_data).Run(); return; }
diff --git a/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.h b/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.h index 2992ff03..c2c1f287 100644 --- a/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.h +++ b/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.h
@@ -5,8 +5,8 @@ #ifndef CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_BUBBLE_SIGNIN_PROMO_CONTROLLER_H_ #define CHROME_BROWSER_UI_AUTOFILL_AUTOFILL_BUBBLE_SIGNIN_PROMO_CONTROLLER_H_ -#include "base/functional/callback.h" #include "base/memory/weak_ptr.h" +#include "components/sync/service/local_data_description.h" struct AccountInfo; namespace signin { @@ -30,7 +30,7 @@ explicit AutofillBubbleSignInPromoController( content::WebContents& web_contents, signin_metrics::AccessPoint access_point, - base::OnceCallback<void(content::WebContents*)> move_callback); + syncer::LocalDataItemModel::DataId data_id); ~AutofillBubbleSignInPromoController(); // Called by the view when the "Sign in" button in the promo bubble is @@ -42,7 +42,7 @@ private: // Used to move the local data item to the account storage once the sign in // has been completed. - base::OnceCallback<void(content::WebContents*)> move_callback_; + const syncer::LocalDataItemModel::DataId data_id_; base::WeakPtr<content::WebContents> web_contents_; signin_metrics::AccessPoint access_point_; };
diff --git a/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller_unittest.cc b/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller_unittest.cc index b364bb77..e4e5f96 100644 --- a/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller_unittest.cc +++ b/chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller_unittest.cc
@@ -3,164 +3,89 @@ // found in the LICENSE file. #include "chrome/browser/ui/autofill/autofill_bubble_signin_promo_controller.h" -#include "base/test/mock_callback.h" #include "chrome/browser/signin/identity_manager_factory.h" #include "chrome/browser/sync/sync_service_factory.h" -#include "chrome/test/base/chrome_render_view_host_test_harness.h" -#include "components/signin/public/base/signin_metrics.h" +#include "chrome/test/base/testing_profile.h" #include "components/signin/public/base/signin_switches.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/identity_test_utils.h" -#include "components/sync/test/test_sync_service.h" +#include "components/sync/service/local_data_description.h" +#include "components/sync/test/mock_sync_service.h" +#include "content/public/browser/web_contents.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" namespace { -std::unique_ptr<KeyedService> BuildTestSyncService( +std::unique_ptr<KeyedService> BuildMockSyncService( content::BrowserContext* context) { - return std::make_unique<syncer::TestSyncService>(); + return std::make_unique<testing::NiceMock<syncer::MockSyncService>>(); } } // namespace -class AutofillBubbleSignInPromoControllerTest - : public ChromeRenderViewHostTestHarness { +class AutofillBubbleSignInPromoControllerTest : public testing::Test { public: - void SetUp() override; + AutofillBubbleSignInPromoControllerTest() : id_("test_id") { + TestingProfile::Builder profile_builder; + profile_builder.AddTestingFactory( + SyncServiceFactory::GetInstance(), + base::BindRepeating(&BuildMockSyncService)); + profile_ = profile_builder.Build(); - void TearDown() override { - sync_service_ = nullptr; - ChromeRenderViewHostTestHarness::TearDown(); + web_contents_ = content::WebContentsTester::CreateTestWebContents( + profile_.get(), nullptr); } - autofill::AutofillBubbleSignInPromoController* autofill_bubble_controller() { - return autofill_bubble_controller_.get(); + syncer::MockSyncService* sync_service_mock() { + return static_cast<syncer::MockSyncService*>( + SyncServiceFactory::GetForProfile(profile_.get())); } - base::MockCallback<base::OnceCallback<void(content::WebContents*)>> - mock_callback_; - raw_ptr<syncer::TestSyncService> sync_service_; + signin::IdentityManager* identity_manager() { + return IdentityManagerFactory::GetForProfile(profile_.get()); + } + + std::vector<syncer::LocalDataItemModel::DataId> ids() { return {id_}; } + content::WebContents& web_contents() { return *web_contents_.get(); } private: base::test::ScopedFeatureList feature_list_{ - switches::kExplicitBrowserSigninUIOnDesktop}; - std::unique_ptr<autofill::AutofillBubbleSignInPromoController> - autofill_bubble_controller_; + switches::kImprovedSigninUIOnDesktop}; + content::BrowserTaskEnvironment task_environment_; + content::RenderViewHostTestEnabler render_view_host_test_enabler_; + syncer::LocalDataItemModel::DataId id_; + std::unique_ptr<TestingProfile> profile_; + std::unique_ptr<content::WebContents> web_contents_; }; -void AutofillBubbleSignInPromoControllerTest::SetUp() { - ChromeRenderViewHostTestHarness::SetUp(); - - autofill_bubble_controller_ = +// TODO(crbug.com/388025216): Enable this test. +TEST_F(AutofillBubbleSignInPromoControllerTest, + DISABLED_DataMigrationTriggeredWithExistingAccount) { + auto autofill_bubble_controller = std::make_unique<autofill::AutofillBubbleSignInPromoController>( - *web_contents(), - signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE, - mock_callback_.Get()); - - sync_service_ = static_cast<syncer::TestSyncService*>( - SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( - profile(), base::BindRepeating(&BuildTestSyncService))); -} - -TEST_F(AutofillBubbleSignInPromoControllerTest, - MovesPasswordUponSignInWithExistingAccountAndPasswordsEnabled) { - // First, the sync service is inactive. - sync_service_->SetMaxTransportState( - syncer::SyncService::TransportState::CONFIGURING); + web_contents(), + signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE, ids()[0]); // Simulate a sign in to the web. - signin::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile()); - AccountInfo account_info = signin::MakeAccountAvailable( - identity_manager, + identity_manager(), signin::AccountAvailabilityOptionsBuilder() .WithAccessPoint(signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN) .Build("test@gmail.com")); - { - // Check that the move callback will not be called until the sync service is - // ready. - EXPECT_CALL(mock_callback_, Run(web_contents())).Times(0); - autofill_bubble_controller()->OnSignInToChromeClicked(account_info); - } - - // Enable passwords for the sync service. - sync_service_->SetMaxTransportState( - syncer::SyncService::TransportState::ACTIVE); - sync_service_->GetUserSettings()->SetSelectedType( - syncer::UserSelectableType::kPasswords, true); - - // Check that the move callback will be called this time. - EXPECT_CALL(mock_callback_, Run(web_contents())); - - // Now firing a state changed event should trigger a password move. - sync_service_->FireStateChanged(); - - // Check that the user was signed in to Chrome. - EXPECT_TRUE( - identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)); -} - -TEST_F(AutofillBubbleSignInPromoControllerTest, - DoesNotMovePasswordWhenSyncServiceIsInactive) { - // Set the sync service as inactive. - sync_service_->SetMaxTransportState( - syncer::SyncService::TransportState::CONFIGURING); - - // Simulate a sign in to the web. - signin::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile()); - - AccountInfo account_info = signin::MakeAccountAvailable( - identity_manager, - signin::AccountAvailabilityOptionsBuilder() - .WithAccessPoint(signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN) - .Build("test@gmail.com")); - - // Check that the move callback will not be called. - EXPECT_CALL(mock_callback_, Run(web_contents())).Times(0); + // Check that the data migration will be triggered. + EXPECT_CALL( + *sync_service_mock(), + SelectTypeAndMigrateLocalDataItemsWhenActive(syncer::PASSWORDS, ids())) + .Times(1); // This should sign in the user to Chrome directly, as there is already an // account on the web. - autofill_bubble_controller()->OnSignInToChromeClicked(account_info); - - // Also firing a state changed event should not trigger a password move. - sync_service_->FireStateChanged(); + autofill_bubble_controller->OnSignInToChromeClicked(account_info); // Check that the user was signed in to Chrome. EXPECT_TRUE( - identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)); -} - -TEST_F(AutofillBubbleSignInPromoControllerTest, - DoesNotMovePasswordUponSignInWithExistingAccountAndPasswordsDisabled) { - // Disable passwords for the sync service, but make sure it is active. - sync_service_->GetUserSettings()->SetSelectedType( - syncer::UserSelectableType::kPasswords, false); - sync_service_->SetMaxTransportState( - syncer::SyncService::TransportState::ACTIVE); - - // Simulate a sign in to the web. - signin::IdentityManager* identity_manager = - IdentityManagerFactory::GetForProfile(profile()); - - AccountInfo account_info = signin::MakeAccountAvailable( - identity_manager, - signin::AccountAvailabilityOptionsBuilder() - .WithAccessPoint(signin_metrics::AccessPoint::ACCESS_POINT_WEB_SIGNIN) - .Build("test@gmail.com")); - - // Check that the move callback will not be called. - EXPECT_CALL(mock_callback_, Run(web_contents())).Times(0); - - // This should sign in the user to Chrome directly, as there is already an - // account on the web. It should not trigger a password move. - autofill_bubble_controller()->OnSignInToChromeClicked(account_info); - - // Also firing a state changed event should not trigger a password move. - sync_service_->FireStateChanged(); - - // Check that the user was signed in to Chrome. - EXPECT_TRUE( - identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)); + identity_manager()->HasPrimaryAccount(signin::ConsentLevel::kSignin)); }
diff --git a/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.cc b/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.cc index c2a88ae..a6145370 100644 --- a/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.cc +++ b/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.cc
@@ -56,7 +56,7 @@ } void AutofillSigninPromoTabHelper::InitializeDataMoveAfterSignIn( - base::OnceCallback<void(content::WebContents*)> move_callback, + base::OnceClosure move_callback, signin_metrics::AccessPoint access_point, base::TimeDelta time_limit) { signin::IdentityManager* identity_manager = @@ -126,7 +126,7 @@ return; } // Initiate data move if requirements are met. - std::move(state_->move_callback_).Run(web_contents_); + std::move(state_->move_callback_).Run(); Reset(); } @@ -167,7 +167,7 @@ } // Initiate data move if requirements are met. - std::move(state_->move_callback_).Run(web_contents_); + std::move(state_->move_callback_).Run(); Reset(); }
diff --git a/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.h b/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.h index 68d6336..99b0824d 100644 --- a/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.h +++ b/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper.h
@@ -38,7 +38,7 @@ // |access_point| within the |time_limit|, the |move_callback| will be // executed. void InitializeDataMoveAfterSignIn( - base::OnceCallback<void(content::WebContents*)> move_callback, + base::OnceClosure move_callback, signin_metrics::AccessPoint access_point, base::TimeDelta time_limit = base::Minutes(50)); @@ -69,9 +69,7 @@ base::ScopedObservation<signin::IdentityManager, signin::IdentityManager::Observer> identity_manager_observation_; - std::unique_ptr<password_manager::MovePasswordToAccountStoreHelper> - move_helper_; - base::OnceCallback<void(content::WebContents*)> move_callback_; + base::OnceClosure move_callback_; signin_metrics::AccessPoint access_point_ = signin_metrics::AccessPoint::ACCESS_POINT_UNKNOWN; base::Time initialization_time_;
diff --git a/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper_browsertest.cc b/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper_browsertest.cc index 571a2dd8..e05cb5f 100644 --- a/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper_browsertest.cc +++ b/chrome/browser/ui/autofill/autofill_signin_promo_tab_helper_browsertest.cc
@@ -37,9 +37,10 @@ signin_ui_util::GetSignInTabWithAccessPoint( browser(), signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE); - // Initialize the data move and expect a callback call. - base::MockOnceCallback<void(content::WebContents*)> move_callback; - EXPECT_CALL(move_callback, Run(sign_in_tab)).Times(1); + // Expect the callback for enabling account storage and moving the data to be + // called. + base::MockOnceClosure move_callback; + EXPECT_CALL(move_callback, Run()).Times(1); autofill::AutofillSigninPromoTabHelper* user_data = autofill::AutofillSigninPromoTabHelper::GetForWebContents(*sign_in_tab); @@ -73,9 +74,10 @@ signin_ui_util::GetSignInTabWithAccessPoint( browser(), signin_metrics::AccessPoint::ACCESS_POINT_ADDRESS_BUBBLE); - // Initialize the data move and expect a callback call. - base::MockOnceCallback<void(content::WebContents*)> move_callback; - EXPECT_CALL(move_callback, Run(reauth_tab)).Times(1); + // Expect the callback for enabling account storage and moving the data to be + // called. + base::MockOnceClosure move_callback; + EXPECT_CALL(move_callback, Run()).Times(1); autofill::AutofillSigninPromoTabHelper* user_data = autofill::AutofillSigninPromoTabHelper::GetForWebContents(*reauth_tab);
diff --git a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc index 145eec2..44543f0 100644 --- a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc +++ b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.cc
@@ -69,7 +69,7 @@ #if BUILDFLAG(ENABLE_DICE_SUPPORT) AutofillBubbleBase* TestAutofillBubbleHandler::ShowAddressSignInPromo( content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> move_address_callback) { + const AutofillProfile& autofill_profile) { if (!address_sign_in_promo_bubble_view_) { address_sign_in_promo_bubble_view_ = std::make_unique<TestAutofillBubble>(); }
diff --git a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h index 90c0faa..71ea8c12 100644 --- a/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h +++ b/chrome/browser/ui/autofill/test/test_autofill_bubble_handler.h
@@ -61,8 +61,7 @@ #if BUILDFLAG(ENABLE_DICE_SUPPORT) AutofillBubbleBase* ShowAddressSignInPromo( content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> move_address_callback) - override; + const AutofillProfile& autofill_profile) override; #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) AutofillBubbleBase* ShowFilledCardInformationBubble( content::WebContents* web_contents,
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index b632aab..ecb8b8f 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/ui/browser_commands.h" #include <memory> +#include <numeric> #include <optional> #include <utility> #include <vector>
diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h index d07c247..eb020cb 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.h
@@ -69,8 +69,6 @@ NSStatusItem* item(); NSStatusItem* __strong item_; - StatusItemController* __strong controller_; - // Notification balloon. DesktopNotificationBalloon notification_;
diff --git a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm index 7398a5ea..e5c6870b 100644 --- a/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm +++ b/chrome/browser/ui/cocoa/status_icons/status_icon_mac.mm
@@ -5,6 +5,9 @@ #include "chrome/browser/ui/cocoa/status_icons/status_icon_mac.h" #import <AppKit/AppKit.h> +#include <Foundation/Foundation.h> +#include <objc/message.h> +#include <objc/runtime.h> #include "base/check.h" #include "base/mac/mac_util.h" @@ -17,67 +20,146 @@ #import "ui/menus/cocoa/menu_controller.h" #include "ui/message_center/public/cpp/notifier_id.h" -@interface StatusItemController : NSObject { +constexpr char kStatusItemControllerKey[] = "StatusItemController"; + +// This class bridges between the Objective-C API for status items and the C++ +// classes integrating with Chromium. Owned by the NSStatusBarButton as an +// associated object with the key kStatusItemControllerKey. +@interface StatusItemController : NSObject +// Designated initializer. +- (instancetype)initWithStatusIconMac:(StatusIconMac*)icon + forStatusBarButton:(NSStatusBarButton*)button; + +// Returns the StatusItemController that is responsible for the specified +// `button`. ++ (instancetype)controllerForButton:(NSStatusBarButton*)button; + +// Clears all internal state. +- (void)reset; + +// Handles left mouse clicks. Takes a single parameter so that it can be the +// "action" of a "target/action" pair. +- (void)handleClick:(id)sender; +@end + +@implementation StatusItemController { raw_ptr<StatusIconMac> _statusIcon; // weak } -- (instancetype)initWithIcon:(StatusIconMac*)icon; -- (void)handleClick:(id)sender; -@end // @interface StatusItemController ++ (void)initialize { + // Ensure any future possible subclasses don't cause this to be called more + // than once. + if (self != [StatusItemController class]) { + return; + } -@implementation StatusItemController + // NSStatusBarButton implements -rightMouseDown: by spinning its own event + // loop. What that practically means, though, is that the status bar item + // stays highlighted even after the mouse-up, and a subsequent + // right-mouse-down unhighlights the button but doesn't trigger an action. + // This is an issue in Cocoa known by the community; see posts such as: + // + // https://www.jessesquires.com/blog/2019/08/16/workaround-highlight-bug-nsstatusitem/ + // https://stackoverflow.com/questions/59635971/show-nsmenu-only-on-nsstatusbarbutton-right-click + // + // The standard workaround in these posts is to trigger the desired UI action + // with the right-mouse-up rather than the right-mouse-down. While that's the + // simplest workaround, that's not desirable. + // + // One might consider subclassing NSStatusBarButton to override + // -rightMouseDown: and then use that subclass instead. Unfortunately, that + // proposal is thwarted because the `button` property of NSStatusItem is + // read-only. + // + // Therefore, swizzle the -[NSStatusBarButton rightMouseDown:] method to gain + // control and achieve the desired behavior. + IMP imp = imp_implementationWithBlock(^(id object_self, NSEvent* event) { + StatusItemController* controller = + [StatusItemController controllerForButton:object_self]; + [controller handleClick:nil isRightButton:YES]; + }); -- (instancetype)initWithIcon:(StatusIconMac*)icon { + class_replaceMethod([NSStatusBarButton class], @selector(rightMouseDown:), + imp, nullptr); +} + +- (instancetype)initWithStatusIconMac:(StatusIconMac*)icon + forStatusBarButton:(NSStatusBarButton*)button { + objc_setAssociatedObject(button, kStatusItemControllerKey, self, + OBJC_ASSOCIATION_RETAIN); + _statusIcon = icon; return self; } -- (void)handleClick:(id)sender { - DCHECK(_statusIcon); ++ (instancetype)controllerForButton:(NSStatusBarButton*)button { + return objc_getAssociatedObject(button, kStatusItemControllerKey); +} - // Bring up the status icon menu if there is one, relay the click event - // otherwise. +- (void)reset { + _statusIcon = nullptr; +} + +- (void)handleClick:(id)sender { + [self handleClick:sender isRightButton:NO]; +} + +- (void)handleClick:(id)sender isRightButton:(BOOL)isRightButton { + CHECK(_statusIcon); + if (!_statusIcon->HasStatusIconMenu()) { + // If there is no menu at all, just dispatch the click. _statusIcon->DispatchClickEvent(); } else if (_statusIcon->open_menu_with_secondary_click()) { - NSEvent* event = [NSApp currentEvent]; + // Otherwise, there is a menu. For "open menu with a secondary click", plain + // left-clicks are dispatched normally, and secondary clicks open the menu. + NSEvent* event = NSApp.currentEvent; BOOL secondary_click = - ([event type] == NSEventTypeLeftMouseDown && - [event modifierFlags] & NSEventModifierFlagControl) || - ([event type] == NSEventTypeRightMouseUp); + isRightButton || (event.type == NSEventTypeLeftMouseDown && + event.modifierFlags & NSEventModifierFlagControl); if (secondary_click) { _statusIcon->CreateAndOpenMenu(); - } else if ([event type] == NSEventTypeLeftMouseDown) { + } else if (event.type == NSEventTypeLeftMouseDown) { _statusIcon->DispatchClickEvent(); } } + // There is no "else" here. If there is a menu, but it's not opened with a + // secondary click, it is set as the menu property on the item and code flow + // never gets here. } @end -StatusIconMac::StatusIconMac() { - controller_ = [[StatusItemController alloc] initWithIcon:this]; -} +StatusIconMac::StatusIconMac() = default; StatusIconMac::~StatusIconMac() { - // Remove the status item from the status bar. + // If there is a status item, remove it from the status bar. if (item_) { + // The controller has a raw_ptr to this object, so clear the pointer. + // (Because it's not guaranteed that the association is the sole/last + // reference to the controller, clearing the association is not sufficient.) + StatusItemController* controller = + [StatusItemController controllerForButton:item_.button]; + [controller reset]; [NSStatusBar.systemStatusBar removeStatusItem:item_]; } } NSStatusItem* StatusIconMac::item() { if (!item_) { - // Create a new status item. item_ = [NSStatusBar.systemStatusBar statusItemWithLength:NSSquareStatusItemLength]; - NSButton* item_button = item_.button; + NSStatusBarButton* item_button = item_.button; item_button.enabled = YES; - item_button.target = controller_; - item_button.action = @selector(handleClick:); NSButtonCell* item_button_cell = item_button.cell; item_button_cell.highlightsBy = NSContentsCellMask | NSChangeBackgroundCellMask; + + StatusItemController* controller = + [[StatusItemController alloc] initWithStatusIconMac:this + forStatusBarButton:item_button]; + item_button.target = controller; + item_button.action = @selector(handleClick:); } return item_; } @@ -115,8 +197,8 @@ void StatusIconMac::SetOpenMenuWithSecondaryClick( bool open_menu_with_secondary_click) { open_menu_with_secondary_click_ = open_menu_with_secondary_click; - [[item() button] - sendActionOn:(NSEventMaskLeftMouseDown | NSEventMaskRightMouseUp)]; + [item().button + sendActionOn:(NSEventMaskLeftMouseDown | NSEventMaskRightMouseDown)]; } void StatusIconMac::OnMenuStateChanged() { @@ -130,8 +212,8 @@ void StatusIconMac::CreateAndOpenMenu() { CreateMenu(menu_model_, nil); - [[item() button] performClick:nil]; - [item() setMenu:nil]; + [item().button performClick:nil]; + item().menu = nil; } void StatusIconMac::UpdatePlatformContextMenu(StatusIconMenuModel* model) {
diff --git a/chrome/browser/ui/color/OWNERS b/chrome/browser/ui/color/OWNERS index e0b1e6e..92598d0 100644 --- a/chrome/browser/ui/color/OWNERS +++ b/chrome/browser/ui/color/OWNERS
@@ -2,4 +2,5 @@ per-file new_tab_page_color_mixer*=file://chrome/browser/ui/webui/new_tab_page/OWNERS per-file material_new_tab_page_color_mixer*=file://chrome/browser/ui/webui/new_tab_page/OWNERS +per-file product_specifications_color_mixer*=file://chrome/browser/ui/webui/commerce/OWNERS per-file chrome_color_id.h=*
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index 7437311..350aac5 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -424,6 +424,9 @@ /* Product Specifications colors */ \ E_CPONLY(kColorProductSpecificationsButtonBackground) \ E_CPONLY(kColorProductSpecificationsCitationBackground) \ + E_CPONLY(kColorProductSpecificationsCitationPopupBackground) \ + E_CPONLY(kColorProductSpecificationsCitationPopupText) \ + E_CPONLY(kColorProductSpecificationsCitationPopupTitle) \ E_CPONLY(kColorProductSpecificationsComparisonTableListBackground) \ E_CPONLY(kColorProductSpecificationsDetailChipBackground) \ E_CPONLY(kColorProductSpecificationsDisclosureBackground) \
diff --git a/chrome/browser/ui/color/product_specifications_color_mixer.cc b/chrome/browser/ui/color/product_specifications_color_mixer.cc index 21f8a12..a0c80d9a 100644 --- a/chrome/browser/ui/color/product_specifications_color_mixer.cc +++ b/chrome/browser/ui/color/product_specifications_color_mixer.cc
@@ -16,6 +16,12 @@ mixer[kColorProductSpecificationsButtonBackground] = {ui::kColorSysSurface2}; mixer[kColorProductSpecificationsCitationBackground] = { ui::kColorSysBaseContainer}; + mixer[kColorProductSpecificationsCitationPopupBackground] = { + ui::kColorSysSurface1}; + mixer[kColorProductSpecificationsCitationPopupText] = { + ui::kColorSysOnSurfaceSubtle}; + mixer[kColorProductSpecificationsCitationPopupTitle] = { + ui::kColorSysOnSurface}; mixer[kColorProductSpecificationsComparisonTableListBackground] = { ui::kColorSysSurface5}; mixer[kColorProductSpecificationsDetailChipBackground] = {
diff --git a/chrome/browser/ui/commerce/commerce_ui_tab_helper.cc b/chrome/browser/ui/commerce/commerce_ui_tab_helper.cc index 98128fa5..38d2b8b 100644 --- a/chrome/browser/ui/commerce/commerce_ui_tab_helper.cc +++ b/chrome/browser/ui/commerce/commerce_ui_tab_helper.cc
@@ -145,7 +145,7 @@ return; } - if (service->IsPriceInsightsEligible()) { + if (commerce::IsPriceInsightsEligible(service->GetAccountChecker())) { UpdatePriceInsightsIconView(); } } @@ -187,7 +187,11 @@ discounts_page_action_controller_->ResetForNewNavigation( web_contents()->GetLastCommittedURL()); - if (shopping_service_->IsPriceInsightsEligible()) { + // This value should not be a class member variable as it might change within + // a browser session. + bool is_price_insights_eligible = + commerce::IsPriceInsightsEligible(shopping_service_->GetAccountChecker()); + if (is_price_insights_eligible) { UpdatePriceInsightsIconView(); } @@ -197,7 +201,7 @@ product_specifications_controller_->ResetForNewNavigation( web_contents()->GetLastCommittedURL()); - if (shopping_service_->IsPriceInsightsEligible()) { + if (is_price_insights_eligible) { // Price insights needs product info to get the product cluster title. shopping_service_->GetProductInfoForUrl( web_contents()->GetLastCommittedURL(), @@ -239,7 +243,8 @@ return; } - if (shopping_service_->IsPriceInsightsEligible()) { + if (commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker())) { UpdatePriceInsightsIconView(); } UpdatePriceTrackingIconView(); @@ -265,7 +270,9 @@ } bool CommerceUiTabHelper::ShouldShowPriceInsightsIconView() { - return shopping_service_ && shopping_service_->IsPriceInsightsEligible() && + return shopping_service_ && + commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker()) && price_insights_info_.has_value(); } @@ -287,7 +294,8 @@ product_info_for_page_ = info; - if (shopping_service_->IsPriceInsightsEligible()) { + if (commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker())) { if (!info->product_cluster_title.empty()) { shopping_service_->GetPriceInsightsInfoForUrl( url, @@ -328,10 +336,11 @@ return; } - if (shopping_service_->IsPriceInsightsEligible() && - !got_insights_response_for_page_) { - return; - } + if (commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker()) && + !got_insights_response_for_page_) { + return; + } if (!price_tracking_controller_->ShouldShowForNavigation().has_value()) { return;
diff --git a/chrome/browser/ui/commerce/commerce_ui_tab_helper_unittest.cc b/chrome/browser/ui/commerce/commerce_ui_tab_helper_unittest.cc index a47470a..d6efeca 100644 --- a/chrome/browser/ui/commerce/commerce_ui_tab_helper_unittest.cc +++ b/chrome/browser/ui/commerce/commerce_ui_tab_helper_unittest.cc
@@ -10,6 +10,7 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "base/test/scoped_feature_list.h" #include "chrome/browser/ui/tabs/test/mock_tab_interface.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" #include "chrome/browser/ui/views/side_panel/side_panel_registry.h" @@ -18,6 +19,7 @@ #include "components/bookmarks/browser/bookmark_model.h" #include "components/bookmarks/test/test_bookmark_client.h" #include "components/commerce/core/commerce_feature_list.h" +#include "components/commerce/core/mock_account_checker.h" #include "components/commerce/core/mock_shopping_service.h" #include "components/commerce/core/price_tracking_utils.h" #include "components/commerce/core/shopping_service.h" @@ -77,11 +79,13 @@ public: CommerceUiTabHelperTest() : shopping_service_(std::make_unique<MockShoppingService>()), - image_fetcher_(std::make_unique<image_fetcher::MockImageFetcher>()) { + image_fetcher_(std::make_unique<image_fetcher::MockImageFetcher>()), + account_checker_(std::make_unique<MockAccountChecker>()) { auto client = std::make_unique<bookmarks::TestBookmarkClient>(); client->SetIsSyncFeatureEnabledIncludingBookmarks(true); bookmark_model_ = bookmarks::TestBookmarkClient::CreateModelWithClient(std::move(client)); + shopping_service_->SetAccountChecker(account_checker_.get()); } CommerceUiTabHelperTest(const CommerceUiTabHelperTest&) = delete; @@ -149,6 +153,8 @@ std::unique_ptr<image_fetcher::MockImageFetcher> image_fetcher_; tabs::MockTabInterface tab_interface_; std::unique_ptr<SidePanelRegistry> side_panel_registry_; + std::unique_ptr<MockAccountChecker> account_checker_; + base::test::ScopedFeatureList features_; private: TestingProfile profile_; @@ -240,7 +246,8 @@ ASSERT_FALSE(side_panel_registry_->GetEntryForKey( SidePanelEntry::Key(SidePanelEntry::Id::kShoppingInsights))); - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); std::optional<ProductInfo> product_info = CreateProductInfo( kClusterId, GURL(kProductImageUrl), kProductClusterTitle); @@ -264,7 +271,8 @@ SidePanelEntry::Key(SidePanelEntry::Id::kShoppingInsights))); shopping_service_->SetResponseForGetProductInfoForUrl(std::nullopt); - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); SimulateNavigationCommitted(GURL(kProductUrl)); @@ -276,7 +284,8 @@ TEST_F(CommerceUiTabHelperTest, TestPriceInsightsIconNotAvailableIfEmptyProductInfo) { - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); shopping_service_->SetResponseForGetProductInfoForUrl(std::nullopt); SimulateNavigationCommitted(GURL(kProductUrl)); @@ -287,7 +296,8 @@ TEST_F(CommerceUiTabHelperTest, TestPriceInsightsIconNotAvailableIfNoProductClusterTitle) { - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); std::optional<ProductInfo> info = CreateProductInfo(kClusterId, GURL(kProductImageUrl)); @@ -302,7 +312,8 @@ TEST_F(CommerceUiTabHelperTest, TestRecordShoppingInformationUKM) { ukm::TestAutoSetUkmRecorder ukm_recorder; - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); std::optional<ProductInfo> product_info = CreateProductInfo( kClusterId, GURL(kProductImageUrl), kProductClusterTitle);
diff --git a/chrome/browser/ui/lens/lens_overlay_controller.cc b/chrome/browser/ui/lens/lens_overlay_controller.cc index 9a39c9c..bce46d5 100644 --- a/chrome/browser/ui/lens/lens_overlay_controller.cc +++ b/chrome/browser/ui/lens/lens_overlay_controller.cc
@@ -15,6 +15,7 @@ #include "base/system/sys_info.h" #include "base/task/bind_post_task.h" #include "base/task/sequenced_task_runner.h" +#include "base/task/thread_pool.h" #include "chrome/browser/feedback/show_feedback_page.h" #include "chrome/browser/lens/core/mojom/geometry.mojom.h" #include "chrome/browser/lens/core/mojom/overlay_object.mojom.h"
diff --git a/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.cc b/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.cc index 9d4dfe9..d5ac3012 100644 --- a/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.cc +++ b/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.cc
@@ -27,14 +27,13 @@ password_manager::IsPasswordChangeSupported(details.leak_type)), metrics_recorder_(std::move(metrics_recorder)) {} -CredentialLeakDialogControllerImpl::~CredentialLeakDialogControllerImpl() { - ResetDialog(); -} +CredentialLeakDialogControllerImpl::~CredentialLeakDialogControllerImpl() = + default; void CredentialLeakDialogControllerImpl::ShowCredentialLeakPrompt( - CredentialLeakPrompt* dialog) { + std::unique_ptr<CredentialLeakPrompt> dialog) { DCHECK(dialog); - credential_leak_dialog_ = dialog; + credential_leak_dialog_ = std::move(dialog); credential_leak_dialog_->ShowCredentialLeakPrompt(); } @@ -71,10 +70,7 @@ } void CredentialLeakDialogControllerImpl::ResetDialog() { - if (credential_leak_dialog_) { - credential_leak_dialog_->ControllerGone(); - credential_leak_dialog_ = nullptr; - } + credential_leak_dialog_.reset(); } std::u16string CredentialLeakDialogControllerImpl::GetAcceptButtonLabel()
diff --git a/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.h b/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.h index d07e104..66c1526 100644 --- a/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.h +++ b/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_PASSWORDS_CREDENTIAL_LEAK_DIALOG_CONTROLLER_IMPL_H_ #define CHROME_BROWSER_UI_PASSWORDS_CREDENTIAL_LEAK_DIALOG_CONTROLLER_IMPL_H_ +#include <memory> + #include "base/memory/raw_ptr.h" #include "chrome/browser/ui/passwords/credential_leak_dialog_controller.h" #include "components/password_manager/core/browser/leak_detection_dialog_utils.h" @@ -32,7 +34,7 @@ ~CredentialLeakDialogControllerImpl() override; // Pop up the credential leak dialog. - void ShowCredentialLeakPrompt(CredentialLeakPrompt* dialog); + void ShowCredentialLeakPrompt(std::unique_ptr<CredentialLeakPrompt> dialog); // CredentialLeakDialogController: bool IsShowingAccountChooser() const override; @@ -48,7 +50,7 @@ bool ShouldShowCancelButton() const override; private: - raw_ptr<CredentialLeakPrompt> credential_leak_dialog_ = nullptr; + std::unique_ptr<CredentialLeakPrompt> credential_leak_dialog_; raw_ptr<PasswordsLeakDialogDelegate> delegate_; std::unique_ptr<password_manager::LeakDialogTraits> leak_dialog_traits_; GURL url_;
diff --git a/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl_unittest.cc b/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl_unittest.cc index ef92498..7861596 100644 --- a/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl_unittest.cc +++ b/chrome/browser/ui/passwords/credential_leak_dialog_controller_impl_unittest.cc
@@ -21,6 +21,9 @@ #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" +namespace views { +class Widget; +} namespace { constexpr ukm::SourceId kTestSourceId = 0x1234; @@ -48,7 +51,7 @@ MockCredentialLeakPrompt& operator=(const MockCredentialLeakPrompt&) = delete; MOCK_METHOD(void, ShowCredentialLeakPrompt, (), (override)); - MOCK_METHOD(void, ControllerGone, (), (override)); + MOCK_METHOD(views::Widget*, GetWidgetForTesting, (), (override)); }; class CredentialLeakDialogControllerTest : public testing::Test { @@ -66,6 +69,10 @@ std::move(recorder)); } + std::unique_ptr<StrictMock<MockCredentialLeakPrompt>> SetupLeakPrompt() { + return std::make_unique<StrictMock<MockCredentialLeakPrompt>>(); + } + base::HistogramTester& histogram_tester() { return histogram_tester_; } PasswordsLeakDialogDelegateMock& ui_controller_mock() { @@ -76,8 +83,6 @@ return test_ukm_recorder_; } - MockCredentialLeakPrompt& leak_prompt() { return leak_prompt_; } - CredentialLeakDialogControllerImpl& controller() { return *controller_; } private: @@ -85,7 +90,6 @@ base::HistogramTester histogram_tester_; ukm::TestAutoSetUkmRecorder test_ukm_recorder_; StrictMock<PasswordsLeakDialogDelegateMock> ui_controller_mock_; - StrictMock<MockCredentialLeakPrompt> leak_prompt_; std::unique_ptr<CredentialLeakDialogControllerImpl> controller_; }; @@ -110,8 +114,10 @@ SetUpController( CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(false))); - EXPECT_CALL(leak_prompt(), ShowCredentialLeakPrompt()); - controller().ShowCredentialLeakPrompt(&leak_prompt()); + auto leak_prompt = SetupLeakPrompt(); + + EXPECT_CALL(*leak_prompt, ShowCredentialLeakPrompt()); + controller().ShowCredentialLeakPrompt(std::move(leak_prompt)); EXPECT_CALL(ui_controller_mock(), OnLeakDialogHidden()); controller().OnCloseDialog(); @@ -126,16 +132,16 @@ CheckUkmMetricsExpectations(test_ukm_recorder(), LeakDialogType::kChange, LeakDialogDismissalReason::kNoDirectInteraction); - - EXPECT_CALL(leak_prompt(), ControllerGone()); } TEST_F(CredentialLeakDialogControllerTest, CredentialLeakDialogOk) { SetUpController( CreateLeakType(IsSaved(true), IsReused(false), IsSyncing(false))); - EXPECT_CALL(leak_prompt(), ShowCredentialLeakPrompt()); - controller().ShowCredentialLeakPrompt(&leak_prompt()); + auto leak_prompt = SetupLeakPrompt(); + + EXPECT_CALL(*leak_prompt, ShowCredentialLeakPrompt()); + controller().ShowCredentialLeakPrompt(std::move(leak_prompt)); EXPECT_CALL(ui_controller_mock(), OnLeakDialogHidden()); controller().OnAcceptDialog(); @@ -150,16 +156,16 @@ CheckUkmMetricsExpectations(test_ukm_recorder(), LeakDialogType::kChange, LeakDialogDismissalReason::kClickedOk); - - EXPECT_CALL(leak_prompt(), ControllerGone()); } TEST_F(CredentialLeakDialogControllerTest, CredentialLeakDialogCancel) { SetUpController( CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true))); - EXPECT_CALL(leak_prompt(), ShowCredentialLeakPrompt()); - controller().ShowCredentialLeakPrompt(&leak_prompt()); + auto leak_prompt = SetupLeakPrompt(); + + EXPECT_CALL(*leak_prompt, ShowCredentialLeakPrompt()); + controller().ShowCredentialLeakPrompt(std::move(leak_prompt)); EXPECT_CALL(ui_controller_mock(), OnLeakDialogHidden()); controller().OnCancelDialog(); @@ -175,16 +181,16 @@ CheckUkmMetricsExpectations(test_ukm_recorder(), LeakDialogType::kCheckupAndChange, LeakDialogDismissalReason::kClickedClose); - - EXPECT_CALL(leak_prompt(), ControllerGone()); } TEST_F(CredentialLeakDialogControllerTest, CredentialLeakDialogCheckPasswords) { SetUpController( CreateLeakType(IsSaved(true), IsReused(true), IsSyncing(true))); - EXPECT_CALL(leak_prompt(), ShowCredentialLeakPrompt()); - controller().ShowCredentialLeakPrompt(&leak_prompt()); + auto leak_prompt = SetupLeakPrompt(); + + EXPECT_CALL(*leak_prompt, ShowCredentialLeakPrompt()); + controller().ShowCredentialLeakPrompt(std::move(leak_prompt)); EXPECT_CALL( ui_controller_mock(), @@ -204,23 +210,22 @@ CheckUkmMetricsExpectations( test_ukm_recorder(), LeakDialogType::kCheckup, LeakDialogDismissalReason::kClickedCheckPasswords); - - EXPECT_CALL(leak_prompt(), ControllerGone()); } TEST_F(CredentialLeakDialogControllerTest, PasswordChangeStarted) { SetUpController(CreateLeakType(IsSaved(false), IsReused(false), IsSyncing(true), HasChangePasswordUrl(true))); - EXPECT_CALL(leak_prompt(), ShowCredentialLeakPrompt()); - controller().ShowCredentialLeakPrompt(&leak_prompt()); + auto leak_prompt = SetupLeakPrompt(); + + EXPECT_CALL(*leak_prompt, ShowCredentialLeakPrompt()); + controller().ShowCredentialLeakPrompt(std::move(leak_prompt)); EXPECT_CALL(ui_controller_mock(), ChangePassword(GURL(kUrl), std::u16string(kUsername), std::u16string(kPassword))); EXPECT_CALL(ui_controller_mock(), OnLeakDialogHidden()); controller().OnAcceptDialog(); - EXPECT_CALL(leak_prompt(), ControllerGone()); } TEST_F(CredentialLeakDialogControllerTest, PasswordChangeNotStarted) { @@ -229,14 +234,15 @@ SetUpController(CreateLeakType(IsSaved(false), IsReused(true), IsSyncing(true), HasChangePasswordUrl(true))); - EXPECT_CALL(leak_prompt(), ShowCredentialLeakPrompt()); - controller().ShowCredentialLeakPrompt(&leak_prompt()); + auto leak_prompt = SetupLeakPrompt(); + + EXPECT_CALL(*leak_prompt, ShowCredentialLeakPrompt()); + controller().ShowCredentialLeakPrompt(std::move(leak_prompt)); EXPECT_CALL(ui_controller_mock(), ChangePassword).Times(0); EXPECT_CALL(ui_controller_mock(), NavigateToPasswordCheckup); EXPECT_CALL(ui_controller_mock(), OnLeakDialogHidden()); controller().OnAcceptDialog(); - EXPECT_CALL(leak_prompt(), ControllerGone()); } } // namespace
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc index abf83f2..c06450b3 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.cc
@@ -1200,7 +1200,8 @@ return CreateAutoSigninPromptView(controller, web_contents()); } -CredentialLeakPrompt* ManagePasswordsUIController::CreateCredentialLeakPrompt( +std::unique_ptr<CredentialLeakPrompt> +ManagePasswordsUIController::CreateCredentialLeakPrompt( CredentialLeakDialogController* controller) { return CreateCredentialLeakPromptView(controller, web_contents()); }
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h index 53c1987..f014e039 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller.h +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller.h
@@ -247,7 +247,7 @@ CredentialManagerDialogController* controller); // Called to create the credentials leaked dialog. - virtual CredentialLeakPrompt* CreateCredentialLeakPrompt( + virtual std::unique_ptr<CredentialLeakPrompt> CreateCredentialLeakPrompt( CredentialLeakDialogController* controller); // Check if |web_contents()| is attached to some Browser. Mocked in tests.
diff --git a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc index fec856df..b403002 100644 --- a/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc +++ b/chrome/browser/ui/passwords/manage_passwords_ui_controller_unittest.cc
@@ -84,6 +84,9 @@ using ::testing::ReturnRef; using ::testing::SaveArg; +namespace views { +class Widget; +} namespace { MATCHER_P3(MatchesLoginAndURL, @@ -116,7 +119,7 @@ class PasswordLeakDialogMock : public CredentialLeakPrompt { public: MOCK_METHOD(void, ShowCredentialLeakPrompt, (), (override)); - MOCK_METHOD(void, ControllerGone, (), (override)); + MOCK_METHOD(views::Widget*, GetWidgetForTesting, (), (override)); }; class TestManagePasswordsIconView : public ManagePasswordsIconView { @@ -173,7 +176,7 @@ CreateAutoSigninPrompt, (CredentialManagerDialogController*), (override)); - MOCK_METHOD(CredentialLeakPrompt*, + MOCK_METHOD(std::unique_ptr<CredentialLeakPrompt>, CreateCredentialLeakPrompt, (CredentialLeakDialogController*), (override)); @@ -1656,11 +1659,12 @@ EXPECT_TRUE(controller()->opened_automatic_bubble()); // Leak detection dialog hides the bubble. - PasswordLeakDialogMock dialog_prompt; + auto dialog_prompt = std::make_unique<PasswordLeakDialogMock>(); CredentialLeakDialogController* dialog_controller = nullptr; + EXPECT_CALL(*dialog_prompt, ShowCredentialLeakPrompt); EXPECT_CALL(*controller(), CreateCredentialLeakPrompt) - .WillOnce(DoAll(SaveArg<0>(&dialog_controller), Return(&dialog_prompt))); - EXPECT_CALL(dialog_prompt, ShowCredentialLeakPrompt); + .WillOnce(DoAll(SaveArg<0>(&dialog_controller), + Return(std::move(dialog_prompt)))); controller()->OnCredentialLeak(password_manager::LeakedPasswordDetails( password_manager::CreateLeakType(password_manager::IsSaved(false), password_manager::IsReused(false), @@ -1678,7 +1682,6 @@ Return(base::span<const password_manager::InteractionsStats>())); // Close the dialog. - EXPECT_CALL(dialog_prompt, ControllerGone); EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); dialog_controller->OnAcceptDialog(); @@ -1698,11 +1701,12 @@ EXPECT_FALSE(controller()->opened_automatic_bubble()); // Leak detection dialog hides the bubble. - PasswordLeakDialogMock dialog_prompt; + auto dialog_prompt = std::make_unique<PasswordLeakDialogMock>(); CredentialLeakDialogController* dialog_controller = nullptr; + EXPECT_CALL(*dialog_prompt, ShowCredentialLeakPrompt); EXPECT_CALL(*controller(), CreateCredentialLeakPrompt) - .WillOnce(DoAll(SaveArg<0>(&dialog_controller), Return(&dialog_prompt))); - EXPECT_CALL(dialog_prompt, ShowCredentialLeakPrompt); + .WillOnce(DoAll(SaveArg<0>(&dialog_controller), + Return(std::move(dialog_prompt)))); controller()->OnCredentialLeak(password_manager::LeakedPasswordDetails( password_manager::CreateLeakType(password_manager::IsSaved(false), password_manager::IsReused(false), @@ -1717,7 +1721,6 @@ EXPECT_CALL(*form_manager_ptr, IsBlocklisted()).WillOnce(Return(true)); // Close the dialog. - EXPECT_CALL(dialog_prompt, ControllerGone); EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); dialog_controller->OnAcceptDialog(); @@ -1735,11 +1738,13 @@ EXPECT_TRUE(controller()->opened_automatic_bubble()); // Leak detection dialog hides the bubble. - PasswordLeakDialogMock dialog_prompt; + auto dialog_prompt = std::make_unique<PasswordLeakDialogMock>(); + auto* dialog_prompt_ptr = dialog_prompt.get(); CredentialLeakDialogController* dialog_controller = nullptr; EXPECT_CALL(*controller(), CreateCredentialLeakPrompt) - .WillOnce(DoAll(SaveArg<0>(&dialog_controller), Return(&dialog_prompt))); - EXPECT_CALL(dialog_prompt, ShowCredentialLeakPrompt); + .WillOnce(DoAll(SaveArg<0>(&dialog_controller), + Return(std::move(dialog_prompt)))); + EXPECT_CALL(*dialog_prompt_ptr, ShowCredentialLeakPrompt); controller()->OnCredentialLeak(password_manager::LeakedPasswordDetails( password_manager::CreateLeakType(password_manager::IsSaved(true), password_manager::IsReused(false), @@ -1750,7 +1755,6 @@ EXPECT_FALSE(controller()->opened_automatic_bubble()); // Close the dialog. - EXPECT_CALL(dialog_prompt, ControllerGone); EXPECT_CALL(*controller(), OnUpdateBubbleAndIconVisibility()); dialog_controller->OnAcceptDialog();
diff --git a/chrome/browser/ui/passwords/password_dialog_prompts.h b/chrome/browser/ui/passwords/password_dialog_prompts.h index d9bf3294..d858fcd 100644 --- a/chrome/browser/ui/passwords/password_dialog_prompts.h +++ b/chrome/browser/ui/passwords/password_dialog_prompts.h
@@ -5,12 +5,18 @@ #ifndef CHROME_BROWSER_UI_PASSWORDS_PASSWORD_DIALOG_PROMPTS_H_ #define CHROME_BROWSER_UI_PASSWORDS_PASSWORD_DIALOG_PROMPTS_H_ +#include <memory> + #include "third_party/skia/include/core/SkColor.h" namespace content { class WebContents; } +namespace views { +class Widget; +} + class CredentialLeakDialogController; class CredentialManagerDialogController; @@ -55,17 +61,17 @@ public: CredentialLeakPrompt(const CredentialLeakPrompt&) = delete; CredentialLeakPrompt& operator=(const CredentialLeakPrompt&) = delete; + virtual ~CredentialLeakPrompt() = default; // Shows the dialog. virtual void ShowCredentialLeakPrompt() = 0; - // Notifies the UI element that its controller is no longer managing the UI - // element. The dialog should close. - virtual void ControllerGone() = 0; + // Returns the underlying Widget associated with the on-screen prompt. For + // Testing Only! + virtual views::Widget* GetWidgetForTesting() = 0; protected: CredentialLeakPrompt() = default; - virtual ~CredentialLeakPrompt() = default; }; // Factory function for AccountChooserPrompt on desktop platforms. @@ -79,7 +85,7 @@ content::WebContents* web_contents); // Factory function for CredentialsLeakedPrompt on desktop platforms. -CredentialLeakPrompt* CreateCredentialLeakPromptView( +std::unique_ptr<CredentialLeakPrompt> CreateCredentialLeakPromptView( CredentialLeakDialogController* controller, content::WebContents* web_contents);
diff --git a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc index f5230b01..f5861cd 100644 --- a/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc +++ b/chrome/browser/ui/sync/profile_signin_confirmation_helper_unittest.cc
@@ -16,7 +16,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "base/run_loop.h" -#include "base/strings/string_util.h" +#include "base/strings/span_printf.h" #include "base/strings/utf_string_conversions.h" #include "build/build_config.h" #include "build/chromeos_buildflags.h" @@ -246,7 +246,7 @@ profile_->SetIsNewProfile(true); char buf[18]; for (int i = 0; i < 10; i++) { - base::snprintf(buf, std::size(buf), "http://foo.com/%d", i); + base::SpanPrintf(buf, "http://foo.com/%d", i); history->AddPage(GURL(std::string(buf)), base::Time::Now(), /*context_id=*/{}, 1, GURL(), history::RedirectList(), ui::PAGE_TRANSITION_LINK, history::SOURCE_BROWSED, false);
diff --git a/chrome/browser/ui/tabs/features.cc b/chrome/browser/ui/tabs/features.cc index 980167e..adfca06 100644 --- a/chrome/browser/ui/tabs/features.cc +++ b/chrome/browser/ui/tabs/features.cc
@@ -49,7 +49,7 @@ // vector in the tabstrip model. b/323937237 BASE_FEATURE(kTabStripCollectionStorage, "TabStripCollectionStorage", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); bool CanShowTabSearchPositionSetting() { // The combo button, which includes tab search, is always on the right side
diff --git a/chrome/browser/ui/task_manager/task_manager_table_model.cc b/chrome/browser/ui/task_manager/task_manager_table_model.cc index 932f924b..2dbff18 100644 --- a/chrome/browser/ui/task_manager/task_manager_table_model.cc +++ b/chrome/browser/ui/task_manager/task_manager_table_model.cc
@@ -912,7 +912,8 @@ return observed_task_manager()->IsTaskKillable(tasks_[row_index]); } -void TaskManagerTableModel::RetrieveSavedColumnsSettingsAndUpdateTable() { +void TaskManagerTableModel::RetrieveSavedColumnsSettingsAndUpdateTable( + bool default_sorted_column_to_cpu) { if (!g_browser_process->local_state()) { return; } @@ -948,6 +949,13 @@ if (sorted_col_id && *sorted_col_id == col_id_key) { table_view_delegate_->SetSortDescriptor( TableSortDescriptor(col_id, sort_is_ascending)); + } else if (default_sorted_column_to_cpu && !sorted_col_id && + col_id_key == + GetColumnIdAsString(IDS_TASK_MANAGER_CPU_COLUMN)) { + // If there is no user selected column, the sorting default should be + // the CPU column if it's visible. + table_view_delegate_->SetSortDescriptor( + TableSortDescriptor(IDS_TASK_MANAGER_CPU_COLUMN, false)); } } }
diff --git a/chrome/browser/ui/task_manager/task_manager_table_model.h b/chrome/browser/ui/task_manager/task_manager_table_model.h index bbc89b0..afd53c6 100644 --- a/chrome/browser/ui/task_manager/task_manager_table_model.h +++ b/chrome/browser/ui/task_manager/task_manager_table_model.h
@@ -123,7 +123,8 @@ // Restores the saved columns settings from a previous session into // |columns_settings_| and updates the table view. - void RetrieveSavedColumnsSettingsAndUpdateTable(); + void RetrieveSavedColumnsSettingsAndUpdateTable( + bool default_sorted_column_to_cpu = false); // Stores the current values in |column_settings_| to the user prefs so that // it can be restored later next time the task manager view is opened.
diff --git a/chrome/browser/ui/toasts/BUILD.gn b/chrome/browser/ui/toasts/BUILD.gn index 82b1596..9d6a9d0 100644 --- a/chrome/browser/ui/toasts/BUILD.gn +++ b/chrome/browser/ui/toasts/BUILD.gn
@@ -93,6 +93,10 @@ "//ui/views", "//ui/views:test_support", ] + + if (use_ozone) { + deps += [ "//ui/ozone" ] + } } source_set("browser_tests") {
diff --git a/chrome/browser/ui/toasts/toast_controller_interactive_ui_test.cc b/chrome/browser/ui/toasts/toast_controller_interactive_ui_test.cc index ead171b..609ec3f71 100644 --- a/chrome/browser/ui/toasts/toast_controller_interactive_ui_test.cc +++ b/chrome/browser/ui/toasts/toast_controller_interactive_ui_test.cc
@@ -53,6 +53,10 @@ #include "ui/views/view.h" #include "ui/views/widget/widget.h" +#if BUILDFLAG(IS_OZONE) +#include "ui/ozone/public/ozone_platform.h" +#endif + namespace { DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kFirstTab); DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kSecondTab); @@ -349,6 +353,12 @@ // closes. IN_PROC_BROWSER_TEST_F(ToastControllerInteractiveTest, ToastDoesNotCloseWhileMenuIsOpen) { +#if BUILDFLAG(IS_OZONE) + if (ui::OzonePlatform::GetPlatformNameForTest() == "wayland") { + GTEST_SKIP() << "Flaky in Wayland due to way events are routed and bounds " + "are reported"; + } +#endif ToastParams params(ToastId::kPlusAddressOverride); params.menu_model = std::make_unique<TestMenuModel>(base::DoNothing()); RunTestSequence(ShowToast(std::move(params)), @@ -365,6 +375,12 @@ // Tests that clicking the menu button twice closes the menu, but not the toast. IN_PROC_BROWSER_TEST_F(ToastControllerInteractiveTest, TwoClicksOnMenuButton) { +#if BUILDFLAG(IS_OZONE) + if (ui::OzonePlatform::GetPlatformNameForTest() == "wayland") { + GTEST_SKIP() << "Flaky in Wayland due to way events are routed and bounds " + "are reported"; + } +#endif RunTestSequence( ShowToast(ToastParams(ToastId::kLinkCopied)), WaitForShow(toasts::ToastView::kToastViewId),
diff --git a/chrome/browser/ui/views/autofill/address_sign_in_promo_view.cc b/chrome/browser/ui/views/autofill/address_sign_in_promo_view.cc index f3b67ec5..42778cffc 100644 --- a/chrome/browser/ui/views/autofill/address_sign_in_promo_view.cc +++ b/chrome/browser/ui/views/autofill/address_sign_in_promo_view.cc
@@ -18,7 +18,7 @@ AddressSignInPromoView::AddressSignInPromoView( views::View* anchor_view, content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> move_address_callback) + const AutofillProfile& autofill_profile) : AddressBubbleBaseView(anchor_view, web_contents) { SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone)); SetTitle(IDS_AUTOFILL_SIGNIN_PROMO_TITLE_ADDRESS); @@ -34,7 +34,7 @@ // Show the sign in promo. AddChildView(std::make_unique<AutofillBubbleSignInPromoView>( web_contents, signin_metrics::AccessPoint::ACCESS_POINT_ADDRESS_BUBBLE, - std::move(move_address_callback))); + syncer::LocalDataItemModel::DataId(autofill_profile.guid()))); } AddressSignInPromoView::~AddressSignInPromoView() = default;
diff --git a/chrome/browser/ui/views/autofill/address_sign_in_promo_view.h b/chrome/browser/ui/views/autofill/address_sign_in_promo_view.h index f41cdc8..0ac93c5 100644 --- a/chrome/browser/ui/views/autofill/address_sign_in_promo_view.h +++ b/chrome/browser/ui/views/autofill/address_sign_in_promo_view.h
@@ -9,16 +9,17 @@ namespace autofill { +class AutofillProfile; + // This is the sign in promo view that is shown after a user accepted the // address save/update bubble without being signed into Chrome. class AddressSignInPromoView : public AddressBubbleBaseView { public: DECLARE_CLASS_ELEMENT_IDENTIFIER_VALUE(kBubbleFrameViewId); - explicit AddressSignInPromoView( - views::View* anchor_view, - content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> move_address_callback); + explicit AddressSignInPromoView(views::View* anchor_view, + content::WebContents* web_contents, + const AutofillProfile& autofill_profile); AddressSignInPromoView(const AddressSignInPromoView&) = delete; AddressSignInPromoView& operator=(const AddressSignInPromoView&) = delete;
diff --git a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc index 5112065..bd40b657 100644 --- a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc +++ b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.cc
@@ -192,11 +192,11 @@ #if BUILDFLAG(ENABLE_DICE_SUPPORT) AutofillBubbleBase* AutofillBubbleHandlerImpl::ShowAddressSignInPromo( content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> move_address_callback) { + const AutofillProfile& autofill_profile) { views::View* anchor_view = toolbar_button_provider_->GetAnchorView(kActionShowAddressesBubbleOrPage); - AddressSignInPromoView* bubble = new AddressSignInPromoView( - anchor_view, web_contents, std::move(move_address_callback)); + AddressSignInPromoView* bubble = + new AddressSignInPromoView(anchor_view, web_contents, autofill_profile); if (!views::Button::AsButton(anchor_view)) { PageActionIconView* icon_view = toolbar_button_provider_->GetPageActionIconView(
diff --git a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h index 05d3609..e27f7eec 100644 --- a/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h +++ b/chrome/browser/ui/views/autofill/autofill_bubble_handler_impl.h
@@ -71,8 +71,7 @@ #if BUILDFLAG(ENABLE_DICE_SUPPORT) AutofillBubbleBase* ShowAddressSignInPromo( content::WebContents* web_contents, - base::OnceCallback<void(content::WebContents*)> move_address_callback) - override; + const AutofillProfile& autofill_profile) override; #endif // BUILDFLAG(ENABLE_DICE_SUPPORT) AutofillBubbleBase* ShowUpdateAddressProfileBubble( content::WebContents* web_contents,
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc index 388bb0e..4f1e579f 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_bar_view_unittest.cc
@@ -680,7 +680,7 @@ ASSERT_TRUE(button); // The `LabelButton::AddedToWidget()` call only has an effect for bookmark // buttons on certain platforms, so gate the check. - if (views::PlatformStyle::kInactiveWidgetControlsAppearDisabled) { + if constexpr (views::PlatformStyle::kInactiveWidgetControlsAppearDisabled) { EXPECT_TRUE(button->has_paint_as_active_subscription_for_testing()); } }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc index 71c7639..5e212ac 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.cc
@@ -288,6 +288,47 @@ menu_ = node_to_menu_map_[node]; } +void BookmarkMenuDelegate::SetMenuStartIndex(const BookmarkNode* node, + size_t start_index) { + CHECK(!parent_menu_item_); + auto node_to_start_idx = node_start_child_idx_map_.find(node); + const size_t prev_start_idx = + node_to_start_idx == node_start_child_idx_map_.end() + ? 0 + : node_to_start_idx->second; + + if (prev_start_idx == start_index) { + return; + } + + // It's possible the menu hasn't been built yet, so no update is necessary. + auto node_to_menu = node_to_menu_map_.find(node); + if (node_to_menu == node_to_menu_map_.end()) { + return; + } + + CHECK_LE(start_index, node->children().size()); + node_start_child_idx_map_[node] = start_index; + MenuItemView* parent_menu = node_to_menu->second; + + // Remove obsolete bookmark menus if the start index increased. + for (size_t idx = prev_start_idx; idx < start_index; ++idx) { + const BookmarkNode* child_node = node->children()[idx].get(); + if (auto child_node_to_menu = node_to_menu_map_.find(child_node); + child_node_to_menu != node_to_menu_map_.end()) { + RemoveBookmarkNode(child_node, child_node_to_menu->second); + } + } + + // Add missing bookmark menus if the start index decreased. + for (size_t idx = start_index; idx < prev_start_idx; ++idx) { + const BookmarkNode* child_node = node->children()[idx].get(); + AddBookmarkNode(child_node, parent_menu, idx); + } + + parent_menu->ChildrenChanged(); +} + std::u16string BookmarkMenuDelegate::GetTooltipText( int id, const gfx::Point& screen_loc) const {
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h index 269a772..4f947a0 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate.h
@@ -73,6 +73,11 @@ // the first child of |node| to show in the menu. void SetActiveMenu(const bookmarks::BookmarkNode* node, size_t start_index); + // Updates the start index of the given `node` and updates its menu + // accordingly. + void SetMenuStartIndex(const bookmarks::BookmarkNode* node, + size_t start_index); + // Returns the id given to the next menu. int next_menu_id() const { return next_menu_id_; }
diff --git a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc index 88a02bd..d942e8d 100644 --- a/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc +++ b/chrome/browser/ui/views/bookmarks/bookmark_menu_delegate_unittest.cc
@@ -815,3 +815,65 @@ 0); EXPECT_EQ(2u, root_menu->GetSubmenu()->GetMenuItems().size()); } + +TEST_F(BookmarkMenuDelegateTest, IncreaseStartIndex) { + const BookmarkNode* bookmark_bar_node = model()->bookmark_bar_node(); + ASSERT_EQ(3u, bookmark_bar_node->children().size()); + + NewDelegate(); + bookmark_menu_delegate_->SetActiveMenu(bookmark_bar_node, 0); + views::MenuItemView* root_menu = menu(); + // The menu has items for nodes, a, F1 and F2. + EXPECT_EQ(3u, root_menu->GetSubmenu()->GetMenuItems().size()); + + // Increasing the start index should remove the first nodes. + bookmark_menu_delegate_->SetMenuStartIndex(bookmark_bar_node, 2); + ASSERT_TRUE(root_menu->HasSubmenu()); + ASSERT_EQ(1u, root_menu->GetSubmenu()->GetMenuItems().size()); + EXPECT_EQ(u"F2", root_menu->GetSubmenu()->GetMenuItemAt(0)->title()); +} + +TEST_F(BookmarkMenuDelegateTest, DecreaseStartIndex) { + const BookmarkNode* bookmark_bar_node = model()->bookmark_bar_node(); + ASSERT_EQ(3u, bookmark_bar_node->children().size()); + + NewDelegate(); + bookmark_menu_delegate_->SetActiveMenu(bookmark_bar_node, 2); + views::MenuItemView* root_menu = menu(); + ASSERT_TRUE(root_menu->HasSubmenu()); + EXPECT_EQ(1u, root_menu->GetSubmenu()->GetMenuItems().size()); + + // Decreasing the starting should add the missing nodes. + bookmark_menu_delegate_->SetMenuStartIndex(bookmark_bar_node, 1); + ASSERT_TRUE(root_menu->HasSubmenu()); + ASSERT_EQ(2u, root_menu->GetSubmenu()->GetMenuItems().size()); + EXPECT_EQ(u"F1", root_menu->GetSubmenu()->GetMenuItemAt(0)->title()); + EXPECT_EQ(u"F2", root_menu->GetSubmenu()->GetMenuItemAt(1)->title()); +} + +TEST_F(BookmarkMenuDelegateTest, SetMenuStartIndexUnchanged) { + const BookmarkNode* bookmark_bar_node = model()->bookmark_bar_node(); + ASSERT_EQ(3u, bookmark_bar_node->children().size()); + + NewDelegate(); + bookmark_menu_delegate_->SetActiveMenu(bookmark_bar_node, 2); + views::MenuItemView* root_menu = menu(); + ASSERT_TRUE(root_menu->HasSubmenu()); + EXPECT_EQ(1u, root_menu->GetSubmenu()->GetMenuItems().size()); + + // Nothing should happen if the index is unchanged. + bookmark_menu_delegate_->SetMenuStartIndex(bookmark_bar_node, 2); + ASSERT_TRUE(root_menu->HasSubmenu()); + EXPECT_EQ(1u, root_menu->GetSubmenu()->GetMenuItems().size()); +} + +TEST_F(BookmarkMenuDelegateTest, SetMenuStartIndexForMissingMenu) { + const BookmarkNode* bookmark_bar_node = model()->bookmark_bar_node(); + ASSERT_EQ(3u, bookmark_bar_node->children().size()); + + NewDelegate(); + + // Nothing should happen if the menu wasn't built yet. + bookmark_menu_delegate_->SetMenuStartIndex(bookmark_bar_node, 2); + EXPECT_EQ(nullptr, menu()); +}
diff --git a/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc index 47fb36b..5863d164 100644 --- a/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/commerce/price_insights_icon_view_interactive_uitest.cc
@@ -15,6 +15,8 @@ #include "chrome/test/base/ui_test_utils.h" #include "chrome/test/user_education/interactive_feature_promo_test.h" #include "components/commerce/core/commerce_feature_list.h" +#include "components/commerce/core/feature_utils.h" +#include "components/commerce/core/mock_account_checker.h" #include "components/commerce/core/mock_shopping_service.h" #include "components/commerce/core/test_utils.h" #include "components/feature_engagement/public/feature_constants.h" @@ -98,6 +100,7 @@ std::optional<commerce::PriceInsightsInfo> price_insights_info_; std::optional<commerce::ProductInfo> product_info_; base::CallbackListSubscription create_services_subscription_; + std::unique_ptr<commerce::MockAccountChecker> mock_account_checker_; bool is_browser_context_services_created{false}; private: @@ -108,6 +111,8 @@ mock_shopping_service_ = static_cast<commerce::MockShoppingService*>( commerce::ShoppingServiceFactory::GetForBrowserContext( browser()->profile())); + mock_account_checker_ = std::make_unique<commerce::MockAccountChecker>(); + mock_shopping_service_->SetAccountChecker(mock_account_checker_.get()); price_insights_info_ = commerce::CreateValidPriceInsightsInfo( true, true, commerce::PriceBucket::kLowPrice); @@ -120,10 +125,8 @@ product_info_->product_cluster_id = 12345L; mock_shopping_service_->SetResponseForGetProductInfoForUrl(product_info_); - EXPECT_CALL(*mock_shopping_service_, IsPriceInsightsEligible) - .Times(testing::AnyNumber()); - - mock_shopping_service_->SetIsPriceInsightsEligible(true); + mock_account_checker_->SetAnonymizedUrlDataCollectionEnabled(true); + ASSERT_TRUE(commerce::IsPriceInsightsEligible(mock_account_checker_.get())); mock_shopping_service_->SetIsShoppingListEligible(false); mock_shopping_service_->SetIsDiscountEligibleToShowOnNavigation(false); @@ -183,8 +186,10 @@ IN_PROC_BROWSER_TEST_F(PriceInsightsIconViewInteractiveTest, IconIsNotHighlightedAfterClicking) { - EXPECT_CALL(*mock_shopping_service_, GetProductInfoForUrl); - EXPECT_CALL(*mock_shopping_service_, GetPriceInsightsInfoForUrl); + EXPECT_CALL(*mock_shopping_service_, GetProductInfoForUrl) + .Times(testing::AnyNumber()); + EXPECT_CALL(*mock_shopping_service_, GetPriceInsightsInfoForUrl) + .Times(testing::AnyNumber()); const bool expected_to_highlight = false;
diff --git a/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc b/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc index 72696401..88b1abdb 100644 --- a/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/commerce/price_tracking_icon_view_interactive_uitest.cc
@@ -185,11 +185,7 @@ product_info_->image_url = GURL("http://example.com/image.png"); mock_shopping_service_->SetResponseForGetProductInfoForUrl(product_info_); - EXPECT_CALL(*mock_shopping_service_, IsPriceInsightsEligible) - .Times(testing::AnyNumber()); - mock_shopping_service_->SetIsShoppingListEligible(true); - mock_shopping_service_->SetIsPriceInsightsEligible(false); mock_shopping_service_->SetIsDiscountEligibleToShowOnNavigation(false); }
diff --git a/chrome/browser/ui/views/frame/browser_caption_button_container_win.cc b/chrome/browser/ui/views/frame/browser_caption_button_container_win.cc index c191836..0593b53 100644 --- a/chrome/browser/ui/views/frame/browser_caption_button_container_win.cc +++ b/chrome/browser/ui/views/frame/browser_caption_button_container_win.cc
@@ -4,6 +4,8 @@ #include "chrome/browser/ui/views/frame/browser_caption_button_container_win.h" +#include <windows.h> + #include <memory> #include "chrome/browser/ui/frame/window_frame_util.h"
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index 0cd1a66..d7096d08f 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -1122,6 +1122,10 @@ // OS with some tabs than the NativeBrowserFrame should have destroyed them. DCHECK_EQ(0, browser_->tab_strip_model()->count()); + // Stop the animation timer explicitly here to avoid running it in a nested + // message loop, which may run by Browser destructor. + loading_animation_timer_.Stop(); + // Immersive mode may need to reparent views before they are removed/deleted. immersive_mode_controller_.reset(); @@ -1622,7 +1626,7 @@ web_app_window_title_->SetText(GetWindowTitle()); InvalidateLayout(); } - if (!IsLoadingAnimationRunning() && CanChangeWindowIcon()) { + if (!loading_animation_timer_.IsRunning() && CanChangeWindowIcon()) { frame_->UpdateWindowIcon(); } } @@ -1662,7 +1666,7 @@ const bool should_animate = is_visible && browser_->tab_strip_model()->TabsNeedLoadingUI(); - if (should_animate == IsLoadingAnimationRunning()) { + if (should_animate == loading_animation_timer_.IsRunning()) { // Early return if the loading animation state doesn't change. return; } @@ -1678,16 +1682,17 @@ loading_animation_tracker_->Start(ash::metrics_util::ForSmoothnessV3( base::BindRepeating(&RecordTabLoadingSmoothness))); #endif - // Loads are happening, and the animation isn't running, so start it. + // Loads are happening, and the timer isn't running, so start it. loading_animation_start_ = base::TimeTicks::Now(); - loading_animation_observation_.Observe(GetWidget()->GetCompositor()); + loading_animation_timer_.Start(FROM_HERE, base::Milliseconds(30), this, + &BrowserView::LoadingAnimationCallback); } else { - loading_animation_observation_.Reset(); + loading_animation_timer_.Stop(); #if BUILDFLAG(IS_CHROMEOS) loading_animation_tracker_->Stop(); #endif // Loads are now complete, update the state if a task was scheduled. - OnAnimationStep(base::TimeTicks::Now()); + LoadingAnimationCallback(); } } @@ -1696,28 +1701,6 @@ loading_animation_state_change_closure_ = std::move(closure); } -void BrowserView::OnAnimationStep(base::TimeTicks timestamp) { - if (GetSupportsTabStrip()) { - // Loading animations are shown in the tab for tabbed windows. Update them - // even if the tabstrip isn't currently visible so they're in the right - // state when it returns. - tabstrip_->UpdateLoadingAnimations(timestamp - loading_animation_start_); - } - - if (ShouldShowWindowIcon()) { - WebContents* web_contents = - browser_->tab_strip_model()->GetActiveWebContents(); - // GetActiveWebContents can return null for example under Purify when - // the animations are running slowly and this function is called on a timer - // through LoadingAnimationCallback. - frame_->UpdateThrobber(web_contents && web_contents->IsLoading()); - } -} - -void BrowserView::OnCompositingShuttingDown(ui::Compositor* compositor) { - loading_animation_observation_.Reset(); -} - gfx::Point BrowserView::GetThemeOffsetFromBrowserView() const { gfx::Point browser_view_origin; const views::View* root_view = this; @@ -1757,8 +1740,8 @@ return BrowserView::DevToolsDockedPlacement::kUnknown; } -bool BrowserView::IsLoadingAnimationRunning() const { - return loading_animation_observation_.IsObserving(); +bool BrowserView::IsLoadingAnimationRunningForTesting() const { + return loading_animation_timer_.IsRunning(); } void BrowserView::SetStarredState(bool is_starred) { @@ -4851,6 +4834,25 @@ #endif // BUILDFLAG(ENABLE_WEBUI_TAB_STRIP) } +void BrowserView::LoadingAnimationCallback() { + if (GetSupportsTabStrip()) { + // Loading animations are shown in the tab for tabbed windows. Update them + // even if the tabstrip isn't currently visible so they're in the right + // state when it returns. + tabstrip_->UpdateLoadingAnimations(base::TimeTicks::Now() - + loading_animation_start_); + } + + if (ShouldShowWindowIcon()) { + WebContents* web_contents = + browser_->tab_strip_model()->GetActiveWebContents(); + // GetActiveWebContents can return null for example under Purify when + // the animations are running slowly and this function is called on a timer + // through LoadingAnimationCallback. + frame_->UpdateThrobber(web_contents && web_contents->IsLoading()); + } +} + #if BUILDFLAG(IS_WIN) void BrowserView::CreateJumpList() { // Ensure that this browser's Profile has a JumpList so that the JumpList is
diff --git a/chrome/browser/ui/views/frame/browser_view.h b/chrome/browser/ui/views/frame/browser_view.h index 889fe47d..121c651 100644 --- a/chrome/browser/ui/views/frame/browser_view.h +++ b/chrome/browser/ui/views/frame/browser_view.h
@@ -56,7 +56,6 @@ #include "ui/base/metadata/metadata_header_macros.h" #include "ui/base/mojom/window_show_state.mojom-forward.h" #include "ui/base/pointer/touch_ui_controller.h" -#include "ui/compositor/compositor_animation_observer.h" #include "ui/gfx/native_widget_types.h" #include "ui/views/controls/button/button.h" #include "ui/views/controls/webview/unhandled_keyboard_event_handler.h" @@ -96,7 +95,6 @@ namespace ui { class NativeTheme; -class Compositor; } // namespace ui namespace version_info { @@ -136,7 +134,6 @@ public extensions::ExtensionKeybindingRegistry::Delegate, public ImmersiveModeController::Observer, public webapps::AppBannerManager::Observer, - public ui::CompositorAnimationObserver, public views::FocusChangeListener { METADATA_HEADER(BrowserView, views::ClientView) @@ -170,7 +167,7 @@ // (and hide immediately). static void SetDisableRevealerDelayForTesting(bool disable); - bool IsLoadingAnimationRunning() const; + bool IsLoadingAnimationRunningForTesting() const; // Returns a Browser instance of this view. Browser* browser() { return browser_.get(); } @@ -791,10 +788,6 @@ void OnWillChangeFocus(View* focused_before, View* focused_now) override; void OnDidChangeFocus(View* focused_before, View* focused_now) override; - // CompositorAnimationObserver: - void OnAnimationStep(base::TimeTicks timestamp) override; - void OnCompositingShuttingDown(ui::Compositor* compositor) override; - // Creates an accessible tab label for screen readers that includes the tab // status for the given tab index. This takes the form of // "Page title - Tab state". The optional parameter `is_for_tab` can be set @@ -920,6 +913,9 @@ // Make sure the WebUI tab strip exists if it should. void MaybeInitializeWebUITabStrip(); + // Callback for the loading animation(s) associated with this view. + void LoadingAnimationCallback(); + #if BUILDFLAG(IS_WIN) // Creates the JumpList. void CreateJumpList(); @@ -1270,9 +1266,8 @@ // Kiosk session. bool force_fullscreen_ = false; - // The observation used to update frames for tab-loading animations. - base::ScopedObservation<ui::Compositor, ui::CompositorAnimationObserver> - loading_animation_observation_{this}; + // The timer used to update frames for tab-loading animations. + base::RepeatingTimer loading_animation_timer_; // Closure invoked when the state of the loading animation changes. base::OnceClosure loading_animation_state_change_closure_;
diff --git a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc index c9a3907..45b70468 100644 --- a/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc +++ b/chrome/browser/ui/views/frame/browser_view_interactive_uitest.cc
@@ -391,7 +391,7 @@ } EXPECT_TRUE(browser()->tab_strip_model()->TabsNeedLoadingUI()); - EXPECT_FALSE(browser_view()->IsLoadingAnimationRunning()); + EXPECT_FALSE(browser_view()->IsLoadingAnimationRunningForTesting()); { base::RunLoop run_loop; @@ -404,7 +404,7 @@ } EXPECT_TRUE(browser()->tab_strip_model()->TabsNeedLoadingUI()); - EXPECT_TRUE(browser_view()->IsLoadingAnimationRunning()); + EXPECT_TRUE(browser_view()->IsLoadingAnimationRunningForTesting()); // Now block for the navigation to complete. navigation_watcher.Wait();
diff --git a/chrome/browser/ui/views/frame/browser_view_unittest.cc b/chrome/browser/ui/views/frame/browser_view_unittest.cc index 73b6b9c6..a1e5eaeca 100644 --- a/chrome/browser/ui/views/frame/browser_view_unittest.cc +++ b/chrome/browser/ui/views/frame/browser_view_unittest.cc
@@ -736,10 +736,10 @@ browser_view()->frame()->Show(); EXPECT_TRUE(browser()->tab_strip_model()->TabsNeedLoadingUI()); - EXPECT_TRUE(browser_view()->IsLoadingAnimationRunning()); + EXPECT_TRUE(browser_view()->IsLoadingAnimationRunningForTesting()); browser_view()->frame()->Hide(); EXPECT_TRUE(browser()->tab_strip_model()->TabsNeedLoadingUI()); - EXPECT_FALSE(browser_view()->IsLoadingAnimationRunning()); + EXPECT_FALSE(browser_view()->IsLoadingAnimationRunningForTesting()); }
diff --git a/chrome/browser/ui/views/infobars/confirm_infobar.cc b/chrome/browser/ui/views/infobars/confirm_infobar.cc index 929a33e..550b2e74 100644 --- a/chrome/browser/ui/views/infobars/confirm_infobar.cc +++ b/chrome/browser/ui/views/infobars/confirm_infobar.cc
@@ -110,7 +110,7 @@ order_of_buttons.push_back(cancel_button_); } - if (!views::PlatformStyle::kIsOkButtonLeading) { + if constexpr (!views::PlatformStyle::kIsOkButtonLeading) { base::ranges::reverse(order_of_buttons); }
diff --git a/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc b/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc index f565a3b..d91b392 100644 --- a/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc +++ b/chrome/browser/ui/views/passwords/credential_leak_dialog_view.cc
@@ -4,12 +4,19 @@ #include "chrome/browser/ui/views/passwords/credential_leak_dialog_view.h" +#include <memory> +#include <utility> + +#include "base/functional/bind.h" #include "build/build_config.h" #include "chrome/browser/ui/passwords/credential_leak_dialog_controller.h" +#include "chrome/browser/ui/passwords/password_dialog_prompts.h" +#include "chrome/browser/ui/tabs/public/tab_dialog_manager.h" +#include "chrome/browser/ui/tabs/public/tab_features.h" +#include "chrome/browser/ui/tabs/public/tab_interface.h" #include "chrome/browser/ui/views/accessibility/theme_tracking_non_accessible_image_view.h" #include "chrome/browser/ui/views/chrome_layout_provider.h" #include "chrome/grit/theme_resources.h" -#include "components/constrained_window/constrained_window_views.h" #include "components/password_manager/core/browser/leak_detection_dialog_utils.h" #include "content/public/browser/web_contents.h" #include "ui/base/metadata/metadata_impl_macros.h" @@ -22,6 +29,8 @@ #include "ui/views/bubble/tooltip_icon.h" #include "ui/views/controls/label.h" #include "ui/views/layout/fill_layout.h" +#include "ui/views/view_utils.h" +#include "ui/views/widget/widget.h" namespace { @@ -36,14 +45,76 @@ return explanation_tooltip; } +class CredentialLeakPromptImpl : public CredentialLeakPrompt { + public: + CredentialLeakPromptImpl(CredentialLeakDialogController* controller, + content::WebContents* web_contents); + CredentialLeakPromptImpl(const CredentialLeakPromptImpl&) = delete; + CredentialLeakPromptImpl& operator=(const CredentialLeakPromptImpl&) = delete; + ~CredentialLeakPromptImpl() override = default; + + // Overrides from CredentialLeakPrompt: + void ShowCredentialLeakPrompt() override; + views::Widget* GetWidgetForTesting() override; + + private: + // Callback to make Widget::Close synchronous. + void CloseWidget(views::Widget::ClosedReason closed_reason); + + std::unique_ptr<CredentialLeakDialogView> credential_leak_dialog_view_; + std::unique_ptr<views::Widget> dialog_; +}; + +CredentialLeakPromptImpl::CredentialLeakPromptImpl( + CredentialLeakDialogController* controller, + content::WebContents* web_contents) { + credential_leak_dialog_view_ = + std::make_unique<CredentialLeakDialogView>(controller, web_contents); +} + +void CredentialLeakPromptImpl::ShowCredentialLeakPrompt() { + CHECK(credential_leak_dialog_view_); + auto* tab_interface = tabs::TabInterface::GetFromContents( + credential_leak_dialog_view_->web_contents()); + CHECK(tab_interface); + credential_leak_dialog_view_->InitWindow(); + dialog_ = tab_interface->GetTabFeatures() + ->tab_dialog_manager() + ->CreateShowDialogAndBlockTabInteraction( + credential_leak_dialog_view_.release()); + dialog_->MakeCloseSynchronous(base::BindOnce( + &CredentialLeakPromptImpl::CloseWidget, base::Unretained(this))); +} + +views::Widget* CredentialLeakPromptImpl::GetWidgetForTesting() { + return dialog_.get(); +} + +void CredentialLeakPromptImpl::CloseWidget( + views::Widget::ClosedReason closed_reason) { + auto* credential_leak_dialog_view = + AsViewClass<CredentialLeakDialogView>(dialog_->GetClientContentsView()); + CHECK(credential_leak_dialog_view); + // Tell the controller to destroy its reference this class which will also + // destroy the |dialog_|. + credential_leak_dialog_view->controller()->ResetDialog(); +} + } // namespace CredentialLeakDialogView::CredentialLeakDialogView( CredentialLeakDialogController* controller, content::WebContents* web_contents) : controller_(controller), web_contents_(web_contents) { - DCHECK(controller); - DCHECK(web_contents); + CHECK(controller); + CHECK(web_contents); + + // Set the ownership of the delegate, not the View. The View is owned by the + // Widget as a child view. + // TODO(crbug.com/338254375): Remove the following two lines once this is the + // default state for widgets and the delegates. + views::WidgetDelegate::SetOwnedByWidget(false); + SetOwnershipOfNewWidget(views::Widget::InitParams::CLIENT_OWNS_WIDGET); SetButtons(controller->ShouldShowCancelButton() ? static_cast<int>(ui::mojom::DialogButton::kOk) | @@ -63,9 +134,8 @@ auto close_callback = [](raw_ptr<CredentialLeakDialogController>* controller, ControllerClosureFn fn) { // Null out the controller pointer stored in the parent object, to avoid any - // further calls to the controller and inhibit recursive closes that would - // otherwise happen in ControllerGone(), and invoke the provided method on - // the controller. + // further calls to the controller and inhibit recursive closes, and invoke + // the provided method on the controller. // // Note that when this lambda gets bound it closes over &controller_, not // controller_ itself! @@ -83,27 +153,7 @@ &CredentialLeakDialogController::OnCloseDialog)); } -CredentialLeakDialogView::~CredentialLeakDialogView() { - if (controller_) { - std::exchange(controller_, nullptr)->ResetDialog(); - } -} - -void CredentialLeakDialogView::ShowCredentialLeakPrompt() { - InitWindow(); - constrained_window::ShowWebModalDialogViews(this, web_contents_); -} - -void CredentialLeakDialogView::ControllerGone() { - // Widget::Close() synchronously calls Close() on this instance, which resets - // the |controller_|. The null check for |controller_| here is to avoid - // reentry into Close() - |controller_| might have been nulled out by the - // closure callbacks already, in which case the dialog is already closing. See - // the definition of |close_callback| in the constructor. - if (controller_) { - GetWidget()->Close(); - } -} +CredentialLeakDialogView::~CredentialLeakDialogView() = default; void CredentialLeakDialogView::AddedToWidget() { // Set the header image. @@ -157,8 +207,8 @@ BEGIN_METADATA(CredentialLeakDialogView) END_METADATA -CredentialLeakPrompt* CreateCredentialLeakPromptView( +std::unique_ptr<CredentialLeakPrompt> CreateCredentialLeakPromptView( CredentialLeakDialogController* controller, content::WebContents* web_contents) { - return new CredentialLeakDialogView(controller, web_contents); + return std::make_unique<CredentialLeakPromptImpl>(controller, web_contents); }
diff --git a/chrome/browser/ui/views/passwords/credential_leak_dialog_view.h b/chrome/browser/ui/views/passwords/credential_leak_dialog_view.h index 89742af..6faf59d 100644 --- a/chrome/browser/ui/views/passwords/credential_leak_dialog_view.h +++ b/chrome/browser/ui/views/passwords/credential_leak_dialog_view.h
@@ -17,8 +17,7 @@ class CredentialLeakDialogController; -class CredentialLeakDialogView : public views::DialogDelegateView, - public CredentialLeakPrompt { +class CredentialLeakDialogView : public views::DialogDelegateView { METADATA_HEADER(CredentialLeakDialogView, views::DialogDelegateView) public: @@ -28,18 +27,17 @@ CredentialLeakDialogView& operator=(const CredentialLeakDialogView&) = delete; ~CredentialLeakDialogView() override; - // CredentialsLeakedPrompt: - void ShowCredentialLeakPrompt() override; - void ControllerGone() override; + // Sets up the child views. + void InitWindow(); + + CredentialLeakDialogController* controller() { return controller_; } + content::WebContents* web_contents() { return web_contents_; } private: // views::DialogDelegateView: void AddedToWidget() override; std::u16string GetWindowTitle() const override; - // Sets up the child views. - void InitWindow(); - // A weak pointer to the controller. raw_ptr<CredentialLeakDialogController> controller_ = nullptr; const raw_ptr<content::WebContents, AcrossTasksDanglingUntriaged>
diff --git a/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc b/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc index 3eae9fe..d306d7e 100644 --- a/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc +++ b/chrome/browser/ui/views/passwords/password_dialog_view_browsertest.cc
@@ -64,7 +64,7 @@ CredentialManagerDialogController* controller) override; AutoSigninFirstRunPrompt* CreateAutoSigninPrompt( CredentialManagerDialogController* controller) override; - CredentialLeakPrompt* CreateCredentialLeakPrompt( + std::unique_ptr<CredentialLeakPrompt> CreateCredentialLeakPrompt( CredentialLeakDialogController* controller) override; AccountChooserDialogView* current_account_chooser() const { @@ -76,9 +76,8 @@ current_autosignin_prompt_); } - CredentialLeakDialogView* current_credential_leak_prompt() const { - return static_cast<CredentialLeakDialogView*>( - current_credential_leak_prompt_); + views::Widget* current_credential_leak_widget() const { + return current_credential_leak_prompt_->GetWidgetForTesting(); } MOCK_METHOD(void, OnDialogClosed, (), ()); @@ -126,12 +125,13 @@ return current_autosignin_prompt_; } -CredentialLeakPrompt* +std::unique_ptr<CredentialLeakPrompt> TestManagePasswordsUIController::CreateCredentialLeakPrompt( CredentialLeakDialogController* controller) { - current_credential_leak_prompt_ = + auto current_credential_leak_prompt = ManagePasswordsUIController::CreateCredentialLeakPrompt(controller); - return current_credential_leak_prompt_; + current_credential_leak_prompt_ = current_credential_leak_prompt.get(); + return current_credential_leak_prompt; } std::unique_ptr<password_manager::PasswordFormManagerForUI> WrapFormInManager( @@ -488,13 +488,12 @@ controller()->OnCredentialLeak(password_manager::LeakedPasswordDetails( leak_type, GURL("https://example.com"), u"Eve", u"qwerty", /*in_account_store=*/false)); - ASSERT_TRUE(controller()->current_credential_leak_prompt()); + ASSERT_TRUE(controller()->current_credential_leak_widget()); EXPECT_EQ(password_manager::ui::INACTIVE_STATE, controller()->GetState()); - CredentialLeakDialogView* dialog = - controller()->current_credential_leak_prompt(); - views::test::WidgetDestroyedWaiter bubble_observer(dialog->GetWidget()); + views::Widget* dialog = controller()->current_credential_leak_widget(); + views::test::WidgetDestroyedWaiter bubble_observer(dialog); ui::Accelerator esc(ui::VKEY_ESCAPE, 0); - EXPECT_TRUE(dialog->GetWidget()->client_view()->AcceleratorPressed(esc)); + EXPECT_TRUE(dialog->client_view()->AcceleratorPressed(esc)); bubble_observer.Wait(); }
diff --git a/chrome/browser/ui/views/passwords/password_save_update_view.cc b/chrome/browser/ui/views/passwords/password_save_update_view.cc index 576e0b1..f09fd8b 100644 --- a/chrome/browser/ui/views/passwords/password_save_update_view.cc +++ b/chrome/browser/ui/views/passwords/password_save_update_view.cc
@@ -32,7 +32,6 @@ #include "components/feature_engagement/public/feature_constants.h" #include "components/feature_engagement/public/tracker.h" #include "components/prefs/pref_service.h" -#include "components/signin/public/base/signin_metrics.h" #include "components/signin/public/base/signin_prefs.h" #include "components/signin/public/identity_manager/account_info.h" #include "content/public/browser/storage_partition.h" @@ -50,22 +49,6 @@ #include "ui/views/layout/flex_layout.h" #include "ui/views/view_class_properties.h" -namespace { - -#if BUILDFLAG(ENABLE_DICE_SUPPORT) -// Initiates a `MovePasswordToAccountStoreHelper`, which takes care of moving -// the `form` from profile to account store. -void MovePasswordToAccount( - const password_manager::PasswordForm& form, - password_manager::metrics_util::MoveToAccountStoreTrigger trigger, - content::WebContents* web_contents) { - PasswordsModelDelegateFromWebContents(web_contents) - ->MovePendingPasswordToAccountStoreUsingHelper(form, trigger); -} -#endif // BUILDFLAG(ENABLE_DICE_SUPPORT) - -} // namespace - PasswordSaveUpdateView::PasswordSaveUpdateView( content::WebContents* web_contents, views::View* anchor_view, @@ -225,16 +208,11 @@ accessibility_view->SetVisible(false); accessibility_alert_ = AddChildView(std::move(accessibility_view)); - auto move_callback = - base::BindOnce(&MovePasswordToAccount, controller_.pending_password(), - password_manager::metrics_util::MoveToAccountStoreTrigger:: - kUserOptedInAfterSavingLocally); - // Show the sign in promo. auto sign_in_promo = std::make_unique<AutofillBubbleSignInPromoView>( controller_.GetWebContents(), signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE, - std::move(move_callback)); + PasswordFormUniqueKey(controller_.pending_password())); AddChildView(std::move(sign_in_promo)); // Notify the screen reader that the bubble changed.
diff --git a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_interactive_uitest.cc b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_interactive_uitest.cc index 926d9abe..1e8c5a0b 100644 --- a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_interactive_uitest.cc +++ b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_interactive_uitest.cc
@@ -2,9 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/test/gmock_callback_support.h" #include "base/test/metrics/histogram_tester.h" -#include "chrome/browser/autofill/personal_data_manager_factory.h" #include "chrome/browser/password_manager/password_manager_test_util.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/signin/chrome_signin_client_test_util.h" @@ -23,7 +21,6 @@ #include "chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h" #include "chrome/browser/ui/views/promos/bubble_signin_promo_signin_button_view.h" #include "chrome/test/base/interactive_test_utils.h" -#include "chrome/test/base/profile_waiter.h" #include "components/autofill/content/browser/content_autofill_client.h" #include "components/autofill/core/browser/data_manager/addresses/address_data_manager.h" #include "components/autofill/core/browser/data_manager/personal_data_manager.h" @@ -40,8 +37,9 @@ #include "components/signin/public/identity_manager/accounts_mutator.h" #include "components/signin/public/identity_manager/identity_manager.h" #include "components/signin/public/identity_manager/identity_test_utils.h" +#include "components/sync/base/data_type.h" #include "components/sync/base/features.h" -#include "components/sync/test/test_sync_service.h" +#include "components/sync/test/mock_sync_service.h" #include "content/public/test/browser_test.h" #include "google_apis/gaia/gaia_auth_consumer.h" #include "ui/views/interaction/element_tracker_views.h" @@ -53,33 +51,22 @@ using autofill::AddressSignInPromoView; using autofill::AutofillProfile; using autofill::ContentAutofillClient; -using autofill::PersonalDataManager; using autofill::SaveAddressProfileView; -class MockAddressDataManagerObserver : public AddressDataManager::Observer { - public: - MOCK_METHOD(void, OnAddressDataChanged, (), (override)); -}; - constexpr char kButton[] = "SignInButton"; -MATCHER_P(FormMatches, form, "") { - return form.signon_realm == arg.signon_realm && form.url == arg.url && - form.action == arg.action && - form.username_element == arg.username_element && - form.password_element == arg.password_element; -} +using testing::_; +using testing::Return; -MATCHER_P(AddressMatches, address, "") { - return arg->Compare(address) == 0; +std::unique_ptr<KeyedService> BuildMockSyncService( + content::BrowserContext* context) { + return std::make_unique<testing::NiceMock<syncer::MockSyncService>>(); } } // namespace class AutofillBubbleSignInPromoInteractiveUITest : public ManagePasswordsTest { public: - DECLARE_CLASS_CUSTOM_ELEMENT_EVENT_TYPE(kAddressDataChanged); - void SetUpInProcessBrowserTestFixture() override { ManagePasswordsTest::SetUpInProcessBrowserTestFixture(); url_loader_factory_helper_.SetUp(); @@ -96,16 +83,10 @@ } void OnWillCreateBrowserContextServices(content::BrowserContext* context) { - // Create password stores. + // Create local password store and mock sync service. local_password_store_ = CreateAndUseTestPasswordStore(context); - account_password_store_ = CreateAndUseTestAccountPasswordStore(context); - } - - void PreRunTestOnMainThread() override { - ManagePasswordsTest::PreRunTestOnMainThread(); - - // Set the sync service to be signed out by default. - ConfigurePasswordSync(SyncConfiguration::kNotSyncing); + SyncServiceFactory::GetInstance()->SetTestingFactoryAndUse( + context, base::BindRepeating(&BuildMockSyncService)); } // Trigger the password save by simulating an "Accept" in the password bubble, @@ -125,27 +106,16 @@ // persistent error state. bool IsSignedIn(); - // This is needed because the TestSyncService will not automatically become - // available upon sign in. - void ActivateSyncService(AccountInfo& info) { - static_cast<syncer::TestSyncService*>( - SyncServiceFactory::GetForProfile(browser()->profile())) - ->SetSignedIn(signin::ConsentLevel::kSignin, info); + // Mock the activation of the sync service upon sign in. + void ActivateSyncService() { + ON_CALL(sync_service_mock(), GetTransportState()) + .WillByDefault(Return(syncer::SyncService::TransportState::ACTIVE)); + ON_CALL(sync_service_mock(), HasSyncConsent()).WillByDefault(Return(true)); } // Add additional account info for pixel tests. void ExtendAccountInfo(AccountInfo& info); - std::vector<const AutofillProfile*> local_addresses() const { - return address_data_manager().GetProfilesByRecordType( - AutofillProfile::RecordType::kLocalOrSyncable); - } - - std::vector<const AutofillProfile*> account_addresses() const { - return address_data_manager().GetProfilesByRecordType( - AutofillProfile::RecordType::kAccount); - } - ContentAutofillClient& client() const { return *ContentAutofillClient::FromWebContents( browser()->tab_strip_model()->GetActiveWebContents()); @@ -155,6 +125,11 @@ return client().GetPersonalDataManager().address_data_manager(); } + syncer::MockSyncService& sync_service_mock() { + return *static_cast<syncer::MockSyncService*>( + SyncServiceFactory::GetForProfile(browser()->profile())); + } + network::TestURLLoaderFactory* test_url_loader_factory() { return url_loader_factory_helper_.test_url_loader_factory(); } @@ -163,8 +138,6 @@ return IdentityManagerFactory::GetForProfile(browser()->profile()); } - void OnAddressDataChanged(); - void SaveAddress(autofill::AutofillClient::AddressPromptUserDecision decision, base::optional_ref<const AutofillProfile> profile); @@ -174,7 +147,6 @@ ChromeSigninClientWithURLLoaderHelper url_loader_factory_helper_; base::CallbackListSubscription create_services_subscription_; scoped_refptr<password_manager::TestPasswordStore> local_password_store_; - scoped_refptr<password_manager::TestPasswordStore> account_password_store_; }; void AutofillBubbleSignInPromoInteractiveUITest::SavePassword() { @@ -198,16 +170,14 @@ void AutofillBubbleSignInPromoInteractiveUITest::SignIn( signin_metrics::AccessPoint access_point) { - AccountInfo info = signin::MakeAccountAvailable( + ActivateSyncService(); + signin::MakeAccountAvailable( identity_manager(), signin::AccountAvailabilityOptionsBuilder(test_url_loader_factory()) .WithCookie() .WithAccessPoint(access_point) + .AsPrimary(signin::ConsentLevel::kSignin) .Build("test@email.com")); - - ActivateSyncService(info); - identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount( - info.account_id, signin::ConsentLevel::kSignin, access_point); } bool AutofillBubbleSignInPromoInteractiveUITest::IsSignInURL() { @@ -228,35 +198,26 @@ signin::UpdateAccountInfoForAccount(identity_manager(), info); } -void AutofillBubbleSignInPromoInteractiveUITest::OnAddressDataChanged() { - views::ElementTrackerViews::GetInstance()->NotifyCustomEvent( - kAddressDataChanged, BrowserView::GetBrowserViewForBrowser(browser())); -} - void AutofillBubbleSignInPromoInteractiveUITest::SaveAddress( autofill::AutofillClient::AddressPromptUserDecision decision, base::optional_ref<const AutofillProfile> profile) { address_data_manager().AddProfile(*profile); } -DEFINE_CLASS_CUSTOM_ELEMENT_EVENT_TYPE( - AutofillBubbleSignInPromoInteractiveUITest, - kAddressDataChanged); - ///////////////////////////////////////////////////////////////// ///// Password Sign in Promo IN_PROC_BROWSER_TEST_F(AutofillBubbleSignInPromoInteractiveUITest, PasswordSignInPromoNoAccountPresent) { base::HistogramTester histogram_tester; - // Set up password and password stores. - GetController()->OnPasswordSubmitted(CreateFormManager( - local_password_store_.get(), account_password_store_.get())); + + // Set up password and the local password store. + GetController()->OnPasswordSubmitted( + CreateFormManager(local_password_store_.get(), nullptr)); // Save the password and check that it was properly saved to profile store. SavePassword(); EXPECT_EQ(1u, local_password_store_->stored_passwords().size()); - EXPECT_EQ(0u, account_password_store_->stored_passwords().size()); // Wait for the bubble to be replaced with the sign in promo and click the // sign in button. @@ -283,25 +244,18 @@ *browser()->tab_strip_model()->GetActiveWebContents()) ->IsInitializedForTesting()); - // Simulate a sign in event with the correct access point, which will move the - // password. Wait for the password to show up in account store. - auto account_store_waiter = - password_manager::PasswordStoreWaiter(account_password_store_.get()); + // This would move the password to account storage. + EXPECT_CALL(sync_service_mock(), SelectTypeAndMigrateLocalDataItemsWhenActive( + syncer::PASSWORDS, _)) + .Times(1); + + // Simulate a sign in event with the correct access point, which should call + // `SelectTypeAndMigrateLocalDataItemsWhenActive()`. SignIn(signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE); - account_store_waiter.WaitOrReturn(); // Check that the sign in was successful. EXPECT_TRUE(IsSignedIn()); - // Check that password was moved to account store. - EXPECT_EQ(0u, local_password_store_->stored_passwords().size()); - EXPECT_EQ(1u, account_password_store_->stored_passwords().size()); - - auto found = account_password_store_->stored_passwords().find( - test_form()->signon_realm); - EXPECT_NE(account_password_store_->stored_passwords().end(), found); - EXPECT_THAT(found->second, testing::ElementsAre(FormMatches(*test_form()))); - // Signin metrics - Offered/Started/Completed are recorded, but no values for // WebSignin (WithDefault). histogram_tester.ExpectBucketCount( @@ -323,6 +277,7 @@ IN_PROC_BROWSER_TEST_F(AutofillBubbleSignInPromoInteractiveUITest, PasswordSignInPromoWithWebSignedInAccount) { base::HistogramTester histogram_tester; + // Sign in with an account, but only on the web. The primary account is not // set. AccountInfo info = signin::MakeAccountAvailable( @@ -333,21 +288,23 @@ .Build("test@email.com")); ExtendAccountInfo(info); - // Set up password and password stores. - GetController()->OnPasswordSubmitted(CreateFormManager( - local_password_store_.get(), account_password_store_.get())); + // Set up password and the local password store. + GetController()->OnPasswordSubmitted( + CreateFormManager(local_password_store_.get(), nullptr)); // Save the password and check that it was properly saved to profile store. SavePassword(); EXPECT_EQ(1u, local_password_store_->stored_passwords().size()); - EXPECT_EQ(0u, account_password_store_->stored_passwords().size()); + + // This would move the password to account storage. + EXPECT_CALL(sync_service_mock(), SelectTypeAndMigrateLocalDataItemsWhenActive( + syncer::PASSWORDS, _)) + .Times(1); // Wait for the bubble to be replaced with the sign in promo and click the - // sign in button. This should directly sign the user in and move the - // password. - auto account_store_waiter = - password_manager::PasswordStoreWaiter(account_password_store_.get()); - ActivateSyncService(info); + // sign in button. This should directly sign the user in and trigger the data + // migration. + ActivateSyncService(); RunTestSequence( WaitForEvent(BubbleSignInPromoSignInButtonView::kPromoSignInButton, kBubbleSignInPromoSignInButtonHasCallback), @@ -361,7 +318,6 @@ BubbleSignInPromoSignInButtonView::kPromoSignInButton, kButton), PressButton(kButton).SetMustRemainVisible(false), EnsureNotPresent(PasswordSaveUpdateView::kPasswordBubble)); - account_store_waiter.WaitOrReturn(); // Check that there is no helper attached to the sign in tab, because the // password was already moved. @@ -372,15 +328,6 @@ // Check that the sign in was successful. EXPECT_TRUE(IsSignedIn()); - // Check that password was moved to account store. - EXPECT_EQ(0u, local_password_store_->stored_passwords().size()); - EXPECT_EQ(1u, account_password_store_->stored_passwords().size()); - - auto found = account_password_store_->stored_passwords().find( - test_form()->signon_realm); - EXPECT_NE(account_password_store_->stored_passwords().end(), found); - EXPECT_THAT(found->second, testing::ElementsAre(FormMatches(*test_form()))); - // Signin metrics - WebSignin (WithDefault) metrics are also recorded. histogram_tester.ExpectBucketCount( "Signin.SignIn.Offered", @@ -411,9 +358,9 @@ ExtendAccountInfo(info); signin::SetInvalidRefreshTokenForPrimaryAccount(identity_manager()); - // Set up password and password stores. - GetController()->OnPasswordSubmitted(CreateFormManager( - local_password_store_.get(), account_password_store_.get())); + // Set up password and the local password store. + GetController()->OnPasswordSubmitted( + CreateFormManager(local_password_store_.get(), nullptr)); // Start recording metrics after signing in. base::HistogramTester histogram_tester; @@ -421,7 +368,6 @@ // Save the password and check that it was properly saved to profile store. SavePassword(); EXPECT_EQ(1u, local_password_store_->stored_passwords().size()); - EXPECT_EQ(0u, account_password_store_->stored_passwords().size()); // Wait for the bubble to be replaced with the sign in promo and click // the sign in button. @@ -449,32 +395,25 @@ ->IsInitializedForTesting()); EXPECT_FALSE(IsSignedIn()); + // This would move the password to account storage. + EXPECT_CALL(sync_service_mock(), SelectTypeAndMigrateLocalDataItemsWhenActive( + syncer::PASSWORDS, _)) + .Times(1); + // Set a new refresh token for the primary account, which verifies the - // user's identity and signs them back in. The password will be moved to - // account store. - auto account_store_waiter = - password_manager::PasswordStoreWaiter(account_password_store_.get()); - ActivateSyncService(info); + // user's identity and signs them back in. This triggers the local data + // migration. + ActivateSyncService(); identity_manager()->GetAccountsMutator()->AddOrUpdateAccount( info.gaia, info.email, "dummy_refresh_token", /*is_under_advanced_protection=*/false, signin_metrics::AccessPoint::ACCESS_POINT_PASSWORD_BUBBLE, signin_metrics::SourceForRefreshTokenOperation:: kDiceResponseHandler_Signin); - account_store_waiter.WaitOrReturn(); // Check that the sign in was successful. EXPECT_TRUE(IsSignedIn()); - // Check that password was moved to account store. - EXPECT_EQ(0u, local_password_store_->stored_passwords().size()); - EXPECT_EQ(1u, account_password_store_->stored_passwords().size()); - - auto found = account_password_store_->stored_passwords().find( - test_form()->signon_realm); - EXPECT_NE(account_password_store_->stored_passwords().end(), found); - EXPECT_THAT(found->second, testing::ElementsAre(FormMatches(*test_form()))); - // Signin metrics - nothing should be recorded for reauth. histogram_tester.ExpectTotalCount("Signin.SignIn.Offered", 0); histogram_tester.ExpectTotalCount("Signin.SignIn.Started", 0); @@ -494,28 +433,12 @@ AutofillProfile address = autofill::test::GetFullProfile(); TriggerSaveAddressBubble(address); - // Set up observer in order to ensure that `OnAddressDataChanged` is called - // twice. Fire an event the first time it is called, as this is coming from - // when the first address save bubble was accepted. The second time it is - // called will be for the address migration. - testing::NiceMock<MockAddressDataManagerObserver> observer; - base::RunLoop run_loop; - EXPECT_CALL(observer, OnAddressDataChanged) - .Times(2) - .WillOnce([&] { OnAddressDataChanged(); }) - .WillOnce(base::test::RunClosure(run_loop.QuitClosure())); - base::ScopedObservation<AddressDataManager, AddressDataManager::Observer> - observation{&observer}; - observation.Observe(&address_data_manager()); - // Accept the save bubble, wait for it to be replaced with the sign in promo // and click the sign in button. RunTestSequence( PressButton(views::DialogClientView::kOkButtonElementId), - InParallel( - WaitForEvent(kBrowserViewElementId, kAddressDataChanged), - WaitForEvent(BubbleSignInPromoSignInButtonView::kPromoSignInButton, - kBubbleSignInPromoSignInButtonHasCallback)), + WaitForEvent(BubbleSignInPromoSignInButtonView::kPromoSignInButton, + kBubbleSignInPromoSignInButtonHasCallback), EnsureNotPresent(SaveAddressProfileView::kTopViewId), EnsurePresent(AddressSignInPromoView::kBubbleFrameViewId), SetOnIncompatibleAction( @@ -528,10 +451,6 @@ PressButton(kButton).SetMustRemainVisible(false), EnsureNotPresent(AddressSignInPromoView::kBubbleFrameViewId)); - // Check that address was saved to local store. - EXPECT_EQ(1u, local_addresses().size()); - EXPECT_EQ(0u, account_addresses().size()); - // Check that clicking the sign in button navigated to a sign in page. EXPECT_TRUE(IsSignInURL()); @@ -541,21 +460,18 @@ *browser()->tab_strip_model()->GetActiveWebContents()) ->IsInitializedForTesting()); + // This would move the address to account storage. + std::vector<syncer::LocalDataItemModel::DataId> items{address.guid()}; + EXPECT_CALL(sync_service_mock(), SelectTypeAndMigrateLocalDataItemsWhenActive( + syncer::CONTACT_INFO, items)) + .Times(1); + // Simulate a sign in event with the correct access point, which will move the // address. SignIn(signin_metrics::AccessPoint::ACCESS_POINT_ADDRESS_BUBBLE); - // Wait for the address to be moved. - run_loop.Run(); - // Check that the sign in was successful. EXPECT_TRUE(IsSignedIn()); - - // Check that the address was moved to account store. - EXPECT_EQ(0u, local_addresses().size()); - EXPECT_EQ(1u, account_addresses().size()); - EXPECT_THAT(account_addresses(), - testing::ElementsAre(AddressMatches(address))); } IN_PROC_BROWSER_TEST_F(AutofillBubbleSignInPromoInteractiveUITest, @@ -574,30 +490,20 @@ AutofillProfile address = autofill::test::GetFullProfile(); TriggerSaveAddressBubble(address); - // Set up observer in order to ensure that `OnAddressDataChanged` is called - // twice. Fire an event the first time it is called, as this is coming from - // when the first address save bubble was accepted. The second time it is - // called will be for the address migration. - testing::NiceMock<MockAddressDataManagerObserver> observer; - base::RunLoop run_loop; - EXPECT_CALL(observer, OnAddressDataChanged) - .Times(2) - .WillOnce([&] { OnAddressDataChanged(); }) - .WillOnce(base::test::RunClosure(run_loop.QuitClosure())); - base::ScopedObservation<AddressDataManager, AddressDataManager::Observer> - observation{&observer}; - observation.Observe(&address_data_manager()); + // This would move the address to account storage. + std::vector<syncer::LocalDataItemModel::DataId> items{address.guid()}; + EXPECT_CALL(sync_service_mock(), SelectTypeAndMigrateLocalDataItemsWhenActive( + syncer::CONTACT_INFO, items)) + .Times(1); // Accept the save bubble, wait for the save bubble to be replaced with the // sign in promo and click the sign in button. This should directly sign the // user in and move the address. - ActivateSyncService(info); + ActivateSyncService(); RunTestSequence( PressButton(views::DialogClientView::kOkButtonElementId), - InParallel( - WaitForEvent(kBrowserViewElementId, kAddressDataChanged), - WaitForEvent(BubbleSignInPromoSignInButtonView::kPromoSignInButton, - kBubbleSignInPromoSignInButtonHasCallback)), + WaitForEvent(BubbleSignInPromoSignInButtonView::kPromoSignInButton, + kBubbleSignInPromoSignInButtonHasCallback), EnsureNotPresent(SaveAddressProfileView::kTopViewId), EnsurePresent(AddressSignInPromoView::kBubbleFrameViewId), SetOnIncompatibleAction( @@ -610,9 +516,6 @@ PressButton(kButton).SetMustRemainVisible(false), EnsureNotPresent(AddressSignInPromoView::kBubbleFrameViewId)); - // Wait for the address to be moved. - run_loop.Run(); - // Check that there is no helper attached to the sign in tab, because the // password was already moved. EXPECT_FALSE(autofill::AutofillSigninPromoTabHelper::GetForWebContents( @@ -621,12 +524,6 @@ // Check that the sign in was successful. EXPECT_TRUE(IsSignedIn()); - - // Check that the address was moved to account store. - EXPECT_EQ(0u, local_addresses().size()); - EXPECT_EQ(1u, account_addresses().size()); - EXPECT_THAT(account_addresses(), - testing::ElementsAre(AddressMatches(address))); } #if BUILDFLAG(IS_MAC) @@ -650,28 +547,12 @@ AutofillProfile address = autofill::test::GetFullProfile(); TriggerSaveAddressBubble(address); - // Set up observer in order to ensure that `OnAddressDataChanged` is called - // twice. Fire an event the first time it is called, as this is coming from - // when the first address save bubble was accepted. The second time it is - // called will be for the address migration. - testing::NiceMock<MockAddressDataManagerObserver> observer; - base::RunLoop run_loop; - EXPECT_CALL(observer, OnAddressDataChanged) - .Times(2) - .WillOnce([&] { OnAddressDataChanged(); }) - .WillOnce(base::test::RunClosure(run_loop.QuitClosure())); - base::ScopedObservation<AddressDataManager, AddressDataManager::Observer> - observation{&observer}; - observation.Observe(&address_data_manager()); - // Accept the save bubble, wait for the save bubble to be replaced with the // sign in promo and click the sign in button. RunTestSequence( PressButton(views::DialogClientView::kOkButtonElementId), - InParallel( - WaitForEvent(kBrowserViewElementId, kAddressDataChanged), - WaitForEvent(BubbleSignInPromoSignInButtonView::kPromoSignInButton, - kBubbleSignInPromoSignInButtonHasCallback)), + WaitForEvent(BubbleSignInPromoSignInButtonView::kPromoSignInButton, + kBubbleSignInPromoSignInButtonHasCallback), EnsureNotPresent(SaveAddressProfileView::kTopViewId), EnsurePresent(AddressSignInPromoView::kBubbleFrameViewId), SetOnIncompatibleAction( @@ -684,10 +565,6 @@ PressButton(kButton).SetMustRemainVisible(false), EnsureNotPresent(AddressSignInPromoView::kBubbleFrameViewId)); - // Check that address was saved to local store. - EXPECT_EQ(1u, local_addresses().size()); - EXPECT_EQ(0u, account_addresses().size()); - // Check that clicking the sign in button navigated to a sign in page. EXPECT_TRUE(IsSignInURL()); @@ -697,10 +574,16 @@ *browser()->tab_strip_model()->GetActiveWebContents()) ->IsInitializedForTesting()); + // This would move the address to account storage. + std::vector<syncer::LocalDataItemModel::DataId> items{address.guid()}; + EXPECT_CALL(sync_service_mock(), SelectTypeAndMigrateLocalDataItemsWhenActive( + syncer::CONTACT_INFO, items)) + .Times(1); + // Set a new refresh token for the primary account, which verifies the - // user's identity and signs them back in. The address will be moved to - // account store. - ActivateSyncService(info); + // user's identity and signs them back in. This would trigger the data + // migration. + ActivateSyncService(); identity_manager()->GetAccountsMutator()->AddOrUpdateAccount( info.gaia, info.email, "dummy_refresh_token", /*is_under_advanced_protection=*/false, @@ -708,15 +591,6 @@ signin_metrics::SourceForRefreshTokenOperation:: kDiceResponseHandler_Signin); - // Wait for the address to be moved. - run_loop.Run(); - // Check that the sign in was successful. EXPECT_TRUE(IsSignedIn()); - - // Check that the address was moved to account store. - EXPECT_EQ(0u, local_addresses().size()); - EXPECT_EQ(1u, account_addresses().size()); - EXPECT_THAT(account_addresses(), - testing::ElementsAre(AddressMatches(address))); }
diff --git a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc index 2b4d02c..eba22e8 100644 --- a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc +++ b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.cc
@@ -61,8 +61,8 @@ AutofillBubbleSignInPromoView::AutofillBubbleSignInPromoView( content::WebContents* web_contents, signin_metrics::AccessPoint access_point, - base::OnceCallback<void(content::WebContents*)> move_callback) - : controller_(*web_contents, access_point, std::move(move_callback)) { + syncer::LocalDataItemModel::DataId data_id) + : controller_(*web_contents, access_point, std::move(data_id)) { SetLayoutManager(std::make_unique<views::FillLayout>()); Profile* profile =
diff --git a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h index 82234316..d7aacb4 100644 --- a/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h +++ b/chrome/browser/ui/views/promos/autofill_bubble_signin_promo_view.h
@@ -35,7 +35,7 @@ explicit AutofillBubbleSignInPromoView( content::WebContents* web_contents, signin_metrics::AccessPoint access_point, - base::OnceCallback<void(content::WebContents*)> move_callback); + syncer::LocalDataItemModel::DataId data_id); AutofillBubbleSignInPromoView(const AutofillBubbleSignInPromoView&) = delete; AutofillBubbleSignInPromoView& operator=( const AutofillBubbleSignInPromoView&) = delete;
diff --git a/chrome/browser/ui/views/tab_sharing/tab_sharing_infobar.cc b/chrome/browser/ui/views/tab_sharing/tab_sharing_infobar.cc index c2c5cc4c..97dce86 100644 --- a/chrome/browser/ui/views/tab_sharing/tab_sharing_infobar.cc +++ b/chrome/browser/ui/views/tab_sharing/tab_sharing_infobar.cc
@@ -229,7 +229,7 @@ order_of_buttons.push_back(csc_indicator_button_); } - if (!views::PlatformStyle::kIsOkButtonLeading) { + if constexpr (!views::PlatformStyle::kIsOkButtonLeading) { base::ranges::reverse(order_of_buttons); }
diff --git a/chrome/browser/ui/views/task_manager_view.cc b/chrome/browser/ui/views/task_manager_view.cc index 1006f5f..cdada453 100644 --- a/chrome/browser/ui/views/task_manager_view.cc +++ b/chrome/browser/ui/views/task_manager_view.cc
@@ -353,6 +353,7 @@ TaskManagerView::TaskManagerView(StartAction start_action) : tab_table_(nullptr), tab_table_parent_(nullptr), + table_config_(GetTableConfigs()), is_always_on_top_(false) { task_manager::RecordNewOpenEvent(start_action); set_use_custom_frame(false); @@ -386,6 +387,7 @@ .scroll_view_rounded = tm_refresh_enabled, .layout_refresh = tm_refresh_enabled, .dialog_button_disabled = tm_refresh_enabled, + .sort_on_cpu_by_default = tm_refresh_enabled, }; } @@ -400,7 +402,8 @@ // Columns are already retrieved, however since the table model changed, the // refresh types for this model need to be set for each column. Otherwise, the // values for each column will stop updating. - table_model_->RetrieveSavedColumnsSettingsAndUpdateTable(); + table_model_->RetrieveSavedColumnsSettingsAndUpdateTable( + table_config_.sort_on_cpu_by_default); // Redraw the table immediately by scheduling a paint since the rows most // likely changed in between switching models. @@ -600,8 +603,6 @@ } void TaskManagerView::Init() { - const auto table_config = GetTableConfigs(); - // Create the table columns. for (size_t i = 0; i < kColumnsSize; ++i) { const auto& col_data = kColumns[i]; @@ -617,8 +618,8 @@ nullptr, columns_, views::TableType::kIconAndText, false); tab_table_ = tab_table.get(); table_model_ = std::make_unique<TaskManagerTableModel>( - this, table_config.layout_refresh ? DisplayCategory::kTabs - : DisplayCategory::kAll); + this, table_config_.layout_refresh ? DisplayCategory::kTabs + : DisplayCategory::kAll); tab_table->SetModel(table_model_.get()); tab_table->SetGrouper(this); tab_table->SetSortOnPaint(true); @@ -626,7 +627,7 @@ tab_table->set_context_menu_controller(this); set_context_menu_controller(this); - if (table_config.dialog_button_disabled) { + if (table_config_.dialog_button_disabled) { SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone)); } else { SetButtons(static_cast<int>(ui::mojom::DialogButton::kOk)); @@ -634,7 +635,7 @@ l10n_util::GetStringUTF16(IDS_TASK_MANAGER_KILL)); } - if (table_config.header_padding) { + if (table_config_.header_padding) { views::TableHeaderStyle header_style = { .cell_vertical_padding = 16, .cell_horizontal_padding = 12, @@ -659,7 +660,7 @@ SetBorder(views::CreateEmptyBorder(content_insets)); // Setup Layout Manager for Dialog - if (table_config.layout_refresh) { + if (table_config_.layout_refresh) { views::FlexLayout* content_layout = SetLayoutManager(std::make_unique<views::FlexLayout>()); content_layout->SetOrientation(views::LayoutOrientation::kVertical); @@ -671,10 +672,10 @@ // Add Process List (a.k.a Scroll View) tab_table_parent_ = AddChildView( - CreateProcessView(std::move(tab_table), table_config.table_has_border, - table_config.layout_refresh)); + CreateProcessView(std::move(tab_table), table_config_.table_has_border, + table_config_.layout_refresh)); - if (table_config.scroll_view_rounded) { + if (table_config_.scroll_view_rounded) { tab_table_parent_->SetPaintToLayer(ui::LAYER_TEXTURED); ui::Layer* scroll_view_layer = tab_table_parent_->layer(); @@ -684,7 +685,8 @@ scroll_view_layer->SetIsFastRoundedCorner(true); } - table_model_->RetrieveSavedColumnsSettingsAndUpdateTable(); + table_model_->RetrieveSavedColumnsSettingsAndUpdateTable( + table_config_.sort_on_cpu_by_default); AddAccelerator(ui::Accelerator(ui::VKEY_W, ui::EF_CONTROL_DOWN)); AddAccelerator(
diff --git a/chrome/browser/ui/views/task_manager_view.h b/chrome/browser/ui/views/task_manager_view.h index a225bf0..ac06e6da8 100644 --- a/chrome/browser/ui/views/task_manager_view.h +++ b/chrome/browser/ui/views/task_manager_view.h
@@ -130,6 +130,7 @@ bool scroll_view_rounded; bool layout_refresh; bool dialog_button_disabled; + bool sort_on_cpu_by_default; }; friend class TaskManagerViewTest; @@ -195,6 +196,9 @@ raw_ptr<views::TableView, DanglingUntriaged> tab_table_; raw_ptr<views::View, DanglingUntriaged> tab_table_parent_; + // Specifications on how to layout the table. + TableConfigs table_config_; + // all possible columns, not necessarily visible. std::vector<ui::TableColumn> columns_;
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc index ff1d431..5d8191d 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.cc
@@ -55,7 +55,7 @@ } // namespace void ParentAccessUiHandlerImpl::RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError error) { + supervised_user::ParentAccessWidgetError error) { if (delegate_) { base::UmaHistogramEnumeration( parent_access::GetHistogramTitleForFlowType( @@ -120,7 +120,7 @@ DLOG(ERROR) << "ParentAccessUiHandlerImpl: OAuth2 token request failed. " << error.state() << ": " << error.ToString(); RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kOAuthError); + supervised_user::ParentAccessWidgetError::kOAuthError); std::move(callback).Run( parent_access_ui::mojom::GetOauthTokenStatus::kError, "" /* No token */); @@ -137,8 +137,7 @@ LOG(ERROR) << "Delegate not available in ParentAccessUiHandler - WebUI was " "probably created without a dialog"; RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError:: - kDelegateNotAvailable); + supervised_user::ParentAccessWidgetError::kDelegateNotAvailable); std::move(callback).Run(parent_access_ui::mojom::ParentAccessParams::New()); return; } @@ -153,8 +152,7 @@ LOG(ERROR) << "Delegate not available in ParentAccessUiHandler - WebUI was " "probably created without a dialog"; RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError:: - kDelegateNotAvailable); + supervised_user::ParentAccessWidgetError::kDelegateNotAvailable); std::move(callback).Run(); return; } @@ -202,8 +200,7 @@ LOG(ERROR) << "Delegate not available in ParentAccessUiHandler - WebUI was " "probably created without a dialog"; RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError:: - kDelegateNotAvailable); + supervised_user::ParentAccessWidgetError::kDelegateNotAvailable); std::move(callback).Run(""); return; } @@ -260,7 +257,7 @@ LOG(ERROR) << "ParentAccessHandler::ParentAccessResult: Error decoding " "parent_access_result from base64"; RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kDecodingError); + supervised_user::ParentAccessWidgetError::kDecodingError); message->type = parent_access_ui::mojom::ParentAccessServerMessageType::kError; @@ -274,7 +271,7 @@ LOG(ERROR) << "ParentAccessHandler::ParentAccessResult: Error parsing " "decoded_parent_access_result to proto"; RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kParsingError); + supervised_user::ParentAccessWidgetError::kParsingError); message->type = parent_access_ui::mojom::ParentAccessServerMessageType::kError; @@ -308,7 +305,7 @@ "callback received and ignored: " << parent_access_callback.callback_case(); RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kUnknownCallback); + supervised_user::ParentAccessWidgetError::kUnknownCallback); message->type = parent_access_ui::mojom::ParentAccessServerMessageType::kIgnore; std::move(callback).Run(std::move(message));
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.h b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.h index b86c1b6c..9d34044 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.h +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl.h
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/webui/ash/parent_access/parent_access_ui.mojom.h" #include "chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_delegate.h" #include "components/supervised_user/core/browser/proto/parent_access_callback.pb.h" +#include "components/supervised_user/core/common/supervised_user_constants.h" #include "mojo/public/cpp/bindings/pending_receiver.h" #include "mojo/public/cpp/bindings/receiver.h" @@ -66,26 +67,13 @@ const kids::platform::parentaccess::client::proto::ParentAccessToken* GetParentAccessTokenForTest(); - // Used for metrics. These values are logged to UMA. Entries should not be - // renumbered and numeric values should never be reused. Please keep in sync - // with "FamilyLinkUserParentAccessWidgetError" in - // src/tools/metrics/histograms/enums.xml. - enum class ParentAccessWidgetError { - kOAuthError = 0, - kDelegateNotAvailable = 1, - kDecodingError = 2, - kParsingError = 3, - kUnknownCallback = 4, - kMaxValue = kUnknownCallback - }; - private: void OnAccessTokenFetchComplete(GetOauthTokenCallback callback, GoogleServiceAuthError error, signin::AccessTokenInfo access_token_info); void RecordParentAccessWidgetError( - ParentAccessUiHandlerImpl::ParentAccessWidgetError error); + supervised_user::ParentAccessWidgetError error); // Used to fetch OAuth2 access tokens. raw_ptr<signin::IdentityManager> identity_manager_ = nullptr;
diff --git a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc index a90c407..60989c9 100644 --- a/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc +++ b/chrome/browser/ui/webui/ash/parent_access/parent_access_ui_handler_impl_unittest.cc
@@ -211,12 +211,12 @@ histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, std::nullopt), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kOAuthError, 1); + supervised_user::ParentAccessWidgetError::kOAuthError, 1); histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, GetTestedFlowType()), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kOAuthError, 1); + supervised_user::ParentAccessWidgetError::kOAuthError, 1); } // Verifies that only one access token fetch is possible at a time. @@ -470,12 +470,12 @@ histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, std::nullopt), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kUnknownCallback, 1); + supervised_user::ParentAccessWidgetError::kUnknownCallback, 1); histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, GetTestedFlowType()), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kUnknownCallback, 1); + supervised_user::ParentAccessWidgetError::kUnknownCallback, 1); } // Verifies that the OnPageSizeChanged status is ignored. @@ -508,12 +508,12 @@ histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, std::nullopt), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kUnknownCallback, 1); + supervised_user::ParentAccessWidgetError::kUnknownCallback, 1); histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, GetTestedFlowType()), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kUnknownCallback, 1); + supervised_user::ParentAccessWidgetError::kUnknownCallback, 1); } // Verifies that the OnCommunicationEstablished status is ignored. @@ -548,7 +548,7 @@ histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, std::nullopt), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kUnknownCallback, 1); + supervised_user::ParentAccessWidgetError::kUnknownCallback, 1); } // Verifies metric is recorded for no delegate error. @@ -575,8 +575,7 @@ histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, std::nullopt), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kDelegateNotAvailable, - 1); + supervised_user::ParentAccessWidgetError::kDelegateNotAvailable, 1); } TEST_P(ParentAccessUiHandlerImplTestParameterized, @@ -596,12 +595,12 @@ histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, std::nullopt), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kDecodingError, 1); + supervised_user::ParentAccessWidgetError::kDecodingError, 1); histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, GetTestedFlowType()), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kDecodingError, 1); + supervised_user::ParentAccessWidgetError::kDecodingError, 1); } // Verifies metric is recorded when received callback cannot be parsed to proto. @@ -622,12 +621,12 @@ histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, std::nullopt), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kParsingError, 1); + supervised_user::ParentAccessWidgetError::kParsingError, 1); histogram_tester.ExpectUniqueSample( parent_access::GetHistogramTitleForFlowType( parent_access::kParentAccessWidgetErrorHistogramBase, GetTestedFlowType()), - ParentAccessUiHandlerImpl::ParentAccessWidgetError::kParsingError, 1); + supervised_user::ParentAccessWidgetError::kParsingError, 1); } class ExtensionApprovalsDisabledTest
diff --git a/chrome/browser/ui/webui/glic/glic.mojom b/chrome/browser/ui/webui/glic/glic.mojom index bfaecc0..d9b384a6a 100644 --- a/chrome/browser/ui/webui/glic/glic.mojom +++ b/chrome/browser/ui/webui/glic/glic.mojom
@@ -20,6 +20,10 @@ interface PageHandler { // Creates a WebClientHandler, for use by a single web client instance. CreateWebClient(pending_receiver<WebClientHandler> web_client_receiver); + + // Sync Google account sign-in cookies to the webview, so that it can sign-in + // automatically. + SyncWebviewCookies() => (bool success); }; // Reason why getting tab context failed. @@ -101,6 +105,11 @@ // the profile associated with this webui is invalid, which should only // possibly happen during teardown. GetUserProfileInfo() => (UserProfileInfo? profile_info); + + // Sync signin cookies to webview. This is the same as + // `PageHandler.SyncWebviewCookies()`, except this call originates from the + // webview. + SyncCookies() => (bool success); }; // State of the glic panel.
diff --git a/chrome/browser/ui/webui/glic/glic_page_handler.cc b/chrome/browser/ui/webui/glic/glic_page_handler.cc index fbcefc89..7a31664 100644 --- a/chrome/browser/ui/webui/glic/glic_page_handler.cc +++ b/chrome/browser/ui/webui/glic/glic_page_handler.cc
@@ -168,6 +168,10 @@ installed_ = false; } + void SyncCookies(SyncCookiesCallback callback) override { + glic_service_->SyncWebviewCookies(std::move(callback)); + } + private: void WebClientDisconnected() { Uninstall(); } @@ -215,5 +219,9 @@ web_client_handler_ = std::make_unique<GlicWebClientHandler>( browser_context_, std::move(web_client_receiver)); } +void GlicPageHandler::SyncWebviewCookies(SyncWebviewCookiesCallback callback) { + GlicKeyedServiceFactory::GetGlicKeyedService(browser_context_) + ->SyncWebviewCookies(std::move(callback)); +} } // namespace glic
diff --git a/chrome/browser/ui/webui/glic/glic_page_handler.h b/chrome/browser/ui/webui/glic/glic_page_handler.h index 3b9e057..cc94b664 100644 --- a/chrome/browser/ui/webui/glic/glic_page_handler.h +++ b/chrome/browser/ui/webui/glic/glic_page_handler.h
@@ -33,6 +33,8 @@ void CreateWebClient(::mojo::PendingReceiver<glic::mojom::WebClientHandler> web_client_receiver) override; + void SyncWebviewCookies(SyncWebviewCookiesCallback callback) override; + private: // There should at most one WebClientHandler at a time. A new one is created // each time the webview loads a page.
diff --git a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc index 0e17cff..f38acbb 100644 --- a/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc +++ b/chrome/browser/ui/webui/policy/policy_ui_browsertest.cc
@@ -1065,7 +1065,7 @@ // The browser's locale needs to be "en-US" to be able to see the banner static constexpr std::string_view kValidLocale = "en-US"; - static constexpr std::string_view kInvalidLocale = "not-en-US"; + static constexpr std::string_view kInvalidLocale = "en-AU"; protected: void SetPromotionBannerDismissedPref(bool is_dismissed) {
diff --git a/chrome/browser/ui/webui/searchbox/searchbox_handler.cc b/chrome/browser/ui/webui/searchbox/searchbox_handler.cc index 56937ad8..586da13d9 100644 --- a/chrome/browser/ui/webui/searchbox/searchbox_handler.cc +++ b/chrome/browser/ui/webui/searchbox/searchbox_handler.cc
@@ -6,6 +6,7 @@ #include "base/base64.h" #include "base/base64url.h" +#include "base/containers/contains.h" #include "build/branding_buildflags.h" #include "chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.h" #include "chrome/browser/bookmarks/bookmark_model_factory.h"
diff --git a/chrome/browser/ui/webui/settings/people_handler.cc b/chrome/browser/ui/webui/settings/people_handler.cc index 3f7102b0..a2d9241 100644 --- a/chrome/browser/ui/webui/settings/people_handler.cc +++ b/chrome/browser/ui/webui/settings/people_handler.cc
@@ -1125,7 +1125,22 @@ !service->GetUserSettings()->IsInitialSyncFeatureSetupComplete() && identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)); - const SyncStatusLabels status_labels = GetSyncStatusLabels(profile_); + SyncStatusLabels status_labels; + + // if flag enabled + if (switches::IsImprovedSettingsUIOnDesktopEnabled()) { + const std::optional<AvatarSyncErrorType> error = + GetAvatarSyncErrorType(profile_); + if (error.has_value()) { + status_labels = GetAvatarSyncErrorLabelsForSettings(error.value()); + } else { + status_labels = GetSyncStatusLabelsForSettings( + SyncServiceFactory::GetForProfile(profile_)); + } + } else { + status_labels = GetSyncStatusLabels(profile_); + } + // TODO(crbug.com/40660240): Consider unifying some of the fields below to // avoid redundancy. sync_status.Set("statusText",
diff --git a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager_unittest.cc b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager_unittest.cc index 8bce92a..ac06091 100644 --- a/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager_unittest.cc +++ b/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_update_manager_unittest.cc
@@ -1259,7 +1259,7 @@ // TODO(b/326527744): This test is flaky on asan ChromeOS builder. TEST_F(IsolatedWebAppUpdateManagerUpdateTest, - StopsNonStartedUpdateApplyTasksIfIwaIsUninstalled) { + DISABLED_StopsNonStartedUpdateApplyTasksIfIwaIsUninstalled) { AddDummyIsolatedAppToRegistry( profile(), iwa_info1_->url_info.origin().GetURL(), "installed app 1", IsolationData::Builder(iwa_info1_->installed_location,
diff --git a/chrome/browser/webauthn/enclave_manager.cc b/chrome/browser/webauthn/enclave_manager.cc index 107b4eb..a92c24c 100644 --- a/chrome/browser/webauthn/enclave_manager.cc +++ b/chrome/browser/webauthn/enclave_manager.cc
@@ -133,7 +133,8 @@ bool renew_pin = false; std::unique_ptr<StoreKeysArgs> store_keys_args; bool setup_account = false; - std::string pin; // the PIN to add to an account. + std::string pin; // the PIN to add to set up an account with. + std::string set_pin; // the PIN to set on an existing account. std::string updated_pin; // a new PIN, to replace the current PIN. std::string rapt; // ReAuthentication Proof Token. bool update_wrapped_pin; // copy `wrapped_pin` and `pin_public_key` to the @@ -1104,14 +1105,14 @@ kHashingPIN, kDownloadingRecoveryKeyStoreKeys, kWaitingForEnclaveTokenForPINWrapping, - kWrappingPIN, + kWrappingPINAndSecret, kWaitingForRecoveryKeyStore, kJoiningPINToDomain, kJoiningUpdatedPINToDomain, #if BUILDFLAG(IS_MAC) kJoiningICloudKeychainToDomain, #endif // BUILDFLAG(IS_MAC) - kChangingPIN, + kSettingPIN, kRenewingPIN, kWaitingForEnclaveTokenForUnregister, kUnregistering, @@ -1218,8 +1219,8 @@ DoWaitingForEnclaveTokenForPINWrapping(std::move(event)); break; - case State::kWrappingPIN: - DoWrappingPIN(std::move(event)); + case State::kWrappingPINAndSecret: + DoWrappingPINAndSecret(std::move(event)); break; case State::kWaitingForRecoveryKeyStore: @@ -1230,8 +1231,8 @@ DoJoiningPINToDomain(std::move(event)); break; - case State::kChangingPIN: - DoChangingPIN(std::move(event)); + case State::kSettingPIN: + DoSettingPIN(std::move(event)); break; case State::kJoiningUpdatedPINToDomain: @@ -1316,14 +1317,14 @@ return "DownloadingRecoveryKeyStoreKeys"; case State::kWaitingForEnclaveTokenForPINWrapping: return "WaitingForEnclaveTokenForPINWrapping"; - case State::kWrappingPIN: - return "WrappingPIN"; + case State::kWrappingPINAndSecret: + return "WrappingPINAndSecret"; case State::kWaitingForRecoveryKeyStore: return "WaitingForRecoveryKeyStore"; case State::kJoiningPINToDomain: return "JoiningPINToDomain"; - case State::kChangingPIN: - return "ChangingPIN"; + case State::kSettingPIN: + return "SettingPIN"; case State::kJoiningUpdatedPINToDomain: return "JoiningUpdatedPINToDomain"; case State::kRenewingPIN: @@ -1501,13 +1502,15 @@ } #endif // BUILDFLAG(IS_MAC) - if (!action_->updated_pin.empty()) { + if (!action_->set_pin.empty() || !action_->updated_pin.empty()) { if (!user_->registered()) { state_ = State::kStop; return; } - is_pin_update_ = true; + is_set_pin_ = !action_->set_pin.empty(); + is_pin_update_ = !action_->updated_pin.empty(); + CHECK(is_set_pin_ ^ is_pin_update_); rapt_ = std::move(action_->rapt); SyncWithSecurityDomain(); return; @@ -1956,8 +1959,15 @@ } } + if (is_set_pin_ && result->gpm_pin_metadata) { + // There is already a PIN. + state_ = State::kStop; + return; + } + state_ = State::kHashingPIN; - HashPIN(std::move(action_->updated_pin)); + HashPIN(action_->set_pin.empty() ? std::move(action_->updated_pin) + : std::move(action_->set_pin)); } void DoHashingPIN(Event event) { @@ -2023,17 +2033,17 @@ CHECK(absl::holds_alternative<AccessToken>(event)) << ToString(event); std::string token = std::move(absl::get_if<AccessToken>(&event)->value()); - if (is_pin_update_) { - SendPINChangeRequest(std::move(token)); + if (is_set_pin_ || is_pin_update_) { + SendPINSetRequest(std::move(token)); } else if (is_pin_renewal_) { SendPINRenewalRequest(std::move(token)); } else { - SendPINWrappingRequest(std::move(token)); + SendPINAndSecretWrappingRequest(std::move(token)); } } - void SendPINWrappingRequest(std::string token) { - state_ = State::kWrappingPIN; + void SendPINAndSecretWrappingRequest(std::string token) { + state_ = State::kWrappingPINAndSecret; enclave::Transact( manager_->network_context_factory_, enclave::GetEnclaveIdentity(), std::move(token), @@ -2049,13 +2059,13 @@ weak_ptr_factory_.GetWeakPtr())); } - void SendPINChangeRequest(std::string token) { + void SendPINSetRequest(std::string token) { uint8_t counter_id[enclave::kCounterIDLen]; crypto::RandBytes(counter_id); uint8_t vault_handle_without_type[enclave::kVaultHandleLen - 1]; crypto::RandBytes(vault_handle_without_type); - state_ = State::kChangingPIN; + state_ = State::kSettingPIN; std::vector<uint8_t> wrapped_secret = GetCurrentWrappedSecretForUser(user_).second; enclave::Transact( @@ -2095,7 +2105,7 @@ weak_ptr_factory_.GetWeakPtr())); } - void DoWrappingPIN(Event event) { + void DoWrappingPINAndSecret(Event event) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (absl::holds_alternative<Failure>(event)) { @@ -2163,7 +2173,7 @@ } const bool updating_pin_member = is_pin_update_ || is_pin_renewal_; - if (!updating_pin_member) { + if (!updating_pin_member && !is_set_pin_) { CHECK(wrapped_pin_proto_->wrapped_pin().empty()); wrapped_pin_proto_->set_wrapped_pin(BuildWrappedPIN( *hashed_pin_, /*generation=*/0, @@ -2185,15 +2195,17 @@ CHECK_EQ(!previous_pin_public_key.empty(), updating_pin_member); user_->set_pin_public_key(vault_public_key); - state_ = updating_pin_member ? State::kJoiningUpdatedPINToDomain - : State::kJoiningPINToDomain; + state_ = (updating_pin_member || is_set_pin_) + ? State::kJoiningUpdatedPINToDomain + : State::kJoiningPINToDomain; std::optional<trusted_vault::MemberKeysSource> member_keys_source = std::move(member_keys_source_); - // If changing or renewing a PIN then `member_keys_source` will have been - // populated by the enclave. Otherwise a new PIN is being set and + // If changing, renewing, or setting a PIN then `member_keys_source` will + // have been populated by the enclave. Otherwise a new PIN is being set and // `store_keys_args_for_joining_` will contain the security domain secret, // which is sufficient for calculating the member keys. - CHECK_EQ(member_keys_source.has_value(), updating_pin_member); + CHECK_EQ(member_keys_source.has_value(), + updating_pin_member || is_set_pin_); if (!member_keys_source) { member_keys_source = trusted_vault::GetTrustedVaultKeysWithVersions( store_keys_args_for_joining_->keys, @@ -2224,12 +2236,19 @@ return; } + if (is_set_pin_) { + // If adding a PIN to an existing account, then we're done. + success_ = true; + state_ = State::kStop; + return; + } + store_keys_args_for_joining_->last_key_version = key_version; if (!StoreWrappedSecrets( user_, GetNewSecretsToStore(*user_, *store_keys_args_for_joining_), base::span_from_ref(wrapping_response_->GetArray()[1]))) { - FIDO_LOG(ERROR) << "Secret wrapping resulted in malformed resposne: " + FIDO_LOG(ERROR) << "Secret wrapping resulted in malformed response: " << cbor::DiagnosticWriter::Write(*wrapping_response_); state_ = State::kStop; return; @@ -2274,7 +2293,7 @@ } #endif // BUILDFLAG(IS_MAC) - void DoChangingPIN(Event event) { + void DoSettingPIN(Event event) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); state_ = State::kStop; @@ -2562,6 +2581,8 @@ std::unique_ptr<trusted_vault::RecoveryKeyStoreConnection::Request> recovery_key_store_request_; std::optional<cbor::Value> wrapping_response_; + // True if a PIN is being hashed in order to add to an existing account. + bool is_set_pin_ = false; // True if a PIN is being hashed in order to change it, rather than to set // a new PIN on an account. bool is_pin_update_ = false; @@ -2738,6 +2759,20 @@ Act(); } +void EnclaveManager::SetPIN(std::string pin, + std::string rapt, + EnclaveManager::Callback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(user_->registered()); + + auto action = std::make_unique<PendingAction>(); + action->callback = std::move(callback); + action->set_pin = std::move(pin); + action->rapt = std::move(rapt); + pending_actions_.emplace_back(std::move(action)); + Act(); +} + void EnclaveManager::ChangePIN(std::string updated_pin, std::string rapt, EnclaveManager::Callback callback) {
diff --git a/chrome/browser/webauthn/enclave_manager.h b/chrome/browser/webauthn/enclave_manager.h index 886d872d..8b6c221 100644 --- a/chrome/browser/webauthn/enclave_manager.h +++ b/chrome/browser/webauthn/enclave_manager.h
@@ -184,6 +184,8 @@ // to call after `StoreKeys` has been called and thus `has_pending_keys` // returns true. void AddDeviceAndPINToAccount(std::string pin, Callback callback); + // Set a PIN on an account that doesn't currently have one. + void SetPIN(std::string pin, std::string rapt, Callback callback); // Change the GPM PIN on the account. If a RAPT (Reauthentication Proof Token) // is given then it will be used, otherwise the UV key will be used, causing // system UI to appear to verify the user.
diff --git a/chrome/browser/webauthn/enclave_manager_unittest.cc b/chrome/browser/webauthn/enclave_manager_unittest.cc index 39de4c2..d224a2e 100644 --- a/chrome/browser/webauthn/enclave_manager_unittest.cc +++ b/chrome/browser/webauthn/enclave_manager_unittest.cc
@@ -888,6 +888,71 @@ GetAssertionResponseExpectation()); } +TEST_F(EnclaveManagerTest, AddPINToExistingAccount) { + security_domain_service_->pretend_there_are_members(); + const std::string new_pin = "newpin"; + + std::vector<uint8_t> key(kTestKey.begin(), kTestKey.end()); + ASSERT_FALSE(manager_.has_pending_keys()); + manager_.StoreKeys(gaia_id_, {std::move(key)}, + /*last_key_version=*/kSecretVersion); + ASSERT_TRUE(manager_.has_pending_keys()); + + BoolFuture add_future; + manager_.AddDeviceToAccount(std::nullopt, add_future.GetCallback()); + EXPECT_TRUE(add_future.Wait()); + ASSERT_TRUE(manager_.is_ready()); + const std::vector<uint8_t> security_domain_secret = + std::move(manager_.TakeSecret()->second); + + BoolFuture set_pin_future; + manager_.SetPIN(new_pin, "rapt", set_pin_future.GetCallback()); + EXPECT_TRUE(set_pin_future.Wait()); + ASSERT_TRUE(set_pin_future.Get()); + + EXPECT_EQ(security_domain_service_->num_physical_members(), 1u); + EXPECT_EQ(security_domain_service_->num_pin_members(), 1u); + EXPECT_EQ(recovery_key_store_->vaults().size(), 1u); + const std::optional<std::vector<uint8_t>> recovered_security_domain_secret = + FakeMagicArch::RecoverWithPIN(new_pin, *security_domain_service_, + *recovery_key_store_); + CHECK(recovered_security_domain_secret.has_value()); + EXPECT_EQ(*recovered_security_domain_secret, security_domain_secret); + + std::unique_ptr<device::enclave::ClaimedPIN> claimed_pin = + EnclaveManager::MakeClaimedPINSlowly(new_pin, manager_.GetWrappedPIN()); + std::unique_ptr<sync_pb::WebauthnCredentialSpecifics> entity; + DoCreate(/*claimed_pin=*/nullptr, &entity); + DoAssertion(std::move(entity), std::move(claimed_pin), + GetAssertionResponseExpectation()); +} + +TEST_F(EnclaveManagerTest, AddPINToExistingAccountButTheresAlreadyOne) { + security_domain_service_->pretend_there_are_members(); + const std::string pin = "pin"; + const std::string new_pin = "newpin"; + + std::vector<uint8_t> key(kTestKey.begin(), kTestKey.end()); + ASSERT_FALSE(manager_.has_pending_keys()); + manager_.StoreKeys(gaia_id_, {std::move(key)}, + /*last_key_version=*/kSecretVersion); + ASSERT_TRUE(manager_.has_pending_keys()); + + BoolFuture add_future; + manager_.AddDeviceAndPINToAccount(pin, add_future.GetCallback()); + EXPECT_TRUE(add_future.Wait()); + ASSERT_TRUE(manager_.is_ready()); + const std::vector<uint8_t> security_domain_secret = + std::move(manager_.TakeSecret()->second); + + BoolFuture set_pin_future; + manager_.SetPIN(new_pin, "rapt", set_pin_future.GetCallback()); + EXPECT_TRUE(set_pin_future.Wait()); + + // This should fail because there's already a PIN set. + ASSERT_FALSE(set_pin_future.Get()); +} + TEST_F(EnclaveManagerTest, ChangePINWithTwoDevices) { security_domain_service_->pretend_there_are_members(); const std::string pin = "pin";
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 786c1cf1..c069639 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1736164015-a2e4e97014cc2d6347bed764c6acf3dda22c1ebc-9036501137b419fc1fe11d418547f3ae0bcd7d94.profdata +chrome-android32-main-1736186382-0f1becc19629091e3833d4081d50db5a6705ea66-46e5d6b5d02dac49d2d882bd84e288bb640b2429.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index 8e82440..ad8e8a97 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1736173361-186c1a765eae389d12d2909dd7d00c34e8337b8e-5435124828be2b05da46b94530bb88869181eb85.profdata +chrome-android64-main-1736194541-15e8ab9fa98f148286a5dd2e807250681cb0054f-a3f9fcb35c2cc2dabf94b6acf3677b50ca0d8d9e.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index d4adc36..ac98aa8f 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1736164015-0f903cdba3e02334be4204dacea103b94405707c-9036501137b419fc1fe11d418547f3ae0bcd7d94.profdata +chrome-linux-main-1736186382-aee256fd05601db48ad70d1e42a126f5cb913058-46e5d6b5d02dac49d2d882bd84e288bb640b2429.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index c8f2cb3ad..719de55 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1736171909-4cdb932f3ef2559993ccb2385897099eb9c20087-86d72d0261b16de5ffcab9f1284fb7956766488e.profdata +chrome-mac-arm-main-1736186382-59adf927053f5ee23d8c418fb8c634928fc66da4-46e5d6b5d02dac49d2d882bd84e288bb640b2429.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index 2aedf2f..670ee23 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1736164015-a8c200e8881226c479fe1c4fffda409bc93d83f4-9036501137b419fc1fe11d418547f3ae0bcd7d94.profdata +chrome-mac-main-1736186382-e7562175a8d83e5061e66b31e97fb3828eadf591-46e5d6b5d02dac49d2d882bd84e288bb640b2429.profdata
diff --git a/chrome/build/win-arm64.pgo.txt b/chrome/build/win-arm64.pgo.txt index 286c5c7..97adc10d 100644 --- a/chrome/build/win-arm64.pgo.txt +++ b/chrome/build/win-arm64.pgo.txt
@@ -1 +1 @@ -chrome-win-arm64-main-1736164015-37f22b2e0fafc48030c529e34802b4bae4dbc11b-9036501137b419fc1fe11d418547f3ae0bcd7d94.profdata +chrome-win-arm64-main-1736186382-9a4d6a9b398eb1d364bbd2ee51d0c3783b60c984-46e5d6b5d02dac49d2d882bd84e288bb640b2429.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index 187b090..9a14eecd 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1736153710-5077d38cc01bd6e37e0ec45691f909dc2fb9cc0e-fa7d5850ace87798e8c16c93268ad0cfb35aca8c.profdata +chrome-win32-main-1736175397-2de91431a0b8c58704ee06e4f8fe05b74b3bde3a-e6c1a1be20ee034550551e58c5b254029123bb41.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index e5e4ed80..a0125e3 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1736142401-3f611aa3dad57eab20c7d0d4b75170a2dfcf87fd-c8f265f6c7bdc2efe5221925909c82fa4a421a95.profdata +chrome-win64-main-1736175397-b79f209eeeff8ad456dcbd4afc1cb67325955c12-e6c1a1be20ee034550551e58c5b254029123bb41.profdata
diff --git a/chrome/common/profiler/thread_profiler_platform_configuration.cc b/chrome/common/profiler/thread_profiler_platform_configuration.cc index 7514fc80..fc9ee5b4 100644 --- a/chrome/common/profiler/thread_profiler_platform_configuration.cc +++ b/chrome/common/profiler/thread_profiler_platform_configuration.cc
@@ -276,14 +276,6 @@ sampling_profiler::ProfilerProcessType process, sampling_profiler::ProfilerThreadType thread, std::optional<version_info::Channel> release_channel) const { -#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_ARM64) - // For now, we only enable SSM in the Browser process and Main thread on - // Android 64, since Libunwindstack doesn't support JavaScript. - if (!(process == sampling_profiler::ProfilerProcessType::kBrowser && - thread == sampling_profiler::ProfilerThreadType::kMain)) { - return false; - } -#endif if (!release_channel.has_value() || browser_test_mode_enabled()) { return true; }
diff --git a/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc b/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc index 3505f64..8489447 100644 --- a/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc +++ b/chrome/common/profiler/thread_profiler_platform_configuration_unittest.cc
@@ -161,21 +161,10 @@ continue; } -#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_ARM64) - if (process == sampling_profiler::ProfilerProcessType::kBrowser && - thread == sampling_profiler::ProfilerThreadType::kMain) { - EXPECT_TRUE(config()->IsEnabledForThread( - process, thread, version_info::Channel::CANARY)); - } else { - EXPECT_FALSE(config()->IsEnabledForThread( - process, thread, version_info::Channel::CANARY)); - } -#else EXPECT_TRUE(config()->IsEnabledForThread(process, thread, version_info::Channel::CANARY)); -#endif -#if BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_ARMEL) +#if BUILDFLAG(IS_ANDROID) auto android_config1 = ThreadProfilerPlatformConfiguration::Create( /* browser_test_mode_enabled=*/false, base::BindLambdaForTesting([](double probability) { return true; })); @@ -186,25 +175,6 @@ base::BindLambdaForTesting([](double probability) { return false; })); EXPECT_FALSE(android_config2->IsEnabledForThread( process, thread, version_info::Channel::DEV)); -#elif BUILDFLAG(IS_ANDROID) && defined(ARCH_CPU_ARM64) - auto android_config1 = ThreadProfilerPlatformConfiguration::Create( - /* browser_test_mode_enabled=*/false, - base::BindLambdaForTesting([](double probability) { return true; })); - auto android_config2 = ThreadProfilerPlatformConfiguration::Create( - /* browser_test_mode_enabled=*/false, - base::BindLambdaForTesting([](double probability) { return false; })); - - if (process == sampling_profiler::ProfilerProcessType::kBrowser && - thread == sampling_profiler::ProfilerThreadType::kMain) { - EXPECT_TRUE(android_config1->IsEnabledForThread( - process, thread, version_info::Channel::DEV)); - } else { - EXPECT_FALSE(android_config1->IsEnabledForThread( - process, thread, version_info::Channel::DEV)); - } - - EXPECT_FALSE(android_config2->IsEnabledForThread( - process, thread, version_info::Channel::DEV)); #else EXPECT_TRUE(config()->IsEnabledForThread(process, thread, version_info::Channel::DEV));
diff --git a/chrome/test/BUILD.gn b/chrome/test/BUILD.gn index 7a3db410..d00b90c 100644 --- a/chrome/test/BUILD.gn +++ b/chrome/test/BUILD.gn
@@ -8197,7 +8197,6 @@ "../browser/nearby_sharing/nearby_receive_manager_unittest.cc", "../browser/nearby_sharing/nearby_share_delegate_impl_unittest.cc", "../browser/nearby_sharing/nearby_share_feature_usage_metrics_unittest.cc", - "../browser/nearby_sharing/nearby_share_profile_info_provider_impl_unittest.cc", "../browser/nearby_sharing/nearby_share_settings_unittest.cc", "../browser/nearby_sharing/nearby_share_transfer_profiler_unittest.cc", "../browser/nearby_sharing/nearby_sharing_service_impl_unittest.cc",
diff --git a/chrome/test/base/android/android_browser_test.cc b/chrome/test/base/android/android_browser_test.cc index 0c8876a..237b3d2 100644 --- a/chrome/test/base/android/android_browser_test.cc +++ b/chrome/test/base/android/android_browser_test.cc
@@ -7,6 +7,7 @@ #include "base/command_line.h" #include "chrome/browser/ui/android/tab_model/tab_model.h" #include "chrome/browser/ui/android/tab_model/tab_model_list.h" +#include "chrome/test/base/chrome_test_utils.h" #include "chrome/test/base/test_launcher_utils.h" #include "content/public/test/test_utils.h" @@ -58,3 +59,7 @@ } return count; } + +base::FilePath AndroidBrowserTest::GetChromeTestDataDir() const { + return chrome_test_utils::GetChromeTestDataDir(); +}
diff --git a/chrome/test/base/android/android_browser_test.h b/chrome/test/base/android/android_browser_test.h index 811c0fd..6af6fcb 100644 --- a/chrome/test/base/android/android_browser_test.h +++ b/chrome/test/base/android/android_browser_test.h
@@ -48,6 +48,9 @@ // and setup functions. static size_t GetTestPreCount(); + // Returns the test data path used by the embedded test server. + base::FilePath GetChromeTestDataDir() const; + private: // Temporary user data directory. Used only when a user data directory is not // specified in the command line.
diff --git a/chrome/test/base/chrome_test_utils.cc b/chrome/test/base/chrome_test_utils.cc index 74067ea8..a5818d1 100644 --- a/chrome/test/base/chrome_test_utils.cc +++ b/chrome/test/base/chrome_test_utils.cc
@@ -40,4 +40,8 @@ #endif } +base::FilePath GetChromeTestDataDir() { + return base::FilePath(FILE_PATH_LITERAL("chrome/test/data")); +} + } // namespace chrome_test_utils
diff --git a/chrome/test/base/chrome_test_utils.h b/chrome/test/base/chrome_test_utils.h index f94c698b..2cf06ac03 100644 --- a/chrome/test/base/chrome_test_utils.h +++ b/chrome/test/base/chrome_test_utils.h
@@ -26,6 +26,9 @@ // window created by tests, more specific behaviour requires other means. Profile* GetProfile(PlatformBrowserTest* browser_test); +// Returns the test data path used by the embedded test server. +base::FilePath GetChromeTestDataDir(); + } // namespace chrome_test_utils #endif // CHROME_TEST_BASE_CHROME_TEST_UTILS_H_
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index daebdc9..7369742 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -73,6 +73,7 @@ #include "chrome/common/url_constants.h" #include "chrome/renderer/chrome_content_renderer_client.h" #include "chrome/test/base/chrome_test_suite.h" +#include "chrome/test/base/chrome_test_utils.h" #include "chrome/test/base/test_launcher_utils.h" #include "chrome/test/base/testing_browser_process.h" #include "chrome/test/base/ui_test_utils.h" @@ -821,7 +822,7 @@ #endif // !BUILDFLAG(IS_MAC) base::FilePath InProcessBrowserTest::GetChromeTestDataDir() const { - return base::FilePath(FILE_PATH_LITERAL("chrome/test/data")); + return chrome_test_utils::GetChromeTestDataDir(); } void InProcessBrowserTest::PreRunTestOnMainThread() {
diff --git a/chrome/test/data/browsing_topics/topics-writable-pixel.png b/chrome/test/data/browsing_topics/topics-writable-pixel.png new file mode 100644 index 0000000..818c71d --- /dev/null +++ b/chrome/test/data/browsing_topics/topics-writable-pixel.png Binary files differ
diff --git a/chrome/test/data/browsing_topics/topics-writable-pixel.png.mock-http-headers b/chrome/test/data/browsing_topics/topics-writable-pixel.png.mock-http-headers new file mode 100644 index 0000000..90c64ce3 --- /dev/null +++ b/chrome/test/data/browsing_topics/topics-writable-pixel.png.mock-http-headers
@@ -0,0 +1,4 @@ +HTTP/1.1 {{STATUS}} +Access-Control-Allow-Origin: * +{{OBSERVE_BROWSING_TOPICS_HEADER}} +{{REDIRECT_HEADER}}
diff --git a/chrome/test/data/browsing_topics/topics-writable-pixel2.png b/chrome/test/data/browsing_topics/topics-writable-pixel2.png new file mode 100644 index 0000000..818c71d --- /dev/null +++ b/chrome/test/data/browsing_topics/topics-writable-pixel2.png Binary files differ
diff --git a/chrome/test/data/browsing_topics/topics-writable-pixel2.png.mock-http-headers b/chrome/test/data/browsing_topics/topics-writable-pixel2.png.mock-http-headers new file mode 100644 index 0000000..90c64ce3 --- /dev/null +++ b/chrome/test/data/browsing_topics/topics-writable-pixel2.png.mock-http-headers
@@ -0,0 +1,4 @@ +HTTP/1.1 {{STATUS}} +Access-Control-Allow-Origin: * +{{OBSERVE_BROWSING_TOPICS_HEADER}} +{{REDIRECT_HEADER}}
diff --git a/chrome/test/data/extensions/api_test/scripting/css_injection/manifest.json b/chrome/test/data/extensions/api_test/scripting/css_injection/manifest.json index 400d8d8..03aaa81a 100644 --- a/chrome/test/data/extensions/api_test/scripting/css_injection/manifest.json +++ b/chrome/test/data/extensions/api_test/scripting/css_injection/manifest.json
@@ -10,6 +10,7 @@ "host_permissions": [ "http://example.com/*", "http://subframes.example/*", - "http://b.com/*" + "http://b.com/*", + "http://subframes-sandboxed.example/*" ] }
diff --git a/chrome/test/data/extensions/api_test/scripting/css_injection/worker.js b/chrome/test/data/extensions/api_test/scripting/css_injection/worker.js index 0b6cdd6..1b81f9a 100644 --- a/chrome/test/data/extensions/api_test/scripting/css_injection/worker.js +++ b/chrome/test/data/extensions/api_test/scripting/css_injection/worker.js
@@ -16,7 +16,8 @@ function getBodyColor() { const hostname = (new URL(location.href)).hostname; - return hostname + ' ' + getComputedStyle(document.body).backgroundColor; + return (hostname || location.href) + ' ' + + getComputedStyle(document.body).backgroundColor; } async function getBodyColorsForTab(tabId) { @@ -75,6 +76,25 @@ chrome.test.succeed(); }, + async function sandboxedSubframes() { + const query = {url: 'http://subframes-sandboxed.example/*'}; + const tab = await getSingleTab(query); + const results = await chrome.scripting.insertCSS({ + target: { + tabId: tab.id, + allFrames: true, + }, + css: CSS_RED, + }); + chrome.test.assertEq(undefined, results); + const colors = await getBodyColorsForTab(tab.id); + chrome.test.assertEq(2, colors.length); + colors.sort(); + chrome.test.assertEq(`about:srcdoc ${RED}`, colors[0]); + chrome.test.assertEq(`subframes-sandboxed.example ${RED}`, colors[1]); + chrome.test.succeed(); + }, + async function specificFrames() { const query = {url: 'http://subframes.example/*'}; const tab = await getSingleTab(query);
diff --git a/chrome/test/data/extensions/api_test/scripting/remove_css/frame3.html b/chrome/test/data/extensions/api_test/scripting/remove_css/frame3.html index 70d813f7..6b68ee4 100644 --- a/chrome/test/data/extensions/api_test/scripting/remove_css/frame3.html +++ b/chrome/test/data/extensions/api_test/scripting/remove_css/frame3.html
@@ -7,5 +7,5 @@ <div id="main"> Hello. </div> - <iframe id="frame4" srcdoc="<style>#main{color:red}</style><div id='main'>Hello.</div>"></iframe> + <iframe id="frame4" sandbox srcdoc="<style>#main{color:red}</style><div id='main'>Hello.</div>"></iframe> </html>
diff --git a/chrome/test/data/extensions/api_test/scripting/sub_frames/manifest.json b/chrome/test/data/extensions/api_test/scripting/sub_frames/manifest.json index 4b32740..77136cc 100644 --- a/chrome/test/data/extensions/api_test/scripting/sub_frames/manifest.json +++ b/chrome/test/data/extensions/api_test/scripting/sub_frames/manifest.json
@@ -7,5 +7,5 @@ "service_worker": "worker.js", "type": "module" }, - "host_permissions": ["http://a.com/*", "http://b.com/*"] + "host_permissions": ["http://a.com/*", "http://b.com/*", "http://e.com/*"] }
diff --git a/chrome/test/data/extensions/api_test/scripting/sub_frames/worker.js b/chrome/test/data/extensions/api_test/scripting/sub_frames/worker.js index 94459d79..cf1ee76 100644 --- a/chrome/test/data/extensions/api_test/scripting/sub_frames/worker.js +++ b/chrome/test/data/extensions/api_test/scripting/sub_frames/worker.js
@@ -382,4 +382,24 @@ chrome.test.succeed(); }, + async function injectIntoSandboxedSrcdoc() { + const tab = await getSingleTab({url: 'http://e.com/*'}); + const results = await chrome.scripting.executeScript({ + target: { + tabId: tab.id, + allFrames: true, + }, + func: injectedFunction, + }); + chrome.test.assertEq(2, results.length); + + // Note: The 'e.com' result is guaranteed to be first, since it's the root + // frame. + const url1 = new URL(results[0].result); + chrome.test.assertEq('e.com', url1.hostname); + + chrome.test.assertEq('about:srcdoc', results[1].result); + chrome.test.succeed(); + }, + ]);
diff --git a/chrome/test/data/webui/chromeos/BUILD.gn b/chrome/test/data/webui/chromeos/BUILD.gn index 234e96b..5973adf 100644 --- a/chrome/test/data/webui/chromeos/BUILD.gn +++ b/chrome/test/data/webui/chromeos/BUILD.gn
@@ -234,7 +234,7 @@ "network/network_nameservers_test.ts", "network/network_password_input_test.js", "network/network_property_list_mojo_test.js", - "network/network_proxy_exclusions_test.js", + "network/network_proxy_exclusions_test.ts", "network/network_proxy_input_test.ts", "network/network_proxy_test.ts", "network/network_select_test.ts",
diff --git a/chrome/test/data/webui/chromeos/network/network_proxy_exclusions_test.js b/chrome/test/data/webui/chromeos/network/network_proxy_exclusions_test.js deleted file mode 100644 index 76c28a1..0000000 --- a/chrome/test/data/webui/chromeos/network/network_proxy_exclusions_test.js +++ /dev/null
@@ -1,42 +0,0 @@ -// Copyright 2020 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://os-settings/strings.m.js'; -import 'chrome://resources/ash/common/network/network_proxy_exclusions.js'; - -import {flush} from 'chrome://resources/polymer/v3_0/polymer/polymer_bundled.min.js'; -import {assertDeepEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; - -suite('NetworkProxyExclusionsTest', function() { - /** @type {!NetworkProxyExclusions|undefined} */ - let proxyExclusions; - - setup(function() { - proxyExclusions = document.createElement('network-proxy-exclusions'); - document.body.appendChild(proxyExclusions); - flush(); - }); - - test('Clear fires proxy-exclusions-change event', function(done) { - proxyExclusions.exclusions = [ - 'one', - 'two', - 'three', - ]; - flush(); - - // Verify that clicking the clear button fires the proxy-exclusions-change - // event and that the item was removed from the exclusions list. - proxyExclusions.addEventListener('proxy-exclusions-change', function() { - assertDeepEquals(proxyExclusions.exclusions, ['two', 'three']); - done(); - }); - - const clearBtn = proxyExclusions.$$('cr-icon-button'); - assertTrue(!!clearBtn); - - // Simulate pressing clear on the first exclusion list item. - clearBtn.click(); - }); -});
diff --git a/chrome/test/data/webui/chromeos/network/network_proxy_exclusions_test.ts b/chrome/test/data/webui/chromeos/network/network_proxy_exclusions_test.ts new file mode 100644 index 0000000..6e9e690a --- /dev/null +++ b/chrome/test/data/webui/chromeos/network/network_proxy_exclusions_test.ts
@@ -0,0 +1,52 @@ +// Copyright 2020 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://os-settings/strings.m.js'; +import 'chrome://resources/ash/common/network/network_proxy_exclusions.js'; + +import {NetworkProxyExclusionsElement} from 'chrome://resources/ash/common/network/network_proxy_exclusions.js'; +import {assertDeepEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; + +suite('NetworkProxyExclusionsTest', () => { + let proxyExclusions: NetworkProxyExclusionsElement; + + setup(async () => { + proxyExclusions = document.createElement('network-proxy-exclusions'); + document.body.appendChild(proxyExclusions); + await flushTasks(); + }); + + teardown(async () => { + if (!proxyExclusions) { + return; + } + proxyExclusions.remove(); + await flushTasks(); + }); + + test('Clear fires proxy-exclusions-change event', async () => { + proxyExclusions.exclusions = [ + 'one', + 'two', + 'three', + ]; + await flushTasks(); + + const clearBtn = + proxyExclusions.shadowRoot!.querySelector('cr-icon-button'); + assertTrue(!!clearBtn); + + // Verify that clicking the clear button fires the proxy-exclusions-change + // event and that the item was removed from the exclusions list. + const proxyExclusionsChangeEvent = + eventToPromise('proxy-exclusions-change', proxyExclusions); + clearBtn.click(); + await proxyExclusionsChangeEvent; + await flushTasks(); + assertDeepEquals(1, 1); + assertDeepEquals(proxyExclusions.exclusions, ['two', 'three']); + }); +});
diff --git a/chrome/test/data/webui/commerce/product_specifications/app_test.ts b/chrome/test/data/webui/commerce/product_specifications/app_test.ts index cefac4ef..f971587 100644 --- a/chrome/test/data/webui/commerce/product_specifications/app_test.ts +++ b/chrome/test/data/webui/commerce/product_specifications/app_test.ts
@@ -195,6 +195,11 @@ return eventToPromise(LOADING_END_EVENT_TYPE, appElement); } + function focusWindowAndTriggerSetUpdate(set: ProductSpecificationsSet) { + appElement.focusWindowForTesting(); + callbackRouterRemote.onProductSpecificationsSetUpdated(set); + } + setup(async () => { document.body.innerHTML = window.trustedTypes!.emptyHTML; loadTimeData.overrideValues({ @@ -928,7 +933,7 @@ // Trigger an update where the URLs haven't changed, they just change order. const orderSwitchedSpecsSetUrls = [{url: 'https://example.com/2'}, {url: 'https://example.com/1'}]; - callbackRouterRemote.onProductSpecificationsSetUpdated(createSpecsSet( + focusWindowAndTriggerSetUpdate(createSpecsSet( {urls: orderSwitchedSpecsSetUrls, uuid: {value: testId}})); await waitAfterNextRender(appElement); @@ -1024,7 +1029,7 @@ shoppingServiceApi.getArgs('getProductSpecificationsForUrls')[0]); // Trigger an update where only the title has changed. - callbackRouterRemote.onProductSpecificationsSetUpdated(createSpecsSet( + focusWindowAndTriggerSetUpdate(createSpecsSet( {name: 'Diff title', urls: specsSetUrls, uuid: {value: testId}})); await waitAfterNextRender(appElement); @@ -1076,7 +1081,7 @@ shoppingServiceApi.getArgs('getProductSpecificationsForUrls')[0]); // Trigger an update where only the title has changed. - callbackRouterRemote.onProductSpecificationsSetUpdated(createSpecsSet( + focusWindowAndTriggerSetUpdate(createSpecsSet( {urls: [{url: 'https://example.com/new_url'}], uuid: {value: testId}})); await waitAfterNextRender(appElement); @@ -1522,7 +1527,7 @@ assertEquals('My products', document.title); // Simulate a name change from sync. - callbackRouterRemote.onProductSpecificationsSetUpdated(createSpecsSet( + focusWindowAndTriggerSetUpdate(createSpecsSet( {name: 'My specific products', urls: [], uuid: {value: testId}})); await flushTasks(); @@ -1697,7 +1702,7 @@ }, })); // Simulate an update from sync (as a result of the above change). - callbackRouterRemote.onProductSpecificationsSetUpdated( + focusWindowAndTriggerSetUpdate( createSpecsSet({urls: [], uuid: {value: testId}})); await waitAfterNextRender(appElement); @@ -1912,7 +1917,7 @@ }, })); // Simulate an update from sync (as a result of the above change). - callbackRouterRemote.onProductSpecificationsSetUpdated( + focusWindowAndTriggerSetUpdate( createSpecsSet({urls: [], uuid: {value: testId}})); // There's no loading animation when transitioning to the empty state, so // we don't need to wait for loading to end. @@ -2391,7 +2396,7 @@ const appElement = await createAppElement(); await flushTasks(); - callbackRouterRemote.onProductSpecificationsSetUpdated({ + focusWindowAndTriggerSetUpdate({ name: 'def', uuid: {value: '123'}, urls: [{url: 'http://example2.com'}],
diff --git a/chrome/test/data/webui/commerce/product_specifications/description_citation_test.ts b/chrome/test/data/webui/commerce/product_specifications/description_citation_test.ts index a72a0a82..7590df4 100644 --- a/chrome/test/data/webui/commerce/product_specifications/description_citation_test.ts +++ b/chrome/test/data/webui/commerce/product_specifications/description_citation_test.ts
@@ -7,7 +7,7 @@ import type {DescriptionCitationElement} from 'chrome://compare/description_citation.js'; import {loadTimeData} from 'chrome://resources/js/load_time_data.js'; import {OpenWindowProxyImpl} from 'chrome://resources/js/open_window_proxy.js'; -import {assertEquals, assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {assertEquals, assertFalse, assertTrue} from 'chrome://webui-test/chai_assert.js'; import type {MetricsTracker} from 'chrome://webui-test/metrics_test_support.js'; import {fakeMetricsPrivate} from 'chrome://webui-test/metrics_test_support.js'; import {flushTasks} from 'chrome://webui-test/polymer_test_util.js'; @@ -24,11 +24,17 @@ document.body.innerHTML = window.trustedTypes!.emptyHTML; citationElement = document.createElement('description-citation'); - citationElement.url = 'http://example.com/initial_url'; + citationElement.urlInfo = { + title: '', + url: {url: 'http://example.com/initial_url'}, + faviconUrl: {url: ''}, + thumbnailUrl: {url: ''}, + previewText: '', + }; document.body.appendChild(citationElement); loadTimeData.overrideValues({ - citationA11yLabel: 'Citation $1 of $2, $3, $4', + citationA11yLabel: 'Citation $1 of $2, $3, $4. $5. $6.', }); await flushTasks(); @@ -36,17 +42,56 @@ test('citation renders correctly', async () => { citationElement.index = 4; - citationElement.url = 'http://example.com/long/path/url'; + citationElement.urlInfo = { + title: 'Page Title', + url: {url: 'http://example.com/long/path/url'}, + faviconUrl: {url: 'https://example.com/favicon.png'}, + thumbnailUrl: {url: ''}, + previewText: 'Preview text', + }; citationElement.citationCount = 8; citationElement.productName = 'product'; await flushTasks(); assertTrue(!!citationElement.$.citation); assertEquals('4', citationElement.$.citation.textContent!?.trim()); - assertEquals('example.com', citationElement.$.tooltip.textContent!?.trim()); + assertTrue(citationElement.$.tooltip.textContent!?.includes('example.com')); + + assertTrue( + !!citationElement.shadowRoot!.querySelector('.faviconContainer')); + assertTrue(!!citationElement.shadowRoot!.querySelector('.previewText')); + + const label = loadTimeData.getStringF( + 'citationA11yLabel', 4, 8, 'product', 'example.com', 'Page Title', + 'Preview text'); + const elementAriaContent = + citationElement.$.citation.getAttribute('aria-label') || ''; + assertEquals(label, elementAriaContent); + }); + + test('citation without favicon url or preview text', async () => { + citationElement.index = 4; + citationElement.urlInfo = { + title: '', + url: {url: 'http://example.com/long/path/url'}, + faviconUrl: {url: ''}, + thumbnailUrl: {url: ''}, + previewText: '', + }; + citationElement.citationCount = 8; + citationElement.productName = 'product'; + await flushTasks(); + + assertTrue(!!citationElement.$.citation); + assertEquals('4', citationElement.$.citation.textContent!?.trim()); + assertTrue(citationElement.$.tooltip.textContent!?.includes('example.com')); + + assertFalse( + !!citationElement.shadowRoot!.querySelector('.faviconContainer')); + assertFalse(!!citationElement.shadowRoot!.querySelector('.previewText')); const expectedAriaLabel = loadTimeData.getStringF( - 'citationA11yLabel', 4, 8, 'product', 'example.com'); + 'citationA11yLabel', 4, 8, 'product', 'example.com', '', ''); assertEquals( expectedAriaLabel, citationElement.$.citation.getAttribute('aria-label')); @@ -54,20 +99,36 @@ test('tooltip excludes www', async () => { citationElement.index = 1; - citationElement.url = 'http://www.example.com/'; + citationElement.urlInfo = { + title: '', + url: {url: 'http://www.example.com/'}, + faviconUrl: {url: ''}, + thumbnailUrl: {url: ''}, + previewText: '', + }; citationElement.citationCount = 1; citationElement.productName = 'product'; await flushTasks(); assertTrue(!!citationElement.$.citation); assertEquals('1', citationElement.$.citation.textContent!?.trim()); - assertEquals('example.com', citationElement.$.tooltip.textContent!?.trim()); + + // Ensure the citation only contains TLD+1. + assertTrue(citationElement.$.tooltip.textContent!?.includes('example.com')); + assertFalse( + citationElement.$.tooltip.textContent!?.includes('www.example.com')); }); test('click opens tab', async () => { const url = 'http://example.com/long/path/url'; citationElement.index = 1; - citationElement.url = url; + citationElement.urlInfo = { + title: '', + url: {url: url}, + faviconUrl: {url: ''}, + thumbnailUrl: {url: ''}, + previewText: '', + }; citationElement.citationCount = 1; citationElement.productName = 'product'; await flushTasks();
diff --git a/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc b/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc index 7b89e63..73346fd9 100644 --- a/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc +++ b/chrome/test/data/webui/commerce/product_specifications/product_specifications_browsertest.cc
@@ -69,8 +69,7 @@ base::WeakPtrFactory<ProductSpecificationsTest> weak_ptr_factory_{this}; }; -// TODO(crbug.com/385024070): Flaky on all platforms. -IN_PROC_BROWSER_TEST_F(ProductSpecificationsTest, DISABLED_App) { +IN_PROC_BROWSER_TEST_F(ProductSpecificationsTest, App) { RunTest("commerce/product_specifications/app_test.js", "mocha.run()"); }
diff --git a/chrome/test/data/webui/cr_components/chromeos/BUILD.gn b/chrome/test/data/webui/cr_components/chromeos/BUILD.gn index bb94342..4f01106 100644 --- a/chrome/test/data/webui/cr_components/chromeos/BUILD.gn +++ b/chrome/test/data/webui/cr_components/chromeos/BUILD.gn
@@ -68,7 +68,7 @@ "network/network_list_test.js", "network/network_password_input_test.js", "network/network_property_list_mojo_test.js", - "network/network_proxy_exclusions_test.js", + "network/network_proxy_exclusions_test.ts", "network/network_proxy_input_test.ts", "network/network_proxy_test.ts", "network/network_select_test.ts",
diff --git a/chrome/test/data/webui/side_panel/BUILD.gn b/chrome/test/data/webui/side_panel/BUILD.gn index df4e530e..6ae96b9 100644 --- a/chrome/test/data/webui/side_panel/BUILD.gn +++ b/chrome/test/data/webui/side_panel/BUILD.gn
@@ -14,6 +14,7 @@ "bookmarks/power_bookmarks_labels_test.ts", "bookmarks/power_bookmarks_list_test.ts", "bookmarks/power_bookmarks_service_test.ts", + "bookmarks/keyboard_arrow_navigation_service_test.ts", "bookmarks/test_bookmarks_api_proxy.ts", "bookmarks/test_power_bookmarks_delegate.ts", "commerce/price_tracking_section_test.ts",
diff --git a/chrome/test/data/webui/side_panel/bookmarks/keyboard_arrow_navigation_service_test.ts b/chrome/test/data/webui/side_panel/bookmarks/keyboard_arrow_navigation_service_test.ts new file mode 100644 index 0000000..70cff98 --- /dev/null +++ b/chrome/test/data/webui/side_panel/bookmarks/keyboard_arrow_navigation_service_test.ts
@@ -0,0 +1,182 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import {KeyArrowNavigationService} from 'chrome://bookmarks-side-panel.top-chrome/keyboard_arrow_navigation_service.js'; +import {getDeepActiveElement} from 'chrome://resources/js/util.js'; +import {assertEquals} from 'chrome://webui-test/chai_assert.js'; + +suite('KeyArrowNavigationServiceTest', () => { + let service: KeyArrowNavigationService; + let rootElement: HTMLElement; + + const parentFolder: chrome.bookmarks.BookmarkTreeNode = { + id: '2', + parentId: '0', + title: 'Other Bookmarks', + children: [ + { + id: '3', + parentId: '2', + title: 'First child bookmark', + url: 'http://child/bookmark/1/', + dateAdded: 1, + dateLastUsed: 4, + }, + { + id: '4', + parentId: '2', + title: 'Second child bookmark', + url: 'http://child/bookmark/2/', + dateAdded: 3, + dateLastUsed: 3, + }, + { + id: '5', + parentId: '2', + title: 'Child folder', + dateAdded: 2, + children: [ + { + id: '6', + parentId: '5', + title: 'Nested bookmark', + url: 'http://nested/bookmark/', + dateAdded: 4, + }, + ], + }, + ], + }; + + function createParentHTMLNode(parentNode: chrome.bookmarks.BookmarkTreeNode): + HTMLElement { + const parentElement = document.createElement('div'); + parentElement.id = 'root'; + parentElement.attachShadow({mode: 'open'}); + + if (parentNode.children) { + for (const node of parentNode.children) { + parentElement.shadowRoot!.append(createChildNodes(node)); + } + } + + return parentElement; + } + + function createChildNodes(node: chrome.bookmarks.BookmarkTreeNode): + HTMLElement { + const element = document.createElement('div'); + element.id = `box-${node.id}`; + element.innerText = node.title; + element.tabIndex = 0; + element.attachShadow({mode: 'open'}); + + const span = document.createElement('span'); + span.innerText = node.title; + element.appendChild(span); + + if (node.children) { + for (const child of node.children) { + element.shadowRoot!.append(createChildNodes(child)); + } + } + + return element; + } + + function dispatchArrowEvent(element: HTMLElement, direction: string) { + element.dispatchEvent(new KeyboardEvent('keydown', {key: direction})); + } + + setup(async () => { + document.body.innerHTML = window.trustedTypes!.emptyHTML; + rootElement = createParentHTMLNode(parentFolder); + document.body.append(rootElement); + + service = new KeyArrowNavigationService(rootElement, 'div'); + service.startListening(); + service.rebuildNavigationElements(rootElement); + rootElement.focus(); + }); + + test('Initializes', () => { + const elementListIds = + service.getElementsForTesting().map((el: HTMLElement) => el.id); + + assertEquals( + JSON.stringify(elementListIds), + JSON.stringify(['box-3', 'box-4', 'box-5', 'box-6'])); + }); + + test('MovesFocus', () => { + const elements = service.getElementsForTesting(); + elements[0]!.focus(); + + let activeElement = getDeepActiveElement(); + assertEquals(activeElement!.id, 'box-3'); + + dispatchArrowEvent(rootElement, 'ArrowDown'); + + activeElement = getDeepActiveElement(); + assertEquals(activeElement!.id, 'box-4'); + + dispatchArrowEvent(rootElement, 'ArrowDown'); + + activeElement = getDeepActiveElement(); + assertEquals(activeElement!.id, 'box-5'); + + dispatchArrowEvent(rootElement, 'ArrowUp'); + dispatchArrowEvent(rootElement, 'ArrowUp'); + + activeElement = getDeepActiveElement(); + assertEquals(activeElement!.id, 'box-3'); + }); + + test('RemovesNestedElement', () => { + const elements = service.getElementsForTesting(); + elements[0]!.focus(); + + let activeElement = getDeepActiveElement(); + assertEquals(activeElement!.id, 'box-3'); + + let elementListIds = + service.getElementsForTesting().map((el: HTMLElement) => el.id); + assertEquals( + JSON.stringify(elementListIds), + JSON.stringify(['box-3', 'box-4', 'box-5', 'box-6'])); + + const targetElement = rootElement.shadowRoot!.querySelector('#box-5')!; + service.removeElementsWithin(targetElement as HTMLElement); + + elementListIds = + service.getElementsForTesting().map((el: HTMLElement) => el.id); + assertEquals( + JSON.stringify(elementListIds), + JSON.stringify(['box-3', 'box-4', 'box-5'])); + + dispatchArrowEvent(rootElement, 'ArrowDown'); + dispatchArrowEvent(rootElement, 'ArrowDown'); + dispatchArrowEvent(rootElement, 'ArrowDown'); + + activeElement = getDeepActiveElement(); + assertEquals(activeElement!.id, 'box-3'); + }); + + test('AddsElements', () => { + service.removeElementsWithin(rootElement as HTMLElement); + let elementListIds = + service.getElementsForTesting().map((el: HTMLElement) => el.id); + + assertEquals(JSON.stringify(elementListIds), JSON.stringify([])); + + service.addElementsWithin(rootElement); + + elementListIds = + service.getElementsForTesting().map((el: HTMLElement) => el.id); + + assertEquals( + JSON.stringify(elementListIds), + JSON.stringify(['box-3', 'box-4', 'box-5', 'box-6'])); + }); +});
diff --git a/chrome/test/data/webui/side_panel/bookmarks/sp_bookmarks_interactive_test.cc b/chrome/test/data/webui/side_panel/bookmarks/sp_bookmarks_interactive_test.cc index 80b5a94..10c901f4 100644 --- a/chrome/test/data/webui/side_panel/bookmarks/sp_bookmarks_interactive_test.cc +++ b/chrome/test/data/webui/side_panel/bookmarks/sp_bookmarks_interactive_test.cc
@@ -45,6 +45,12 @@ "mocha.run()"); } +IN_PROC_BROWSER_TEST_F(SidePanelPowerBookmarksTest, + KeyboardArrowNavigationService) { + RunTest("side_panel/bookmarks/keyboard_arrow_navigation_service_test.js", + "mocha.run()"); +} + IN_PROC_BROWSER_TEST_F(SidePanelPowerBookmarksTest, DragManager) { RunTest("side_panel/bookmarks/power_bookmarks_drag_manager_test.js", "mocha.run()");
diff --git a/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts b/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts index 51c0e8f..7b9024d 100644 --- a/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts +++ b/chrome/test/data/webui/side_panel/reading_list/reading_list_app_test.ts
@@ -89,6 +89,9 @@ }); test('return all entries', async () => { + readingListApp.setExpandedForTesting(); + await microtasksFinished(); + const urls = [ 'https://www.google.com', 'https://www.apple.com', @@ -154,6 +157,9 @@ }); test('Click on item mark as unread button triggers actions', async () => { + readingListApp.setExpandedForTesting(); + await microtasksFinished(); + const expectedUrl = 'https://www.bing.com'; const readingListItem = @@ -205,29 +211,26 @@ }); test('Keyboard navigation abides by item list range boundaries', async () => { - const urls = [ - 'https://www.google.com', - 'https://www.apple.com', - 'https://www.bing.com', - 'https://www.yahoo.com', - ]; + readingListApp.setExpandedForTesting(); + await microtasksFinished(); - // Select first item. - readingListApp.selected = - readingListApp.shadowRoot!.querySelector( - 'reading-list-item')!.dataset['url']!; + // First item (after header) should be selected by default. + assertEquals(1, readingListApp.getFocusedIndexForTesting()); keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowUp'); - assertEquals(urls[3], readingListApp.selected); + assertEquals(5, readingListApp.getFocusedIndexForTesting()); keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowDown'); - assertEquals(urls[0], readingListApp.selected); + assertEquals(1, readingListApp.getFocusedIndexForTesting()); keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowDown'); - assertEquals(urls[1], readingListApp.selected); + assertEquals(2, readingListApp.getFocusedIndexForTesting()); + + keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowDown'); + assertEquals(4, readingListApp.getFocusedIndexForTesting()); keyDownOn(readingListApp.$.readingListList, 0, [], 'ArrowUp'); - assertEquals(urls[0], readingListApp.selected); + assertEquals(2, readingListApp.getFocusedIndexForTesting()); }); test(
diff --git a/chromecast/android/BUILD.gn b/chromecast/android/BUILD.gn index 0367c43..4fd3516 100644 --- a/chromecast/android/BUILD.gn +++ b/chromecast/android/BUILD.gn
@@ -43,38 +43,6 @@ java_targets = [ "//chromecast:cast_browser_apk" ] } -# These are all known //third_party/android_deps targets that chromecast -# internal code depends on. Reference these targets so if anyone wants to -# remove these targets upstream, they need to at least add someone from -# //chromecast OWNERS as a reviewer to make sure it's safe. -# -# This list was generated from chromecast/internal using: -# -# find | grep BUILD.gn | xargs grep -hi '//third_party/android_deps:' | \ -# grep -v "deps =" | sed 's/ *//g' | sort | uniq -group("internal_android_deps") { - testonly = true - public_deps = [ - "//third_party/android_deps:protobuf_lite_runtime_java", - "//third_party/androidx:androidx_annotation_annotation_java", - "//third_party/androidx:androidx_core_core_java", - "//third_party/androidx:androidx_fragment_fragment_java", - "//third_party/androidx:androidx_leanback_leanback_preference_java", - "//third_party/androidx:androidx_legacy_legacy_support_v4_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_common_java", - "//third_party/androidx:androidx_lifecycle_lifecycle_viewmodel_java", - "//third_party/androidx:androidx_localbroadcastmanager_localbroadcastmanager_java", - "//third_party/androidx:androidx_media_media_java", - "//third_party/androidx:androidx_mediarouter_mediarouter_java", - "//third_party/androidx:androidx_preference_preference_java", - "//third_party/androidx:androidx_recyclerview_recyclerview_java", - "//third_party/androidx:androidx_slice_slice_builders_java", - "//third_party/androidx:androidx_slice_slice_core_java", - "//third_party/androidx:androidx_test_core_java", - "//third_party/androidx:androidx_tvprovider_tvprovider_java", - ] -} - # Util to copy libc++_shared.so to APK. copy("copy_libcxx_shared") { sources = [ "${sysroot}/usr/lib/${android_abi_target}/libc++_shared.so" ]
diff --git a/chromecast/browser/android/BUILD.gn b/chromecast/browser/android/BUILD.gn index d2c2c1f..e9c0631 100644 --- a/chromecast/browser/android/BUILD.gn +++ b/chromecast/browser/android/BUILD.gn
@@ -159,10 +159,6 @@ # TODO(slan): We may need to pass this in as a parameter. "//third_party/androidx:androidx_localbroadcastmanager_localbroadcastmanager_java", - "//third_party/androidx:androidx_slice_slice_builders_java", - - # Used internally for Settings UI. - "//third_party/androidx:androidx_slice_slice_core_java", "//ui/android:ui_java", ]
diff --git a/chromecast/starboard/media/media/drm_util.cc b/chromecast/starboard/media/media/drm_util.cc index 533e508..9a152a1 100644 --- a/chromecast/starboard/media/media/drm_util.cc +++ b/chromecast/starboard/media/media/drm_util.cc
@@ -21,70 +21,42 @@ DrmInfoWrapper::DrmInfoWrapper() = default; DrmInfoWrapper::DrmInfoWrapper( - StarboardDrmSampleInfo drm_sample_info, - std::vector<StarboardDrmSubSampleMapping> mappings) { - drm_sample_info_ = std::move(drm_sample_info); - subsample_mappings_ = std::move(mappings); + std::unique_ptr<StarboardDrmSampleInfo> drm_sample_info, + std::unique_ptr<std::vector<StarboardDrmSubSampleMapping>> mappings) + : drm_sample_info_(std::move(drm_sample_info)), + subsample_mappings_(std::move(mappings)) {} - UpdateSubsampleInfo(); -} +DrmInfoWrapper::DrmInfoWrapper(DrmInfoWrapper&& other) = default; -DrmInfoWrapper::DrmInfoWrapper(DrmInfoWrapper&& other) { - drm_sample_info_ = std::move(other.drm_sample_info_); - subsample_mappings_ = std::move(other.subsample_mappings_); - - UpdateSubsampleInfo(); - other.drm_sample_info_ = std::nullopt; -} - -DrmInfoWrapper& DrmInfoWrapper::operator=(DrmInfoWrapper&& other) { - drm_sample_info_ = std::move(other.drm_sample_info_); - subsample_mappings_ = std::move(other.subsample_mappings_); - - UpdateSubsampleInfo(); - other.drm_sample_info_ = std::nullopt; - return *this; -} +DrmInfoWrapper& DrmInfoWrapper::operator=(DrmInfoWrapper&& other) = default; DrmInfoWrapper::~DrmInfoWrapper() = default; StarboardDrmSampleInfo* DrmInfoWrapper::GetDrmSampleInfo() { - return drm_sample_info_ ? &*drm_sample_info_ : nullptr; + return drm_sample_info_.get(); } -void DrmInfoWrapper::UpdateSubsampleInfo() { - if (!drm_sample_info_) { - return; - } - - drm_sample_info_->subsample_count = subsample_mappings_.size(); - drm_sample_info_->subsample_mapping = - subsample_mappings_.empty() ? nullptr : subsample_mappings_.data(); -} - -DrmInfoWrapper GetDrmInfo(const CastDecoderBuffer& buffer) { +DrmInfoWrapper DrmInfoWrapper::Create(const CastDecoderBuffer& buffer) { const CastDecryptConfig* decrypt_config = buffer.decrypt_config(); if (!decrypt_config) { return DrmInfoWrapper(); } - // Populate drm_sample_info. - StarboardDrmSampleInfo drm_info; - + auto drm_info = std::make_unique<StarboardDrmSampleInfo>(); switch (decrypt_config->encryption_scheme()) { case EncryptionScheme::kUnencrypted: return DrmInfoWrapper(); case EncryptionScheme::kAesCtr: - drm_info.encryption_scheme = kStarboardDrmEncryptionSchemeAesCtr; + drm_info->encryption_scheme = kStarboardDrmEncryptionSchemeAesCtr; break; case EncryptionScheme::kAesCbc: - drm_info.encryption_scheme = kStarboardDrmEncryptionSchemeAesCbc; + drm_info->encryption_scheme = kStarboardDrmEncryptionSchemeAesCbc; break; } - drm_info.encryption_pattern.crypt_byte_block = + drm_info->encryption_pattern.crypt_byte_block = decrypt_config->pattern().encrypt_blocks; - drm_info.encryption_pattern.skip_byte_block = + drm_info->encryption_pattern.skip_byte_block = decrypt_config->pattern().skip_blocks; int iv_size = decrypt_config->iv().size(); @@ -96,10 +68,10 @@ iv_size = kMaxIvLength; } for (int i = 0; i < iv_size; ++i) { - drm_info.initialization_vector[i] = + drm_info->initialization_vector[i] = static_cast<uint8_t>(decrypt_config->iv().at(i)); } - drm_info.initialization_vector_size = iv_size; + drm_info->initialization_vector_size = iv_size; int id_size = decrypt_config->key_id().size(); if (id_size > kMaxIdLength) { @@ -109,20 +81,24 @@ id_size = kMaxIdLength; } for (int i = 0; i < id_size; ++i) { - drm_info.identifier[i] = + drm_info->identifier[i] = static_cast<uint8_t>(decrypt_config->key_id().at(i)); } - drm_info.identifier_size = id_size; + drm_info->identifier_size = id_size; // Populate subsample_mappings. - std::vector<StarboardDrmSubSampleMapping> subsample_mappings; - subsample_mappings.reserve(decrypt_config->subsamples().size()); + auto subsample_mappings = + std::make_unique<std::vector<StarboardDrmSubSampleMapping>>(); + subsample_mappings->reserve(decrypt_config->subsamples().size()); for (const SubsampleEntry& subsample : decrypt_config->subsamples()) { StarboardDrmSubSampleMapping mapping; mapping.clear_byte_count = subsample.clear_bytes; mapping.encrypted_byte_count = subsample.cypher_bytes; - subsample_mappings.push_back(std::move(mapping)); + subsample_mappings->push_back(std::move(mapping)); } + drm_info->subsample_count = subsample_mappings->size(); + drm_info->subsample_mapping = + subsample_mappings->empty() ? nullptr : subsample_mappings->data(); return DrmInfoWrapper(std::move(drm_info), std::move(subsample_mappings)); }
diff --git a/chromecast/starboard/media/media/drm_util.h b/chromecast/starboard/media/media/drm_util.h index 1f78822..3cc55c020 100644 --- a/chromecast/starboard/media/media/drm_util.h +++ b/chromecast/starboard/media/media/drm_util.h
@@ -1,14 +1,11 @@ // Copyright 2024 The Chromium Authors // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// -// Contains a helper function to get DRM info from buffers. This logic can be -// used by both the StarboardAudioDecoder and the StarboardVideoDecoder. #ifndef CHROMECAST_STARBOARD_MEDIA_MEDIA_DRM_UTIL_H_ #define CHROMECAST_STARBOARD_MEDIA_MEDIA_DRM_UTIL_H_ -#include <optional> +#include <memory> #include <vector> #include "chromecast/public/media/cast_decoder_buffer.h" @@ -22,18 +19,17 @@ // non-null value and subsample mappings are present, the lifetime of those // subsamples is tied to the lifetime of the wrapper. // -// After moving or destroying a DrmInfoWrapper, any pointers previously returned -// by GetDrmSampleInfo should not be dereferenced, as they are no longer valid. +// This class is useful because StarboardDrmSampleInfo holds pointers that must +// live at least as long as the StarboardDrmSampleInfo itself. This is +// accomplished by managing all the relevant lifetimes in this class. +// +// Instances of this class should be created via DrmInfoWrapper::Create(). class DrmInfoWrapper { public: - // Constructs a DrmInfoWrapper for unencrypted content. GetDrmSampleInfo() - // will return null. - DrmInfoWrapper(); - - // Constructs a DrmInfoWrapper representing encrypted content. - // GetDrmSampleInfo() will return a populated StarboardDrmSampleInfo. - DrmInfoWrapper(StarboardDrmSampleInfo drm_sample_info, - std::vector<StarboardDrmSubSampleMapping> mappings); + // Extracts and returns DRM info from `buffer`. If the buffer is not + // encrypted, the StarboardDrmSampleInfo returned by GetDrmSampleInfo will be + // null. + static DrmInfoWrapper Create(const CastDecoderBuffer& buffer); // DrmInfoWrapper is movable but not copyable. DrmInfoWrapper(DrmInfoWrapper&& other); @@ -44,24 +40,27 @@ ~DrmInfoWrapper(); // Returns a pointer to the DrmSampleInfo owned by this wrapper, or null if - // there is no sample info. The returned pointer must not be dereferenced - // after moving or destroying this object. + // there is no sample info. StarboardDrmSampleInfo* GetDrmSampleInfo(); private: - // Updates drm_sample_info->subsample_count and - // drm_sample_info->subsample_mapping to refer to `subsample_mappings`. These - // fields need to be updated when moving a DrmInfoWrapper. - void UpdateSubsampleInfo(); + // Constructs a DrmInfoWrapper for unencrypted content. GetDrmSampleInfo() + // will return null. + DrmInfoWrapper(); - std::optional<StarboardDrmSampleInfo> drm_sample_info_; - std::vector<StarboardDrmSubSampleMapping> subsample_mappings_; + // Constructs a DrmInfoWrapper representing encrypted content. + DrmInfoWrapper( + std::unique_ptr<StarboardDrmSampleInfo> drm_sample_info, + std::unique_ptr<std::vector<StarboardDrmSubSampleMapping>> mappings); + + // unique_ptrs are used here for the sake of pointer stability, so that moving + // a DrmInfoWrapper does not require updating any code that referenced the + // pointers. + std::unique_ptr<StarboardDrmSampleInfo> drm_sample_info_; + std::unique_ptr<std::vector<StarboardDrmSubSampleMapping>> + subsample_mappings_; }; -// Extracts and returns DRM info from `buffer`. If the buffer is not encrypted, -// the StarboardDrmSampleInfo returned by GetDrmSampleInfo will be null. -DrmInfoWrapper GetDrmInfo(const CastDecoderBuffer& buffer); - } // namespace media } // namespace chromecast
diff --git a/chromecast/starboard/media/media/starboard_audio_decoder.cc b/chromecast/starboard/media/media/starboard_audio_decoder.cc index 3c5e171..04bf590b 100644 --- a/chromecast/starboard/media/media/starboard_audio_decoder.cc +++ b/chromecast/starboard/media/media/starboard_audio_decoder.cc
@@ -186,7 +186,7 @@ decoded_bytes_ += size_of_buffer; - return PushBufferInternal(std::move(sample), GetDrmInfo(*buffer), + return PushBufferInternal(std::move(sample), DrmInfoWrapper::Create(*buffer), std::move(data_copy), size_of_buffer); }
diff --git a/chromecast/starboard/media/media/starboard_video_decoder.cc b/chromecast/starboard/media/media/starboard_video_decoder.cc index 013751e..82af347 100644 --- a/chromecast/starboard/media/media/starboard_video_decoder.cc +++ b/chromecast/starboard/media/media/starboard_video_decoder.cc
@@ -204,7 +204,7 @@ decoded_bytes_ += copy_size; - return PushBufferInternal(std::move(sample), GetDrmInfo(*buffer), + return PushBufferInternal(std::move(sample), DrmInfoWrapper::Create(*buffer), std::move(data_copy), copy_size); }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index 95b1445..2dff05f0 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -16150.0.0-1065894 \ No newline at end of file +16151.0.0-1065906 \ No newline at end of file
diff --git a/chromeos/ash/components/browser_context_helper/browser_context_helper.cc b/chromeos/ash/components/browser_context_helper/browser_context_helper.cc index 5d9bd63f..3c68f708 100644 --- a/chromeos/ash/components/browser_context_helper/browser_context_helper.cc +++ b/chromeos/ash/components/browser_context_helper/browser_context_helper.cc
@@ -123,7 +123,7 @@ return browser_context; } -const user_manager::User* BrowserContextHelper::GetUserByBrowserContext( +user_manager::User* BrowserContextHelper::GetUserByBrowserContext( content::BrowserContext* browser_context) { if (!IsUserBrowserContext(browser_context)) { return nullptr; @@ -138,7 +138,7 @@ } if (UseAnnotatedAccountId()) { CHECK(account_id); - return user_manager::UserManager::Get()->FindUser(*account_id); + return user_manager::UserManager::Get()->FindUserAndModify(*account_id); } const std::string hash = GetUserIdHashFromBrowserContext(browser_context); @@ -148,7 +148,7 @@ // TODO(crbug.com/40225390): find user by AccountId, once it is annotated // to Profile in tests. auto* user_manager = user_manager::UserManager::Get(); - for (const user_manager::User* user : user_manager->GetLoggedInUsers()) { + for (user_manager::User* user : user_manager->GetLoggedInUsers()) { if (user->username_hash() == hash) { if (!account_id || *account_id != user->GetAccountId()) { // TODO(crbug.com/40225390): fix tests to annotate AccountId properly.
diff --git a/chromeos/ash/components/browser_context_helper/browser_context_helper.h b/chromeos/ash/components/browser_context_helper/browser_context_helper.h index 087f98c..895b276 100644 --- a/chromeos/ash/components/browser_context_helper/browser_context_helper.h +++ b/chromeos/ash/components/browser_context_helper/browser_context_helper.h
@@ -102,7 +102,7 @@ // Returns User instance of the given |browser_context|. If not found, // returns nullptr. - const user_manager::User* GetUserByBrowserContext( + user_manager::User* GetUserByBrowserContext( content::BrowserContext* browser_context); // Returns user browser context dir in a format of "u-${user_id_hash}".
diff --git a/chromeos/ash/components/carrier_lock/OWNERS b/chromeos/ash/components/carrier_lock/OWNERS index 4b62753..cd12bb92 100644 --- a/chromeos/ash/components/carrier_lock/OWNERS +++ b/chromeos/ash/components/carrier_lock/OWNERS
@@ -1,2 +1 @@ -gordonseto@google.com hsuregan@chromium.org
diff --git a/chromeos/ash/services/assistant/BUILD.gn b/chromeos/ash/services/assistant/BUILD.gn index 76788b713..5692c18 100644 --- a/chromeos/ash/services/assistant/BUILD.gn +++ b/chromeos/ash/services/assistant/BUILD.gn
@@ -170,6 +170,7 @@ ] deps = [ ":lib", + "//ash/public/cpp/resources:ash_public_unscaled_resources", "//base", "//chromeos/ash/components/assistant:buildflags", "//chromeos/ash/services/assistant/public/cpp",
diff --git a/chromeos/ash/services/assistant/public/cpp/assistant_browser_delegate.h b/chromeos/ash/services/assistant/public/cpp/assistant_browser_delegate.h index b7d9fab..e0b7814 100644 --- a/chromeos/ash/services/assistant/public/cpp/assistant_browser_delegate.h +++ b/chromeos/ash/services/assistant/public/cpp/assistant_browser_delegate.h
@@ -113,6 +113,9 @@ // Opens the new entry point. virtual void OpenNewEntryPoint() = 0; + // Returns resource id of Assistant new entry point icon. + virtual int GetNewEntryPointIconResourceId() = 0; + #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) // Requests a connection to Libassistant service interface via the browser. virtual void RequestLibassistantService(
diff --git a/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc b/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc index 285909bd..2e0fd71a 100644 --- a/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc +++ b/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.cc
@@ -5,6 +5,7 @@ #include "chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.h" #include "ash/public/cpp/new_window_delegate.h" +#include "ash/public/cpp/resources/grit/ash_public_unscaled_resources.h" #include "base/types/expected.h" #include "chromeos/ash/services/assistant/public/cpp/assistant_browser_delegate.h" #include "chromeos/ash/services/assistant/public/cpp/features.h" @@ -63,4 +64,10 @@ std::move(open_new_entry_point_closure_).Run(); } +int ScopedAssistantBrowserDelegate::GetNewEntryPointIconResourceId() { + // A placeholder resource id. Use resource id in //ash to avoid having a + // dependency to //chrome. + return IDR_SETTINGS_LOGO_192; +} + } // namespace ash::assistant
diff --git a/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.h b/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.h index 38075458..7ba70cf 100644 --- a/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.h +++ b/chromeos/ash/services/assistant/test_support/scoped_assistant_browser_delegate.h
@@ -61,6 +61,7 @@ base::expected<bool, AssistantBrowserDelegate::Error> IsNewEntryPointEligibleForPrimaryProfile() override; void OpenNewEntryPoint() override; + int GetNewEntryPointIconResourceId() override; #if BUILDFLAG(ENABLE_CROS_LIBASSISTANT) void RequestLibassistantService( mojo::PendingReceiver<libassistant::mojom::LibassistantService> receiver)
diff --git a/chromeos/services/assistant/public/shared/BUILD.gn b/chromeos/services/assistant/public/shared/BUILD.gn index 468e630b..ef67e45c 100644 --- a/chromeos/services/assistant/public/shared/BUILD.gn +++ b/chromeos/services/assistant/public/shared/BUILD.gn
@@ -32,6 +32,8 @@ } else { deps = [ ":new_entry_point_constants_placeholder" ] } + + public_deps = [ ":new_entry_point_constants_interface" ] } source_set("new_entry_point_constants_placeholder") {
diff --git a/clank b/clank index c0f9cfa..f9c09c54 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit c0f9cfa5836eb7aedcef22bb09fa19001ed59c35 +Subproject commit f9c09c54dcfa04880a60179b519ee0866babdcbc
diff --git a/components/autofill/content/renderer/form_autofill_util.cc b/components/autofill/content/renderer/form_autofill_util.cc index f07d9375..c237a10 100644 --- a/components/autofill/content/renderer/form_autofill_util.cc +++ b/components/autofill/content/renderer/form_autofill_util.cc
@@ -2866,8 +2866,7 @@ } } - std::move(potential_matches) - .Run(std::vector<std::string>(matches.begin(), matches.end())); + std::move(potential_matches).Run(std::move(matches).extract()); } std::string ExtractFinalCheckoutAmountFromDom(
diff --git a/components/autofill/ios/browser/autofill_agent_unittests.mm b/components/autofill/ios/browser/autofill_agent_unittests.mm index ae5393fe..b068714b 100644 --- a/components/autofill/ios/browser/autofill_agent_unittests.mm +++ b/components/autofill/ios/browser/autofill_agent_unittests.mm
@@ -408,7 +408,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:@"frameID"]; + frameID:@"frameID" + onlyPassword:NO]; [autofill_agent_ checkIfSuggestionsAvailableForForm:form_query hasUserGesture:NO webState:&fake_web_state_ @@ -456,7 +457,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:@"frameID"]; + frameID:@"frameID" + onlyPassword:NO]; [autofill_agent_ retrieveSuggestionsForForm:form_query webState:&fake_web_state_ completionHandler:completionHandler]; @@ -796,7 +798,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:@"frameID"]; + frameID:@"frameID" + onlyPassword:NO]; [autofill_agent_ retrieveSuggestionsForForm:form_query webState:&fake_web_state_ completionHandler:completionHandler]; @@ -854,7 +857,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:@"frameID"]; + frameID:@"frameID" + onlyPassword:NO]; [autofill_agent_ retrieveSuggestionsForForm:form_query webState:&fake_web_state_ completionHandler:completionHandler];
diff --git a/components/autofill/ios/browser/form_suggestion_provider_query.h b/components/autofill/ios/browser/form_suggestion_provider_query.h index edb2543..9276040 100644 --- a/components/autofill/ios/browser/form_suggestion_provider_query.h +++ b/components/autofill/ios/browser/form_suggestion_provider_query.h
@@ -48,6 +48,10 @@ // ID of a frame containing the form. @property(readonly, nonatomic, copy) NSString* frameID; +// YES if only passwords should be returned as suggestions (e.g. no password +// generation suggestion). +@property(readonly, nonatomic, assign) BOOL onlyPassword; + - (instancetype)initWithFormName:(NSString*)formName formRendererID:(autofill::FormRendererId)formRendererID fieldIdentifier:(NSString*)fieldIdentifier @@ -55,7 +59,8 @@ fieldType:(NSString*)fieldType type:(NSString*)type typedValue:(NSString*)typedValue - frameID:(NSString*)frameID NS_DESIGNATED_INITIALIZER; + frameID:(NSString*)frameID + onlyPassword:(BOOL)onlyPassword NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE;
diff --git a/components/autofill/ios/browser/form_suggestion_provider_query.mm b/components/autofill/ios/browser/form_suggestion_provider_query.mm index aa64dcc..7f14e8b 100644 --- a/components/autofill/ios/browser/form_suggestion_provider_query.mm +++ b/components/autofill/ios/browser/form_suggestion_provider_query.mm
@@ -17,7 +17,8 @@ fieldType:(NSString*)fieldType type:(NSString*)type typedValue:(NSString*)typedValue - frameID:(NSString*)frameID { + frameID:(NSString*)frameID + onlyPassword:(BOOL)onlyPassword { self = [super init]; if (self) { _formName = [formName copy]; @@ -28,6 +29,7 @@ _type = [type copy]; _typedValue = [typedValue copy]; _frameID = [frameID copy]; + _onlyPassword = onlyPassword; } return self; }
diff --git a/components/autofill/ios/browser/form_suggestion_provider_query_unittests.mm b/components/autofill/ios/browser/form_suggestion_provider_query_unittests.mm index 05717c4..5ee8620 100644 --- a/components/autofill/ios/browser/form_suggestion_provider_query_unittests.mm +++ b/components/autofill/ios/browser/form_suggestion_provider_query_unittests.mm
@@ -36,7 +36,8 @@ fieldType:kObfuscatedFieldType type:kTestFocusType typedValue:kTestTypedValue - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; EXPECT_TRUE([formQuery hasFocusType]); } @@ -52,7 +53,8 @@ fieldType:kTestTextFieldType type:kTestInputType typedValue:kTestTypedValue - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; EXPECT_FALSE([formQuery hasFocusType]); }
diff --git a/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java b/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java index a4d2bd4..d27a0a1 100644 --- a/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java +++ b/components/browser_ui/banners/android/java/src/org/chromium/components/browser_ui/banners/SwipableOverlayView.java
@@ -4,6 +4,7 @@ package org.chromium.components.browser_ui.banners; +import static org.chromium.build.NullUtil.assumeNonNull; import static org.chromium.cc.mojom.RootScrollOffsetUpdateFrequency.ALL_UPDATES; import android.animation.Animator; @@ -120,14 +121,14 @@ /** Set the given WebContents for scrolling changes. */ public void setWebContents(WebContents webContents) { if (mWebContents != null) { - GestureListenerManager.fromWebContents(mWebContents) + assumeNonNull(GestureListenerManager.fromWebContents(mWebContents)) .removeListener(mGestureStateListener); } mWebContents = webContents; // See comment in onLayout() as to why the listener is only attached if mTotalHeight is > 0. - if (mWebContents != null && mTotalHeight > 0) { - GestureListenerManager.fromWebContents(mWebContents) + if (webContents != null && mTotalHeight > 0) { + assumeNonNull(GestureListenerManager.fromWebContents(webContents)) .addListener(mGestureStateListener, ALL_UPDATES); } } @@ -220,12 +221,13 @@ // Adding a listener to GestureListenerManager results in extra IPCs on every frame, which // is very costly. Only attach the listener if needed. if (mWebContents != null && mGestureStateListener != null) { + GestureListenerManager gestureManager = + GestureListenerManager.fromWebContents(mWebContents); + assumeNonNull(gestureManager); if (mTotalHeight > 0) { - GestureListenerManager.fromWebContents(mWebContents) - .addListener(mGestureStateListener, ALL_UPDATES); + gestureManager.addListener(mGestureStateListener, ALL_UPDATES); } else { - GestureListenerManager.fromWebContents(mWebContents) - .removeListener(mGestureStateListener); + gestureManager.removeListener(mGestureStateListener); } }
diff --git a/components/browsing_topics/browsing_topics_service_impl.cc b/components/browsing_topics/browsing_topics_service_impl.cc index 8db5bef6..75e86d8f 100644 --- a/components/browsing_topics/browsing_topics_service_impl.cc +++ b/components/browsing_topics/browsing_topics_service_impl.cc
@@ -270,7 +270,14 @@ // <iframe src=[url] browsingtopics> request. kObserveViaIframeAttributeApi = 5, - kMaxValue = kObserveViaIframeAttributeApi, + // Get topics via <img src=[url] browsingtopics>. + kGetViaImgAttributeApi = 6, + + // Observe topics via the "Sec-Browsing-Topics: ?1" response header for the + // <img src=[url] browsingtopics> request. + kObserveViaImgAttributeApi = 7, + + kMaxValue = kObserveViaImgAttributeApi, }; void RecordBrowsingTopicsApiActionTypeMetrics(ApiCallerSource caller_source, @@ -314,6 +321,24 @@ return; } + if (caller_source == ApiCallerSource::kImgAttribute) { + if (get_topics) { + DCHECK(!observe); + + base::UmaHistogramEnumeration( + kBrowsingTopicsApiActionTypeHistogramId, + BrowsingTopicsApiActionType::kGetViaImgAttributeApi); + return; + } + + DCHECK(observe); + base::UmaHistogramEnumeration( + kBrowsingTopicsApiActionTypeHistogramId, + BrowsingTopicsApiActionType::kObserveViaImgAttributeApi); + + return; + } + DCHECK_EQ(caller_source, ApiCallerSource::kFetch); if (get_topics) {
diff --git a/components/browsing_topics/common/common_types.h b/components/browsing_topics/common/common_types.h index c7f373e..dbfe3d33e 100644 --- a/components/browsing_topics/common/common_types.h +++ b/components/browsing_topics/common/common_types.h
@@ -40,6 +40,9 @@ // The API usage is from <iframe src=[url] browsingtopics>. kIframeAttribute, + + // The API usage is from <img src=[url] browsingtopics>. + kImgAttribute, }; // Represents the different reasons why the topics API access is denied. These
diff --git a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/BooleanCachedFeatureParam.java b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/BooleanCachedFeatureParam.java index a371bc8..235534c 100644 --- a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/BooleanCachedFeatureParam.java +++ b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/BooleanCachedFeatureParam.java
@@ -10,6 +10,7 @@ import org.chromium.base.FeatureList; import org.chromium.base.FeatureMap; +import org.chromium.base.FeatureOverrides; import org.chromium.base.cached_flags.ValuesReturned; import org.chromium.base.supplier.Supplier; @@ -73,12 +74,8 @@ * Forces the parameter to return a specific value for testing. * * @param overrideValue the value to be returned - * @deprecated use <code>@EnableFeatures("Feature:param/value")</code> instead. */ - @Deprecated public void setForTesting(boolean overrideValue) { - FeatureList.TestValues testValues = new FeatureList.TestValues(); - testValues.addFieldTrialParamOverride(this, String.valueOf(overrideValue)); - FeatureList.mergeTestValues(testValues, /* replace= */ true); + FeatureOverrides.overrideParam(getFeatureName(), getName(), overrideValue); } }
diff --git a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/DoubleCachedFeatureParam.java b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/DoubleCachedFeatureParam.java index 8e6998c..ff07c1d 100644 --- a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/DoubleCachedFeatureParam.java +++ b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/DoubleCachedFeatureParam.java
@@ -10,6 +10,7 @@ import org.chromium.base.FeatureList; import org.chromium.base.FeatureMap; +import org.chromium.base.FeatureOverrides; import org.chromium.base.cached_flags.ValuesReturned; import org.chromium.base.supplier.Supplier; @@ -75,12 +76,8 @@ * Forces the parameter to return a specific value for testing. * * @param overrideValue the value to be returned - * @deprecated use <code>@EnableFeatures("Feature:param/value")</code> instead. */ - @Deprecated public void setForTesting(double overrideValue) { - FeatureList.TestValues testValues = new FeatureList.TestValues(); - testValues.addFieldTrialParamOverride(this, String.valueOf(overrideValue)); - FeatureList.mergeTestValues(testValues, /* replace= */ true); + FeatureOverrides.overrideParam(getFeatureName(), getName(), overrideValue); } }
diff --git a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/IntCachedFeatureParam.java b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/IntCachedFeatureParam.java index fbbf4a3..3874303 100644 --- a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/IntCachedFeatureParam.java +++ b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/IntCachedFeatureParam.java
@@ -10,6 +10,7 @@ import org.chromium.base.FeatureList; import org.chromium.base.FeatureMap; +import org.chromium.base.FeatureOverrides; import org.chromium.base.cached_flags.ValuesReturned; import org.chromium.base.supplier.Supplier; @@ -73,12 +74,8 @@ * Forces the parameter to return a specific value for testing. * * @param overrideValue the value to be returned - * @deprecated use <code>@EnableFeatures("Feature:param/value")</code> instead. */ - @Deprecated public void setForTesting(int overrideValue) { - FeatureList.TestValues testValues = new FeatureList.TestValues(); - testValues.addFieldTrialParamOverride(this, String.valueOf(overrideValue)); - FeatureList.mergeTestValues(testValues, /* replace= */ true); + FeatureOverrides.overrideParam(getFeatureName(), getName(), overrideValue); } }
diff --git a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/StringCachedFeatureParam.java b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/StringCachedFeatureParam.java index 3138fc7..ab6db4085 100644 --- a/components/cached_flags/android/java/src/org/chromium/components/cached_flags/StringCachedFeatureParam.java +++ b/components/cached_flags/android/java/src/org/chromium/components/cached_flags/StringCachedFeatureParam.java
@@ -11,6 +11,7 @@ import org.chromium.base.FeatureList; import org.chromium.base.FeatureMap; +import org.chromium.base.FeatureOverrides; import org.chromium.base.cached_flags.ValuesReturned; import org.chromium.base.supplier.Supplier; @@ -75,12 +76,8 @@ * Forces the parameter to return a specific value for testing. * * @param overrideValue the value to be returned - * @deprecated use <code>@EnableFeatures("Feature:param/value")</code> instead. */ - @Deprecated public void setForTesting(String overrideValue) { - FeatureList.TestValues testValues = new FeatureList.TestValues(); - testValues.addFieldTrialParamOverride(this, overrideValue); - FeatureList.mergeTestValues(testValues, /* replace= */ true); + FeatureOverrides.overrideParam(getFeatureName(), getName(), overrideValue); } }
diff --git a/components/commerce/core/android/shopping_service_android.cc b/components/commerce/core/android/shopping_service_android.cc index 00aea99d..7f679157 100644 --- a/components/commerce/core/android/shopping_service_android.cc +++ b/components/commerce/core/android/shopping_service_android.cc
@@ -11,6 +11,7 @@ #include "base/android/jni_string.h" #include "base/functional/bind.h" #include "components/bookmarks/browser/bookmark_node.h" +#include "components/commerce/core/feature_utils.h" #include "components/commerce/core/subscriptions/commerce_subscription.h" #include "url/android/gurl_android.h" #include "url/gurl.h" @@ -439,7 +440,8 @@ const JavaParamRef<jobject>& obj) { CHECK(shopping_service_); - return shopping_service_->IsPriceInsightsEligible(); + return commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker()); } bool ShoppingServiceAndroid::IsDiscountEligibleToShowOnNavigation(
diff --git a/components/commerce/core/feature_utils.cc b/components/commerce/core/feature_utils.cc index e40dd77..5379b42a 100644 --- a/components/commerce/core/feature_utils.cc +++ b/components/commerce/core/feature_utils.cc
@@ -58,6 +58,16 @@ return true; } +bool IsPriceInsightsEligible(AccountChecker* account_checker) { + if (!account_checker || + !commerce::IsRegionLockedFeatureEnabled( + kPriceInsights, kPriceInsightsRegionLaunched, + account_checker->GetCountry(), account_checker->GetLocale())) { + return false; + } + return account_checker->IsAnonymizedUrlDataCollectionEnabled(); +} + bool IsSubscriptionsApiEnabled(AccountChecker* account_checker) { return IsRegionLockedFeatureEnabled( kSubscriptionsApi, kSubscriptionsApiRegionLaunched,
diff --git a/components/commerce/core/feature_utils.h b/components/commerce/core/feature_utils.h index 6a76b654..c0c1c68 100644 --- a/components/commerce/core/feature_utils.h +++ b/components/commerce/core/feature_utils.h
@@ -20,6 +20,13 @@ // whether to create critical, feature-related infrastructure. bool IsShoppingListEligible(AccountChecker* account_checker); +// This is a feature check for the "price insights", which will return true +// if the user has the feature flag enabled, has MSBB enabled, and (if +// applicable) is in an eligible country and locale. The value returned by +// this method can change at runtime, so it should not be used when deciding +// whether to create critical, feature-related infrastructure. +bool IsPriceInsightsEligible(AccountChecker* account_checker); + // Returns whether the subscriptions API is available for use. This considers // the user's region and locale and is not necessarily bound to any specific // user-facing feature.
diff --git a/components/commerce/core/mock_shopping_service.cc b/components/commerce/core/mock_shopping_service.cc index cbfbe9a1..16b83cf3 100644 --- a/components/commerce/core/mock_shopping_service.cc +++ b/components/commerce/core/mock_shopping_service.cc
@@ -67,7 +67,6 @@ std::vector<const bookmarks::BookmarkNode*>()); SetGetAllShoppingBookmarksValue( std::vector<const bookmarks::BookmarkNode*>()); - SetIsPriceInsightsEligible(true); SetResponseForGetPriceInsightsInfoForUrl(std::nullopt); SetGetAllParcelStatusesCallbackValue(std::vector<ParcelTrackingStatus>()); } @@ -238,11 +237,6 @@ .WillByDefault(testing::Return(bookmarks)); } -void MockShoppingService::SetIsPriceInsightsEligible(bool is_eligible) { - ON_CALL(*this, IsPriceInsightsEligible) - .WillByDefault(testing::Return(is_eligible)); -} - void MockShoppingService::SetIsDiscountEligibleToShowOnNavigation( bool is_eligible) { ON_CALL(*this, IsDiscountEligibleToShowOnNavigation)
diff --git a/components/commerce/core/mock_shopping_service.h b/components/commerce/core/mock_shopping_service.h index d633af4..343401d 100644 --- a/components/commerce/core/mock_shopping_service.h +++ b/components/commerce/core/mock_shopping_service.h
@@ -116,7 +116,6 @@ (base::OnceCallback<void(ShoppingService*)>), (override)); MOCK_METHOD(bool, IsMerchantViewerEnabled, (), (override)); - MOCK_METHOD(bool, IsPriceInsightsEligible, (), (override)); MOCK_METHOD(bool, IsDiscountEligibleToShowOnNavigation, (), (override)); MOCK_METHOD(bool, IsParcelTrackingEligible, (), (override)); MOCK_METHOD(void, @@ -175,7 +174,6 @@ std::vector<const bookmarks::BookmarkNode*> bookmarks); void SetGetAllShoppingBookmarksValue( std::vector<const bookmarks::BookmarkNode*> bookmarks); - void SetIsPriceInsightsEligible(bool is_eligible); void SetIsDiscountEligibleToShowOnNavigation(bool is_eligible); void SetResponseForGetDiscountInfoForUrl( const std::vector<DiscountInfo>& infos);
diff --git a/components/commerce/core/shopping_service.cc b/components/commerce/core/shopping_service.cc index e46c6a0f..742a6306 100644 --- a/components/commerce/core/shopping_service.cc +++ b/components/commerce/core/shopping_service.cc
@@ -840,15 +840,6 @@ kCommerceMerchantViewerRegionLaunched); } -bool ShoppingService::IsPriceInsightsEligible() { - if (!IsRegionLockedFeatureEnabled(kPriceInsights, - kPriceInsightsRegionLaunched)) { - return false; - } - return account_checker_ && - account_checker_->IsAnonymizedUrlDataCollectionEnabled(); -} - bool ShoppingService::IsPriceInsightsInfoApiEnabled() { return IsRegionLockedFeatureEnabled(kPriceInsights, kPriceInsightsRegionLaunched);
diff --git a/components/commerce/core/shopping_service.h b/components/commerce/core/shopping_service.h index 954f1bae..698b62c 100644 --- a/components/commerce/core/shopping_service.h +++ b/components/commerce/core/shopping_service.h
@@ -369,13 +369,6 @@ // enabled country and locale. virtual bool IsMerchantViewerEnabled(); - // This is a feature check for the "price insights", which will return true - // if the user has the feature flag enabled, has MSBB enabled, and (if - // applicable) is in an eligible country and locale. The value returned by - // this method can change at runtime, so it should not be used when deciding - // whether to create critical, feature-related infrastructure. - virtual bool IsPriceInsightsEligible(); - // This is a feature check for "show discounts on navigation", which will // return true if the user has the feature flag enabled, is signed-in and // synced, has MSBB enabled, and (if applicable) is in an eligible country and
diff --git a/components/commerce/core/test_utils.cc b/components/commerce/core/test_utils.cc index 9a20140..4a8f9b13 100644 --- a/components/commerce/core/test_utils.cc +++ b/components/commerce/core/test_utils.cc
@@ -10,6 +10,7 @@ #include "base/run_loop.h" #include "base/strings/utf_string_conversions.h" #include "components/bookmarks/browser/bookmark_model.h" +#include "components/commerce/core/commerce_feature_list.h" #include "components/commerce/core/mock_account_checker.h" #include "components/commerce/core/pref_names.h" #include "components/commerce/core/price_tracking_utils.h" @@ -95,6 +96,13 @@ base::Value(enabled_state)); } +void SetUpPriceInsightsEligibility(base::test::ScopedFeatureList* feature_list, + MockAccountChecker* account_checker, + bool is_eligible) { + feature_list->InitAndEnableFeature(kPriceInsights); + account_checker->SetAnonymizedUrlDataCollectionEnabled(is_eligible); +} + std::optional<PriceInsightsInfo> CreateValidPriceInsightsInfo( bool has_price_range_data, bool has_price_history_data,
diff --git a/components/commerce/core/test_utils.h b/components/commerce/core/test_utils.h index 055cf1b..b58fb0f 100644 --- a/components/commerce/core/test_utils.h +++ b/components/commerce/core/test_utils.h
@@ -8,6 +8,7 @@ #include <optional> #include <string> +#include "base/test/scoped_feature_list.h" #include "components/commerce/core/commerce_types.h" #include "components/commerce/core/shopping_service.h" #include "components/commerce/core/subscriptions/commerce_subscription.h" @@ -82,6 +83,11 @@ void SetTabCompareEnterprisePolicyPref(TestingPrefServiceSimple* prefs, int enabled_state); +// Set up price insights eligibility for testing. +void SetUpPriceInsightsEligibility(base::test::ScopedFeatureList* feature_list, + MockAccountChecker* account_checker, + bool is_eligible); + std::optional<PriceInsightsInfo> CreateValidPriceInsightsInfo( bool has_price_range_data = false, bool has_price_history_data = false,
diff --git a/components/commerce/core/webui/shopping_service_handler.cc b/components/commerce/core/webui/shopping_service_handler.cc index a7dee5e..39a4201 100644 --- a/components/commerce/core/webui/shopping_service_handler.cc +++ b/components/commerce/core/webui/shopping_service_handler.cc
@@ -42,16 +42,21 @@ namespace commerce { namespace { -std::vector<shopping_service::mojom::UrlInfoPtr> UrlInfoToMojo( +shopping_service::mojom::UrlInfoPtr UrlInfoToMojo(const UrlInfo& url_info) { + auto url_info_ptr = shopping_service::mojom::UrlInfo::New(); + url_info_ptr->url = url_info.url; + url_info_ptr->title = base::UTF16ToUTF8(url_info.title); + url_info_ptr->previewText = url_info.previewText.value_or(""); + url_info_ptr->favicon_url = url_info.favicon_url.value_or(GURL()); + return url_info_ptr; +} + +std::vector<shopping_service::mojom::UrlInfoPtr> UrlInfoListToMojo( const std::vector<UrlInfo>& url_infos) { std::vector<shopping_service::mojom::UrlInfoPtr> url_info_ptr_list; for (const UrlInfo& url_info : url_infos) { - auto url_info_ptr = shopping_service::mojom::UrlInfo::New(); - url_info_ptr->url = url_info.url; - url_info_ptr->title = base::UTF16ToUTF8(url_info.title); - url_info_ptr->previewText = url_info.previewText.value_or(""); - url_info_ptr_list.push_back(std::move(url_info_ptr)); + url_info_ptr_list.push_back(UrlInfoToMojo(url_info)); } return url_info_ptr_list; } @@ -145,12 +150,7 @@ if (!url_info.url.SchemeIsHTTPOrHTTPS()) { continue; } - auto url_info_ptr = shopping_service::mojom::UrlInfo::New(); - url_info_ptr->url = url_info.url; - url_info_ptr->title = base::UTF16ToUTF8(url_info.title); - url_info_ptr->favicon_url = url_info.favicon_url.value_or(GURL()); - url_info_ptr->thumbnail_url = url_info.thumbnail_url.value_or(GURL()); - desc_text_ptr->urls.push_back(std::move(url_info_ptr)); + desc_text_ptr->urls.push_back(UrlInfoToMojo(url_info)); } return desc_text_ptr; } @@ -365,8 +365,9 @@ void ShoppingServiceHandler::GetProductInfoForCurrentUrl( GetProductInfoForCurrentUrlCallback callback) { - if (!shopping_service_->IsPriceInsightsEligible() || !delegate_ || - !delegate_->GetCurrentTabUrl().has_value()) { + if (!commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker()) || + !delegate_ || !delegate_->GetCurrentTabUrl().has_value()) { std::move(callback).Run(shared::mojom::ProductInfo::New()); return; } @@ -449,8 +450,9 @@ void ShoppingServiceHandler::GetPriceInsightsInfoForCurrentUrl( GetPriceInsightsInfoForCurrentUrlCallback callback) { - if (!shopping_service_->IsPriceInsightsEligible() || !delegate_ || - !delegate_->GetCurrentTabUrl().has_value()) { + if (!commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker()) || + !delegate_ || !delegate_->GetCurrentTabUrl().has_value()) { std::move(callback).Run(shopping_service::mojom::PriceInsightsInfo::New()); return; } @@ -465,7 +467,8 @@ void ShoppingServiceHandler::GetPriceInsightsInfoForUrl( const GURL& url, GetPriceInsightsInfoForUrlCallback callback) { - if (!shopping_service_->IsPriceInsightsEligible()) { + if (!commerce::IsPriceInsightsEligible( + shopping_service_->GetAccountChecker())) { std::move(callback).Run(url, shopping_service::mojom::PriceInsightsInfo::New()); return; @@ -520,7 +523,7 @@ shopping_service_->GetUrlInfosForWebWrappersWithProducts(base::BindOnce( [](GetUrlInfosForProductTabsCallback callback, const std::vector<UrlInfo> infos) { - std::move(callback).Run(UrlInfoToMojo(infos)); + std::move(callback).Run(UrlInfoListToMojo(infos)); }, std::move(callback))); } @@ -532,7 +535,7 @@ return; } - std::move(callback).Run(UrlInfoToMojo( + std::move(callback).Run(UrlInfoListToMojo( shopping_service_->GetUrlInfosForRecentlyViewedWebWrappers())); }
diff --git a/components/commerce/core/webui/shopping_service_handler_unittest.cc b/components/commerce/core/webui/shopping_service_handler_unittest.cc index f2a0850..a9eef02f 100644 --- a/components/commerce/core/webui/shopping_service_handler_unittest.cc +++ b/components/commerce/core/webui/shopping_service_handler_unittest.cc
@@ -153,7 +153,8 @@ TestGetProductInfoForCurrentUrl_FeatureEligible) { base::RunLoop run_loop; - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); std::optional<commerce::ProductInfo> info; info.emplace(); @@ -177,8 +178,8 @@ TEST_F(ShoppingServiceHandlerTest, TestGetProductInfoForUrl) { base::RunLoop run_loop; - shopping_service_->SetIsPriceInsightsEligible(true); - + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); std::optional<commerce::ProductInfo> info; info.emplace(); info->title = "example_title"; @@ -210,7 +211,8 @@ info.emplace(); info->title = "example_title"; shopping_service_->SetResponseForGetProductInfoForUrl(info); - shopping_service_->SetIsPriceInsightsEligible(false); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + false); handler_->GetProductInfoForCurrentUrl(base::BindOnce( [](base::RunLoop* run_loop, shared::mojom::ProductInfoPtr product_info) { @@ -239,7 +241,8 @@ info->catalog_history_prices.emplace_back("2021-01-01", 3330000); info->catalog_history_prices.emplace_back("2021-01-02", 4440000); - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); shopping_service_->SetResponseForGetPriceInsightsInfoForUrl(info); handler_->GetPriceInsightsInfoForCurrentUrl(base::BindOnce( @@ -286,7 +289,8 @@ info->catalog_history_prices.emplace_back("2021-01-01", 3330000); info->catalog_history_prices.emplace_back("2021-01-02", 4440000); - shopping_service_->SetIsPriceInsightsEligible(true); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + true); shopping_service_->SetResponseForGetPriceInsightsInfoForUrl(info); handler_->GetPriceInsightsInfoForUrl( @@ -327,7 +331,8 @@ info.emplace(); info->product_cluster_id = 123u; - shopping_service_->SetIsPriceInsightsEligible(false); + commerce::SetUpPriceInsightsEligibility(&features_, account_checker_.get(), + false); shopping_service_->SetResponseForGetPriceInsightsInfoForUrl(info); handler_->GetPriceInsightsInfoForUrl(
diff --git a/components/commerce_strings.grdp b/components/commerce_strings.grdp index 47314bc..07839ced 100644 --- a/components/commerce_strings.grdp +++ b/components/commerce_strings.grdp
@@ -567,7 +567,7 @@ Open </message> <message name="IDS_COMPARE_CITATION_A11Y_LABEL" desc="The accessibility label for a citation in the compare feature's UI."> - Citation <ph name="CURRENT_CITATION">$1<ex>1</ex></ph> of <ph name="MAX_CITATIONS">$2<ex>3</ex></ph>, <ph name="PRODUCT_NAME">$3<ex>Laptop</ex></ph>, <ph name="URL">$4<ex>http://example.com</ex></ph> + Citation <ph name="CURRENT_CITATION">$1<ex>1</ex></ph> of <ph name="MAX_CITATIONS">$2<ex>3</ex></ph>, <ph name="PRODUCT_NAME">$3<ex>Laptop</ex></ph>, <ph name="URL">$4<ex>http://example.com</ex></ph>. <ph name="PAGE_TITLE">$5<ex>Review for Product</ex></ph>. <ph name="PAGE_PREVIEW">$6<ex>This is a brief summary of the page</ex></ph>. </message> <message name="IDS_COMPARE_DEFAULT_PAGE_TITLE" desc="The default page title for the tab compare feature."> Compare
diff --git a/components/commerce_strings_grdp/IDS_COMPARE_CITATION_A11Y_LABEL.png.sha1 b/components/commerce_strings_grdp/IDS_COMPARE_CITATION_A11Y_LABEL.png.sha1 index f9d8d15f..acd1015 100644 --- a/components/commerce_strings_grdp/IDS_COMPARE_CITATION_A11Y_LABEL.png.sha1 +++ b/components/commerce_strings_grdp/IDS_COMPARE_CITATION_A11Y_LABEL.png.sha1
@@ -1 +1 @@ -a283090b186ee376b37cb466466056308eddb71a \ No newline at end of file +345f73ddfe6c821a157e5cf1f534ed592d5b7bb9 \ No newline at end of file
diff --git a/components/enterprise/data_controls/core/browser/data_controls_policy_handler_unittest.cc b/components/enterprise/data_controls/core/browser/data_controls_policy_handler_unittest.cc index 70ecaf1..7d542e82 100644 --- a/components/enterprise/data_controls/core/browser/data_controls_policy_handler_unittest.cc +++ b/components/enterprise/data_controls/core/browser/data_controls_policy_handler_unittest.cc
@@ -503,8 +503,6 @@ ] } ])", - u"Error at PolicyForTesting[0].restrictions[0].class: Schema " - u"validation error: Invalid value for string\n" u"Error at PolicyForTesting[0]: \"PRINTING\" is not a supported " u"restriction on this platform", }, @@ -605,7 +603,8 @@ ASSERT_FALSE(errors.empty()); ASSERT_TRUE(errors.HasError(kPolicyName)); - std::u16string messages = errors.GetErrorMessages(kPolicyName); + std::u16string messages = errors.GetErrorMessages( + kPolicyName, policy::PolicyMap::MessageType::kWarning); ASSERT_EQ(messages, u"Error at PolicyForTesting[2]: Schema validation error: Policy " u"type mismatch: expected: \"dictionary\", actual: \"integer\"."); @@ -625,8 +624,6 @@ std::u16string messages = errors.GetErrorMessages(kPolicyName); ASSERT_EQ( messages, - u"Error at PolicyForTesting[3].restrictions[0].class: Schema " - u"validation error: Invalid value for string\n" u"Error at PolicyForTesting[2]: Keys \"and, or\" cannot be set in the " u"same dictionary");
diff --git a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.cc b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.cc index 5d3e8216..b177600 100644 --- a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.cc +++ b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.cc
@@ -16,6 +16,8 @@ #include "components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h" #include "components/subresource_filter/content/shared/browser/utils.h" #include "components/subresource_filter/core/common/activation_decision.h" +#include "components/subresource_filter/core/common/scoped_timers.h" +#include "components/subresource_filter/core/common/time_measurements.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom-shared.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" #include "content/public/browser/navigation_handle.h" @@ -24,6 +26,7 @@ namespace fingerprinting_protection_filter { using ::subresource_filter::ActivationDecision; +using ::subresource_filter::ScopedTimers; using ::subresource_filter::mojom::ActivationLevel; using ::subresource_filter::mojom::ActivationState; @@ -74,10 +77,21 @@ return {.level = ActivationLevel::kDisabled, .decision = ActivationDecision::ACTIVATION_DISABLED}; } - + bool has_breakage_exception = false; if (features::IsFingerprintingProtectionRefreshHeuristicExceptionEnabled( - is_incognito_) && - HasBreakageException(navigation_handle()->GetURL(), *prefs_)) { + is_incognito_)) { + auto has_exception_timer = ScopedTimers::StartIf( + features::SampleEnablePerformanceMeasurements(is_incognito_), + [](base::TimeDelta latency_sample) { + UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( + HasRefreshCountExceptionWallDurationHistogramName, latency_sample, + base::Microseconds(1), base::Seconds(10), 50); + }); + has_breakage_exception = + HasBreakageException(navigation_handle()->GetURL(), *prefs_); + } + if (has_breakage_exception) { + UMA_HISTOGRAM_BOOLEAN(HasRefreshCountExceptionHistogramName, true); // Disabled by breakage exception. return {.level = ActivationLevel::kDisabled, .decision = ActivationDecision::URL_ALLOWLISTED}; @@ -149,7 +163,7 @@ ActivationState activation_state; activation_state.activation_level = activation_result.level; activation_state.measure_performance = - GetEnablePerformanceMeasurements(is_incognito_); + features::SampleEnablePerformanceMeasurements(is_incognito_); activation_state.enable_logging = features::IsFingerprintingProtectionConsoleLoggingEnabled(); @@ -166,25 +180,4 @@ ActivationDecision::ACTIVATION_DECISION_MAX); } -namespace { - -bool ShouldMeasurePerformance(double performance_measurement_rate) { - return base::ThreadTicks::IsSupported() && - (performance_measurement_rate == 1 || - base::RandDouble() < performance_measurement_rate); -} - -} // namespace - -bool FingerprintingProtectionPageActivationThrottle:: - GetEnablePerformanceMeasurements(bool is_incognito) const { - // Performance measurement rate may differ between incognito and - // non-incognito modes. - double performance_measurement_rate = GetFieldTrialParamByFeatureAsDouble( - is_incognito ? features::kEnableFingerprintingProtectionFilterInIncognito - : features::kEnableFingerprintingProtectionFilter, - features::kPerformanceMeasurementRateParam, 0.0); - return ShouldMeasurePerformance(performance_measurement_rate); -} - } // namespace fingerprinting_protection_filter
diff --git a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.h b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.h index d141fd32..e50c507 100644 --- a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.h +++ b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle.h
@@ -61,6 +61,8 @@ private: FRIEND_TEST_ALL_PREFIXES(FPFPageActivationThrottleTestGetActivationTest, GetActivationComputesLevelAndDecision); + FRIEND_TEST_ALL_PREFIXES(FPFPageActivationThrottleTestRefreshHeuristicUmaTest, + RefreshHeuristicUmasAreLoggedCorrectly); // Computes the ActivationLevel and ActivationDecision for the current URL // based on feature flags/params and prefs. This function is necessary because
diff --git a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle_unittest.cc b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle_unittest.cc index 750ea71..af88c9c9 100644 --- a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle_unittest.cc +++ b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_page_activation_throttle_unittest.cc
@@ -350,67 +350,127 @@ mock_throttle.WillProcessResponse(); } -TEST_F(FPFPageActivationThrottleTest, FlagEnabled_MeasurePerformanceRate) { - scoped_feature_list_.InitAndEnableFeatureWithParameters( - features::kEnableFingerprintingProtectionFilter, - {{"performance_measurement_rate", "1.0"}}); +struct FPFRefreshHeuristicUmaTestCase { + std::string test_name; - auto mock_throttle = MockFingerprintingProtectionPageActivationThrottle( - mock_nav_handle_.get(), test_support_.tracking_protection_settings(), - test_support_.prefs()); + // Configuration + bool is_refresh_heuristic_enabled; + bool has_refresh_heuristic_exception; - EXPECT_EQ( - mock_throttle.GetEnablePerformanceMeasurements(/*is_incognito=*/false), - true); -} + // Expectations + bool expect_has_exception_uma; + bool expect_latency_uma; +}; -TEST_F(FPFPageActivationThrottleTest, - IncognitoFlagEnabled_MeasurePerformanceRate) { - scoped_feature_list_.InitAndEnableFeatureWithParameters( - features::kEnableFingerprintingProtectionFilterInIncognito, - {{"performance_measurement_rate", "1.0"}}); +class FPFPageActivationThrottleTestRefreshHeuristicUmaTest + : public content::RenderViewHostTestHarness, + public testing::WithParamInterface<FPFRefreshHeuristicUmaTestCase> { + public: + FPFPageActivationThrottleTestRefreshHeuristicUmaTest() = default; - auto mock_throttle = MockFingerprintingProtectionPageActivationThrottle( - mock_nav_handle_.get(), test_support_.tracking_protection_settings(), - test_support_.prefs()); + GURL GetTestUrl() { return GURL("http://cool.things.com"); } - EXPECT_EQ( - mock_throttle.GetEnablePerformanceMeasurements(/*is_incognito=*/true), - true); -} + void SetUp() override { + content::RenderViewHostTestHarness::SetUp(); + mock_nav_handle_ = std::make_unique<content::MockNavigationHandle>( + RenderViewHostTestHarness::web_contents()); + } -TEST_F( - FPFPageActivationThrottleTest, - PerformancemanceMeasurementRateNotSet_NonIncognito_DoNotMeasurePerformance) { - scoped_feature_list_.InitAndEnableFeatureWithParameters( - features::kEnableFingerprintingProtectionFilter, - /*params*/ {}); + void TearDown() override { + mock_nav_handle_.reset(); + RenderViewHostTestHarness::TearDown(); + } - auto mock_throttle = MockFingerprintingProtectionPageActivationThrottle( - mock_nav_handle_.get(), test_support_.tracking_protection_settings(), - test_support_.prefs()); + void InitializeFeatureFlag(const FPFRefreshHeuristicUmaTestCase& test_case) { + static constexpr std::string kRefreshHeuristicThreshold = "3"; + static constexpr std::string kRefreshHeuristicThresholdDisabled = "0"; + scoped_feature_list_.InitWithFeaturesAndParameters( + {{features::kEnableFingerprintingProtectionFilter, + {{"activation_level", "enabled"}, + {"performance_measurement_rate", "1.0"}, + {features::kRefreshHeuristicExceptionThresholdParam, + test_case.is_refresh_heuristic_enabled + ? kRefreshHeuristicThreshold + : kRefreshHeuristicThresholdDisabled}}}}, + {}); + } - EXPECT_EQ( - mock_throttle.GetEnablePerformanceMeasurements(/*is_incognito=*/false), - false); -} + protected: + TestSupport test_support_; + std::unique_ptr<content::MockNavigationHandle> mock_nav_handle_; + base::test::ScopedFeatureList scoped_feature_list_; +}; -TEST_F( - FPFPageActivationThrottleTest, - PerformancemanceMeasurementRateNotSet_Incognito_DoNotMeasurePerformance) { +const FPFRefreshHeuristicUmaTestCase kRefreshHeuristicUmaTestCases[] = { + {.test_name = "RefreshHeuristicEnabled_HasException_LogsUmas", + .is_refresh_heuristic_enabled = true, + .has_refresh_heuristic_exception = true, + .expect_has_exception_uma = true, + .expect_latency_uma = true}, + {.test_name = "RefreshHeuristicEnabled_NoException_LogsLatencyUma", + .is_refresh_heuristic_enabled = true, + .has_refresh_heuristic_exception = false, + .expect_has_exception_uma = false, + .expect_latency_uma = true}, + {.test_name = "RefreshHeuristicDisabled_HasException_DoesntLogUmas", + .is_refresh_heuristic_enabled = false, + .has_refresh_heuristic_exception = true, + .expect_has_exception_uma = false, + .expect_latency_uma = false}, + {.test_name = "RefreshHeuristicDisabled_NoException_DoesntLogUmas", + .is_refresh_heuristic_enabled = false, + .has_refresh_heuristic_exception = false, + .expect_has_exception_uma = false, + .expect_latency_uma = false}}; + +INSTANTIATE_TEST_SUITE_P( + FPFPageActivationThrottleTestRefreshHeuristicUmaTestTestSuiteInstantiation, + FPFPageActivationThrottleTestRefreshHeuristicUmaTest, + testing::ValuesIn<FPFRefreshHeuristicUmaTestCase>( + kRefreshHeuristicUmaTestCases), + [](const testing::TestParamInfo< + FPFPageActivationThrottleTestRefreshHeuristicUmaTest::ParamType>& + info) { return info.param.test_name; }); + +TEST_P(FPFPageActivationThrottleTestRefreshHeuristicUmaTest, + RefreshHeuristicUmasAreLoggedCorrectly) { base::HistogramTester histograms; + const FPFRefreshHeuristicUmaTestCase& test_case = GetParam(); - scoped_feature_list_.InitAndEnableFeatureWithParameters( - features::kEnableFingerprintingProtectionFilterInIncognito, - /*params*/ {}); + // Initialize feature flags and params. + InitializeFeatureFlag(test_case); - auto mock_throttle = MockFingerprintingProtectionPageActivationThrottle( + // Add exception + if (test_case.has_refresh_heuristic_exception) { + AddBreakageException(GURL(GetTestUrl()), *test_support_.prefs()); + } + + // Navigate to the test url. + mock_nav_handle_->set_url(GetTestUrl()); + + // Call `GetActivation` on throttle to trigger UMAs. + auto test_throttle = FingerprintingProtectionPageActivationThrottle( mock_nav_handle_.get(), test_support_.tracking_protection_settings(), test_support_.prefs()); + test_throttle.GetActivation(); - EXPECT_EQ( - mock_throttle.GetEnablePerformanceMeasurements(/*is_incognito=*/true), - false); + if (test_case.expect_has_exception_uma) { + histograms.ExpectTotalCount(HasRefreshCountExceptionHistogramName, 1); + histograms.ExpectUniqueSample(HasRefreshCountExceptionHistogramName, 1, 1); + } else { + histograms.ExpectTotalCount(HasRefreshCountExceptionHistogramName, 0); + } + + if (test_case.expect_latency_uma) { + // Just test whether a latency has been logged at all - we don't need to + // test the latency measurement itself, since that's done entirely by the + // subresource filter library macro (UMA_HISTOGRAM_CUSTOM_MICRO_TIMES). + histograms.ExpectTotalCount( + HasRefreshCountExceptionWallDurationHistogramName, 1); + } else { + histograms.ExpectTotalCount( + HasRefreshCountExceptionWallDurationHistogramName, 0); + } } struct FPFGetActivationTestCase { @@ -486,7 +546,7 @@ base::test::ScopedFeatureList scoped_feature_list_; }; -const FPFGetActivationTestCase kTestCases[] = { +const FPFGetActivationTestCase kGetActivationTestCases[] = { {.test_name = "FPFEnabled_ActivationEnabled_NoException_NotOnlyIf3pc", .is_fp_feature_enabled = true, .activation_level_param = ActivationLevel::kEnabled, @@ -622,7 +682,7 @@ INSTANTIATE_TEST_SUITE_P( FPFPageActivationThrottleTestGetActivationTestTestSuiteInstantiation, FPFPageActivationThrottleTestGetActivationTest, - testing::ValuesIn<FPFGetActivationTestCase>(kTestCases), + testing::ValuesIn<FPFGetActivationTestCase>(kGetActivationTestCases), [](const testing::TestParamInfo< FPFPageActivationThrottleTestGetActivationTest::ParamType>& info) { return info.param.test_name;
diff --git a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.cc b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.cc index df208a84..9223306 100644 --- a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.cc +++ b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.cc
@@ -8,6 +8,7 @@ #include "base/check.h" #include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" #include "components/fingerprinting_protection_filter/browser/fingerprinting_protection_observer.h" #include "components/fingerprinting_protection_filter/browser/throttle_manager.h" #include "components/fingerprinting_protection_filter/common/fingerprinting_protection_breakage_exception.h" @@ -20,6 +21,8 @@ #include "components/subresource_filter/content/shared/browser/utils.h" #include "components/subresource_filter/core/browser/verified_ruleset_dealer.h" #include "components/subresource_filter/core/common/load_policy.h" +#include "components/subresource_filter/core/common/scoped_timers.h" +#include "components/subresource_filter/core/common/time_measurements.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom-shared.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/navigation_handle_user_data.h" @@ -45,6 +48,7 @@ using ::subresource_filter::GetSubresourceFilterRootPage; using ::subresource_filter::IsInSubresourceFilterRoot; +using ::subresource_filter::ScopedTimers; using ::subresource_filter::VerifiedRulesetDealer; using ::subresource_filter::mojom::ActivationLevel; @@ -273,20 +277,48 @@ // refresh even if the navigation is cancelled (e.g. due to tab closing). if (subresource_blocked_in_current_primary_page() && navigation_handle->GetReloadType() != content::ReloadType::NONE) { + const GURL& url = navigation_handle->GetURL(); // Collect metrics regardless of whether the heuristic exception is enabled. int refresh_count = GetRefreshMetricsManager().IncrementAndGetRefreshCount( - navigation_handle->GetURL(), *web_contents()); + url, *web_contents()); - if (features::IsFingerprintingProtectionRefreshHeuristicExceptionEnabled( - is_incognito_) && - refresh_count >= - features::GetFingerprintingProtectionRefreshHeuristicThreshold( - is_incognito_)) { - // Heuristic: If we blocked a subresource and the user refreshes enough - // times on the same site within this WebContents, we suspect there's been - // breakage on this site and add an exception. - CHECK(pref_service_ != nullptr); - AddBreakageException(navigation_handle->GetURL(), *pref_service_); + TryAddRefreshBreakageException(url, refresh_count); + } +} + +void FingerprintingProtectionWebContentsHelper::TryAddRefreshBreakageException( + const GURL& url, + int refresh_count) { + std::string etld_plus_one = GetEtldPlusOne(url); + if (etld_plus_one.empty()) { + // Invalid URL. + return; + } + + bool was_exception_already_added = + exception_already_added_for_etld_plus_one_.contains(etld_plus_one); + if (!was_exception_already_added && + features::IsFingerprintingProtectionRefreshHeuristicExceptionEnabled( + is_incognito_) && + refresh_count >= + features::GetFingerprintingProtectionRefreshHeuristicThreshold( + is_incognito_)) { + // Heuristic: If we blocked a subresource and the user refreshes enough + // times on the same site within this WebContents, we suspect there's been + // breakage on this site and add an exception. + CHECK(pref_service_ != nullptr); + UMA_HISTOGRAM_BOOLEAN(AddRefreshCountExceptionHistogramName, true); + { + auto add_exception_timer = ScopedTimers::StartIf( + features::SampleEnablePerformanceMeasurements(is_incognito_), + [](base::TimeDelta latency_sample) { + UMA_HISTOGRAM_CUSTOM_MICRO_TIMES( + AddRefreshCountExceptionWallDurationHistogramName, + latency_sample, base::Microseconds(1), base::Seconds(10), 50); + }); + if (AddBreakageException(url, *pref_service_)) { + exception_already_added_for_etld_plus_one_.insert(etld_plus_one); + } } } }
diff --git a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.h b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.h index bf7f6472..2456d98 100644 --- a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.h +++ b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper.h
@@ -60,6 +60,7 @@ // measuring breakage on valid URLs. int IncrementAndGetRefreshCount(const GURL& url, content::WebContents& web_contents); + // Logs UMA and UKM metrics for each eTLD+1 that had at least one refresh in // the attached WebContents. void LogMetrics() const; @@ -213,6 +214,14 @@ // hide this member. RefreshMetricsManager refresh_metrics_manager_; + // Keeps track of when a refresh count heuristic breakage exception has been + // added for an eTLD+1, so that we save on performance costs of adding it + // again. + base::flat_set<std::string> exception_already_added_for_etld_plus_one_; + // Adds an exception for the eTLD+1 of the given URL if the given refresh + // count exceeds the threshold and an exception was not already added. + void TryAddRefreshBreakageException(const GURL& url, int refresh_count); + WEB_CONTENTS_USER_DATA_KEY_DECL(); };
diff --git a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper_unittest.cc b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper_unittest.cc index c2e32d5f..b4eff49b5 100644 --- a/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper_unittest.cc +++ b/components/fingerprinting_protection_filter/browser/fingerprinting_protection_web_contents_helper_unittest.cc
@@ -859,6 +859,9 @@ {{kGoogleUkmId, 2}, {kYoutubeUkmId, 4}, {kAppspotUkmId, 4}}); } +// Note: In these tests, when testing the latency UMA, we just check whether it +// is logged at all, as the measurement is done by a subresource filter library +// macro (UMA_HISTOGRAM_CUSTOM_MICRO_TIMES). class FingerprintingProtectionRefreshCountExceptionTest : public content::RenderViewHostTestHarness { public: @@ -869,9 +872,11 @@ // Enable feature param for adding exception in both regular and incognito. scoped_feature_list_.InitWithFeaturesAndParameters( {{features::kEnableFingerprintingProtectionFilter, - {{features::kRefreshHeuristicExceptionThresholdParam, "3"}}}, + {{features::kRefreshHeuristicExceptionThresholdParam, "3"}, + {"performance_measurement_rate", "1.0"}}}, {features::kEnableFingerprintingProtectionFilterInIncognito, - {{features::kRefreshHeuristicExceptionThresholdParam, "3"}}}}, + {{features::kRefreshHeuristicExceptionThresholdParam, "3"}, + {"performance_measurement_rate", "1.0"}}}}, {}); } @@ -907,27 +912,36 @@ base::test::ScopedFeatureList scoped_feature_list_; TestSupport test_support_; }; - TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NotEnoughRefreshesOnOneSite_NoException_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 0); EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, RefreshesOnOneSite_HasException_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 3); EXPECT_TRUE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 1); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 1); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 1); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NonContiguousRefreshesOnOneSite_HasException_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 1); @@ -937,10 +951,16 @@ EXPECT_TRUE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); // No exception for the non-refreshed site. EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); + // UMAs for one exception added. + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 1); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 1); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 1); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NotEnoughRefreshesOnMultipleSites_NoExceptions_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 1); @@ -951,10 +971,14 @@ EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, RefreshesOnMultipleSites_AllHaveExceptions_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 3); @@ -964,11 +988,17 @@ EXPECT_TRUE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_TRUE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_TRUE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + // UMAs for 3 exceptions added + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 3); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 3); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 3); } TEST_F( FingerprintingProtectionRefreshCountExceptionTest, NonContiguousRefreshesOfDifferentAmountsOnMultipleSites_SomeHaveExceptions_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); // Navigate between different sites and reload multiple times each, but only @@ -987,10 +1017,16 @@ EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); EXPECT_FALSE( HasBreakageException(GURL(kNonReloadedSiteUrl), *test_support_.prefs())); + // UMAs for 2 exceptions added + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 2); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 2); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 2); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, RefreshHeuristicParamDisabled_NoException_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); // Disable feature param for exception. @@ -1007,10 +1043,14 @@ EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NoBlockedSubresource_NoException_Incognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/true); // Navigate and reload multiple times each, but no blocked subresources. @@ -1021,28 +1061,41 @@ EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NotEnoughRefreshesOnOneSite_NoException_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 0); EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, RefreshesOnOneSite_HasException_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 3); EXPECT_TRUE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 1); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 1); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 1); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NonContiguousRefreshesOnOneSite_HasException_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 1); @@ -1052,10 +1105,16 @@ EXPECT_TRUE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); // No exception for the non-refreshed site. EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); + // UMAs for one exception added. + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 1); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 1); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 1); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NotEnoughRefreshesOnMultipleSites_NoExceptions_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 1); @@ -1066,10 +1125,14 @@ EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, RefreshesOnMultipleSites_AllHaveExceptions_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); NavigateBlockSubresourceAndReloadNTimes(kGoogleUrl, 3); @@ -1079,11 +1142,17 @@ EXPECT_TRUE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_TRUE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_TRUE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + // UMAs for three exceptions added. + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 3); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 3); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 3); } TEST_F( FingerprintingProtectionRefreshCountExceptionTest, NonContiguousRefreshesOfDifferentAmountsOnMultipleSites_SomeHaveExceptions_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); // Navigate between different sites and reload multiple times each, but only @@ -1102,10 +1171,16 @@ EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); EXPECT_FALSE( HasBreakageException(GURL(kNonReloadedSiteUrl), *test_support_.prefs())); + // UMAs for two exceptions added. + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 2); + histograms.ExpectUniqueSample(AddRefreshCountExceptionHistogramName, 1, 2); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 2); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, RefreshHeuristicParamDisabled_NoException_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); // Disable feature param for exception. @@ -1122,10 +1197,14 @@ EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } TEST_F(FingerprintingProtectionRefreshCountExceptionTest, NoBlockedSubresource_NoException_NonIncognito) { + base::HistogramTester histograms; InitializeWebContentsHelper(/*is_incognito=*/false); // Navigate and reload multiple times each, but no blocked subresources. @@ -1136,6 +1215,9 @@ EXPECT_FALSE(HasBreakageException(GURL(kGoogleUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kYoutubeUrl), *test_support_.prefs())); EXPECT_FALSE(HasBreakageException(GURL(kAppspotUrl), *test_support_.prefs())); + histograms.ExpectTotalCount(AddRefreshCountExceptionHistogramName, 0); + histograms.ExpectTotalCount(AddRefreshCountExceptionWallDurationHistogramName, + 0); } } // namespace
diff --git a/components/fingerprinting_protection_filter/common/BUILD.gn b/components/fingerprinting_protection_filter/common/BUILD.gn index b3b6616f..ea29b6f 100644 --- a/components/fingerprinting_protection_filter/common/BUILD.gn +++ b/components/fingerprinting_protection_filter/common/BUILD.gn
@@ -53,11 +53,16 @@ source_set("unit_tests") { testonly = true - sources = [ "fingerprinting_protection_breakage_exception_unittest.cc" ] + sources = [ + "fingerprinting_protection_breakage_exception_unittest.cc", + "fingerprinting_protection_filter_features_unittest.cc", + ] deps = [ ":exceptions", + ":features", ":prefs", "//base", + "//base/test:test_support", "//components/prefs", "//components/prefs:test_support", "//testing/gtest",
diff --git a/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_constants.h b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_constants.h index 579e2b4..55f6434f 100644 --- a/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_constants.h +++ b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_constants.h
@@ -40,6 +40,21 @@ const char RefreshCountHistogramName[] = "FingerprintingProtection.WebContentsObserver.RefreshCount"; +const char HasRefreshCountExceptionHistogramName[] = + "FingerprintingProtection.PageLoad.RefreshCount.SiteHasBreakageException"; + +const char AddRefreshCountExceptionHistogramName[] = + "FingerprintingProtection.WebContentsObserver.RefreshCount." + "AddBreakageException"; + +const char HasRefreshCountExceptionWallDurationHistogramName[] = + "FingerprintingProtection.PageLoad.RefreshCount." + "SiteHasBreakageExceptionWallDuration"; + +const char AddRefreshCountExceptionWallDurationHistogramName[] = + "FingerprintingProtection.WebContentsObserver.RefreshCount." + "AddBreakageExceptionWallDuration"; + // Console messages // ----------------
diff --git a/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.cc b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.cc index 9d4787c..f4d522f 100644 --- a/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.cc +++ b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.cc
@@ -6,6 +6,7 @@ #include "base/feature_list.h" #include "base/metrics/field_trial_params.h" +#include "base/rand_util.h" #include "components/subresource_filter/core/mojom/subresource_filter.mojom.h" namespace fingerprinting_protection_filter::features { @@ -55,6 +56,23 @@ return kRefreshHeuristicExceptionThresholdNonIncognito.Get(); } +bool SampleEnablePerformanceMeasurements(bool is_incognito) { + if (!base::ThreadTicks::IsSupported()) { + // Can't do accurate performance measurements if ThreadTicks not supported. + return false; + } + + // Get sampling rate based on whether we're in incognito. + const base::Feature& feature = + is_incognito ? features::kEnableFingerprintingProtectionFilterInIncognito + : features::kEnableFingerprintingProtectionFilter; + const double sampling_rate = GetFieldTrialParamByFeatureAsDouble( + feature, features::kPerformanceMeasurementRateParam, 0.0); + + // Randomly sample. + return base::RandDouble() < sampling_rate; +} + constexpr base::FeatureParam<subresource_filter::mojom::ActivationLevel>::Option kActivationLevelOptions[] = { {subresource_filter::mojom::ActivationLevel::kDisabled, "disabled"},
diff --git a/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h index 8bf086f..8c47c1a5 100644 --- a/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h +++ b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h
@@ -53,6 +53,12 @@ COMPONENT_EXPORT(FINGERPRINTING_PROTECTION_FILTER_FEATURES) int GetFingerprintingProtectionRefreshHeuristicThreshold(bool is_incognito); +// Randomly determines whether performance measurements will be enabled, +// using the rate specified by the regular or incognito feature flag parameter, +// depending on the value of `is_incognito`. +COMPONENT_EXPORT(FINGERPRINTING_PROTECTION_FILTER_FEATURES) +bool SampleEnablePerformanceMeasurements(bool is_incognito); + COMPONENT_EXPORT(FINGERPRINTING_PROTECTION_FILTER_FEATURES) extern const base::FeatureParam<subresource_filter::mojom::ActivationLevel> kActivationLevel;
diff --git a/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features_unittest.cc b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features_unittest.cc new file mode 100644 index 0000000..d1c1ef1 --- /dev/null +++ b/components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features_unittest.cc
@@ -0,0 +1,61 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h" + +#include "base/test/scoped_feature_list.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace fingerprinting_protection_filter::features { +namespace { + +class FingerprintingProtectionFeaturesTest : public ::testing::Test { + public: + FingerprintingProtectionFeaturesTest() = default; + void SetUp() override {} + + void TearDown() override { scoped_feature_list_.Reset(); } + + protected: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +TEST_F(FingerprintingProtectionFeaturesTest, + PerformancemanceMeasurementRateSet_NonIncognito_MeasurePerformance) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + features::kEnableFingerprintingProtectionFilter, + {{"performance_measurement_rate", "1.0"}}); + + EXPECT_EQ(SampleEnablePerformanceMeasurements(/*is_incognito=*/false), true); +} + +TEST_F(FingerprintingProtectionFeaturesTest, + PerformancemanceMeasurementRateSet_Incognito_MeasurePerformance) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + features::kEnableFingerprintingProtectionFilterInIncognito, + {{"performance_measurement_rate", "1.0"}}); + + EXPECT_EQ(SampleEnablePerformanceMeasurements(/*is_incognito=*/true), true); +} + +TEST_F( + FingerprintingProtectionFeaturesTest, + PerformancemanceMeasurementRateNotSet_NonIncognito_DoNotMeasurePerformance) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + features::kEnableFingerprintingProtectionFilter, {{}}); + + EXPECT_EQ(SampleEnablePerformanceMeasurements(/*is_incognito=*/false), false); +} + +TEST_F( + FingerprintingProtectionFeaturesTest, + PerformancemanceMeasurementRateNotSet_Incognito_DoNotMeasurePerformance) { + scoped_feature_list_.InitAndEnableFeatureWithParameters( + features::kEnableFingerprintingProtectionFilter, {{}}); + + EXPECT_EQ(SampleEnablePerformanceMeasurements(/*is_incognito=*/true), false); +} + +} // namespace +} // namespace fingerprinting_protection_filter::features
diff --git a/components/memory_pressure/system_memory_pressure_evaluator_win.cc b/components/memory_pressure/system_memory_pressure_evaluator_win.cc index 0d7ccb6..0984139 100644 --- a/components/memory_pressure/system_memory_pressure_evaluator_win.cc +++ b/components/memory_pressure/system_memory_pressure_evaluator_win.cc
@@ -302,8 +302,14 @@ base::UmaHistogramCounts10M("Memory.CommitRemainingMB", remaining_limit_int); // Calculate percentage used - uint64_t temp_percentage = (commit_total_mb * 100) / commit_limit_mb; - int percentage_used = base::saturated_cast<int>(temp_percentage); + int percentage_used; + if (commit_limit_int == 0) { + // Handle division by zero. + percentage_used = 0; + } else { + uint64_t temp_percentage = (commit_total_mb * 100) / commit_limit_mb; + percentage_used = base::saturated_cast<int>(temp_percentage); + } base::UmaHistogramPercentage("Memory.CommitPercentageUsed", percentage_used); }
diff --git a/components/memory_pressure/system_memory_pressure_evaluator_win_unittest.cc b/components/memory_pressure/system_memory_pressure_evaluator_win_unittest.cc index 074d7472..8578123 100644 --- a/components/memory_pressure/system_memory_pressure_evaluator_win_unittest.cc +++ b/components/memory_pressure/system_memory_pressure_evaluator_win_unittest.cc
@@ -410,5 +410,40 @@ 1); } +// Verifies behavior when commit limit is zero (division by zero). +TEST_F(WinSystemMemoryPressureEvaluatorTest, DivisionByZero) { + base::HistogramTester histogram_tester; + TestSystemMemoryPressureEvaluator evaluator(false, nullptr); + evaluator.SetPerformanceRetrievalSuccessCall(true); + evaluator.SetCommitLimit(0, 0); // Commit limit is zero. + + evaluator.RecordCommitHistograms(); + + histogram_tester.ExpectUniqueSample( + kPerformanceInfoRetrievalSuccessHistogramName, true, 1); + histogram_tester.ExpectUniqueSample(kCommitLimitMBHistogramName, 0, 1); + histogram_tester.ExpectUniqueSample(kCommitRemainingMBHistogramName, 0, 1); + histogram_tester.ExpectUniqueSample(kCommitPercentageUsedHistogramName, 0, 1); +} + +// Verifies behavior with potential underflow when calculating remaining commit +// limit. +TEST_F(WinSystemMemoryPressureEvaluatorTest, PotentialUnderflow) { + base::HistogramTester histogram_tester; + TestSystemMemoryPressureEvaluator evaluator(false, nullptr); + evaluator.SetPerformanceRetrievalSuccessCall(true); + // Set a commit total that is greater than commit limit + evaluator.SetCommitLimit(1024, 2048); + + evaluator.RecordCommitHistograms(); + + histogram_tester.ExpectUniqueSample( + kPerformanceInfoRetrievalSuccessHistogramName, true, 1); + histogram_tester.ExpectUniqueSample(kCommitLimitMBHistogramName, 4, 1); + histogram_tester.ExpectUniqueSample(kCommitRemainingMBHistogramName, 0, 1); + histogram_tester.ExpectUniqueSample(kCommitPercentageUsedHistogramName, 200, + 1); +} + } // namespace win } // namespace memory_pressure
diff --git a/components/omnibox/browser/BUILD.gn b/components/omnibox/browser/BUILD.gn index b09c56f..354ea41 100644 --- a/components/omnibox/browser/BUILD.gn +++ b/components/omnibox/browser/BUILD.gn
@@ -193,6 +193,8 @@ "document_provider.h", "document_suggestions_service.cc", "document_suggestions_service.h", + "enterprise_search_aggregator_provider.cc", + "enterprise_search_aggregator_provider.h", "favicon_cache.cc", "favicon_cache.h", "featured_search_provider.cc",
diff --git a/components/omnibox/browser/autocomplete_classifier.cc b/components/omnibox/browser/autocomplete_classifier.cc index 00ad5a30..ec9df37 100644 --- a/components/omnibox/browser/autocomplete_classifier.cc +++ b/components/omnibox/browser/autocomplete_classifier.cc
@@ -83,6 +83,7 @@ AutocompleteProvider::TYPE_SEARCH | AutocompleteProvider::TYPE_SHORTCUTS | AutocompleteProvider::TYPE_HISTORY_FUZZY | AutocompleteProvider::TYPE_CALCULATOR | + AutocompleteProvider::TYPE_ENTERPRISE_SEARCH_AGGREGATOR | #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_IOS) (history_embeddings::GetFeatureParameters().omnibox_scoped || history_embeddings::GetFeatureParameters().omnibox_unscoped
diff --git a/components/omnibox/browser/autocomplete_controller.cc b/components/omnibox/browser/autocomplete_controller.cc index ebe968f..65879bf 100644 --- a/components/omnibox/browser/autocomplete_controller.cc +++ b/components/omnibox/browser/autocomplete_controller.cc
@@ -56,6 +56,7 @@ #include "components/omnibox/browser/calculator_provider.h" #include "components/omnibox/browser/clipboard_provider.h" #include "components/omnibox/browser/document_provider.h" +#include "components/omnibox/browser/enterprise_search_aggregator_provider.h" #include "components/omnibox/browser/featured_search_provider.h" #include "components/omnibox/browser/history_embeddings_provider.h" #include "components/omnibox/browser/history_fuzzy_provider.h" @@ -1114,10 +1115,15 @@ // Don't run document provider, except for Google Drive. case AutocompleteProvider::TYPE_DOCUMENT: - return (keyword_turl && - base::StartsWith(keyword_turl->url(), - "https://drive.google.com", - base::CompareCase::INSENSITIVE_ASCII)); + return keyword_turl && + base::StartsWith(keyword_turl->url(), "https://drive.google.com", + base::CompareCase::INSENSITIVE_ASCII); + + // Don't run aggregator provider unless the user is in a aggregator scope. + case AutocompleteProvider::TYPE_ENTERPRISE_SEARCH_AGGREGATOR: + return keyword_turl && + keyword_turl->policy_origin() == + TemplateURLData::PolicyOrigin::kSearchAggregator; // Treat all other providers as usual. default: @@ -1128,6 +1134,8 @@ // Some providers should only run in starter pack mode or in the CrOS // launcher. If we reach here, we're not in starter pack mode. switch (provider->type()) { + case AutocompleteProvider::TYPE_ENTERPRISE_SEARCH_AGGREGATOR: + return false; case AutocompleteProvider::TYPE_OPEN_TAB: return is_cros_launcher_; #if !BUILDFLAG(IS_IOS) @@ -1185,6 +1193,10 @@ document_provider_ = DocumentProvider::Create(provider_client_.get(), this); providers_.push_back(document_provider_.get()); } + if (provider_types & + AutocompleteProvider::TYPE_ENTERPRISE_SEARCH_AGGREGATOR) { + providers_.push_back(new EnterpriseSearchAggregatorProvider()); + } if (provider_types & AutocompleteProvider::TYPE_ON_DEVICE_HEAD) { on_device_head_provider_ = OnDeviceHeadProvider::Create(provider_client_.get(), this);
diff --git a/components/omnibox/browser/autocomplete_controller.h b/components/omnibox/browser/autocomplete_controller.h index 8be1470d..2e75d27 100644 --- a/components/omnibox/browser/autocomplete_controller.h +++ b/components/omnibox/browser/autocomplete_controller.h
@@ -36,10 +36,6 @@ #include "components/optimization_guide/machine_learning_tflite_buildflags.h" #include "third_party/omnibox_proto/types.pb.h" -#if BUILDFLAG(BUILD_WITH_TFLITE_LIB) -#include "components/omnibox/browser/autocomplete_scoring_model_service.h" -#endif // BUILDFLAG(BUILD_WITH_TFLITE_LIB) - class ClipboardProvider; class DocumentProvider; class FeaturedSearchProvider;
diff --git a/components/omnibox/browser/enterprise_search_aggregator_provider.cc b/components/omnibox/browser/enterprise_search_aggregator_provider.cc new file mode 100644 index 0000000..84ec12b --- /dev/null +++ b/components/omnibox/browser/enterprise_search_aggregator_provider.cc
@@ -0,0 +1,37 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "enterprise_search_aggregator_provider.h" + +#include "components/omnibox/browser/autocomplete_input.h" +#include "components/omnibox/browser/autocomplete_provider.h" +#include "components/omnibox/common/omnibox_feature_configs.h" + +EnterpriseSearchAggregatorProvider::EnterpriseSearchAggregatorProvider() + : AutocompleteProvider( + AutocompleteProvider::TYPE_ENTERPRISE_SEARCH_AGGREGATOR) {} + +EnterpriseSearchAggregatorProvider::~EnterpriseSearchAggregatorProvider() = + default; + +void EnterpriseSearchAggregatorProvider::Start(const AutocompleteInput& input, + bool minimal_changes) { + if (!omnibox_feature_configs::SearchAggregatorProvider::Get() + .AreMockEnginesValid()) { + return; + } + + matches_.clear(); + AutocompleteMatch match{this, 1000, false, + AutocompleteMatchType::FEATURED_ENTERPRISE_SEARCH}; + match.destination_url = GURL{"https://google.com"}; + match.contents = u"This is a FEATURED_ENTERPRISE_SEARCH match"; + match.description = u"This is a FEATURED_ENTERPRISE_SEARCH match"; + matches_.push_back(match); +} + +void EnterpriseSearchAggregatorProvider::Stop(bool clear_cached_results, + bool due_to_user_inactivity) { + done_ = true; +}
diff --git a/components/omnibox/browser/enterprise_search_aggregator_provider.h b/components/omnibox/browser/enterprise_search_aggregator_provider.h new file mode 100644 index 0000000..e368008b --- /dev/null +++ b/components/omnibox/browser/enterprise_search_aggregator_provider.h
@@ -0,0 +1,22 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_OMNIBOX_BROWSER_ENTERPRISE_SEARCH_AGGREGATOR_PROVIDER_H_ +#define COMPONENTS_OMNIBOX_BROWSER_ENTERPRISE_SEARCH_AGGREGATOR_PROVIDER_H_ + +#include "components/omnibox/browser/autocomplete_provider.h" + +class EnterpriseSearchAggregatorProvider : public AutocompleteProvider { + public: + EnterpriseSearchAggregatorProvider(); + + // AutocompleteProvider: + void Start(const AutocompleteInput& input, bool minimal_changes) override; + void Stop(bool clear_cached_results, bool due_to_user_inactivity) override; + + private: + ~EnterpriseSearchAggregatorProvider() override; +}; + +#endif // COMPONENTS_OMNIBOX_BROWSER_ENTERPRISE_SEARCH_AGGREGATOR_PROVIDER_H_
diff --git a/components/omnibox/common/omnibox_feature_configs.cc b/components/omnibox/common/omnibox_feature_configs.cc index fe1075d..650c33b 100644 --- a/components/omnibox/common/omnibox_feature_configs.cc +++ b/components/omnibox/common/omnibox_feature_configs.cc
@@ -94,42 +94,35 @@ base::FEATURE_DISABLED_BY_DEFAULT); SearchAggregatorProvider::SearchAggregatorProvider() { - Init( - /*enabled=*/base::FeatureList::IsEnabled(kSearchAggregatorProvider), - /*name=*/ - base::FeatureParam<std::string>(&kSearchAggregatorProvider, "name", "") - .Get(), - /*shortcut=*/ - base::FeatureParam<std::string>(&kSearchAggregatorProvider, "shortcut", - "") - .Get(), - /*search_url=*/ - base::FeatureParam<std::string>(&kSearchAggregatorProvider, "search_url", - "") - .Get(), - /*suggest_url=*/ - base::FeatureParam<std::string>(&kSearchAggregatorProvider, "suggest_url", - "") - .Get(), - /*icon_url=*/ - base::FeatureParam<std::string>(&kSearchAggregatorProvider, "icon_url", - "") - .Get(), - /*trigger_omnibox_blending=*/ + enabled = base::FeatureList::IsEnabled(kSearchAggregatorProvider); + name = base::FeatureParam<std::string>(&kSearchAggregatorProvider, "name", "") + .Get(); + shortcut = base::FeatureParam<std::string>(&kSearchAggregatorProvider, + "shortcut", "") + .Get(); + search_url = base::FeatureParam<std::string>(&kSearchAggregatorProvider, + "search_url", "") + .Get(); + suggest_url = base::FeatureParam<std::string>(&kSearchAggregatorProvider, + "suggest_url", "") + .Get(); + icon_url = base::FeatureParam<std::string>(&kSearchAggregatorProvider, + "icon_url", "") + .Get(); + trigger_omnibox_blending = base::FeatureParam<bool>(&kSearchAggregatorProvider, "trigger_omnibox_blending", false) - .Get(), - /*callback_delay=*/ + .Get(); + callback_delay = base::FeatureParam<base::TimeDelta>( &kSearchAggregatorProvider, "callback_delay", base::Milliseconds(0)) - .Get(), - /*num_suggestions=*/ + .Get(); + num_suggestions = base::FeatureParam<int>(&kSearchAggregatorProvider, "num_suggestions", 0) - .Get(), - /*response_type=*/ - base::FeatureParam<std::string>(&kSearchAggregatorProvider, - "response_type", "success") - .Get()); + .Get(); + response_type = base::FeatureParam<std::string>(&kSearchAggregatorProvider, + "response_type", "success") + .Get(); } SearchAggregatorProvider::SearchAggregatorProvider( @@ -140,77 +133,33 @@ SearchAggregatorProvider::~SearchAggregatorProvider() = default; -std::vector<base::Value> SearchAggregatorProvider::GetSearchEngines() const { +bool SearchAggregatorProvider::AreMockEnginesValid() const { + return enabled && !shortcut.empty() && shortcut[0] != '@' && !name.empty() && + !search_url.empty() && + search_url.find("{searchTerms}") != std::string::npos && + !suggest_url.empty(); +} + +std::vector<base::Value> SearchAggregatorProvider::CreateMockSearchEngines() + const { std::vector<base::Value> engines; - if (valid_search_engine()) { - engines.emplace_back( - CreateMockSearchAggregator(/*featured_by_policy=*/true)); - engines.emplace_back( - CreateMockSearchAggregator(/*featured_by_policy=*/false)); - } + engines.emplace_back(CreateMockSearchAggregator(/*featured_by_policy=*/true)); + engines.emplace_back( + CreateMockSearchAggregator(/*featured_by_policy=*/false)); return engines; } -void SearchAggregatorProvider::Init(bool enabled, - const std::string& name, - const std::string& shortcut, - const std::string& search_url, - const std::string& suggest_url, - const std::string& icon_url, - bool trigger_omnibox_blending, - base::TimeDelta callback_delay, - int num_suggestions, - const std::string& response_type) { - enabled_ = enabled; - if (!enabled_) { - return; - } - - name_ = name; - shortcut_ = shortcut; - search_url_ = search_url; - suggest_url_ = suggest_url; - icon_url_ = icon_url; - trigger_omnibox_blending_ = trigger_omnibox_blending; - callback_delay_ = callback_delay; - num_suggestions_ = num_suggestions; - response_type_ = response_type; - - // Perform some soft validation to prevent crashes downstream. - valid_search_engine_ = - !shortcut_.empty() && shortcut_[0] != '@' && !name_.empty() && - !search_url_.empty() && - search_url_.find("{searchTerms}") != std::string::npos && - !suggest_url_.empty(); - if (!valid_search_engine_) { - VLOG(2) << "Search aggregator injected by field trial is invalid"; - return; - } -} - -void SearchAggregatorProvider::Init(bool enabled, - bool trigger_omnibox_blending) { - Init(/*enabled=*/enabled, - /*name=*/"", - /*shortcut=*/"", - /*search_url=*/"", - /*suggest_url=*/"", - /*icon_url=*/"", - /*trigger_omnibox_blending=*/trigger_omnibox_blending, - /*callback_delay=*/base::Milliseconds(0), - /*num_suggestions=*/0, - /*response_type=*/"success"); -} - base::Value::Dict SearchAggregatorProvider::CreateMockSearchAggregator( bool featured_by_policy) const { + CHECK(AreMockEnginesValid()); + base::Value::Dict result; - result.Set("short_name", name_); - result.Set("keyword", featured_by_policy ? '@' + shortcut_ : shortcut_); - result.Set("url", search_url_); - result.Set("suggestions_url", suggest_url_); - if (!icon_url_.empty()) { - result.Set("favicon_url", icon_url_); + result.Set("short_name", name); + result.Set("keyword", featured_by_policy ? '@' + shortcut : shortcut); + result.Set("url", search_url); + result.Set("suggestions_url", suggest_url); + if (!icon_url.empty()) { + result.Set("favicon_url", icon_url); } result.Set("policy_origin",
diff --git a/components/omnibox/common/omnibox_feature_configs.h b/components/omnibox/common/omnibox_feature_configs.h index 014cd03b..32c9cf0 100644 --- a/components/omnibox/common/omnibox_feature_configs.h +++ b/components/omnibox/common/omnibox_feature_configs.h
@@ -9,8 +9,6 @@ #include "base/time/time.h" #include "base/values.h" -class EnterpriseSearchManagerProviderInjectionTest; - namespace omnibox_feature_configs { /* @@ -77,8 +75,10 @@ class Config { public: static const T& Get() { - static T config; - return config; + static T* config; + if (config == nullptr) + config = new T(); + return *config; } }; @@ -169,68 +169,44 @@ // If enabled, injects a mock search engine using the same format as policy // `EnterpriseSearchAggregatorSettings` to be applied. Ignored if feature // policy is set. -class SearchAggregatorProvider : public Config<SearchAggregatorProvider> { +struct SearchAggregatorProvider : Config<SearchAggregatorProvider> { DECLARE_FEATURE(kSearchAggregatorProvider); - - public: SearchAggregatorProvider(); SearchAggregatorProvider(const SearchAggregatorProvider&); SearchAggregatorProvider& operator=(const SearchAggregatorProvider&); ~SearchAggregatorProvider(); - bool enabled() const { return enabled_; } - bool valid_search_engine() const { return valid_search_engine_; } - std::vector<base::Value> GetSearchEngines() const; - bool trigger_omnibox_blending() const { return trigger_omnibox_blending_; } - - private: - friend ::EnterpriseSearchManagerProviderInjectionTest; - - // Makes it easier for tests to set a config. - void Init(bool enabled, - const std::string& name, - const std::string& shortcut, - const std::string& search_url, - const std::string& suggest_url, - const std::string& icon_url, - bool trigger_omnibox_blending, - base::TimeDelta callback_delay, - int num_suggestions, - const std::string& response_type); - // Same as `Init(,,,,,,)` setting all string arguments as empty. - void Init(bool enabled, bool trigger_omnibox_blending); - - // Returns a dictionary corresponding to the search engine + // Utility methods + bool AreMockEnginesValid() const; + std::vector<base::Value> CreateMockSearchEngines() const; base::Value::Dict CreateMockSearchAggregator(bool featured_by_policy) const; - // If true, injects mock search aggregator in the Omnibox. - bool enabled_ = false; - // If true, the data passes soft validation that prevents crashes downstream. - // Only set as true is `enabled_` is true. - bool valid_search_engine_ = false; + bool enabled; + // The search engine name, shown in the Omnibox. - std::string name_; + std::string name; // The shortcut the user enters to trigger the search. - std::string shortcut_; + std::string shortcut; // The URL on which to perform a search. - std::string search_url_; + std::string search_url; // The URL that provides search suggestions. - std::string suggest_url_; + std::string suggest_url; // The URL to an imanage that will be used on search suggestions. - std::string icon_url_; + std::string icon_url; // If enabled, Chrome will blend search suggestions with other Omnibox // suggestions without requiring keyword mode. - bool trigger_omnibox_blending_ = false; + bool trigger_omnibox_blending; // The amount of time to wait before calling the callback function after // making a request to get enterprise suggestions. - base::TimeDelta callback_delay_; + base::TimeDelta callback_delay; // The number of suggestions to show users. - int num_suggestions_; + int num_suggestions; // Type of request response. Can be one of the following strings. - // "success" - Successful response. - // "success_no_suggestions" - Successful response but empty suggestions field. - // "backoff" - No response was sent or response took too long. - std::string response_type_; + // - "success" - Successful response. + // - "success_no_suggestions" - Successful response but empty suggestions + // field. + // - "backoff" - No response was sent or response took too long. + std::string response_type; }; // If enabled, uses RichAnswerTemplate instead of SuggestionAnswer to display
diff --git a/components/optimization_guide/content/browser/page_content_proto_util.cc b/components/optimization_guide/content/browser/page_content_proto_util.cc index d028b88d..4e9e3c3 100644 --- a/components/optimization_guide/content/browser/page_content_proto_util.cc +++ b/components/optimization_guide/content/browser/page_content_proto_util.cc
@@ -70,6 +70,9 @@ return optimization_guide::proto::ANNOTATED_ROLE_ASIDE; case blink::mojom::AIPageContentAnnotatedRole::kFooter: return optimization_guide::proto::ANNOTATED_ROLE_FOOTER; + case blink::mojom::AIPageContentAnnotatedRole::kContentHidden: + // TODO(crbug.com/383541963): Wire up to the proto format. + return optimization_guide::proto::ANNOTATED_ROLE_UNKNOWN; } NOTREACHED(); }
diff --git a/components/optimization_guide/proto/features/model_prototyping.proto b/components/optimization_guide/proto/features/model_prototyping.proto index 2e8db48e..fbe6ecb7 100644 --- a/components/optimization_guide/proto/features/model_prototyping.proto +++ b/components/optimization_guide/proto/features/model_prototyping.proto
@@ -368,7 +368,6 @@ string logging_description = 2; // The email address of the user who uploaded the data. This will only be - // populated for the TVC data upload, this field will not be scrubbed and will - // be used to identify the user if there are issues with this feature. + // populated for the TVC data upload. string user_email = 3; }
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc index 7f31835..a18c40f 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc +++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.cc
@@ -59,24 +59,6 @@ namespace page_load_metrics { -namespace features { - -// Enables or disables the restricted navigation ad tagging feature. When -// enabled, the AdTagging heuristic is modified to additional information to -// determine if a frame is an ad. If the frame's navigation url matches an allow -// list rule, it is not an ad. -// -// If a frame's navigation url does not match a blocked rule, but was created by -// ad script and is same domain to the top-level frame, it is not an ad. -// -// Currently this feature only changes AdTagging behavior for metrics recorded -// in AdsPageLoadMetricsObserver, and for triggering the Heavy Ad Intervention. -BASE_FEATURE(kRestrictedNavigationAdTagging, - "RestrictedNavigationAdTagging", - base::FEATURE_ENABLED_BY_DEFAULT); - -} // namespace features - namespace { using RectId = PageAdDensityTracker::RectId; @@ -261,8 +243,6 @@ base::TickClock* clock, heavy_ad_intervention::HeavyAdBlocklist* blocklist) : clock_(clock ? clock : base::DefaultTickClock::GetInstance()), - restricted_navigation_ad_tagging_enabled_(base::FeatureList::IsEnabled( - features::kRestrictedNavigationAdTagging)), heavy_ad_service_(heavy_ad_service), application_locale_getter_(application_locale_getter), heavy_ad_blocklist_(blocklist), @@ -557,8 +537,7 @@ // Only un-tag frames as ads if the navigation has committed. This prevents // frames from being untagged that have an aborted navigation to allowlist // urls. - if (restricted_navigation_ad_tagging_enabled_ && load_policy && - navigation_handle->GetNetErrorCode() == net::OK && + if (load_policy && navigation_handle->GetNetErrorCode() == net::OK && navigation_handle->HasCommitted()) { // If a filter list explicitly allows the rule, we should ignore a detected // ad.
diff --git a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h index 2e0bc9a..d4213a5 100644 --- a/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h +++ b/components/page_load_metrics/browser/observers/ad_metrics/ads_page_load_metrics_observer.h
@@ -37,10 +37,6 @@ namespace page_load_metrics { -namespace features { -BASE_DECLARE_FEATURE(kRestrictedNavigationAdTagging); -} - // This observer labels each sub-frame as an ad or not, and keeps track of // relevant per-frame and whole-page byte statistics. class AdsPageLoadMetricsObserver @@ -299,10 +295,6 @@ // page. bool page_load_is_reload_ = false; - // Whether the restricted navigation ad tagging feature is enabled on this - // page load. - const bool restricted_navigation_ad_tagging_enabled_; - // Stores whether the heavy ad intervention is blocklisted or not for the user // on the URL of this page. Incognito Profiles will cause this to be set to // true. Used as a cache to avoid checking the blocklist once the page is
diff --git a/components/password_manager/ios/password_suggestion_helper_unittest.mm b/components/password_manager/ios/password_suggestion_helper_unittest.mm index 062baca5..1e4f46c 100644 --- a/components/password_manager/ios/password_suggestion_helper_unittest.mm +++ b/components/password_manager/ios/password_suggestion_helper_unittest.mm
@@ -127,7 +127,8 @@ fieldType:fieldType type:kQueryFocusType typedValue:@"" - frameID:frameID]; + frameID:frameID + onlyPassword:NO]; } FormSuggestionProviderQuery* BuildPasswordQuery(
diff --git a/components/password_manager/ios/shared_password_controller.mm b/components/password_manager/ios/shared_password_controller.mm index 867294b..7030115 100644 --- a/components/password_manager/ios/shared_password_controller.mm +++ b/components/password_manager/ios/shared_password_controller.mm
@@ -645,7 +645,8 @@ [suggestions addObject:suggestion]; } - if ([self canGeneratePasswordForForm:formQuery.formRendererID + if (!formQuery.onlyPassword && + [self canGeneratePasswordForForm:formQuery.formRendererID fieldIdentifier:formQuery.fieldRendererID fieldType:formQuery.fieldType inFrame:frame]) {
diff --git a/components/password_manager/ios/shared_password_controller_unittest.mm b/components/password_manager/ios/shared_password_controller_unittest.mm index 9ad0c3c7..846478e 100644 --- a/components/password_manager/ios/shared_password_controller_unittest.mm +++ b/components/password_manager/ios/shared_password_controller_unittest.mm
@@ -528,7 +528,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; auto web_frame = web::FakeWebFrame::Create(SysNSStringToUTF8(kTestFrameID), @@ -570,7 +571,8 @@ fieldType:kObfuscatedFieldType // Ensures this is a password form. type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; const std::string web_frame_id = SysNSStringToUTF8(kTestFrameID); auto web_frame = web::FakeWebFrame::Create(web_frame_id, @@ -611,7 +613,8 @@ fieldType:kObfuscatedFieldType // Ensures this is a password form. type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; web::WebFrame* frame = nullptr; const std::string frame_id = ""; @@ -647,7 +650,8 @@ fieldType:kObfuscatedFieldType // Ensures this is a password form. type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; FormSuggestion* suggestion = [FormSuggestion suggestionWithValue:@"value" displayDescription:@"display-description" @@ -703,7 +707,8 @@ fieldType:kObfuscatedFieldType // Ensures this is a password form. type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; const std::string web_frame_id = SysNSStringToUTF8(kTestFrameID); auto web_frame = @@ -1339,7 +1344,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; [[form_helper_ expect] findPasswordFormsInFrame:frame completionHandler:[OCMArg any]]; @@ -1409,7 +1415,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; [[form_helper_ expect] findPasswordFormsInFrame:frame completionHandler:[OCMArg any]]; @@ -1436,7 +1443,8 @@ fieldType:kObfuscatedFieldType type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; [[form_helper_ expect] findPasswordFormsInFrame:frame completionHandler:[OCMArg any]]; @@ -1514,7 +1522,8 @@ fieldType:kObfuscatedFieldType type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; [controller_ retrieveSuggestionsForForm:form_query @@ -1650,7 +1659,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; id mock_completion_handler = [OCMArg checkWithBlock:^BOOL(void (^completionHandler)(BOOL)) { @@ -1695,7 +1705,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:kTestFrameID]; + frameID:kTestFrameID + onlyPassword:NO]; OCMExpect([suggestion_helper_ retrieveSuggestionsWithForm:form_query]) .andReturn(@[]);
diff --git a/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/DefaultPaymentFeatureConfig.java b/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/DefaultPaymentFeatureConfig.java index bb7f4cd..2d52fd97 100644 --- a/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/DefaultPaymentFeatureConfig.java +++ b/components/payments/content/android/junit/src/org/chromium/components/payments/test_support/DefaultPaymentFeatureConfig.java
@@ -4,32 +4,22 @@ package org.chromium.components.payments.test_support; -import com.google.common.collect.ImmutableMap; - -import org.chromium.base.FeatureList; -import org.chromium.base.FeatureList.TestValues; +import org.chromium.base.FeatureOverrides; import org.chromium.components.payments.PaymentFeatureList; -import java.util.Map; - /** Default flag configuration for payments features in unit tests. */ public abstract class DefaultPaymentFeatureConfig { - private static final Map<String, Boolean> DEFAULT_FEATURE_VALUES = - ImmutableMap.<String, Boolean>builder() - .put(PaymentFeatureList.WEB_PAYMENTS, true) - .put(PaymentFeatureList.WEB_PAYMENTS_SINGLE_APP_UI_SKIP, true) - .put(PaymentFeatureList.GPAY_APP_DYNAMIC_UPDATE, true) - .put(PaymentFeatureList.WEB_PAYMENTS_EXPERIMENTAL_FEATURES, true) - .put(PaymentFeatureList.OMIT_PARAMETERS_IN_READY_TO_PAY, false) - .buildOrThrow(); - /** * Sets the default flag configuration for payments feature flags for unit tests. Does not * override @EnableFeatures and @DisableFeatures annotations. */ public static void setDefaultFlagConfigurationForTesting() { - TestValues paymentsFeaturesOverrides = new TestValues(); - paymentsFeaturesOverrides.setFeatureFlagsOverride(DEFAULT_FEATURE_VALUES); - FeatureList.mergeTestValues(paymentsFeaturesOverrides, false); + FeatureOverrides.newBuilder() + .enable(PaymentFeatureList.WEB_PAYMENTS) + .enable(PaymentFeatureList.WEB_PAYMENTS_SINGLE_APP_UI_SKIP) + .enable(PaymentFeatureList.GPAY_APP_DYNAMIC_UPDATE) + .enable(PaymentFeatureList.WEB_PAYMENTS_EXPERIMENTAL_FEATURES) + .disable(PaymentFeatureList.OMIT_PARAMETERS_IN_READY_TO_PAY) + .applyWithoutOverwrite(); } }
diff --git a/components/permissions/features.cc b/components/permissions/features.cc index fca3edd..4d6e688e 100644 --- a/components/permissions/features.cc +++ b/components/permissions/features.cc
@@ -23,7 +23,7 @@ #if !BUILDFLAG(IS_ANDROID) BASE_FEATURE(kKeyboardAndPointerLockPrompt, "KeyboardAndPointerLockPrompt", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); #endif // !BUILDFLAG(IS_ANDROID) // Enables different positioning of the permission dialog, so that it's placed
diff --git a/components/policy/core/browser/policy_conversions_client.cc b/components/policy/core/browser/policy_conversions_client.cc index 002b23a..4be1fd9 100644 --- a/components/policy/core/browser/policy_conversions_client.cc +++ b/components/policy/core/browser/policy_conversions_client.cc
@@ -307,29 +307,28 @@ (policy.conflicts.size() <= 1 || !policy_has_unmerged_source)); } - std::u16string error = - GetPolicyError(policy_name, policy, errors, known_policy_schema); - - if (!error.empty()) { + if (std::u16string error = + GetPolicyMessage(policy_name, policy, PolicyMap::MessageType::kError, + errors, known_policy_schema); + !error.empty()) { value.Set("error", error); LOG_POLICY(ERROR, POLICY_PROCESSING) << policy_name << " has an error of type: " << error; } - if (!IsMachineInfoHidden(policy.scope, show_machine_values_)) { - std::u16string warning = policy.GetLocalizedMessages( - PolicyMap::MessageType::kWarning, - base::BindRepeating(&l10n_util::GetStringUTF16)); - if (!warning.empty()) { - value.Set("warning", warning); - } + if (std::u16string warning = GetPolicyMessage( + policy_name, policy, PolicyMap::MessageType::kWarning, errors, + known_policy_schema); + !warning.empty()) { + value.Set("warning", warning); } - std::u16string info = policy.GetLocalizedMessages( - PolicyMap::MessageType::kInfo, - base::BindRepeating(&l10n_util::GetStringUTF16)); - if (!info.empty()) + if (std::u16string info = + GetPolicyMessage(policy_name, policy, PolicyMap::MessageType::kInfo, + errors, known_policy_schema); + !info.empty()) { value.Set("info", info); + } if (policy.ignored()) value.Set("ignored", true); @@ -463,15 +462,17 @@ return USER_SCOPE; } -std::u16string PolicyConversionsClient::GetPolicyError( +std::u16string PolicyConversionsClient::GetPolicyMessage( const std::string& policy_name, const PolicyMap::Entry& policy, + PolicyMap::MessageType message_type, PolicyErrorMap* errors, std::optional<Schema> known_policy_schema) const { if (IsMachineInfoHidden(policy.scope, show_machine_values_)) { return u""; } - if (!known_policy_schema.has_value()) { + if (!known_policy_schema.has_value() && + message_type == PolicyMap::MessageType::kError) { // We don't know what this policy is. This is an important error to // show. return l10n_util::GetStringUTF16(IDS_POLICY_UNKNOWN); @@ -480,10 +481,10 @@ // The PolicyMap contains errors about retrieving the policy, while the // PolicyErrorMap contains validation errors. Concat the errors. auto policy_map_errors = policy.GetLocalizedMessages( - PolicyMap::MessageType::kError, - base::BindRepeating(&l10n_util::GetStringUTF16)); + message_type, base::BindRepeating(&l10n_util::GetStringUTF16)); auto error_map_errors = - errors ? errors->GetErrorMessages(policy_name) : std::u16string(); + errors ? errors->GetErrorMessages(policy_name, message_type) + : std::u16string(); if (policy_map_errors.empty()) { return error_map_errors; } @@ -493,7 +494,8 @@ } return base::JoinString( - {policy_map_errors, errors->GetErrorMessages(policy_name)}, u"\n"); + {policy_map_errors, errors->GetErrorMessages(policy_name, message_type)}, + u"\n"); } } // namespace policy
diff --git a/components/policy/core/browser/policy_conversions_client.h b/components/policy/core/browser/policy_conversions_client.h index 12a4566..be8b5584 100644 --- a/components/policy/core/browser/policy_conversions_client.h +++ b/components/policy/core/browser/policy_conversions_client.h
@@ -178,9 +178,10 @@ std::string GetPolicyScope(const std::string& policy_name, const PolicyScope& policy_scope) const; - std::u16string GetPolicyError( + std::u16string GetPolicyMessage( const std::string& policy_name, const PolicyMap::Entry& policy, + PolicyMap::MessageType message_type, PolicyErrorMap* errors, std::optional<Schema> known_policy_schema) const;
diff --git a/components/policy/core/browser/policy_error_map.cc b/components/policy/core/browser/policy_error_map.cc index cc1f447..204f1d7f 100644 --- a/components/policy/core/browser/policy_error_map.cc +++ b/components/policy/core/browser/policy_error_map.cc
@@ -159,11 +159,20 @@ } std::u16string PolicyErrorMap::GetErrorMessages(const std::string& policy) { + return GetErrorMessages(policy, PolicyMap::MessageType::kError); +} + +std::u16string PolicyErrorMap::GetErrorMessages( + const std::string& policy, + PolicyMap::MessageType message_type) { CheckReadyAndConvert(); std::pair<const_iterator, const_iterator> range = map_.equal_range(policy); std::vector<std::u16string_view> list; - for (auto it = range.first; it != range.second; ++it) - list.push_back(it->second.message); + for (auto it = range.first; it != range.second; ++it) { + if (it->second.level == message_type) { + list.push_back(it->second.message); + } + } return base::JoinString(list, u"\n"); }
diff --git a/components/policy/core/browser/policy_error_map.h b/components/policy/core/browser/policy_error_map.h index 5c0fa09..09b58cc 100644 --- a/components/policy/core/browser/policy_error_map.h +++ b/components/policy/core/browser/policy_error_map.h
@@ -42,8 +42,8 @@ // IsReady is true. IsReady will be true once the UI message loop has started. bool IsReady() const; - // Adds an entry with key |policy|, the error message corresponding to - // |message_id| in grit/generated_resources.h and its error_path |error_path| + // Adds an entry with key `policy`, the error message corresponding to + // `message_id` in grit/generated_resources.h and its error_path `error_path` // to the map. void AddError( const std::string& policy, @@ -51,10 +51,10 @@ PolicyErrorPath error_path = {}, PolicyMap::MessageType error_level = PolicyMap::MessageType::kError); - // Adds an entry with key |policy|, the error message corresponding to - // |message_id| in grit/generated_resources.h and its error_path |error_path| + // Adds an entry with key `policy`, the error message corresponding to + // `message_id` in grit/generated_resources.h and its error_path `error_path` // to the map and replaces the placeholder within the error message with - // |replacement_string|. + // `replacement_string`. void AddError( const std::string& policy, int message_id, @@ -78,21 +78,27 @@ PolicyErrorPath error_path = {}, PolicyMap::MessageType error_level = PolicyMap::MessageType::kError); - // Returns true if there is any error for |policy|. + // Returns true if there is any error for `policy`. bool HasError(const std::string& policy); // Returns true if there is any fatal error (PolicyMap::MessageType::kError) - // for |policy|. Returns false if |policy| only has non-fatal errors + // for `policy`. Returns false if `policy` only has non-fatal errors // (PolicyMap::MessageType::kInfo or PolicyMap::MessageType::kWarning) or no // errors at all. bool HasFatalError(const std::string& policy); - // Returns all the error messages stored for |policy|, separated by a white - // space. Returns an empty string if there are no errors for |policy|. + // Returns all the error messages stored for `policy`, separated by a white + // space. Returns an empty string if there are no errors for `policy`. std::u16string GetErrorMessages(const std::string& policy); - // Returns all the error metadata stored for |policy| in a vector. Returns an - // empty vector if there are no errors for |policy|. + // Returns all the messages stored for `policy` with matching `message_type`, + // separated by a white space. Returns an empty string if there are no such + // messages for `policy`. + std::u16string GetErrorMessages(const std::string& policy, + PolicyMap::MessageType message_type); + + // Returns all the error metadata stored for `policy` in a vector. Returns an + // empty vector if there are no errors for `policy`. std::vector<Data> GetErrors(const std::string& policy); bool empty() const; @@ -107,10 +113,10 @@ // Maps the error when ready, otherwise adds it to the pending errors list. void AddError(std::unique_ptr<PendingError> error); - // Converts a PendingError into a |map_| entry. + // Converts a PendingError into a `map_` entry. void Convert(PendingError* error); - // Converts all pending errors to |map_| entries. + // Converts all pending errors to `map_` entries. void CheckReadyAndConvert(); std::vector<std::unique_ptr<PendingError>> pending_;
diff --git a/components/policy/core/browser/policy_error_map_unittest.cc b/components/policy/core/browser/policy_error_map_unittest.cc index ceba227..1bcb331 100644 --- a/components/policy/core/browser/policy_error_map_unittest.cc +++ b/components/policy/core/browser/policy_error_map_unittest.cc
@@ -78,9 +78,24 @@ PolicyErrorMap errors; ASSERT_TRUE(errors.IsReady()); errors.AddError(kPolicyWithError, IDS_POLICY_BLOCKED); + errors.AddError(kPolicyWithError, IDS_POLICY_LABEL_IGNORED, /*error_path=*/{}, + PolicyMap::MessageType::kError); + errors.AddError(kPolicyWithError, IDS_POLICY_LABEL_DEPRECATED, + /*error_path=*/{}, PolicyMap::MessageType::kWarning); + errors.AddError(kPolicyWithError, IDS_POLICY_LABEL_SUPERSEDED_VALUE, + /*error_path=*/{}, PolicyMap::MessageType::kInfo); EXPECT_EQ(errors.GetErrorMessages(kPolicyWithError), - u"This policy is blocked, its value will be ignored."); + u"This policy is blocked, its value will be ignored.\nIgnored"); + EXPECT_EQ( + errors.GetErrorMessages(kPolicyWithError, PolicyMap::MessageType::kError), + u"This policy is blocked, its value will be ignored.\nIgnored"); + EXPECT_EQ(errors.GetErrorMessages(kPolicyWithError, + PolicyMap::MessageType::kWarning), + u"Deprecated"); + EXPECT_EQ( + errors.GetErrorMessages(kPolicyWithError, PolicyMap::MessageType::kInfo), + u"Value (superseded)"); } TEST(PolicyErrorMapTest, GetErrorMessagesWithReplacement) {
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentMandatory.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentMandatory.yaml index ab29654..52f4e25 100644 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentMandatory.yaml +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentMandatory.yaml
@@ -1,10 +1,10 @@ caption: Enable mandatory cloud management enrollment desc: |- - Setting the policy to Enabled mandates <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph> enrollment and blocks <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> launch process if failed. + Setting the policy to Enabled mandates <ph name="CHROME_ENTERPRISE_CORE_NAME">Chrome Enterprise Core</ph> browser enrollment and blocks <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> launch process if failed. - Setting the policy to Disabled or leaving it unset renders <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph> optional and doesn't block <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> launch process if failed. + Setting the policy to Disabled or leaving it unset renders <ph name="CHROME_ENTERPRISE_CORE_NAME">Chrome Enterprise Core</ph> browser enrollment optional and doesn't block <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> launch process if failed. - Machine scope cloud policy enrollment on desktop uses this policy. See https://support.google.com/chrome/a/answer/9301891?ref_topic=9301744 for details. + Machine scope cloud policy enrollment on desktop uses this policy. See https://support.google.com/chrome/a/answer/9301891 for details. example_value: true features: dynamic_refresh: false
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentToken.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentToken.yaml index 2dc15a0..9112d7c 100644 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentToken.yaml +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudManagementEnrollmentToken.yaml
@@ -1,8 +1,8 @@ caption: The enrollment token of cloud policy desc: |- - Setting the policy means <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> tries to register itself with <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph>. The value of this policy is an enrollment token you can retrieve from the <ph name="GOOGLE_ADMIN_CONSOLE_PRODUCT_NAME">Google Admin console</ph>. + Setting the policy means <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> tries to register itself with <ph name="CHROME_ENTERPRISE_CORE_NAME">Chrome Enterprise Core</ph> browser management. The value of this policy is an enrollment token you can retrieve from the <ph name="GOOGLE_ADMIN_CONSOLE_PRODUCT_NAME">Google Admin console</ph>. - See https://support.google.com/chrome/a/answer/9301891?ref_topic=9301744 for details. + See https://support.google.com/chrome/a/answer/9301891 for details. example_value: 37185d02-e055-11e7-80c1-9a214cf093ae features: dynamic_refresh: false
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudPolicyOverridesPlatformPolicy.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudPolicyOverridesPlatformPolicy.yaml index a7c7bc9f..e327e9c 100644 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudPolicyOverridesPlatformPolicy.yaml +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudPolicyOverridesPlatformPolicy.yaml
@@ -3,11 +3,12 @@ desc: |- Setting the policy to Enabled means cloud policy takes precedence if it conflicts with platform policy. - Setting the policy to Disabled or leaving it unset means platform policy takes precedence if it conflicts with cloud policy. + Setting the policy to Disabled or leaving it unset means platform policy takes precedence if it conflicts with cloud policy. - This mandatory policy affects machine scope cloud policies. + This mandatory policy affects machine scope cloud policies. - This policy is only available on <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph>; it has no effect on <ph name="GOOGLE_UPDATE_NAME">Google Update</ph>. + This policy is specific to <ph name="PRODUCT_NAME">$1<ex>Google Chrome</ex></ph> and does not affect <ph name="GOOGLE_UPDATE_NAME">Google Update</ph> because they are independent applications. + <ph name="GOOGLE_UPDATE_NAME">Google Update</ph> has a separate policy with the same name. example_value: false features: dynamic_refresh: true
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyMerge.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyMerge.yaml index 0f91bc05..a9f5a36 100644 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyMerge.yaml +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyMerge.yaml
@@ -1,13 +1,13 @@ caption: Enables merging of user cloud policies into machine-level policies default: false desc: |- - Setting the policy to Enabled allows policies associated with a <ph name="GOOGLE_WORKSPACE_PRODUCT_NAME">Google Workspace</ph> account to be merged into machine-level policies. + Setting the policy to Enabled allows policies associated with a managed account to be merged into machine-level policies. - Only policies originating from secure users can be merged. A secure user is affiliated with the organization that manages their browser using <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph>. All other user-level policies will always be ignored. + Setting the policy to Disabled or leaving it unset prevents user-level cloud policies from being merged with policies from any other sources. - Policies that need to be merged also need to be set in either <ph name="POLICY_POLICYLISTMULTIPLESOURCEMERGELIST">PolicyListMultipleSourceMergeList</ph> or <ph name="POLICY_POLICYDICTIONARYMULTIPLESOURCEMERGELIST">PolicyDictionaryMultipleSourceMergeList</ph>. This policy will be ignored if neither of the two aforementioned policies is configured. + Only policies originating from secure users can take precedence. A secure user is affiliated with the organization that manages their browser using <ph name="CHROME_ENTERPRISE_CORE_NAME">Chrome Enterprise Core</ph>. All other user-level policies will have default precedence. - Leaving the policy unset or setting it to Disabled prevents user-level cloud policies from being merged with policies from any other sources. + Policies that need to be merged also need to be set in either <ph name="POLICY_LIST_MULTIPLE_SOURCE_MERGE_LIST_POLICY_NAME">PolicyListMultipleSourceMergeList</ph> or <ph name="POLICY_DICTIONARY_MULTIPLE_SOURCE_MERGE_LIST_POLICY_NAME">PolicyDictionaryMultipleSourceMergeList</ph>. This policy will be ignored if neither of the two aforementioned policies is configured. example_value: true features: dynamic_refresh: true
diff --git a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyOverridesCloudMachinePolicy.yaml b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyOverridesCloudMachinePolicy.yaml index 3ed2981..7cce04f 100644 --- a/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyOverridesCloudMachinePolicy.yaml +++ b/components/policy/resources/templates/policy_definitions/Miscellaneous/CloudUserPolicyOverridesCloudMachinePolicy.yaml
@@ -2,13 +2,13 @@ Browser Cloud Management</ph> policies. default: false desc: |- - Setting the policy to Enabled allows policies associated with a <ph name="GOOGLE_WORKSPACE_PRODUCT_NAME">Google Workspace</ph> account to take precedence if they conflict with <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph> policies. + Setting the policy to Enabled allows policies associated with a managed account to take precedence if they conflict with <ph name="CHROME_ENTERPRISE_CORE_NAME">Chrome Enterprise Core</ph> browser policies. - Only policies originating from secure users can take precedence. A secure user is affiliated with the organization that manages their browser using <ph name="CHROME_BROWSER_CLOUD_MANAGEMENT_NAME">Chrome Browser Cloud Management</ph>. All other user-level policies will have default precedence. + Setting the policy to Disabled or leaving it unset causes user-level cloud policies to have default priority. - The policy can be combined with <ph name="POLICY_CLOUDPOLICYOVERRIDESPLATFORMPOLICY">CloudPolicyOverridesPlatformPolicy</ph>. If both policies are enabled, user cloud policies will also take precedence over conflicting platform policies. + Only policies originating from secure users can take precedence. A secure user is affiliated with the organization that manages their browser using <ph name="CHROME_ENTERPRISE_CORE_NAME">Chrome Enterprise Core</ph>. All other user-level policies will have default precedence. - Leaving the policy unset or setting it to disabled causes user-level cloud policies to have default priority. + The policy can be combined with <ph name="POLICY_CLOUD_POLICY_OVERRIDES_PLATFORM_POLICY_POLICY_NAME">CloudPolicyOverridesPlatformPolicy</ph>. If both policies are enabled, user cloud policies will also take precedence over conflicting platform policies. example_value: false features: dynamic_refresh: true
diff --git a/components/privacy_sandbox_strings.grd b/components/privacy_sandbox_strings.grd index 69e86e6..71b65e4 100644 --- a/components/privacy_sandbox_strings.grd +++ b/components/privacy_sandbox_strings.grd
@@ -553,7 +553,7 @@ Google requires companies to state publicly that they won't use this data to track you across sites. Some sites may use your activity to personalize your experience for more than just ads. They may also combine it with other information they already know about you. Companies are responsible for letting you know how they use your data. Learn more in our <ph name="BEGIN_LINK1"><a href="$1" aria-description="$2" on-click="$3" id="$4" target="_blank"></ph>Privacy Policy<ph name="LINK_END1"></a></ph>. </message> <message name="IDS_SETTINGS_SITE_SUGGESTED_ADS_PAGE_DISCLAIMER_LINK_ARIA_DESCRIPTION" desc="" translateable="false"> - Learn more in our + Opens Privacy Policy in a new tab </message> <!--Ad topics page - Ads API UX Enhancement--> <message name="IDS_SETTINGS_AD_TOPICS_PAGE_DISCLAIMER" desc="" translateable="false">
diff --git a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm index 84fb832..e02a94b 100644 --- a/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm +++ b/components/remote_cocoa/app_shim/native_widget_ns_window_bridge.mm
@@ -222,8 +222,18 @@ void* rank_as_void) { DCHECK_NE(lhs, rhs); - if ([lhs isKindOfClass:[ViewsCompositorSuperview class]]) + // Put `NSVisualEffectView` before `ViewsCompositorSuperview` otherwise when + // using `NSVisualEffectView` for `vibrancy` it will hide content displayed by + // the compositor. + if ([lhs isKindOfClass:[NSVisualEffectView class]]) { return NSOrderedAscending; + } + if ([lhs isKindOfClass:[ViewsCompositorSuperview class]]) { + if ([rhs isKindOfClass:[NSVisualEffectView class]]) { + return NSOrderedDescending; + } + return NSOrderedAscending; + } const RankMap* rank = static_cast<const RankMap*>(rank_as_void); auto left_rank = rank->find(lhs);
diff --git a/components/search_engines/android/BUILD.gn b/components/search_engines/android/BUILD.gn index c4b6dfba..777e053 100644 --- a/components/search_engines/android/BUILD.gn +++ b/components/search_engines/android/BUILD.gn
@@ -85,7 +85,6 @@ "java/src/org/chromium/components/search_engines/FakeTemplateUrl.java", "java/src/org/chromium/components/search_engines/TemplateUrlTestHelpers.java", "java/src/org/chromium/components/search_engines/test/util/SearchEngineChoiceServiceTestUtil.java", - "java/src/org/chromium/components/search_engines/test/util/SearchEnginesFeaturesTestUtil.java", ] deps = [ ":delegate_java",
diff --git a/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEngineChoiceServiceUnitTest.java b/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEngineChoiceServiceUnitTest.java index 36a4398..8f8d115 100644 --- a/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEngineChoiceServiceUnitTest.java +++ b/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEngineChoiceServiceUnitTest.java
@@ -39,19 +39,17 @@ import org.robolectric.shadows.ShadowLooper; import org.chromium.base.FeatureList; +import org.chromium.base.FeatureOverrides; import org.chromium.base.Promise; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; import org.chromium.base.test.util.Features.EnableFeatures; import org.chromium.components.search_engines.SearchEngineChoiceService.RefreshReason; import org.chromium.components.search_engines.SearchEngineCountryDelegate.DeviceChoiceEventType; -import org.chromium.components.search_engines.test.util.SearchEnginesFeaturesTestUtil; import java.time.Instant; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; -import java.util.Map; @SmallTest @RunWith(ParameterizedRobolectricTestRunner.class) @@ -383,18 +381,22 @@ boolean isClayBlockingEnabled, boolean isDarkLaunchEnabled, @Nullable Integer defaultBrowserPromoSuppressedMillis) { + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder(); if (isClayBlockingEnabled) { - Map<String, String> params = new HashMap<>(); - params.put("is_dark_launch", isDarkLaunchEnabled ? "true" : ""); - params.put("dialog_timeout_millis", "0"); + overrides = + overrides + .enable(SearchEnginesFeatures.CLAY_BLOCKING) + .param("is_dark_launch", isDarkLaunchEnabled ? "true" : "") + .param("dialog_timeout_millis", 0); if (defaultBrowserPromoSuppressedMillis != null) { - params.put( - "default_browser_promo_suppressed_millis", - defaultBrowserPromoSuppressedMillis.toString()); + overrides = + overrides.param( + "default_browser_promo_suppressed_millis", + defaultBrowserPromoSuppressedMillis); } - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams(params); } else { - SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams(null); + overrides = overrides.disable(SearchEnginesFeatures.CLAY_BLOCKING); } + overrides.apply(); } }
diff --git a/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEnginesFeatureUtilsUnitTest.java b/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEnginesFeatureUtilsUnitTest.java index 30f5eae..12d564d 100644 --- a/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEnginesFeatureUtilsUnitTest.java +++ b/components/search_engines/android/java/src/org/chromium/components/search_engines/SearchEnginesFeatureUtilsUnitTest.java
@@ -9,64 +9,65 @@ import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; -import static org.chromium.components.search_engines.test.util.SearchEnginesFeaturesTestUtil.configureClayBlockingFeatureParams; +import static org.chromium.components.search_engines.SearchEnginesFeatures.CLAY_BLOCKING; import androidx.test.filters.SmallTest; import org.junit.Test; import org.junit.runner.RunWith; +import org.chromium.base.FeatureOverrides; import org.chromium.base.test.BaseRobolectricTestRunner; -import java.util.Map; - @SmallTest @RunWith(BaseRobolectricTestRunner.class) public class SearchEnginesFeatureUtilsUnitTest { @Test public void clayBlockingFeatureParamAsBoolean() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertFalse( SearchEnginesFeatureUtils.clayBlockingFeatureParamAsBoolean("bool_param", false)); - configureClayBlockingFeatureParams(Map.of("bool_param", "true")); + overrides.param("bool_param", true).apply(); assertTrue( SearchEnginesFeatureUtils.clayBlockingFeatureParamAsBoolean("bool_param", false)); - configureClayBlockingFeatureParams(Map.of("bool_param", "false")); + FeatureOverrides.overrideParam(CLAY_BLOCKING, "bool_param", false); assertFalse( SearchEnginesFeatureUtils.clayBlockingFeatureParamAsBoolean("bool_param", false)); - configureClayBlockingFeatureParams(Map.of("bool_param", "")); + FeatureOverrides.overrideParam(CLAY_BLOCKING, "bool_param", ""); assertFalse( SearchEnginesFeatureUtils.clayBlockingFeatureParamAsBoolean("bool_param", false)); - configureClayBlockingFeatureParams(Map.of("bool_param", "bad input")); + FeatureOverrides.overrideParam(CLAY_BLOCKING, "bool_param", "bad input"); assertFalse( SearchEnginesFeatureUtils.clayBlockingFeatureParamAsBoolean("bool_param", false)); } @Test public void clayBlockingFeatureParamAsInt() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertEquals(SearchEnginesFeatureUtils.clayBlockingFeatureParamAsInt("int_param", 42), 42); - configureClayBlockingFeatureParams(Map.of("int_param", "0")); + overrides.param("int_param", 0).apply(); assertEquals(SearchEnginesFeatureUtils.clayBlockingFeatureParamAsInt("int_param", 42), 0); - configureClayBlockingFeatureParams(Map.of("int_param", "24")); + overrides.param("int_param", 24).apply(); assertEquals(SearchEnginesFeatureUtils.clayBlockingFeatureParamAsInt("int_param", 42), 24); - configureClayBlockingFeatureParams(Map.of("int_param", "")); + overrides.param("int_param", "").apply(); assertThrows( NumberFormatException.class, () -> SearchEnginesFeatureUtils.clayBlockingFeatureParamAsInt("int_param", 42)); - configureClayBlockingFeatureParams(Map.of("int_param", "-24")); + overrides.param("int_param", -24).apply(); assertEquals(SearchEnginesFeatureUtils.clayBlockingFeatureParamAsInt("int_param", 42), -24); - configureClayBlockingFeatureParams(Map.of("int_param", "bad input")); + overrides.param("int_param", "bad input").apply(); assertThrows( NumberFormatException.class, () -> SearchEnginesFeatureUtils.clayBlockingFeatureParamAsInt("int_param", 42)); @@ -74,59 +75,65 @@ @Test public void clayBlockingUseFakeBackend() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertFalse(SearchEnginesFeatureUtils.clayBlockingUseFakeBackend()); - configureClayBlockingFeatureParams(Map.of("use_fake_backend", "true")); + overrides.param("use_fake_backend", true).apply(); assertTrue(SearchEnginesFeatureUtils.clayBlockingUseFakeBackend()); } @Test public void clayBlockingIsDarkLaunch() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertFalse(SearchEnginesFeatureUtils.clayBlockingIsDarkLaunch()); - configureClayBlockingFeatureParams(Map.of("is_dark_launch", "true")); + overrides.param("is_dark_launch", true).apply(); assertTrue(SearchEnginesFeatureUtils.clayBlockingIsDarkLaunch()); } @Test public void clayBlockingEnableVerboseLogging() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertFalse(SearchEnginesFeatureUtils.clayBlockingEnableVerboseLogging()); - configureClayBlockingFeatureParams(Map.of("enable_verbose_logging", "true")); + overrides.param("enable_verbose_logging", true).apply(); assertTrue(SearchEnginesFeatureUtils.clayBlockingEnableVerboseLogging()); } @Test public void clayBlockingDialogTimeoutMillis() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertEquals(SearchEnginesFeatureUtils.clayBlockingDialogTimeoutMillis(), 60_000); - configureClayBlockingFeatureParams(Map.of("dialog_timeout_millis", "24")); + overrides.param("dialog_timeout_millis", 24).apply(); assertEquals(SearchEnginesFeatureUtils.clayBlockingDialogTimeoutMillis(), 24); } @Test public void clayBlockingDialogSilentlyPendingDurationMillis() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertEquals( SearchEnginesFeatureUtils.clayBlockingDialogSilentlyPendingDurationMillis(), 0); - configureClayBlockingFeatureParams(Map.of("silent_pending_duration_millis", "24")); + overrides.param("silent_pending_duration_millis", 24).apply(); assertEquals( SearchEnginesFeatureUtils.clayBlockingDialogSilentlyPendingDurationMillis(), 24); } @Test public void clayBlockingDialogDefaultBrowserPromoSuppressedMillis() { - configureClayBlockingFeatureParams(Map.of()); + FeatureOverrides.Builder overrides = FeatureOverrides.newBuilder().enable(CLAY_BLOCKING); + overrides.apply(); assertEquals( 24 * 60 * 60 * 1000, SearchEnginesFeatureUtils.clayBlockingDialogDefaultBrowserPromoSuppressedMillis()); - configureClayBlockingFeatureParams(Map.of("default_browser_promo_suppressed_millis", "24")); + overrides.param("default_browser_promo_suppressed_millis", 24).apply(); assertEquals( 24, SearchEnginesFeatureUtils.clayBlockingDialogDefaultBrowserPromoSuppressedMillis());
diff --git a/components/search_engines/android/java/src/org/chromium/components/search_engines/test/util/SearchEnginesFeaturesTestUtil.java b/components/search_engines/android/java/src/org/chromium/components/search_engines/test/util/SearchEnginesFeaturesTestUtil.java deleted file mode 100644 index fa3a7bc3..0000000 --- a/components/search_engines/android/java/src/org/chromium/components/search_engines/test/util/SearchEnginesFeaturesTestUtil.java +++ /dev/null
@@ -1,54 +0,0 @@ -// Copyright 2024 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -package org.chromium.components.search_engines.test.util; - -import androidx.annotation.Nullable; - -import org.chromium.base.FeatureList; -import org.chromium.components.search_engines.SearchEnginesFeatures; - -import java.util.Map; - -public final class SearchEnginesFeaturesTestUtil { - - /** - * Helper to call {@link #configureFeatureParams} for {@link - * SearchEnginesFeatures#CLAY_BLOCKING}. - */ - public static void configureClayBlockingFeatureParams( - @Nullable Map<String, String> paramsAndValues) { - configureFeatureParams(SearchEnginesFeatures.CLAY_BLOCKING, paramsAndValues); - } - - /** - * Helper to override feature flag states. - * - * @param featureName the name of the feature to configure. - * @param paramsAndValues the state in which the feature will be set. If {@code null}, the - * feature will be disabled. Otherwise, the feature will be enabled and the entries of this - * map will be used to configure the feature params. - */ - public static void configureFeatureParams( - String featureName, @Nullable Map<String, String> paramsAndValues) { - var testFeatures = new FeatureList.TestValues(); - - if (paramsAndValues == null) { - // Disable the feature. - testFeatures.addFeatureFlagOverride(featureName, false); - } else { - // Enable the feature and set the params. - testFeatures.addFeatureFlagOverride(featureName, true); - for (var entry : paramsAndValues.entrySet()) { - testFeatures.addFieldTrialParamOverride( - featureName, entry.getKey(), entry.getValue()); - } - } - - FeatureList.mergeTestValues(testFeatures, /* replace= */ true); - } - - // Block instantiation - private SearchEnginesFeaturesTestUtil() {} -}
diff --git a/components/search_engines/enterprise/enterprise_search_manager.cc b/components/search_engines/enterprise/enterprise_search_manager.cc index 7bc7db3..f9e18aa 100644 --- a/components/search_engines/enterprise/enterprise_search_manager.cc +++ b/components/search_engines/enterprise/enterprise_search_manager.cc
@@ -122,13 +122,12 @@ // Use pref loading result (either empty or non-empty) if there are no mock // search engines available. if (!omnibox_feature_configs::SearchAggregatorProvider::Get() - .valid_search_engine()) { + .AreMockEnginesValid()) { return pref_loading_result; } - // In case the policy is not available or the policy value is empty, auto mock_engines = omnibox_feature_configs::SearchAggregatorProvider::Get() - .GetSearchEngines(); + .CreateMockSearchEngines(); CHECK(!mock_engines.empty()); for (const base::Value& mock_engine : mock_engines) { search_engines->emplace_back(DictToTemplateURLData(mock_engine));
diff --git a/components/search_engines/enterprise/enterprise_search_manager_unittest.cc b/components/search_engines/enterprise/enterprise_search_manager_unittest.cc index b8bb9172..b68eb7c 100644 --- a/components/search_engines/enterprise/enterprise_search_manager_unittest.cc +++ b/components/search_engines/enterprise/enterprise_search_manager_unittest.cc
@@ -289,13 +289,21 @@ base::TimeDelta callback_delay, int num_suggestions, const std::string& response_type) { - scoped_config_.Get().Init(enabled, name, shortcut, search_url, suggest_url, - icon_url, trigger_omnibox_blending, - callback_delay, num_suggestions, response_type); + scoped_config_.Get().enabled = enabled; + scoped_config_.Get().name = name; + scoped_config_.Get().shortcut = shortcut; + scoped_config_.Get().search_url = search_url; + scoped_config_.Get().suggest_url = suggest_url; + scoped_config_.Get().icon_url = icon_url; + scoped_config_.Get().trigger_omnibox_blending = trigger_omnibox_blending; + scoped_config_.Get().callback_delay = callback_delay; + scoped_config_.Get().num_suggestions = num_suggestions; + scoped_config_.Get().response_type = response_type; } void InitScopedConfig(bool enabled, bool trigger_omnibox_blending) { - scoped_config_.Get().Init(enabled, trigger_omnibox_blending); + scoped_config_.Get().enabled = enabled; + scoped_config_.Get().trigger_omnibox_blending = trigger_omnibox_blending; } omnibox_feature_configs::ScopedConfigForTesting< @@ -337,9 +345,9 @@ /*enabled=*/false, /*trigger_omnibox_blending=*/true); - ASSERT_FALSE(scoped_config_.Get().enabled()); - ASSERT_FALSE(scoped_config_.Get().valid_search_engine()); - ASSERT_FALSE(scoped_config_.Get().trigger_omnibox_blending()); + EXPECT_FALSE(scoped_config_.Get().enabled); + EXPECT_FALSE(scoped_config_.Get().AreMockEnginesValid()); + EXPECT_TRUE(scoped_config_.Get().trigger_omnibox_blending); } else { // Use empty shortcut for invalid mock engine. InitScopedConfig( @@ -357,11 +365,11 @@ /*num_suggestions=*/4, /*response_type=*/"success"); - ASSERT_TRUE(scoped_config_.Get().enabled()); - ASSERT_EQ( - scoped_config_.Get().valid_search_engine(), + EXPECT_TRUE(scoped_config_.Get().enabled); + EXPECT_EQ( + scoped_config_.Get().AreMockEnginesValid(), test_case.mock_setting_status == MockSettingStatus::kEnabledValid); - ASSERT_TRUE(scoped_config_.Get().trigger_omnibox_blending()); + EXPECT_TRUE(scoped_config_.Get().trigger_omnibox_blending); } base::MockRepeatingCallback<void(
diff --git a/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc b/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc index ca35d2ba..cc4d887 100644 --- a/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc +++ b/components/services/storage/indexed_db/locks/partitioned_lock_manager.cc
@@ -294,8 +294,9 @@ } } -std::set<PartitionedLockHolder*> PartitionedLockManager::GetBlockedRequests( - const base::flat_set<PartitionedLockId>& held_locks) const { +bool PartitionedLockManager::IsBlockingAnyRequest( + const base::flat_set<PartitionedLockId>& held_locks, + base::RepeatingCallback<bool(PartitionedLockHolder*)> filter) const { std::set<PartitionedLockHolder*> blocked_requests; // Rebuild the set of lock requests so we can apply @@ -308,11 +309,12 @@ } for (const AcquisitionRequest& request : request_queue_) { - if (RequestsAreOverlapping(request.lock_requests, reconstructed_requests)) { - blocked_requests.insert(request.locks_holder.get()); + if (request.locks_holder.get() && filter.Run(request.locks_holder.get()) && + RequestsAreOverlapping(request.lock_requests, reconstructed_requests)) { + return true; } } - return blocked_requests; + return false; } bool operator<(const PartitionedLockManager::PartitionedLockRequest& x,
diff --git a/components/services/storage/indexed_db/locks/partitioned_lock_manager.h b/components/services/storage/indexed_db/locks/partitioned_lock_manager.h index 5823f978..523d631 100644 --- a/components/services/storage/indexed_db/locks/partitioned_lock_manager.h +++ b/components/services/storage/indexed_db/locks/partitioned_lock_manager.h
@@ -99,9 +99,13 @@ std::vector<PartitionedLockId> GetUnacquirableLocks( std::vector<PartitionedLockRequest>& lock_requests); - // Returns the lock requests that are blocked on the provided lock holder. - std::set<PartitionedLockHolder*> GetBlockedRequests( - const base::flat_set<PartitionedLockId>& held_locks) const; + // Returns true if `held_locks` are blocking any queued request. Only requests + // for which `filter` returns true are considered. It's possible for + // `blocked_requests` to be very large, so this is intended to be as efficient + // as possible. + bool IsBlockingAnyRequest( + const base::flat_set<PartitionedLockId>& held_locks, + base::RepeatingCallback<bool(PartitionedLockHolder*)> filter) const; // Outputs the lock state (held & requested locks) into a debug value, // suitable for printing an 'internals' or to print during debugging. The
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scope.cc b/components/services/storage/indexed_db/scopes/leveldb_scope.cc index 191fd1d..fdda2ed 100644 --- a/components/services/storage/indexed_db/scopes/leveldb_scope.cc +++ b/components/services/storage/indexed_db/scopes/leveldb_scope.cc
@@ -186,7 +186,6 @@ DCHECK(!committed_); DCHECK(!locks_.empty()); switch (mode) { - case LevelDBScopeDeletionMode::kDeferred: case LevelDBScopeDeletionMode::kDeferredWithCompaction: deferred_delete_ranges_.emplace_back(begin.ToString(), end.ToString()); break; @@ -196,10 +195,6 @@ #endif bool end_exclusive = true; switch (mode) { - case LevelDBScopeDeletionMode::kDeferred: - SetModeToUndoLog(); - AddCleanupDeleteRangeTask(begin.ToString(), end.ToString()); - return leveldb::Status::OK(); case LevelDBScopeDeletionMode::kDeferredWithCompaction: SetModeToUndoLog(); AddCleanupDeleteAndCompactRangeTask(begin.ToString(), end.ToString()); @@ -355,20 +350,9 @@ undo_task_buffer_.Clear(); } -void LevelDBScope::AddCleanupDeleteRangeTask(std::string begin, - std::string end) { - DCHECK(cleanup_task_buffer_.operation_case() == - LevelDBScopesCleanupTask::OPERATION_NOT_SET); - auto* const range = cleanup_task_buffer_.mutable_delete_range(); - range->set_begin(std::move(begin)); - range->set_end(std::move(end)); - AddBufferedCleanupTask(); -} - void LevelDBScope::AddCleanupDeleteAndCompactRangeTask(std::string begin, std::string end) { - DCHECK(cleanup_task_buffer_.operation_case() == - LevelDBScopesCleanupTask::OPERATION_NOT_SET); + DCHECK(!cleanup_task_buffer_.has_delete_range_and_compact()); auto* const range = cleanup_task_buffer_.mutable_delete_range_and_compact(); range->set_begin(std::move(begin)); range->set_end(std::move(end));
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scope.h b/components/services/storage/indexed_db/scopes/leveldb_scope.h index 126380e..781b0a3 100644 --- a/components/services/storage/indexed_db/scopes/leveldb_scope.h +++ b/components/services/storage/indexed_db/scopes/leveldb_scope.h
@@ -140,7 +140,6 @@ // decrements the |undo_sequence_number_|. void AddBufferedUndoTask(); - void AddCleanupDeleteRangeTask(std::string begin, std::string end); void AddCleanupDeleteAndCompactRangeTask(std::string begin, std::string end); // Writes the current |cleanup_task_buffer_| to the |write_batch_|, and // decrements the |cleanup_sequence_number_|.
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scope_deletion_mode.h b/components/services/storage/indexed_db/scopes/leveldb_scope_deletion_mode.h index 950324cc..28678fa6 100644 --- a/components/services/storage/indexed_db/scopes/leveldb_scope_deletion_mode.h +++ b/components/services/storage/indexed_db/scopes/leveldb_scope_deletion_mode.h
@@ -15,10 +15,8 @@ // The range will be deleted eventually. All future access to this range is // undefined - the data may or may not still exist, even after Chrome // restarts. So only do this for ranges that are known to never be used again. - // This mode treats the 'end' of the range as exclusive. - kDeferred, - // Same as |kDeferred|, except the range will also be compacted afterwards - // to further ensure the data is deleted. + // The range will also be compacted afterwards to further ensure the data is + // deleted. // This mode treats the 'end' of the range as exclusive. kDeferredWithCompaction };
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scope_unittest.cc b/components/services/storage/indexed_db/scopes/leveldb_scope_unittest.cc index ed43144..c6fc8e4 100644 --- a/components/services/storage/indexed_db/scopes/leveldb_scope_unittest.cc +++ b/components/services/storage/indexed_db/scopes/leveldb_scope_unittest.cc
@@ -327,51 +327,6 @@ locks.clear(); } -TEST_F(LevelDBScopeTest, DeleteRangeDeferred) { - SetUpRealDatabase(); - PartitionedLockManager lock_manager; - std::optional<leveldb::Status> failure_status; - LevelDBScopes scopes( - metadata_prefix_, kWriteBatchSizeForTesting, leveldb_, &lock_manager, - base::BindLambdaForTesting( - [&failure_status](leveldb::Status s) { failure_status = s; })); - - leveldb::Status s = scopes.Initialize(); - EXPECT_TRUE(s.ok()); - scopes.StartRecoveryAndCleanupTasks(); - - std::string value; - auto scope = scopes.CreateScope( - AcquireLocksSync(&lock_manager, {CreateSimpleExclusiveLock()})); - for (int i = 0; i < 20; ++i) { - std::string key = CreateKey(i); - value = i % 2 == 0 ? CreateLargeValue(i) : "smallvalue"; - s = scope->Put(key, value); - EXPECT_TRUE(s.ok()); - } - CommitAndWaitForCleanup(scopes, std::move(scope)); - EXPECT_FALSE(failure_status.has_value()); - - scope = scopes.CreateScope( - AcquireLocksSync(&lock_manager, {CreateSimpleExclusiveLock()})); - s = scope->DeleteRange(CreateKey(0), CreateKey(20), - LevelDBScopeDeletionMode::kDeferred); - EXPECT_TRUE(s.ok()); - CommitAndWaitForCleanup(scopes, std::move(scope)); - EXPECT_FALSE(failure_status.has_value()); - - // Be a good citizen and acquire read locks. - auto locks = AcquireLocksSync(&lock_manager, {CreateSimpleSharedLock()}); - leveldb::ReadOptions options; - options.verify_checksums = true; - for (int i = 0; i < 20; ++i) { - std::string key = CreateKey(i); - s = leveldb_->db()->Get(options, key, &value); - EXPECT_TRUE(s.IsNotFound()) << i; - } - EXPECT_FALSE(failure_status.has_value()); -} - TEST_F(LevelDBScopeTest, DeleteRangeCompact) { SetUpRealDatabase(); PartitionedLockManager lock_manager; @@ -416,64 +371,6 @@ EXPECT_FALSE(failure_status.has_value()); } -TEST_F(LevelDBScopeTest, RevertWithDeferredDelete) { - SetUpRealDatabase(); - PartitionedLockManager lock_manager; - std::optional<leveldb::Status> failure_status; - LevelDBScopes scopes( - metadata_prefix_, kWriteBatchSizeForTesting, leveldb_, &lock_manager, - base::BindLambdaForTesting( - [&failure_status](leveldb::Status s) { failure_status = s; })); - leveldb::Status s = scopes.Initialize(); - EXPECT_TRUE(s.ok()); - scopes.StartRecoveryAndCleanupTasks(); - - // This test makes sure that the cleanup scheduled after the revert doesn't - // execute it's cleanup tasks. - - // Populate the database. - std::string value; - auto scope = scopes.CreateScope( - AcquireLocksSync(&lock_manager, {CreateSimpleExclusiveLock()})); - for (int i = 0; i < 20; ++i) { - std::string key = CreateKey(i); - value = i % 2 == 0 ? CreateLargeValue(i) : "smallvalue"; - s = scope->Put(key, value); - EXPECT_TRUE(s.ok()); - } - CommitAndWaitForCleanup(scopes, std::move(scope)); - EXPECT_FALSE(failure_status.has_value()); - - // Do a deferred delete & a write large enough to make this a log-based scope, - // and then revert it. - scope = scopes.CreateScope( - AcquireLocksSync(&lock_manager, {CreateSimpleExclusiveLock()})); - value = CreateLargeValue(20); - s = scope->Put(CreateKey(20), value); - s = scope->DeleteRange(CreateKey(0), CreateKey(20), - LevelDBScopeDeletionMode::kDeferred); - EXPECT_TRUE(s.ok()); - scope.reset(); - - // Wait until cleanup task runs. - task_env_.RunUntilIdle(); - EXPECT_FALSE(failure_status.has_value()); - - // If the cleanup correctly ignored the tasks, then the values should still - // exist. - auto locks = AcquireLocksSync(&lock_manager, {CreateSimpleSharedLock()}); - leveldb::ReadOptions options; - options.verify_checksums = true; - for (int i = 0; i < 20; ++i) { - std::string key = CreateKey(i); - s = leveldb_->db()->Get(options, key, &value); - EXPECT_TRUE(s.ok()) << i; - } - s = leveldb_->db()->Get(options, CreateKey(20), &value); - EXPECT_TRUE(s.IsNotFound()); - EXPECT_FALSE(failure_status.has_value()); -} - TEST_F(LevelDBScopeTest, BrokenDBForInitialize) { leveldb::Status error = leveldb::Status::IOError("test"); leveldb_ = FakeLevelDBFactory::GetBrokenLevelDB(error, base::FilePath());
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks.cc b/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks.cc index 269a28f..c1748f3a 100644 --- a/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks.cc +++ b/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks.cc
@@ -181,34 +181,23 @@ for (; iterator->Valid() && iterator->key().starts_with(cleanup_tasks_prefix); iterator->Next()) { leveldb::Slice value = iterator->value(); - if (!cleanup_task.ParseFromArray(value.data(), value.size())) + if (!cleanup_task.ParseFromArray(value.data(), value.size())) { return leveldb::Status::Corruption("Invalid cleanup operation value."); - - switch (cleanup_task.operation_case()) { - case LevelDBScopesCleanupTask::kDeleteRange: { - auto range = cleanup_task.delete_range(); - s = DeleteRange(range.begin(), range.end(), read_options, - write_options); - if (!s.ok() || level_db_->destruction_requested()) [[unlikely]] { - return s; - } - break; - } - case LevelDBScopesCleanupTask::kDeleteRangeAndCompact: { - auto range = cleanup_task.delete_range_and_compact(); - leveldb::Slice begin(range.begin()); - leveldb::Slice end(range.end()); - s = DeleteRange(begin, end, read_options, write_options); - if (!s.ok() || level_db_->destruction_requested()) [[unlikely]] { - return s; - } - level_db_->db()->CompactRange(&begin, &end); - break; - } - // The protobuf code generator is to blame for this style mismatch. - case LevelDBScopesCleanupTask::OPERATION_NOT_SET: - return leveldb::Status::Corruption("Invalid cleanup operation type."); } + + if (!cleanup_task.has_delete_range_and_compact()) { + return leveldb::Status::Corruption("Invalid cleanup operation type."); + } + + const auto& range = cleanup_task.delete_range_and_compact(); + leveldb::Slice begin(range.begin()); + leveldb::Slice end(range.end()); + s = DeleteRange(begin, end, read_options, write_options); + if (!s.ok() || level_db_->destruction_requested()) [[unlikely]] { + return s; + } + level_db_->db()->CompactRange(&begin, &end); + write_batch_.Delete(iterator->key()); s = MaybeSubmitWriteBatch(write_options);
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks_unittest.cc b/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks_unittest.cc index 70dfca4..649024e 100644 --- a/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks_unittest.cc +++ b/components/services/storage/indexed_db/scopes/leveldb_scopes_tasks_unittest.cc
@@ -35,9 +35,10 @@ bool ignore_cleanup_tasks) { WriteScopesMetadata(scope_number, ignore_cleanup_tasks); - cleanup_task_buffer_.mutable_delete_range()->set_begin( + cleanup_task_buffer_.mutable_delete_range_and_compact()->set_begin( delete_range_start_key_); - cleanup_task_buffer_.mutable_delete_range()->set_end(delete_range_end_key_); + cleanup_task_buffer_.mutable_delete_range_and_compact()->set_end( + delete_range_end_key_); WriteCleanupTask(scope_number, /*sequence_number=*/0); int64_t undo_sequence_number = leveldb_scopes::kFirstSequenceNumberToWrite;
diff --git a/components/services/storage/indexed_db/scopes/leveldb_scopes_unittest.cc b/components/services/storage/indexed_db/scopes/leveldb_scopes_unittest.cc index ad227ff4..eb39469 100644 --- a/components/services/storage/indexed_db/scopes/leveldb_scopes_unittest.cc +++ b/components/services/storage/indexed_db/scopes/leveldb_scopes_unittest.cc
@@ -72,9 +72,10 @@ WriteScopesMetadata(kScopeToResumeRevert, false); // Cleanup task that will be ignored. - cleanup_task_buffer_.mutable_delete_range()->set_begin( + cleanup_task_buffer_.mutable_delete_range_and_compact()->set_begin( kCleanupDeleteRangeBegin); - cleanup_task_buffer_.mutable_delete_range()->set_end(kCleanupDeleteRangeEnd); + cleanup_task_buffer_.mutable_delete_range_and_compact()->set_end( + kCleanupDeleteRangeEnd); WriteCleanupTask(kScopeToResumeRevert, /*sequence_number=*/0); // Undo task that will be executed.
diff --git a/components/services/storage/indexed_db/scopes/scopes_metadata.proto b/components/services/storage/indexed_db/scopes/scopes_metadata.proto index 9923e6b..72a9eb1 100644 --- a/components/services/storage/indexed_db/scopes/scopes_metadata.proto +++ b/components/services/storage/indexed_db/scopes/scopes_metadata.proto
@@ -50,8 +50,5 @@ bytes begin = 1; bytes end = 2; } - oneof operation { - DeleteRange delete_range = 1; - DeleteRange delete_range_and_compact = 2; - } + optional DeleteRange delete_range_and_compact = 2; }
diff --git a/components/supervised_user/core/common/supervised_user_constants.h b/components/supervised_user/core/common/supervised_user_constants.h index 1e70982..44b3d8c 100644 --- a/components/supervised_user/core/common/supervised_user_constants.h +++ b/components/supervised_user/core/common/supervised_user_constants.h
@@ -13,9 +13,7 @@ // The result of local web approval flow. // Used for metrics. Those values are logged to UMA. Entries should not be // renumbered and numeric values should never be reused. -// Matches the enum "FamilyLinkUserLocalWebApprovalResult" in -// src/tools/metrics/histograms/enums.xml. -// LINT.IfChange +// LINT.IfChange(LocalApprovalResult) enum class LocalApprovalResult { kApproved = 0, kDeclined = 1, @@ -23,9 +21,20 @@ kError = 3, kMaxValue = kError }; -// LINT.ThenChange( -// //tools/metrics/histograms/enums.xml -// ) +// LINT.ThenChange(//tools/metrics/histograms/metadata/families/enums.xml:FamilyLinkUserLocalWebApprovalResult) + +// Used for metrics. These values are logged to UMA. Entries should not be +// renumbered and numeric values should never be reused. +// LINT.IfChange(ParentAccessWidgetError) +enum class ParentAccessWidgetError { + kOAuthError = 0, + kDelegateNotAvailable = 1, + kDecodingError = 2, + kParsingError = 3, + kUnknownCallback = 4, + kMaxValue = kUnknownCallback +}; +// LINT.ThenChange(//tools/metrics/histograms/metadata/families/enums.xml:FamilyLinkUserParentAccessWidgetError) // This enum describes the filter types of Chrome, which is // set by Family Link App or at families.google.com/families. These values
diff --git a/components/user_education/views/help_bubble_view.cc b/components/user_education/views/help_bubble_view.cc index a53a61e..2195ae9 100644 --- a/components/user_education/views/help_bubble_view.cc +++ b/components/user_education/views/help_bubble_view.cc
@@ -545,7 +545,7 @@ // Add the default button if there is one based on platform style. if (default_button) { - if (views::PlatformStyle::kIsOkButtonLeading) { + if constexpr (views::PlatformStyle::kIsOkButtonLeading) { default_button_ = button_container->AddChildViewAt(std::move(default_button), 0); } else {
diff --git a/components/user_manager/fake_user_manager.cc b/components/user_manager/fake_user_manager.cc index 897e906..16b1eb1 100644 --- a/components/user_manager/fake_user_manager.cc +++ b/components/user_manager/fake_user_manager.cc
@@ -156,31 +156,6 @@ NotifyOnLogin(); } -User* FakeUserManager::GetActiveUserInternal() const { - if (active_user_ != nullptr) - return active_user_; - - if (!users_.empty()) { - if (active_account_id_.is_valid()) { - for (UserList::const_iterator it = users_.begin(); it != users_.end(); - ++it) { - if ((*it)->GetAccountId() == active_account_id_) - return *it; - } - } - return users_[0]; - } - return nullptr; -} - -const User* FakeUserManager::GetActiveUser() const { - return GetActiveUserInternal(); -} - -User* FakeUserManager::GetActiveUser() { - return GetActiveUserInternal(); -} - void FakeUserManager::SwitchActiveUser(const AccountId& account_id) { for (UserList::const_iterator it = logged_in_users_.begin(); it != logged_in_users_.end(); ++it) {
diff --git a/components/user_manager/fake_user_manager.h b/components/user_manager/fake_user_manager.h index 0a0d4ea..886d987 100644 --- a/components/user_manager/fake_user_manager.h +++ b/components/user_manager/fake_user_manager.h
@@ -69,8 +69,6 @@ bool browser_restart, bool is_child) override; - const User* GetActiveUser() const override; - User* GetActiveUser() override; void SwitchActiveUser(const AccountId& account_id) override; void SaveUserDisplayName(const AccountId& account_id, const std::u16string& display_name) override; @@ -115,15 +113,7 @@ using UserManagerImpl::SetEphemeralModeConfig; using UserManagerImpl::SetOwnerId; - protected: - // If set this is the active user. If empty, the first created user is the - // active user. - AccountId active_account_id_ = EmptyAccountId(); - private: - // We use this internal function for const-correctness. - User* GetActiveUserInternal() const; - // stub, always empty. AccountId owner_account_id_ = EmptyAccountId();
diff --git a/components/variations/net/BUILD.gn b/components/variations/net/BUILD.gn index ee3372e..ff78a53d 100644 --- a/components/variations/net/BUILD.gn +++ b/components/variations/net/BUILD.gn
@@ -25,7 +25,6 @@ deps = [ "//base", "//components/google/core/common", - "//components/metrics", "//components/variations:variations_mojom", "//components/variations/field_trial_config", "//components/variations/proto",
diff --git a/components/viz/common/features.cc b/components/viz/common/features.cc index fc205d0..55bb7f0 100644 --- a/components/viz/common/features.cc +++ b/components/viz/common/features.cc
@@ -210,7 +210,7 @@ // Enable WebView providing frame rate hints to View system. BASE_FEATURE(kWebViewFrameRateHints, "WebViewFrameRateHints", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); #endif BASE_FEATURE(kDrawPredictedInkPoint,
diff --git a/components/viz/service/compositor_frame_fuzzer/BUILD.gn b/components/viz/service/compositor_frame_fuzzer/BUILD.gn index 803ceb36..7e5dbbd2 100644 --- a/components/viz/service/compositor_frame_fuzzer/BUILD.gn +++ b/components/viz/service/compositor_frame_fuzzer/BUILD.gn
@@ -69,7 +69,9 @@ ":generate_seed_corpus", "//components/viz/service", "//components/viz/test:test_support", + "//gpu:test_support", "//mojo/core/embedder", + "//testing/gmock", "//third_party/libprotobuf-mutator", ]
diff --git a/components/viz/service/compositor_frame_fuzzer/DEPS b/components/viz/service/compositor_frame_fuzzer/DEPS index 626a7ce..b41e1e0 100644 --- a/components/viz/service/compositor_frame_fuzzer/DEPS +++ b/components/viz/service/compositor_frame_fuzzer/DEPS
@@ -7,6 +7,10 @@ "compositor_frame_fuzzer.cc": [ "+mojo/core/embedder", ], + "compositor_frame_fuzzer_util.cc": [ + "+gpu/command_buffer/client/test_shared_image_interface.h", + "+gpu/command_buffer/client/client_shared_image.h", + ], "fuzzer_browser_process.*": [ "+mojo/public", ]
diff --git a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc index fef60a9..611d022 100644 --- a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc +++ b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.cc
@@ -14,6 +14,8 @@ #include "components/viz/common/quads/tile_draw_quad.h" #include "components/viz/common/resources/bitmap_allocation.h" #include "components/viz/common/resources/resource_sizes.h" +#include "gpu/command_buffer/client/client_shared_image.h" +#include "gpu/command_buffer/client/test_shared_image_interface.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/gfx/geometry/mask_filter_info.h" @@ -103,7 +105,7 @@ class FuzzedCompositorFrameBuilder { public: - FuzzedCompositorFrameBuilder() = default; + FuzzedCompositorFrameBuilder(); FuzzedCompositorFrameBuilder(const FuzzedCompositorFrameBuilder&) = delete; FuzzedCompositorFrameBuilder& operator=(const FuzzedCompositorFrameBuilder&) = @@ -151,6 +153,8 @@ // in memory (see TryReserveBitmapBytes). FuzzedBitmap* AllocateFuzzedBitmap(const gfx::Size& size, SkColor4f color); + scoped_refptr<gpu::TestSharedImageInterface> shared_image_interface_; + // Number of bytes that have already been reserved for the allocation of // specific bitmaps/textures. uint64_t reserved_bytes_ = 0; @@ -161,6 +165,10 @@ FuzzedData data_; }; +FuzzedCompositorFrameBuilder::FuzzedCompositorFrameBuilder() + : shared_image_interface_( + base::MakeRefCounted<gpu::TestSharedImageInterface>()) {} + FuzzedData FuzzedCompositorFrameBuilder::Build( const proto::CompositorRenderPass& render_pass_spec) { static FrameTokenGenerator next_frame_token; @@ -273,9 +281,10 @@ FuzzedBitmap* fuzzed_bitmap = AllocateFuzzedBitmap( tile_size, GetColorFromProtobuf(quad_spec.tile_quad().texture_color())); TransferableResource transferable_resource = - TransferableResource::MakeSoftwareSharedBitmap( - fuzzed_bitmap->id, gpu::SyncToken(), fuzzed_bitmap->size, - SinglePlaneFormat::kRGBA_8888); + TransferableResource::MakeSoftwareSharedImage( + fuzzed_bitmap->shared_image, fuzzed_bitmap->sync_token, + fuzzed_bitmap->size, SinglePlaneFormat::kBGRA_8888, + TransferableResource::ResourceSource::kTileRasterTask); auto* shared_quad_state = pass->CreateAndAppendSharedQuadState(); ConfigureSharedQuadState(shared_quad_state, quad_spec); @@ -391,7 +400,7 @@ const gfx::Size& size) { uint64_t bitmap_bytes; if (!ResourceSizes::MaybeSizeInBytes<uint64_t>( - size, SinglePlaneFormat::kRGBA_8888, &bitmap_bytes) || + size, SinglePlaneFormat::kBGRA_8888, &bitmap_bytes) || bitmap_bytes > kMaxTextureMemory - reserved_bytes_) { return false; } @@ -403,27 +412,36 @@ FuzzedBitmap* FuzzedCompositorFrameBuilder::AllocateFuzzedBitmap( const gfx::Size& size, SkColor4f color) { - SharedBitmapId shared_bitmap_id = SharedBitmap::GenerateId(); - base::MappedReadOnlyRegion shm = bitmap_allocation::AllocateSharedBitmap( - size, SinglePlaneFormat::kRGBA_8888); + auto shared_image_mapping = shared_image_interface_->CreateSharedImage( + {SinglePlaneFormat::kBGRA_8888, size, gfx::ColorSpace(), + gpu::SHARED_IMAGE_USAGE_CPU_WRITE_ONLY, "FuzzedCompositorFrameBuilder"}); + + CHECK(shared_image_mapping.shared_image); + gpu::SyncToken sync_token = shared_image_interface_->GenVerifiedSyncToken(); SkBitmap bitmap; SkImageInfo info = SkImageInfo::MakeN32Premul(size.width(), size.height()); - bitmap.installPixels(info, shm.mapping.memory(), info.minRowBytes()); + bitmap.installPixels(info, shared_image_mapping.mapping.memory(), + info.minRowBytes()); bitmap.eraseColor(color); data_.allocated_bitmaps.push_back( - {shared_bitmap_id, size, std::move(shm.region)}); + {size, std::move(shared_image_mapping.mapping), + std::move(shared_image_mapping.shared_image), sync_token}); return &data_.allocated_bitmaps.back(); } } // namespace -FuzzedBitmap::FuzzedBitmap(const SharedBitmapId& id, - const gfx::Size& size, - base::ReadOnlySharedMemoryRegion shared_region) - : id(id), size(size), shared_region(std::move(shared_region)) {} +FuzzedBitmap::FuzzedBitmap(const gfx::Size& size, + base::WritableSharedMemoryMapping mapping, + scoped_refptr<gpu::ClientSharedImage> shared_image, + gpu::SyncToken sync_token) + : size(size), + mapping(std::move(mapping)), + shared_image(std::move(shared_image)), + sync_token(std::move(sync_token)) {} FuzzedBitmap::~FuzzedBitmap() = default; FuzzedBitmap::FuzzedBitmap(FuzzedBitmap&& other) noexcept = default;
diff --git a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h index 8bf13618..10add41 100644 --- a/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h +++ b/components/viz/service/compositor_frame_fuzzer/compositor_frame_fuzzer_util.h
@@ -15,17 +15,19 @@ namespace viz { struct FuzzedBitmap { - FuzzedBitmap(const SharedBitmapId& id, - const gfx::Size& size, - base::ReadOnlySharedMemoryRegion shared_region); + FuzzedBitmap(const gfx::Size& size, + base::WritableSharedMemoryMapping mapping, + scoped_refptr<gpu::ClientSharedImage> shared_image, + gpu::SyncToken sync_token); ~FuzzedBitmap(); FuzzedBitmap(FuzzedBitmap&& other) noexcept; FuzzedBitmap& operator=(FuzzedBitmap&& other) = default; - SharedBitmapId id; gfx::Size size; - base::ReadOnlySharedMemoryRegion shared_region; + base::WritableSharedMemoryMapping mapping; + scoped_refptr<gpu::ClientSharedImage> shared_image; + gpu::SyncToken sync_token; }; struct FuzzedData {
diff --git a/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc b/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc index 4506159..f9e832e1 100644 --- a/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc +++ b/components/viz/service/compositor_frame_fuzzer/fuzzer_browser_process.cc
@@ -64,11 +64,6 @@ sink_client.BindInterfaceRemote(), /* render_input_router_config= */ nullptr); - for (auto& fuzzed_bitmap : allocated_bitmaps) { - sink_remote->DidAllocateSharedBitmap( - fuzzed_bitmap.shared_region.Duplicate(), fuzzed_bitmap.id); - } - lsi_allocator_.GenerateId(); SurfaceId embedded_surface_id(kEmbeddedFrameSinkId, lsi_allocator_.GetCurrentLocalSurfaceId()); @@ -86,9 +81,9 @@ display_private_->ForceImmediateDrawAndSwapIfPossible(); for (auto& fuzzed_bitmap : allocated_bitmaps) { - sink_remote->DidDeleteSharedBitmap(fuzzed_bitmap.id); + fuzzed_bitmap.shared_image->UpdateDestructionSyncToken( + fuzzed_bitmap.sync_token); } - // run queued messages (memory deallocation) base::RunLoop().RunUntilIdle();
diff --git a/components/viz/service/display/frame_interval_decider.cc b/components/viz/service/display/frame_interval_decider.cc index c97c2889..5dd62c5 100644 --- a/components/viz/service/display/frame_interval_decider.cc +++ b/components/viz/service/display/frame_interval_decider.cc
@@ -8,8 +8,10 @@ #include <utility> +#include "base/cpu_reduction_experiment.h" #include "base/functional/overloaded.h" #include "base/memory/ptr_util.h" +#include "base/metrics/histogram_functions.h" #include "base/trace_event/trace_event.h" #include "components/viz/common/quads/frame_interval_inputs.h" #include "components/viz/service/surfaces/surface.h" @@ -87,6 +89,18 @@ } } + if (base::ShouldLogHistogramForCpuReductionExperiment()) { + base::UmaHistogramEnumeration("Viz.FrameIntervalDecider.ResultMatcherType", + matcher_type); + if (match_result && + absl::holds_alternative<base::TimeDelta>(match_result.value())) { + base::UmaHistogramCustomTimes( + "Viz.FrameIntervalDecider.ResultTimeDelta", + absl::get<base::TimeDelta>(match_result.value()), + base::Milliseconds(0), base::Milliseconds(500), 50); + } + } + // If nothing matched, use the default. if (!match_result) { match_result = absl::visit(
diff --git a/components/viz/service/display/frame_interval_matchers.h b/components/viz/service/display/frame_interval_matchers.h index 032cf7df..ed31ea5 100644 --- a/components/viz/service/display/frame_interval_matchers.h +++ b/components/viz/service/display/frame_interval_matchers.h
@@ -22,13 +22,16 @@ namespace viz { +// These values are persisted to logs. Entries should not be renumbered and +// numeric values should never be reused. enum class FrameIntervalMatcherType { - kNone, - kInputBoost, - kOnlyVideo, - kVideoConference, - kOnlyAnimatingImage, - kOnlyScrollBarFadeOut, + kNone = 0, + kInputBoost = 1, + kOnlyVideo = 2, + kVideoConference = 3, + kOnlyAnimatingImage = 4, + kOnlyScrollBarFadeOut = 5, + kMaxValue = kOnlyScrollBarFadeOut, }; // Works with `FrameIntervalDecider` to compute the ideal frame interval.
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 0676a6f9..e2ee649 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -4003,12 +4003,7 @@ overlay->mailbox = dst_overlay_backing.mailbox; overlay->resource_size_in_pixels = dst_overlay_backing.size; - if (can_skip_render_pass) { - int pixel_size = quad->rect.width() * quad->rect.height(); - UMA_HISTOGRAM_COUNTS_10M( - "Compositing.SkiaRenderer.SkippedOverlayRenderPassDrawQuadSize", - pixel_size); - } else { + if (!can_skip_render_pass) { current_canvas_ = skia_output_surface_->BeginPaintRenderPass( quad->render_pass_id, dst_overlay_backing.size, dst_overlay_backing.format, dst_overlay_backing.alpha_type,
diff --git a/components/viz/service/frame_sinks/fling_scheduler_android_unittest.cc b/components/viz/service/frame_sinks/fling_scheduler_android_unittest.cc index a51cd03..13a3469 100644 --- a/components/viz/service/frame_sinks/fling_scheduler_android_unittest.cc +++ b/components/viz/service/frame_sinks/fling_scheduler_android_unittest.cc
@@ -8,8 +8,10 @@ #include "build/build_config.h" #include "components/input/features.h" #include "components/viz/service/display_embedder/server_shared_bitmap_manager.h" +#include "components/viz/service/frame_sinks/external_begin_frame_source_android.h" #include "components/viz/service/frame_sinks/frame_sink_manager_impl.h" #include "components/viz/service/input/input_manager.h" +#include "components/viz/test/begin_frame_args_test.h" #include "components/viz/test/mock_compositor_frame_sink_client.h" #include "components/viz/test/test_output_surface_provider.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,7 +24,14 @@ class FakeInputManager : public InputManager { public: explicit FakeInputManager(FrameSinkManagerImpl* frame_sink_manager) - : InputManager(frame_sink_manager) {} + : InputManager(frame_sink_manager), + begin_frame_source_(BeginFrameSource::kNotRestartableId, + 60.f, + /*requires_align_with_java=*/false) { + // Send BeginFrame without any observer. + auto args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); + begin_frame_source_.OnBeginFrame(args); + } FakeInputManager(const FakeInputManager&) = delete; FakeInputManager& operator=(const FakeInputManager&) = delete; @@ -35,7 +44,7 @@ } private: - StubBeginFrameSource begin_frame_source_; + ExternalBeginFrameSourceAndroid begin_frame_source_; }; class FlingSchedulerTest : public testing::Test,
diff --git a/components/viz/service/input/fling_scheduler_android.cc b/components/viz/service/input/fling_scheduler_android.cc index 50c7fbef..c7f2872 100644 --- a/components/viz/service/input/fling_scheduler_android.cc +++ b/components/viz/service/input/fling_scheduler_android.cc
@@ -74,13 +74,13 @@ return; } - auto* begin_frame_provider = GetBeginFrameSource(); - if (!begin_frame_provider) { + auto* begin_frame_source = GetBeginFrameSource(); + if (!begin_frame_source) { return; } - begin_frame_provider->AddObserver(this); - observed_begin_frame_source_ = begin_frame_provider; + observed_begin_frame_source_ = begin_frame_source; + observed_begin_frame_source_->AddObserver(this); } void FlingSchedulerAndroid::StopObservingBeginFrames() {
diff --git a/components/viz/test/test_shared_image_interface_provider.cc b/components/viz/test/test_shared_image_interface_provider.cc index ea45475..1d7dc62 100644 --- a/components/viz/test/test_shared_image_interface_provider.cc +++ b/components/viz/test/test_shared_image_interface_provider.cc
@@ -4,6 +4,8 @@ #include "components/viz/test/test_shared_image_interface_provider.h" +#include <utility> + #include "gpu/command_buffer/client/test_shared_image_interface.h" namespace viz { @@ -13,6 +15,11 @@ shared_image_interface_( base::MakeRefCounted<gpu::TestSharedImageInterface>()) {} +TestSharedImageInterfaceProvider::TestSharedImageInterfaceProvider( + scoped_refptr<gpu::SharedImageInterface> shared_image_interface) + : SharedImageInterfaceProvider(nullptr), + shared_image_interface_(std::move(shared_image_interface)) {} + TestSharedImageInterfaceProvider::~TestSharedImageInterfaceProvider() = default; gpu::SharedImageInterface*
diff --git a/components/viz/test/test_shared_image_interface_provider.h b/components/viz/test/test_shared_image_interface_provider.h index 83d2190..142ffa66 100644 --- a/components/viz/test/test_shared_image_interface_provider.h +++ b/components/viz/test/test_shared_image_interface_provider.h
@@ -16,6 +16,8 @@ class TestSharedImageInterfaceProvider : public SharedImageInterfaceProvider { public: TestSharedImageInterfaceProvider(); + TestSharedImageInterfaceProvider( + scoped_refptr<gpu::SharedImageInterface> shared_image_interface); ~TestSharedImageInterfaceProvider() override; gpu::SharedImageInterface* GetSharedImageInterface() override;
diff --git a/content/browser/browser_context_impl.cc b/content/browser/browser_context_impl.cc index 0308c38..428c036 100644 --- a/content/browser/browser_context_impl.cc +++ b/content/browser/browser_context_impl.cc
@@ -89,7 +89,7 @@ // have DIPS enabled. (This is important for embedders like ChromeOS, which // have internal non-user-facing browser contexts. We don't want to touch // them.) - if (dips_delegate_ && !dips_delegate_->ShouldEnableDips(self_)) { + if (!GetContentClient()->browser()->ShouldEnableDips(self_)) { return; } @@ -412,13 +412,12 @@ } namespace { -bool ShouldEnableDips(BrowserContext* browser_context, - DipsDelegate* dips_delegate) { +bool ShouldEnableDips(BrowserContext* browser_context) { if (!base::FeatureList::IsEnabled(features::kDIPS)) { return false; } - if (dips_delegate && !dips_delegate->ShouldEnableDips(browser_context)) { + if (!GetContentClient()->browser()->ShouldEnableDips(browser_context)) { return false; } @@ -428,7 +427,7 @@ DIPSServiceImpl* BrowserContextImpl::GetDipsService() { if (!dips_service_) { - if (!ShouldEnableDips(self_, dips_delegate_.get())) { + if (!ShouldEnableDips(self_)) { return nullptr; } dips_service_ = std::make_unique<DIPSServiceImpl>(
diff --git a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc index d0447c9..7871a50a 100644 --- a/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc +++ b/content/browser/browsing_data/browsing_data_remover_impl_browsertest.cc
@@ -769,7 +769,7 @@ // provided to HasTrustTokens(origin, _) calls in AddOrigin: // - If data has not been cleared, // HasTrustToken(origin, https://probe.example) - // is expected to fail with kResourceLimited because |origin| is at + // is expected to fail with kSiteIssuerLimit because |origin| is at // its number-of-associated-issuers limit, so the answerer will refuse // to answer a query for an origin it has not yet seen. // - If data has been cleared, the answerer should be able to fulfill the @@ -778,11 +778,11 @@ url::Origin::Create(GURL("https://probe.example")), base::BindLambdaForTesting( [&](network::mojom::HasTrustTokensResultPtr result) { - // HasTrustTokens will error out with kResourceLimited exactly + // HasTrustTokens will error out with kSiteIssuerLimit exactly // when the top-frame origin |origin| was previously added by // AddOrigin. if (result->status == - network::mojom::TrustTokenOperationStatus::kResourceLimited) { + network::mojom::TrustTokenOperationStatus::kSiteIssuerLimit) { has_origin = true; }
diff --git a/content/browser/browsing_topics/browsing_topics_url_loader_interceptor.cc b/content/browser/browsing_topics/browsing_topics_url_loader_interceptor.cc index e9c75fb..db6189f 100644 --- a/content/browser/browsing_topics/browsing_topics_url_loader_interceptor.cc +++ b/content/browser/browsing_topics/browsing_topics_url_loader_interceptor.cc
@@ -4,6 +4,7 @@ #include "content/browser/browsing_topics/browsing_topics_url_loader_interceptor.h" +#include "components/browsing_topics/common/common_types.h" #include "content/browser/browsing_topics/header_util.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/content_browser_client.h" @@ -170,7 +171,9 @@ std::vector<blink::mojom::EpochTopicPtr> topics; topics_eligible_ = GetContentClient()->browser()->HandleTopicsWebApi( origin, request_initiator_frame->GetMainFrame(), - browsing_topics::ApiCallerSource::kFetch, + resource_request_->is_fetch_like_api + ? browsing_topics::ApiCallerSource::kFetch + : browsing_topics::ApiCallerSource::kImgAttribute, /*get_topics=*/true, /*observe=*/false, topics); @@ -200,9 +203,11 @@ return; } - HandleTopicsEligibleResponse(head->parsed_headers, - url::Origin::Create(url_), *rfh, - browsing_topics::ApiCallerSource::kFetch); + HandleTopicsEligibleResponse( + head->parsed_headers, url::Origin::Create(url_), *rfh, + resource_request_->is_fetch_like_api + ? browsing_topics::ApiCallerSource::kFetch + : browsing_topics::ApiCallerSource::kImgAttribute); topics_eligible_ = false; }
diff --git a/content/browser/browsing_topics/header_util.cc b/content/browser/browsing_topics/header_util.cc index 6e59fdd..c93244d 100644 --- a/content/browser/browsing_topics/header_util.cc +++ b/content/browser/browsing_topics/header_util.cc
@@ -5,6 +5,7 @@ #include "content/browser/browsing_topics/header_util.h" #include "base/strings/strcat.h" +#include "components/browsing_topics/common/common_types.h" #include "components/browsing_topics/common/semantic_tree.h" #include "content/browser/renderer_host/render_frame_host_impl.h" #include "content/public/browser/content_browser_client.h" @@ -148,7 +149,8 @@ RenderFrameHost& request_initiator_frame, browsing_topics::ApiCallerSource caller_source) { DCHECK(caller_source == browsing_topics::ApiCallerSource::kFetch || - caller_source == browsing_topics::ApiCallerSource::kIframeAttribute); + caller_source == browsing_topics::ApiCallerSource::kIframeAttribute || + caller_source == browsing_topics::ApiCallerSource::kImgAttribute); if (!parsed_headers || !parsed_headers->observe_browsing_topics) { return;
diff --git a/content/browser/devtools/devtools_instrumentation.cc b/content/browser/devtools/devtools_instrumentation.cc index 3f870f6..90fd0be 100644 --- a/content/browser/devtools/devtools_instrumentation.cc +++ b/content/browser/devtools/devtools_instrumentation.cc
@@ -1355,6 +1355,20 @@ return result; } +bool ApplyNetworkCookieControlsOverrides( + DevToolsAgentHostImpl* agent_host, + net::CookieSettingOverrides& overrides) { + if (!agent_host) { + return false; + } + for (auto* network : protocol::NetworkHandler::ForAgentHost(agent_host)) { + if (network->enabled()) { + network->ApplyCookieControlsOverrides(overrides); + } + } + return !overrides.empty(); +} + namespace { template <typename HandlerType> bool MaybeCreateProxyForInterception(
diff --git a/content/browser/devtools/devtools_instrumentation.h b/content/browser/devtools/devtools_instrumentation.h index c6746338..1e4c380 100644 --- a/content/browser/devtools/devtools_instrumentation.h +++ b/content/browser/devtools/devtools_instrumentation.h
@@ -9,6 +9,7 @@ to the relevant set of devtools protocol handlers. */ +#include <cstdint> #include <optional> #include <vector> @@ -25,6 +26,7 @@ #include "content/public/browser/certificate_request_result_type.h" #include "content/public/browser/global_routing_id.h" #include "mojo/public/cpp/bindings/pending_receiver.h" +#include "net/cookies/cookie_setting_override.h" #include "net/filter/source_stream.h" #include "services/network/public/cpp/url_loader_completion_status.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" @@ -142,6 +144,8 @@ network::URLLoaderFactoryBuilder& factory_builder, network::mojom::URLLoaderFactoryOverridePtr* factory_override); + DevToolsAgentHostImpl* agent_host() { return agent_host_; } + private: WillCreateURLLoaderFactoryParams(DevToolsAgentHostImpl* agent_host, const base::UnguessableToken& devtools_token, @@ -485,6 +489,11 @@ void DidChangeFrameLoadingState(FrameTreeNode& ftn); +// Returns true if devtools wants to override the cookie settings. +bool ApplyNetworkCookieControlsOverrides( + DevToolsAgentHostImpl* params, + net::CookieSettingOverrides& overrides); + } // namespace devtools_instrumentation } // namespace content
diff --git a/content/browser/devtools/protocol/network_handler.cc b/content/browser/devtools/protocol/network_handler.cc index 3e320ae..c2b4863 100644 --- a/content/browser/devtools/protocol/network_handler.cc +++ b/content/browser/devtools/protocol/network_handler.cc
@@ -78,6 +78,7 @@ #include "net/cookies/canonical_cookie.h" #include "net/cookies/cookie_inclusion_status.h" #include "net/cookies/cookie_partition_key.h" +#include "net/cookies/cookie_setting_override.h" #include "net/cookies/cookie_util.h" #include "net/http/http_response_headers.h" #include "net/http/http_status_code.h" @@ -3192,6 +3193,23 @@ accepted_stream_types_->end()); } +void NetworkHandler::ApplyCookieControlsOverrides( + net::CookieSettingOverrides& overrides) { + if (enable_third_party_cookie_restriction_) { + overrides.Put(net::CookieSettingOverride::kForceDisableThirdPartyCookies); + overrides.Put( + net::CookieSettingOverride::kForceEnableThirdPartyCookieMitigations); + } + // TODO(https://crbug.com/375352611): Handle the case to force enable + // third-party cookies. + if (disable_third_party_cookie_metadata_) { + overrides.Put(net::CookieSettingOverride::kSkipTPCDMetadataGrant); + } + if (disable_third_party_cookie_heuristics_) { + overrides.Put(net::CookieSettingOverride::kSkipTPCDHeuristicsGrant); + } +} + void NetworkHandler::RequestIntercepted( std::unique_ptr<InterceptedRequestInfo> info) { std::optional<protocol::Network::ErrorReason> error_reason; @@ -3683,6 +3701,9 @@ kOperationSuccessfullyFulfilledLocally: return protocol::Network::TrustTokenOperationDone::StatusEnum:: FulfilledLocally; + case network::mojom::TrustTokenOperationStatus::kSiteIssuerLimit: + return protocol::Network::TrustTokenOperationDone::StatusEnum:: + SiteIssuerLimit; } }
diff --git a/content/browser/devtools/protocol/network_handler.h b/content/browser/devtools/protocol/network_handler.h index c2dc6b55..d85ba5d 100644 --- a/content/browser/devtools/protocol/network_handler.h +++ b/content/browser/devtools/protocol/network_handler.h
@@ -21,6 +21,7 @@ #include "mojo/public/cpp/system/data_pipe.h" #include "net/base/net_errors.h" #include "net/cookies/canonical_cookie.h" +#include "net/cookies/cookie_setting_override.h" #include "net/filter/source_stream.h" #include "net/net_buildflags.h" #include "services/network/public/mojom/devtools_observer.mojom-forward.h" @@ -220,6 +221,7 @@ bool* disable_cache, std::optional<std::vector<net::SourceStream::SourceType>>* accepted_stream_types); + void ApplyCookieControlsOverrides(net::CookieSettingOverrides& overrides); void PrefetchRequestWillBeSent( const std::string& request_id, const network::ResourceRequest& request,
diff --git a/content/browser/dips/dips_test_utils.cc b/content/browser/dips/dips_test_utils.cc index fa5fdd1..a836c3a 100644 --- a/content/browser/dips/dips_test_utils.cc +++ b/content/browser/dips/dips_test_utils.cc
@@ -410,10 +410,6 @@ // DATA_TYPE_HISTORY bit. class SimpleDipsDelegate : public content::DipsDelegate { public: - bool ShouldEnableDips(content::BrowserContext* browser_context) override { - return true; - } - void OnDipsServiceCreated(content::BrowserContext* browser_context, DIPSService* dips_service) override {}
diff --git a/content/browser/indexed_db/instance/database.cc b/content/browser/indexed_db/instance/database.cc index 85cb07f..5179e922 100644 --- a/content/browser/indexed_db/instance/database.cc +++ b/content/browser/indexed_db/instance/database.cc
@@ -163,10 +163,26 @@ return bucket_context_->lock_manager(); } +bool Database::OnlyHasOneClient() const { + if (connections_.empty()) { + return true; + } + + const base::UnguessableToken& token = (*connections_.begin())->client_token(); + return std::all_of(connections_.begin(), connections_.end(), + [&token](Connection* connection) { + return connection->client_token() == token; + }); +} + void Database::RequireBlockingTransactionClientsToBeActive( Transaction* current_transaction, std::vector<PartitionedLockManager::PartitionedLockRequest>& lock_requests) { + if (OnlyHasOneClient()) { + return; + } + std::vector<PartitionedLockId> blocked_lock_ids = lock_manager().GetUnacquirableLocks(lock_requests);
diff --git a/content/browser/indexed_db/instance/database.h b/content/browser/indexed_db/instance/database.h index 358cec7..93734e79 100644 --- a/content/browser/indexed_db/instance/database.h +++ b/content/browser/indexed_db/instance/database.h
@@ -373,6 +373,13 @@ std::vector<PartitionedLockManager::PartitionedLockRequest> BuildLockRequestsFromTransaction(Transaction* transaction) const; + // In rare cases there are a very large number of queued + // requests/transactions, so calculations related to blocking or blocked + // clients can be expensive. See crbug.com/384476946. This method is used for + // shortcutting such operations when there's only a single client. Also + // returns true for zero clients. + bool OnlyHasOneClient() const; + // Find the transactions that block `current_transaction` from acquiring the // locks, and ensure that the clients with blocking transactions are active. void RequireBlockingTransactionClientsToBeActive(
diff --git a/content/browser/indexed_db/instance/transaction.cc b/content/browser/indexed_db/instance/transaction.cc index 0c18fab..8ab0113 100644 --- a/content/browser/indexed_db/instance/transaction.cc +++ b/content/browser/indexed_db/instance/transaction.cc
@@ -294,28 +294,42 @@ bool Transaction::IsTransactionBlockingOtherClients( bool consider_priority) const { CHECK_EQ(state_, STARTED); - std::set<PartitionedLockHolder*> blocked_requests = - bucket_context_->lock_manager().GetBlockedRequests(lock_ids()); + + if (database_->OnlyHasOneClient()) { + return false; + } + base::TimeTicks start = base::TimeTicks::Now(); - const bool is_blocking_others = std::ranges::any_of( - blocked_requests, [&](PartitionedLockHolder* blocked_lock_holder) { - auto* lock_request_data = static_cast<LockRequestData*>( - blocked_lock_holder->GetUserData(LockRequestData::kKey)); - if (!lock_request_data) { - return true; - } - // If `this` - // * comes from a background client (priority > 0), and - // * is equal or higher priority than the blocked transaction's client - // (aka equally or less severely throttled) - // then don't worry about blocking it. - const int this_priority = connection_->scheduling_priority(); - if (consider_priority && (this_priority > 0) && - (this_priority <= lock_request_data->scheduling_priority)) { - return false; - } - return lock_request_data->client_token != connection_->client_token(); - }); + std::optional<int> scheduling_priority; + if (consider_priority) { + scheduling_priority = connection_->scheduling_priority(); + } + const bool is_blocking_others = + bucket_context_->lock_manager().IsBlockingAnyRequest( + lock_ids(), + base::BindRepeating( + [](std::optional<int> this_priority, + const base::UnguessableToken& this_token, + PartitionedLockHolder* blocked_lock_holder) { + auto* lock_request_data = static_cast<LockRequestData*>( + blocked_lock_holder->GetUserData(LockRequestData::kKey)); + if (!lock_request_data) { + return true; + } + // If `this` + // * comes from a background client (priority > 0), and + // * is equal or higher priority than the blocked + // transaction's client + // (aka equally or less severely throttled) + // then don't worry about blocking it. + if (this_priority && (*this_priority > 0) && + (*this_priority <= + lock_request_data->scheduling_priority)) { + return false; + } + return lock_request_data->client_token != this_token; + }, + scheduling_priority, connection_->client_token())); base::TimeDelta duration = base::TimeTicks::Now() - start; if (duration > base::Milliseconds(2)) { base::UmaHistogramTimes("IndexedDB.CalculateBlockingStatusLongTimes",
diff --git a/content/browser/loader/navigation_url_loader_impl.cc b/content/browser/loader/navigation_url_loader_impl.cc index d1fd0bc..e93fa14 100644 --- a/content/browser/loader/navigation_url_loader_impl.cc +++ b/content/browser/loader/navigation_url_loader_impl.cc
@@ -80,6 +80,7 @@ #include "net/base/load_timing_info.h" #include "net/cert/sct_status_flags.h" #include "net/cert/signed_certificate_timestamp_and_status.h" +#include "net/cookies/cookie_setting_override.h" #include "net/http/http_content_disposition.h" #include "net/http/http_request_headers.h" #include "net/http/http_status_code.h" @@ -1701,17 +1702,28 @@ factory_builder, &header_client, bypass_redirect_checks, /*disable_secure_dns=*/nullptr, /*factory_override=*/nullptr, GetUIThreadTaskRunner({BrowserTaskType::kNavigationNetworkResponse})); - devtools_instrumentation::WillCreateURLLoaderFactoryParams::ForFrame( - frame_tree_node->current_frame_host()) - .Run(/*is_navigation=*/true, - /*is_download=*/false, factory_builder, - /*factory_override=*/nullptr); + + auto devtools_params = + devtools_instrumentation::WillCreateURLLoaderFactoryParams::ForFrame( + frame_tree_node->current_frame_host()); + devtools_params.Run(/*is_navigation=*/true, + /*is_download=*/false, factory_builder, + /*factory_override=*/nullptr); + net::CookieSettingOverrides devtools_cookie_overrides; if (header_client) { return base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>( CreateURLLoaderFactoryWithHeaderClient(std::move(header_client), std::move(factory_builder), storage_partition)); + } else if (devtools_instrumentation::ApplyNetworkCookieControlsOverrides( + devtools_params.agent_host(), devtools_cookie_overrides)) { + network::mojom::URLLoaderFactoryParamsPtr params = + storage_partition->CreateURLLoaderFactoryParams(); + params->devtools_cookie_setting_overrides = + std::move(devtools_cookie_overrides); + return std::move(factory_builder) + .Finish(storage_partition->GetNetworkContext(), std::move(params)); } else { return std::move(factory_builder) .Finish(storage_partition->GetURLLoaderFactoryForBrowserProcess());
diff --git a/content/browser/loader/url_loader_factory_utils.cc b/content/browser/loader/url_loader_factory_utils.cc index 195d988..2298c30 100644 --- a/content/browser/loader/url_loader_factory_utils.cc +++ b/content/browser/loader/url_loader_factory_utils.cc
@@ -6,6 +6,7 @@ #include "content/browser/storage_partition_impl.h" #include "content/public/browser/browser_thread.h" +#include "net/cookies/cookie_setting_override.h" namespace content { namespace url_loader_factory { @@ -280,6 +281,11 @@ factory_params->header_client = std::move(header_client); factory_params->factory_override = std::move(factory_override); factory_params->disable_secure_dns = disable_secure_dns; + if (devtools_params) { + devtools_instrumentation::ApplyNetworkCookieControlsOverrides( + devtools_params->agent_host(), + factory_params->devtools_cookie_setting_overrides); + } if (GetTestingInterceptor()) { GetTestingInterceptor().Run(terminal_params.process_id(), factory_builder);
diff --git a/content/browser/network/http_cookie_browsertest.cc b/content/browser/network/http_cookie_browsertest.cc index c1744547c..2fd5847 100644 --- a/content/browser/network/http_cookie_browsertest.cc +++ b/content/browser/network/http_cookie_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/test/bind.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" +#include "content/browser/devtools/protocol/devtools_protocol_test_support.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/storage_partition.h" #include "content/public/browser/web_contents.h" @@ -590,19 +591,12 @@ return http_response; } -class ThirdPartyCookiesBlockedHttpCookieBrowserTest - : public ContentBrowserTest { +class ThirdPartyCookiesHttpCookieBrowserTest : public ContentBrowserTest { public: - ThirdPartyCookiesBlockedHttpCookieBrowserTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { - feature_list_.InitWithFeatures( - { - net::features::kForceThirdPartyCookieBlocking, - }, - {}); - } + ThirdPartyCookiesHttpCookieBrowserTest() + : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {} - ~ThirdPartyCookiesBlockedHttpCookieBrowserTest() override = default; + ~ThirdPartyCookiesHttpCookieBrowserTest() override = default; void SetUpOnMainThread() override { ContentBrowserTest::SetUpOnMainThread(); @@ -691,6 +685,22 @@ private: net::test_server::EmbeddedTestServer https_server_; +}; + +class ThirdPartyCookiesBlockedHttpCookieBrowserTest + : public ThirdPartyCookiesHttpCookieBrowserTest { + public: + ThirdPartyCookiesBlockedHttpCookieBrowserTest() { + feature_list_.InitWithFeatures( + { + net::features::kForceThirdPartyCookieBlocking, + }, + {}); + } + + ~ThirdPartyCookiesBlockedHttpCookieBrowserTest() override = default; + + private: base::test::ScopedFeatureList feature_list_; }; @@ -865,11 +875,10 @@ } class AncestorChainBitEnabledThirdPartyCookiesBlockedTest - : public ContentBrowserTest, + : public ThirdPartyCookiesHttpCookieBrowserTest, public ::testing::WithParamInterface<bool> { public: - AncestorChainBitEnabledThirdPartyCookiesBlockedTest() - : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) { + AncestorChainBitEnabledThirdPartyCookiesBlockedTest() { feature_list_.InitWithFeatureStates( {{net::features::kForceThirdPartyCookieBlocking, true}, {net::features::kAncestorChainBitEnabledInPartitionedCookies, @@ -880,35 +889,8 @@ ~AncestorChainBitEnabledThirdPartyCookiesBlockedTest() override = default; - void SetUpOnMainThread() override { - ContentBrowserTest::SetUpOnMainThread(); - host_resolver()->AddRule("*", "127.0.0.1"); - https_server()->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES); - https_server()->AddDefaultHandlers(GetTestDataFilePath()); - https_server()->RegisterRequestHandler( - base::BindRepeating(&HandleEchoCookiesWithCorsRequest)); - ASSERT_TRUE(https_server()->Start()); - } - - WebContents* web_contents() const { return shell()->web_contents(); } - - net::EmbeddedTestServer* https_server() { return &https_server_; } - - GURL EchoCookiesUrl(const std::string& host) const { - return https_server_.GetURL(host, "/echoheader?Cookie"); - } - - std::string ExtractFrameContent(RenderFrameHost* frame) const { - return EvalJs(frame, "document.body.textContent").ExtractString(); - } - - std::string ExtractCookieFromDocument(RenderFrameHost* frame) const { - return EvalJs(frame, "document.cookie").ExtractString(); - } - private: base::test::ScopedFeatureList feature_list_; - net::test_server::EmbeddedTestServer https_server_; }; IN_PROC_BROWSER_TEST_P(AncestorChainBitEnabledThirdPartyCookiesBlockedTest, @@ -1302,6 +1284,74 @@ net::CookieStringIs(UnorderedElementsAre(Key(kSameSiteNoneCookieName)))); } +class DevToolsOverridesThirdPartyCookiesBrowserTest + : public TestDevToolsProtocolClient, + public ThirdPartyCookiesHttpCookieBrowserTest { + public: + DevToolsOverridesThirdPartyCookiesBrowserTest() = default; + + ~DevToolsOverridesThirdPartyCookiesBrowserTest() override = default; + + void SetUpOnMainThread() override { + ThirdPartyCookiesHttpCookieBrowserTest::SetUpOnMainThread(); + AttachToWebContents(shell()->web_contents()); + SendCommandAsync("Network.enable"); + } + + void TearDownOnMainThread() override { DetachProtocolClient(); } +}; + +IN_PROC_BROWSER_TEST_F(DevToolsOverridesThirdPartyCookiesBrowserTest, + DevToolsForceDisableTPC) { + // Set SameSite=None cookie on top-level-site kHostA. + ASSERT_TRUE(SetCookie( + web_contents()->GetBrowserContext(), https_server()->GetURL(kHostA, "/"), + base::StrCat({kSameSiteNoneCookieName, "=1;Secure;SameSite=None;"}))); + ASSERT_TRUE(NavigateToURL(web_contents(), EchoCookiesUrl(kHostA))); + ASSERT_THAT( + ExtractFrameContent(web_contents()->GetPrimaryMainFrame()), + net::CookieStringIs(UnorderedElementsAre(Key(kSameSiteNoneCookieName)))); + // Embed an iframe containing A in B and check 3pc is allowed. + ASSERT_THAT( + content::ArrangeFramesAndGetContentFromLeaf( + web_contents(), https_server(), + FrameTreeForHostAndUrl(kHostB, EchoCookiesUrl(kHostA)), {0}), + net::CookieStringIs(UnorderedElementsAre(Key(kSameSiteNoneCookieName)))); + + // Apply devtools overrides to enable 3pc restriction. + base::Value::Dict command_params; + command_params.Set("enableThirdPartyCookieRestriction", true); + command_params.Set("disableThirdPartyCookieMetadata", false); + command_params.Set("disableThirdPartyCookieHeuristics", false); + SendCommandSync("Network.setCookieControls", std::move(command_params)); + + // 3pc should be blocked due to devtools overrides. + EXPECT_THAT(content::ArrangeFramesAndGetContentFromLeaf( + web_contents(), https_server(), + FrameTreeForHostAndUrl(kHostB, EchoCookiesUrl(kHostA)), {0}), + "None"); + EXPECT_THAT(Fetch(web_contents()->GetPrimaryMainFrame(), + https_server()->GetURL(kHostA, kEchoCookiesWithCorsPath), + "cors", "include") + .ExtractString(), + net::CookieStringIs(IsEmpty())); + + SendCommandAsync("Network.disable"); + // The override should stop working and 3pc is re-allowed after devtools is + // disabled. + EXPECT_THAT( + content::ArrangeFramesAndGetContentFromLeaf( + web_contents(), https_server(), + FrameTreeForHostAndUrl(kHostB, EchoCookiesUrl(kHostA)), {0}), + net::CookieStringIs(UnorderedElementsAre(Key(kSameSiteNoneCookieName)))); + EXPECT_THAT( + Fetch(web_contents()->GetPrimaryMainFrame(), + https_server()->GetURL(kHostA, kEchoCookiesWithCorsPath), "cors", + "include") + .ExtractString(), + net::CookieStringIs(UnorderedElementsAre(Key(kSameSiteNoneCookieName)))); +} + INSTANTIATE_TEST_SUITE_P(/* no label */, HttpCookieBrowserTest, ::testing::Bool());
diff --git a/content/browser/renderer_host/navigation_transitions/navigation_transition_utils.cc b/content/browser/renderer_host/navigation_transitions/navigation_transition_utils.cc index 2c831bc..6df64fc 100644 --- a/content/browser/renderer_host/navigation_transitions/navigation_transition_utils.cc +++ b/content/browser/renderer_host/navigation_transitions/navigation_transition_utils.cc
@@ -141,6 +141,8 @@ is_copied_from_embedder ? CacheHitOrMissReason::kCapturedEmptyBitmapFromEmbedder : CacheHitOrMissReason::kCapturedEmptyBitmapFromWebPage); + entry->navigation_transition_data().set_is_copied_from_embedder( + is_copied_from_embedder); } return; }
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 2e47e64..6aef73a 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -5649,6 +5649,9 @@ void RenderFrameHostImpl::DidCommitPageActivation( NavigationRequest* committing_navigation_request, mojom::DidCommitProvisionalLoadParamsPtr params) { + TRACE_EVENT("navigation", "RenderFrameHostImpl::DidCommitPageActivation", + ChromeTrackEvent::kRenderFrameHost, this, + "committing_navigation_request", committing_navigation_request); DCHECK(committing_navigation_request->IsPageActivation()); DCHECK(is_main_frame());
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc index bc2e3f9..ec702e3 100644 --- a/content/browser/renderer_host/render_process_host_impl.cc +++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -3086,6 +3086,9 @@ void RenderProcessHostImpl::SetProcessLock( const IsolationContext& isolation_context, const ProcessLock& process_lock) { + TRACE_EVENT_BEGIN("shutdown", "Lock process", + perfetto::Track::FromPointer(this), + ChromeTrackEvent::kRenderProcessHost, *this); ChildProcessSecurityPolicyImpl::GetInstance()->LockProcess( isolation_context, GetDeprecatedID(), !IsUnused(), process_lock); @@ -3096,6 +3099,10 @@ // handled by another call to NotifyRendererOfLockedStateUpdate from // OnProcessLaunched. NotifyRendererOfLockedStateUpdate(); + + // "Lock process" + TRACE_EVENT_END("shutdown", perfetto::Track::FromPointer(this), + ChromeTrackEvent::kRenderProcessHost, *this); } bool RenderProcessHostImpl::IsProcessLockedToSiteForTesting() {
diff --git a/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc b/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc index d74d563c..a5a270a 100644 --- a/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc +++ b/content/browser/tpcd_heuristics/opener_heuristic_browsertest.cc
@@ -375,7 +375,10 @@ protected: void WaitForCookieIssueAndCheck(std::string_view third_party_site, - std::string_view warning) { + std::string_view warning, + std::string_view exclusion) { + CHECK(warning.empty() || exclusion.empty()) + << "inclusion reason and exclusion reason should not co-exist"; auto is_cookie_issue = [](const base::Value::Dict& params) { const std::string* issue_code = params.FindStringByDottedPath("issue.code"); @@ -386,6 +389,9 @@ base::Value::Dict params = WaitForMatchingNotification( "Audits.issueAdded", base::BindRepeating(is_cookie_issue)); + std::string_view reason_name = + warning.empty() ? "cookieExclusionReasons" : "cookieWarningReasons"; + std::string_view reason_value = warning.empty() ? exclusion : warning; std::string partial_expected = content::JsReplace(R"({ "cookie": { @@ -393,10 +399,10 @@ "name": "name", "path": "/" }, - "cookieWarningReasons": [ $2 ], + $2: [ $3 ], "operation": "ReadCookie", })", - third_party_site, warning); + third_party_site, reason_name, reason_value); // Find relevant fields from cookieIssueDetails ASSERT_THAT(params.FindDictByDottedPath("issue.details.cookieIssueDetails"), @@ -1336,7 +1342,54 @@ https_server_.GetURL("sub.b.test", "/favicon/icon.png")); // CookieIssue was fired since it was exempt from blocking - WaitForCookieIssueAndCheck("sub.b.test", "WarnThirdPartyCookieHeuristic"); + WaitForCookieIssueAndCheck("sub.b.test", + /*warning=*/{"WarnThirdPartyCookieHeuristic"}, + /*exclusion=*/{}); +} + +// TODO: crbug.com/376625002 - disabled for the move to //content since the +// DevTools integration is still only in //chrome. Either find a way to +// implement this test in //content or move it back to //chrome. +IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest, + DISABLED_PopupInteraction_DevtoolsDisableHeuristics) { + GURL opener_url = https_server_.GetURL("a.test", "/title1.html"); + GURL popup_url_1 = https_server_.GetURL("c.test", "/title1.html"); + GURL popup_url_2 = + https_server_.GetURL("b.test", "/server-redirect?title1.html"); + GURL popup_url_3 = https_server_.GetURL("b.test", "/title1.html"); + + // Initialize popup and interaction. + ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), opener_url)); + ASSERT_OK_AND_ASSIGN(WebContents * popup, OpenPopup(popup_url_1)); + + clock_.Advance(base::Minutes(1)); + ASSERT_TRUE(content::NavigateToURL(popup, popup_url_2, popup_url_3)); + + clock_.Advance(base::Minutes(1)); + SimulateMouseClick(popup); + + // Add a cookie access by popup_url on opener_url. + ASSERT_TRUE(NavigateToSetCookie(GetActiveWebContents(), &https_server_, + "sub.b.test", + /*is_secure_cookie_set=*/true, + /*is_ad_tagged=*/false)); + + SendCommandAsync("Network.enable"); + base::Value::Dict command_params; + command_params.Set("enableThirdPartyCookieRestriction", true); + command_params.Set("disableThirdPartyCookieMetadata", false); + command_params.Set("disableThirdPartyCookieHeuristics", true); + SendCommandSync("Network.setCookieControls", std::move(command_params)); + + ASSERT_TRUE(content::NavigateToURL(GetActiveWebContents(), opener_url)); + CreateImageAndWaitForCookieAccess( + GetActiveWebContents(), + https_server_.GetURL("sub.b.test", "/favicon/icon.png")); + + // Since the cookie is no longer exempted by heuristics, + // ExcludeThirdPartyPhaseout cookie issue should be present. + WaitForCookieIssueAndCheck("sub.b.test", /*warning=*/{}, + /*exclusion=*/{"ExcludeThirdPartyPhaseout"}); } IN_PROC_BROWSER_TEST_F(OpenerHeuristicBrowserTest,
diff --git a/content/browser/webrtc/resources/BUILD.gn b/content/browser/webrtc/resources/BUILD.gn index 8f2672a..1f60aae3 100644 --- a/content/browser/webrtc/resources/BUILD.gn +++ b/content/browser/webrtc/resources/BUILD.gn
@@ -2,17 +2,17 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -import("//tools/grit/grit_rule.gni") -import("//ui/webui/resources/tools/generate_grd.gni") +import("//ui/webui/resources/tools/build_webui.gni") -generated_grd = "$target_gen_dir/resources.grd" - -generate_grd("build_grd") { - out_grd = generated_grd +build_webui("build") { grd_prefix = "webrtc_internals" - input_files_base_dir = rebase_path(".", "//") - input_files = [ + static_files = [ + "webrtc_internals.css", + "webrtc_internals.html", + ] + + non_web_component_files = [ "candidate_grid.js", "data_series.js", "dump_creator.js", @@ -24,22 +24,12 @@ "tab_view.js", "timeline_graph_view.js", "user_media_table.js", - "webrtc_internals.html", - "webrtc_internals.css", "webrtc_internals.js", ] -} -grit("resources") { - source = generated_grd - enable_input_discovery_for_gn_analyze = false - deps = [ ":build_grd" ] + webui_context_type = "trusted" - outputs = [ - "grit/webrtc_internals_resources.h", - "grit/webrtc_internals_resources_map.cc", - "grit/webrtc_internals_resources_map.h", - "webrtc_internals_resources.pak", - ] - output_dir = "$root_gen_dir/content/browser/webrtc/resources" + ts_deps = [ "//ui/webui/resources/js:build_ts" ] + + grit_output_dir = "$root_gen_dir/content/browser/webrtc/resources" }
diff --git a/content/child/runtime_features.cc b/content/child/runtime_features.cc index 02dc9e5..91637a9 100644 --- a/content/child/runtime_features.cc +++ b/content/child/runtime_features.cc
@@ -220,6 +220,8 @@ {wf::EnableFedCmIdpSigninStatus, raw_ref(features::kFedCmIdpSigninStatusEnabled), kSetOnlyIfOverridden}, + {wf::EnableFedCmLightweightMode, + raw_ref(features::kFedCmLightweightMode), kDefault}, {wf::EnableGamepadMultitouch, raw_ref(features::kEnableGamepadMultitouch)}, {wf::EnableSharedStorageAPI, @@ -395,6 +397,9 @@ kSetOnlyIfOverridden}, {"TopicsDocumentAPI", raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, + {"TopicsImgAPI", raw_ref(features::kPrivacySandboxAdsAPIsOverride), + kSetOnlyIfOverridden}, + {"TopicsImgAPI", raw_ref(features::kPrivacySandboxAdsAPIsM1Override)}, {"TouchTextEditingRedesign", raw_ref(features::kTouchTextEditingRedesign)}, {"TrustedTypesFromLiteral", @@ -583,6 +588,7 @@ << blink::features::kBrowsingTopics.name << " in addition."; WebRuntimeFeatures::EnableTopicsAPI(false); WebRuntimeFeatures::EnableTopicsDocumentAPI(false); + WebRuntimeFeatures::EnableTopicsImgAPI(false); } else { if (!base::FeatureList::IsEnabled( blink::features::kBrowsingTopicsDocumentAPI)) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/AdditionalNavigationParamsUtils.java b/content/public/android/java/src/org/chromium/content/browser/AdditionalNavigationParamsUtils.java index ecc67c5..c9e6980 100644 --- a/content/public/android/java/src/org/chromium/content/browser/AdditionalNavigationParamsUtils.java +++ b/content/public/android/java/src/org/chromium/content/browser/AdditionalNavigationParamsUtils.java
@@ -4,17 +4,18 @@ package org.chromium.content.browser; -import androidx.annotation.Nullable; - import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; import org.jni_zero.JniType; import org.chromium.base.UnguessableToken; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.AdditionalNavigationParams; /** Interface which provides native access to an AdditionalNavigationParams instance. */ @JNINamespace("content") +@NullMarked public class AdditionalNavigationParamsUtils { private AdditionalNavigationParamsUtils() {} @@ -22,7 +23,7 @@ private static AdditionalNavigationParams create( @JniType("base::UnguessableToken") UnguessableToken initiatorFrameToken, int initiatorProcessId, - @Nullable @JniType("std::optional<base::UnguessableToken>") + @JniType("std::optional<base::UnguessableToken>") @Nullable UnguessableToken attributionSrcToken) { return new AdditionalNavigationParams( initiatorFrameToken, initiatorProcessId, attributionSrcToken); @@ -40,7 +41,7 @@ } @CalledByNative - private static @JniType("std::optional<base::UnguessableToken>") UnguessableToken + private static @JniType("std::optional<base::UnguessableToken>") @Nullable UnguessableToken getAttributionSrcToken(AdditionalNavigationParams params) { return params.getAttributionSrcToken(); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java b/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java index effa1a66..f035720 100644 --- a/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java +++ b/content/public/android/java/src/org/chromium/content/browser/AppWebMessagePort.java
@@ -10,8 +10,6 @@ import android.util.Pair; import androidx.annotation.MainThread; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; @@ -21,6 +19,8 @@ import org.chromium.base.ThreadUtils; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.MessagePayload; import org.chromium.content_public.browser.MessagePort; @@ -77,6 +77,7 @@ * This object is not thread safe but public methods may be called from any thread. */ @JNINamespace("content::android") +@NullMarked public class AppWebMessagePort implements MessagePort { private static final String TAG = "AppWebMessagePort"; @@ -84,15 +85,15 @@ // The |what| value for handleMessage. private static final int MESSAGE_RECEIVED = 1; - @NonNull private final MessageCallback mMessageCallback; + private final MessageCallback mMessageCallback; - MessageHandler(@NonNull MessageCallback callback, @Nullable Handler handler) { + MessageHandler(MessageCallback callback, @Nullable Handler handler) { super(handler == null ? Looper.getMainLooper() : handler.getLooper()); mMessageCallback = callback; } @Override - public void handleMessage(@NonNull final Message msg) { + public void handleMessage(final Message msg) { if (msg.what == MESSAGE_RECEIVED) { final Pair<MessagePayload, MessagePort[]> obj = (Pair<MessagePayload, MessagePort[]>) msg.obj; @@ -103,7 +104,8 @@ } @MainThread - public void onMessage(final MessagePayload messagePayload, final MessagePort[] sentPorts) { + public void onMessage( + final MessagePayload messagePayload, final MessagePort @Nullable [] sentPorts) { ThreadUtils.assertOnUiThread(); sendMessage(obtainMessage(MESSAGE_RECEIVED, Pair.create(messagePayload, sentPorts))); } @@ -111,7 +113,7 @@ // Accessed on UI thread only. private long mNativeAppWebMessagePort; - private MessageHandler mMessageHandler; + private @Nullable MessageHandler mMessageHandler; // Can be accessed from any thread, client needs to keep thread safe. Need volatile since they // may be accessed concurrently from UI thread and client thread, which may be different. @@ -182,7 +184,7 @@ } @Override - public void postMessage(MessagePayload messagePayload, MessagePort[] sentPorts) + public void postMessage(MessagePayload messagePayload, MessagePort @Nullable [] sentPorts) throws IllegalStateException { if (isClosed() || isTransferred()) { throw new IllegalStateException("Port is already closed or transferred"); @@ -253,7 +255,7 @@ @MainThread @CalledByNative - private void onMessage(@NonNull MessagePayload payload, @Nullable MessagePort[] ports) { + private void onMessage(MessagePayload payload, MessagePort @Nullable [] ports) { ThreadUtils.assertOnUiThread(); if (mMessageHandler != null) { mMessageHandler.onMessage(payload, ports); @@ -290,13 +292,13 @@ @NativeMethods @MainThread interface Natives { - @NonNull + AppWebMessagePort[] createPair(); void postMessage( long nativeAppWebMessagePort, MessagePayload messagePayload, - MessagePort[] sentPorts); + MessagePort @Nullable [] sentPorts); void setShouldReceiveMessages(long nativeAppWebMessagePort, boolean shouldReceiveMessage);
diff --git a/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java b/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java index 595ee0da..c01150a 100644 --- a/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java +++ b/content/public/android/java/src/org/chromium/content/browser/AttributionOsLevelManager.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.pm.PackageManager; import android.net.Uri; import android.os.Build; @@ -38,6 +40,8 @@ import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.url.GURL; import java.io.IOException; @@ -55,6 +59,7 @@ * library. */ @JNINamespace("content") +@NullMarked public class AttributionOsLevelManager { private static final String TAG = "AttributionManager"; // TODO: replace with constant in android.Manifest.permission once it becomes available in U. @@ -62,10 +67,10 @@ "android.permission.ACCESS_ADSERVICES_ATTRIBUTION"; // Used for testing - private static MeasurementManagerFutures sManagerForTesting; + private static @Nullable MeasurementManagerFutures sManagerForTesting; private long mNativePtr; - private MeasurementManagerFutures mManager; + private @Nullable MeasurementManagerFutures mManager; @IntDef({ OperationType.REGISTER_SOURCE, @@ -143,7 +148,7 @@ return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R; } - private static @OperationResult int getOperationResultFromMessage(String message) { + private static @OperationResult int getOperationResultFromMessage(@Nullable String message) { if (message == null) { return OperationResult.ERROR_UNKNOWN; } else { @@ -241,7 +246,7 @@ mNativePtr = nativePtr; } - private MeasurementManagerFutures getManager() { + private @Nullable MeasurementManagerFutures getManager() { if (!supportsAttribution()) { return null; } @@ -280,7 +285,7 @@ future, new FutureCallback<Object>() { @Override - public void onSuccess(Object result) { + public void onSuccess(@Nullable Object result) { onRegistrationCompleted(requestId, type, OperationResult.SUCCESS); } @@ -294,7 +299,7 @@ } @CalledByNative - private static List<WebSourceParams> createWebSourceParamsList(int size) { + private static @Nullable List<WebSourceParams> createWebSourceParamsList(int size) { if (!supportsAttribution()) { return null; } @@ -377,7 +382,7 @@ } @CalledByNative - private static List<WebTriggerParams> createWebTriggerParamsList(int size) { + private static @Nullable List<WebTriggerParams> createWebTriggerParamsList(int size) { if (!supportsAttribution()) { return null; } @@ -537,7 +542,7 @@ } @Override - public void onSuccess(Object result) { + public void onSuccess(@Nullable Object result) { recordOperationResult( OperationType.DELETE_REGISTRATIONS, OperationResult.SUCCESS); onCall(); @@ -632,8 +637,8 @@ future, new FutureCallback<Integer>() { @Override - public void onSuccess(Integer status) { - onMeasurementStateReturned(status, OperationResult.SUCCESS); + public void onSuccess(@Nullable Integer status) { + onMeasurementStateReturned(assumeNonNull(status), OperationResult.SUCCESS); } @Override
diff --git a/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java b/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java index a524ceb..0b4ddb5 100644 --- a/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/AudioFocusDelegate.java
@@ -17,6 +17,8 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * AudioFocusDelegate is the Java counterpart of content::AudioFocusDelegateAndroid. @@ -30,12 +32,13 @@ * like a notification. */ @JNINamespace("content") +@NullMarked public class AudioFocusDelegate implements AudioManager.OnAudioFocusChangeListener { private static final String TAG = "MediaSession"; private int mFocusType; private boolean mIsDucking; - private AudioFocusRequest mFocusRequest; + private @Nullable AudioFocusRequest mFocusRequest; // Native pointer to C++ content::AudioFocusDelegateAndroid. // It will be set to 0 when the native AudioFocusDelegateAndroid object is destroyed.
diff --git a/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java index 10d30881..6ee7731 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java +++ b/content/public/android/java/src/org/chromium/content/browser/BackgroundSyncNetworkObserver.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.Manifest; import android.annotation.SuppressLint; import android.content.pm.PackageManager; @@ -20,6 +22,8 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.net.ConnectionType; import org.chromium.net.NetworkChangeNotifierAutoDetect; import org.chromium.net.RegistrationPolicyAlwaysRegister; @@ -41,14 +45,15 @@ */ @JNINamespace("content") @VisibleForTesting +@NullMarked public class BackgroundSyncNetworkObserver implements NetworkChangeNotifierAutoDetect.Observer { private static final String TAG = "BgSyncNetObserver"; private static boolean sSetConnectionTypeForTesting; - private NetworkChangeNotifierAutoDetect mNotifier; + private @Nullable NetworkChangeNotifierAutoDetect mNotifier; // The singleton instance. @SuppressLint("StaticFieldLeak") - private static BackgroundSyncNetworkObserver sInstance; + private static @Nullable BackgroundSyncNetworkObserver sInstance; // List of native observers. These are each called when the network state changes. private List<Long> mNativePtrs; @@ -84,7 +89,7 @@ } @CalledByNative - private static BackgroundSyncNetworkObserver createObserver(long nativePtr) { + private static @Nullable BackgroundSyncNetworkObserver createObserver(long nativePtr) { ThreadUtils.assertOnUiThread(); getBackgroundSyncNetworkObserver().registerObserver(nativePtr); @@ -174,6 +179,7 @@ public void onNetworkDisconnect(long netId) { ThreadUtils.assertOnUiThread(); if (sSetConnectionTypeForTesting) return; + assumeNonNull(mNotifier); // If we're in doze mode (N+ devices), onConnectionTypeChanged may not // be called, but this function should. So update the connection type
diff --git a/content/public/android/java/src/org/chromium/content/browser/BindingManager.java b/content/public/android/java/src/org/chromium/content/browser/BindingManager.java index 632c1e6..6da59eab 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BindingManager.java +++ b/content/public/android/java/src/org/chromium/content/browser/BindingManager.java
@@ -15,6 +15,8 @@ import org.chromium.base.ResettersForTesting; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.process_launcher.ChildProcessConnection; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Iterator; import java.util.Set; @@ -23,6 +25,7 @@ * Manages oom bindings used to bound child services. * This object must only be accessed from the launcher thread. */ +@NullMarked class BindingManager implements ComponentCallbacks2 { private static final String TAG = "BindingManager"; @@ -36,7 +39,7 @@ // Delays used when clearing moderate binding pool when onSentToBackground happens. private static final long BINDING_POOL_CLEARER_DELAY_MILLIS = 10 * 1000; - private static Boolean sUseNotPerceptibleBindingForTesting; + private static @Nullable Boolean sUseNotPerceptibleBindingForTesting; private final Set<ChildProcessConnection> mConnections = new ArraySet<ChildProcessConnection>(); // Can be -1 to mean no max size. @@ -46,7 +49,7 @@ // If not null, this is the connection in |mConnections| that does not have a binding added // by BindingManager. - private ChildProcessConnection mWaivedConnection; + private @Nullable ChildProcessConnection mWaivedConnection; private int mConnectionsDroppedDueToMaxSize;
diff --git a/content/public/android/java/src/org/chromium/content/browser/BrowserContextHandleImpl.java b/content/public/android/java/src/org/chromium/content/browser/BrowserContextHandleImpl.java index ce3075d..3bf69fbd 100644 --- a/content/public/android/java/src/org/chromium/content/browser/BrowserContextHandleImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/BrowserContextHandleImpl.java
@@ -7,10 +7,12 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.BrowserContextHandle; /** An interface that provides access to a native BrowserContext. */ @JNINamespace("content") +@NullMarked public class BrowserContextHandleImpl { private BrowserContextHandleImpl() {}
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionMetrics.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionMetrics.java index 9ff6bec..23235c07 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionMetrics.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessConnectionMetrics.java
@@ -14,6 +14,8 @@ import org.chromium.base.process_launcher.ChildProcessConnection; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Random; import java.util.Set; @@ -27,15 +29,16 @@ * * This class enforces that it is only used on the launcher thread other than during init. */ +@NullMarked public class ChildProcessConnectionMetrics { @VisibleForTesting private static final long INITIAL_EMISSION_DELAY_MS = 60 * 1000; // 1 min. private static final long REGULAR_EMISSION_DELAY_MS = 5 * 60 * 1000; // 5 min. - private static ChildProcessConnectionMetrics sInstance; + private static @Nullable ChildProcessConnectionMetrics sInstance; // Whether the main application is currently brought to the foreground. private boolean mApplicationInForegroundOnUiThread; - private BindingManager mBindingManager; + private @Nullable BindingManager mBindingManager; private final Set<ChildProcessConnection> mConnections = new ArraySet<>(); private final Random mRandom = new Random();
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java index 610a97ce..026d8327 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessCreationParamsImpl.java
@@ -65,14 +65,14 @@ if (sInitialized) extras.putInt(EXTRA_LIBRARY_PROCESS_TYPE, sLibraryProcessType); } - public static @Nullable String getPackageNameForPrivilegedService() { - return sInitialized + public static String getPackageNameForPrivilegedService() { + return sPackageNameForPrivilegedService != null ? sPackageNameForPrivilegedService : ContextUtils.getApplicationContext().getPackageName(); } - public static @Nullable String getPackageNameForSandboxedService() { - return sInitialized + public static String getPackageNameForSandboxedService() { + return sPackageNameForSandboxedService != null ? sPackageNameForSandboxedService : ContextUtils.getApplicationContext().getPackageName(); } @@ -93,11 +93,11 @@ return extras.getInt(EXTRA_LIBRARY_PROCESS_TYPE, LibraryProcessType.PROCESS_CHILD); } - public static @Nullable String getPrivilegedServicesName() { - return sInitialized ? sPrivilegedServicesName : PRIVILEGED_SERVICES_NAME; + public static String getPrivilegedServicesName() { + return sPrivilegedServicesName != null ? sPrivilegedServicesName : PRIVILEGED_SERVICES_NAME; } - public static @Nullable String getSandboxedServicesName() { - return sInitialized ? sSandboxedServicesName : SANDBOXED_SERVICES_NAME; + public static String getSandboxedServicesName() { + return sSandboxedServicesName != null ? sSandboxedServicesName : SANDBOXED_SERVICES_NAME; } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java index f3071663..9c2d351d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncherHelperImpl.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.os.Bundle; import android.os.Handler; @@ -11,7 +13,6 @@ import android.os.ParcelFileDescriptor; import android.text.TextUtils; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.jni_zero.CalledByNative; @@ -38,6 +39,9 @@ import org.chromium.base.process_launcher.FileDescriptorInfo; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.app.SandboxedProcessService; import org.chromium.content.common.ContentSwitchUtils; import org.chromium.content_public.browser.ChildProcessImportance; @@ -58,6 +62,7 @@ * Each public or jni methods should have explicit documentation on what threads they are called. */ @JNINamespace("content::internal") +@NullMarked public final class ChildProcessLauncherHelperImpl { private static final String TAG = "ChildProcLH"; @@ -85,37 +90,38 @@ private static boolean sCheckedServiceGroupImportance; // A warmed-up connection to a sandboxed service. - private static SpareChildConnection sSpareSandboxedConnection; + private static @Nullable SpareChildConnection sSpareSandboxedConnection; // Allocator used for sandboxed services. - private static ChildConnectionAllocator sSandboxedChildConnectionAllocator; - private static ChildProcessRanking sSandboxedChildConnectionRanking; + private static @Nullable ChildConnectionAllocator sSandboxedChildConnectionAllocator; + private static @Nullable ChildProcessRanking sSandboxedChildConnectionRanking; // Map from PID to ChildProcessLauncherHelper. private static final Map<Integer, ChildProcessLauncherHelperImpl> sLauncherByPid = new HashMap<>(); // Allocator used for non-sandboxed services. - private static ChildConnectionAllocator sPrivilegedChildConnectionAllocator; + private static @Nullable ChildConnectionAllocator sPrivilegedChildConnectionAllocator; // Used by tests to override the default sandboxed service allocator settings. - private static ChildConnectionAllocator.ConnectionFactory sSandboxedServiceFactoryForTesting; + private static ChildConnectionAllocator.@Nullable ConnectionFactory + sSandboxedServiceFactoryForTesting; private static int sSandboxedServicesCountForTesting = -1; - private static String sSandboxedServicesNameForTesting; + private static @Nullable String sSandboxedServicesNameForTesting; private static boolean sSkipDelayForReducePriorityOnBackgroundForTesting; - private static BindingManager sBindingManager; + private static @Nullable BindingManager sBindingManager; // Whether the main application is currently brought to the foreground. private static boolean sApplicationInForegroundOnUiThread; // Set on UI thread only, but null-checked on launcher thread as well. - private static ApplicationStatus.ApplicationStateListener sAppStateListener; + private static ApplicationStatus.@Nullable ApplicationStateListener sAppStateListener; // TODO(boliu): These are only set for sandboxed renderer processes. Generalize them for // all types of processes. - private final ChildProcessRanking mRanking; - private final BindingManager mBindingManager; + private final @Nullable ChildProcessRanking mRanking; + private final @Nullable BindingManager mBindingManager; // Whether the created process should be sandboxed. private final boolean mSandboxed; @@ -124,7 +130,7 @@ private final boolean mReducePriorityOnBackground; // The type of process as determined by the command line. - private final String mProcessType; + private final @Nullable String mProcessType; // Whether the process can use warmed up connection. private final boolean mCanUseWarmUpConnection; @@ -143,14 +149,14 @@ // The bundle with RELRO FD. For sending to child processes, including the ones that did not // announce whether they inherit from the app zygote. Declared as volatile to allow sending it // from different threads. - private static volatile Bundle sZygoteBundle; + private static volatile @Nullable Bundle sZygoteBundle; private static boolean sIgnoreMainFrameVisibilityForImportance; private final ChildProcessLauncher.Delegate mLauncherDelegate = new ChildProcessLauncher.Delegate() { @Override - public ChildProcessConnection getBoundConnection( + public @Nullable ChildProcessConnection getBoundConnection( ChildConnectionAllocator connectionAllocator, ChildProcessConnection.ServiceCallback serviceCallback) { if (!mCanUseWarmUpConnection) return null; @@ -306,10 +312,12 @@ } private static void sendPreviouslySeenZygoteBundleToExistingConnections(int pid) { + assumeNonNull(sZygoteBundle); for (var entry : sLauncherByPid.entrySet()) { int otherPid = entry.getKey(); if (pid != otherPid) { - ChildProcessConnection otherConnection = entry.getValue().mLauncher.getConnection(); + ChildProcessConnection otherConnection = + assumeNonNull(entry.getValue().mLauncher.getConnection()); if (otherConnection.getZygotePid() == 0) { // The Zygote PID for each connection must be finalized before the launcher // thread starts processing the zygote info. Zygote PID being 0 guarantees that @@ -334,7 +342,7 @@ private boolean mDroppedStrongBingingDueToBackgrounding; @CalledByNative - private static FileDescriptorInfo makeFdInfo( + private static @Nullable FileDescriptorInfo makeFdInfo( int id, int fd, boolean autoClose, long offset, long size) { assert LauncherThread.runningOnLauncherThread(); ParcelFileDescriptor pFd; @@ -446,6 +454,7 @@ new Runnable() { @Override public void run() { + assumeNonNull(sSandboxedChildConnectionRanking); ChildConnectionAllocator allocator = getConnectionAllocator(context, /* sandboxed= */ true); if (ChildProcessConnection.supportVariableConnections()) { @@ -492,7 +501,7 @@ private void reducePriorityOnBackgroundOnLauncherThread() { assert LauncherThread.runningOnLauncherThread(); if (mDroppedStrongBingingDueToBackgrounding) return; - ChildProcessConnection connection = mLauncher.getConnection(); + ChildProcessConnection connection = assumeNonNull(mLauncher.getConnection()); if (!connection.isConnected()) return; if (connection.isStrongBindingBound()) { connection.removeStrongBinding(); @@ -503,7 +512,7 @@ private void raisePriorityOnForegroundOnLauncherThread() { assert LauncherThread.runningOnLauncherThread(); if (!mDroppedStrongBingingDueToBackgrounding) return; - ChildProcessConnection connection = mLauncher.getConnection(); + ChildProcessConnection connection = assumeNonNull(mLauncher.getConnection()); if (!connection.isConnected()) return; connection.addStrongBinding(); mDroppedStrongBingingDueToBackgrounding = false; @@ -574,6 +583,7 @@ packageName); Runnable freeSlotRunnable = () -> { + assumeNonNull(sSandboxedChildConnectionRanking); ChildProcessConnection lowestRank = sSandboxedChildConnectionRanking.getLowestRankedConnection(); if (lowestRank != null) { @@ -637,6 +647,7 @@ return sSandboxedChildConnectionAllocator; } + @NullUnmarked private ChildProcessLauncherHelperImpl( long nativePointer, String[] commandLine, @@ -644,8 +655,8 @@ boolean sandboxed, boolean reducePriorityOnBackground, boolean canUseWarmUpConnection, - IBinder binderCallback, - IBinder binderBox) { + @Nullable IBinder binderCallback, + @Nullable IBinder binderBox) { assert LauncherThread.runningOnLauncherThread(); mNativeChildProcessLauncherHelper = nativePointer; @@ -745,6 +756,7 @@ LauncherThread.post(() -> mLauncher.stop()); } + @NullUnmarked @CalledByNative private void setPriority( int pid, @@ -768,7 +780,7 @@ return; } - ChildProcessConnection connection = mLauncher.getConnection(); + ChildProcessConnection connection = assumeNonNull(mLauncher.getConnection()); if (ChildProcessCreationParamsImpl.getIgnoreVisibilityForImportance()) { visible = false; boostForPendingViews = false; @@ -877,12 +889,13 @@ * Dumps the stack of the child process with |pid| without crashing it. * @param pid Process id of the child process. */ + @NullUnmarked @CalledByNative private void dumpProcessStack(int pid) { assert LauncherThread.runningOnLauncherThread(); ChildProcessLauncherHelperImpl launcher = getByPid(pid); if (launcher != null) { - ChildProcessConnection connection = launcher.mLauncher.getConnection(); + ChildProcessConnection connection = assumeNonNull(launcher.mLauncher.getConnection()); connection.dumpProcessStack(); } } @@ -898,7 +911,7 @@ return bundle; } - private static ChildProcessLauncherHelperImpl getByPid(int pid) { + private static @Nullable ChildProcessLauncherHelperImpl getByPid(int pid) { return sLauncherByPid.get(pid); } @@ -977,7 +990,7 @@ } @VisibleForTesting - public ChildProcessConnection getChildProcessConnection() { + public @Nullable ChildProcessConnection getChildProcessConnection() { return mLauncher.getConnection(); } @@ -985,7 +998,7 @@ return mLauncher.getConnectionAllocator(); } - public static ChildProcessConnection getWarmUpConnectionForTesting() { + public static @Nullable ChildProcessConnection getWarmUpConnectionForTesting() { return sSpareSandboxedConnection == null ? null : sSpareSandboxedConnection.getConnection(); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java index b5a45785..ebcdbee 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessRanking.java
@@ -8,6 +8,8 @@ import org.chromium.base.process_launcher.ChildProcessConnection; import org.chromium.build.BuildConfig; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ChildProcessImportance; import java.util.ArrayList; @@ -16,6 +18,7 @@ import java.util.List; /** Ranking of ChildProcessConnections for a particular ChildConnectionAllocator. */ +@NullMarked public class ChildProcessRanking implements Iterable<ChildProcessConnection> { private static final boolean ENABLE_CHECKS = BuildConfig.ENABLE_ASSERTS; private static final int NO_GROUP = 0; @@ -234,7 +237,7 @@ } public void updateConnection( - ChildProcessConnection connection, + @Nullable ChildProcessConnection connection, boolean visible, long frameDepth, boolean intersectsViewport, @@ -252,7 +255,7 @@ reposition(i); } - public ChildProcessConnection getLowestRankedConnection() { + public @Nullable ChildProcessConnection getLowestRankedConnection() { if (mRankings.isEmpty()) return null; return mRankings.get(mRankings.size() - 1).connection; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ClientDataJsonImpl.java b/content/public/android/java/src/org/chromium/content/browser/ClientDataJsonImpl.java index 1a7152d..9e97499 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ClientDataJsonImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ClientDataJsonImpl.java
@@ -4,12 +4,12 @@ package org.chromium.content.browser; -import androidx.annotation.Nullable; - import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; import org.chromium.blink.mojom.PaymentOptions; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ClientDataRequestType; import org.chromium.url.Origin; @@ -17,17 +17,17 @@ /** The implementation of ClientDataJson. */ @JNINamespace("content") +@NullMarked public class ClientDataJsonImpl { /** The implementation of {@link ClientDataJson#buildClientDataJson}. */ - @Nullable - public static String buildClientDataJson( + public static @Nullable String buildClientDataJson( @ClientDataRequestType int clientDataRequestType, String callerOrigin, byte[] challenge, boolean isCrossOrigin, - PaymentOptions paymentOptions, - String relyingPartyId, - Origin topOrigin) { + @Nullable PaymentOptions paymentOptions, + @Nullable String relyingPartyId, + @Nullable Origin topOrigin) { return ClientDataJsonImplJni.get() .buildClientDataJson( clientDataRequestType, @@ -46,8 +46,8 @@ String callerOrigin, byte[] challenge, boolean isCrossOrigin, - ByteBuffer optionsByteBuffer, - String relyingPartyId, - Origin topOrigin); + @Nullable ByteBuffer optionsByteBuffer, + @Nullable String relyingPartyId, + @Nullable Origin topOrigin); } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContactsDialogHost.java b/content/public/android/java/src/org/chromium/content/browser/ContactsDialogHost.java index f54fbd630..8e294f5 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContactsDialogHost.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContactsDialogHost.java
@@ -12,6 +12,8 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ContactsPicker; import org.chromium.content_public.browser.ContactsPickerListener; import org.chromium.content_public.browser.WebContents; @@ -25,6 +27,7 @@ * side. */ @JNINamespace("content") +@NullMarked public class ContactsDialogHost implements ContactsPickerListener { private long mNativeContactsProviderAndroid; private final WebContents mWebContents; @@ -173,11 +176,11 @@ interface Natives { void addContact( long nativeContactsProviderAndroid, - String[] names, - String[] emails, - String[] tel, - ByteBuffer[] addresses, - ByteBuffer[] icons); + String @Nullable [] names, + String @Nullable [] emails, + String @Nullable [] tel, + ByteBuffer @Nullable [] addresses, + ByteBuffer @Nullable [] icons); void endContactsList( long nativeContactsProviderAndroid,
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 b8498bf..3e5af4e3 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
@@ -5,10 +5,13 @@ package org.chromium.content.browser; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** A class factory for downstream injecting code to content layer. */ +@NullMarked public class ContentClassFactory { - private static ContentClassFactory sSingleton; + private static @Nullable ContentClassFactory sSingleton; /** Sets the factory object. */ public static void set(ContentClassFactory factory) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentNfcDelegate.java b/content/public/android/java/src/org/chromium/content/browser/ContentNfcDelegate.java index 25e7891a..7a866bd 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentNfcDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentNfcDelegate.java
@@ -9,6 +9,7 @@ import org.jni_zero.CalledByNative; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; import org.chromium.device.nfc.NfcDelegate; /** @@ -16,6 +17,7 @@ * corresponding NfcHost objects, allowing the NFC implementation to access the Activity of the * WebContents with which its requesting frame is associated. */ +@NullMarked public class ContentNfcDelegate implements NfcDelegate { @CalledByNative private static ContentNfcDelegate create() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java index db4e964..3527aa35 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentUiEventHandler.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.os.SystemClock; import android.view.InputDevice; import android.view.KeyEvent; @@ -16,6 +18,8 @@ import org.jni_zero.NativeMethods; import org.chromium.base.UserData; +import org.chromium.build.annotations.Initializer; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.input.ImeAdapterImpl; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; @@ -29,6 +33,7 @@ * content components. */ @JNINamespace("content") +@NullMarked public class ContentUiEventHandler implements UserData { private final WebContentsImpl mWebContents; private InternalAccessDelegate mEventDelegate; @@ -40,8 +45,12 @@ } public static ContentUiEventHandler fromWebContents(WebContents webContents) { - return ((WebContentsImpl) webContents) - .getOrSetUserData(ContentUiEventHandler.class, UserDataFactoryLazyHolder.INSTANCE); + ContentUiEventHandler ret = + ((WebContentsImpl) webContents) + .getOrSetUserData( + ContentUiEventHandler.class, UserDataFactoryLazyHolder.INSTANCE); + assert ret != null; + return ret; } public ContentUiEventHandler(WebContents webContents) { @@ -57,6 +66,7 @@ return contentUiEventHandler; } + @Initializer public void setEventDelegate(InternalAccessDelegate delegate) { mEventDelegate = delegate; } @@ -201,7 +211,10 @@ // It's a very real (and valid) possibility that a fling may still // be active when programatically scrolling. Cancelling the fling in // such cases ensures a consistent gesture event stream. - if (GestureListenerManagerImpl.fromWebContents(mWebContents).hasActiveFlingScroll()) { + GestureListenerManagerImpl gestureManager = + GestureListenerManagerImpl.fromWebContents(mWebContents); + assumeNonNull(gestureManager); + if (gestureManager.hasActiveFlingScroll()) { ContentUiEventHandlerJni.get() .cancelFling(mNativeContentUiEventHandler, ContentUiEventHandler.this, time); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ContentViewStaticsImpl.java b/content/public/android/java/src/org/chromium/content/browser/ContentViewStaticsImpl.java index 080a9f6d..3de4126 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ContentViewStaticsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ContentViewStaticsImpl.java
@@ -6,9 +6,11 @@ import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; import org.chromium.net.ProxyChangeListener; /** Implementations of {@link ContentViewStatics}. */ +@NullMarked public class ContentViewStaticsImpl { /** * Suspends Webkit timers in all renderers.
diff --git a/content/public/android/java/src/org/chromium/content/browser/Gamepad.java b/content/public/android/java/src/org/chromium/content/browser/Gamepad.java index b40663bc0..1a346efb 100644 --- a/content/public/android/java/src/org/chromium/content/browser/Gamepad.java +++ b/content/public/android/java/src/org/chromium/content/browser/Gamepad.java
@@ -4,11 +4,14 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.view.KeyEvent; import android.view.MotionEvent; import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; import org.chromium.content_public.browser.WebContents; @@ -18,6 +21,7 @@ * Encapsulates component class {@link GamepadList} for use in content, with regards * to its state according to content being attached to/detached from window. */ +@NullMarked class Gamepad implements WindowEventObserver, UserData { private final Context mContext; @@ -26,12 +30,15 @@ } public static Gamepad from(WebContents webContents) { - return ((WebContentsImpl) webContents) - .getOrSetUserData(Gamepad.class, UserDataFactoryLazyHolder.INSTANCE); + Gamepad ret = + ((WebContentsImpl) webContents) + .getOrSetUserData(Gamepad.class, UserDataFactoryLazyHolder.INSTANCE); + assert ret != null; + return ret; } public Gamepad(WebContents webContents) { - mContext = ((WebContentsImpl) webContents).getContext(); + mContext = assumeNonNull(((WebContentsImpl) webContents).getContext()); WindowEventObserverManager.from(webContents).addObserver(this); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java b/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java index 23c70fe..566f215 100644 --- a/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/GestureListenerManagerImpl.java
@@ -4,6 +4,7 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; import static org.chromium.cc.mojom.RootScrollOffsetUpdateFrequency.NONE; import android.view.HapticFeedbackConstants; @@ -21,6 +22,8 @@ import org.chromium.base.TraceEvent; import org.chromium.base.UserData; import org.chromium.blink.mojom.EventType; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.cc.mojom.RootScrollOffsetUpdateFrequency; import org.chromium.content.browser.input.ImeAdapterImpl; import org.chromium.content.browser.selection.SelectionPopupControllerImpl; @@ -45,6 +48,7 @@ * Instantiated object is held inside {@link UserDataHost} that is managed by {@link WebContents}. */ @JNINamespace("content") +@NullMarked public class GestureListenerManagerImpl implements GestureListenerManager, WindowEventObserver, @@ -55,15 +59,15 @@ GestureListenerManagerImpl::new; } - private static GestureListenerManagerImpl sInstanceForTesting; + private static @Nullable GestureListenerManagerImpl sInstanceForTesting; private final WebContentsImpl mWebContents; private final ObserverList<GestureStateListener> mListeners; private final RewindableIterator<GestureStateListener> mIterator; private final HashMap<GestureStateListener, Integer> mListenerFrequency; - private SelectionPopupControllerImpl mSelectionPopupController; + private @Nullable SelectionPopupControllerImpl mSelectionPopupController; private ViewAndroidDelegate mViewDelegate; - private InternalAccessDelegate mScrollDelegate; + private @Nullable InternalAccessDelegate mScrollDelegate; private final boolean mHidePastePopupOnGSB; private final boolean mResetGestureDetectionOnLosingFocus; @@ -81,14 +85,15 @@ /** Whether a fling scroll is currently active. */ private boolean mHasActiveFlingScroll; - private @RootScrollOffsetUpdateFrequency.EnumType Integer mRootScrollOffsetUpdateFrequency; + private @RootScrollOffsetUpdateFrequency.EnumType @Nullable Integer + mRootScrollOffsetUpdateFrequency; /** * @param webContents {@link WebContents} object. * @return {@link GestureListenerManager} object used for the give WebContents. * Creates one if not present. */ - public static GestureListenerManagerImpl fromWebContents(WebContents webContents) { + public static @Nullable GestureListenerManagerImpl fromWebContents(WebContents webContents) { if (sInstanceForTesting != null) return sInstanceForTesting; return ((WebContentsImpl) webContents) .getOrSetUserData( @@ -107,7 +112,7 @@ mListeners = new ObserverList<GestureStateListener>(); mIterator = mListeners.rewindableIterator(); mListenerFrequency = new HashMap<>(); - mViewDelegate = mWebContents.getViewAndroidDelegate(); + mViewDelegate = assumeNonNull(mWebContents.getViewAndroidDelegate()); mViewDelegate.addVerticalScrollDirectionChangeListener(this); WindowEventObserverManager.from(mWebContents).addObserver(this); mNativeGestureListenerManager = @@ -507,6 +512,7 @@ } private void notifyDelegateOfScrollChange(float scrollOffsetX, float scrollOffsetY) { + assumeNonNull(mScrollDelegate); RenderCoordinatesImpl rc = mWebContents.getRenderCoordinates(); mScrollDelegate.onScrollChanged( (int) rc.fromLocalCssToPix(scrollOffsetX), @@ -526,6 +532,7 @@ if (mSelectionPopupController == null) { mSelectionPopupController = SelectionPopupControllerImpl.fromWebContents(mWebContents); + assumeNonNull(mSelectionPopupController); } // Use the active scroll signal for hiding. The animation movement by // fling will naturally hide the ActionMode by invalidating its content
diff --git a/content/public/android/java/src/org/chromium/content/browser/GpuProcessCallback.java b/content/public/android/java/src/org/chromium/content/browser/GpuProcessCallback.java index 78b7ae2..ee8d601 100644 --- a/content/public/android/java/src/org/chromium/content/browser/GpuProcessCallback.java +++ b/content/public/android/java/src/org/chromium/content/browser/GpuProcessCallback.java
@@ -12,6 +12,7 @@ import org.jni_zero.NativeMethods; import org.chromium.base.UnguessableToken; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.common.IGpuProcessCallback; import org.chromium.content.common.InputTransferTokenWrapper; import org.chromium.content.common.SurfaceWrapper; @@ -19,6 +20,7 @@ import org.chromium.content_public.browser.SurfaceInputTransferHandlerMap; @JNINamespace("content") +@NullMarked class GpuProcessCallback extends IGpuProcessCallback.Stub { GpuProcessCallback() {}
diff --git a/content/public/android/java/src/org/chromium/content/browser/HostZoomMapImpl.java b/content/public/android/java/src/org/chromium/content/browser/HostZoomMapImpl.java index d6ab3b4..82aacfd 100644 --- a/content/public/android/java/src/org/chromium/content/browser/HostZoomMapImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/HostZoomMapImpl.java
@@ -16,6 +16,7 @@ import org.chromium.base.MathUtils; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.BrowserContextHandle; import org.chromium.content_public.browser.HostZoomMap; import org.chromium.content_public.browser.SiteZoomInfo; @@ -25,6 +26,7 @@ /** Implementations of {@link HostZoomMap} */ @JNINamespace("content") +@NullMarked public class HostZoomMapImpl { // Private constructor to prevent unwanted construction. private HostZoomMapImpl() {}
diff --git a/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java index 27921fb8..3320e78 100644 --- a/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/InterfaceRegistrarImpl.java
@@ -8,6 +8,8 @@ import org.jni_zero.JNINamespace; import org.chromium.blink.mojom.AndroidFontLookup; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.androidoverlay.AndroidOverlayProviderImpl; import org.chromium.content.browser.font.AndroidFontLookupImpl; import org.chromium.content_public.browser.InterfaceRegistrar; @@ -18,6 +20,7 @@ import org.chromium.services.service_manager.InterfaceRegistry; @JNINamespace("content") +@NullMarked class InterfaceRegistrarImpl { private static boolean sHasRegisteredRegistrars; @@ -80,7 +83,7 @@ private static class SingletonInterfaceRegistrar implements InterfaceRegistrar<Void> { @Override - public void registerInterfaces(InterfaceRegistry registry, Void v) { + public void registerInterfaces(InterfaceRegistry registry, @Nullable Void v) { registry.addInterface( AndroidOverlayProvider.MANAGER, new AndroidOverlayProviderImpl.Factory()); // TODO(avayvod): Register the PresentationService implementation here.
diff --git a/content/public/android/java/src/org/chromium/content/browser/JavascriptInjectorImpl.java b/content/public/android/java/src/org/chromium/content/browser/JavascriptInjectorImpl.java index 0d0259a..d1bc5f2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/JavascriptInjectorImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/JavascriptInjectorImpl.java
@@ -12,6 +12,8 @@ import org.chromium.base.UserData; import org.chromium.build.annotations.DoNotInline; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; import org.chromium.content_public.browser.JavascriptInjector; @@ -25,6 +27,7 @@ /** Implementation class of the interface {@link JavascriptInjector}. */ @JNINamespace("content") +@NullMarked public class JavascriptInjectorImpl implements JavascriptInjector, UserData { private static final class UserDataFactoryLazyHolder { private static final UserDataFactory<JavascriptInjectorImpl> INSTANCE = @@ -42,7 +45,7 @@ * @return {@link JavascriptInjector} object used for the give WebContents. Creates one if not * present. */ - public static JavascriptInjector fromWebContents(WebContents webContents) { + public static @Nullable JavascriptInjector fromWebContents(WebContents webContents) { JavascriptInjectorImpl javascriptInjector = ((WebContentsImpl) webContents) .getOrSetUserData( @@ -76,7 +79,9 @@ @Override public void addPossiblyUnsafeInterface( - Object object, String name, Class<? extends Annotation> requiredAnnotation) { + @Nullable Object object, + String name, + @Nullable Class<? extends Annotation> requiredAnnotation) { if (object == null) return; if (mNativePtr != 0) { @@ -112,7 +117,7 @@ JavascriptInjectorImpl caller, Object object, String name, - Class requiredAnnotation); + @Nullable Class requiredAnnotation); void removeInterface( long nativeJavascriptInjector, JavascriptInjectorImpl caller, String name);
diff --git a/content/public/android/java/src/org/chromium/content/browser/JavascriptInterface.java b/content/public/android/java/src/org/chromium/content/browser/JavascriptInterface.java index 9f6aa4d..e61f743 100644 --- a/content/public/android/java/src/org/chromium/content/browser/JavascriptInterface.java +++ b/content/public/android/java/src/org/chromium/content/browser/JavascriptInterface.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser; +import org.chromium.build.annotations.NullMarked; + import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -17,4 +19,5 @@ @SuppressWarnings("javadoc") @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD}) +@NullMarked public @interface JavascriptInterface {}
diff --git a/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java b/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java index ddfafdd..643de05a 100644 --- a/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java +++ b/content/public/android/java/src/org/chromium/content/browser/JoystickHandler.java
@@ -8,6 +8,7 @@ import android.view.MotionEvent; import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.input.ImeAdapterImpl; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; @@ -16,6 +17,7 @@ import org.chromium.ui.base.EventForwarder; /** Bridges content and joystick device event conversion and forwarding. */ +@NullMarked public class JoystickHandler implements ImeEventObserver, UserData { private final EventForwarder mEventForwarder; @@ -27,8 +29,12 @@ } public static JoystickHandler fromWebContents(WebContents webContents) { - return ((WebContentsImpl) webContents) - .getOrSetUserData(JoystickHandler.class, UserDataFactoryLazyHolder.INSTANCE); + JoystickHandler ret = + ((WebContentsImpl) webContents) + .getOrSetUserData( + JoystickHandler.class, UserDataFactoryLazyHolder.INSTANCE); + assert ret != null; + return ret; } /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java b/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java index 49849e4..87d7dab 100644 --- a/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java +++ b/content/public/android/java/src/org/chromium/content/browser/LauncherThread.java
@@ -14,9 +14,11 @@ import org.jni_zero.JNINamespace; import org.chromium.base.JavaHandlerThread; +import org.chromium.build.annotations.NullMarked; /** This is the process launcher thread. It is available before native library is loaded. */ @JNINamespace("content::android") +@NullMarked public final class LauncherThread { private static final JavaHandlerThread sThread = new JavaHandlerThread("Chrome_ProcessLauncherThread", Process.THREAD_PRIORITY_DEFAULT);
diff --git a/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java b/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java index 0973e71..edcbeb2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/MediaSessionImpl.java
@@ -4,13 +4,13 @@ package org.chromium.content.browser; -import androidx.annotation.Nullable; - import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.MediaSession; import org.chromium.content_public.browser.MediaSessionObserver; import org.chromium.content_public.browser.WebContents; @@ -28,6 +28,7 @@ * collection root. */ @JNINamespace("content") +@NullMarked public class MediaSessionImpl extends MediaSession { private long mNativeMediaSessionAndroid; @@ -35,11 +36,11 @@ private ObserverList.RewindableIterator<MediaSessionObserver> mObserversIterator; private boolean mIsControllable; - private Boolean mIsSuspended; - private MediaMetadata mMetadata; - private List<MediaImage> mImagesList; - private HashSet<Integer> mActionSet; - private MediaPosition mPosition; + private @Nullable Boolean mIsSuspended; + private @Nullable MediaMetadata mMetadata; + private @Nullable List<MediaImage> mImagesList; + private @Nullable HashSet<Integer> mActionSet; + private @Nullable MediaPosition mPosition; public static MediaSessionImpl fromWebContents(WebContents webContents) { return MediaSessionImplJni.get().getMediaSessionFromWebContents(webContents);
diff --git a/content/public/android/java/src/org/chromium/content/browser/MessagePayloadJni.java b/content/public/android/java/src/org/chromium/content/browser/MessagePayloadJni.java index 69df965..110d4e00 100644 --- a/content/public/android/java/src/org/chromium/content/browser/MessagePayloadJni.java +++ b/content/public/android/java/src/org/chromium/content/browser/MessagePayloadJni.java
@@ -4,23 +4,23 @@ package org.chromium.content.browser; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.MessagePayload; import org.chromium.content_public.browser.MessagePayloadType; /** Helper class to call MessagePayload methods from native. */ @JNINamespace("content") +@NullMarked final class MessagePayloadJni { private MessagePayloadJni() {} @MessagePayloadType @CalledByNative - private static int getType(@NonNull MessagePayload payload) { + private static int getType(MessagePayload payload) { return payload.getType(); } @@ -30,17 +30,17 @@ } @CalledByNative - private static String getAsString(@NonNull MessagePayload payload) { + private static @Nullable String getAsString(MessagePayload payload) { return payload.getAsString(); } @CalledByNative - private static MessagePayload createFromArrayBuffer(@NonNull byte[] arrayBuffer) { + private static MessagePayload createFromArrayBuffer(byte[] arrayBuffer) { return new MessagePayload(arrayBuffer); } @CalledByNative - private static byte[] getAsArrayBuffer(@NonNull MessagePayload payload) { + private static byte[] getAsArrayBuffer(MessagePayload payload) { return payload.getAsArrayBuffer(); } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/MotionEventSynthesizerImpl.java b/content/public/android/java/src/org/chromium/content/browser/MotionEventSynthesizerImpl.java index 256a06d3..88c3da34 100644 --- a/content/public/android/java/src/org/chromium/content/browser/MotionEventSynthesizerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/MotionEventSynthesizerImpl.java
@@ -10,9 +10,11 @@ import android.view.MotionEvent.PointerProperties; import android.view.View; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.MotionEventSynthesizer; /** Injects synthetic touch events. All the coordinates are of physical unit. */ +@NullMarked public class MotionEventSynthesizerImpl implements MotionEventSynthesizer { private static final int MAX_NUM_POINTERS = 16;
diff --git a/content/public/android/java/src/org/chromium/content/browser/NfcHost.java b/content/public/android/java/src/org/chromium/content/browser/NfcHost.java index 105a9d49..d6c5c4db 100644 --- a/content/public/android/java/src/org/chromium/content/browser/NfcHost.java +++ b/content/public/android/java/src/org/chromium/content/browser/NfcHost.java
@@ -10,12 +10,15 @@ import org.jni_zero.CalledByNative; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.WebContents; import org.chromium.ui.base.WindowAndroid; /** Tracks the Activiy for a given WebContents on behalf of a NFC instance that cannot talk * directly to WebContents. */ +@NullMarked class NfcHost implements WindowEventObserver { private static final SparseArray<NfcHost> sContextHostsMap = new SparseArray<NfcHost>(); @@ -27,7 +30,7 @@ // The callback that the NFC instance has registered for being notified when the Activity // changes. - private Callback<Activity> mCallback; + private @Nullable Callback<@Nullable Activity> mCallback; /** Provides access to NfcHost via context ID. */ public static NfcHost fromContextId(int contextId) { @@ -51,7 +54,7 @@ * track changes to the Activity associated with its context ID (i.e., the activity associated * with |mWebContents|). */ - public void trackActivityChanges(Callback<Activity> callback) { + public void trackActivityChanges(Callback<@Nullable Activity> callback) { // Only the main frame is allowed to access NFC // (https://w3c.github.io/web-nfc/#security-policies). The renderer enforces this by // dropping connection requests from nested frames. Therefore, this class should never see @@ -60,13 +63,13 @@ mCallback = callback; // This may be null in tests. - WindowEventObserverManager manager = WindowEventObserverManager.from(mWebContents); + WindowEventObserverManager manager = WindowEventObserverManager.maybeFrom(mWebContents); if (manager != null) { manager.addObserver(this); } WindowAndroid window = mWebContents.getTopLevelNativeWindow(); - mCallback.onResult(window != null ? window.getActivity().get() : null); + callback.onResult(window != null ? window.getActivity().get() : null); } /** @@ -76,7 +79,7 @@ mCallback = null; // This may be null in tests. - WindowEventObserverManager manager = WindowEventObserverManager.from(mWebContents); + WindowEventObserverManager manager = WindowEventObserverManager.maybeFrom(mWebContents); if (manager != null) { manager.removeObserver(this); } @@ -86,7 +89,7 @@ /** Updates the Activity associated with this instance. */ @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid) { Activity activity = null; if (newWindowAndroid != null) { activity = newWindowAndroid.getActivity().get();
diff --git a/content/public/android/java/src/org/chromium/content/browser/PopupController.java b/content/public/android/java/src/org/chromium/content/browser/PopupController.java index 1354808..96ab859 100644 --- a/content/public/android/java/src/org/chromium/content/browser/PopupController.java +++ b/content/public/android/java/src/org/chromium/content/browser/PopupController.java
@@ -4,7 +4,11 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.selection.SelectionPopupControllerImpl; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; @@ -14,6 +18,7 @@ import java.util.List; /** Controls all the popup views on content view. */ +@NullMarked public class PopupController implements UserData { /** Interface for popup views that expose a method for hiding itself. */ public interface HideablePopup { @@ -27,7 +32,7 @@ private final List<HideablePopup> mHideablePopups = new ArrayList<>(); - public static PopupController fromWebContents(WebContents webContents) { + public static @Nullable PopupController fromWebContents(WebContents webContents) { return ((WebContentsImpl) webContents) .getOrSetUserData(PopupController.class, UserDataFactoryLazyHolder.INSTANCE); } @@ -38,7 +43,7 @@ * Hide all popup views. * @param webContents {@link WebContents} for current content. */ - public static void hideAll(WebContents webContents) { + public static void hideAll(@Nullable WebContents webContents) { if (webContents == null) return; PopupController controller = PopupController.fromWebContents(webContents); if (controller != null) controller.hideAllPopups(); @@ -48,7 +53,7 @@ * Hide all popup views and clear text selection UI. * @param webContents {@link WebContents} for current content. */ - public static void hidePopupsAndClearSelection(WebContents webContents) { + public static void hidePopupsAndClearSelection(@Nullable WebContents webContents) { if (webContents == null) return; SelectionPopupControllerImpl controller = @@ -62,9 +67,11 @@ * @param webContents {@link WebContents} for current content. * @param popup {@link Hideable} popup view object. */ - public static void register(WebContents webContents, HideablePopup popup) { + public static void register(@Nullable WebContents webContents, HideablePopup popup) { if (webContents == null) return; - PopupController.fromWebContents(webContents).registerPopup(popup); + PopupController popupController = PopupController.fromWebContents(webContents); + assumeNonNull(popupController); + popupController.registerPopup(popup); } public void hideAllPopups() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java index 30df3ad..e8de0bc6 100644 --- a/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/RenderCoordinatesImpl.java
@@ -5,6 +5,8 @@ package org.chromium.content.browser; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content_public.browser.RenderCoordinates; import org.chromium.content_public.browser.WebContents; @@ -17,8 +19,9 @@ * * Unless stated otherwise, all coordinates are in CSS (document) coordinate space. */ +@NullMarked public class RenderCoordinatesImpl implements RenderCoordinates { - private static RenderCoordinatesImpl sInstanceForTesting; + private static @Nullable RenderCoordinatesImpl sInstanceForTesting; // Scroll offset from the native in CSS. private float mScrollXCss;
diff --git a/content/public/android/java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java b/content/public/android/java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java index b4a8cf6..98951a3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/RenderWidgetHostViewImpl.java
@@ -9,6 +9,8 @@ import org.jni_zero.NativeMethods; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.RenderWidgetHostView; /** @@ -17,11 +19,12 @@ * names). This object allows the browser to access and control the renderer's top level View. */ @JNINamespace("content") +@NullMarked public class RenderWidgetHostViewImpl implements RenderWidgetHostView { private long mNativeRenderWidgetHostView; // Remember the stack for clearing native the native stack for debugging use after destroy. - private Throwable mNativeDestroyThrowable; + private @Nullable Throwable mNativeDestroyThrowable; @CalledByNative private static RenderWidgetHostViewImpl create(long renderWidgetHostViewLong) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java index 58f8666..3624c56 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ScreenOrientationProviderImpl.java
@@ -11,8 +11,6 @@ import android.util.Pair; import android.view.Surface; -import androidx.annotation.Nullable; - import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; @@ -20,6 +18,8 @@ import org.chromium.base.ApplicationStatus; import org.chromium.base.ApplicationStatus.ActivityStateListener; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ScreenOrientationDelegate; import org.chromium.content_public.browser.ScreenOrientationProvider; import org.chromium.content_public.browser.WebContents; @@ -32,6 +32,7 @@ /** This is the implementation of the C++ counterpart ScreenOrientationProvider. */ @JNINamespace("content") +@NullMarked public class ScreenOrientationProviderImpl implements ActivityStateListener, ScreenOrientationProvider { private static class Holder { @@ -45,7 +46,7 @@ private static final boolean LOCK = true; private static final boolean UNLOCK = false; - private ScreenOrientationDelegate mDelegate; + private @Nullable ScreenOrientationDelegate mDelegate; /** * The keys of the map are the activities for which screen orientation are @@ -90,7 +91,7 @@ } @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid) { if (newWindowAndroid == null) return; if (mLockOrUnlock) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java b/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java index 4ef1bd4c..d302bbc 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java +++ b/content/public/android/java/src/org/chromium/content/browser/SpareChildConnection.java
@@ -7,17 +7,19 @@ import android.content.Context; import android.os.Bundle; -import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import org.chromium.base.Log; import org.chromium.base.process_launcher.ChildConnectionAllocator; import org.chromium.base.process_launcher.ChildProcessConnection; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * This class is used to create a single spare ChildProcessConnection (usually early on during * start-up) that can then later be retrieved when a connection to a service is needed. */ +@NullMarked public class SpareChildConnection { private static final String TAG = "SpareChildConn"; @@ -25,14 +27,14 @@ private final ChildConnectionAllocator mConnectionAllocator; // The actual spare connection. - private ChildProcessConnection mConnection; + private @Nullable ChildProcessConnection mConnection; // True when there is a spare connection and it is bound. private boolean mConnectionReady; // The callback that should be called when the connection becomes bound. Set when the connection // is retrieved. - private ChildProcessConnection.ServiceCallback mConnectionServiceCallback; + private ChildProcessConnection.@Nullable ServiceCallback mConnectionServiceCallback; /** Creates and binds a ChildProcessConnection using the specified parameters. */ public SpareChildConnection( @@ -84,9 +86,9 @@ * @return a connection that has been bound or is being bound if one was created with the same * allocator as the one provided, null otherwise. */ - public ChildProcessConnection getConnection( + public @Nullable ChildProcessConnection getConnection( ChildConnectionAllocator allocator, - @NonNull final ChildProcessConnection.ServiceCallback serviceCallback) { + final ChildProcessConnection.ServiceCallback serviceCallback) { assert LauncherThread.runningOnLauncherThread(); if (isEmpty() || mConnectionAllocator != allocator || mConnectionServiceCallback != null) { return null; @@ -128,7 +130,7 @@ } @VisibleForTesting - public ChildProcessConnection getConnection() { + public @Nullable ChildProcessConnection getConnection() { return mConnection; } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognitionImpl.java b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognitionImpl.java index 62e5d15..59d8e0e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SpeechRecognitionImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/SpeechRecognitionImpl.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.annotation.SuppressLint; import android.content.ComponentName; import android.content.Context; @@ -26,6 +28,8 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.PackageUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import org.chromium.content_public.browser.SpeechRecognition; import org.chromium.media.mojom.SpeechRecognitionErrorCode; @@ -36,6 +40,7 @@ /** Implementation of {@link SpeechRecognition}. */ @JNINamespace("content") +@NullMarked public class SpeechRecognitionImpl { private static final String TAG = "SpeechRecog"; @@ -55,11 +60,11 @@ // The speech recognition provider (if any) matching PROVIDER_PACKAGE_NAME and // PROVIDER_MIN_VERSION as selected by initialize(). - private static ComponentName sRecognitionProvider; + private static @Nullable ComponentName sRecognitionProvider; private final Intent mIntent; private final RecognitionListener mListener; - private SpeechRecognizer mRecognizer; + private @Nullable SpeechRecognizer mRecognizer; // Native pointer to C++ SpeechRecognizerImplAndroid. private long mNativeSpeechRecognizerImplAndroid; @@ -174,10 +179,11 @@ } ArrayList<String> list = - bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION); + assumeNonNull(bundle.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)); String[] results = list.toArray(new String[list.size()]); - float[] scores = bundle.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES); + float[] scores = + assumeNonNull(bundle.getFloatArray(SpeechRecognizer.CONFIDENCE_SCORES)); SpeechRecognitionImplJni.get() .onRecognitionResults( @@ -205,7 +211,7 @@ } /** Returns null if there is no Google LLC provided RecognitionService available on device. */ - private static ComponentName createRecognitionProvider() { + private static @Nullable ComponentName createRecognitionProvider() { if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.S || BuildInfo.getInstance().isAutomotive) { return getComponent(SSBG_PACKAGE_NAME, -1); @@ -215,7 +221,7 @@ } @SuppressLint("WrongConstant") - private static ComponentName getComponent(String packageName, int packageMinVersion) { + private static @Nullable ComponentName getComponent(String packageName, int packageMinVersion) { Context context = ContextUtils.getApplicationContext(); PackageManager pm = context.getPackageManager(); Intent intent = new Intent(RecognitionService.SERVICE_INTERFACE); @@ -283,6 +289,7 @@ } try { + assumeNonNull(mRecognizer); mRecognizer.destroy(); } catch (IllegalArgumentException e) { // Intentionally swallow exception. This incorrectly throws exception on some samsung
diff --git a/content/public/android/java/src/org/chromium/content/browser/SyntheticGestureTarget.java b/content/public/android/java/src/org/chromium/content/browser/SyntheticGestureTarget.java index e804b518..b50aa48 100644 --- a/content/public/android/java/src/org/chromium/content/browser/SyntheticGestureTarget.java +++ b/content/public/android/java/src/org/chromium/content/browser/SyntheticGestureTarget.java
@@ -9,8 +9,11 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; + /** Forwards synthetic events to MotionEventSynthesizer. Owned by its native. */ @JNINamespace("content") +@NullMarked public class SyntheticGestureTarget { private final MotionEventSynthesizerImpl mMotionEventSynthesizer;
diff --git a/content/public/android/java/src/org/chromium/content/browser/TtsPlatformImpl.java b/content/public/android/java/src/org/chromium/content/browser/TtsPlatformImpl.java index a48c3f37..3b37017 100644 --- a/content/public/android/java/src/org/chromium/content/browser/TtsPlatformImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/TtsPlatformImpl.java
@@ -9,8 +9,6 @@ import android.speech.tts.UtteranceProgressListener; import android.text.TextUtils; -import androidx.annotation.Nullable; - import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; @@ -21,6 +19,8 @@ import org.chromium.base.task.AsyncTask; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.ArrayList; import java.util.HashMap; @@ -38,6 +38,7 @@ * use PostTask.runOrPostTask(TaskTraits.UI_DEFAULT, ...) when calling back to C++. */ @JNINamespace("content") +@NullMarked class TtsPlatformImpl { private static class TtsVoice { private final String mName; @@ -230,6 +231,7 @@ } private List<TtsVoice> getVoices() { + assert mVoices != null; return mVoices; } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/ViewEventSinkImpl.java b/content/public/android/java/src/org/chromium/content/browser/ViewEventSinkImpl.java index 57b6d83b..ecde6463 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ViewEventSinkImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/ViewEventSinkImpl.java
@@ -4,10 +4,14 @@ package org.chromium.content.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.res.Configuration; import org.chromium.base.TraceEvent; import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; import org.chromium.content_public.browser.ViewEventSink; @@ -17,11 +21,12 @@ import org.chromium.ui.base.WindowAndroid.ActivityStateObserver; /** Implementation of the interface {@link ViewEventSink}. */ +@NullMarked public final class ViewEventSinkImpl implements ViewEventSink, ActivityStateObserver, UserData { private final WebContentsImpl mWebContents; // Whether the container view has view-level focus. - private Boolean mHasViewFocus; + private @Nullable Boolean mHasViewFocus; // This is used in place of window focus on the container view, as we can't actually use window // focus due to issues where content expects to be focused while a popup steals window focus. @@ -31,7 +36,7 @@ // Whether we consider this WebContents to have input focus. This is computed through // mHasViewFocus and mPaused. See the comments on mPaused for how this doesn't exactly match // Android's notion of input focus and why we need to do this. - private Boolean mHasInputFocus; + private @Nullable Boolean mHasInputFocus; private boolean mHideKeyboardOnBlur; private static final class UserDataFactoryLazyHolder { @@ -39,8 +44,12 @@ } public static ViewEventSinkImpl from(WebContents webContents) { - return ((WebContentsImpl) webContents) - .getOrSetUserData(ViewEventSinkImpl.class, UserDataFactoryLazyHolder.INSTANCE); + ViewEventSinkImpl ret = + ((WebContentsImpl) webContents) + .getOrSetUserData( + ViewEventSinkImpl.class, UserDataFactoryLazyHolder.INSTANCE); + assert ret != null; + return ret; } public ViewEventSinkImpl(WebContents webContents) { @@ -49,7 +58,10 @@ @Override public void setAccessDelegate(ViewEventSink.InternalAccessDelegate accessDelegate) { - GestureListenerManagerImpl.fromWebContents(mWebContents).setScrollDelegate(accessDelegate); + GestureListenerManagerImpl gestureManager = + GestureListenerManagerImpl.fromWebContents(mWebContents); + assumeNonNull(gestureManager); + gestureManager.setScrollDelegate(accessDelegate); ContentUiEventHandler.fromWebContents(mWebContents).setEventDelegate(accessDelegate); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/WindowEventObserver.java b/content/public/android/java/src/org/chromium/content/browser/WindowEventObserver.java index 0dff4410..f3ad50d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/WindowEventObserver.java +++ b/content/public/android/java/src/org/chromium/content/browser/WindowEventObserver.java
@@ -6,6 +6,8 @@ import android.content.res.Configuration; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver; @@ -13,6 +15,7 @@ * Interface to implement if Window-related events are needed. * This also includes an event for {@link WindowAndroid} (not Android window). */ +@NullMarked public interface WindowEventObserver extends DisplayAndroidObserver { /** This is called when the container view is attached to a window. */ default void onAttachedToWindow() {} @@ -26,7 +29,7 @@ default void onWindowFocusChanged(boolean gainFocus) {} /** Notifies observer when WindowAndroid is changed. */ - default void onWindowAndroidChanged(WindowAndroid newWindowAndroid) {} + default void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid) {} /** * @see View#onConfigurationChanged()
diff --git a/content/public/android/java/src/org/chromium/content/browser/WindowEventObserverManager.java b/content/public/android/java/src/org/chromium/content/browser/WindowEventObserverManager.java index faacee29b..d8deddf 100644 --- a/content/public/android/java/src/org/chromium/content/browser/WindowEventObserverManager.java +++ b/content/public/android/java/src/org/chromium/content/browser/WindowEventObserverManager.java
@@ -9,6 +9,8 @@ import org.chromium.base.ActivityState; import org.chromium.base.ObserverList; import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content.browser.webcontents.WebContentsImpl.UserDataFactory; import org.chromium.content_public.browser.WebContents; @@ -17,10 +19,11 @@ import org.chromium.ui.display.DisplayAndroid.DisplayAndroidObserver; /** Manages {@link WindowEventObserver} instances used for WebContents. */ +@NullMarked public final class WindowEventObserverManager implements DisplayAndroidObserver, UserData { private final ObserverList<WindowEventObserver> mWindowEventObservers = new ObserverList<>(); - private WindowAndroid mWindowAndroid; + private @Nullable WindowAndroid mWindowAndroid; private ViewEventSinkImpl mViewEventSink; private boolean mAttachedToWindow; @@ -34,6 +37,12 @@ } public static WindowEventObserverManager from(WebContents webContents) { + WindowEventObserverManager ret = maybeFrom(webContents); + assert ret != null; + return ret; + } + + public static @Nullable WindowEventObserverManager maybeFrom(WebContents webContents) { return ((WebContentsImpl) webContents) .getOrSetUserData( WindowEventObserverManager.class, UserDataFactoryLazyHolder.INSTANCE); @@ -96,7 +105,7 @@ * Called when {@link WindowAndroid} for WebContents is updated. * @param windowAndroid A new WindowAndroid object. */ - public void onWindowAndroidChanged(WindowAndroid windowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid windowAndroid) { if (windowAndroid == mWindowAndroid) return; removeUiObservers();
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java index 9a330e25..a35f6d1 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityActionAndEventTracker.java
@@ -7,9 +7,13 @@ import android.os.Bundle; import android.view.accessibility.AccessibilityEvent; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.LinkedList; /** Helper class for tracking accessibility actions and events for end-to-end tests. */ +@NullMarked public class AccessibilityActionAndEventTracker { private LinkedList<String> mEvents; private boolean mTestComplete; @@ -26,7 +30,7 @@ } } - public void addAction(int action, Bundle arguments) { + public void addAction(int action, @Nullable Bundle arguments) { // In rare cases there may be a lingering action, so only add if the test is not complete. if (!mTestComplete) { mEvents.add(actionToString(action, arguments)); @@ -72,7 +76,7 @@ * @param arguments Bundle arguments * @return String representation of the given action */ - private String actionToString(int action, Bundle arguments) { + private String actionToString(int action, @Nullable Bundle arguments) { StringBuilder builder = new StringBuilder(); builder.append(AccessibilityNodeInfoUtils.toString(action)); @@ -84,12 +88,8 @@ for (String key : arguments.keySet()) { argsBuilder.append(" {"); argsBuilder.append(key); - // In case of null values, check what the key returns. - if (arguments.get(key) != null) { - argsBuilder.append(arguments.get(key).toString()); - } else { - argsBuilder.append("null"); - } + // In case of null values, use "null". + argsBuilder.append(arguments.get(key)); argsBuilder.append("},"); } argsBuilder.append(" ]"); @@ -109,7 +109,7 @@ * @param event AccessibilityEvent event to get a string for * @return String representation of the given event */ - private static String eventToString(AccessibilityEvent event) { + private static @Nullable String eventToString(AccessibilityEvent event) { // Convert event type to a human readable String (except TYPE_WINDOW_CONTENT_CHANGED with no // CONTENT_CHANGE_TYPE_STATE_DESCRIPTION flag) if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityDelegate.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityDelegate.java index 7d903da4..eb686aff1 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityDelegate.java
@@ -8,8 +8,8 @@ import android.view.View; import android.view.ViewStructure; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.WebContents; /** @@ -17,12 +17,14 @@ * relying on {@link WebContents}. This enables {@link WebContentsAccessibilityImpl} to be used * without an instance of {@link WebContents}. */ +@NullMarked public interface AccessibilityDelegate { /** * @return The {@link View} that contains the content that accessibility is used for. */ View getContainerView(); + @Nullable String getProductVersion(); boolean isIncognito(); @@ -60,7 +62,7 @@ * @param nodeRect The Rect where the click action happened for. * @return Whether this event was handled. */ - default boolean performClick(Rect nodeRect) { + default boolean performClick(@Nullable Rect nodeRect) { return false; } @@ -70,7 +72,7 @@ * @return Whether this delegate performed the scroll. If false, the scroll request will be sent * to WebContents. */ - default boolean scrollToMakeNodeVisible(Rect nodeRect) { + default boolean scrollToMakeNodeVisible(@Nullable Rect nodeRect) { return false; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityEventDispatcher.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityEventDispatcher.java index 5a13c521..00522047 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityEventDispatcher.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityEventDispatcher.java
@@ -6,6 +6,9 @@ import android.os.SystemClock; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -15,6 +18,7 @@ * throttle and queue AccessibilityEvents that are sent in quick succession. This ensures we do * not overload the system and create lag by sending superfluous events. */ +@NullMarked public class AccessibilityEventDispatcher { // Maps an AccessibilityEvent type to a throttle delay in milliseconds. This is populated once // in the constructor. @@ -60,7 +64,7 @@ * * @param toRemove The Runnable to remove. */ - void removeRunnable(Runnable toRemove); + void removeRunnable(@Nullable Runnable toRemove); /** * Build an AccessibilityEvent for the given id and type. Requires a connection through the
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityHistogramRecorder.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityHistogramRecorder.java index 6bfb9e9c..79049a9e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityHistogramRecorder.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityHistogramRecorder.java
@@ -12,9 +12,11 @@ import org.chromium.base.MathUtils; import org.chromium.base.TraceEvent; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.accessibility.AccessibilityState; /** Helper class for recording UMA histograms of accessibility events */ +@NullMarked public class AccessibilityHistogramRecorder { // OnDemand AX Mode histogram values @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoBuilder.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoBuilder.java index 9cc7c47..59ef0e9 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoBuilder.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoBuilder.java
@@ -57,6 +57,8 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ContentFeatureList; import org.chromium.content_public.browser.ContentFeatureMap; @@ -70,6 +72,7 @@ * construct objects for the virtual view hierarchy to provide to the Android framework. */ @JNINamespace("content") +@NullMarked public class AccessibilityNodeInfoBuilder { // Constants defined for AccessibilityNodeInfo Bundle extras keys. These values are Chromium // specific, and allow Chromium-based browsers to provide richer information to AT. These @@ -150,9 +153,11 @@ int currentAccessibilityFocusId(); // The language tag String provided by the default Locale of the device. + @Nullable String getLanguageTag(); // Comma separate value of HTML tags that a given node can traverse by. + @Nullable String getSupportedHtmlTags(); // Set of coordinates for providing the correct size and scroll of the View.
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java index 8ae255ad..d6e2f72 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AccessibilityNodeInfoUtils.java
@@ -55,11 +55,15 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Utility class for common actions involving AccessibilityNodeInfo objects. */ +@NullMarked public class AccessibilityNodeInfoUtils { /** * Helper method to perform a custom toString on a given AccessibilityNodeInfo object. @@ -68,7 +72,8 @@ * @return String Custom toString result for the given object */ public static String toString( - AccessibilityNodeInfoCompat node, boolean includeScreenSizeDependentAttributes) { + @Nullable AccessibilityNodeInfoCompat node, + boolean includeScreenSizeDependentAttributes) { if (node == null) return ""; StringBuilder builder = new StringBuilder(); @@ -402,7 +407,8 @@ // Since every node has a few Bundle extras, and some are often empty, we will only // print non-null and not empty values. - if (extras.get(key) == null || extras.get(key).toString().isEmpty()) { + Object value = extras.get(key); + if (value == null || value.toString().isEmpty()) { continue; } @@ -431,11 +437,7 @@ } // Simplify the key String before printing to make test outputs easier to read. - bundleStrings.add( - key.replace("AccessibilityNodeInfo.", "") - + "=\"" - + extras.get(key).toString() - + "\""); + bundleStrings.add(key.replace("AccessibilityNodeInfo.", "") + "=\"" + value + "\""); } builder.append(TextUtils.join(", ", bundleStrings)).append("]");
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AssistDataBuilder.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AssistDataBuilder.java index ad34f9d..d9ccb7bc 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AssistDataBuilder.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AssistDataBuilder.java
@@ -14,6 +14,8 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; + import java.util.ArrayList; import java.util.Arrays; @@ -26,6 +28,7 @@ * provide to the Android framework. */ @JNINamespace("content") +@NullMarked public class AssistDataBuilder { private static final String CSS_DISPLAY_BUNDLE_KEY = "display"; private static final String METADATA_BUNDLE_KEY = "metadata";
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java index 8d60827..ce8cb8c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/AutoDisableAccessibilityHandler.java
@@ -8,11 +8,14 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; + /** * Helper class that handles the logic and state behind the "Auto Disable" accessibility feature. * Clients need to cancel/reset the timer based on their implementation (e.g. on a user action). * Only one timer per instance can exist. */ +@NullMarked public class AutoDisableAccessibilityHandler { /** Interface for any Client of this handler. */ interface Client {
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/ViewStructureBuilder.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/ViewStructureBuilder.java index d40c946..ea5a050 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/ViewStructureBuilder.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/ViewStructureBuilder.java
@@ -22,6 +22,7 @@ import org.jni_zero.CalledByNative; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.RenderCoordinatesImpl; import java.util.ArrayList; @@ -29,6 +30,7 @@ /** */ +@NullMarked public class ViewStructureBuilder { private RenderCoordinatesImpl mRenderCoordinates;
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityDelegate.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityDelegate.java index 1cf119f..57d92b41 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/WebContentsAccessibilityDelegate.java
@@ -4,14 +4,19 @@ package org.chromium.content.browser.accessibility; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.view.View; import android.view.ViewStructure; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.RenderCoordinatesImpl; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content_public.browser.WebContents; /** Implementation of {@link AccessibilityDelegate} based on {@link WebContents}. */ +@NullMarked public class WebContentsAccessibilityDelegate implements AccessibilityDelegate { private final WebContentsImpl mWebContents; private final AccessibilityCoordinatesImpl mAccessibilityCoordinatesImpl; @@ -23,11 +28,13 @@ @Override public View getContainerView() { - return mWebContents.getViewAndroidDelegate().getContainerView(); + View ret = assumeNonNull(mWebContents.getViewAndroidDelegate()).getContainerView(); + assert ret != null; + return ret; } @Override - public String getProductVersion() { + public @Nullable String getProductVersion() { return mWebContents.getProductVersion(); }
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 0abb9cc..e3ce5415 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
@@ -51,6 +51,7 @@ import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_PARAGRAPH; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.MOVEMENT_GRANULARITY_WORD; +import static org.chromium.build.NullUtil.assumeNonNull; import static org.chromium.content.browser.accessibility.AccessibilityNodeInfoBuilder.EXTRAS_DATA_REQUEST_IMAGE_DATA_KEY; import static org.chromium.content.browser.accessibility.AccessibilityNodeInfoBuilder.EXTRAS_KEY_URL; import static org.chromium.content_public.browser.ContentFeatureList.ACCESSIBILITY_MANAGE_BROADCAST_RECEIVER_ON_BACKGROUND; @@ -95,6 +96,8 @@ import org.chromium.base.task.TaskRunner; import org.chromium.base.task.TaskTraits; import org.chromium.build.BuildConfig; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.WindowEventObserver; import org.chromium.content.browser.WindowEventObserverManager; import org.chromium.content.browser.accessibility.AccessibilityDelegate.AccessibilityCoordinates; @@ -131,6 +134,7 @@ * non-Compat versions of these for any clients. */ @JNINamespace("content") +@NullMarked public class WebContentsAccessibilityImpl extends AccessibilityNodeProviderCompat implements WebContentsAccessibility, WindowEventObserver, @@ -159,7 +163,7 @@ private final AccessibilityDelegate mDelegate; protected AccessibilityManager mAccessibilityManager; protected Context mContext; - private final String mProductVersion; + private final @Nullable String mProductVersion; protected long mNativeObj; protected long mNativeAssistDataObj; private boolean mIsHovering; @@ -173,21 +177,21 @@ private int mAccessibilityFocusId; private int mLastAccessibilityFocusId = View.NO_ID; private int mSelectionNodeId; - private View mAutofillPopupView; - private CaptioningController mCaptioningController; + private @Nullable View mAutofillPopupView; + private @Nullable CaptioningController mCaptioningController; private boolean mIsCurrentlyExtendingSelection; private int mSelectionStart; private int mCursorIndex; - private String mSupportedHtmlElementTypes; + private @Nullable String mSupportedHtmlElementTypes; private final AccessibilityNodeInfoBuilder mAccessibilityNodeInfoBuilder; private boolean mHasFinishedLatestAccessibilitySnapshot; private boolean mPendingSetSequentialFocus; // Observer for WebContents, used to update state when |this| is shown/hidden. - private WebContentsObserver mWebContentsObserver; + private @Nullable WebContentsObserver mWebContentsObserver; // Tracker for all actions performed and events sent by this instance, used for testing. - private AccessibilityActionAndEventTracker mTracker; + private @Nullable AccessibilityActionAndEventTracker mTracker; // Helper object to track and record values relevant to histograms. private final AccessibilityHistogramRecorder mHistogramRecorder; @@ -212,7 +216,7 @@ // performAction. If false, all accessibility requests will be honored. When null, treat the // value as false, this is to differentiate between an initial value and a value set by a // client, since we assert the value is changed with each call to the setter. (Default: null). - private Boolean mIsObscuredByAnotherView; + private @Nullable Boolean mIsObscuredByAnotherView; // This array maps a given virtualViewId to an |AccessibilityNodeInfoCompat| for that view. We // use this to update a node quickly rather than building from one scratch each time. @@ -221,8 +225,8 @@ // This handles the dispatching of accessibility events. It acts as an intermediary where we can // apply throttling rules, delay event construction, etc. private final AccessibilityEventDispatcher mEventDispatcher; - private volatile String mSystemLanguageTag; - private BroadcastReceiver mBroadcastReceiver; + private volatile @Nullable String mSystemLanguageTag; + private @Nullable BroadcastReceiver mBroadcastReceiver; // Only un-register the broadcast receiver if this is true, otherwise it would result in a // crash. private volatile boolean mIsBroadcastReceiverRegistered; @@ -256,7 +260,7 @@ private static final UserDataFactory<WebContentsAccessibilityImpl> INSTANCE = new Factory(); } - public static WebContentsAccessibilityImpl fromWebContents(WebContents webContents) { + public static @Nullable WebContentsAccessibilityImpl fromWebContents(WebContents webContents) { return ((WebContentsImpl) webContents) .getOrSetUserData( WebContentsAccessibilityImpl.class, UserDataFactoryLazyHolder.INSTANCE); @@ -290,7 +294,7 @@ if (webContents != null) { mCaptioningController = new CaptioningController(webContents); WindowEventObserverManager.from(webContents).addObserver(this); - webContents.getViewAndroidDelegate().addObserver(this); + assumeNonNull(webContents.getViewAndroidDelegate()).addObserver(this); } mDelegate.setOnScrollPositionChangedCallback( () -> { @@ -324,12 +328,12 @@ } @Override - public String getLanguageTag() { + public @Nullable String getLanguageTag() { return mSystemLanguageTag; } @Override - public String getSupportedHtmlTags() { + public @Nullable String getSupportedHtmlTags() { return mSupportedHtmlElementTypes; } @@ -388,7 +392,7 @@ } @Override - public void removeRunnable(Runnable toRemove) { + public void removeRunnable(@Nullable Runnable toRemove) { mView.removeCallbacks(toRemove); } @@ -651,6 +655,7 @@ @Override public void onDetachedFromWindow() { + assumeNonNull(mCaptioningController); try (TraceEvent te = TraceEvent.scoped("WebContentsAccessibilityImpl.onDetachedFromWindow")) { mCaptioningController.stopListening(); @@ -694,6 +699,8 @@ @Override public void onAttachedToWindow() { + assumeNonNull(mCaptioningController); + assumeNonNull(mWebContentsObserver); TraceEvent.begin("WebContentsAccessibilityImpl.onAttachedToWindow"); // When webContents is non-null (e.g. not a Paint Preview), we will track usage stats. @@ -737,7 +744,7 @@ } @Override - public void onWindowAndroidChanged(WindowAndroid windowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid windowAndroid) { TraceEvent.begin("WebContentsAccessibilityImpl.onWindowAndroidChanged"); // When the WindowAndroid changes, we must update our Context reference to the new value. // We also need to remove all references to the previous context, which in this case would @@ -846,7 +853,7 @@ // AccessibilityNodeProvider @Override - public AccessibilityNodeProvider getAccessibilityNodeProvider() { + public @Nullable AccessibilityNodeProvider getAccessibilityNodeProvider() { // The |WebContentsAccessibilityImpl| class will rely on the Compat library, but we will // not require other parts of Chrome to do the same for simplicity, so unwrap the // |AccessibilityNodeProvider| object before returning. @@ -862,7 +869,7 @@ * * @return AccessibilityNodeProviderCompat (this) */ - public AccessibilityNodeProviderCompat getAccessibilityNodeProviderCompat() { + public @Nullable AccessibilityNodeProviderCompat getAccessibilityNodeProviderCompat() { if (shouldPreventNativeEngineUse()) return null; // If the Auto-Disable feature is on, and accessibility has been disabled, when the @@ -942,7 +949,7 @@ } @Override - public AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { + public @Nullable AccessibilityNodeInfoCompat createAccessibilityNodeInfo(int virtualViewId) { if (!isAccessibilityEnabled()) { return null; } @@ -1134,7 +1141,7 @@ } @Override - public boolean performAction(int virtualViewId, int action, Bundle arguments) { + public boolean performAction(int virtualViewId, int action, @Nullable Bundle arguments) { // We don't support any actions on the host view or nodes // that are not (any longer) in the tree. if (!isAccessibilityEnabled() @@ -1743,6 +1750,7 @@ if (WebContentsAccessibilityImplJni.get() .isAutofillPopupNode(mNativeObj, mAccessibilityFocusId)) { + assumeNonNull(mAutofillPopupView); mAutofillPopupView.requestFocus(); } @@ -1788,7 +1796,7 @@ mEventDispatcher.enqueueEvent(virtualViewId, eventType); } - private AccessibilityEvent buildAccessibilityEvent(int virtualViewId, int eventType) { + private @Nullable AccessibilityEvent buildAccessibilityEvent(int virtualViewId, int eventType) { // If accessibility is disabled, node is invalid, or we don't have any frame info, // then the virtual hierarchy doesn't exist in the view of the Android framework, // so should never send any events. @@ -2059,7 +2067,7 @@ } } - private Rect getAbsolutePositionForNode(int virtualViewId) { + private @Nullable Rect getAbsolutePositionForNode(int virtualViewId) { int[] coords = WebContentsAccessibilityImplJni.get() .getAbsolutePositionForNode(mNativeObj, virtualViewId); @@ -2124,7 +2132,7 @@ int virtualViewId, AccessibilityNodeInfoCompat info, String extraDataKey, - Bundle arguments) { + @Nullable Bundle arguments) { switch (extraDataKey) { case EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY: getExtraDataTextCharacterLocations(virtualViewId, info, arguments); @@ -2136,7 +2144,7 @@ } private void getExtraDataTextCharacterLocations( - int virtualViewId, AccessibilityNodeInfoCompat info, Bundle arguments) { + int virtualViewId, AccessibilityNodeInfoCompat info, @Nullable Bundle arguments) { // Arguments must be provided, but some debug tools may not so guard against this. if (arguments == null) return; @@ -2202,7 +2210,7 @@ // These two methods are only used for one-off accessibility tree snapshots. long initForAssistData( WebContentsAccessibilityImpl caller, - WebContents webContents, + @Nullable WebContents webContents, AssistDataBuilder builder); void requestAccessibilityTreeSnapshot( @@ -2223,7 +2231,7 @@ void disableRendererAccessibility(long nativeWebContentsAccessibilityAndroid); void reEnableRendererAccessibility( - long nativeWebContentsAccessibilityAndroid, WebContents webContents); + long nativeWebContentsAccessibilityAndroid, @Nullable WebContents webContents); void deleteEarly(long nativeWebContentsAccessibilityAndroid);
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningBridge.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningBridge.java index 92fe4a50..91c9ff7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningBridge.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningBridge.java
@@ -8,15 +8,18 @@ import android.view.accessibility.CaptioningManager; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Locale; /** Implementation of SystemCaptioningBridge that uses CaptioningManager. */ +@NullMarked public class CaptioningBridge extends CaptioningManager.CaptioningChangeListener implements SystemCaptioningBridge { private final CaptioningChangeDelegate mCaptioningChangeDelegate; private final CaptioningManager mCaptioningManager; - private static CaptioningBridge sInstance; + private static @Nullable CaptioningBridge sInstance; public static CaptioningBridge getInstance() { if (sInstance == null) { @@ -44,7 +47,7 @@ } @Override - public void onLocaleChanged(Locale locale) { + public void onLocaleChanged(@Nullable Locale locale) { mCaptioningChangeDelegate.onLocaleChanged(locale); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegate.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegate.java index 1d75f793..2a89083 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningChangeDelegate.java
@@ -10,6 +10,8 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.accessibility.captioning.SystemCaptioningBridge.SystemCaptioningBridgeListener; import java.lang.ref.WeakReference; @@ -26,6 +28,7 @@ * * <p>https://developer.android.com/reference/android/view/accessibility/CaptioningManager.CaptioningChangeListener.html */ +@NullMarked public class CaptioningChangeDelegate { private static final String FONT_STYLE_ITALIC = "italic"; @@ -33,13 +36,13 @@ private boolean mTextTracksEnabled; - private String mTextTrackBackgroundColor; - private String mTextTrackFontFamily; - private String mTextTrackFontStyle; - private String mTextTrackFontVariant; - private String mTextTrackTextColor; - private String mTextTrackTextShadow; - private String mTextTrackTextSize; + private @Nullable String mTextTrackBackgroundColor; + private @Nullable String mTextTrackFontFamily; + private @Nullable String mTextTrackFontStyle; + private @Nullable String mTextTrackFontVariant; + private @Nullable String mTextTrackTextColor; + private @Nullable String mTextTrackTextShadow; + private @Nullable String mTextTrackTextSize; // Using weak references to avoid preventing listeners from getting GC'ed. private final HashSet<WeakReference<SystemCaptioningBridgeListener>> mListeners = new HashSet<>(); @@ -63,7 +66,7 @@ /** * @see android.view.accessibility.CaptioningManager.CaptioningChangeListener#onLocaleChanged */ - public void onLocaleChanged(Locale locale) {} + public void onLocaleChanged(@Nullable Locale locale) {} /** * @see android.view.accessibility.CaptioningManager.CaptioningChangeListener#onUserStyleChanged @@ -98,7 +101,7 @@ * @return the CSS-friendly String representation of the * edge attribute. */ - public static String getShadowFromColorAndSystemEdge(String color, Integer type) { + public static String getShadowFromColorAndSystemEdge(String color, @Nullable Integer type) { String edgeShadow = ""; if (type != null) { switch (type) { @@ -135,7 +138,7 @@ * @param typeFace a Typeface object. * @return a string representation of the font family name. */ - public static String getFontFromSystemFont(Typeface typeFace) { + public static String getFontFromSystemFont(@Nullable Typeface typeFace) { if (typeFace == null) return ""; // The list of fonts are obtained from apps/Settings/res/values/arrays.xml @@ -159,7 +162,7 @@ * @param color The Integer color to convert * @return a "rgba" CSS style string */ - public static String androidColorToCssColor(Integer color) { + public static String androidColorToCssColor(@Nullable Integer color) { if (color == null) { return DEFAULT_CAPTIONING_PREF_VALUE; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningController.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningController.java index 7b56bf3e..c2d62bc 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningController.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningController.java
@@ -8,10 +8,12 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.WebContents; /** Sends notification when platform closed caption settings have changed. */ @JNINamespace("content") +@NullMarked public class CaptioningController implements SystemCaptioningBridge.SystemCaptioningBridgeListener { private SystemCaptioningBridge mSystemCaptioningBridge; private long mNativeCaptioningController;
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningStyle.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningStyle.java index e5545c6..0366c84 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningStyle.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/CaptioningStyle.java
@@ -7,6 +7,9 @@ import android.graphics.Typeface; import android.view.accessibility.CaptioningManager.CaptionStyle; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * This is an internal representation of the captioning. This class follows the paradigm that was * introduced in KitKat while not using that API directly so that it can be used everywhere. @@ -14,13 +17,14 @@ * <p>For information on CaptionStyle, introduced in KitKat, see: {@link} * https://developer.android.com/reference/android/view/accessibility/CaptioningManager.CaptionStyle.html */ +@NullMarked public class CaptioningStyle { - private Integer mBackgroundColor; - private Integer mEdgeColor; - private Integer mEdgeType; - private Integer mForegroundColor; - private Integer mWindowColor; - private Typeface mTypeface; + private @Nullable Integer mBackgroundColor; + private @Nullable Integer mEdgeColor; + private @Nullable Integer mEdgeType; + private @Nullable Integer mForegroundColor; + private @Nullable Integer mWindowColor; + private @Nullable Typeface mTypeface; /** * Construct a Chromium CaptioningStyle object. @@ -33,12 +37,12 @@ * @param typeFace Typeface of the CaptioningStyle */ public CaptioningStyle( - Integer backgroundColor, - Integer edgeColor, - Integer edgeType, - Integer foregroundColor, - Integer windowColor, - Typeface typeface) { + @Nullable Integer backgroundColor, + @Nullable Integer edgeColor, + @Nullable Integer edgeType, + @Nullable Integer foregroundColor, + @Nullable Integer windowColor, + @Nullable Typeface typeface) { mBackgroundColor = backgroundColor; mEdgeColor = edgeColor; mEdgeType = edgeType; @@ -51,7 +55,7 @@ * @return the background color specified by the platform if one was specified * otherwise returns null */ - public Integer getBackgroundColor() { + public @Nullable Integer getBackgroundColor() { return mBackgroundColor; } @@ -59,7 +63,7 @@ * @return the edge color specified by the platform if one was specified * otherwise returns null */ - public Integer getEdgeColor() { + public @Nullable Integer getEdgeColor() { return mEdgeColor; } @@ -67,7 +71,7 @@ * @return the edge type specified by the platform if one was specified * otherwise returns null */ - public Integer getEdgeType() { + public @Nullable Integer getEdgeType() { return mEdgeType; } @@ -75,7 +79,7 @@ * @return the foreground color specified by the platform if one was specified * otherwise returns null */ - public Integer getForegroundColor() { + public @Nullable Integer getForegroundColor() { return mForegroundColor; } @@ -83,7 +87,7 @@ * @return the window color specified by the platform if one was specified * otherwise returns null */ - public Integer getWindowColor() { + public @Nullable Integer getWindowColor() { return mWindowColor; } @@ -91,7 +95,7 @@ * @return the Typeface specified by the platform if one was specified * otherwise returns null */ - public Typeface getTypeface() { + public @Nullable Typeface getTypeface() { return mTypeface; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java index c2c90846..9723e86 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/SystemCaptioningBridge.java
@@ -4,7 +4,10 @@ package org.chromium.content.browser.accessibility.captioning; +import org.chromium.build.annotations.NullMarked; + /** Interface for platform dependent captioning bridges. */ +@NullMarked public interface SystemCaptioningBridge { /** Interface for listening to changed from SystemCaptioningBridge. */ public interface SystemCaptioningBridgeListener {
diff --git a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/TextTrackSettings.java b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/TextTrackSettings.java index 511c5674..4fdf33e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/TextTrackSettings.java +++ b/content/public/android/java/src/org/chromium/content/browser/accessibility/captioning/TextTrackSettings.java
@@ -4,22 +4,26 @@ package org.chromium.content.browser.accessibility.captioning; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.Objects; /** * Bundles the Closed Caption Track Settings and ensures that non-null * strings are used used by the recipient of this bundle. */ +@NullMarked public final class TextTrackSettings { private static final String DEFAULT_VALUE = ""; private boolean mTextTracksEnabled; - private String mTextTrackBackgroundColor; - private String mTextTrackFontFamily; - private String mTextTrackFontStyle; - private String mTextTrackFontVariant; - private String mTextTrackTextColor; - private String mTextTrackTextShadow; - private String mTextTrackTextSize; + private @Nullable String mTextTrackBackgroundColor; + private @Nullable String mTextTrackFontFamily; + private @Nullable String mTextTrackFontStyle; + private @Nullable String mTextTrackFontVariant; + private @Nullable String mTextTrackTextColor; + private @Nullable String mTextTrackTextShadow; + private @Nullable String mTextTrackTextSize; /** * Constructs a new TextTrackSettings object that will @@ -41,13 +45,13 @@ */ public TextTrackSettings( boolean textTracksEnabled, - String textTrackBackgroundColor, - String textTrackFontFamily, - String textTrackFontStyle, - String textTrackFontVariant, - String textTrackTextColor, - String textTrackTextShadow, - String textTrackTextSize) { + @Nullable String textTrackBackgroundColor, + @Nullable String textTrackFontFamily, + @Nullable String textTrackFontStyle, + @Nullable String textTrackFontVariant, + @Nullable String textTrackTextColor, + @Nullable String textTrackTextShadow, + @Nullable String textTrackTextSize) { mTextTracksEnabled = textTracksEnabled; mTextTrackBackgroundColor = textTrackBackgroundColor; mTextTrackFontFamily = textTrackFontFamily;
diff --git a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/AndroidOverlayProviderImpl.java b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/AndroidOverlayProviderImpl.java index 1dca3d6..439fa00 100644 --- a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/AndroidOverlayProviderImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/AndroidOverlayProviderImpl.java
@@ -8,6 +8,8 @@ import org.jni_zero.JNINamespace; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.media.mojom.AndroidOverlay; import org.chromium.media.mojom.AndroidOverlayClient; import org.chromium.media.mojom.AndroidOverlayConfig; @@ -21,6 +23,7 @@ * sense that all provider clients talk to the same instance in the browser. */ @JNINamespace("content") +@NullMarked public class AndroidOverlayProviderImpl implements AndroidOverlayProvider { private static final String TAG = "AndroidOverlayProvider"; @@ -102,7 +105,7 @@ /** Mojo factory. */ public static class Factory implements InterfaceFactory<AndroidOverlayProvider> { - private static AndroidOverlayProviderImpl sImpl; + private static @Nullable AndroidOverlayProviderImpl sImpl; public Factory() {}
diff --git a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayCore.java b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayCore.java index 8ebc6cc..edb0804 100644 --- a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayCore.java +++ b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayCore.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.androidoverlay; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.annotation.SuppressLint; import android.app.Dialog; import android.content.Context; @@ -15,6 +17,9 @@ import android.view.WindowManager; import org.chromium.base.Log; +import org.chromium.build.annotations.Initializer; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.gfx.mojom.Rect; import org.chromium.media.mojom.AndroidOverlayConfig; @@ -25,8 +30,11 @@ * Note that this does not implement AndroidOverlay; we just manage the android side of it. The * mojo interface is implemented by DialogOverlayImpl. */ +@NullMarked class DialogOverlayCore { private static final String TAG = "DSCore"; + // Android marks LayoutParams.token as @NonNull, but we null it out to mark state. + private static final IBinder INVALID_TOKEN = assumeNonNull(null); // Host interface, since we're on the wrong thread to talk to mojo, or anything else, really. public interface Host { @@ -38,15 +46,15 @@ void onOverlayDestroyed(); } - private Host mHost; + private @Nullable Host mHost; // When initialized via Init, we'll create mDialog. We'll clear it when we send // onOverlayDestroyed to the host. In general, when this is null, either we haven't been // initialized yet, or we've been torn down. It shouldn't be the case that anything calls // methods after construction but before |initialize()|, though. - private Dialog mDialog; + private @Nullable Dialog mDialog; - private Callbacks mDialogCallbacks; + private @Nullable Callbacks mDialogCallbacks; // Most recent layout parameters. private WindowManager.LayoutParams mLayoutParams; @@ -67,6 +75,7 @@ * @param host host interface, for sending messages that (probably) need to thread hop. * @param asPanel if true, then we'll be a panel. This is intended for tests only. */ + @Initializer public void initialize( Context context, AndroidOverlayConfig config, Host host, boolean asPanel) { mHost = host; @@ -88,7 +97,7 @@ // If we've not released the dialog yet, then do so. dismissDialogQuietly(); - mLayoutParams.token = null; + mLayoutParams.token = INVALID_TOKEN; // We don't bother to notify |mHost| that we've been destroyed; it told us. mHost = null; @@ -120,13 +129,13 @@ * client shouldn't call us before getting the surface anyway. */ public void layoutSurface(final Rect rect) { - if (mDialog == null || mLayoutParams.token == null) return; + if (mDialog == null || mLayoutParams.token == INVALID_TOKEN) return; // Note that it is important to not update the attributes if updating the layout params was // a no-op because it results in unnecessary re-layouts for the window. if (!copyRectToLayoutParams(rect)) return; - mDialog.getWindow().setAttributes(mLayoutParams); + assumeNonNull(mDialog.getWindow()).setAttributes(mLayoutParams); } /** @@ -158,10 +167,11 @@ public void surfaceRedrawNeeded(SurfaceHolder holder) {} } - public void onWindowToken(IBinder token) { + public void onWindowToken(@Nullable IBinder token) { if (mDialog == null || mHost == null) return; - if (token == null || (mLayoutParams.token != null && token != mLayoutParams.token)) { + if (token == null + || (mLayoutParams.token != INVALID_TOKEN && token != mLayoutParams.token)) { // We've lost the token, if we had one, or we got a new one. // Notify the client. mHost.onOverlayDestroyed(); @@ -177,9 +187,10 @@ // We have a token, so layout the dialog. mLayoutParams.token = token; - mDialog.getWindow().setAttributes(mLayoutParams); + Window window = assumeNonNull(mDialog.getWindow()); + window.setAttributes(mLayoutParams); mDialogCallbacks = new Callbacks(); - mDialog.getWindow().takeSurface(mDialogCallbacks); + window.takeSurface(mDialogCallbacks); mDialog.show(); // We don't notify the client here. We'll wait until the Android Surface is created. @@ -244,6 +255,7 @@ } /** Package-private to retrieve our current dialog for tests. */ + @Nullable Dialog getDialog() { return mDialog; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java index f670686c..80f1ff37 100644 --- a/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/androidoverlay/DialogOverlayImpl.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.androidoverlay; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.os.IBinder; import android.view.Surface; @@ -16,6 +18,8 @@ import org.chromium.base.ContextUtils; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.gfx.mojom.Rect; import org.chromium.media.mojom.AndroidOverlay; @@ -31,15 +35,16 @@ * from that thread from the UI thread. */ @JNINamespace("content") +@NullMarked public class DialogOverlayImpl implements AndroidOverlay, DialogOverlayCore.Host, ViewTreeObserver.OnPreDrawListener { private static final String TAG = "DialogOverlayImpl"; - private AndroidOverlayClient mClient; + private @Nullable AndroidOverlayClient mClient; // Runnable that we'll run when the overlay notifies us that it's been released. private Runnable mReleasedRunnable; - private DialogOverlayCore mDialogCore; + private @Nullable DialogOverlayCore mDialogCore; private long mNativeHandle; @@ -53,7 +58,7 @@ private Rect mLastRect; // Observes the container view to update our location. - private ViewTreeObserver mContainerViewViewTreeObserver; + private @Nullable ViewTreeObserver mContainerViewViewTreeObserver; private final AndroidOverlayConfig mConfig; private final boolean mAsPanel; @@ -62,7 +67,7 @@ // notify the client to cleanup tasks on the surface, because the surface may be // destroyed before SurfaceHolder.Callback2.surfaceDestroyed returns. private final Runnable mTearDownDialogOverlaysHandler = this::onOverlayDestroyed; - private WebContentsImpl mWebContents; + private @Nullable WebContentsImpl mWebContents; /** * @param client Mojo client interface. @@ -274,9 +279,8 @@ Context context = window.getContext().get(); if (ContextUtils.activityFromContext(context) == null) return; - mDialogCore = new DialogOverlayCore(); - mDialogCore.initialize(context, mConfig, DialogOverlayImpl.this, mAsPanel); + mDialogCore.initialize(assumeNonNull(context), mConfig, DialogOverlayImpl.this, mAsPanel); mDialogCore.onWindowToken(window.getWindowToken()); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/device_posture/DevicePosturePlatformProviderAndroid.java b/content/public/android/java/src/org/chromium/content/browser/device_posture/DevicePosturePlatformProviderAndroid.java index 7601abb..c4e66a7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/device_posture/DevicePosturePlatformProviderAndroid.java +++ b/content/public/android/java/src/org/chromium/content/browser/device_posture/DevicePosturePlatformProviderAndroid.java
@@ -7,7 +7,6 @@ import android.graphics.Rect; import android.os.Build; -import androidx.annotation.Nullable; import androidx.window.extensions.layout.DisplayFeature; import androidx.window.extensions.layout.FoldingFeature; import androidx.window.extensions.layout.WindowLayoutInfo; @@ -17,6 +16,8 @@ import org.jni_zero.NativeMethods; import org.chromium.blink_public.common.BlinkFeatures; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.WindowEventObserver; import org.chromium.content.browser.WindowEventObserverManager; import org.chromium.content.browser.webcontents.WebContentsImpl; @@ -30,10 +31,11 @@ * into the native class to relay them to blink. */ @JNINamespace("content") +@NullMarked public class DevicePosturePlatformProviderAndroid implements WindowEventObserver { private long mNativeDevicePosturePlatformProvider; private final WebContentsImpl mWebContents; - private WindowLayoutInfoListener mWindowLayoutInfoListener; + private @Nullable WindowLayoutInfoListener mWindowLayoutInfoListener; private boolean mListening; @CalledByNative @@ -49,7 +51,7 @@ assert webContents != null; mNativeDevicePosturePlatformProvider = nativeDevicePosturePlatformProvider; mWebContents = webContents; - WindowEventObserverManager manager = WindowEventObserverManager.from(mWebContents); + WindowEventObserverManager manager = WindowEventObserverManager.maybeFrom(mWebContents); if (manager != null) { manager.addObserver(this); } @@ -100,7 +102,7 @@ } @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid) { unObserveWindowLayoutListener(); // We were listening before the change, we should listen on the new window. if (mListening) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/device_posture/WindowLayoutInfoListener.java b/content/public/android/java/src/org/chromium/content/browser/device_posture/WindowLayoutInfoListener.java index 9ffcb19..71622a9 100644 --- a/content/public/android/java/src/org/chromium/content/browser/device_posture/WindowLayoutInfoListener.java +++ b/content/public/android/java/src/org/chromium/content/browser/device_posture/WindowLayoutInfoListener.java
@@ -4,10 +4,11 @@ package org.chromium.content.browser.device_posture; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.os.Build; -import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.window.extensions.core.util.function.Consumer; import androidx.window.extensions.layout.WindowLayoutInfo; @@ -16,6 +17,8 @@ import org.chromium.base.UnownedUserData; import org.chromium.base.UnownedUserDataHost; import org.chromium.base.UnownedUserDataKey; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; import org.chromium.window.WindowUtil; @@ -23,13 +26,14 @@ * WindowLayoutInfoListener This class listen for WindowLayoutInfo changes and inform the device * posture service with the values. */ +@NullMarked public class WindowLayoutInfoListener implements UnownedUserData { private static final UnownedUserDataKey<WindowLayoutInfoListener> KEY = new UnownedUserDataKey<>(WindowLayoutInfoListener.class); private final Consumer<WindowLayoutInfo> mWindowLayoutInfoChangedCallback; - private WindowAndroid mWindowAndroid; + private @Nullable WindowAndroid mWindowAndroid; private ObserverList<DevicePosturePlatformProviderAndroid> mObservers = new ObserverList<>(); - private WindowLayoutInfo mCurrentWindowLayoutInfo; + private @Nullable WindowLayoutInfo mCurrentWindowLayoutInfo; private WindowLayoutInfoListener(WindowAndroid window) { assert window != null; @@ -51,6 +55,7 @@ } public void addObserver(DevicePosturePlatformProviderAndroid observer) { + assumeNonNull(mWindowAndroid); assert !mObservers.hasObserver(observer); Context context = mWindowAndroid.getContext().get(); if (mObservers.isEmpty() && context != null) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java b/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java index 02dc5fe..ea60bf2 100644 --- a/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/font/AndroidFontLookupImpl.java
@@ -11,7 +11,6 @@ import android.os.ParcelFileDescriptor; import android.os.SystemClock; -import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import androidx.core.provider.FontRequest; import androidx.core.provider.FontsContractCompat; @@ -26,6 +25,8 @@ import org.chromium.base.task.SequencedTaskRunner; import org.chromium.base.task.TaskTraits; import org.chromium.blink.mojom.AndroidFontLookup; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import org.chromium.mojo.bindings.ExecutorFactory; import org.chromium.mojo.system.Core; @@ -47,6 +48,7 @@ * Implementation of the Mojo IPC interface that can be called from the renderer side to fetch fonts * from GMS Core. */ +@NullMarked public class AndroidFontLookupImpl implements AndroidFontLookup { private static final String TAG = "AndroidFontLookup"; private static final String READ_ONLY_MODE = "r"; @@ -137,7 +139,7 @@ */ @Override public void matchLocalFontByUniqueName( - @NonNull String fontUniqueName, MatchLocalFontByUniqueName_Response callback) { + String fontUniqueName, MatchLocalFontByUniqueName_Response callback) { long startTimeMs = SystemClock.elapsedRealtime(); // Get executor associated with the current thread for running Mojo callback. @@ -186,7 +188,7 @@ * * @param fontUniqueName The ICU case folded unique full font name to fetch. */ - private ReadOnlyFile fetchFontInBackground(String fontUniqueName, Core core) { + private @Nullable ReadOnlyFile fetchFontInBackground(String fontUniqueName, Core core) { ParcelFileDescriptor fileDescriptor = tryFetchFont(fontUniqueName); if (fileDescriptor == null) { // Avoid re-requesting this font in future. @@ -211,7 +213,7 @@ * @param fontUniqueName The ICU case folded unique full font name to fetch. * @return An opened font file descriptor, or null if the font file is not available. */ - private ParcelFileDescriptor tryFetchFont(String fontUniqueName) { + private @Nullable ParcelFileDescriptor tryFetchFont(String fontUniqueName) { ParcelFileDescriptor cachedFd = mFetchedFontCache.get(fontUniqueName); if (cachedFd != null) { try { @@ -346,7 +348,7 @@ * per process, see {@link ContextUtils#getApplicationContext()} for more info. */ @SuppressLint("StaticFieldLeak") - private static AndroidFontLookupImpl sImpl; + private static @Nullable AndroidFontLookupImpl sImpl; public Factory() {}
diff --git a/content/public/android/java/src/org/chromium/content/browser/font/FontsContractWrapper.java b/content/public/android/java/src/org/chromium/content/browser/font/FontsContractWrapper.java index 68fbd95..55ef222 100644 --- a/content/public/android/java/src/org/chromium/content/browser/font/FontsContractWrapper.java +++ b/content/public/android/java/src/org/chromium/content/browser/font/FontsContractWrapper.java
@@ -8,18 +8,18 @@ import android.content.pm.PackageManager.NameNotFoundException; import android.os.CancellationSignal; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.core.provider.FontRequest; import androidx.core.provider.FontsContractCompat; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** Wrapper around the {@link FontsContractCompat} static API to allow for mocking in tests. */ +@NullMarked public class FontsContractWrapper { - @NonNull + FontsContractCompat.FontFamilyResult fetchFonts( - @NonNull Context context, - @Nullable CancellationSignal cancellationSignal, - @NonNull FontRequest request) + Context context, @Nullable CancellationSignal cancellationSignal, FontRequest request) throws NameNotFoundException { return FontsContractCompat.fetchFonts(context, cancellationSignal, request); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java index ded0f22..df60f8b7 100644 --- a/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/framehost/NavigationControllerImpl.java
@@ -15,6 +15,8 @@ import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.AdditionalNavigationParams; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.NavigationController; @@ -32,6 +34,7 @@ @JNINamespace("content") // TODO(tedchoc): Remove the package restriction once this class moves to a non-public content // package whose visibility will be enforced via DEPS. +@NullMarked /* package */ class NavigationControllerImpl implements NavigationController { private static final String TAG = "NavigationController"; @@ -188,7 +191,7 @@ } @Override - public NavigationHandle loadUrl(LoadUrlParams params) { + public @Nullable NavigationHandle loadUrl(LoadUrlParams params) { NavigationHandle navigationHandle = null; if (mNativeNavigationControllerAndroid != 0) { String headers = @@ -252,7 +255,7 @@ } @Override - public NavigationHistory getNavigationHistory() { + public @Nullable NavigationHistory getNavigationHistory() { if (mNativeNavigationControllerAndroid == 0) return null; NavigationHistory history = new NavigationHistory(); int currentIndex = @@ -266,7 +269,8 @@ } @Override - public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit) { + public @Nullable NavigationHistory getDirectedNavigationHistory( + boolean isForward, int itemLimit) { if (mNativeNavigationControllerAndroid == 0) return null; NavigationHistory history = new NavigationHistory(); NavigationControllerImplJni.get() @@ -320,7 +324,7 @@ } @Override - public NavigationEntry getEntryAtIndex(int index) { + public @Nullable NavigationEntry getEntryAtIndex(int index) { if (mNativeNavigationControllerAndroid != 0) { return NavigationControllerImplJni.get() .getEntryAtIndex( @@ -333,7 +337,7 @@ } @Override - public NavigationEntry getVisibleEntry() { + public @Nullable NavigationEntry getVisibleEntry() { if (mNativeNavigationControllerAndroid != 0) { return NavigationControllerImplJni.get() .getVisibleEntry( @@ -344,7 +348,7 @@ } @Override - public NavigationEntry getPendingEntry() { + public @Nullable NavigationEntry getPendingEntry() { if (mNativeNavigationControllerAndroid != 0) { return NavigationControllerImplJni.get() .getPendingEntry( @@ -385,7 +389,7 @@ } @Override - public String getEntryExtraData(int index, String key) { + public @Nullable String getEntryExtraData(int index, String key) { if (mNativeNavigationControllerAndroid == 0) return null; return NavigationControllerImplJni.get() .getEntryExtraData( @@ -493,21 +497,21 @@ String url, int loadUrlType, int transitionType, - String referrerUrl, + @Nullable String referrerUrl, int referrerPolicy, int uaOverrideOption, - String extraHeaders, - ResourceRequestBody postData, - String baseUrlForDataUrl, - String virtualUrlForSpecialCases, - String dataUrlAsString, + @Nullable String extraHeaders, + @Nullable ResourceRequestBody postData, + @Nullable String baseUrlForDataUrl, + @Nullable String virtualUrlForSpecialCases, + @Nullable String dataUrlAsString, boolean canLoadLocalResources, boolean isRendererInitiated, boolean shouldReplaceCurrentEntry, - Origin initiatorOrigin, + @Nullable Origin initiatorOrigin, boolean hasUserGesture, boolean shouldClearHistoryList, - AdditionalNavigationParams additionalNavigationParams, + @Nullable AdditionalNavigationParams additionalNavigationParams, long inputStart, long navigationUIDataPtr, boolean isPdf);
diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostDelegate.java b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostDelegate.java index 7f1ffb29..b5893510 100644 --- a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostDelegate.java
@@ -4,10 +4,13 @@ package org.chromium.content.browser.framehost; +import org.chromium.build.annotations.NullMarked; + /** * The RenderFrameHost Java wrapper to allow communicating with the native RenderFrameHost object. * */ +@NullMarked public interface RenderFrameHostDelegate { // Mirrors callbacks for native RenderFrameHostDelegate. void renderFrameCreated(RenderFrameHostImpl host);
diff --git a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java index 1445aa09..aff6444 100644 --- a/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/framehost/RenderFrameHostImpl.java
@@ -4,8 +4,6 @@ package org.chromium.content.browser.framehost; -import androidx.annotation.Nullable; - import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; import org.jni_zero.JniType; @@ -14,6 +12,8 @@ import org.chromium.base.Callback; import org.chromium.base.UnguessableToken; import org.chromium.blink.mojom.AuthenticatorStatus; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.GlobalRenderFrameHostId; import org.chromium.content_public.browser.JavaScriptCallback; import org.chromium.content_public.browser.LifecycleState; @@ -33,6 +33,7 @@ * object. */ @JNINamespace("content") +@NullMarked public class RenderFrameHostImpl implements RenderFrameHost { private long mNativeRenderFrameHostAndroid; // mDelegate can be null. @@ -94,28 +95,25 @@ } @Override - @Nullable - public GURL getLastCommittedURL() { + public @Nullable GURL getLastCommittedURL() { if (mNativeRenderFrameHostAndroid == 0) return null; return RenderFrameHostImplJni.get().getLastCommittedURL(mNativeRenderFrameHostAndroid); } @Override - @Nullable - public Origin getLastCommittedOrigin() { + public @Nullable Origin getLastCommittedOrigin() { if (mNativeRenderFrameHostAndroid == 0) return null; return RenderFrameHostImplJni.get().getLastCommittedOrigin(mNativeRenderFrameHostAndroid); } @Override - @Nullable - public RenderFrameHost getMainFrame() { + public @Nullable RenderFrameHost getMainFrame() { if (mNativeRenderFrameHostAndroid == 0) return null; return RenderFrameHostImplJni.get().getMainFrame(mNativeRenderFrameHostAndroid); } @Override - public void getCanonicalUrlForSharing(Callback<GURL> callback) { + public void getCanonicalUrlForSharing(Callback<@Nullable GURL> callback) { if (mNativeRenderFrameHostAndroid == 0) { callback.onResult(null); return; @@ -125,7 +123,7 @@ } @Override - public List<RenderFrameHost> getAllRenderFrameHosts() { + public @Nullable List<RenderFrameHost> getAllRenderFrameHosts() { if (mNativeRenderFrameHostAndroid == 0) return null; return RenderFrameHostImplJni.get().getAllRenderFrameHosts(mNativeRenderFrameHostAndroid); } @@ -177,7 +175,7 @@ } @Override - public <I extends Interface, P extends Interface.Proxy> P getInterfaceToRendererFrame( + public <I extends Interface, P extends Interface.Proxy> @Nullable P getInterfaceToRendererFrame( Interface.Manager<I, P> manager) { if (mNativeRenderFrameHostAndroid == 0) return null; Pair<P, InterfaceRequest<I>> result = manager.getInterfaceRequest(CoreImpl.getInstance()); @@ -197,8 +195,7 @@ } /** Return the AndroidOverlay routing token for this RenderFrameHostImpl. */ - @Nullable - public UnguessableToken getAndroidOverlayRoutingToken() { + public @Nullable UnguessableToken getAndroidOverlayRoutingToken() { if (mNativeRenderFrameHostAndroid == 0) return null; return RenderFrameHostImplJni.get() .getAndroidOverlayRoutingToken(mNativeRenderFrameHostAndroid); @@ -303,7 +300,8 @@ RenderFrameHost getMainFrame(long nativeRenderFrameHostAndroid); - void getCanonicalUrlForSharing(long nativeRenderFrameHostAndroid, Callback<GURL> callback); + void getCanonicalUrlForSharing( + long nativeRenderFrameHostAndroid, Callback<@Nullable GURL> callback); @JniType("std::vector") List<RenderFrameHost> getAllRenderFrameHosts(long nativeRenderFrameHostAndroid); @@ -354,6 +352,6 @@ long nativeRenderFrameHostAndroid, String stript, int isolatedWorldId, - JavaScriptCallback callback); + @Nullable JavaScriptCallback callback); } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ChromiumBaseInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/ChromiumBaseInputConnection.java index 4b7fdc2..0d1910c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ChromiumBaseInputConnection.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ChromiumBaseInputConnection.java
@@ -12,10 +12,15 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** An interface to help switch between AdapterInputConnection and ChromiumInputConnection. */ +@NullMarked public interface ChromiumBaseInputConnection extends InputConnection { /** A factory class to create or reuse ChromiumBaseInputConnection. */ public interface Factory { + @Nullable ChromiumBaseInputConnection initializeAndGet( View view, ImeAdapterImpl imeAdapter,
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java b/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java index 78655b6..8e69893e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/CursorAnchorInfoController.java
@@ -12,10 +12,9 @@ import android.view.inputmethod.EditorBoundsInfo; import android.view.inputmethod.TextAppearanceInfo; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.chromium.blink.mojom.InputCursorAnchorInfo; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.InputMethodManagerWrapper; import org.chromium.gfx.mojom.Rect; @@ -24,6 +23,7 @@ * {@link InputMethodManager#updateCursorAnchorInfo(View, CursorAnchorInfo)}. This interface is also * used in unit tests to mock out {@link CursorAnchorInfo}. */ +@NullMarked final class CursorAnchorInfoController { /** An interface to mock out {@link View#getLocationOnScreen(int[])} for testing. */ public interface ViewDelegate { @@ -59,22 +59,21 @@ private float mInsertionMarkerTop; private float mInsertionMarkerBottom; - @Nullable private CursorAnchorInfo mLastCursorAnchorInfo; + private @Nullable CursorAnchorInfo mLastCursorAnchorInfo; // Data which has come through the new code path from the renderer. Eventually, other data like // visible line bounds, composition bounds and editor bounds will be removed in favour of this. - @Nullable private InputCursorAnchorInfo mInputCursorAnchorInfo; + private @Nullable InputCursorAnchorInfo mInputCursorAnchorInfo; - @NonNull private final Matrix mMatrix = new Matrix(); - @NonNull private final int[] mViewOrigin = new int[2]; + private final Matrix mMatrix = new Matrix(); + private final int[] mViewOrigin = new int[2]; - @NonNull private final CursorAnchorInfo.Builder mCursorAnchorInfoBuilder = new CursorAnchorInfo.Builder(); - @Nullable private InputMethodManagerWrapper mInputMethodManagerWrapper; - @Nullable private final ComposingTextDelegate mComposingTextDelegate; - @NonNull private final ViewDelegate mViewDelegate; + private @Nullable InputMethodManagerWrapper mInputMethodManagerWrapper; + private final ComposingTextDelegate mComposingTextDelegate; + private final ViewDelegate mViewDelegate; private CursorAnchorInfoController( InputMethodManagerWrapper inputMethodManagerWrapper, @@ -128,7 +127,7 @@ */ // TODO(crbug.com/40940885): Remove this method once it is no longer used. public void setBounds( - @Nullable float[] characterBounds, @Nullable float[] lineBounds, View view) { + float @Nullable [] characterBounds, float @Nullable [] lineBounds, View view) { if (!mIsEditable) return; boolean shouldUpdate = false; if (mInputCursorAnchorInfo == null) { @@ -171,7 +170,7 @@ * @param view The attached view. */ // TODO(crbug.com/40940885): Remove this method and call sites. - public void updateWithEditorBoundsInfo(EditorBoundsInfo editorBoundsInfo, View view) { + public void updateWithEditorBoundsInfo(@Nullable EditorBoundsInfo editorBoundsInfo, View view) { if (!mIsEditable) return; mLastCursorAnchorInfo = null; updateCursorAnchorInfo(view); @@ -196,7 +195,7 @@ float insertionMarkerHorizontal, float insertionMarkerTop, float insertionMarkerBottom, - @NonNull View view) { + View view) { if (!mIsEditable) return; // Reuse {@param #mViewOrigin} to avoid object creation, as this method is supposed to be
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java b/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java index b657528..a0cef0c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/DateTimeChooserAndroid.java
@@ -11,12 +11,15 @@ import org.jni_zero.NativeMethods; import org.chromium.base.ContextUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.picker.DateTimeSuggestion; import org.chromium.content.browser.picker.InputDialogContainer; import org.chromium.ui.base.WindowAndroid; /** Plumbing for the different date/time dialog adapters. */ @JNINamespace("content") +@NullMarked class DateTimeChooserAndroid { private long mNativeDateTimeChooserAndroid; private final InputDialogContainer mInputDialogContainer; @@ -69,7 +72,7 @@ } @CalledByNative - private static DateTimeChooserAndroid createDateTimeChooser( + private static @Nullable DateTimeChooserAndroid createDateTimeChooser( WindowAndroid windowAndroid, long nativeDateTimeChooserAndroid, int dialogType,
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java index 2977bfc1..4c205ac 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeAdapterImpl.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.input; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.content.res.Configuration; import android.graphics.Color; @@ -43,7 +45,6 @@ import android.view.inputmethod.SelectGesture; import android.view.inputmethod.SelectRangeGesture; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.view.inputmethod.EditorInfoCompat; @@ -62,6 +63,8 @@ import org.chromium.blink.mojom.StylusWritingGestureData; import org.chromium.blink_public.web.WebInputEventModifier; import org.chromium.blink_public.web.WebTextInputMode; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.GestureListenerManagerImpl; import org.chromium.content.browser.WindowEventObserver; import org.chromium.content.browser.WindowEventObserverManager; @@ -115,6 +118,7 @@ * lifetime of the object. */ @JNINamespace("content") +@NullMarked public class ImeAdapterImpl implements ImeAdapter, WindowEventObserver, UserData, InputMethodManagerWrapper.Delegate { private static final String TAG = "Ime"; @@ -129,12 +133,12 @@ private long mNativeImeAdapterAndroid; private InputMethodManagerWrapper mInputMethodManagerWrapper; - private ChromiumBaseInputConnection mInputConnection; - private ChromiumBaseInputConnection.Factory mInputConnectionFactory; + private @Nullable ChromiumBaseInputConnection mInputConnection; + private ChromiumBaseInputConnection.@Nullable Factory mInputConnectionFactory; // NOTE: This object will not be released by Android framework until the matching // ResultReceiver in the InputMethodService (IME app) gets gc'ed. - private ShowKeyboardResultReceiver mShowKeyboardResultReceiver; + private @Nullable ShowKeyboardResultReceiver mShowKeyboardResultReceiver; private final WebContentsImpl mWebContents; private ViewAndroidDelegate mViewDelegate; @@ -163,12 +167,15 @@ private int mLastSelectionStart; private int mLastSelectionEnd; + + @SuppressWarnings("NullAway.Init") private String mLastText; + private int mLastCompositionStart; private int mLastCompositionEnd; private boolean mRestartInputOnNextStateUpdate; // Do not access directly, use getStylusWritingImeCallback() instead. - private StylusWritingImeCallback mStylusWritingImeCallback; + private @Nullable StylusWritingImeCallback mStylusWritingImeCallback; private SparseArray<OngoingGesture> mOngoingGestures = new SparseArray<>(); // True if ImeAdapter is connected to render process. @@ -241,14 +248,17 @@ * @return {@link ImeAdapter} object. */ public static ImeAdapterImpl fromWebContents(WebContents webContents) { - return ((WebContentsImpl) webContents) - .getOrSetUserData(ImeAdapterImpl.class, UserDataFactoryLazyHolder.INSTANCE); + ImeAdapterImpl ret = + ((WebContentsImpl) webContents) + .getOrSetUserData(ImeAdapterImpl.class, UserDataFactoryLazyHolder.INSTANCE); + assert ret != null; + return ret; } /** Returns an instance of the default {@link InputMethodManagerWrapper} */ public static InputMethodManagerWrapper createDefaultInputMethodManagerWrapper( Context context, - WindowAndroid windowAndroid, + @Nullable WindowAndroid windowAndroid, InputMethodManagerWrapper.Delegate delegate) { return new InputMethodManagerWrapperImpl(context, windowAndroid, delegate); } @@ -259,8 +269,9 @@ */ public ImeAdapterImpl(WebContents webContents) { mWebContents = (WebContentsImpl) webContents; - mViewDelegate = mWebContents.getViewAndroidDelegate(); - assert mViewDelegate != null; + ViewAndroidDelegate viewDelegate = mWebContents.getViewAndroidDelegate(); + assert viewDelegate != null; + mViewDelegate = viewDelegate; // Use application context here to avoid leaking the activity context. InputMethodManagerWrapper wrapper = @@ -307,12 +318,12 @@ } @Override - public InputConnection getActiveInputConnection() { + public @Nullable InputConnection getActiveInputConnection() { return mInputConnection; } @Override - public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + public @Nullable InputConnection onCreateInputConnection(EditorInfo outAttrs) { boolean allowKeyboardLearning = mWebContents != null && !mWebContents.isIncognito(); InputConnection inputConnection = onCreateInputConnection(outAttrs, allowKeyboardLearning); @@ -419,7 +430,7 @@ * @see View#onCreateInputConnection(EditorInfo) * @param allowKeyboardLearning Whether to allow keyboard (IME) app to do personalized learning. */ - public ChromiumBaseInputConnection onCreateInputConnection( + public @Nullable ChromiumBaseInputConnection onCreateInputConnection( EditorInfo outAttrs, boolean allowKeyboardLearning) { // InputMethodService evaluates fullscreen mode even when the new input connection is // null. This makes sure IME doesn't enter fullscreen mode or open custom UI. @@ -473,7 +484,7 @@ return mInputConnection; } - private void setInputConnection(ChromiumBaseInputConnection inputConnection) { + private void setInputConnection(@Nullable ChromiumBaseInputConnection inputConnection) { if (mInputConnection == inputConnection) return; // The previous input connection might be waiting for state update. if (mInputConnection != null) mInputConnection.unblockOnUiThread(); @@ -498,27 +509,29 @@ mInputConnectionFactory = factory; } - ChromiumBaseInputConnection.Factory getInputConnectionFactoryForTest() { + ChromiumBaseInputConnection.@Nullable Factory getInputConnectionFactoryForTest() { return mInputConnectionFactory; } public void setTriggerDelayedOnCreateInputConnectionForTest(boolean trigger) { + assumeNonNull(mInputConnectionFactory); mInputConnectionFactory.setTriggerDelayedOnCreateInputConnection(trigger); } /** Get the current input connection for testing purposes. */ @VisibleForTesting @Override - public InputConnection getInputConnectionForTest() { + public @Nullable InputConnection getInputConnectionForTest() { return mInputConnection; } @VisibleForTesting @Override public void setComposingTextForTest(final CharSequence text, final int newCursorPosition) { - mInputConnection + ChromiumBaseInputConnection inputConnection = assumeNonNull(mInputConnection); + inputConnection .getHandler() - .post(() -> mInputConnection.setComposingText(text, newCursorPosition)); + .post(() -> inputConnection.setComposingText(text, newCursorPosition)); } private static int getModifiers(int metaState) { @@ -825,7 +838,7 @@ } @Override - public void onWindowAndroidChanged(WindowAndroid windowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid windowAndroid) { if (mInputMethodManagerWrapper != null) { mInputMethodManagerWrapper.onWindowAndroidChanged(windowAndroid); } @@ -912,7 +925,7 @@ } /** Update extracted text to input method manager. */ - void updateExtractedText(int token, ExtractedText extractedText) { + void updateExtractedText(int token, @Nullable ExtractedText extractedText) { mInputMethodManagerWrapper.updateExtractedText(getContainerView(), token, extractedText); } @@ -1615,7 +1628,7 @@ } @CalledByNative - private void setBounds(@Nullable float[] characterBounds, @Nullable float[] lineBounds) { + private void setBounds(float @Nullable [] characterBounds, float @Nullable [] lineBounds) { mCursorAnchorInfoController.setBounds(characterBounds, lineBounds, getContainerView()); } @@ -1634,7 +1647,7 @@ boolean sendKeyEvent( long nativeImeAdapterAndroid, ImeAdapterImpl caller, - KeyEvent event, + @Nullable KeyEvent event, int type, int modifiers, long timestampMs,
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ImeUtils.java b/content/public/android/java/src/org/chromium/content/browser/input/ImeUtils.java index d5cb7e2..e15f80da 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ImeUtils.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ImeUtils.java
@@ -18,12 +18,14 @@ import org.chromium.base.ThreadUtils; import org.chromium.blink_public.web.WebTextInputFlags; import org.chromium.blink_public.web.WebTextInputMode; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.base.ime.TextInputAction; import org.chromium.ui.base.ime.TextInputType; import java.util.Locale; /** Utilities for IME such as computing outAttrs, and dumping object information. */ +@NullMarked public class ImeUtils { /** * Compute {@link EditorInfo} based on the given parameters. This is needed for
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/InputMethodManagerWrapperImpl.java b/content/public/android/java/src/org/chromium/content/browser/input/InputMethodManagerWrapperImpl.java index e2ddc89..058e7c0 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/InputMethodManagerWrapperImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/InputMethodManagerWrapperImpl.java
@@ -18,6 +18,8 @@ import org.chromium.base.Log; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.InputMethodManagerWrapper; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.display.DisplayAndroid; @@ -25,20 +27,21 @@ import java.lang.ref.WeakReference; /** Wrapper around Android's InputMethodManager */ +@NullMarked public class InputMethodManagerWrapperImpl implements InputMethodManagerWrapper { private static final boolean DEBUG_LOGS = false; private static final String TAG = "IMM"; private final Context mContext; - private WindowAndroid mWindowAndroid; + private @Nullable WindowAndroid mWindowAndroid; private Delegate mDelegate; - private Runnable mPendingRunnableOnInputConnection; + private @Nullable Runnable mPendingRunnableOnInputConnection; public InputMethodManagerWrapperImpl( - Context context, WindowAndroid windowAndroid, Delegate delegate) { + Context context, @Nullable WindowAndroid windowAndroid, Delegate delegate) { if (DEBUG_LOGS) Log.i(TAG, "Constructor"); mContext = context; mWindowAndroid = windowAndroid; @@ -46,7 +49,7 @@ } @Override - public void onWindowAndroidChanged(WindowAndroid windowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid windowAndroid) { mWindowAndroid = windowAndroid; } @@ -63,7 +66,8 @@ * * @return The Activity. May return null if it fails. */ - private static Activity getActivityFromWindowAndroid(WindowAndroid windowAndroid) { + private static @Nullable Activity getActivityFromWindowAndroid( + @Nullable WindowAndroid windowAndroid) { if (windowAndroid == null) return null; // Unwrap this when we actually need it. WeakReference<Activity> weakRef = windowAndroid.getActivity(); @@ -149,7 +153,7 @@ } @Override - public boolean isActive(View view) { + public boolean isActive(@Nullable View view) { InputMethodManager manager = getInputMethodManager(); final boolean active = manager != null && manager.isActive(view); if (DEBUG_LOGS) Log.i(TAG, "isActive: " + active); @@ -158,7 +162,7 @@ @Override public boolean hideSoftInputFromWindow( - IBinder windowToken, int flags, ResultReceiver resultReceiver) { + IBinder windowToken, int flags, @Nullable ResultReceiver resultReceiver) { if (DEBUG_LOGS) Log.i(TAG, "hideSoftInputFromWindow"); mPendingRunnableOnInputConnection = null; InputMethodManager manager = getInputMethodManager(); @@ -198,7 +202,7 @@ @Override public void updateExtractedText( - View view, int token, android.view.inputmethod.ExtractedText text) { + View view, int token, android.view.inputmethod.@Nullable ExtractedText text) { if (DEBUG_LOGS) Log.d(TAG, "updateExtractedText"); InputMethodManager manager = getInputMethodManager(); if (manager == null) return;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/OngoingGesture.java b/content/public/android/java/src/org/chromium/content/browser/input/OngoingGesture.java index d637372..7c66a3f 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/OngoingGesture.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/OngoingGesture.java
@@ -4,12 +4,11 @@ package org.chromium.content.browser.input; -import androidx.annotation.Nullable; - import org.chromium.base.ThreadUtils; import org.chromium.base.metrics.RecordHistogram; import org.chromium.blink.mojom.HandwritingGestureResult; import org.chromium.blink.mojom.StylusWritingGestureData; +import org.chromium.build.annotations.NullMarked; import java.util.concurrent.Executor; import java.util.function.IntConsumer; @@ -18,19 +17,17 @@ * Stores data needed to process and record the result of a gesture, reporting it to Android. * Also records how long it took to process the gesture. */ +@NullMarked class OngoingGesture { private static int sLastId; private final int mId; - private final @Nullable StylusWritingGestureData mGestureData; - private final @Nullable Executor mExecutor; - private final @Nullable IntConsumer mConsumer; + private final StylusWritingGestureData mGestureData; + private final Executor mExecutor; + private final IntConsumer mConsumer; private final long mCreationTimestamp; - OngoingGesture( - @Nullable StylusWritingGestureData gestureData, - @Nullable Executor executor, - @Nullable IntConsumer consumer) { + OngoingGesture(StylusWritingGestureData gestureData, Executor executor, IntConsumer consumer) { ThreadUtils.assertOnUiThread(); mId = ++sLastId; mGestureData = gestureData; @@ -40,10 +37,6 @@ } void onGestureHandled(@HandwritingGestureResult.EnumType int result) { - if (mExecutor == null || mConsumer == null) { - logGestureResult(HandwritingGestureResult.UNKNOWN); - return; - } mExecutor.execute(() -> mConsumer.accept(result)); logGestureResult(result); @@ -63,7 +56,6 @@ return mId; } - @Nullable StylusWritingGestureData getGestureData() { return mGestureData; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/Range.java b/content/public/android/java/src/org/chromium/content/browser/input/Range.java index a4a0871..95c708b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/Range.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/Range.java
@@ -6,7 +6,10 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; + /** A simple class to set start and end in int type. */ +@NullMarked public class Range { private int mStart; // guaranteed to be smaller than or equal to mEnd private int mEnd;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopup.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopup.java index a3aa0fd..c02b683e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopup.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopup.java
@@ -13,6 +13,8 @@ import org.jni_zero.NativeMethods; import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.PopupController; import org.chromium.content.browser.PopupController.HideablePopup; import org.chromium.content.browser.WindowEventObserver; @@ -30,6 +32,7 @@ /** Handles the popup UI for the lt&;select> HTML tag support. */ @JNINamespace("content") +@NullMarked public class SelectPopup implements HideablePopup, ViewAndroidDelegate.ContainerViewObserver, @@ -49,7 +52,7 @@ private final WebContentsImpl mWebContents; private View mContainerView; - private Ui mPopupView; + private @Nullable Ui mPopupView; private long mNativeSelectPopup; private long mNativeSelectPopupSourceFrame; @@ -63,8 +66,11 @@ * @return {@link SelectPopup} object. */ public static SelectPopup fromWebContents(WebContents webContents) { - return ((WebContentsImpl) webContents) - .getOrSetUserData(SelectPopup.class, UserDataFactoryLazyHolder.INSTANCE); + SelectPopup ret = + ((WebContentsImpl) webContents) + .getOrSetUserData(SelectPopup.class, UserDataFactoryLazyHolder.INSTANCE); + assert ret != null; + return ret; } @CalledByNative @@ -113,7 +119,7 @@ // WindowEventObserver @Override - public void onWindowAndroidChanged(WindowAndroid windowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid windowAndroid) { close(); } @@ -199,7 +205,7 @@ * Notifies that items were selected in the currently showing select popup. * @param indices Array of indices of the selected items. */ - public void selectMenuItems(int[] indices) { + public void selectMenuItems(int @Nullable [] indices) { if (mNativeSelectPopup != 0) { SelectPopupJni.get() .selectMenuItems( @@ -218,6 +224,6 @@ long nativeSelectPopup, SelectPopup caller, long nativeSelectPopupSourceFrame, - int[] indices); + int @Nullable [] indices); } }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupAdapter.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupAdapter.java index a5196ba..f010ef3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupAdapter.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupAdapter.java
@@ -12,6 +12,9 @@ import android.widget.CheckedTextView; import android.widget.TextView; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.ArrayList; import java.util.List; @@ -19,6 +22,7 @@ * Select popup item adapter for SelectPopupDialog, used so we can disable * OPTION_GROUP items. */ +@NullMarked public class SelectPopupAdapter extends ArrayAdapter<SelectPopupItem> { // Holds the items of the select popup alert dialog list. private List<SelectPopupItem> mItems; @@ -46,8 +50,8 @@ } @Override - public View getView(int position, View convertView, ViewGroup parent) { - if (position < 0 || position >= getCount()) return null; + public View getView(int position, @Nullable View convertView, ViewGroup parent) { + assert position >= 0 && position < getCount(); convertView = super.getView(position, convertView, parent); ((TextView) convertView).setText(mItems.get(position).getLabel());
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java index dd720658..0fc1099c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDialog.java
@@ -16,6 +16,8 @@ import android.widget.ListView; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import org.chromium.content_public.browser.util.DialogTypeRecorder; import org.chromium.ui.widget.UiWidgetFactory; @@ -23,6 +25,7 @@ import java.util.List; /** Handles the popup dialog for the <select> HTML tag support. */ +@NullMarked public class SelectPopupDialog implements SelectPopup.Ui { private static final int[] SELECT_DIALOG_ATTRS = { R.attr.select_dialog_multichoice, R.attr.select_dialog_singlechoice @@ -30,13 +33,13 @@ // The dialog hosting the popup list view. private final AlertDialog mListBoxPopup; - private final Callback<int[]> mSelectionChangedCallback; + private final Callback<int @Nullable []> mSelectionChangedCallback; private boolean mSelectionNotified; public SelectPopupDialog( Context windowContext, - Callback<int[]> selectionChangedCallback, + Callback<int @Nullable []> selectionChangedCallback, List<SelectPopupItem> items, boolean multiple, int[] selected) { @@ -144,7 +147,7 @@ return indices; } - private void notifySelection(int[] indicies) { + private void notifySelection(int @Nullable [] indicies) { if (mSelectionNotified) return; mSelectionChangedCallback.onResult(indicies); mSelectionNotified = true;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java index 025dd026..52b347c 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupDropdown.java
@@ -4,12 +4,16 @@ package org.chromium.content.browser.input; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.view.View; import android.widget.AdapterView; import android.widget.PopupWindow; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.GestureListenerManager; import org.chromium.content_public.browser.GestureStateListener; import org.chromium.content_public.browser.WebContents; @@ -19,15 +23,16 @@ import java.util.List; /** Handles the dropdown popup for the <select> HTML tag support. */ +@NullMarked public class SelectPopupDropdown implements SelectPopup.Ui { - private final Callback<int[]> mSelectionChangedCallback; + private final Callback<int @Nullable []> mSelectionChangedCallback; private final DropdownPopupWindow mDropdownPopupWindow; private boolean mSelectionNotified; public SelectPopupDropdown( Context context, - Callback<int[]> selectionChangedCallback, + Callback<int @Nullable []> selectionChangedCallback, View anchorView, List<SelectPopupItem> items, int[] selected, @@ -60,18 +65,19 @@ notifySelection(null); } }); - GestureListenerManager.fromWebContents(webContents) - .addListener( - new GestureStateListener() { - @Override - public void onScrollStarted( - int scrollOffsetY, int scrollExtentY, boolean isDirectionUp) { - hide(true); - } - }); + GestureListenerManager gestureManager = GestureListenerManager.fromWebContents(webContents); + assumeNonNull(gestureManager); + gestureManager.addListener( + new GestureStateListener() { + @Override + public void onScrollStarted( + int scrollOffsetY, int scrollExtentY, boolean isDirectionUp) { + hide(true); + } + }); } - private void notifySelection(int[] indicies) { + private void notifySelection(int @Nullable [] indicies) { if (mSelectionNotified) return; mSelectionChangedCallback.onResult(indicies); mSelectionNotified = true;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java index e8015757..3bb95145 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SelectPopupItem.java
@@ -4,12 +4,14 @@ package org.chromium.content.browser.input; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.DropdownItemBase; /** * Select popup item containing the label, the type and the enabled state * of an item belonging to a select popup dialog. */ +@NullMarked public class SelectPopupItem extends DropdownItemBase { private final String mLabel; private final int mType;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SpellCheckPopupWindow.java b/content/public/android/java/src/org/chromium/content/browser/input/SpellCheckPopupWindow.java index 285f9143..ecb0a2a3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SpellCheckPopupWindow.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SpellCheckPopupWindow.java
@@ -8,12 +8,15 @@ import android.text.SpannableString; import android.view.View; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; /** * A subclass of SuggestionsPopupWindow to be used for showing suggestions from a spell check * marker. */ +@NullMarked public class SpellCheckPopupWindow extends SuggestionsPopupWindow { private String[] mSuggestions = new String[0]; @@ -26,7 +29,7 @@ public SpellCheckPopupWindow( Context context, TextSuggestionHost textSuggestionHost, - WindowAndroid windowAndroid, + @Nullable WindowAndroid windowAndroid, View parentView) { super(context, textSuggestionHost, windowAndroid, parentView); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/StylusGestureConverter.java b/content/public/android/java/src/org/chromium/content/browser/input/StylusGestureConverter.java index c83bd5b..378bab77 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/StylusGestureConverter.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/StylusGestureConverter.java
@@ -23,6 +23,8 @@ import org.chromium.blink.mojom.StylusWritingGestureAction; import org.chromium.blink.mojom.StylusWritingGestureData; import org.chromium.blink.mojom.StylusWritingGestureGranularity; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.gfx.mojom.Rect; import org.chromium.mojo_base.mojom.String16; @@ -33,6 +35,7 @@ * Converts stylus rich gestures from their Android representation to their Blink representation. */ @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) +@NullMarked public class StylusGestureConverter { // Should be kept in sync with StylusHandwritingGesture in tools/metrics/histograms/enums.xml. // These values are persisted to logs. Entries should not be renumbered and @@ -74,7 +77,7 @@ "InputMethod.StylusHandwriting.Gesture", gestureType, UmaGestureType.NUM_ENTRIES); } - public static StylusWritingGestureData createGestureData(HandwritingGesture gesture) { + public static @Nullable StylusWritingGestureData createGestureData(HandwritingGesture gesture) { if (gesture instanceof SelectGesture) { logGestureType(UmaGestureType.SELECT); return createGestureData((SelectGesture) gesture); @@ -269,10 +272,13 @@ * @return A String16 object which wraps an array of short integers for each character in the * string. */ - private static String16 toMojoString(String string) { - int len = string != null ? string.length() : 0; + private static String16 toMojoString(@Nullable String string) { + if (string == null) { + string = ""; + } + int len = string.length(); short[] data = new short[len]; - for (int i = 0; i < data.length; i++) { + for (int i = 0; i < len; i++) { data[i] = (short) string.charAt(i); } String16 mojoString = new String16();
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SuggestionInfo.java b/content/public/android/java/src/org/chromium/content/browser/input/SuggestionInfo.java index ddc3905..6a88933e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SuggestionInfo.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SuggestionInfo.java
@@ -6,11 +6,14 @@ import org.jni_zero.CalledByNative; +import org.chromium.build.annotations.NullMarked; + /** * Represents an entry in a text suggestion popup menu. Contains the information * necessary to display the menu entry and the information necessary to apply * the suggestion. */ +@NullMarked public class SuggestionInfo { private final int mMarkerTag; private final int mSuggestionIndex;
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/SuggestionsPopupWindow.java b/content/public/android/java/src/org/chromium/content/browser/input/SuggestionsPopupWindow.java index 7239988..9490291 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/SuggestionsPopupWindow.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/SuggestionsPopupWindow.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.input; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -24,11 +26,15 @@ import android.widget.TextView; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; +import org.chromium.build.annotations.RequiresNonNull; import org.chromium.content.R; import org.chromium.ui.UiUtils; import org.chromium.ui.base.WindowAndroid; /** Popup window that displays a menu for viewing and applying text replacement suggestions. */ +@NullMarked public abstract class SuggestionsPopupWindow implements OnItemClickListener, OnDismissListener, View.OnClickListener { private static final String ACTION_USER_DICTIONARY_INSERT = @@ -38,14 +44,14 @@ private final Context mContext; protected final TextSuggestionHost mTextSuggestionHost; private final View mParentView; - private WindowAndroid mWindowAndroid; + private @Nullable WindowAndroid mWindowAndroid; - private Activity mActivity; - private DisplayMetrics mDisplayMetrics; + private @Nullable Activity mActivity; + private @Nullable DisplayMetrics mDisplayMetrics; private PopupWindow mPopupWindow; private LinearLayout mContentView; - private String mHighlightedText; + private @Nullable String mHighlightedText; private int mNumberOfSuggestionsToUse; private TextView mAddToDictionaryButton; private TextView mDeleteButton; @@ -65,7 +71,7 @@ public SuggestionsPopupWindow( Context context, TextSuggestionHost textSuggestionHost, - WindowAndroid windowAndroid, + @Nullable WindowAndroid windowAndroid, View parentView) { mContext = context; mTextSuggestionHost = textSuggestionHost; @@ -171,7 +177,7 @@ } /** Used by TextSuggestionHost to update {@link WindowAndroid} to the current one. */ - public void updateWindowAndroid(WindowAndroid windowAndroid) { + public void updateWindowAndroid(@Nullable WindowAndroid windowAndroid) { mWindowAndroid = windowAndroid; } @@ -218,6 +224,7 @@ } } + @RequiresNonNull("mDisplayMetrics") private void measureContent() { // Make the menu wide enough to fit its widest item. int width = @@ -251,6 +258,7 @@ mNumberOfSuggestionsToUse = getSuggestionsCount(); mHighlightedText = highlightedText; + assumeNonNull(mWindowAndroid); mActivity = mWindowAndroid.getActivity().get(); // Note: the Activity can be null here if we're in a WebView that was created without // using an Activity. So all code in this class should handle this case.
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/TextInputState.java b/content/public/android/java/src/org/chromium/content/browser/input/TextInputState.java index e6e739a..ce0dfe8 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/TextInputState.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/TextInputState.java
@@ -11,12 +11,16 @@ import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.Locale; /** * An immutable class to contain text, selection range, composition range, and whether * it's single line or multiple lines that are being edited. */ +@NullMarked public class TextInputState { private final CharSequence mText; private final Range mSelection; @@ -83,7 +87,7 @@ return mReplyToRequest; } - public CharSequence getSelectedText() { + public @Nullable CharSequence getSelectedText() { if (mSelection.start() == mSelection.end()) return null; return TextUtils.substring(mText, mSelection.start(), mSelection.end()); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionHost.java b/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionHost.java index e73dd76..df6a8cc 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionHost.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionHost.java
@@ -13,6 +13,8 @@ import org.jni_zero.NativeMethods; import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.PopupController; import org.chromium.content.browser.PopupController.HideablePopup; import org.chromium.content.browser.WindowEventObserver; @@ -29,6 +31,7 @@ * the commands in that menu (by calling back to the C++ class). */ @JNINamespace("content") +@NullMarked public class TextSuggestionHost implements WindowEventObserver, HideablePopup, UserData { private long mNativeTextSuggestionHost; private final WebContentsImpl mWebContents; @@ -36,10 +39,10 @@ private final ViewAndroidDelegate mViewDelegate; private boolean mIsAttachedToWindow; - private WindowAndroid mWindowAndroid; + private @Nullable WindowAndroid mWindowAndroid; - private SpellCheckPopupWindow mSpellCheckPopupWindow; - private TextSuggestionsPopupWindow mTextSuggestionsPopupWindow; + private @Nullable SpellCheckPopupWindow mSpellCheckPopupWindow; + private @Nullable TextSuggestionsPopupWindow mTextSuggestionsPopupWindow; private static final class UserDataFactoryLazyHolder { private static final UserDataFactory<TextSuggestionHost> INSTANCE = TextSuggestionHost::new; @@ -53,8 +56,12 @@ */ @VisibleForTesting static TextSuggestionHost fromWebContents(WebContents webContents) { - return ((WebContentsImpl) webContents) - .getOrSetUserData(TextSuggestionHost.class, UserDataFactoryLazyHolder.INSTANCE); + TextSuggestionHost ret = + ((WebContentsImpl) webContents) + .getOrSetUserData( + TextSuggestionHost.class, UserDataFactoryLazyHolder.INSTANCE); + assert ret != null; + return ret; } @CalledByNative @@ -70,10 +77,14 @@ */ public TextSuggestionHost(WebContents webContents) { mWebContents = (WebContentsImpl) webContents; - mContext = mWebContents.getContext(); + Context context = mWebContents.getContext(); + assert context != null; + mContext = context; mWindowAndroid = mWebContents.getTopLevelNativeWindow(); - mViewDelegate = mWebContents.getViewAndroidDelegate(); - assert mViewDelegate != null; + + ViewAndroidDelegate viewDelegate = mWebContents.getViewAndroidDelegate(); + assert viewDelegate != null; + mViewDelegate = viewDelegate; PopupController.register(mWebContents, this); WindowEventObserverManager.from(mWebContents).addObserver(this); } @@ -89,7 +100,7 @@ // WindowEventObserver @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid) { mWindowAndroid = newWindowAndroid; if (mSpellCheckPopupWindow != null) { mSpellCheckPopupWindow.updateWindowAndroid(mWindowAndroid); @@ -199,7 +210,7 @@ } /** Tells Blink to remove spelling markers under all instances of the specified word. */ - public void onNewWordAddedToDictionary(String word) { + public void onNewWordAddedToDictionary(@Nullable String word) { TextSuggestionHostJni.get() .onNewWordAddedToDictionary( mNativeTextSuggestionHost, TextSuggestionHost.this, word); @@ -227,14 +238,14 @@ /** * @return The TextSuggestionsPopupWindow, if one exists. */ - public SuggestionsPopupWindow getTextSuggestionsPopupWindowForTesting() { + public @Nullable SuggestionsPopupWindow getTextSuggestionsPopupWindowForTesting() { return mTextSuggestionsPopupWindow; } /** * @return The SpellCheckPopupWindow, if one exists. */ - public SuggestionsPopupWindow getSpellCheckPopupWindowForTesting() { + public @Nullable SuggestionsPopupWindow getSpellCheckPopupWindowForTesting() { return mSpellCheckPopupWindow; } @@ -253,7 +264,9 @@ long nativeTextSuggestionHostAndroid, TextSuggestionHost caller); void onNewWordAddedToDictionary( - long nativeTextSuggestionHostAndroid, TextSuggestionHost caller, String word); + long nativeTextSuggestionHostAndroid, + TextSuggestionHost caller, + @Nullable String word); void onSuggestionMenuClosed( long nativeTextSuggestionHostAndroid, TextSuggestionHost caller);
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java b/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java index 13d3c42..95735fc6 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/TextSuggestionsPopupWindow.java
@@ -10,6 +10,8 @@ import android.text.style.TextAppearanceSpan; import android.view.View; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import org.chromium.ui.base.WindowAndroid; @@ -17,8 +19,11 @@ * A subclass of SuggestionsPopupWindow to be used for showing suggestions from one or more * SuggestionSpans. */ +@NullMarked public class TextSuggestionsPopupWindow extends SuggestionsPopupWindow { + @SuppressWarnings("NullAway.Init") private SuggestionInfo[] mSuggestionInfos; + private TextAppearanceSpan mPrefixSpan; private TextAppearanceSpan mSuffixSpan; @@ -31,7 +36,7 @@ public TextSuggestionsPopupWindow( Context context, TextSuggestionHost textSuggestionHost, - WindowAndroid windowAndroid, + @Nullable WindowAndroid windowAndroid, View parentView) { super(context, textSuggestionHost, windowAndroid, parentView);
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java index 801ef82..1a40b5b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnection.java
@@ -4,6 +4,7 @@ package org.chromium.content.browser.input; +import static org.chromium.build.NullUtil.assumeNonNull; import static org.chromium.content.browser.input.StylusGestureConverter.createGestureData; import android.annotation.SuppressLint; @@ -24,8 +25,6 @@ import android.view.inputmethod.InputConnection; import android.view.inputmethod.SurroundingText; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; @@ -35,6 +34,8 @@ import org.chromium.base.task.TaskTraits; import org.chromium.blink.mojom.StylusWritingGestureData; import org.chromium.blink_public.common.BlinkFeatures; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.ContentFeatureMap; import java.util.concurrent.BlockingQueue; @@ -53,6 +54,7 @@ * so 'extends' here should have no functional effect at all. See crbug.com/616334 for more * details. */ +@NullMarked class ThreadedInputConnection extends BaseInputConnection implements ChromiumBaseInputConnection { private static final String TAG = "Ime"; private static final boolean DEBUG_LOGS = false; @@ -100,7 +102,7 @@ // a bunch of new objects for each key stroke. private final BlockingQueue<TextInputState> mQueue = new LinkedBlockingQueue<>(); private int mPendingAccent; - private TextInputState mCachedTextInputState; + private @Nullable TextInputState mCachedTextInputState; private int mCurrentExtractedTextRequestToken; private boolean mShouldUpdateExtractedText; @@ -212,7 +214,7 @@ } } - private void updateSelection(TextInputState textInputState) { + private void updateSelection(@Nullable TextInputState textInputState) { if (textInputState == null) return; assertOnImeThread(); if (mNumNestedBatchEdits != 0) return; @@ -241,7 +243,7 @@ }); } - private TextInputState requestAndWaitForTextInputState() { + private @Nullable TextInputState requestAndWaitForTextInputState() { if (DEBUG_LOGS) Log.i(TAG, "requestAndWaitForTextInputState"); if (runningOnUiThread()) { Log.w(TAG, "InputConnection API is not called on IME thread. Returning cached result."); @@ -283,7 +285,7 @@ * Block until we get the expected state update. * @return TextInputState if we get it successfully. null otherwise. */ - private TextInputState blockAndGetStateUpdate() { + private @Nullable TextInputState blockAndGetStateUpdate() { if (DEBUG_LOGS) Log.i(TAG, "blockAndGetStateUpdate"); assertOnImeThread(); boolean shouldUpdateSelection = false; @@ -426,7 +428,7 @@ * @see InputConnection#getExtractedText(android.view.inputmethod.ExtractedTextRequest, int) */ @Override - public ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { + public @Nullable ExtractedText getExtractedText(ExtractedTextRequest request, int flags) { if (DEBUG_LOGS) Log.i(TAG, "getExtractedText"); assertOnImeThread(); mShouldUpdateExtractedText = (flags & GET_EXTRACTED_TEXT_MONITOR) > 0; @@ -437,7 +439,8 @@ return convertToExtractedText(textInputState); } - private ExtractedText convertToExtractedText(TextInputState textInputState) { + private @Nullable ExtractedText convertToExtractedText( + @Nullable TextInputState textInputState) { if (textInputState == null) return null; ExtractedText extractedText = new ExtractedText(); extractedText.text = textInputState.text(); @@ -658,7 +661,8 @@ @RequiresApi(Build.VERSION_CODES.S) @SuppressLint("Override") @Override - public SurroundingText getSurroundingText(int beforeLength, int afterLength, int flags) { + public @Nullable SurroundingText getSurroundingText( + int beforeLength, int afterLength, int flags) { if (DEBUG_LOGS) { Log.i(TAG, "getSurroundingText [%d %d %x]", beforeLength, afterLength, flags); } @@ -671,7 +675,7 @@ * @see InputConnection#getTextBeforeCursor(int, int) */ @Override - public CharSequence getTextBeforeCursor(int maxChars, int flags) { + public @Nullable CharSequence getTextBeforeCursor(int maxChars, int flags) { if (DEBUG_LOGS) Log.i(TAG, "getTextBeforeCursor [%d %x]", maxChars, flags); TextInputState textInputState = requestAndWaitForTextInputState(); if (textInputState == null) return null; @@ -682,7 +686,7 @@ * @see InputConnection#getTextAfterCursor(int, int) */ @Override - public CharSequence getTextAfterCursor(int maxChars, int flags) { + public @Nullable CharSequence getTextAfterCursor(int maxChars, int flags) { if (DEBUG_LOGS) Log.i(TAG, "getTextAfterCursor [%d %x]", maxChars, flags); TextInputState textInputState = requestAndWaitForTextInputState(); if (textInputState == null) return null; @@ -693,7 +697,7 @@ * @see InputConnection#getSelectedText(int) */ @Override - public CharSequence getSelectedText(int flags) { + public @Nullable CharSequence getSelectedText(int flags) { if (DEBUG_LOGS) Log.i(TAG, "getSelectedText [%x]", flags); TextInputState textInputState = requestAndWaitForTextInputState(); if (textInputState == null) return null; @@ -797,9 +801,11 @@ @Override @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE) public void performHandwritingGesture( - @NonNull HandwritingGesture gesture, + HandwritingGesture gesture, @Nullable Executor executor, @Nullable IntConsumer consumer) { + assumeNonNull(executor); + assumeNonNull(consumer); if (!ContentFeatureMap.isEnabled(BlinkFeatures.STYLUS_RICH_GESTURES)) { return; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java index e3a05f7..40ddadd 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionFactory.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.input; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.os.Handler; import android.os.HandlerThread; import android.view.View; @@ -13,12 +15,15 @@ import androidx.annotation.VisibleForTesting; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.InputMethodManagerWrapper; /** * A factory class for {@link ThreadedInputConnection}. The class also includes triggering * mechanism (hack) to run our InputConnection on non-UI thread. */ +@NullMarked public class ThreadedInputConnectionFactory implements ChromiumBaseInputConnection.Factory { private static final String TAG = "Ime"; private static final boolean DEBUG_LOGS = false; @@ -32,9 +37,9 @@ private static final int CHECK_REGISTER_RETRY = 1; private final InputMethodManagerWrapper mInputMethodManagerWrapper; - private ThreadedInputConnectionProxyView mProxyView; - private ThreadedInputConnection mThreadedInputConnection; - private CheckInvalidator mCheckInvalidator; + private @Nullable ThreadedInputConnectionProxyView mProxyView; + private @Nullable ThreadedInputConnection mThreadedInputConnection; + private @Nullable CheckInvalidator mCheckInvalidator; private boolean mReentrantTriggering; private boolean mTriggerDelayedOnCreateInputConnection; @@ -116,7 +121,7 @@ } @Override - public ThreadedInputConnection initializeAndGet( + public @Nullable ThreadedInputConnection initializeAndGet( View view, ImeAdapterImpl imeAdapter, int inputType, @@ -192,6 +197,7 @@ new Runnable() { @Override public void run() { + assumeNonNull(mProxyView); // This is a hack to make InputMethodManager believe that the proxy view // now has a focus. As a result, InputMethodManager will think that // mProxyView is focused, and will call getHandler() of the view when @@ -217,7 +223,7 @@ public void run() { postCheckRegisterResultOnUiThread( view, - mCheckInvalidator, + assumeNonNull(mCheckInvalidator), CHECK_REGISTER_RETRY); } }); @@ -244,13 +250,13 @@ postDelayed(view, r, 1000); mFocusState = FocusState.NOT_APPLICABLE; } else { - view.getHandler().post(r); + assumeNonNull(view.getHandler()).post(r); } } @VisibleForTesting protected void postDelayed(View view, Runnable r, long delayMs) { - view.getHandler().postDelayed(r, delayMs); + assumeNonNull(view.getHandler()).postDelayed(r, delayMs); } // Note that this function is called both from IME thread and UI thread.
diff --git a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java index 0113e75f..2f7cfd8e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java +++ b/content/public/android/java/src/org/chromium/content/browser/input/ThreadedInputConnectionProxyView.java
@@ -14,11 +14,14 @@ import org.chromium.base.Log; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; /** This is a fake View that is only exposed to InputMethodManager. */ +@NullMarked public class ThreadedInputConnectionProxyView extends View { private static final String TAG = "ImeProxyView"; private static final boolean DEBUG_LOGS = false; @@ -110,7 +113,7 @@ } @Override - public View getRootView() { + public @Nullable View getRootView() { // Returning a null here matches mCurRootView being null value in InputMethodManager, // which represents that the current focused window is not IME target window. // In this case, you are still able to type. @@ -134,7 +137,7 @@ } @Override - public IBinder getWindowToken() { + public @Nullable IBinder getWindowToken() { if (DEBUG_LOGS) Log.w(TAG, "getWindowToken"); return mWindowToken.get(); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/DateDialogNormalizer.java b/content/public/android/java/src/org/chromium/content/browser/picker/DateDialogNormalizer.java index b021716..d13a9b8 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/DateDialogNormalizer.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/DateDialogNormalizer.java
@@ -7,12 +7,15 @@ import android.widget.DatePicker; import android.widget.DatePicker.OnDateChangedListener; +import org.chromium.build.annotations.NullMarked; + import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.TimeZone; /** Sets the current, min, and max values on the given DatePicker. */ +@NullMarked public class DateDialogNormalizer { /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/DatePickerDialogCompat.java b/content/public/android/java/src/org/chromium/content/browser/picker/DatePickerDialogCompat.java index 3a2b52bd..f7835091 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/DatePickerDialogCompat.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/DatePickerDialogCompat.java
@@ -9,12 +9,15 @@ import android.content.DialogInterface; import android.widget.DatePicker; +import org.chromium.build.annotations.NullMarked; + /** * The behavior of the DatePickerDialog changed after JellyBean so it now calls * OndateSetListener.onDateSet() even when the dialog is dismissed (e.g. back button, tap * outside). This class will call the listener instead of the DatePickerDialog only when the * BUTTON_POSITIVE has been clicked. */ +@NullMarked class DatePickerDialogCompat extends DatePickerDialog { private final OnDateSetListener mCallBack;
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/DateTimePickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/picker/DateTimePickerDialog.java index 16a718d7..1868fa0 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/DateTimePickerDialog.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/DateTimePickerDialog.java
@@ -17,6 +17,7 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.R; import java.util.Calendar; @@ -27,6 +28,7 @@ * A dialog that allows the user to choose a date and time. Shown for HTML form input elements * with type "datetime" or "datetime-local". */ +@NullMarked public class DateTimePickerDialog extends AlertDialog implements OnClickListener, OnDateChangedListener, OnTimeChangedListener { private final DatePicker mDatePicker;
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestion.java b/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestion.java index 3d54fbc1..6a5a5e0 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestion.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestion.java
@@ -6,10 +6,13 @@ import android.text.TextUtils; +import org.chromium.build.annotations.NullMarked; + /** * Date/time suggestion container used to store information for each suggestion that will be shown * in the suggestion list dialog. Keep in sync with date_time_suggestion.h. */ +@NullMarked public class DateTimeSuggestion { private final double mValue; private final String mLocalizedValue;
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestionListAdapter.java b/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestionListAdapter.java index c017108..da9fb423 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestionListAdapter.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/DateTimeSuggestionListAdapter.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.picker; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.view.LayoutInflater; import android.view.View; @@ -11,11 +13,14 @@ import android.widget.ArrayAdapter; import android.widget.TextView; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import java.util.List; /** Date/time suggestion adapter for the suggestion dialog. */ +@NullMarked class DateTimeSuggestionListAdapter extends ArrayAdapter<DateTimeSuggestion> { private final Context mContext; @@ -25,9 +30,11 @@ } @Override - public View getView(int position, View convertView, ViewGroup parent) { - View layout = convertView; - if (convertView == null) { + public View getView(int position, @Nullable View convertView, ViewGroup parent) { + View layout; + if (convertView != null) { + layout = convertView; + } else { LayoutInflater inflater = LayoutInflater.from(mContext); layout = inflater.inflate(R.layout.date_time_suggestion, parent, false); } @@ -38,8 +45,9 @@ labelView.setText(mContext.getText(R.string.date_picker_dialog_other_button_label)); sublabelView.setText(""); } else { - labelView.setText(getItem(position).localizedValue()); - sublabelView.setText(getItem(position).label()); + DateTimeSuggestion item = assumeNonNull(getItem(position)); + labelView.setText(item.localizedValue()); + sublabelView.setText(item.label()); } return layout;
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/InputDialogContainer.java b/content/public/android/java/src/org/chromium/content/browser/picker/InputDialogContainer.java index 01df480..4463be1e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/InputDialogContainer.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/InputDialogContainer.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.picker; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.app.AlertDialog; import android.app.DatePickerDialog.OnDateSetListener; import android.app.TimePickerDialog; @@ -19,6 +21,9 @@ import android.widget.TimePicker; import org.chromium.base.Log; +import org.chromium.build.annotations.EnsuresNonNullIf; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import org.chromium.content.browser.picker.DateTimePickerDialog.OnDateTimeSetListener; import org.chromium.content.browser.picker.MultiFieldTimePickerDialog.OnMultiFieldTimeSetListener; @@ -33,6 +38,7 @@ import java.util.concurrent.TimeUnit; /** Opens the appropriate date/time picker dialog for the given dialog type. */ +@NullMarked public class InputDialogContainer { private static final String TAG = "InputDialogContainer"; @@ -48,7 +54,7 @@ // Prevents sending two notifications (from onClick and from onDismiss) private boolean mDialogAlreadyDismissed; - private AlertDialog mDialog; + private @Nullable AlertDialog mDialog; private final InputActionDelegate mInputActionDelegate; public static boolean isDialogInputType(int type) { @@ -180,7 +186,8 @@ dismissDialog(); showPickerDialog(dialogType, dialogValue, min, max, step); } else { - double suggestionValue = adapter.getItem(position).value(); + double suggestionValue = + assumeNonNull(adapter.getItem(position)).value(); mInputActionDelegate.replaceDateTime(suggestionValue); dismissDialog(); mDialogAlreadyDismissed = true; @@ -262,20 +269,27 @@ int stepTime = (int) step; + AlertDialog dialog; if (dialogType == TextInputType.DATE) { - DatePickerDialogCompat dialog = + DatePickerDialogCompat dateDialog = new DatePickerDialogCompat( mContext, new DateListener(dialogType), year, month, monthDay); DateDialogNormalizer.normalize( - dialog.getDatePicker(), dialog, year, month, monthDay, (long) min, (long) max); + dateDialog.getDatePicker(), + dateDialog, + year, + month, + monthDay, + (long) min, + (long) max); - dialog.setTitle(mContext.getText(R.string.date_picker_dialog_title)); - mDialog = dialog; + dateDialog.setTitle(mContext.getText(R.string.date_picker_dialog_title)); + dialog = dateDialog; } else if (dialogType == TextInputType.TIME) { // If user doesn't need to set seconds and milliseconds, show the default clock style // time picker dialog. Otherwise, show a full spinner style time picker. if (stepTime < 0 || stepTime >= 60000 /* milliseconds in a minute */) { - mDialog = + dialog = new TimePickerDialog( mContext, new TimeListener(dialogType), @@ -283,7 +297,7 @@ minute, DateFormat.is24HourFormat(mContext)); } else { - mDialog = + dialog = new MultiFieldTimePickerDialog( mContext, /* theme= */ 0, @@ -299,7 +313,7 @@ } } else if (dialogType == TextInputType.DATE_TIME || dialogType == TextInputType.DATE_TIME_LOCAL) { - mDialog = + dialog = new DateTimePickerDialog( mContext, new DateTimeListener(dialogType), @@ -312,26 +326,28 @@ min, max); } else if (dialogType == TextInputType.MONTH) { - mDialog = + dialog = new MonthPickerDialog( mContext, new MonthOrWeekListener(dialogType), year, month, min, max); } else if (dialogType == TextInputType.WEEK) { - mDialog = + dialog = new WeekPickerDialog( mContext, new MonthOrWeekListener(dialogType), year, week, min, max); + } else { + assert false : "type was " + dialogType; + dialog = assumeNonNull(null); } - - mDialog.setButton( + dialog.setButton( DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.date_picker_dialog_set), - (DialogInterface.OnClickListener) mDialog); + (DialogInterface.OnClickListener) dialog); - mDialog.setButton( + dialog.setButton( DialogInterface.BUTTON_NEGATIVE, mContext.getText(android.R.string.cancel), (DialogInterface.OnClickListener) null); - mDialog.setButton( + dialog.setButton( DialogInterface.BUTTON_NEUTRAL, mContext.getText(R.string.date_picker_dialog_clear), new DialogInterface.OnClickListener() { @@ -342,7 +358,7 @@ } }); - mDialog.setOnDismissListener( + dialog.setOnDismissListener( new OnDismissListener() { @Override public void onDismiss(final DialogInterface dialog) { @@ -353,10 +369,12 @@ } }); + mDialog = dialog; mDialogAlreadyDismissed = false; - mDialog.show(); + dialog.show(); } + @EnsuresNonNullIf("mDialog") private boolean isDialogShowing() { return mDialog != null && mDialog.isShowing(); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/MonthPicker.java b/content/public/android/java/src/org/chromium/content/browser/picker/MonthPicker.java index d075b6e..cb7fbfc 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/MonthPicker.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/MonthPicker.java
@@ -7,6 +7,7 @@ import android.annotation.SuppressLint; import android.content.Context; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.R; import java.text.DateFormatSymbols; @@ -18,6 +19,7 @@ /** A month picker. */ // TODO(crbug.com/40479664): Fix this properly. @SuppressLint("DefaultLocale") +@NullMarked public class MonthPicker extends TwoFieldDatePicker { private static final int MONTHS_NUMBER = 12;
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/MonthPickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/picker/MonthPickerDialog.java index 7184cd2..82790ac 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/MonthPickerDialog.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/MonthPickerDialog.java
@@ -6,9 +6,11 @@ import android.content.Context; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.R; /** A month picker dialog */ +@NullMarked public class MonthPickerDialog extends TwoFieldDatePickerDialog { /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/MultiFieldTimePickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/picker/MultiFieldTimePickerDialog.java index e824541..afbf296 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/MultiFieldTimePickerDialog.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/MultiFieldTimePickerDialog.java
@@ -12,6 +12,7 @@ import android.view.View; import android.widget.NumberPicker; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.R; import java.util.ArrayList; @@ -26,6 +27,7 @@ * The milli picker is not displayed if step >= SECOND_IN_MILLIS * The second picker is not displayed if step >= MINUTE_IN_MILLIS. */ +@NullMarked public class MultiFieldTimePickerDialog extends AlertDialog implements OnClickListener { private final NumberPicker mHourSpinner;
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePicker.java b/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePicker.java index ced7910..fb3c8f0 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePicker.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePicker.java
@@ -15,6 +15,8 @@ import android.widget.NumberPicker; import android.widget.NumberPicker.OnValueChangeListener; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import java.util.Calendar; @@ -22,13 +24,14 @@ import java.util.TimeZone; /** This class is heavily based on android.widget.DatePicker. */ +@NullMarked public abstract class TwoFieldDatePicker extends FrameLayout { private final NumberPicker mPositionInYearSpinner; private final NumberPicker mYearSpinner; - private OnMonthOrWeekChangedListener mMonthOrWeekChangedListener; + private @Nullable OnMonthOrWeekChangedListener mMonthOrWeekChangedListener; // It'd be nice to use android.text.Time like in other Dialogs but // it suffers from the 2038 effect so it would prevent us from @@ -177,7 +180,7 @@ public void init( int year, int positionInYear, - OnMonthOrWeekChangedListener onMonthOrWeekChangedListener) { + @Nullable OnMonthOrWeekChangedListener onMonthOrWeekChangedListener) { setCurrentDate(year, positionInYear); updateSpinners(); mMonthOrWeekChangedListener = onMonthOrWeekChangedListener;
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePickerDialog.java index 25509366e..17014b0 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePickerDialog.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/TwoFieldDatePickerDialog.java
@@ -9,10 +9,12 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.R; import org.chromium.content.browser.picker.TwoFieldDatePicker.OnMonthOrWeekChangedListener; /** A two-field data picker dialog. */ +@NullMarked public abstract class TwoFieldDatePickerDialog extends AlertDialog implements OnClickListener, OnMonthOrWeekChangedListener { @@ -74,9 +76,8 @@ mPicker.init(year, positionInYear, this); } - protected TwoFieldDatePicker createPicker(Context context, double minValue, double maxValue) { - return null; - } + protected abstract TwoFieldDatePicker createPicker( + Context context, double minValue, double maxValue); @Override public void onClick(DialogInterface dialog, int which) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/WeekPicker.java b/content/public/android/java/src/org/chromium/content/browser/picker/WeekPicker.java index 8677fe5..53b3ddf3 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/WeekPicker.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/WeekPicker.java
@@ -6,12 +6,14 @@ import android.content.Context; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.R; import java.util.Calendar; import java.util.TimeZone; /** This class is heavily based on android.widget.DatePicker. */ +@NullMarked public class WeekPicker extends TwoFieldDatePicker { public WeekPicker(Context context, double minValue, double maxValue) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/picker/WeekPickerDialog.java b/content/public/android/java/src/org/chromium/content/browser/picker/WeekPickerDialog.java index fe1695e..bc86e485 100644 --- a/content/public/android/java/src/org/chromium/content/browser/picker/WeekPickerDialog.java +++ b/content/public/android/java/src/org/chromium/content/browser/picker/WeekPickerDialog.java
@@ -6,9 +6,11 @@ import android.content.Context; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.R; /** A week picker dialog. */ +@NullMarked public class WeekPickerDialog extends TwoFieldDatePickerDialog { /**
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java index cd4c8ac..7aed64eb 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/LGEmailActionModeWorkaroundImpl.java
@@ -21,6 +21,7 @@ import org.chromium.base.PackageUtils; import org.chromium.base.task.PostTask; import org.chromium.base.task.TaskTraits; +import org.chromium.build.annotations.NullMarked; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -33,6 +34,7 @@ * a system update. However, LG Email team is committed to fixing this in the near future. * This is a version code limited workaround to avoid crashes in the app. */ +@NullMarked public final class LGEmailActionModeWorkaroundImpl { private static final String TAG = "Ime";
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierAnimator.java b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierAnimator.java index 3bf033d..75d765e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierAnimator.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierAnimator.java
@@ -8,11 +8,13 @@ import android.view.animation.LinearInterpolator; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; /** * MagnifierAnimator adds animation to MagnifierWrapper when there is a change in y direction. * MagnifierWrapper class isolated P APIs out so we could write test for MagnifierAnimator. */ +@NullMarked public class MagnifierAnimator { private static final boolean DEBUG = false; private static final String TAG = "Magnifier";
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierSurfaceControl.java b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierSurfaceControl.java index c54d39e39..36e186e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierSurfaceControl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierSurfaceControl.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.selection; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.graphics.Rect; import android.os.Build; import android.view.AttachedSurfaceControl; @@ -16,6 +18,8 @@ import org.jni_zero.JNINamespace; import org.jni_zero.NativeMethods; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.webcontents.WebContentsImpl; /** @@ -25,6 +29,7 @@ */ @RequiresApi(Build.VERSION_CODES.TIRAMISU) @JNINamespace("content") +@NullMarked public class MagnifierSurfaceControl implements MagnifierWrapper { // Shadows are implemented as linear gradients with the same rounded corner as the main // content. Values are in device independent pixels, and converted to pixels at run time. @@ -39,12 +44,12 @@ private final WebContentsImpl mWebContents; private final SelectionPopupControllerImpl.ReadbackViewCallback mViewCallback; - private View mView; + private @Nullable View mView; private int mWidthPx; private int mHeightPx; private int mVerticalOffsetPx; - private SurfaceControl mSurfaceControl; - private SurfaceControl.Transaction mTransaction; + private @Nullable SurfaceControl mSurfaceControl; + private SurfaceControl.@Nullable Transaction mTransaction; public MagnifierSurfaceControl( WebContentsImpl webContents, @@ -56,13 +61,15 @@ @Override public void show(float x, float y) { Rect localVisibleRect = new Rect(); - if (!getView().getLocalVisibleRect(localVisibleRect)) { + View view = assumeNonNull(getView()); + if (!view.getLocalVisibleRect(localVisibleRect)) { dismiss(); return; } createNativeIfNeeded(); if (mSurfaceControl != null) { + assumeNonNull(mTransaction); x = x - mWidthPx / 2f; y = y - mHeightPx / 2f; float readback_y = y; @@ -81,7 +88,7 @@ .setReadbackOrigin(mNativeMagnifierSurfaceControl, x, readback_y); int[] viewOriginInSurface = new int[2]; - getView().getLocationInSurface(viewOriginInSurface); + view.getLocationInSurface(viewOriginInSurface); mTransaction.setPosition( mSurfaceControl, x + viewOriginInSurface[0], y + viewOriginInSurface[1]); mTransaction.apply(); @@ -106,8 +113,9 @@ private void createNativeIfNeeded() { if (mNativeMagnifierSurfaceControl != 0) return; - if (getView() == null) return; - AttachedSurfaceControl attachedSurfaceControl = getView().getRootSurfaceControl(); + View view = getView(); + if (view == null) return; + AttachedSurfaceControl attachedSurfaceControl = view.getRootSurfaceControl(); if (attachedSurfaceControl == null) return; SurfaceControl surfaceControl = @@ -123,7 +131,7 @@ float cornerRadius; float zoom; { - Magnifier androidMagnifier = new Magnifier(getView()); + Magnifier androidMagnifier = new Magnifier(view); mWidthPx = androidMagnifier.getWidth(); mHeightPx = androidMagnifier.getHeight(); mVerticalOffsetPx = androidMagnifier.getDefaultVerticalSourceToMagnifierOffset(); @@ -132,7 +140,7 @@ androidMagnifier.dismiss(); } - float density = getView().getResources().getDisplayMetrics().density; + float density = view.getResources().getDisplayMetrics().density; mNativeMagnifierSurfaceControl = MagnifierSurfaceControlJni.get() .create( @@ -156,6 +164,7 @@ } mNativeMagnifierSurfaceControl = 0; if (mSurfaceControl != null) { + assumeNonNull(mTransaction); mTransaction.reparent(mSurfaceControl, null); mTransaction.apply(); mTransaction.close(); @@ -166,7 +175,7 @@ mView = null; } - private View getView() { + private @Nullable View getView() { if (mView == null) { mView = mViewCallback.getReadbackView(); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapper.java b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapper.java index 8cd81fd..15ee411 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapper.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapper.java
@@ -4,7 +4,10 @@ package org.chromium.content.browser.selection; +import org.chromium.build.annotations.NullMarked; + /** A wrapper interface of Magnifier class. */ +@NullMarked public interface MagnifierWrapper { /** Wrapper of {@link Magnifier#show()}. */ public void show(float x, float y);
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapperImpl.java b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapperImpl.java index a1cabe8..1a4214b 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapperImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/MagnifierWrapperImpl.java
@@ -9,14 +9,17 @@ import android.widget.Magnifier; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** Implements MagnifierWrapper interface. */ @SuppressLint("NewApi") // Magnifier requires API level 28. +@NullMarked public class MagnifierWrapperImpl implements MagnifierWrapper { private static final boolean DEBUG = false; private static final String TAG = "Magnifier"; - private Magnifier mMagnifier; + private @Nullable Magnifier mMagnifier; private SelectionPopupControllerImpl.ReadbackViewCallback mCallback; /** Constructor. */
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 index 2f607fd..a58b6ae 100644 --- 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
@@ -21,7 +21,6 @@ import androidx.annotation.IdRes; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.content.ContextCompat; @@ -30,6 +29,8 @@ import org.chromium.base.Log; import org.chromium.base.PackageManagerUtils; import org.chromium.base.StrictModeContext; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionClient.Result; @@ -49,6 +50,7 @@ * 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. */ +@NullMarked public class SelectActionMenuHelper { private static final String TAG = "SelectActionMenu"; // 20 char limit. @@ -145,7 +147,7 @@ public static SortedSet<SelectionMenuGroup> getMenuItems( SelectActionMenuDelegate delegate, Context context, - @Nullable SelectionClient.Result classificationResult, + SelectionClient.@Nullable Result classificationResult, boolean isSelectionPassword, boolean isSelectionReadOnly, String selectedText, @@ -182,11 +184,10 @@ return itemGroups; } - @Nullable - private static SelectionMenuGroup getPrimaryAssistItems( + private static @Nullable SelectionMenuGroup getPrimaryAssistItems( Context context, String selectedText, - @Nullable SelectionClient.Result classificationResult) { + SelectionClient.@Nullable Result classificationResult) { if (selectedText.isEmpty()) { return null; } @@ -241,8 +242,7 @@ return defaultGroup; } - @Nullable - private static SelectionMenuGroup getSecondaryAssistItems( + private static @Nullable SelectionMenuGroup getSecondaryAssistItems( @Nullable SelectionActionMenuDelegate selectionActionMenuDelegate, @Nullable Result classificationResult, String selectedText) { @@ -356,7 +356,7 @@ private static void addAdditionalTextProcessingItems( SelectionMenuGroup textProcessingItems, - SelectionActionMenuDelegate selectionActionMenuDelegate) { + @Nullable SelectionActionMenuDelegate selectionActionMenuDelegate) { if (selectionActionMenuDelegate != null) { textProcessingItems.addItems( selectionActionMenuDelegate.getAdditionalTextProcessingItems()); @@ -374,8 +374,7 @@ return new Intent().setAction(Intent.ACTION_PROCESS_TEXT).setType("text/plain"); } - @Nullable - private static Drawable getPrimaryActionIconForClassificationResult( + private static @Nullable Drawable getPrimaryActionIconForClassificationResult( SelectionClient.Result classificationResult) { final List<Drawable> additionalIcons = classificationResult.additionalIcons; Drawable icon; @@ -388,8 +387,7 @@ return icon; } - @Nullable - private static View.OnClickListener getActionClickListener(RemoteAction action) { + private static View.@Nullable OnClickListener getActionClickListener(RemoteAction action) { if (TextUtils.isEmpty(action.getTitle()) || action.getActionIntent() == null) { return null; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionIndicesConverter.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionIndicesConverter.java index 916795d..62878ca 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionIndicesConverter.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionIndicesConverter.java
@@ -4,8 +4,14 @@ package org.chromium.content.browser.selection; +import static org.chromium.build.NullUtil.assumeNonNull; + import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; +import org.chromium.build.annotations.RequiresNonNull; + import java.text.BreakIterator; import java.util.regex.Pattern; @@ -23,15 +29,16 @@ * updateSelectionState() must be called. If updateSelectionState() or getWordDelta() returns false, * we should end the current logging session immediately since there must be a DOM change. */ +@NullMarked public class SelectionIndicesConverter { private static final Pattern PATTERN_WHITESPACE = Pattern.compile("[\\p{javaSpaceChar}\\s]+"); // Tracking the overall selection during current logging session. - private String mGlobalSelectionText; + private @Nullable String mGlobalSelectionText; private int mGlobalStartOffset; // Tracking previous selection. - private String mLastSelectionText; + private @Nullable String mLastSelectionText; private int mLastStartOffset; // The start offset from SelectionStarted call. @@ -46,6 +53,7 @@ updateGlobalSelection(selectionText, startOffset); return true; } + assumeNonNull(mLastSelectionText); boolean update = false; int endOffset = startOffset + selectionText.length(); @@ -77,6 +85,7 @@ } public boolean getWordDelta(int start, int end, int[] wordIndices) { + assumeNonNull(mGlobalSelectionText); assert wordIndices.length == 2; wordIndices[0] = wordIndices[1] = 0; @@ -125,7 +134,7 @@ } @VisibleForTesting - protected String getGlobalSelectionText() { + protected @Nullable String getGlobalSelectionText() { return mGlobalSelectionText; } @@ -170,6 +179,7 @@ @VisibleForTesting protected boolean isWhitespace(int start, int end) { + assumeNonNull(mGlobalSelectionText); return PATTERN_WHITESPACE.matcher(mGlobalSelectionText.substring(start, end)).matches(); } @@ -202,6 +212,7 @@ // Within each selection logging session, we obtain the next selection from shrink, expand or // reverse select the current selection. To update global selection, we only need to extend both // sides of the last global selection with current selection if necessary. + @RequiresNonNull("mGlobalSelectionText") private void combineGlobalSelection(String selectionText, int startOffset) { int endOffset = startOffset + selectionText.length(); int globalEndOffset = mGlobalStartOffset + mGlobalSelectionText.length();
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionMenuCachedResult.java b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionMenuCachedResult.java index 5c187027..909b6ac 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SelectionMenuCachedResult.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SelectionMenuCachedResult.java
@@ -4,8 +4,8 @@ package org.chromium.content.browser.selection; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.SelectionClient; import org.chromium.content_public.browser.SelectionMenuGroup; import org.chromium.content_public.browser.selection.SelectionActionMenuDelegate; @@ -25,15 +25,16 @@ * compare other params. * </ol> */ +@NullMarked public class SelectionMenuCachedResult { - private final @Nullable SelectionClient.Result mClassificationResult; + private final SelectionClient.@Nullable Result mClassificationResult; private final boolean mIsSelectionPassword; private final boolean mIsSelectionReadOnly; private final String mSelectedText; private final SortedSet<SelectionMenuGroup> mLastSelectionMenuItems; public SelectionMenuCachedResult( - @Nullable SelectionClient.Result classificationResult, + SelectionClient.@Nullable Result classificationResult, boolean isSelectionPassword, boolean isSelectionReadOnly, String selectedText, @@ -62,11 +63,11 @@ * @return true if params are equivalent otherwise false. */ public boolean canReuseResult( - @Nullable SelectionClient.Result classificationResult, + SelectionClient.@Nullable Result classificationResult, boolean isSelectionPassword, boolean isSelectionReadOnly, String selectedText, - SelectionActionMenuDelegate selectionActionMenuDelegate) { + @Nullable SelectionActionMenuDelegate selectionActionMenuDelegate) { if (selectionActionMenuDelegate != null && !selectionActionMenuDelegate.canReuseCachedSelectionMenu()) { return false;
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 aba04f42..1f75933 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
@@ -4,6 +4,8 @@ package org.chromium.content.browser.selection; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.app.Activity; import android.app.SearchManager; import android.content.Context; @@ -27,8 +29,6 @@ import androidx.annotation.IdRes; import androidx.annotation.IntDef; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.Px; import androidx.annotation.RequiresApi; import androidx.annotation.VisibleForTesting; @@ -45,6 +45,9 @@ import org.chromium.base.metrics.RecordUserAction; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; +import org.chromium.build.annotations.EnsuresNonNullIf; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.R; import org.chromium.content.browser.GestureListenerManagerImpl; import org.chromium.content.browser.PopupController; @@ -88,6 +91,7 @@ /** Implementation of the interface {@link SelectionPopupController}. */ @JNINamespace("content") +@NullMarked public class SelectionPopupControllerImpl extends ActionModeCallbackHelper implements ImeEventObserver, SelectionPopupController, @@ -139,11 +143,11 @@ } private final Handler mHandler; - private Context mContext; - private WindowAndroid mWindowAndroid; + private @Nullable Context mContext; + private @Nullable WindowAndroid mWindowAndroid; private WebContentsImpl mWebContents; - private ActionModeCallback mCallback; - private RenderFrameHost mRenderFrameHost; + private @Nullable ActionModeCallback mCallback; + private @Nullable RenderFrameHost mRenderFrameHost; private long mNativeSelectionPopupController; private SelectionClient.ResultCallback mResultCallback; @@ -156,8 +160,8 @@ private Runnable mRepeatingHideRunnable; // Can be null temporarily when switching between WindowAndroid. - @Nullable private View mView; - private ActionMode mActionMode; + private @Nullable View mView; + private @Nullable ActionMode mActionMode; // Supplier of whether action bar is showing now. private final ObservableSupplierImpl<Boolean> mIsActionBarShowingSupplier = @@ -196,31 +200,31 @@ // Dropdown menu delegate that handles showing a dropdown style text selection menu. // This must be set by the embedders that want to use this functionality. - @Nullable private SelectionDropdownMenuDelegate mDropdownMenuDelegate; + private @Nullable SelectionDropdownMenuDelegate mDropdownMenuDelegate; /** * The {@link SelectionClient} that processes textual selection, or {@code null} if none * exists. */ - private SelectionClient mSelectionClient; + private @Nullable SelectionClient mSelectionClient; - @Nullable private SmartSelectionEventProcessor mSmartSelectionEventProcessor; + private @Nullable SmartSelectionEventProcessor mSmartSelectionEventProcessor; - private PopupController mPopupController; + private @Nullable PopupController mPopupController; // The classificaton result of the selected text if the selection exists and // SelectionClient was able to classify it, otherwise null. - private SelectionClient.Result mClassificationResult; + private SelectionClient.@Nullable Result mClassificationResult; private boolean mPreserveSelectionOnNextLossOfFocus; // Delegate used by embedders to customize selection menu. - @Nullable private SelectionActionMenuDelegate mSelectionActionMenuDelegate; + private @Nullable SelectionActionMenuDelegate mSelectionActionMenuDelegate; - private MagnifierAnimator mMagnifierAnimator; + private @Nullable MagnifierAnimator mMagnifierAnimator; // Cached selection menu items to check against new selections. - @Nullable private SelectionMenuCachedResult mSelectionMenuCachedResult; + private @Nullable SelectionMenuCachedResult mSelectionMenuCachedResult; /** Custom {@link android.view.View.OnClickListener} map for ActionMode menu items. */ private final Map<MenuItem, View.OnClickListener> mCustomActionMenuItemClickListeners; @@ -228,6 +232,7 @@ /** An interface for getting {@link View} for readback. */ public interface ReadbackViewCallback { /** Gets the {@link View} for readback. */ + @Nullable View getReadbackView(); } @@ -248,7 +253,7 @@ * @return {@link SelectionPopupController} object. {@code null} if not available because {@link * #create()} is not called yet. */ - public static SelectionPopupControllerImpl fromWebContents(WebContents webContents) { + public static @Nullable SelectionPopupControllerImpl fromWebContents(WebContents webContents) { return ((WebContentsImpl) webContents) .getOrSetUserData( SelectionPopupControllerImpl.class, UserDataFactoryLazyHolder.INSTANCE); @@ -260,7 +265,8 @@ * @param webContents {@link WebContents} object. * @return {@link SelectionPopupController} object. {@code null} if not available. */ - public static SelectionPopupControllerImpl fromWebContentsNoCreate(WebContents webContents) { + public static @Nullable SelectionPopupControllerImpl fromWebContentsNoCreate( + WebContents webContents) { return ((WebContentsImpl) webContents) .getOrSetUserData(SelectionPopupControllerImpl.class, null); } @@ -302,11 +308,13 @@ */ public SelectionPopupControllerImpl(WebContents webContents) { this(webContents, null, true); - setActionModeCallback(ActionModeCallbackHelper.EMPTY_CALLBACK); + mCallback = ActionModeCallbackHelper.EMPTY_CALLBACK; } private SelectionPopupControllerImpl( - WebContents webContents, PopupController popupController, boolean initializeNative) { + WebContents webContents, + @Nullable PopupController popupController, + boolean initializeNative) { mHandler = new Handler(); mWebContents = (WebContentsImpl) webContents; mPopupController = popupController; @@ -332,7 +340,7 @@ } }; - WindowEventObserverManager manager = WindowEventObserverManager.from(mWebContents); + WindowEventObserverManager manager = WindowEventObserverManager.maybeFrom(mWebContents); if (manager != null) { manager.addObserver(this); } @@ -404,12 +412,12 @@ } @Override - public SelectionActionMenuDelegate getSelectionActionMenuDelegate() { + public @Nullable SelectionActionMenuDelegate getSelectionActionMenuDelegate() { return mSelectionActionMenuDelegate; } @Override - public RenderFrameHost getRenderFrameHost() { + public @Nullable RenderFrameHost getRenderFrameHost() { return mRenderFrameHost; } @@ -418,21 +426,21 @@ return mResultCallback; } - public SelectionClient.Result getClassificationResult() { + public SelectionClient.@Nullable Result getClassificationResult() { return mClassificationResult; } @Override - public SelectionClient getSelectionClient() { + public @Nullable SelectionClient getSelectionClient() { return mSelectionClient; } - @Nullable - public SelectionMenuCachedResult getSelectionMenuCachedResultForTesting() { + public @Nullable SelectionMenuCachedResult getSelectionMenuCachedResultForTesting() { return mSelectionMenuCachedResult; } @Override + @EnsuresNonNullIf("mActionMode") public boolean isActionModeValid() { return mActionMode != null; } @@ -471,7 +479,7 @@ if (sEnableTabletUiModeForTesting) { return true; } - return DeviceFormFactor.isWindowOnTablet(mWindowAndroid); + return DeviceFormFactor.isWindowOnTablet(assumeNonNull(mWindowAndroid)); } /** @@ -625,7 +633,7 @@ ActionMode actionMode = mView.startActionMode(mCallback, ActionMode.TYPE_FLOATING); if (actionMode != null) { // This is to work around an LGE email issue. See crbug.com/651706 for more details. - LGEmailActionModeWorkaroundImpl.runIfNecessary(mContext, actionMode); + LGEmailActionModeWorkaroundImpl.runIfNecessary(assumeNonNull(mContext), actionMode); } setActionMode(actionMode); mUnselectAllOnDismiss = true; @@ -648,6 +656,7 @@ private SelectionDropdownMenuDelegate.ItemClickListener getDropdownItemClickListener( SelectionDropdownMenuDelegate delegate) { return item -> { + assumeNonNull(mCallback); final int groupId = delegate.getGroupId(item); final int id = delegate.getItemId(item); logSelectionAction(groupId, id); @@ -659,6 +668,7 @@ private MVCListAdapter.ModelList getDropdownItems() { MVCListAdapter.ModelList items = new MVCListAdapter.ModelList(); if (mDropdownMenuDelegate != null) { + assumeNonNull(mContext); SortedSet<SelectionMenuGroup> allItemGroups = getMenuItems(); int groupIndex = 0; @@ -716,6 +726,7 @@ @VisibleForTesting protected void createAndShowDropdownMenu() { + assert mContext != null; assert mView != null; assert mDropdownMenuDelegate != null; @@ -827,7 +838,7 @@ } @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid) { if (newWindowAndroid == null) { reset(); return; @@ -913,13 +924,14 @@ public void onCreateActionMode(ActionMode mode, Menu menu) { mode.setTitle( mWindowAndroid != null && DeviceFormFactor.isWindowOnTablet(mWindowAndroid) - ? mContext.getString(R.string.actionbar_textselection_title) + ? assumeNonNull(mContext).getString(R.string.actionbar_textselection_title) : null); mode.setSubtitle(null); } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + assumeNonNull(mContext); SortedSet<SelectionMenuGroup> menuItems = getMenuItems(); SelectActionMenuHelper.removeAllAddedGroupsFromMenu(menu); @@ -950,6 +962,7 @@ !isFocusedNodeEditable(), getSelectedText(), mSelectionActionMenuDelegate)) { + assert mContext != null; mSelectionMenuCachedResult = new SelectionMenuCachedResult( mClassificationResult, @@ -983,7 +996,7 @@ SortedSet<SelectionMenuGroup> menuGroups, Menu menu, Map<MenuItem, View.OnClickListener> customMenuItemClickListeners, - @Nullable MenuItem.OnMenuItemClickListener additionalMenuItemClickListener) { + MenuItem.@Nullable OnMenuItemClickListener additionalMenuItemClickListener) { for (SelectionMenuGroup group : menuGroups) { addMenuItemsToActionMenu( context, @@ -1004,7 +1017,7 @@ SelectionMenuGroup group, Menu menu, Map<MenuItem, View.OnClickListener> customMenuItemClickListeners, - @Nullable MenuItem.OnMenuItemClickListener additionalMenuItemClickListener) { + MenuItem.@Nullable OnMenuItemClickListener additionalMenuItemClickListener) { // All menu items and groups are sorted already at this point, so this is just passing // 1-indexed value as order. int menuItemCount = menu.size(); @@ -1103,6 +1116,7 @@ if (!isSelectActionModeAllowed(MENU_ITEM_PROCESS_TEXT)) { return; } + assert mContext != null; SelectionMenuGroup textProcessingItems = SelectActionMenuHelper.getTextProcessingItems( @@ -1142,7 +1156,7 @@ int groupId, int id, @Nullable Intent intent, - @Nullable View.OnClickListener clickListener) { + View.@Nullable OnClickListener clickListener) { // Use the click listener for the item if it has one. if (clickListener != null) { clickListener.onClick(null); @@ -1298,6 +1312,7 @@ /** Perform a share action. */ @VisibleForTesting public void share() { + assumeNonNull(mContext); RecordUserAction.record(UMA_MOBILE_ACTION_MODE_SHARE); String query = sanitizeQuery(getSelectedText(), MAX_SHARE_QUERY_LENGTH); if (TextUtils.isEmpty(query)) return; @@ -1316,6 +1331,7 @@ /** Perform a processText action (translating the text, for example). */ private void processText(Intent intent) { + assumeNonNull(mWindowAndroid); RecordUserAction.record("MobileActionMode.ProcessTextIntent"); // Use MAX_SHARE_QUERY_LENGTH for the Intent 100k limitation. @@ -1348,6 +1364,7 @@ @VisibleForTesting @SuppressWarnings(value = "UnsafeImplicitIntentLaunch") public void search() { + assumeNonNull(mContext); RecordUserAction.record("MobileActionMode.WebSearch"); String query = sanitizeQuery(getSelectedText(), MAX_SEARCH_QUERY_LENGTH); if (TextUtils.isEmpty(query)) return; @@ -1416,7 +1433,7 @@ } @Override - public void handleTextReplacementAction(String text) { + public void handleTextReplacementAction(@Nullable String text) { if (mWebContents == null || text == null) return; // Do not handle the result if no text is selected or current selection is not editable. // There are scenarios where hasSelection returns false but selected text is present @@ -1452,8 +1469,7 @@ } @Override - public void setDropdownMenuDelegate( - @NonNull SelectionDropdownMenuDelegate dropdownMenuDelegate) { + public void setDropdownMenuDelegate(SelectionDropdownMenuDelegate dropdownMenuDelegate) { mDropdownMenuDelegate = dropdownMenuDelegate; } @@ -1568,7 +1584,9 @@ case SelectionEventType.INSERTION_HANDLE_MOVED: mSelectionRect.set(left, top, right, bottom); - if (!getGestureListenerManager().isScrollInProgress() && isPasteActionModeValid()) { + if (!assumeNonNull(GestureListenerManagerImpl.fromWebContents(mWebContents)) + .isScrollInProgress() + && isPasteActionModeValid()) { showActionModeOrClearOnFailure(); } else { destroySelectActionMode(); @@ -1663,11 +1681,6 @@ } @VisibleForTesting - /* package */ GestureListenerManagerImpl getGestureListenerManager() { - return GestureListenerManagerImpl.fromWebContents(mWebContents); - } - - @VisibleForTesting @CalledByNative /* package */ void onDragUpdate(@TouchSelectionDraggableType int type, float x, float y) { // If this is for longpress drag selector, we can only have mangifier on S and above. @@ -1697,6 +1710,7 @@ private PopupController getPopupController() { if (mPopupController == null) { mPopupController = PopupController.fromWebContents(mWebContents); + assert mPopupController != null; } return mPopupController; } @@ -1712,7 +1726,7 @@ * @return The context used for SelectionPopupController. */ @CalledByNative - private Context getContext() { + private @Nullable Context getContext() { return mContext; } @@ -1848,7 +1862,7 @@ return mLastSelectedText; } - private void setActionMode(ActionMode actionMode) { + private void setActionMode(@Nullable ActionMode actionMode) { mActionMode = actionMode; mIsActionBarShowingSupplier.set(isSelectActionBarShowing()); } @@ -1933,13 +1947,13 @@ } @Override - public TextClassifier getTextClassifier() { + public @Nullable TextClassifier getTextClassifier() { SelectionClient client = getSelectionClient(); return client == null ? null : client.getTextClassifier(); } @Override - public TextClassifier getCustomTextClassifier() { + public @Nullable TextClassifier getCustomTextClassifier() { SelectionClient client = getSelectionClient(); return client == null ? null : client.getCustomTextClassifier(); } @@ -1960,7 +1974,7 @@ * @return current touch handle rects object array. */ @VisibleForTesting - Object[] getTouchHandleRects() { + Object @Nullable [] getTouchHandleRects() { if (mNativeSelectionPopupController == 0) return null; return SelectionPopupControllerImplJni.get() .getTouchHandleRects(
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java index d341af66..01d59e4 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionClient.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.selection; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.os.Build; import android.provider.Settings; @@ -11,7 +13,6 @@ import android.view.textclassifier.TextClassifier; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; @@ -19,6 +20,8 @@ import org.chromium.base.ObserverList; import org.chromium.base.UserData; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.webcontents.WebContentsImpl; import org.chromium.content_public.browser.SelectAroundCaretResult; import org.chromium.content_public.browser.SelectionClient; @@ -37,6 +40,7 @@ * SmartSelectionProvider which does the classification itself. */ @JNINamespace("content") +@NullMarked public class SmartSelectionClient implements SelectionClient, UserData { @IntDef({RequestType.CLASSIFY, RequestType.SUGGEST_AND_CLASSIFY}) @Retention(RetentionPolicy.SOURCE) @@ -55,9 +59,14 @@ private static final int NUM_EXTRA_CHARS = 240; private long mNativeSmartSelectionClient; + + @SuppressWarnings("NullAway.Init") private SmartSelectionProvider mProvider; + + @SuppressWarnings("NullAway.Init") private ResultCallback mCallback; - private SmartSelectionEventProcessor mSmartSelectionEventProcessor; + + private @Nullable SmartSelectionEventProcessor mSmartSelectionEventProcessor; /** Observer list for surrounding text received. */ private final ObserverList<SurroundingTextCallback> mSurroundingTextReceivedListeners = @@ -67,7 +76,7 @@ * Creates the SmartSelectionClient if not present. Returns null in case SmartSelectionProvider * does not exist in the system. */ - public static SmartSelectionClient fromWebContents( + public static @Nullable SmartSelectionClient fromWebContents( ResultCallback callback, WebContents webContents) { WindowAndroid windowAndroid = webContents.getTopLevelNativeWindow(); if (windowAndroid == null) return null; @@ -78,8 +87,10 @@ } SmartSelectionClient client = - ((WebContentsImpl) webContents) - .getOrSetUserData(SmartSelectionClient.class, SmartSelectionClient::new); + assumeNonNull( + ((WebContentsImpl) webContents) + .getOrSetUserData( + SmartSelectionClient.class, SmartSelectionClient::new)); client.setCallback(callback, webContents); return client; } @@ -133,7 +144,7 @@ } @Override - public SelectionEventProcessor getSelectionEventProcessor() { + public @Nullable SelectionEventProcessor getSelectionEventProcessor() { return mSmartSelectionEventProcessor; } @@ -143,12 +154,12 @@ } @Override - public TextClassifier getTextClassifier() { + public @Nullable TextClassifier getTextClassifier() { return mProvider.getTextClassifier(); } @Override - public TextClassifier getCustomTextClassifier() { + public @Nullable TextClassifier getCustomTextClassifier() { return mProvider.getCustomTextClassifier(); } @@ -203,7 +214,7 @@ } } - private static boolean isDeviceProvisioned(Context context) { + private static boolean isDeviceProvisioned(@Nullable Context context) { if (context == null || context.getContentResolver() == null) return true; // Returns false when device is not provisioned, i.e. before a new device went through // signup process.
diff --git a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionEventProcessor.java b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionEventProcessor.java index 0fbbe87..9c16451e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionEventProcessor.java +++ b/content/public/android/java/src/org/chromium/content/browser/selection/SmartSelectionEventProcessor.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.selection; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Context; import android.os.Build; import android.view.textclassifier.SelectionEvent; @@ -11,10 +13,12 @@ import android.view.textclassifier.TextClassificationManager; import android.view.textclassifier.TextClassifier; -import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; +import org.chromium.build.annotations.RequiresNonNull; import org.chromium.content.browser.WindowEventObserver; import org.chromium.content.browser.WindowEventObserverManager; import org.chromium.content_public.browser.SelectionClient; @@ -33,19 +37,21 @@ * are ignored but we count each punctuation mark as a word. */ @RequiresApi(Build.VERSION_CODES.P) +@NullMarked public class SmartSelectionEventProcessor implements SelectionEventProcessor { private static final String TAG = "SmartSelectionLogger"; private static final boolean DEBUG = false; // May be null if {@link onWindowAndroidChanged()} sets it to null. - private WindowAndroid mWindowAndroid; + private @Nullable WindowAndroid mWindowAndroid; - private TextClassifier mSession; + private @Nullable TextClassifier mSession; - private SelectionIndicesConverter mConverter; + private @Nullable SelectionIndicesConverter mConverter; - public static SmartSelectionEventProcessor create(WebContents webContents) { - if (webContents.getTopLevelNativeWindow().getContext().get() == null) { + public static @Nullable SmartSelectionEventProcessor create(WebContents webContents) { + var topWindow = webContents.getTopLevelNativeWindow(); + if (topWindow == null || topWindow.getContext().get() == null) { return null; } return new SmartSelectionEventProcessor(webContents); @@ -53,12 +59,13 @@ private SmartSelectionEventProcessor(WebContents webContents) { mWindowAndroid = webContents.getTopLevelNativeWindow(); - WindowEventObserverManager manager = WindowEventObserverManager.from(webContents); + WindowEventObserverManager manager = WindowEventObserverManager.maybeFrom(webContents); if (manager != null) { manager.addObserver( new WindowEventObserver() { @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged( + @Nullable WindowAndroid newWindowAndroid) { mWindowAndroid = newWindowAndroid; } }); @@ -81,8 +88,9 @@ } public void onSelectionModified( - String selectionText, int startOffset, SelectionClient.Result result) { + String selectionText, int startOffset, SelectionClient.@Nullable Result result) { if (mSession == null) return; + assumeNonNull(mConverter); if (!mConverter.updateSelectionState(selectionText, startOffset)) { // DOM change detected, end logging session. endTextClassificationSession(); @@ -112,10 +120,14 @@ } public void onSelectionAction( - String selectionText, int startOffset, int action, SelectionClient.Result result) { + String selectionText, + int startOffset, + int action, + SelectionClient.@Nullable Result result) { if (mSession == null) { return; } + assumeNonNull(mConverter); if (!mConverter.updateSelectionState(selectionText, startOffset)) { // DOM change detected, end logging session. endTextClassificationSession(); @@ -170,12 +182,12 @@ mSession = null; } + @RequiresNonNull("mSession") public void logEvent(SelectionEvent selectionEvent) { mSession.onSelectionEvent(selectionEvent); } - @Nullable - public TextClassifier getTextClassifierSession() { + public @Nullable TextClassifier getTextClassifierSession() { return mSession; } }
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 31838fc..d399ca1f 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
@@ -4,6 +4,8 @@ package org.chromium.content.browser.selection; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.annotation.SuppressLint; import android.app.RemoteAction; import android.content.Context; @@ -17,11 +19,12 @@ import android.view.textclassifier.TextSelection; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import org.chromium.base.Log; import org.chromium.base.task.AsyncTask; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.WindowEventObserver; import org.chromium.content.browser.WindowEventObserverManager; import org.chromium.content_public.browser.SelectionClient; @@ -34,6 +37,7 @@ import java.util.List; /** Controls Smart Text selection. Talks to the Android TextClassificationManager API. */ +@NullMarked public class SmartSelectionProvider { private static final String TAG = "SmartSelProvider"; @@ -45,13 +49,13 @@ } private SelectionClient.ResultCallback mResultCallback; - private WindowAndroid mWindowAndroid; - private ClassificationTask mClassificationTask; - private TextClassifier mTextClassifier; + private @Nullable WindowAndroid mWindowAndroid; + private @Nullable ClassificationTask mClassificationTask; + private @Nullable TextClassifier mTextClassifier; private Handler mHandler; private Runnable mFailureResponseRunnable; - @Nullable private final SmartSelectionEventProcessor mSelectionEventProcessor; + private final @Nullable SmartSelectionEventProcessor mSelectionEventProcessor; public SmartSelectionProvider( SelectionClient.ResultCallback callback, @@ -59,12 +63,13 @@ @Nullable SmartSelectionEventProcessor selectionEventProcessor) { mResultCallback = callback; mWindowAndroid = webContents.getTopLevelNativeWindow(); - WindowEventObserverManager manager = WindowEventObserverManager.from(webContents); + WindowEventObserverManager manager = WindowEventObserverManager.maybeFrom(webContents); if (manager != null) { manager.addObserver( new WindowEventObserver() { @Override - public void onWindowAndroidChanged(WindowAndroid newWindowAndroid) { + public void onWindowAndroidChanged( + @Nullable WindowAndroid newWindowAndroid) { mWindowAndroid = newWindowAndroid; } }); @@ -97,6 +102,7 @@ } public void setTextClassifier(TextClassifier textClassifier) { + assumeNonNull(mWindowAndroid); mTextClassifier = textClassifier; Context context = mWindowAndroid.getContext().get(); @@ -109,7 +115,7 @@ // TODO(wnwen): Remove this suppression once the constant is added to lint. @SuppressLint("WrongConstant") - public TextClassifier getTextClassifier() { + public @Nullable TextClassifier getTextClassifier() { if (mTextClassifier != null) return mTextClassifier; if (mWindowAndroid == null) { @@ -123,11 +129,11 @@ .getTextClassifier(); } - public TextClassifier getCustomTextClassifier() { + public @Nullable TextClassifier getCustomTextClassifier() { return mTextClassifier; } - private TextClassifier getTextClassificationSession() { + private @Nullable TextClassifier getTextClassificationSession() { if (mWindowAndroid == null) { return null; } @@ -152,6 +158,7 @@ mHandler.post(mFailureResponseRunnable); return; } + assumeNonNull(mWindowAndroid); if (mClassificationTask != null) { mClassificationTask.cancel(false); @@ -177,7 +184,7 @@ private final CharSequence mText; private final int mOriginalStart; private final int mOriginalEnd; - private final Context mContext; + private final @Nullable Context mContext; ClassificationTask( TextClassifier classifier, @@ -185,7 +192,7 @@ CharSequence text, int start, int end, - Context context) { + @Nullable Context context) { mTextClassifier = classifier; mRequestType = requestType; mText = text; @@ -243,7 +250,7 @@ } private SelectionClient.Result makeResult( - int start, int end, TextClassification tc, TextSelection ts) { + int start, int end, TextClassification tc, @Nullable TextSelection ts) { SelectionClient.Result result = new SelectionClient.Result(); result.text = mText.toString(); @@ -270,7 +277,8 @@ // SmartSelectionProvider. TextClassification#getActions() is only available on P and above, // so @RequiresApi(Build.VERSION_CODES.P) - private List<Drawable> loadIconDrawables(Context context, TextClassification tc) { + private @Nullable List<Drawable> loadIconDrawables( + @Nullable Context context, TextClassification tc) { if (context == null || tc == null) return null; ArrayList<Drawable> res = new ArrayList<>();
diff --git a/content/public/android/java/src/org/chromium/content/browser/sms/SmsProviderGms.java b/content/public/android/java/src/org/chromium/content/browser/sms/SmsProviderGms.java index 69f2811..dfea80f5 100644 --- a/content/public/android/java/src/org/chromium/content/browser/sms/SmsProviderGms.java +++ b/content/public/android/java/src/org/chromium/content/browser/sms/SmsProviderGms.java
@@ -16,6 +16,8 @@ import org.chromium.base.ContextUtils; import org.chromium.base.Log; import org.chromium.base.ResettersForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; /** @@ -30,18 +32,19 @@ * */ @JNINamespace("content") +@NullMarked public class SmsProviderGms { private static final String TAG = "SmsProviderGms"; private static final int MIN_GMS_VERSION_NUMBER_WITH_CODE_BROWSER_BACKEND = 202990000; private final long mSmsProviderGmsAndroid; private final @GmsBackend int mBackend; - private SmsUserConsentReceiver mUserConsentReceiver; - private SmsVerificationReceiver mVerificationReceiver; + private @Nullable SmsUserConsentReceiver mUserConsentReceiver; + private @Nullable SmsVerificationReceiver mVerificationReceiver; private Wrappers.WebOTPServiceContext mContext; - private WindowAndroid mWindow; - private Wrappers.SmsRetrieverClientWrapper mClient; + private @Nullable WindowAndroid mWindow; + private Wrappers.@Nullable SmsRetrieverClientWrapper mClient; @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) public SmsProviderGms( @@ -77,11 +80,11 @@ ResettersForTesting.register(() -> mVerificationReceiver = oldValue); } - public SmsUserConsentReceiver getUserConsentReceiverForTesting() { + public @Nullable SmsUserConsentReceiver getUserConsentReceiverForTesting() { return mUserConsentReceiver; } - public SmsVerificationReceiver getVerificationReceiverForTesting() { + public @Nullable SmsVerificationReceiver getVerificationReceiverForTesting() { return mVerificationReceiver; } @@ -118,16 +121,16 @@ // If the SMS retrieval request is made from a remote device, e.g. desktop, we only proceed // with the verification receiver because the user consent receiver introduces too much user // friction. In addition, we do not apply the fallback logic in such case. - boolean shouldUseVerificationReceiver = - mVerificationReceiver != null - && (!isLocalRequest || mBackend != GmsBackend.USER_CONSENT); - boolean shouldUseUserConsentReceiver = - mUserConsentReceiver != null - && isLocalRequest - && mBackend != GmsBackend.VERIFICATION - && window != null; - if (shouldUseVerificationReceiver) mVerificationReceiver.listen(isLocalRequest); - if (shouldUseUserConsentReceiver) mUserConsentReceiver.listen(window); + if (mVerificationReceiver != null + && (!isLocalRequest || mBackend != GmsBackend.USER_CONSENT)) { + mVerificationReceiver.listen(isLocalRequest); + } + if (mUserConsentReceiver != null + && isLocalRequest + && mBackend != GmsBackend.VERIFICATION + && window != null) { + mUserConsentReceiver.listen(window); + } } /** @@ -170,7 +173,7 @@ // --------- Callbacks for receivers - void onReceive(String sms, @GmsBackend int backend) { + void onReceive(@Nullable String sms, @GmsBackend int backend) { SmsProviderGmsJni.get().onReceive(mSmsProviderGmsAndroid, sms, backend); } @@ -186,7 +189,7 @@ SmsProviderGmsJni.get().onNotAvailable(mSmsProviderGmsAndroid); } - public WindowAndroid getWindow() { + public @Nullable WindowAndroid getWindow() { return mWindow; } @@ -217,7 +220,7 @@ @NativeMethods interface Natives { - void onReceive(long nativeSmsProviderGms, String sms, @GmsBackend int backend); + void onReceive(long nativeSmsProviderGms, @Nullable String sms, @GmsBackend int backend); void onTimeout(long nativeSmsProviderGms);
diff --git a/content/public/android/java/src/org/chromium/content/browser/sms/SmsUserConsentReceiver.java b/content/public/android/java/src/org/chromium/content/browser/sms/SmsUserConsentReceiver.java index 97aac93..4c105b4 100644 --- a/content/public/android/java/src/org/chromium/content/browser/sms/SmsUserConsentReceiver.java +++ b/content/public/android/java/src/org/chromium/content/browser/sms/SmsUserConsentReceiver.java
@@ -18,10 +18,13 @@ import com.google.android.gms.tasks.Task; import org.chromium.base.ContextUtils; +import org.chromium.base.IntentUtils; import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; import org.chromium.ui.base.WindowAndroid; /** Encapsulates logic to retrieve OTP code via SMS User Consent API. */ +@NullMarked public class SmsUserConsentReceiver extends BroadcastReceiver { private static final String TAG = "SmsUserConsentRcvr"; private static final boolean DEBUG = false; @@ -75,12 +78,8 @@ return; } - final Status status; - - try { - status = (Status) intent.getParcelableExtra(SmsRetriever.EXTRA_STATUS); - } catch (Throwable e) { - if (DEBUG) Log.d(TAG, "Error getting parceable."); + final Status status = IntentUtils.safeGetParcelableExtra(intent, SmsRetriever.EXTRA_STATUS); + if (status == null) { return; }
diff --git a/content/public/android/java/src/org/chromium/content/browser/sms/SmsVerificationReceiver.java b/content/public/android/java/src/org/chromium/content/browser/sms/SmsVerificationReceiver.java index 3d9325f0..54776c25 100644 --- a/content/public/android/java/src/org/chromium/content/browser/sms/SmsVerificationReceiver.java +++ b/content/public/android/java/src/org/chromium/content/browser/sms/SmsVerificationReceiver.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.sms; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.app.Activity; import android.app.PendingIntent; import android.content.BroadcastReceiver; @@ -24,8 +26,10 @@ import com.google.android.gms.tasks.Task; import org.chromium.base.ContextUtils; +import org.chromium.base.IntentUtils; import org.chromium.base.Log; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.sms.Wrappers.WebOTPServiceContext; import org.chromium.ui.base.WindowAndroid; @@ -38,6 +42,7 @@ * * <p>TODO(majidvp): rename legacy Verification name to more appropriate name ( e.g., BrowserCode. */ +@NullMarked public class SmsVerificationReceiver extends BroadcastReceiver { private static final String TAG = "SmsVerification"; private static final boolean DEBUG = false; @@ -97,6 +102,7 @@ } @Override + @SuppressWarnings("NullAway") // https://github.com/uber/NullAway/issues/1122 public void onReceive(Context context, Intent intent) { if (DEBUG) Log.d(TAG, "Received something!"); @@ -112,12 +118,8 @@ return; } - final Status status; - - try { - status = (Status) intent.getParcelableExtra(SmsRetriever.EXTRA_STATUS); - } catch (Throwable e) { - if (DEBUG) Log.d(TAG, "Error getting parceable"); + Status status = IntentUtils.safeGetParcelableExtra(intent, SmsRetriever.EXTRA_STATUS); + if (status == null) { return; } @@ -178,8 +180,7 @@ ResolvableApiException rex = (ResolvableApiException) exception; try { PendingIntent resolutionIntent = rex.getResolution(); - mProvider - .getWindow() + assumeNonNull(mProvider.getWindow()) .showIntent( resolutionIntent, new WindowAndroid.IntentCallback() {
diff --git a/content/public/android/java/src/org/chromium/content/browser/sms/Wrappers.java b/content/public/android/java/src/org/chromium/content/browser/sms/Wrappers.java index bf5030269..658853e 100644 --- a/content/public/android/java/src/org/chromium/content/browser/sms/Wrappers.java +++ b/content/public/android/java/src/org/chromium/content/browser/sms/Wrappers.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.sms; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.BroadcastReceiver; import android.content.Context; import android.content.ContextWrapper; @@ -16,6 +18,10 @@ import com.google.android.gms.auth.api.phone.SmsRetrieverClient; import com.google.android.gms.tasks.Task; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + +@NullMarked class Wrappers { // Prevent instantiation. private Wrappers() {} @@ -23,13 +29,14 @@ /** Wraps com.google.android.gms.auth.api.phone.SmsRetrieverClient. */ static class SmsRetrieverClientWrapper { // Used for user consent flow. - private final SmsRetrieverClient mSmsRetrieverClient; + private final @Nullable SmsRetrieverClient mSmsRetrieverClient; // Used for browser code flow. - private final SmsCodeBrowserClient mSmsCodeBrowserClient; - private WebOTPServiceContext mContext; + private final @Nullable SmsCodeBrowserClient mSmsCodeBrowserClient; + private @Nullable WebOTPServiceContext mContext; public SmsRetrieverClientWrapper( - SmsRetrieverClient smsRetrieverClient, SmsCodeBrowserClient smsCodeBrowserClient) { + @Nullable SmsRetrieverClient smsRetrieverClient, + @Nullable SmsCodeBrowserClient smsCodeBrowserClient) { mSmsRetrieverClient = smsRetrieverClient; mSmsCodeBrowserClient = smsCodeBrowserClient; } @@ -38,15 +45,17 @@ mContext = context; } - public WebOTPServiceContext getContext() { + public @Nullable WebOTPServiceContext getContext() { return mContext; } public Task<Void> startSmsCodeBrowserRetriever() { + assumeNonNull(mSmsCodeBrowserClient); return mSmsCodeBrowserClient.startSmsCodeRetriever(); } - public Task<Void> startSmsUserConsent(String senderAddress) { + public Task<Void> startSmsUserConsent(@Nullable String senderAddress) { + assumeNonNull(mSmsRetrieverClient); return mSmsRetrieverClient.startSmsUserConsent(senderAddress); } } @@ -56,8 +65,8 @@ * registered BroadcastReceiver. */ static class WebOTPServiceContext extends ContextWrapper { - private BroadcastReceiver mVerificationReceiver; - private BroadcastReceiver mUserConsentReceiver; + private @Nullable BroadcastReceiver mVerificationReceiver; + private @Nullable BroadcastReceiver mUserConsentReceiver; private final SmsProviderGms mSmsProviderGms; public WebOTPServiceContext(Context context, SmsProviderGms provider) { @@ -65,11 +74,11 @@ mSmsProviderGms = provider; } - public SmsVerificationReceiver getRegisteredVerificationReceiver() { + public @Nullable SmsVerificationReceiver getRegisteredVerificationReceiver() { return (SmsVerificationReceiver) mVerificationReceiver; } - public SmsUserConsentReceiver getRegisteredUserConsentReceiver() { + public @Nullable SmsUserConsentReceiver getRegisteredUserConsentReceiver() { return (SmsUserConsentReceiver) mUserConsentReceiver; } @@ -77,7 +86,7 @@ return new SmsVerificationReceiver(mSmsProviderGms, this); } - private void onRegisterReceiver(BroadcastReceiver receiver, IntentFilter filter) { + private void onRegisterReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) { if (filter.hasAction(SmsCodeRetriever.SMS_CODE_RETRIEVED_ACTION)) { mVerificationReceiver = receiver; } else { @@ -90,32 +99,33 @@ @Override public Intent registerReceiver( - BroadcastReceiver receiver, + @Nullable BroadcastReceiver receiver, IntentFilter filter, - String permission, - Handler handler) { + @Nullable String permission, + @Nullable Handler handler) { onRegisterReceiver(receiver, filter); return super.registerReceiver(receiver, filter, permission, handler); } @Override - public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { + public Intent registerReceiver(@Nullable BroadcastReceiver receiver, IntentFilter filter) { throw new RuntimeException(); // Not implemented. } @Override public Intent registerReceiver( - BroadcastReceiver receiver, + @Nullable BroadcastReceiver receiver, IntentFilter filter, - String permission, - Handler handler, + @Nullable String permission, + @Nullable Handler handler, int flags) { onRegisterReceiver(receiver, filter); return super.registerReceiver(receiver, filter, permission, handler, flags); } @Override - public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) { + public Intent registerReceiver( + @Nullable BroadcastReceiver receiver, IntentFilter filter, int flags) { throw new RuntimeException(); // Not implemented. }
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/EmptyInternalAccessDelegate.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/EmptyInternalAccessDelegate.java index 10a238a..fa8db0f 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/EmptyInternalAccessDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/EmptyInternalAccessDelegate.java
@@ -7,12 +7,14 @@ import android.view.KeyEvent; import android.view.MotionEvent; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.ViewEventSink; /** * Empty implementation of {@link ViewEventSink.InternalAccessDelegate}. Intentional no-op for * transient stage usage. */ +@NullMarked public class EmptyInternalAccessDelegate implements ViewEventSink.InternalAccessDelegate { @Override public boolean super_onKeyUp(int keyCode, KeyEvent event) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java index 16680647..5c0c67d 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsImpl.java
@@ -4,6 +4,8 @@ package org.chromium.content.browser.webcontents; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; @@ -18,7 +20,6 @@ import android.view.Surface; import android.view.ViewStructure; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.jni_zero.CalledByNative; @@ -34,6 +35,9 @@ import org.chromium.base.UserData; import org.chromium.base.UserDataHost; import org.chromium.blink_public.input.SelectionGranularity; +import org.chromium.build.annotations.Initializer; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.cc.input.BrowserControlsOffsetTagsInfo; import org.chromium.content.browser.AppWebMessagePort; import org.chromium.content.browser.GestureListenerManagerImpl; @@ -81,6 +85,7 @@ * The WebContentsImpl Java wrapper to allow communicating with the native WebContentsImpl object. */ @JNINamespace("content") +@NullMarked public class WebContentsImpl implements WebContents, RenderFrameHostDelegate, WindowEventObserver { private static final String TAG = "WebContentsImpl"; @@ -109,15 +114,20 @@ public static final Parcelable.Creator<WebContents> CREATOR = new Parcelable.Creator<WebContents>() { @Override - public WebContents createFromParcel(Parcel source) { + public @Nullable WebContents createFromParcel(Parcel source) { Bundle bundle = source.readBundle(); // Check the version. - if (bundle.getLong(PARCEL_VERSION_KEY, -1) != 0) return null; + if (bundle == null || bundle.getLong(PARCEL_VERSION_KEY, -1) != 0) { + return null; + } // Check that we're in the same process. ParcelUuid parcelUuid = bundle.getParcelable(PARCEL_PROCESS_GUARD_KEY); - if (sParcelableUUID.compareTo(parcelUuid.getUuid()) != 0) return null; + if (parcelUuid == null + || sParcelableUUID.compareTo(parcelUuid.getUuid()) != 0) { + return null; + } // Attempt to retrieve the WebContents object from the native pointer. return WebContentsImplJni.get() @@ -162,10 +172,10 @@ private final List<RenderFrameHostImpl> mFrames = new ArrayList<>(); private long mNativeWebContentsAndroid; - private NavigationController mNavigationController; + private @Nullable NavigationController mNavigationController; // Lazily created proxy observer for handling all Java-based WebContentsObservers. - private WebContentsObserverProxy mObserverProxy; + private @Nullable WebContentsObserverProxy mObserverProxy; class SmartClipCallback { public SmartClipCallback(final Handler smartClipHandler) { @@ -190,11 +200,11 @@ final Handler mHandler; } - private SmartClipCallback mSmartClipCallback; + private @Nullable SmartClipCallback mSmartClipCallback; - private EventForwarder mEventForwarder; + private @Nullable EventForwarder mEventForwarder; - private StylusWritingHandler mStylusWritingHandler; + private @Nullable StylusWritingHandler mStylusWritingHandler; // Cached copy of all positions and scales as reported by the renderer. private RenderCoordinatesImpl mRenderCoordinates; @@ -206,13 +216,13 @@ private boolean mInitialized; // Remember the stack for clearing native the native stack for debugging use after destroy. - private Throwable mNativeDestroyThrowable; + private @Nullable Throwable mNativeDestroyThrowable; - private ObserverList<Runnable> mTearDownDialogOverlaysHandlers; + private @Nullable ObserverList<Runnable> mTearDownDialogOverlaysHandlers; private static class WebContentsInternalsImpl implements WebContentsInternals { - public UserDataHost userDataHost; - public ViewAndroidDelegate viewAndroidDelegate; + public final UserDataHost userDataHost = new UserDataHost(); + public @Nullable ViewAndroidDelegate viewAndroidDelegate; } private WebContentsImpl( @@ -230,6 +240,7 @@ } @Override + @Initializer public void setDelegates( String productVersion, ViewAndroidDelegate viewDelegate, @@ -245,7 +256,6 @@ internals = (WebContentsInternalsImpl) mInternalsHolder.get(); } else { internals = new WebContentsInternalsImpl(); - internals.userDataHost = new UserDataHost(); } mInternalsHolder = internalsHolder; mInternalsHolder.set(internals); @@ -281,15 +291,14 @@ } } - @Nullable - public Context getContext() { + public @Nullable Context getContext() { assert mInitialized; WindowAndroid window = getTopLevelNativeWindow(); return window != null ? window.getContext().get() : null; } - public String getProductVersion() { + public @Nullable String getProductVersion() { assert mInitialized; return mProductVersion; } @@ -344,13 +353,13 @@ } @Override - public WindowAndroid getTopLevelNativeWindow() { + public @Nullable WindowAndroid getTopLevelNativeWindow() { checkNotDestroyed(); return WebContentsImplJni.get().getTopLevelNativeWindow(mNativeWebContentsAndroid); } @Override - public void setTopLevelNativeWindow(WindowAndroid windowAndroid) { + public void setTopLevelNativeWindow(@Nullable WindowAndroid windowAndroid) { checkNotDestroyed(); WebContentsImplJni.get().setTopLevelNativeWindow(mNativeWebContentsAndroid, windowAndroid); WindowEventObserverManager.from(this).onWindowAndroidChanged(windowAndroid); @@ -358,7 +367,8 @@ } @Override - public ViewAndroidDelegate getViewAndroidDelegate() { + public @Nullable ViewAndroidDelegate getViewAndroidDelegate() { + // TODO(agrieve): I suspect this never returns null... if (mInternalsHolder == null) return null; WebContentsInternals internals = mInternalsHolder.get(); if (internals == null) return null; @@ -407,7 +417,7 @@ } @Override - public NavigationController getNavigationController() { + public @Nullable NavigationController getNavigationController() { return mNavigationController; } @@ -605,7 +615,7 @@ WebContentsImplJni.get().collapseSelection(mNativeWebContentsAndroid); } - private SelectionPopupControllerImpl getSelectionPopupController() { + private @Nullable SelectionPopupControllerImpl getSelectionPopupController() { return SelectionPopupControllerImpl.fromWebContents(this); } @@ -708,14 +718,14 @@ } @Override - public void evaluateJavaScript(String script, JavaScriptCallback callback) { + public void evaluateJavaScript(String script, @Nullable JavaScriptCallback callback) { ThreadUtils.assertOnUiThread(); if (isDestroyed() || script == null) return; WebContentsImplJni.get().evaluateJavaScript(mNativeWebContentsAndroid, script, callback); } @Override - public void evaluateJavaScriptForTests(String script, JavaScriptCallback callback) { + public void evaluateJavaScriptForTests(String script, @Nullable JavaScriptCallback callback) { ThreadUtils.assertOnUiThread(); if (script == null) return; checkNotDestroyed(); @@ -733,9 +743,9 @@ @Override public void postMessageToMainFrame( MessagePayload messagePayload, - String sourceOrigin, + @Nullable String sourceOrigin, String targetOrigin, - MessagePort[] ports) { + MessagePort @Nullable [] ports) { if (ports != null) { for (MessagePort port : ports) { if (port.isClosed() || port.isTransferred()) { @@ -862,13 +872,13 @@ } @Override - public StylusWritingImeCallback getStylusWritingImeCallback() { + public @Nullable StylusWritingImeCallback getStylusWritingImeCallback() { ImeAdapterImpl imeAdapter = ImeAdapterImpl.fromWebContents(this); if (imeAdapter == null) return null; return imeAdapter.getStylusWritingImeCallback(); } - public StylusWritingHandler getStylusWritingHandler() { + public @Nullable StylusWritingHandler getStylusWritingHandler() { return mStylusWritingHandler; } @@ -886,14 +896,16 @@ return mStylusWritingHandler != null && mStylusWritingHandler.handleTouchEvent( motionEvent, - getViewAndroidDelegate().getContainerView()); + assumeNonNull(getViewAndroidDelegate()) + .getContainerView()); } @Override public void handleHoverEvent(MotionEvent motionEvent) { if (mStylusWritingHandler != null) { mStylusWritingHandler.handleHoverEvent( - motionEvent, getViewAndroidDelegate().getContainerView()); + motionEvent, + assumeNonNull(getViewAndroidDelegate()).getContainerView()); } } }); @@ -1038,8 +1050,8 @@ * not created yet, or {@code userDataFactory} is null, or the internal data * storage is already garbage-collected. */ - public <T extends UserData> T getOrSetUserData( - Class<T> key, UserDataFactory<T> userDataFactory) { + public <T extends UserData> @Nullable T getOrSetUserData( + Class<T> key, @Nullable UserDataFactory<T> userDataFactory) { // For tests that go without calling |initialize|. if (!mInitialized) return null; @@ -1073,7 +1085,6 @@ WebContentsInternalsImpl internals = (WebContentsInternalsImpl) mInternalsHolder.get(); if (internals == null) { internals = new WebContentsInternalsImpl(); - internals.userDataHost = new UserDataHost(); } mInternalsHolder.set(internals); mInitialized = true; @@ -1084,7 +1095,8 @@ // Be sure to call initializeForTesting() first. assert mInitialized; - WebContentsInternalsImpl internals = (WebContentsInternalsImpl) mInternalsHolder.get(); + WebContentsInternalsImpl internals = + assumeNonNull((WebContentsInternalsImpl) mInternalsHolder.get()); internals.userDataHost.setUserData(key, userData); } @@ -1098,7 +1110,7 @@ * @return {@code UserDataHost} that contains internal user data. {@code null} if * it is already gc'ed. */ - private UserDataHost getUserDataHost() { + private @Nullable UserDataHost getUserDataHost() { if (mInternalsHolder == null) return null; WebContentsInternals internals = mInternalsHolder.get(); if (internals == null) return null; @@ -1262,9 +1274,11 @@ void clearNativeReference(long nativeWebContentsAndroid); + @Nullable WindowAndroid getTopLevelNativeWindow(long nativeWebContentsAndroid); - void setTopLevelNativeWindow(long nativeWebContentsAndroid, WindowAndroid windowAndroid); + void setTopLevelNativeWindow( + long nativeWebContentsAndroid, @Nullable WindowAndroid windowAndroid); RenderFrameHost getMainFrame(long nativeWebContentsAndroid); @@ -1354,19 +1368,23 @@ void resumeLoadingCreatedWebContents(long nativeWebContentsAndroid); void evaluateJavaScript( - long nativeWebContentsAndroid, String script, JavaScriptCallback callback); + long nativeWebContentsAndroid, + String script, + @Nullable JavaScriptCallback callback); void evaluateJavaScriptForTests( - long nativeWebContentsAndroid, String script, JavaScriptCallback callback); + long nativeWebContentsAndroid, + String script, + @Nullable JavaScriptCallback callback); void addMessageToDevToolsConsole(long nativeWebContentsAndroid, int level, String message); void postMessageToMainFrame( long nativeWebContentsAndroid, MessagePayload payload, - String sourceOrigin, + @Nullable String sourceOrigin, String targetOrigin, - MessagePort[] ports); + MessagePort @Nullable [] ports); boolean hasAccessedInitialDocument(long nativeWebContentsAndroid);
diff --git a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java index 4461469..c41e825 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java +++ b/content/public/android/java/src/org/chromium/content/browser/webcontents/WebContentsObserverProxy.java
@@ -12,6 +12,8 @@ import org.chromium.base.ObserverList.RewindableIterator; import org.chromium.base.TerminationStatus; import org.chromium.base.ThreadUtils; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.GlobalRenderFrameHostId; import org.chromium.content_public.browser.LifecycleState; import org.chromium.content_public.browser.LoadCommittedDetails; @@ -30,6 +32,7 @@ * avoiding redundant JNI-related work when there are multiple Java-based observers. */ @JNINamespace("content") +@NullMarked class WebContentsObserverProxy extends WebContentsObserver { private long mNativeWebContentsObserverProxy; private final ObserverList<WebContentsObserver> mObservers; @@ -482,7 +485,7 @@ } @Override - public void onTopLevelNativeWindowChanged(WindowAndroid windowAndroid) { + public void onTopLevelNativeWindowChanged(@Nullable WindowAndroid windowAndroid) { handleObserverCall(); Iterator<WebContentsObserver> observersIterator = mObservers.iterator(); for (; observersIterator.hasNext(); ) {
diff --git a/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialsCreationDelegate.java b/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialsCreationDelegate.java index df32019..90150f27 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialsCreationDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/webid/DigitalCredentialsCreationDelegate.java
@@ -7,12 +7,14 @@ import android.app.Activity; import org.chromium.base.Promise; +import org.chromium.build.annotations.NullMarked; /** * Delegate interface for calling into GMSCore's private identity credentials. * * <p>TODO(crbug.com/380039257) delete this once GMSCore publishes this API. */ +@NullMarked public interface DigitalCredentialsCreationDelegate { public Promise<String> create(Activity window, String origin, String request); }
diff --git a/content/public/android/java/src/org/chromium/content/browser/webid/IdentityCredentialsDelegate.java b/content/public/android/java/src/org/chromium/content/browser/webid/IdentityCredentialsDelegate.java index d61833e..d3a0408 100644 --- a/content/public/android/java/src/org/chromium/content/browser/webid/IdentityCredentialsDelegate.java +++ b/content/public/android/java/src/org/chromium/content/browser/webid/IdentityCredentialsDelegate.java
@@ -25,16 +25,20 @@ import org.chromium.base.Log; import org.chromium.base.Promise; import org.chromium.base.ServiceLoaderUtil; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; import java.util.Arrays; +@NullMarked public class IdentityCredentialsDelegate { private static final String TAG = "IdentityCredentials"; // Arbitrary request code that is used when invoking the GMSCore API. private static final int REQUEST_CODE_DIGITAL_CREDENTIALS = 777; - public Promise<String> get(String origin, String request) { + public @Nullable Promise<String> get(String origin, String request) { // TODO(crbug.com/40257092): implement this. return null; } @@ -54,6 +58,7 @@ ResultReceiver resultReceiver = new ResultReceiver(new Handler(Looper.getMainLooper())) { // android.credentials.GetCredentialException requires API level 34 + @NullUnmarked @SuppressLint("NewApi") @Override protected void onReceiveResult(int code, Bundle data) {
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallback.java b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallback.java index 98bfb963..49bfa61 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallback.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallback.java
@@ -8,12 +8,14 @@ import android.view.ActionMode; import android.view.View; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * An {@link ActionMode.Callback2} adapter that adds APIs that are not dependent on * {@link ActionMode}, {@link android.view.Menu} or {@link android.view.MenuItem}. */ +@NullMarked public abstract class ActionModeCallback extends ActionMode.Callback2 { /** * Callback for handling drop-down menu item clicks. @@ -28,5 +30,5 @@ int groupId, int id, @Nullable Intent intent, - @Nullable View.OnClickListener clickListener); + View.@Nullable OnClickListener clickListener); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java index 6c8619f..17344e35 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ActionModeCallbackHelper.java
@@ -12,8 +12,8 @@ import android.view.View; import android.webkit.WebSettings; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.selection.SelectionPopupControllerImpl; /** @@ -21,6 +21,7 @@ * {@link android.view.ActionMode}. Exposes the functionality of the class * for embedder to provide with the callback instance that interacts with it. */ +@NullMarked public abstract class ActionModeCallbackHelper { private static final String TAG = "ActionModeHelper"; @@ -71,7 +72,7 @@ int groupId, int id, @Nullable Intent intent, - @Nullable View.OnClickListener clickListener) { + View.@Nullable OnClickListener clickListener) { return false; } } @@ -100,8 +101,7 @@ * @return {@link RenderFrameHost} object only available during page selection, * if there is a valid ActionMode available. */ - @Nullable - public abstract RenderFrameHost getRenderFrameHost(); + public abstract @Nullable RenderFrameHost getRenderFrameHost(); /** * Set the action mode menu items allowed on the content. @@ -144,7 +144,7 @@ int groupId, int id, @Nullable Intent intent, - @Nullable View.OnClickListener clickListener); + View.@Nullable OnClickListener clickListener); /** * @see {@link ActionMode.Callback#onDestroyActionMode(ActionMode)}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/AdditionalNavigationParams.java b/content/public/android/java/src/org/chromium/content_public/browser/AdditionalNavigationParams.java index e88846f4..ccf769f9 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/AdditionalNavigationParams.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/AdditionalNavigationParams.java
@@ -4,15 +4,16 @@ package org.chromium.content_public.browser; -import androidx.annotation.Nullable; - import org.chromium.base.UnguessableToken; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Holds parameters for NavigationController::LoadUrlParams::AdditionalNavigationParams. This is * used to route information about the initiator frame to the navigation request, which is needed * for event-level reporting to function properly. */ +@NullMarked public class AdditionalNavigationParams { private final UnguessableToken mInitiatorFrameToken; private final int mInitiatorProcessId;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/BrowserContextHandle.java b/content/public/android/java/src/org/chromium/content_public/browser/BrowserContextHandle.java index 82c086b..6b256af 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/BrowserContextHandle.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/BrowserContextHandle.java
@@ -4,7 +4,10 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** An interface that provides access to a native BrowserContext. */ +@NullMarked public interface BrowserContextHandle { /** @return A pointer to the native BrowserContext that this object wraps. */ long getNativeBrowserContextPointer();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ChildProcessLauncherHelper.java b/content/public/android/java/src/org/chromium/content_public/browser/ChildProcessLauncherHelper.java index db34dfdf..0a84b9b 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ChildProcessLauncherHelper.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ChildProcessLauncherHelper.java
@@ -6,9 +6,11 @@ import android.content.Context; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.ChildProcessLauncherHelperImpl; /** Interface for helper launching child processes. */ +@NullMarked public final class ChildProcessLauncherHelper { private ChildProcessLauncherHelper() {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ClientDataJson.java b/content/public/android/java/src/org/chromium/content_public/browser/ClientDataJson.java index 0360b1d..43fdd403 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ClientDataJson.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ClientDataJson.java
@@ -4,14 +4,14 @@ package org.chromium.content_public.browser; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.chromium.blink.mojom.PaymentOptions; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.ClientDataJsonImpl; import org.chromium.url.Origin; /** A utility class for WebAuthn to process the clientDataJson data structure in the API. */ +@NullMarked public final class ClientDataJson { private ClientDataJson() {} @@ -29,11 +29,10 @@ * @param topOrigin The origin of the page. * @return The string of the JSON, can be null when error happens. */ - @Nullable - public static String buildClientDataJson( + public static @Nullable String buildClientDataJson( @ClientDataRequestType int clientDataRequestType, - @NonNull String callerOrigin, - @NonNull byte[] challenge, + String callerOrigin, + byte[] challenge, boolean isCrossOrigin, @Nullable PaymentOptions paymentOptions, @Nullable String relyingPartyId,
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContactsPicker.java b/content/public/android/java/src/org/chromium/content_public/browser/ContactsPicker.java index d0fc63f..6cba3b59 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContactsPicker.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContactsPicker.java
@@ -6,21 +6,25 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + /** * A utility class that allows the embedder to provide a Contacts Picker implementation to content. */ +@NullMarked public final class ContactsPicker { /** * The current delegate for the contacts picker, or null if navigator.contacts is not * supported. */ - private static ContactsPickerDelegate sContactsPickerDelegate; + private static @Nullable ContactsPickerDelegate sContactsPickerDelegate; /** * The object that represents the currently visible contacts picker UI, or null if none is * visible. */ - private static Object sPicker; + private static @Nullable Object sPicker; private ContactsPicker() {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerDelegate.java b/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerDelegate.java index 60c93a7d..62adcf5 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerDelegate.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerDelegate.java
@@ -4,7 +4,10 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** A delegate interface for the contacts picker. */ +@NullMarked public interface ContactsPickerDelegate { /** * Called to display the contacts picker.
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerListener.java b/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerListener.java index 84165c4..6f2d9cd 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerListener.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContactsPickerListener.java
@@ -7,6 +7,8 @@ import androidx.annotation.IntDef; import org.chromium.blink.mojom.ContactIconBlob; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.payments.mojom.PaymentAddress; import java.lang.annotation.Retention; @@ -16,14 +18,15 @@ import java.util.List; /** The callback used to indicate what action the user took in the picker. */ +@NullMarked public interface ContactsPickerListener { /** A container class for exchanging contact details. */ public static class Contact { public final List<String> names; public final List<String> emails; public final List<String> tel; - public final List<ByteBuffer> serializedAddresses; - public final List<ByteBuffer> serializedIcons; + public final @Nullable List<ByteBuffer> serializedAddresses; + public final @Nullable List<ByteBuffer> serializedIcons; public Contact( List<String> contactNames,
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java index 12fbc32..e1b7864 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureList.java
@@ -4,7 +4,10 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** Convenience static methods to access {@link ContentFeatureMap}. */ +@NullMarked public class ContentFeatureList { private ContentFeatureList() {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureMap.java b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureMap.java index 1bed717..1cb01bf 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureMap.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContentFeatureMap.java
@@ -8,9 +8,11 @@ import org.jni_zero.NativeMethods; import org.chromium.base.FeatureMap; +import org.chromium.build.annotations.NullMarked; /** Java accessor for base::Features listed in content/browser/android/content_feature_map.cc. */ @JNINamespace("content::android") +@NullMarked public class ContentFeatureMap extends FeatureMap { private static final ContentFeatureMap sInstance = new ContentFeatureMap();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContentViewStatics.java b/content/public/android/java/src/org/chromium/content_public/browser/ContentViewStatics.java index 7a17071e..31adbfe 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContentViewStatics.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContentViewStatics.java
@@ -4,9 +4,11 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.ContentViewStaticsImpl; /** Implementations of various static methods. */ +@NullMarked public class ContentViewStatics { /** * Suspends Webkit timers in all renderers.
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ContentWebFeatureUsageUtils.java b/content/public/android/java/src/org/chromium/content_public/browser/ContentWebFeatureUsageUtils.java index bff3af42..120b235 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ContentWebFeatureUsageUtils.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ContentWebFeatureUsageUtils.java
@@ -8,9 +8,11 @@ import org.jni_zero.NativeMethods; import org.chromium.blink.mojom.WebFeature; +import org.chromium.build.annotations.NullMarked; /** A Java API for calling ContentBrowserClient::LogWebFeatureForCurrentPage(). */ @JNINamespace("content") +@NullMarked public class ContentWebFeatureUsageUtils { public static void logWebFeatureForCurrentPage( WebContents webContents, @WebFeature.EnumType int webFeature) {
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/GestureListenerManager.java b/content/public/android/java/src/org/chromium/content_public/browser/GestureListenerManager.java index 43cd669..713a8d1 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/GestureListenerManager.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/GestureListenerManager.java
@@ -4,6 +4,8 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.cc.mojom.RootScrollOffsetUpdateFrequency; import org.chromium.content.browser.GestureListenerManagerImpl; @@ -11,13 +13,14 @@ * Manages the {@link GestureStateListener} instances observing various gesture * events notifications from content layer. */ +@NullMarked public interface GestureListenerManager { /** * @param webContents {@link WebContents} object. * @return {@link GestureListenerManager} object used for the give WebContents. * Creates one if not present. */ - static GestureListenerManager fromWebContents(WebContents webContents) { + static @Nullable GestureListenerManager fromWebContents(WebContents webContents) { return GestureListenerManagerImpl.fromWebContents(webContents); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java b/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java index 87ebaaee..7bbcc5f 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/GestureStateListener.java
@@ -4,10 +4,13 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** * An interface that is notified of events and state changes related to gesture processing * from content layer. */ +@NullMarked public abstract class GestureStateListener { /** Called when the pinch gesture starts. */ public void onPinchStarted() {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/GlobalRenderFrameHostId.java b/content/public/android/java/src/org/chromium/content_public/browser/GlobalRenderFrameHostId.java index af6e1d8d..2b80349 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/GlobalRenderFrameHostId.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/GlobalRenderFrameHostId.java
@@ -4,12 +4,15 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + import java.util.Objects; /** * Identifies a RenderFrameHost. * See the native equivalent: content::GlobalRenderFrameHostId. */ +@NullMarked public final class GlobalRenderFrameHostId { // Note that this is an internal identifier, not the PID from the OS. private final int mChildId;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java b/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java index 7d0b219..682351b7 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/HostZoomMap.java
@@ -4,14 +4,15 @@ package org.chromium.content_public.browser; -import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.HostZoomMapImpl; import java.util.Map; /** Implementations of various static methods related to page zoom. */ +@NullMarked public class HostZoomMap { // Preset zoom factors that the +/- buttons can "snap" the zoom level to if user chooses to // not use the slider. These zoom factors correspond to the zoom levels that are used on @@ -41,7 +42,7 @@ * @param webContents WebContents to update * @param newZoomLevel double - new zoom level */ - public static void setZoomLevel(@NonNull WebContents webContents, double newZoomLevel) { + public static void setZoomLevel(WebContents webContents, double newZoomLevel) { assert !webContents.isDestroyed(); // Just before sending the zoom level to the backend, we will take into account the system @@ -75,7 +76,7 @@ * @param webContents WebContents to get zoom level for * @return double current zoom level */ - public static double getZoomLevel(@NonNull WebContents webContents) { + public static double getZoomLevel(WebContents webContents) { assert !webContents.isDestroyed(); // Just before returning a zoom level from the backend, we must again take into account the
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ImageDownloadCallback.java b/content/public/android/java/src/org/chromium/content_public/browser/ImageDownloadCallback.java index 30a013e..d6c44a4 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ImageDownloadCallback.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ImageDownloadCallback.java
@@ -7,11 +7,13 @@ import android.graphics.Bitmap; import android.graphics.Rect; +import org.chromium.build.annotations.NullMarked; import org.chromium.url.GURL; import java.util.List; /** Java counterpart of native ImageDownloadCallback. */ +@NullMarked public interface ImageDownloadCallback { /** * Called when image downloading is completed.
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ImeAdapter.java b/content/public/android/java/src/org/chromium/content_public/browser/ImeAdapter.java index c7599150..b30e43af 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ImeAdapter.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ImeAdapter.java
@@ -11,10 +11,13 @@ import androidx.annotation.VisibleForTesting; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.input.ImeAdapterImpl; import org.chromium.ui.base.WindowAndroid; /** Adapts and plumbs android IME service onto the chrome text input API. */ +@NullMarked public interface ImeAdapter { /** Composition key code sent when user either hit a key or hit a selection. */ static final int COMPOSITION_KEY_CODE = 229; @@ -44,6 +47,7 @@ * @return the active {@link InputConnection} that the IME uses to communicate updates to its * clients. */ + @Nullable InputConnection getActiveInputConnection(); /** @@ -59,6 +63,7 @@ /** * @see View#onCreateInputConnection(EditorInfo) */ + @Nullable InputConnection onCreateInputConnection(EditorInfo outAttrs); /** @@ -92,6 +97,7 @@ ResultReceiver getNewShowKeyboardReceiver(); /** Get the current input connection for testing purposes. */ + @Nullable InputConnection getInputConnectionForTest(); /**
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ImeEventObserver.java b/content/public/android/java/src/org/chromium/content_public/browser/ImeEventObserver.java index 0e4a8f1..df855b9 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ImeEventObserver.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ImeEventObserver.java
@@ -6,7 +6,10 @@ import android.view.KeyEvent; +import org.chromium.build.annotations.NullMarked; + /** Interface for the classes that need to be notified of IME changes. */ +@NullMarked public interface ImeEventObserver { /** Called to notify the delegate about synthetic/real key events before sending to renderer. */ default void onImeEvent() {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java b/content/public/android/java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java index 96c4382..ae36d93 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/InputMethodManagerWrapper.java
@@ -9,9 +9,12 @@ import android.view.View; import android.view.inputmethod.CursorAnchorInfo; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; /** Wrapper around Android's InputMethodManager so that the implementation can be swapped out. */ +@NullMarked public interface InputMethodManagerWrapper { /** An embedder may implement this for multi-display support. */ public interface Delegate { @@ -32,13 +35,14 @@ /** * @see android.view.inputmethod.InputMethodManager#isActive(View) */ - boolean isActive(View view); + boolean isActive(@Nullable View view); /** * @see android.view.inputmethod.InputMethodManager#hideSoftInputFromWindow(IBinder, int, * ResultReceiver) */ - boolean hideSoftInputFromWindow(IBinder windowToken, int flags, ResultReceiver resultReceiver); + boolean hideSoftInputFromWindow( + IBinder windowToken, int flags, @Nullable ResultReceiver resultReceiver); /** * @see android.view.inputmethod.InputMethodManager#updateSelection(View, int, int, int, int) @@ -56,13 +60,14 @@ * @see android.view.inputmethod.InputMethodManager * #updateExtractedText(View,int, ExtractedText) */ - void updateExtractedText(View view, int token, android.view.inputmethod.ExtractedText text); + void updateExtractedText( + View view, int token, android.view.inputmethod.@Nullable ExtractedText text); /** * Call this when WindowAndroid object has changed. * @param newWindowAndroid The new WindowAndroid object. */ - void onWindowAndroidChanged(WindowAndroid newWindowAndroid); + void onWindowAndroidChanged(@Nullable WindowAndroid newWindowAndroid); /** Call this when non-null InputConnection has been created. */ void onInputConnectionCreated();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/InputTransferHandler.java b/content/public/android/java/src/org/chromium/content_public/browser/InputTransferHandler.java index 67b31b0..bce53412 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/InputTransferHandler.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/InputTransferHandler.java
@@ -14,11 +14,15 @@ import org.chromium.base.ContextUtils; import org.chromium.base.TraceEvent; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.NullUnmarked; +import org.chromium.build.annotations.Nullable; @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) +@NullMarked public class InputTransferHandler { private InputTransferToken mBrowserToken; - private InputTransferToken mVizToken; + private @Nullable InputTransferToken mVizToken; public InputTransferHandler(InputTransferToken browserToken) { mBrowserToken = browserToken; @@ -34,6 +38,7 @@ mVizToken = token; } + @NullUnmarked public boolean maybeTransferInputToViz() { if (!canTransferInputToViz()) { return false;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java b/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java index 79774a3..96d64a4 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/InterfaceRegistrar.java
@@ -4,6 +4,8 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.services.service_manager.InterfaceRegistry; import java.util.ArrayList; @@ -15,15 +17,16 @@ * @param <ParamType> the type of parameter to pass to the InterfaceRegistrar when adding its * interfaces to an InterfaceRegistry */ +@NullMarked public interface InterfaceRegistrar<ParamType> { /** Invoked to register interfaces on |registry|, parametrized by |paramValue|. */ - public void registerInterfaces(InterfaceRegistry registry, ParamType paramValue); + public void registerInterfaces(InterfaceRegistry registry, @Nullable ParamType paramValue); /** A registry of InterfaceRegistrars. */ public static class Registry<ParamType> { - private static Registry<Void> sSingletonRegistry; - private static Registry<WebContents> sWebContentsRegistry; - private static Registry<RenderFrameHost> sRenderFrameHostRegistry; + private static @Nullable Registry<Void> sSingletonRegistry; + private static @Nullable Registry<WebContents> sWebContentsRegistry; + private static @Nullable Registry<RenderFrameHost> sRenderFrameHostRegistry; private List<InterfaceRegistrar<ParamType>> mRegistrars = new ArrayList<InterfaceRegistrar<ParamType>>(); @@ -79,7 +82,8 @@ mRegistrars.add(registrar); } - private void applyRegistrars(InterfaceRegistry interfaceRegistry, ParamType param) { + private void applyRegistrars( + InterfaceRegistry interfaceRegistry, @Nullable ParamType param) { for (InterfaceRegistrar<ParamType> registrar : mRegistrars) { registrar.registerInterfaces(interfaceRegistry, param); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/JavaScriptCallback.java b/content/public/android/java/src/org/chromium/content_public/browser/JavaScriptCallback.java index 1b572048..282f6b3 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/JavaScriptCallback.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/JavaScriptCallback.java
@@ -4,7 +4,10 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** Callback interface for WebContents evaluateJavaScript(). */ +@NullMarked public interface JavaScriptCallback { /** * Called from native in response to evaluateJavaScript().
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/JavascriptInjector.java b/content/public/android/java/src/org/chromium/content_public/browser/JavascriptInjector.java index 557c2a9..0e793d4b1 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/JavascriptInjector.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/JavascriptInjector.java
@@ -6,6 +6,8 @@ import android.util.Pair; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.JavascriptInjectorImpl; import java.lang.annotation.Annotation; @@ -15,13 +17,14 @@ * Interface that provides API used to inject user-defined objects that allow custom Javascript * interfaces. */ +@NullMarked public interface JavascriptInjector { /** * @param webContents {@link WebContents} object. * @return {@link JavascriptInjector} object used for the give WebContents. Creates one if not * present. */ - static JavascriptInjector fromWebContents(WebContents webContents) { + static @Nullable JavascriptInjector fromWebContents(WebContents webContents) { return JavascriptInjectorImpl.fromWebContents(webContents); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/KeyboardShortcutRecorder.java b/content/public/android/java/src/org/chromium/content_public/browser/KeyboardShortcutRecorder.java index 424fba7..d90e53c 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/KeyboardShortcutRecorder.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/KeyboardShortcutRecorder.java
@@ -7,11 +7,13 @@ import androidx.annotation.IntDef; import org.chromium.base.metrics.RecordHistogram; +import org.chromium.build.annotations.NullMarked; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** Records physical keyboard shortcut events. Suitable for use by any content embedder. */ +@NullMarked public class KeyboardShortcutRecorder { // This should be kept in sync with the definition |PhysicalKeyboardShortcut| in // tools/metrics/histograms/enums.xml and
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/LGEmailActionModeWorkaround.java b/content/public/android/java/src/org/chromium/content_public/browser/LGEmailActionModeWorkaround.java index a69adbc..5d1c133 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/LGEmailActionModeWorkaround.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/LGEmailActionModeWorkaround.java
@@ -4,6 +4,7 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.selection.LGEmailActionModeWorkaroundImpl; /** @@ -13,6 +14,7 @@ * a system update. However, LG Email team is committed to fixing this in the near future. * This is a version code limited workaround to avoid crashes in the app. */ +@NullMarked public final class LGEmailActionModeWorkaround { private LGEmailActionModeWorkaround() {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/LoadCommittedDetails.java b/content/public/android/java/src/org/chromium/content_public/browser/LoadCommittedDetails.java index 2f7935a..a7e9688 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/LoadCommittedDetails.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/LoadCommittedDetails.java
@@ -7,6 +7,7 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; import org.chromium.url.GURL; /** @@ -14,6 +15,7 @@ * {@link WebContentsObserver#navigationEntryCommitted(LoadCommittedDetails)}. */ @JNINamespace("content") +@NullMarked public class LoadCommittedDetails { private final boolean mDidReplaceEntry; private final int mPreviousEntryIndex;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java b/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java index 8ceb892..87108ed 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/LoadUrlParams.java
@@ -4,8 +4,6 @@ package org.chromium.content_public.browser; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import org.jni_zero.JNINamespace; @@ -13,6 +11,8 @@ import org.chromium.base.UserDataHost; import org.chromium.base.supplier.Supplier; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content_public.browser.navigation_controller.LoadURLType; import org.chromium.content_public.browser.navigation_controller.UserAgentOverrideOption; import org.chromium.content_public.common.Referrer; @@ -31,21 +31,22 @@ * values. */ @JNINamespace("content") +@NullMarked public class LoadUrlParams { // Fields with counterparts in NavigationController::LoadURLParams. private String mUrl; - private Origin mInitiatorOrigin; + private @Nullable Origin mInitiatorOrigin; private int mLoadUrlType; private int mTransitionType; - private Referrer mReferrer; - private Map<String, String> mExtraHeaders; - @Nullable private UserDataHost mNavigationHandleUserDataHost; - private String mVerbatimHeaders; + private @Nullable Referrer mReferrer; + private @Nullable Map<String, String> mExtraHeaders; + private @Nullable UserDataHost mNavigationHandleUserDataHost; + private @Nullable String mVerbatimHeaders; private int mUaOverrideOption; - private ResourceRequestBody mPostData; - private String mBaseUrlForDataUrl; - private String mVirtualUrlForSpecialCases; - private String mDataUrlAsString; + private @Nullable ResourceRequestBody mPostData; + private @Nullable String mBaseUrlForDataUrl; + private @Nullable String mVirtualUrlForSpecialCases; + private @Nullable String mDataUrlAsString; private boolean mCanLoadLocalResources; private boolean mIsRendererInitiated; private boolean mShouldReplaceCurrentEntry; @@ -53,8 +54,8 @@ private long mInputStartTimestamp; private boolean mHasUserGesture; private boolean mShouldClearHistoryList; - @Nullable private AdditionalNavigationParams mAdditionalNavigationParams; - private Supplier<Long> mNavigationUIDataSupplier; + private @Nullable AdditionalNavigationParams mAdditionalNavigationParams; + private @Nullable Supplier<Long> mNavigationUIDataSupplier; private boolean mIsPdf; /** @@ -105,7 +106,7 @@ * Creates a new LoadUrlParams that is a copy of {@code other}. * The user data host is intentionally not copied. */ - public static LoadUrlParams copy(@NonNull LoadUrlParams other) { + public static LoadUrlParams copy(LoadUrlParams other) { LoadUrlParams copy = new LoadUrlParams(other.mUrl); copy.mInitiatorOrigin = other.mInitiatorOrigin; copy.mLoadUrlType = other.mLoadUrlType; @@ -155,7 +156,7 @@ * does not require a special charset. */ public static LoadUrlParams createLoadDataParams( - String data, String mimeType, boolean isBase64Encoded, String charset) { + String data, String mimeType, boolean isBase64Encoded, @Nullable String charset) { LoadUrlParams params = new LoadUrlParams(buildDataUri(data, mimeType, isBase64Encoded, charset)); params.setLoadType(LoadURLType.DATA); @@ -164,7 +165,7 @@ } private static String buildDataUri( - String data, String mimeType, boolean isBase64Encoded, String charset) { + String data, String mimeType, boolean isBase64Encoded, @Nullable String charset) { StringBuilder dataUrl = new StringBuilder("data:"); dataUrl.append(mimeType); if (charset != null && !charset.isEmpty()) { @@ -222,7 +223,7 @@ boolean isBase64Encoded, String baseUrl, String historyUrl, - String charset) { + @Nullable String charset) { LoadUrlParams params; // For WebView compatibility, when the base URL has the 'data:' // scheme, we treat it as a regular data URL load and skip setting @@ -275,7 +276,7 @@ } /** Return the base url for a data url, otherwise null. */ - public String getBaseUrl() { + public @Nullable String getBaseUrl() { return mBaseUrlForDataUrl; } @@ -308,7 +309,7 @@ /** * @return the referrer of this load. */ - public Referrer getReferrer() { + public @Nullable Referrer getReferrer() { return mReferrer; } @@ -323,7 +324,7 @@ } /** Return the extra headers as a map. */ - public Map<String, String> getExtraHeaders() { + public @Nullable Map<String, String> getExtraHeaders() { return mExtraHeaders; } @@ -342,8 +343,7 @@ * Returns the user data to be added to the navigation handle. Clears out the existing user data * host on each call. May return null if there is no data. This is not part of the content API. */ - @Nullable - public UserDataHost takeNavigationHandleUserData() { + public @Nullable UserDataHost takeNavigationHandleUserData() { UserDataHost returnValue = mNavigationHandleUserDataHost; mNavigationHandleUserDataHost = null; return returnValue; @@ -356,7 +356,7 @@ * exploded form through setExtraHeaders(). Embedders that work with extra headers in opaque * collapsed form can use the setVerbatimHeaders() / getVerbatimHeaders() instead. */ - public String getExtraHeadersString() { + public @Nullable String getExtraHeadersString() { return getExtraHeadersString("\n", false); } @@ -365,11 +365,11 @@ * is set. This form is suitable for passing to native * net::HttpRequestHeaders::AddHeadersFromString. */ - public String getExtraHttpRequestHeadersString() { + public @Nullable String getExtraHttpRequestHeadersString() { return getExtraHeadersString("\r\n", true); } - private String getExtraHeadersString(String delimiter, boolean addTerminator) { + private @Nullable String getExtraHeadersString(String delimiter, boolean addTerminator) { if (mExtraHeaders == null) return null; StringBuilder headerBuilder = new StringBuilder(); @@ -407,7 +407,7 @@ /** * @return the verbatim extra headers string */ - public String getVerbatimHeaders() { + public @Nullable String getVerbatimHeaders() { return mVerbatimHeaders; } @@ -439,7 +439,7 @@ /** * @return the data to be sent through POST */ - public ResourceRequestBody getPostData() { + public @Nullable ResourceRequestBody getPostData() { return mPostData; } @@ -459,7 +459,7 @@ * * @return The virtual url for this data or pdf load. */ - public String getVirtualUrlForSpecialCases() { + public @Nullable String getVirtualUrlForSpecialCases() { return mVirtualUrlForSpecialCases; } @@ -479,7 +479,7 @@ * * @return The data url. */ - public String getDataUrlAsString() { + public @Nullable String getDataUrlAsString() { return mDataUrlAsString; } @@ -612,8 +612,7 @@ /** * @return The additional navigation params associated with the load. */ - @Nullable - public AdditionalNavigationParams getAdditionalNavigationParams() { + public @Nullable AdditionalNavigationParams getAdditionalNavigationParams() { return mAdditionalNavigationParams; } @@ -632,7 +631,7 @@ } /** Returns the supplier for {@link NavigationUIData} or null. */ - public Supplier<Long> getNavigationUIDataSupplier() { + public @Nullable Supplier<Long> getNavigationUIDataSupplier() { return mNavigationUIDataSupplier; } @@ -654,6 +653,6 @@ * Parses |url| as a GURL on the native side, and * returns true if it's scheme is data:. */ - boolean isDataScheme(String url); + boolean isDataScheme(@Nullable String url); } }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java b/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java index b83cdcc..61e00d8 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/MediaSession.java
@@ -4,18 +4,18 @@ package org.chromium.content_public.browser; -import androidx.annotation.Nullable; - import org.chromium.base.ObserverList; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.MediaSessionImpl; /** The MediaSession Java wrapper to allow communicating with the native MediaSession object. */ +@NullMarked public abstract class MediaSession { /** * @return The MediaSession associated with |contents|. */ - @Nullable - public static MediaSession fromWebContents(WebContents contents) { + public static @Nullable MediaSession fromWebContents(WebContents contents) { // TODO(zqzhang): directly call WebContentsImpl.getMediaSession() when WebContentsImpl // package restriction is removed. return MediaSessionImpl.fromWebContents(contents);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/MediaSessionObserver.java b/content/public/android/java/src/org/chromium/content_public/browser/MediaSessionObserver.java index 7e9869c..b12102f 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/MediaSessionObserver.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/MediaSessionObserver.java
@@ -4,8 +4,8 @@ package org.chromium.content_public.browser; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.MediaSessionImpl; import org.chromium.services.media_session.MediaImage; import org.chromium.services.media_session.MediaMetadata; @@ -19,8 +19,9 @@ * session messages from Java {@link MediaSession}, which acts acts as a proxy forwarding messages * comming from the native MediaSession. */ +@NullMarked public abstract class MediaSessionObserver { - private MediaSessionImpl mMediaSession; + private @Nullable MediaSessionImpl mMediaSession; /** Construct a MediaSessionObserver and start observing |mediaSession|. */ protected MediaSessionObserver(MediaSession mediaSession) { @@ -38,8 +39,7 @@ /** * @return The observed media session. */ - @Nullable - public final MediaSession getMediaSession() { + public final @Nullable MediaSession getMediaSession() { return mMediaSession; }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/MessagePayload.java b/content/public/android/java/src/org/chromium/content_public/browser/MessagePayload.java index 18260d3..4ea1828 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/MessagePayload.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/MessagePayload.java
@@ -4,8 +4,8 @@ package org.chromium.content_public.browser; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import java.util.Objects; @@ -13,10 +13,11 @@ * Represents a JavaScript message payload. * Currently only String and ArrayBuffer is supported. */ +@NullMarked public final class MessagePayload { @MessagePayloadType private final int mType; - @Nullable private final String mString; - @Nullable private final byte[] mArrayBuffer; + private final @Nullable String mString; + private final byte @Nullable [] mArrayBuffer; /** * Create a MessagePayload String type. @@ -30,7 +31,7 @@ } /** Create a MessagePayload ArrayBuffer type. */ - public MessagePayload(@NonNull byte[] arrayBuffer) { + public MessagePayload(byte[] arrayBuffer) { Objects.requireNonNull(arrayBuffer, "arrayBuffer cannot be null."); mType = MessagePayloadType.ARRAY_BUFFER; mArrayBuffer = arrayBuffer; @@ -42,13 +43,11 @@ return mType; } - @Nullable - public String getAsString() { + public @Nullable String getAsString() { checkType(MessagePayloadType.STRING); return mString; } - @NonNull public byte[] getAsArrayBuffer() { checkType(MessagePayloadType.ARRAY_BUFFER); Objects.requireNonNull(mArrayBuffer, "mArrayBuffer cannot be null."); @@ -65,7 +64,6 @@ } } - @NonNull public static String typeToString(@MessagePayloadType int type) { switch (type) { case MessagePayloadType.STRING:
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/MessagePort.java b/content/public/android/java/src/org/chromium/content_public/browser/MessagePort.java index 97b91cbd..ce7a2ec2 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/MessagePort.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/MessagePort.java
@@ -6,11 +6,14 @@ import android.os.Handler; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.build.annotations.UsedByReflection; import org.chromium.content.browser.AppWebMessagePort; /** Interface for message ports that handle postMessage requests. */ @UsedByReflection("") +@NullMarked public interface MessagePort { /** The message callback for receiving messages. */ public interface MessageCallback { @@ -19,7 +22,7 @@ * @param messagePayload The message payload that was received. * @param sentPorts The {@link MessagePort}s that were sent if any. */ - void onMessage(MessagePayload messagePayload, MessagePort[] sentPorts); + void onMessage(MessagePayload messagePayload, MessagePort @Nullable [] sentPorts); } /** @@ -63,5 +66,5 @@ * @param messagePayload The message payload to be sent. * @param sentPorts The ports to be transferred. */ - void postMessage(MessagePayload messagePayload, MessagePort[] sentPorts); + void postMessage(MessagePayload messagePayload, MessagePort @Nullable [] sentPorts); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/MotionEventSynthesizer.java b/content/public/android/java/src/org/chromium/content_public/browser/MotionEventSynthesizer.java index ecd9ba3..b0cfae6 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/MotionEventSynthesizer.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/MotionEventSynthesizer.java
@@ -6,9 +6,11 @@ import android.view.View; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.MotionEventSynthesizerImpl; /** Injects synthetic touch events. All the coordinates are of physical unit. */ +@NullMarked public interface MotionEventSynthesizer { public static MotionEventSynthesizer create(View target) { return MotionEventSynthesizerImpl.create(target);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java index 2734a8a..cc1c0b0 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationController.java
@@ -4,12 +4,14 @@ package org.chromium.content_public.browser; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * The NavigationController Java wrapper to allow communicating with the native * NavigationController object. */ +@NullMarked public interface NavigationController { /** * @return Whether back navigation is possible from the "current entry". @@ -95,7 +97,7 @@ * Get a copy of the navigation history of NavigationController. * @return navigation history of NavigationController. */ - public NavigationHistory getNavigationHistory(); + public @Nullable NavigationHistory getNavigationHistory(); /** * Get the navigation history of NavigationController from current navigation entry index @@ -105,7 +107,8 @@ * diection. * @return navigation history by keeping above constraints. */ - public NavigationHistory getDirectedNavigationHistory(boolean isForward, int itemLimit); + public @Nullable NavigationHistory getDirectedNavigationHistory( + boolean isForward, int itemLimit); /** Clears SSL preferences for this NavigationController. */ public void clearSslPreferences(); @@ -129,7 +132,7 @@ * @param index Index to retrieve the NavigationEntry for. * @return Entry containing info about the navigation, null if the index is out of bounds. */ - public NavigationEntry getEntryAtIndex(int index); + public @Nullable NavigationEntry getEntryAtIndex(int index); /** * @return The {@link NavigationEntry} that is appropriate to be displayed in the address bar. @@ -141,7 +144,7 @@ * @return The pending {@link NavigationEntry} for this controller or {@code null} if none * exists. */ - public NavigationEntry getPendingEntry(); + public @Nullable NavigationEntry getPendingEntry(); /** * @return The index of the last committed entry. @@ -167,6 +170,7 @@ * @param key The data key. * @return The data value, or null if not found. */ + @Nullable String getEntryExtraData(int index, String key); /**
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java index 5fe3e0f..d79eb98 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationEntry.java
@@ -6,11 +6,11 @@ import android.graphics.Bitmap; -import androidx.annotation.NonNull; - +import org.chromium.build.annotations.NullMarked; import org.chromium.url.GURL; /** Represents one entry in the navigation history of a page. */ +@NullMarked public class NavigationEntry { private final int mIndex; @@ -26,9 +26,9 @@ /** Default constructor. */ public NavigationEntry( int index, - @NonNull GURL url, - @NonNull GURL virtualUrl, - @NonNull GURL originalUrl, + GURL url, + GURL virtualUrl, + GURL originalUrl, String title, Bitmap favicon, int transition, @@ -57,7 +57,7 @@ * scary data: URL or something like that. Use GetVirtualURL() for * showing to the user. */ - public @NonNull GURL getUrl() { + public GURL getUrl() { return mUrl; } @@ -72,14 +72,14 @@ * cases, so if there is no overridden display URL, it will return * the actual one. */ - public @NonNull GURL getVirtualUrl() { + public GURL getVirtualUrl() { return mVirtualUrl; } /** * @return The URL that caused this NavigationEntry to be created. */ - public @NonNull GURL getOriginalUrl() { + public GURL getOriginalUrl() { return mOriginalUrl; }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java index 89b61b64..063abe9b 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHandle.java
@@ -4,13 +4,14 @@ package org.chromium.content_public.browser; -import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; import org.chromium.base.UserDataHost; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.net.NetError; import org.chromium.ui.base.PageTransition; import org.chromium.url.GURL; @@ -18,15 +19,16 @@ /** JNI bridge with content::NavigationHandle */ @JNINamespace("content") +@NullMarked public class NavigationHandle { private long mNativeNavigationHandle; private boolean mIsInPrimaryMainFrame; private boolean mIsRendererInitiated; private boolean mIsSameDocument; private @PageTransition int mPageTransition; - private GURL mUrl; - private GURL mReferrerUrl; - private GURL mBaseUrlForDataUrl; + private @Nullable GURL mUrl; + private @Nullable GURL mReferrerUrl; + private @Nullable GURL mBaseUrlForDataUrl; private boolean mHasCommitted; private boolean mIsDownload; private boolean mIsErrorPage; @@ -34,7 +36,7 @@ private boolean mIsValidSearchFormUrl; private @NetError int mErrorCode; private int mHttpStatusCode; - private Origin mInitiatorOrigin; + private @Nullable Origin mInitiatorOrigin; private boolean mIsPost; private boolean mHasUserGesture; private boolean mIsRedirect; @@ -42,13 +44,13 @@ private long mNavigationId; private boolean mIsPageActivation; private boolean mIsReload; - private UserDataHost mUserDataHost; + private @Nullable UserDataHost mUserDataHost; private boolean mIsPdf; - private String mMimeType; + private @Nullable String mMimeType; private boolean mIsSaveableNavigation; public static NavigationHandle createForTesting( - @NonNull GURL url, + GURL url, boolean isRendererInitiated, @PageTransition int transition, boolean hasUserGesture) { @@ -64,7 +66,7 @@ } public static NavigationHandle createForTesting( - @NonNull GURL url, + GURL url, boolean isInPrimaryMainFrame, boolean isSameDocument, boolean isRendererInitiated, @@ -83,7 +85,7 @@ } public static NavigationHandle createForTesting( - @NonNull GURL url, + GURL url, boolean isInPrimaryMainFrame, boolean isSameDocument, boolean isRendererInitiated, @@ -123,13 +125,13 @@ @CalledByNative private void initialize( long unused_nativeNavigationHandleProxy, - @NonNull GURL url, - @NonNull GURL referrerUrl, - @NonNull GURL baseUrlForDataUrl, + GURL url, + GURL referrerUrl, + GURL baseUrlForDataUrl, boolean isInPrimaryMainFrame, boolean isSameDocument, boolean isRendererInitiated, - Origin initiatorOrigin, + @Nullable Origin initiatorOrigin, @PageTransition int transition, boolean isPost, boolean hasUserGesture, @@ -178,7 +180,7 @@ @CalledByNative @VisibleForTesting public void didFinish( - @NonNull GURL url, + GURL url, boolean isErrorPage, boolean hasCommitted, boolean isPrimaryMainFrameFragmentNavigation, @@ -220,20 +222,17 @@ * The URL the frame is navigating to. This may change during the navigation when encountering * a server redirect. */ - @NonNull - public GURL getUrl() { + public @Nullable GURL getUrl() { return mUrl; } /** The referrer URL for the navigation. */ - @NonNull - public GURL getReferrerUrl() { + public @Nullable GURL getReferrerUrl() { return mReferrerUrl; } /** Used for specifying a base URL for pages loaded via data URLs. */ - @NonNull - public GURL getBaseUrlForDataUrl() { + public @Nullable GURL getBaseUrlForDataUrl() { return mBaseUrlForDataUrl; } @@ -344,7 +343,7 @@ * Get the Origin that initiated this navigation. May be null in the case of navigations * originating from the browser. */ - public Origin getInitiatorOrigin() { + public @Nullable Origin getInitiatorOrigin() { return mInitiatorOrigin; } @@ -395,7 +394,7 @@ } /** Sets the user data host. This should not be considered part of the content API. */ - public void setUserDataHost(UserDataHost userDataHost) { + public void setUserDataHost(@Nullable UserDataHost userDataHost) { mUserDataHost = userDataHost; } @@ -405,7 +404,7 @@ } /** MIME type of the page. */ - public String getMimeType() { + public @Nullable String getMimeType() { return mMimeType; }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHistory.java b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHistory.java index 76f148f..4e83e55 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/NavigationHistory.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/NavigationHistory.java
@@ -4,7 +4,7 @@ package org.chromium.content_public.browser; -// import org.chromium.content_public.browser.NavigationEntry; +import org.chromium.build.annotations.NullMarked; import java.util.ArrayList; @@ -13,6 +13,7 @@ * {@link WebContents}. It is a copy and will not be updated as navigation * occurs on the source {@link WebContents}. */ +@NullMarked public class NavigationHistory { private final ArrayList<NavigationEntry> mEntries = new ArrayList<NavigationEntry>();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/PermissionsPolicyFeature.java b/content/public/android/java/src/org/chromium/content_public/browser/PermissionsPolicyFeature.java index 3c7a6fe..a93433d4 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/PermissionsPolicyFeature.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/PermissionsPolicyFeature.java
@@ -6,12 +6,15 @@ import androidx.annotation.IntDef; +import org.chromium.build.annotations.NullMarked; + import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; // TODO(crbug.com/40707311): This file should be generated with all permissions policy enum values. @IntDef({PermissionsPolicyFeature.PAYMENT, PermissionsPolicyFeature.WEB_SHARE}) @Retention(RetentionPolicy.SOURCE) +@NullMarked public @interface PermissionsPolicyFeature { int PAYMENT = org.chromium.blink.mojom.PermissionsPolicyFeature.PAYMENT; int WEB_SHARE = org.chromium.blink.mojom.PermissionsPolicyFeature.WEB_SHARE;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java b/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java index 7176c04..9f3f62c 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/RenderCoordinates.java
@@ -4,9 +4,11 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.RenderCoordinatesImpl; /** Provides dimension/coordinate information of the view rendered by content layer. */ +@NullMarked public interface RenderCoordinates { /** * @return {@link Coord} instance associated with the given {@link WebContents}.
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java b/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java index d6fefe44..6e9c34cb0 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/RenderFrameHost.java
@@ -4,10 +4,10 @@ package org.chromium.content_public.browser; -import androidx.annotation.Nullable; - import org.chromium.base.Callback; import org.chromium.blink.mojom.AuthenticatorStatus; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.mojo.bindings.Interface; import org.chromium.url.GURL; import org.chromium.url.Origin; @@ -17,6 +17,7 @@ /** * The RenderFrameHost Java wrapper to allow communicating with the native RenderFrameHost object. */ +@NullMarked public interface RenderFrameHost { /** The results of {@link #GetAssertionWebAuthSecurityChecks}. */ final class WebAuthSecurityChecksResults { @@ -85,7 +86,7 @@ * * @return A list of RenderFramesHosts including the current frame and all descendents. */ - public List<RenderFrameHost> getAllRenderFrameHosts(); + public @Nullable List<RenderFrameHost> getAllRenderFrameHosts(); /** * Returns whether the feature policy allows the feature in this frame. @@ -106,7 +107,7 @@ * isRenderFrameLive() if the caller is not inside the call-stack of an * IPC form the renderer (which would guarantee its existence at that time). */ - <I extends Interface, P extends Interface.Proxy> P getInterfaceToRendererFrame( + <I extends Interface, P extends Interface.Proxy> @Nullable P getInterfaceToRendererFrame( Interface.Manager<I, P> manager); /**
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java b/content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java index 5ccc64a5..4b9dd9042 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/RenderWidgetHostView.java
@@ -5,12 +5,14 @@ package org.chromium.content_public.browser; import org.chromium.base.Callback; +import org.chromium.build.annotations.NullMarked; /** * The Android interface to allow communicating with the RenderWidgetHostViewImpl and the native * RenderWidgetHostViewAndroid object. This object allows the browser to access and control the * renderer's top level View. */ +@NullMarked public interface RenderWidgetHostView { /** * If the view is ready to draw contents to the screen. In hardware mode,
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java index 956bdbc..136fce5 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationDelegate.java
@@ -6,10 +6,13 @@ import android.app.Activity; +import org.chromium.build.annotations.NullMarked; + /** * An interface for ScreenOrientationProvider to notify other components that orientation * preferences may change. */ +@NullMarked public interface ScreenOrientationDelegate { /** * Notify the delegate that ScreenOrientationProvider consumers would like to unlock orientation
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java index 4678cf3..146ab38c 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ScreenOrientationProvider.java
@@ -4,8 +4,8 @@ package org.chromium.content_public.browser; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.ScreenOrientationProviderImpl; import org.chromium.ui.base.WindowAndroid; @@ -14,6 +14,7 @@ * TODO(boliu): This interface working with WindowAndroid does not support the use case * when an Activity (and WindowAndroid) is recreated on rotation. */ +@NullMarked public interface ScreenOrientationProvider { static ScreenOrientationProvider getInstance() { return ScreenOrientationProviderImpl.getInstance();
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SelectAroundCaretResult.java b/content/public/android/java/src/org/chromium/content_public/browser/SelectAroundCaretResult.java index cbbeaeea..1e94931 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SelectAroundCaretResult.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SelectAroundCaretResult.java
@@ -4,10 +4,13 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** * A list of parameters about a selection attempt. This data is generated from * third_party/blink/public/mojom/input/input_handler.mojom's SelectAroundCaretResult. */ +@NullMarked public class SelectAroundCaretResult { private final int mExtendedStartAdjust; private final int mExtendedEndAdjust;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SelectionClient.java b/content/public/android/java/src/org/chromium/content_public/browser/SelectionClient.java index 03862b5..a40e626 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SelectionClient.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SelectionClient.java
@@ -4,6 +4,8 @@ package org.chromium.content_public.browser; +import static org.chromium.build.NullUtil.assumeNonNull; + import android.content.Intent; import android.graphics.drawable.Drawable; import android.view.View.OnClickListener; @@ -11,19 +13,20 @@ import android.view.textclassifier.TextClassifier; import android.view.textclassifier.TextSelection; -import androidx.annotation.Nullable; - +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.selection.SmartSelectionClient; import org.chromium.ui.touch_selection.SelectionEventType; import java.util.List; /** Interface to a content layer client that can process and modify selection text. */ +@NullMarked public interface SelectionClient { /** The result of the text analysis. */ public static class Result { /** The surrounding text including the selection. */ - public String text; + public @Nullable String text; /** The start index of the selected text within the surrounding text. */ public int start; @@ -44,25 +47,25 @@ public int endAdjust; /** Label for the suggested menu item. */ - public CharSequence label; + public @Nullable CharSequence label; /** Icon for the suggested menu item. */ - public Drawable icon; + public @Nullable Drawable icon; /** Intent for the suggested menu item. */ - public Intent intent; + public @Nullable Intent intent; /** OnClickListener for the suggested menu item. */ - public OnClickListener onClickListener; + public @Nullable OnClickListener onClickListener; /** TextClassification for logging. */ - public TextClassification textClassification; + public @Nullable TextClassification textClassification; /** TextSelection for logging. */ - public TextSelection textSelection; + public @Nullable TextSelection textSelection; /** Icons for additional menu items. */ - public List<Drawable> additionalIcons; + public @Nullable List<Drawable> additionalIcons; /** * Convenience method mainly for testing the behaviour of {@link @@ -138,7 +141,7 @@ void cancelAllRequests(); /** Returns a SelectionEventProcessor associated with the SelectionClient or null. */ - default SelectionEventProcessor getSelectionEventProcessor() { + default @Nullable SelectionEventProcessor getSelectionEventProcessor() { return null; } @@ -155,19 +158,21 @@ * has been set with setTextClassifier, returns that object, otherwise returns the system * classifier. */ - default TextClassifier getTextClassifier() { + default @Nullable TextClassifier getTextClassifier() { return null; } /** Returns the TextClassifier which has been set with setTextClassifier(), or null. */ - default TextClassifier getCustomTextClassifier() { + default @Nullable TextClassifier getCustomTextClassifier() { return null; } /** Creates a {@link SelectionClient} instance. */ - public static SelectionClient createSmartSelectionClient(WebContents webContents) { - SelectionClient.ResultCallback callback = - SelectionPopupController.fromWebContents(webContents).getResultCallback(); + public static @Nullable SelectionClient createSmartSelectionClient(WebContents webContents) { + SelectionPopupController selectionPopupController = + SelectionPopupController.fromWebContents(webContents); + assumeNonNull(selectionPopupController); + SelectionClient.ResultCallback callback = selectionPopupController.getResultCallback(); return SmartSelectionClient.fromWebContents(callback, webContents); } }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SelectionEventProcessor.java b/content/public/android/java/src/org/chromium/content_public/browser/SelectionEventProcessor.java index 5f1f299..dcbce32 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SelectionEventProcessor.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SelectionEventProcessor.java
@@ -4,5 +4,8 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** Interface for selection event logging. */ +@NullMarked public interface SelectionEventProcessor {}
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 index 44ed6e31..69a6460 100644 --- 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
@@ -6,11 +6,14 @@ import androidx.annotation.IdRes; +import org.chromium.build.annotations.NullMarked; + import java.util.Collection; import java.util.SortedSet; import java.util.TreeSet; /** Data class representing a group in the text selection menu. */ +@NullMarked public final class SelectionMenuGroup implements Comparable<SelectionMenuGroup> { public final @IdRes int id; public final int 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 index 177e815a..8395a492 100644 --- 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
@@ -15,14 +15,16 @@ 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 org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; + import java.util.SortedSet; /** Data class representing an item in the text selection menu. */ +@NullMarked public final class SelectionMenuItem implements Comparable<SelectionMenuItem> { private final @AttrRes int mIconAttr; private final @Nullable Drawable mIcon; @@ -33,7 +35,7 @@ public final int orderInCategory; public final int showAsActionFlags; public final @Nullable CharSequence contentDescription; - public final @Nullable View.OnClickListener clickListener; + public final View.@Nullable OnClickListener clickListener; public final @Nullable Intent intent; public final boolean isEnabled; public final boolean isIconTintable; @@ -48,7 +50,7 @@ int orderInCategory, int showAsActionFlags, @Nullable CharSequence contentDescription, - @Nullable View.OnClickListener clickListener, + View.@Nullable OnClickListener clickListener, @Nullable Intent intent, boolean isEnabled, boolean isIconTintable) { @@ -68,8 +70,7 @@ } /** Convenience method to return the title. */ - @Nullable - public CharSequence getTitle(Context context) { + public @Nullable CharSequence getTitle(Context context) { if (mTitleRes != 0) { return context.getString(mTitleRes); } @@ -77,8 +78,7 @@ } /** Convenience method to return the icon, if any. */ - @Nullable - public Drawable getIcon(Context context) { + public @Nullable Drawable getIcon(Context context) { if (mIconAttr != 0) { try { TypedArray a = context.obtainStyledAttributes(new int[] {mIconAttr}); @@ -111,13 +111,13 @@ private int mOrderInCategory; private int mShowAsActionFlags; private @Nullable CharSequence mContentDescription; - private @Nullable View.OnClickListener mClickListener; + private View.@Nullable OnClickListener mClickListener; private @Nullable Intent mIntent; private boolean mIsEnabled; private boolean mIsIconTintable; /** Pass in a non-null title. */ - public Builder(@NonNull CharSequence title) { + public Builder(@Nullable CharSequence title) { mTitle = title; mTitleRes = 0; initDefaults(); @@ -199,7 +199,7 @@ } /** Click listener for when the menu item is clicked. */ - public Builder setClickListener(@Nullable View.OnClickListener clickListener) { + public Builder setClickListener(View.@Nullable OnClickListener clickListener) { mClickListener = clickListener; return this; }
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 828a3e9..6760a7b 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
@@ -7,10 +7,9 @@ import android.view.ActionMode; import android.view.textclassifier.TextClassifier; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.chromium.base.supplier.ObservableSupplier; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.selection.SelectionPopupControllerImpl; import org.chromium.content_public.browser.selection.SelectionActionMenuDelegate; import org.chromium.content_public.browser.selection.SelectionDropdownMenuDelegate; @@ -25,6 +24,7 @@ * this interface to create {@link ActionMode.Callback} instance and configure the selection * action mode tasks to their requirements. */ +@NullMarked public interface SelectionPopupController { // User action of clicking on the Share option within the selection UI. static final String UMA_MOBILE_ACTION_MODE_SHARE = "MobileActionMode.Share"; @@ -34,7 +34,7 @@ * @return {@link SelectionPopupController} object used for the give WebContents. * {@code null} if not available. */ - static SelectionPopupController fromWebContents(WebContents webContents) { + static @Nullable SelectionPopupController fromWebContents(WebContents webContents) { return SelectionPopupControllerImpl.fromWebContents(webContents); } @@ -43,7 +43,7 @@ * @return {@link SelectionPopupController} object used for the given WebContents if created. * {@code null} if not available. */ - static SelectionPopupController fromWebContentsNoCreate(WebContents webContents) { + static @Nullable SelectionPopupController fromWebContentsNoCreate(WebContents webContents) { return SelectionPopupControllerImpl.fromWebContentsNoCreate(webContents); } @@ -119,7 +119,7 @@ void setSelectionClient(SelectionClient selectionClient); /** Returns the {@link SelectionClient} in the selection popup controller. */ - public SelectionClient getSelectionClient(); + public @Nullable SelectionClient getSelectionClient(); /** Sets TextClassifier for Smart Text selection. */ void setTextClassifier(TextClassifier textClassifier); @@ -129,9 +129,11 @@ * has been set with setTextClassifier, returns that object, otherwise returns the system * classifier. */ + @Nullable TextClassifier getTextClassifier(); /** Returns the TextClassifier which has been set with setTextClassifier(), or null. */ + @Nullable TextClassifier getCustomTextClassifier(); /** @@ -151,7 +153,7 @@ void updateTextSelectionUI(boolean focused); /** Set the dropdown menu delegate that handles showing a dropdown style text selection menu. */ - void setDropdownMenuDelegate(@NonNull SelectionDropdownMenuDelegate dropdownMenuDelegate); + void setDropdownMenuDelegate(SelectionDropdownMenuDelegate dropdownMenuDelegate); /** * Set the {@link SelectionActionMenuDelegate} used by {@link SelectionPopupController} while @@ -165,5 +167,6 @@ * * @return SelectionActionMenuDelegate instance if available, Otherwise Null. */ + @Nullable SelectionActionMenuDelegate getSelectionActionMenuDelegate(); }
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SiteZoomInfo.java b/content/public/android/java/src/org/chromium/content_public/browser/SiteZoomInfo.java index 1a905d40..124bc68 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SiteZoomInfo.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SiteZoomInfo.java
@@ -4,10 +4,12 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.UsedByReflection; /** Represents the zoom information for a host. */ @UsedByReflection("host_zoom_map_impl.cc") +@NullMarked public final class SiteZoomInfo { public final String host; public final double zoomLevel;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SmartClipProvider.java b/content/public/android/java/src/org/chromium/content_public/browser/SmartClipProvider.java index a3ce00c..b37af214 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SmartClipProvider.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SmartClipProvider.java
@@ -6,6 +6,7 @@ import android.os.Handler; +import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.UsedByReflection; /** @@ -16,6 +17,7 @@ * hierarchy. */ @UsedByReflection("ExternalOemSupport") +@NullMarked public interface SmartClipProvider { /** * Initiate extraction of text, HTML, and other information for clipping puposes (smart clip)
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SpeechRecognition.java b/content/public/android/java/src/org/chromium/content_public/browser/SpeechRecognition.java index 4da6255..1638520 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SpeechRecognition.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SpeechRecognition.java
@@ -4,6 +4,7 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.SpeechRecognitionImpl; /** @@ -11,6 +12,7 @@ * on Android. Using Android's platform recognizer offers several benefits, like good quality and * good local fallback when no data connection is available. */ +@NullMarked public final class SpeechRecognition { private SpeechRecognition() {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingHandler.java b/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingHandler.java index 800dac82..e73b8cf 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingHandler.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingHandler.java
@@ -12,7 +12,8 @@ import android.view.inputmethod.EditorBoundsInfo; import android.view.inputmethod.EditorInfo; -import androidx.annotation.Nullable; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; /** * Interface that provides Stylus handwriting to text input functionality in HTML edit fields. This @@ -20,6 +21,7 @@ * in this interface outside of //content (i.e. //components/stylus_handwriting) and these are * called from the current WebContents related classes in //content. */ +@NullMarked public interface StylusWritingHandler { /** * @return true if soft keyboard can be shown during stylus writing. @@ -48,8 +50,7 @@ * @param isEditable is true if focused node is of editable type. * @param currentView the {@link View} in which the focused node changed. */ - @Nullable - default EditorBoundsInfo onFocusedNodeChanged( + default @Nullable EditorBoundsInfo onFocusedNodeChanged( Rect editableBoundsOnScreenDip, boolean isEditable, View currentView, @@ -107,8 +108,7 @@ * @param contentOffsetY the Physical on-screen Y offset amount below the browser controls * @param view the view on which to start stylus handwriting */ - @Nullable - default EditorBoundsInfo onEditElementFocusedForStylusWriting( + default @Nullable EditorBoundsInfo onEditElementFocusedForStylusWriting( Rect focusedEditBounds, Point cursorPosition, float scaleFactor,
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingImeCallback.java b/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingImeCallback.java index 494462f..5a0cc09 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingImeCallback.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/StylusWritingImeCallback.java
@@ -7,6 +7,7 @@ import android.view.View; import org.chromium.blink.mojom.StylusWritingGestureData; +import org.chromium.build.annotations.NullMarked; /** * This interface implements the IME functionality like committing text, showing or hiding soft @@ -15,6 +16,7 @@ * implemented within //content by class responsible to provide the above Ime functions in the * current focused input field (i.e. ImeAdapterImpl). */ +@NullMarked public interface StylusWritingImeCallback { /** * Send a request to set the selection to given range.
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/SurfaceInputTransferHandlerMap.java b/content/public/android/java/src/org/chromium/content_public/browser/SurfaceInputTransferHandlerMap.java index 19e9b5dd..71acd8b3 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/SurfaceInputTransferHandlerMap.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/SurfaceInputTransferHandlerMap.java
@@ -8,11 +8,14 @@ import androidx.annotation.RequiresApi; +import org.chromium.build.annotations.NullMarked; + import java.util.Collections; import java.util.HashMap; import java.util.Map; @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) +@NullMarked public class SurfaceInputTransferHandlerMap { public final Map<Integer, InputTransferHandler> mInputTransferHandlerMap = Collections.synchronizedMap(new HashMap<Integer, InputTransferHandler>());
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/ViewEventSink.java b/content/public/android/java/src/org/chromium/content_public/browser/ViewEventSink.java index 3ec719e..7eb4552 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/ViewEventSink.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/ViewEventSink.java
@@ -8,9 +8,11 @@ import android.view.KeyEvent; import android.view.MotionEvent; +import org.chromium.build.annotations.NullMarked; import org.chromium.content.browser.ViewEventSinkImpl; /** Interface for updating content with view events. */ +@NullMarked public interface ViewEventSink { /** * Interface that consumers of WebContents must implement to allow the proper
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java index e8724658..0b47fbb 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContents.java
@@ -9,11 +9,10 @@ import android.os.Handler; import android.os.Parcelable; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - import org.chromium.base.Callback; import org.chromium.blink_public.input.SelectionGranularity; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.cc.input.BrowserControlsOffsetTagsInfo; import org.chromium.content_public.browser.back_forward_transition.AnimationStage; import org.chromium.ui.OverscrollRefreshHandler; @@ -44,6 +43,7 @@ * bundle.setClassLoader(WebContents.class.getClassLoader()); webContents = * bundle.get("WEBCONTENTSKEY"); */ +@NullMarked public interface WebContents extends Parcelable { /** * Interface used to transfer the internal objects (but callers should own) from WebContents. @@ -54,9 +54,10 @@ * * @param internals a {@link WebContentsInternals} object. */ - void set(WebContentsInternals internals); + void set(@Nullable WebContentsInternals internals); /** Returns {@link WebContentsInternals} object. Can be {@code null}. */ + @Nullable WebContentsInternals get(); } @@ -66,15 +67,15 @@ */ public static InternalsHolder createDefaultInternalsHolder() { return new InternalsHolder() { - private WebContentsInternals mInternals; + private @Nullable WebContentsInternals mInternals; @Override - public void set(WebContentsInternals internals) { + public void set(@Nullable WebContentsInternals internals) { mInternals = internals; } @Override - public WebContentsInternals get() { + public @Nullable WebContentsInternals get() { return mInternals; } }; @@ -99,7 +100,7 @@ ViewAndroidDelegate viewDelegate, ViewEventSink.InternalAccessDelegate accessDelegate, WindowAndroid windowAndroid, - @NonNull InternalsHolder internalsHolder); + InternalsHolder internalsHolder); /** * Clear Java WebContentsObservers so we can put this WebContents to the background. Use this @@ -123,7 +124,7 @@ * TODO(jinsukkim): This should happen through view android tree instead. * @param windowAndroid The new {@link WindowAndroid} for this {@link WebContents}. */ - void setTopLevelNativeWindow(WindowAndroid windowAndroid); + void setTopLevelNativeWindow(@Nullable WindowAndroid windowAndroid); /** * If called too early, the {@link ViewAndroidDelegate} might not be yet available. One can @@ -154,6 +155,7 @@ /** * @return The navigation controller associated with this WebContents. */ + @Nullable NavigationController getNavigationController(); /** @@ -392,9 +394,9 @@ */ void postMessageToMainFrame( MessagePayload messagePayload, - String sourceOrigin, + @Nullable String sourceOrigin, String targetOrigin, - @Nullable MessagePort[] ports); + MessagePort @Nullable [] ports); /** * Creates a message channel for sending postMessage requests and returns the ports for @@ -456,6 +458,7 @@ * @return {@link StylusWritingImeCallback} which is used to implement the IME functionality for * the Stylus handwriting feature. */ + @Nullable StylusWritingImeCallback getStylusWritingImeCallback(); /**
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 861132f..98292efd 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,6 +8,8 @@ import android.view.ViewStructure; import android.view.accessibility.AccessibilityNodeProvider; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.accessibility.WebContentsAccessibilityImpl; /** @@ -15,13 +17,14 @@ * accessibility part is lazily created upon the first request from Android framework on *{@link AccessibilityNodeProvider}, and shares the lifetime with {@link WebContents}. */ +@NullMarked public interface WebContentsAccessibility { /** * @param webContents {@link WebContents} object. * @return {@link WebContentsAccessibility} object used for the give WebContents. * {@code null} if not available. */ - static WebContentsAccessibility fromWebContents(WebContents webContents) { + static @Nullable WebContentsAccessibility fromWebContents(WebContents webContents) { return WebContentsAccessibilityImpl.fromWebContents(webContents); } @@ -38,6 +41,7 @@ * Lazily initializes native accessibility here if it's allowed. * @return The AccessibilityNodeProvider, if available, or null otherwise. */ + @Nullable AccessibilityNodeProvider getAccessibilityNodeProvider(); /**
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsInternals.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsInternals.java index c954c0e..ccf9b40 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsInternals.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsInternals.java
@@ -4,6 +4,8 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; + /** * Marker interface for WebContents internal objects that should be managed by * embedders. Embedders should call {@link WebContents#setInternalHolder} with @@ -13,4 +15,5 @@ * address the requirements that there not be any gc root to webview in content * layer after webview gets detached from view tree. See https://crbug.com/755174. */ +@NullMarked public interface WebContentsInternals {}
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java index e3d67c77..259cb70 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsObserver.java
@@ -5,10 +5,11 @@ package org.chromium.content_public.browser; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import org.chromium.base.TerminationStatus; import org.chromium.blink.mojom.ViewportFit; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.mojom.VirtualKeyboardMode; import org.chromium.url.GURL; @@ -21,11 +22,12 @@ * This class receives callbacks that act as hooks for various a native web contents events related * to loading a url. A single web contents can have multiple WebContentObservers. */ +@NullMarked public abstract class WebContentsObserver { // TODO(jdduke): Remove the destroy method and hold observer embedders // responsible for explicit observer detachment. // Using a weak reference avoids cycles that might prevent GC of WebView's WebContents. - protected WeakReference<WebContents> mWebContents; + protected @Nullable WeakReference<WebContents> mWebContents; public WebContentsObserver(WebContents webContents) { mWebContents = new WeakReference<WebContents>(webContents);
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsStatics.java b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsStatics.java index 65baab6..77247d8 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/WebContentsStatics.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/WebContentsStatics.java
@@ -4,15 +4,18 @@ package org.chromium.content_public.browser; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.content.browser.framehost.RenderFrameHostDelegate; import org.chromium.content.browser.framehost.RenderFrameHostImpl; /** Static public methods for WebContents. */ +@NullMarked public class WebContentsStatics { /** * @return The WebContents associated with the RenderFrameHost. This can be null. */ - public static WebContents fromRenderFrameHost(RenderFrameHost rfh) { + public static @Nullable WebContents fromRenderFrameHost(RenderFrameHost rfh) { RenderFrameHostDelegate delegate = ((RenderFrameHostImpl) rfh).getRenderFrameHostDelegate(); if (delegate == null || !(delegate instanceof WebContents)) { return null;
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionActionMenuDelegate.java b/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionActionMenuDelegate.java index 8d338432..873984d 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionActionMenuDelegate.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionActionMenuDelegate.java
@@ -6,8 +6,7 @@ import android.content.pm.ResolveInfo; -import androidx.annotation.NonNull; - +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.SelectionMenuItem; import org.chromium.content_public.browser.SelectionPopupController; @@ -17,6 +16,7 @@ * Interface for modifying text selection menu functionality. Content embedders can provide * implementation to provide text selection menu item custom behavior. */ +@NullMarked public interface SelectionActionMenuDelegate { /** * Allows the delegate make changes to default menu items created by {@link @@ -35,7 +35,7 @@ List<SelectionMenuItem.Builder> menuItemBuilders, boolean isSelectionPassword, boolean isSelectionReadOnly, - @NonNull String selectedText); + String selectedText); /** * Allows filtering of text processing activities. @@ -52,7 +52,6 @@ * * @return list of additional non selection secondary menu items if any. */ - @NonNull List<SelectionMenuItem> getAdditionalNonSelectionItems(); /** @@ -62,7 +61,6 @@ * * @return list of additional text selection menu items handling text processing if any. */ - @NonNull List<SelectionMenuItem> getAdditionalTextProcessingItems(); /**
diff --git a/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionDropdownMenuDelegate.java b/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionDropdownMenuDelegate.java index d57f85a7..649e84f 100644 --- a/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionDropdownMenuDelegate.java +++ b/content/public/android/java/src/org/chromium/content_public/browser/selection/SelectionDropdownMenuDelegate.java
@@ -10,9 +10,10 @@ import android.view.View; import androidx.annotation.IdRes; -import androidx.annotation.Nullable; import androidx.annotation.Px; +import org.chromium.build.annotations.NullMarked; +import org.chromium.build.annotations.Nullable; import org.chromium.ui.modelutil.MVCListAdapter; import org.chromium.ui.modelutil.MVCListAdapter.ListItem; import org.chromium.ui.modelutil.PropertyModel; @@ -22,6 +23,7 @@ * Each content embedder will need to provide an implementation of this to enable * the behavior when showing the context menu for mouse & trackpad. */ +@NullMarked public interface SelectionDropdownMenuDelegate { /** Listener for handling list item click events. */ @FunctionalInterface @@ -68,8 +70,7 @@ * Returns the {@link android.view.View.OnClickListener} for an item if there is * one. Otherwise returns null. */ - @Nullable - View.OnClickListener getClickListener(PropertyModel itemModel); + View.@Nullable OnClickListener getClickListener(PropertyModel itemModel); /** Returns a divider menu item to be shown in the dropdown menu. */ ListItem getDivider(); @@ -90,7 +91,7 @@ * @return ListItem with text and optionally an icon. */ ListItem getMenuItem( - String title, + @Nullable String title, @Nullable String contentDescription, @IdRes int groupId, @IdRes int id, @@ -98,6 +99,6 @@ boolean isIconTintable, boolean groupContainsIcon, boolean enabled, - @Nullable View.OnClickListener clickListener, + View.@Nullable OnClickListener clickListener, @Nullable Intent intent); }
diff --git a/content/public/android/java/src/org/chromium/content_public/common/InputUtils.java b/content/public/android/java/src/org/chromium/content_public/common/InputUtils.java index 5d87f3c..2acd22e 100644 --- a/content/public/android/java/src/org/chromium/content_public/common/InputUtils.java +++ b/content/public/android/java/src/org/chromium/content_public/common/InputUtils.java
@@ -6,9 +6,11 @@ import android.os.Build; +import org.chromium.build.annotations.NullMarked; import org.chromium.content_public.browser.ContentFeatureList; import org.chromium.content_public.browser.ContentFeatureMap; +@NullMarked public class InputUtils { public static boolean isTransferInputToVizSupported() { return Build.VERSION.SDK_INT >= Build.VERSION_CODES.VANILLA_ICE_CREAM
diff --git a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java index 60acdb2f..a917851f 100644 --- a/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java +++ b/content/public/android/javatests/src/org/chromium/content/browser/JavaBridgeCoercionTest.java
@@ -4,7 +4,7 @@ package org.chromium.content.browser; -import android.os.Build; +import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; import androidx.test.filters.SmallTest; @@ -18,12 +18,12 @@ import org.chromium.base.test.BaseJUnit4ClassRunner; import org.chromium.base.test.util.Batch; -import org.chromium.base.test.util.DisableIf; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.UrlUtils; import org.chromium.content.browser.JavaBridgeActivityTestRule.Controller; import java.io.File; +import java.nio.file.Files; /** * Part of the test suite for the Java Bridge. This class tests that we correctly convert JavaScript @@ -716,9 +716,6 @@ @Test @SmallTest @Feature({"AndroidWebView", "Android-JavaBridge"}) - @DisableIf.Build( - sdk_is_greater_than = Build.VERSION_CODES.TIRAMISU, - message = "crbug.com/385137265") public void testPassJavaObjectFromCustomClassLoader() throws Throwable { // Compiled bytecode (dex) for the following class: // @@ -732,32 +729,48 @@ // } // } final String dexFileName = "content/test/data/android/SelfConsumingObject.dex"; - assertFileIsReadable(UrlUtils.getIsolatedTestFilePath(dexFileName)); + final String externalDexPath = UrlUtils.getIsolatedTestFilePath(dexFileName); + assertFileIsReadable(externalDexPath); final File optimizedDir = File.createTempFile("optimized", ""); Assert.assertTrue(optimizedDir.delete()); Assert.assertTrue(optimizedDir.mkdirs()); - DexClassLoader loader = - new DexClassLoader( - UrlUtils.getIsolatedTestFilePath(dexFileName), - optimizedDir.getAbsolutePath(), - null, - ClassLoader.getSystemClassLoader()); - final Object selfConsuming = - loader.loadClass("org.example.SelfConsumingObject").newInstance(); - mActivityTestRule.runOnUiThread( - new Runnable() { - @Override - public void run() { - mActivityTestRule - .getJavascriptInjector() - .addPossiblyUnsafeInterface(selfConsuming, "selfConsuming", null); - } - }); - mActivityTestRule.synchronousPageReload(); - mActivityTestRule.executeJavaScript( - "testObject.setBooleanValue(" - + "selfConsuming.verifySelf(selfConsuming.getSelf()));"); - Assert.assertTrue(mTestObject.waitForBooleanValue()); + + // Since DCL enforcement has become stricter on newer versions of Android, we can no longer + // load Dex files which are writable. We can't set readonly on external files so copy the + // Dex to internal storage before setting readonly to avoid a security exception. + File externalDex = new File(externalDexPath); + final File dexCopy = File.createTempFile("SelfConsumingObject", ".dex"); + try { + Files.copy(externalDex.toPath(), dexCopy.toPath(), REPLACE_EXISTING); + dexCopy.setReadOnly(); + Assert.assertFalse(dexCopy.canWrite()); + + DexClassLoader loader = + new DexClassLoader( + dexCopy.getAbsolutePath(), + optimizedDir.getAbsolutePath(), + null, + ClassLoader.getSystemClassLoader()); + final Object selfConsuming = + loader.loadClass("org.example.SelfConsumingObject").newInstance(); + mActivityTestRule.runOnUiThread( + new Runnable() { + @Override + public void run() { + mActivityTestRule + .getJavascriptInjector() + .addPossiblyUnsafeInterface( + selfConsuming, "selfConsuming", null); + } + }); + mActivityTestRule.synchronousPageReload(); + mActivityTestRule.executeJavaScript( + "testObject.setBooleanValue(" + + "selfConsuming.verifySelf(selfConsuming.getSelf()));"); + Assert.assertTrue(mTestObject.waitForBooleanValue()); + } finally { + Assert.assertTrue(dexCopy.delete()); + } } // Test passing JavaScript null to a method of an injected object.
diff --git a/content/public/android/junit/src/org/chromium/content/browser/input/OngoingGestureTest.java b/content/public/android/junit/src/org/chromium/content/browser/input/OngoingGestureTest.java index fc2d5e7..b4927716 100644 --- a/content/public/android/junit/src/org/chromium/content/browser/input/OngoingGestureTest.java +++ b/content/public/android/junit/src/org/chromium/content/browser/input/OngoingGestureTest.java
@@ -25,14 +25,21 @@ private static final String GESTURE_RESULT_HISTOGRAM = "InputMethod.StylusHandwriting.GestureResult"; + private static OngoingGesture makeOngoingGesture() { + return new OngoingGesture( + new org.chromium.blink.mojom.StylusWritingGestureData(), + (command) -> {}, + (value) -> {}); + } + @Test @SmallTest public void testGestureRequestsHaveIncreasingIDs() { ThreadUtils.runOnUiThreadBlocking( () -> { - OngoingGesture baseline = new OngoingGesture(null, null, null); - OngoingGesture request1 = new OngoingGesture(null, null, null); - OngoingGesture request2 = new OngoingGesture(null, null, null); + OngoingGesture baseline = makeOngoingGesture(); + OngoingGesture request1 = makeOngoingGesture(); + OngoingGesture request2 = makeOngoingGesture(); assertEquals(baseline.getId() + 1, request1.getId()); assertEquals(baseline.getId() + 2, request2.getId()); }); @@ -40,50 +47,10 @@ @Test @SmallTest - public void testGestureRequestLogsUnknownWithNullExecutor() { - ThreadUtils.runOnUiThreadBlocking( - () -> { - var histogram = - HistogramWatcher.newSingleRecordWatcher( - GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.UNKNOWN); - OngoingGesture request = - new OngoingGesture( - new org.chromium.blink.mojom.StylusWritingGestureData(), - null, - (value) -> {}); - request.onGestureHandled(HandwritingGestureResult.SUCCESS); - histogram.assertExpected(); - }); - } - - @Test - @SmallTest - public void testGestureRequestLogsUnknownWithNullIntConsumer() { - ThreadUtils.runOnUiThreadBlocking( - () -> { - var histogram = - HistogramWatcher.newSingleRecordWatcher( - GESTURE_RESULT_HISTOGRAM, HandwritingGestureResult.UNKNOWN); - OngoingGesture request = - new OngoingGesture( - new org.chromium.blink.mojom.StylusWritingGestureData(), - (command) -> {}, - null); - request.onGestureHandled(HandwritingGestureResult.FAILED); - histogram.assertExpected(); - }); - } - - @Test - @SmallTest public void testGestureRequestLogsCorrectResult() { ThreadUtils.runOnUiThreadBlocking( () -> { - OngoingGesture request = - new OngoingGesture( - new org.chromium.blink.mojom.StylusWritingGestureData(), - (command) -> {}, - (value) -> {}); + OngoingGesture request = makeOngoingGesture(); var histogram = HistogramWatcher.newSingleRecordWatcher(
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 f039ee7..1ca3127 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
@@ -193,7 +193,7 @@ when(mWindowAndroid.getContext()).thenReturn(mWeakContext); mController = SelectionPopupControllerImpl.createForTesting(mWebContents, mPopupController); - when(mController.getGestureListenerManager()).thenReturn(mGestureStateListenerManager); + GestureListenerManagerImpl.setInstanceForTesting(mGestureStateListenerManager); } @Test
diff --git a/content/public/browser/content_browser_client.cc b/content/public/browser/content_browser_client.cc index a344bce..f252c04 100644 --- a/content/public/browser/content_browser_client.cc +++ b/content/public/browser/content_browser_client.cc
@@ -1790,6 +1790,10 @@ return nullptr; } +bool ContentBrowserClient::ShouldEnableDips(BrowserContext* browser_context) { + return true; +} + bool ContentBrowserClient::ShouldSuppressAXLoadComplete(RenderFrameHost* rfh) { return false; }
diff --git a/content/public/browser/content_browser_client.h b/content/public/browser/content_browser_client.h index f3cf5f2..25a2aec8 100644 --- a/content/public/browser/content_browser_client.h +++ b/content/public/browser/content_browser_client.h
@@ -3054,6 +3054,10 @@ // default behavior. virtual std::unique_ptr<DipsDelegate> CreateDipsDelegate(); + // DIPS will be enabled in browser contexts for which this returns true. The + // default implementation returns true for all contexts. + virtual bool ShouldEnableDips(BrowserContext* browser_context); + // Allows the embedder to suppress the firing of the AXLoadComplete event. // Currently, this is only respected on Mac. Since VoiceOver on Mac will // move the focus to web content if the AXLoadComplete event is fired,
diff --git a/content/public/browser/dips_delegate.h b/content/public/browser/dips_delegate.h index 627ea355..5f9d81e 100644 --- a/content/public/browser/dips_delegate.h +++ b/content/public/browser/dips_delegate.h
@@ -22,6 +22,9 @@ // // Instances can be obtained via // ContentBrowserClient::CreateDipsDelegate(). +// +// TODO: crbug.com/387281262 - move methods to ContentBrowserClient and delete +// this class. class CONTENT_EXPORT DipsDelegate { public: // The mask that will be used in place of GetRemoveMask() when embedders @@ -39,9 +42,6 @@ virtual ~DipsDelegate(); - // DIPS will be enabled in browser contexts for which this returns true. - virtual bool ShouldEnableDips(BrowserContext* browser_context) = 0; - // Called once for each DIPSService instance when it's created. // DIPSService::Get() is guaranteed to return the given instance if called // i.e., DIPSService::Get(browser_context) == dips_service.
diff --git a/content/public/common/content_features.cc b/content/public/common/content_features.cc index a3bfcd61..df868627 100644 --- a/content/public/common/content_features.cc +++ b/content/public/common/content_features.cc
@@ -476,6 +476,11 @@ "FedCmWithoutWellKnownEnforcement", base::FEATURE_DISABLED_BY_DEFAULT); +// Enables Lightweight FedCM Mode +BASE_FEATURE(kFedCmLightweightMode, + "FedCmLightweightMode", + base::FEATURE_DISABLED_BY_DEFAULT); + // Enables browser-side focus verification when crossing fenced boundaries. BASE_FEATURE(kFencedFramesEnforceFocus, "FencedFramesEnforceFocus",
diff --git a/content/public/common/content_features.h b/content/public/common/content_features.h index 9fc854ae..ce8f17b 100644 --- a/content/public/common/content_features.h +++ b/content/public/common/content_features.h
@@ -120,6 +120,7 @@ CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmShowFilteredAccounts); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmUseOtherAccount); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmWithoutWellKnownEnforcement); +CONTENT_EXPORT BASE_DECLARE_FEATURE(kFedCmLightweightMode); CONTENT_EXPORT BASE_DECLARE_FEATURE(kFencedFramesEnforceFocus); #if BUILDFLAG(IS_ANDROID) CONTENT_EXPORT BASE_DECLARE_FEATURE(
diff --git a/content/test/content_test_bundle_data.filelist b/content/test/content_test_bundle_data.filelist index 0eab95a..06861ad 100644 --- a/content/test/content_test_bundle_data.filelist +++ b/content/test/content_test_bundle_data.filelist
@@ -6441,11 +6441,6 @@ data/devtools/worker_imported_classic.js data/devtools/worker_imported_module.js data/devtools/zoom.html -data/dips/v1.sql -data/dips/v2.sql -data/dips/v3.sql -data/dips/v4.sql -data/dips/v5.sql data/dips/v6.sql data/dips/v7.sql data/direct_sockets/open.html
diff --git a/content/test/content_test_bundle_data.globlist b/content/test/content_test_bundle_data.globlist index 1f472c5..eab829b8 100644 --- a/content/test/content_test_bundle_data.globlist +++ b/content/test/content_test_bundle_data.globlist
@@ -10,6 +10,11 @@ -data/**/DIR_METADATA -data/**/README.md -data/android/** +-data/dips/v1.sql +-data/dips/v2.sql +-data/dips/v3.sql +-data/dips/v4.sql +-data/dips/v5.sql -data/file_chooser/dir_with*symlink/** -data/gpu/gpu_reference/** -data/gpu/mediapipe/**
diff --git a/device/vr/util/transform_utils.cc b/device/vr/util/transform_utils.cc index 2c41681..92b9dec4 100644 --- a/device/vr/util/transform_utils.cc +++ b/device/vr/util/transform_utils.cc
@@ -2,11 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifdef UNSAFE_BUFFERS_BUILD -// TODO(crbug.com/351564777): Remove this and convert code to safer constructs. -#pragma allow_unsafe_buffers -#endif - #include "device/vr/util/transform_utils.h" #include "ui/gfx/geometry/decomposed_transform.h"
diff --git a/docs/android_debugging_instructions.md b/docs/android_debugging_instructions.md index 4b9efbe..f687b9c 100644 --- a/docs/android_debugging_instructions.md +++ b/docs/android_debugging_instructions.md
@@ -35,11 +35,12 @@ ### Warnings for Blink developers * **Do not use fprintf or printf debugging!** This does not - redirect to logcat. + redirect to adb logcat. Use `LOG(ERROR)` etc. instead. + See also the "Get Blink code to output to the adb log" section. * Redirecting stdio to logcat, as documented [here](https://developer.android.com/studio/command-line/logcat.html#viewingStd), - has a bad side-effect that it breaks `adb_install.py`. See + has a bad side-effect in that it breaks `adb_install.py`. See [here for details](http://stackoverflow.com/questions/28539676/android-adb-fails-to-install-apk-to-nexus-5-on-windows-8-1). ## Take a Screenshot @@ -200,7 +201,7 @@ adb logcat | build/android/stacktrace/java_deobfuscate.py PROGUARD_MAPPING_FILE.mapping ``` -## Get WebKit code to output to the adb log +## Get Blink code to output to the adb log In your build environment: @@ -211,8 +212,10 @@ adb shell start ``` -In the source itself, use `fprintf(stderr, "message");` whenever you need to -output a message. +In the source itself, use `LOG(ERROR),` `LOG(INFO)`, etc. whenever you need to +output a message, and it will be automatically redirected to adb logcat. +Running `adb logcat chromium:E`, for example, will show all log lines from +`LOG(ERROR)` (plus others that match "chromium"). ## Debug unit tests with LLDB
diff --git a/docs/website b/docs/website index 228b145c..4d21409 160000 --- a/docs/website +++ b/docs/website
@@ -1 +1 @@ -Subproject commit 228b145cbe593cd326f9e1f4d038476e18745519 +Subproject commit 4d214097ba7305ec2b3f2dfcf0aa4fd2104c960a
diff --git a/extensions/browser/event_router.h b/extensions/browser/event_router.h index 765c30a..bb2f10b 100644 --- a/extensions/browser/event_router.h +++ b/extensions/browser/event_router.h
@@ -722,4 +722,21 @@ } // namespace extensions +namespace base { + +template <> +struct ScopedObservationTraits<extensions::EventRouter, + extensions::EventRouter::TestObserver> { + static void AddObserver(extensions::EventRouter* source, + extensions::EventRouter::TestObserver* observer) { + source->AddObserverForTesting(observer); + } + static void RemoveObserver(extensions::EventRouter* source, + extensions::EventRouter::TestObserver* observer) { + source->RemoveObserverForTesting(observer); + } +}; + +} // namespace base + #endif // EXTENSIONS_BROWSER_EVENT_ROUTER_H_
diff --git a/extensions/browser/test_event_router_observer.cc b/extensions/browser/test_event_router_observer.cc index a7138d7..8d710c39 100644 --- a/extensions/browser/test_event_router_observer.cc +++ b/extensions/browser/test_event_router_observer.cc
@@ -10,16 +10,11 @@ namespace extensions { -TestEventRouterObserver::TestEventRouterObserver(EventRouter* event_router) - : event_router_(event_router) { - event_router_->AddObserverForTesting(this); +TestEventRouterObserver::TestEventRouterObserver(EventRouter* event_router) { + observation_.Observe(event_router); } -TestEventRouterObserver::~TestEventRouterObserver() { - // Note: can't use ScopedObserver<> here because the method is - // RemoveObserverForTesting() instead of RemoveObserver(). - event_router_->RemoveObserverForTesting(this); -} +TestEventRouterObserver::~TestEventRouterObserver() = default; void TestEventRouterObserver::ClearEvents() { events_.clear();
diff --git a/extensions/browser/test_event_router_observer.h b/extensions/browser/test_event_router_observer.h index a7b31ea..47e16f2 100644 --- a/extensions/browser/test_event_router_observer.h +++ b/extensions/browser/test_event_router_observer.h
@@ -9,8 +9,8 @@ #include <memory> #include <string> -#include "base/memory/raw_ptr.h" #include "base/run_loop.h" +#include "base/scoped_observation.h" #include "extensions/browser/event_router.h" namespace extensions { @@ -42,7 +42,8 @@ EventMap events_; EventMap dispatched_events_; - raw_ptr<EventRouter> event_router_; + base::ScopedObservation<EventRouter, EventRouter::TestObserver> observation_{ + this}; std::unique_ptr<base::RunLoop> run_loop_; };
diff --git a/extensions/common/extension_api.cc b/extensions/common/extension_api.cc index 395cc75..349ace8 100644 --- a/extensions/common/extension_api.cc +++ b/extensions/common/extension_api.cc
@@ -17,9 +17,9 @@ #include "base/json/json_reader.h" #include "base/json/json_writer.h" #include "base/lazy_instance.h" +#include "base/strings/span_printf.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" -#include "base/strings/string_util.h" #include "base/values.h" #include "extensions/common/extension.h" #include "extensions/common/extensions_client.h" @@ -43,9 +43,9 @@ // Tracking down http://crbug.com/121424 char buf[128]; - base::snprintf(buf, std::size(buf), "%s: (%d) '%s'", name.c_str(), - result.has_value() ? static_cast<int>(result->type()) : -1, - !result.has_value() ? result.error().message.c_str() : ""); + base::SpanPrintf(buf, "%s: (%d) '%s'", name.c_str(), + result.has_value() ? static_cast<int>(result->type()) : -1, + !result.has_value() ? result.error().message.c_str() : ""); CHECK(result.has_value()) << result.error().message << " for schema " << schema;
diff --git a/extensions/common/features/feature_provider.cc b/extensions/common/features/feature_provider.cc index 2923547..b41951b 100644 --- a/extensions/common/features/feature_provider.cc +++ b/extensions/common/features/feature_provider.cc
@@ -14,6 +14,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_macros.h" +#include "base/strings/span_printf.h" #include "base/strings/string_split.h" #include "base/strings/string_util.h" #include "base/trace_event/trace_event.h" @@ -32,14 +33,14 @@ // This is provided in feature_util because for some reason features are prone // to mysterious crashes in named map lookups. For example see crbug.com/365192 // and crbug.com/461915. -#define CRASH_WITH_MINIDUMP(message) \ - { \ - std::string message_copy(message); \ - char minidump[BUFSIZ]; \ - base::debug::Alias(&minidump); \ - base::snprintf(minidump, std::size(minidump), "e::%s:%d:\"%s\"", __FILE__, \ - __LINE__, message_copy.c_str()); \ - LOG(FATAL) << message_copy; \ +#define CRASH_WITH_MINIDUMP(message) \ + { \ + std::string message_copy(message); \ + char minidump[BUFSIZ]; \ + base::debug::Alias(&minidump); \ + base::SpanPrintf(minidump, "e::%s:%d:\"%s\"", __FILE__, __LINE__, \ + message_copy.c_str()); \ + LOG(FATAL) << message_copy; \ } class FeatureProviderStatic {
diff --git a/extensions/renderer/dispatcher.cc b/extensions/renderer/dispatcher.cc index 417be37..193b22ed 100644 --- a/extensions/renderer/dispatcher.cc +++ b/extensions/renderer/dispatcher.cc
@@ -25,7 +25,7 @@ #include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" -#include "base/strings/string_util.h" +#include "base/strings/span_printf.h" #include "base/strings/utf_string_conversions.h" #include "base/task/single_thread_task_runner.h" #include "base/time/time.h" @@ -938,8 +938,8 @@ std::string& error = extension_load_errors_[extension_id]; char minidump[256]; base::debug::Alias(&minidump); - base::snprintf(minidump, std::size(minidump), "e::dispatcher:%s:%s", - extension_id.c_str(), error.c_str()); + base::SpanPrintf(minidump, "e::dispatcher:%s:%s", extension_id.c_str(), + error.c_str()); LOG(ERROR) << extension_id << " was never loaded: " << error; base::debug::DumpWithoutCrashing(); return;
diff --git a/gin/v8_initializer.cc b/gin/v8_initializer.cc index 39c7143..7fdb3ae 100644 --- a/gin/v8_initializer.cc +++ b/gin/v8_initializer.cc
@@ -32,8 +32,8 @@ #include "base/notreached.h" #include "base/path_service.h" #include "base/rand_util.h" +#include "base/strings/span_printf.h" #include "base/strings/string_split.h" -#include "base/strings/string_util.h" #include "base/system/sys_info.h" #include "base/threading/platform_thread.h" #include "base/time/time.h" @@ -196,7 +196,7 @@ char buffer[128]; va_list args; va_start(args, format); - int length = base::vsnprintf(buffer, sizeof(buffer), format, args); + int length = base::VSpanPrintf(buffer, format, args); if (length <= 0 || sizeof(buffer) <= static_cast<unsigned>(length)) { PLOG(ERROR) << "Invalid formatted V8 flag: " << format; return;
diff --git a/gpu/command_buffer/service/image_reader_gl_owner.cc b/gpu/command_buffer/service/image_reader_gl_owner.cc index 103334e..f163380 100644 --- a/gpu/command_buffer/service/image_reader_gl_owner.cc +++ b/gpu/command_buffer/service/image_reader_gl_owner.cc
@@ -13,7 +13,6 @@ #include "base/android/jni_android.h" #include "base/android/scoped_hardware_buffer_fence_sync.h" #include "base/debug/dump_without_crashing.h" -#include "base/feature_list.h" #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/memory/raw_ptr.h" @@ -35,10 +34,6 @@ namespace { -BASE_FEATURE(kAlwaysUsePrivateFormatForImageReader, - "AlwaysUsePrivateFormatForImageReader", - base::FEATURE_ENABLED_BY_DEFAULT); - bool IsSurfaceControl(TextureOwner::Mode mode) { switch (mode) { case TextureOwner::Mode::kAImageReaderInsecureSurfaceControl: @@ -147,13 +142,6 @@ // Surface. int32_t width = 1, height = 1; max_images_ = NumRequiredMaxImages(mode); - AIMAGE_FORMATS format = mode == Mode::kAImageReaderSecureSurfaceControl - ? AIMAGE_FORMAT_PRIVATE - : AIMAGE_FORMAT_YUV_420_888; - - if (base::FeatureList::IsEnabled(kAlwaysUsePrivateFormatForImageReader)) { - format = AIMAGE_FORMAT_PRIVATE; - } AImageReader* reader = nullptr; @@ -167,7 +155,7 @@ // Create a new reader for images of the desired size and format. media_status_t return_code = AImageReader_newWithUsage( - width, height, format, usage, max_images_, &reader); + width, height, AIMAGE_FORMAT_PRIVATE, usage, max_images_, &reader); if (return_code != AMEDIA_OK) { LOG(ERROR) << " Image reader creation failed on device model : " << base::android::BuildInfo::GetInstance()->model()
diff --git a/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.cc index 649aa4f..b69b501 100644 --- a/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.cc
@@ -76,33 +76,6 @@ } } -std::unique_ptr<SharedImageBacking> DCompImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe, - base::span<const uint8_t> pixel_data) { - NOTREACHED(); -} - -std::unique_ptr<SharedImageBacking> DCompImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) { - NOTREACHED(); -} - bool DCompImageBackingFactory::IsSupported( SharedImageUsageSet usage, viz::SharedImageFormat format,
diff --git a/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.h b/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.h index 236f5864..8abc05f1 100644 --- a/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/dcomp_image_backing_factory.h
@@ -45,27 +45,6 @@ SharedImageUsageSet usage, std::string debug_label, bool is_thread_safe) override; - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe, - base::span<const uint8_t> pixel_data) override; - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) override; bool IsSupported(SharedImageUsageSet usage, viz::SharedImageFormat format,
diff --git a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc index 40c4ffb..5f43307 100644 --- a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.cc
@@ -84,19 +84,6 @@ pixel_data); } -std::unique_ptr<SharedImageBacking> EGLImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) { - NOTREACHED(); -} - bool EGLImageBackingFactory::IsSupported(SharedImageUsageSet usage, viz::SharedImageFormat format, const gfx::Size& size,
diff --git a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h index a4c0a124..1cd991b 100644 --- a/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/egl_image_backing_factory.h
@@ -59,16 +59,6 @@ std::string debug_label, bool is_thread_safe, base::span<const uint8_t> pixel_data) override; - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) override; bool IsSupported(SharedImageUsageSet usage, viz::SharedImageFormat format, const gfx::Size& size,
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc index ffe1e58..805c6bf 100644 --- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.cc
@@ -147,20 +147,6 @@ usage, std::move(debug_label), pixel_data); } -std::unique_ptr<SharedImageBacking> -GLTextureImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) { - NOTREACHED(); -} - bool GLTextureImageBackingFactory::IsSupported( SharedImageUsageSet usage, viz::SharedImageFormat format,
diff --git a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h index 80778fb..fcf65c9 100644 --- a/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/gl_texture_image_backing_factory.h
@@ -62,16 +62,6 @@ std::string debug_label, bool is_thread_safe, base::span<const uint8_t> pixel_data) override; - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) override; bool IsSupported(SharedImageUsageSet usage, viz::SharedImageFormat format, const gfx::Size& size,
diff --git a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc index ef5c1db..2eecb4f 100644 --- a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.cc
@@ -44,35 +44,6 @@ return texture; } -std::unique_ptr<SharedImageBacking> -RawDrawImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe, - base::span<const uint8_t> data) { - NOTREACHED() << "Not supported"; -} - -std::unique_ptr<SharedImageBacking> -RawDrawImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) { - NOTREACHED(); -} - bool RawDrawImageBackingFactory::CanUseRawDrawImageBacking( SharedImageUsageSet usage, GrContextType gr_context_type) const {
diff --git a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h index 03afbff3..03b7894 100644 --- a/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/raw_draw_image_backing_factory.h
@@ -29,27 +29,6 @@ SharedImageUsageSet usage, std::string debug_label, bool is_thread_safe) override; - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe, - base::span<const uint8_t> pixel_data) override; - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) override; bool IsSupported(SharedImageUsageSet usage, viz::SharedImageFormat format, const gfx::Size& size,
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/shared_image_backing_factory.cc index a69114222..25f2be7e 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/shared_image_backing_factory.cc
@@ -30,6 +30,46 @@ SkAlphaType alpha_type, SharedImageUsageSet usage, std::string debug_label, + bool is_thread_safe) { + NOTREACHED(); +} +std::unique_ptr<SharedImageBacking> +SharedImageBackingFactory::CreateSharedImage( + const Mailbox& mailbox, + viz::SharedImageFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + GrSurfaceOrigin surface_origin, + SkAlphaType alpha_type, + SharedImageUsageSet usage, + std::string debug_label, + bool is_thread_safe, + base::span<const uint8_t> pixel_data) { + NOTREACHED(); +} +std::unique_ptr<SharedImageBacking> +SharedImageBackingFactory::CreateSharedImage( + const Mailbox& mailbox, + viz::SharedImageFormat format, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + GrSurfaceOrigin surface_origin, + SkAlphaType alpha_type, + SharedImageUsageSet usage, + std::string debug_label, + gfx::GpuMemoryBufferHandle handle) { + NOTREACHED(); +} +std::unique_ptr<SharedImageBacking> +SharedImageBackingFactory::CreateSharedImage(const Mailbox& mailbox, + viz::SharedImageFormat format, + SurfaceHandle surface_handle, + const gfx::Size& size, + const gfx::ColorSpace& color_space, + GrSurfaceOrigin surface_origin, + SkAlphaType alpha_type, + SharedImageUsageSet usage, + std::string debug_label, bool is_thread_safe, gfx::BufferUsage buffer_usage) { NOTREACHED();
diff --git a/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h b/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h index 6f53d5db..b07e1c14 100644 --- a/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/shared_image_backing_factory.h
@@ -54,7 +54,7 @@ SkAlphaType alpha_type, SharedImageUsageSet usage, std::string debug_label, - bool is_thread_safe) = 0; + bool is_thread_safe); virtual std::unique_ptr<SharedImageBacking> CreateSharedImage( const Mailbox& mailbox, viz::SharedImageFormat format, @@ -65,7 +65,7 @@ SharedImageUsageSet usage, std::string debug_label, bool is_thread_safe, - base::span<const uint8_t> pixel_data) = 0; + base::span<const uint8_t> pixel_data); virtual std::unique_ptr<SharedImageBacking> CreateSharedImage( const Mailbox& mailbox, viz::SharedImageFormat format, @@ -75,7 +75,7 @@ SkAlphaType alpha_type, SharedImageUsageSet usage, std::string debug_label, - gfx::GpuMemoryBufferHandle handle) = 0; + gfx::GpuMemoryBufferHandle handle); // This new api is introduced for MappableSI work where client code sends // |buffer_usage| info while creating shared image. This info is used in some
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 c2c3113..50ea2ce 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
@@ -14,6 +14,7 @@ #if BUILDFLAG(SKIA_USE_METAL) #include "third_party/skia/include/gpu/graphite/mtl/MtlGraphiteTypes.h" +#include "third_party/skia/include/gpu/graphite/mtl/MtlGraphiteTypesUtils.h" #endif namespace gpu {
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc index 1985e7c..f59a416 100644 --- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.cc
@@ -25,36 +25,6 @@ SharedMemoryImageBackingFactory::CreateSharedImage( const Mailbox& mailbox, viz::SharedImageFormat format, - SurfaceHandle surface_handle, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe) { - NOTREACHED(); -} - -std::unique_ptr<SharedImageBacking> -SharedMemoryImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe, - base::span<const uint8_t> pixel_data) { - NOTREACHED(); -} - -std::unique_ptr<SharedImageBacking> -SharedMemoryImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, GrSurfaceOrigin surface_origin,
diff --git a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h index 8db8555..00423456 100644 --- a/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/shared_memory_image_backing_factory.h
@@ -24,30 +24,6 @@ std::unique_ptr<SharedImageBacking> CreateSharedImage( const Mailbox& mailbox, viz::SharedImageFormat format, - SurfaceHandle surface_handle, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe) override; - - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - bool is_thread_safe, - base::span<const uint8_t> pixel_data) override; - - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, const gfx::Size& size, const gfx::ColorSpace& color_space, GrSurfaceOrigin surface_origin,
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc index f04fdef..159c56c 100644 --- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.cc
@@ -156,20 +156,6 @@ return backing; } -std::unique_ptr<SharedImageBacking> -WrappedSkImageBackingFactory::CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) { - NOTREACHED(); -} - bool WrappedSkImageBackingFactory::IsSupported( SharedImageUsageSet usage, viz::SharedImageFormat format,
diff --git a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h index c4864e7..1698d69 100644 --- a/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/wrapped_sk_image_backing_factory.h
@@ -53,16 +53,6 @@ std::string debug_label, bool is_thread_safe, base::span<const uint8_t> pixel_data) override; - std::unique_ptr<SharedImageBacking> CreateSharedImage( - const Mailbox& mailbox, - viz::SharedImageFormat format, - const gfx::Size& size, - const gfx::ColorSpace& color_space, - GrSurfaceOrigin surface_origin, - SkAlphaType alpha_type, - SharedImageUsageSet usage, - std::string debug_label, - gfx::GpuMemoryBufferHandle handle) override; bool IsSupported(SharedImageUsageSet usage, viz::SharedImageFormat format, const gfx::Size& size,
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index e0b6ce0c..c549a81c 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc
@@ -916,14 +916,21 @@ adapter_options_get_gl_proc.display = display; adapter_options_get_gl_proc.nextInChain = adapter_options.nextInChain; adapter_options.nextInChain = &adapter_options_get_gl_proc; - EGLSurface drawSurface = eglGetCurrentSurface(EGL_DRAW); - EGLSurface readSurface = eglGetCurrentSurface(EGL_READ); - EGLContext context = eglGetCurrentContext(); + EGLSurface drawSurface = nullptr; + EGLSurface readSurface = nullptr; + EGLContext context = nullptr; + if (gl::GetGLImplementation() != gl::kGLImplementationDisabled) { + drawSurface = eglGetCurrentSurface(EGL_DRAW); + readSurface = eglGetCurrentSurface(EGL_READ); + context = eglGetCurrentContext(); + } // Dawn WebGPU API calls, such as adapter.CreateDevice(), may change the // EGLContext. Restore the context on return from this function. absl::Cleanup on_return = [display, drawSurface, readSurface, context] { - eglMakeCurrent(display, drawSurface, readSurface, context); + if (gl::GetGLImplementation() != gl::kGLImplementationDisabled) { + eglMakeCurrent(display, drawSurface, readSurface, context); + } }; #endif
diff --git a/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json b/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json index 618c2bf..8ecdb58 100644 --- a/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json +++ b/infra/config/generated/builders/ci/Linux Builder/targets/chromium.linux.json
@@ -233,7 +233,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 30 + "shards": 33 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -1422,7 +1422,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1913,7 +1913,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1943,7 +1943,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 14 + "shards": 13 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json b/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json index 98257464..b9f03d9 100644 --- a/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json +++ b/infra/config/generated/builders/ci/Linux TSan Builder/targets/chromium.memory.json
@@ -1318,7 +1318,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 5 }, "test": "unit_tests", "test_id_prefix": "ninja://chrome/test:unit_tests/"
diff --git a/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json b/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json index 98257464..b9f03d9 100644 --- a/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json +++ b/infra/config/generated/builders/ci/Linux TSan Tests/targets/chromium.memory.json
@@ -1318,7 +1318,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 5 }, "test": "unit_tests", "test_id_prefix": "ninja://chrome/test:unit_tests/"
diff --git a/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json b/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json index 24326a1..18086c5 100644 --- a/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json +++ b/infra/config/generated/builders/ci/Linux Tests/targets/chromium.linux.json
@@ -202,7 +202,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 30 + "shards": 33 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -1391,7 +1391,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1882,7 +1882,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1912,7 +1912,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 14 + "shards": 13 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/ci/WebKit Linux MSAN/targets/chromium.memory.json b/infra/config/generated/builders/ci/WebKit Linux MSAN/targets/chromium.memory.json index e66b807..b0fed1b 100644 --- a/infra/config/generated/builders/ci/WebKit Linux MSAN/targets/chromium.memory.json +++ b/infra/config/generated/builders/ci/WebKit Linux MSAN/targets/chromium.memory.json
@@ -117,6 +117,9 @@ "dimensions": { "os": "Ubuntu-22.04" }, + "expiration": 36000, + "hard_timeout": 10800, + "io_timeout": 3600, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 18 },
diff --git a/infra/config/generated/builders/ci/Win x64 Builder/targets/chromium.win.json b/infra/config/generated/builders/ci/Win x64 Builder/targets/chromium.win.json index 5e24353..0653784 100644 --- a/infra/config/generated/builders/ci/Win x64 Builder/targets/chromium.win.json +++ b/infra/config/generated/builders/ci/Win x64 Builder/targets/chromium.win.json
@@ -1994,7 +1994,7 @@ "os": "Windows-10-19045" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 + "shards": 15 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/ci/Win10 Tests x64/targets/chromium.win.json b/infra/config/generated/builders/ci/Win10 Tests x64/targets/chromium.win.json index caa8b02a..c509ebf 100644 --- a/infra/config/generated/builders/ci/Win10 Tests x64/targets/chromium.win.json +++ b/infra/config/generated/builders/ci/Win10 Tests x64/targets/chromium.win.json
@@ -1971,7 +1971,7 @@ "os": "Windows-10-19045" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 + "shards": 15 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/ci/android-15-x64-rel/targets/chromium.android.json b/infra/config/generated/builders/ci/android-15-x64-rel/targets/chromium.android.json index 600e3fb5..9b1e712 100644 --- a/infra/config/generated/builders/ci/android-15-x64-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/ci/android-15-x64-rel/targets/chromium.android.json
@@ -90,7 +90,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 + "shards": 14 }, "test": "android_browsertests", "test_id_prefix": "ninja://chrome/test:android_browsertests/" @@ -943,7 +943,8 @@ "caches": "android_35_google_apis_x64" } }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 }, "test": "components_browsertests", "test_id_prefix": "ninja://components:components_browsertests/"
diff --git a/infra/config/generated/builders/ci/android-oreo-x86-rel/targets/chromium.android.json b/infra/config/generated/builders/ci/android-oreo-x86-rel/targets/chromium.android.json index 1feaa63..11526d0 100644 --- a/infra/config/generated/builders/ci/android-oreo-x86-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/ci/android-oreo-x86-rel/targets/chromium.android.json
@@ -1165,7 +1165,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 4 }, "test": "content_unittests", "test_id_prefix": "ninja://content/test:content_unittests/" @@ -3102,7 +3102,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 + "shards": 7 }, "test": "blink_unittests", "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
diff --git a/infra/config/generated/builders/ci/fuchsia-code-coverage/targets/chromium.coverage.json b/infra/config/generated/builders/ci/fuchsia-code-coverage/targets/chromium.coverage.json index 5db33312..366ee712 100644 --- a/infra/config/generated/builders/ci/fuchsia-code-coverage/targets/chromium.coverage.json +++ b/infra/config/generated/builders/ci/fuchsia-code-coverage/targets/chromium.coverage.json
@@ -4,7 +4,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -23,7 +23,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -42,7 +42,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -61,7 +61,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -81,7 +81,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -100,7 +100,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -119,7 +119,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -139,7 +139,7 @@ "args": [ "--git-revision=${got_revision}", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -164,7 +164,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -184,7 +184,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -203,7 +203,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -222,7 +222,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -241,7 +241,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -260,7 +260,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -279,7 +279,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -298,7 +298,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -321,7 +321,7 @@ "--test-arg=--headless", "--test-arg=--ozone-platform=headless", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -341,7 +341,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -361,7 +361,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -383,7 +383,7 @@ "--test-arg=--headless", "--test-arg=--ozone-platform=headless", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large", + "--device-spec=x64-emu-large", "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.coverage.content_browsertests.filter", "--test-launcher-jobs=1" ], @@ -405,7 +405,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -425,7 +425,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -444,7 +444,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -463,7 +463,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -482,7 +482,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -501,7 +501,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -520,7 +520,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -540,7 +540,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -559,7 +559,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -578,7 +578,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -598,7 +598,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -617,7 +617,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -637,7 +637,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -656,7 +656,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -675,7 +675,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -694,7 +694,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -714,7 +714,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -733,7 +733,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -752,7 +752,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -772,7 +772,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -792,7 +792,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -813,7 +813,7 @@ "args": [ "--test-arg=--ozone-platform=headless", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -832,7 +832,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -851,7 +851,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -871,7 +871,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -891,7 +891,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -910,7 +910,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -929,7 +929,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -948,7 +948,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -967,7 +967,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -987,7 +987,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1006,7 +1006,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1025,7 +1025,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1044,7 +1044,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1064,7 +1064,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1084,7 +1084,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1104,7 +1104,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1123,7 +1123,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1143,7 +1143,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large", + "--device-spec=x64-emu-large", "--test-launcher-jobs=1" ], "isolate_profile_data": true, @@ -1164,7 +1164,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1183,7 +1183,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1202,7 +1202,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1221,7 +1221,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1242,7 +1242,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": {
diff --git a/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json b/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json index f71df2b1..e5330d2 100644 --- a/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json +++ b/infra/config/generated/builders/ci/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json
@@ -6,6 +6,9 @@ ], "gtest_tests": [ { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -26,6 +29,9 @@ "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -46,6 +52,9 @@ "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -66,6 +75,9 @@ "test_id_prefix": "ninja://ui/aura:aura_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -86,6 +98,9 @@ "test_id_prefix": "ninja://base:base_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -106,6 +121,9 @@ "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -126,6 +144,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -147,7 +168,8 @@ }, { "args": [ - "--git-revision=${got_revision}" + "--git-revision=${got_revision}", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -174,6 +196,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -195,6 +220,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -215,6 +243,9 @@ "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -235,6 +266,9 @@ "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -255,6 +289,9 @@ "test_id_prefix": "ninja://media/capture:capture_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -275,6 +312,9 @@ "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -295,6 +335,9 @@ "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -315,6 +358,9 @@ "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -339,7 +385,8 @@ "args": [ "--test-arg=--disable-gpu", "--test-arg=--headless", - "--test-arg=--ozone-platform=headless" + "--test-arg=--ozone-platform=headless", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -361,6 +408,9 @@ "test_id_prefix": "ninja://components:components_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -382,6 +432,9 @@ "test_id_prefix": "ninja://components:components_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -405,7 +458,8 @@ "args": [ "--test-arg=--disable-gpu", "--test-arg=--headless", - "--test-arg=--ozone-platform=headless" + "--test-arg=--ozone-platform=headless", + "--device-spec=x64-emu-large" ], "ci_only": true, "isolate_profile_data": true, @@ -429,6 +483,9 @@ "test_id_prefix": "ninja://content/test:content_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -450,6 +507,9 @@ "test_id_prefix": "ninja://content/test:content_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -470,6 +530,9 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -490,6 +553,9 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -510,6 +576,9 @@ "test_id_prefix": "ninja://ui/events:events_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -530,6 +599,9 @@ "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -550,6 +622,9 @@ "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -570,6 +645,9 @@ "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -590,6 +668,9 @@ "test_id_prefix": "ninja://gin:gin_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -610,6 +691,9 @@ "test_id_prefix": "ninja://google_apis:google_apis_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -630,6 +714,9 @@ "test_id_prefix": "ninja://gpu:gpu_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -650,6 +737,9 @@ "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -670,6 +760,9 @@ "test_id_prefix": "ninja://headless:headless_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -690,6 +783,9 @@ "test_id_prefix": "ninja://headless:headless_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -710,6 +806,9 @@ "test_id_prefix": "ninja://ipc:ipc_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -730,6 +829,9 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -750,6 +852,9 @@ "test_id_prefix": "ninja://media:media_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -770,6 +875,9 @@ "test_id_prefix": "ninja://ui/message_center:message_center_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -790,6 +898,9 @@ "test_id_prefix": "ninja://media/midi:midi_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -810,6 +921,9 @@ "test_id_prefix": "ninja://mojo:mojo_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -831,7 +945,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -855,7 +970,8 @@ }, { "args": [ - "--test-arg=--ozone-platform=headless" + "--test-arg=--ozone-platform=headless", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -877,6 +993,9 @@ "test_id_prefix": "ninja://ui/ozone/gl:ozone_gl_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -897,6 +1016,9 @@ "test_id_prefix": "ninja://ui/ozone:ozone_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -918,7 +1040,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -940,6 +1063,9 @@ "test_id_prefix": "ninja://services:services_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -960,6 +1086,9 @@ "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -980,6 +1109,9 @@ "test_id_prefix": "ninja://skia:skia_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1000,6 +1132,9 @@ "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1020,6 +1155,9 @@ "test_id_prefix": "ninja://sql:sql_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1041,7 +1179,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1063,6 +1202,9 @@ "test_id_prefix": "ninja://ui/base:ui_base_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1083,6 +1225,9 @@ "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1103,6 +1248,9 @@ "test_id_prefix": "ninja://ui/tests:ui_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1124,7 +1272,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1147,7 +1296,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1170,7 +1320,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1192,6 +1343,9 @@ "test_id_prefix": "ninja://components/viz:viz_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1212,6 +1366,9 @@ "test_id_prefix": "ninja://fuchsia_web/webengine:web_engine_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1232,6 +1389,9 @@ "test_id_prefix": "ninja://fuchsia_web/webengine:web_engine_integration_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1252,6 +1412,9 @@ "test_id_prefix": "ninja://fuchsia_web/webengine:web_engine_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1272,6 +1435,9 @@ "test_id_prefix": "ninja://ui/wm:wm_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1292,6 +1458,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1314,6 +1483,9 @@ ], "isolated_scripts": [ { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -1336,7 +1508,8 @@ { "args": [ "--num-retries=3", - "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json" + "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1364,7 +1537,8 @@ { "args": [ "--num-retries=3", - "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json" + "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1399,7 +1573,8 @@ "--stable-jobs", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", "--enforce-browser-version", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1435,7 +1610,8 @@ "--dont-restore-color-profile-after-test", "--test-machine-name", "${buildername}", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1472,7 +1648,8 @@ "--stable-jobs", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", "--enforce-browser-version", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1504,7 +1681,8 @@ "--stable-jobs", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", "--enforce-browser-version", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1540,7 +1718,8 @@ "--dont-restore-color-profile-after-test", "--test-machine-name", "${buildername}", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1578,7 +1757,8 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", "--enforce-browser-version", "--dont-restore-color-profile-after-test", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": {
diff --git a/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json b/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json index db404f8..8bf2350d 100644 --- a/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json +++ b/infra/config/generated/builders/ci/linux-chromeos-rel/targets/chromium.chromiumos.json
@@ -295,7 +295,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 104 + "shards": 112 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/"
diff --git a/infra/config/generated/builders/try/android-15-x64-rel/targets/chromium.android.json b/infra/config/generated/builders/try/android-15-x64-rel/targets/chromium.android.json index 600e3fb5..9b1e712 100644 --- a/infra/config/generated/builders/try/android-15-x64-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/try/android-15-x64-rel/targets/chromium.android.json
@@ -90,7 +90,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 + "shards": 14 }, "test": "android_browsertests", "test_id_prefix": "ninja://chrome/test:android_browsertests/" @@ -943,7 +943,8 @@ "caches": "android_35_google_apis_x64" } }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 }, "test": "components_browsertests", "test_id_prefix": "ninja://components:components_browsertests/"
diff --git a/infra/config/generated/builders/try/android-oreo-x86-rel/targets/chromium.android.json b/infra/config/generated/builders/try/android-oreo-x86-rel/targets/chromium.android.json index 1feaa63..11526d0 100644 --- a/infra/config/generated/builders/try/android-oreo-x86-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/try/android-oreo-x86-rel/targets/chromium.android.json
@@ -1165,7 +1165,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 4 }, "test": "content_unittests", "test_id_prefix": "ninja://content/test:content_unittests/" @@ -3102,7 +3102,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 + "shards": 7 }, "test": "blink_unittests", "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
diff --git a/infra/config/generated/builders/try/android-x64-rel/targets/chromium.android.json b/infra/config/generated/builders/try/android-x64-rel/targets/chromium.android.json index 7c0f521..8045728 100644 --- a/infra/config/generated/builders/try/android-x64-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/try/android-x64-rel/targets/chromium.android.json
@@ -147,7 +147,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 12 + "shards": 14 }, "test": "android_browsertests", "test_id_prefix": "ninja://chrome/test:android_browsertests/" @@ -1000,7 +1000,8 @@ "caches": "android_35_google_apis_x64" } }, - "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com" + "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", + "shards": 2 }, "test": "components_browsertests", "test_id_prefix": "ninja://components:components_browsertests/"
diff --git a/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json b/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json index 1feaa63..11526d0 100644 --- a/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json +++ b/infra/config/generated/builders/try/android-x86-rel/targets/chromium.android.json
@@ -1165,7 +1165,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 4 }, "test": "content_unittests", "test_id_prefix": "ninja://content/test:content_unittests/" @@ -3102,7 +3102,7 @@ } }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 6 + "shards": 7 }, "test": "blink_unittests", "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/"
diff --git a/infra/config/generated/builders/try/fuchsia-code-coverage/targets/chromium.coverage.json b/infra/config/generated/builders/try/fuchsia-code-coverage/targets/chromium.coverage.json index 5db33312..366ee712 100644 --- a/infra/config/generated/builders/try/fuchsia-code-coverage/targets/chromium.coverage.json +++ b/infra/config/generated/builders/try/fuchsia-code-coverage/targets/chromium.coverage.json
@@ -4,7 +4,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -23,7 +23,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -42,7 +42,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -61,7 +61,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -81,7 +81,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -100,7 +100,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -119,7 +119,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -139,7 +139,7 @@ "args": [ "--git-revision=${got_revision}", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -164,7 +164,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -184,7 +184,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -203,7 +203,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -222,7 +222,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -241,7 +241,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -260,7 +260,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -279,7 +279,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -298,7 +298,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -321,7 +321,7 @@ "--test-arg=--headless", "--test-arg=--ozone-platform=headless", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -341,7 +341,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -361,7 +361,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -383,7 +383,7 @@ "--test-arg=--headless", "--test-arg=--ozone-platform=headless", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large", + "--device-spec=x64-emu-large", "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.coverage.content_browsertests.filter", "--test-launcher-jobs=1" ], @@ -405,7 +405,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -425,7 +425,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -444,7 +444,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -463,7 +463,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -482,7 +482,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -501,7 +501,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -520,7 +520,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -540,7 +540,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -559,7 +559,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -578,7 +578,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -598,7 +598,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -617,7 +617,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -637,7 +637,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -656,7 +656,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -675,7 +675,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -694,7 +694,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -714,7 +714,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -733,7 +733,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -752,7 +752,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -772,7 +772,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -792,7 +792,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -813,7 +813,7 @@ "args": [ "--test-arg=--ozone-platform=headless", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -832,7 +832,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -851,7 +851,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -871,7 +871,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -891,7 +891,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -910,7 +910,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -929,7 +929,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -948,7 +948,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -967,7 +967,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -987,7 +987,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1006,7 +1006,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1025,7 +1025,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1044,7 +1044,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1064,7 +1064,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1084,7 +1084,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1104,7 +1104,7 @@ "args": [ "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter", "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1123,7 +1123,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1143,7 +1143,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large", + "--device-spec=x64-emu-large", "--test-launcher-jobs=1" ], "isolate_profile_data": true, @@ -1164,7 +1164,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1183,7 +1183,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1202,7 +1202,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1221,7 +1221,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1242,7 +1242,7 @@ { "args": [ "--code-coverage-dir=${ISOLATED_OUTDIR}", - "--device-spec=virtual_device_large" + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": {
diff --git a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json index f71df2b1..e5330d2 100644 --- a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json +++ b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/targets/chromium.fuchsia.json
@@ -6,6 +6,9 @@ ], "gtest_tests": [ { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -26,6 +29,9 @@ "test_id_prefix": "ninja://third_party/abseil-cpp:absl_hardening_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -46,6 +52,9 @@ "test_id_prefix": "ninja://ui/accessibility:accessibility_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -66,6 +75,9 @@ "test_id_prefix": "ninja://ui/aura:aura_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -86,6 +98,9 @@ "test_id_prefix": "ninja://base:base_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -106,6 +121,9 @@ "test_id_prefix": "ninja://third_party/blink/common:blink_common_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -126,6 +144,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_fuzzer_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -147,7 +168,8 @@ }, { "args": [ - "--git-revision=${got_revision}" + "--git-revision=${got_revision}", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -174,6 +196,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/platform:blink_platform_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -195,6 +220,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/controller:blink_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -215,6 +243,9 @@ "test_id_prefix": "ninja://third_party/boringssl:boringssl_crypto_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -235,6 +266,9 @@ "test_id_prefix": "ninja://third_party/boringssl:boringssl_ssl_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -255,6 +289,9 @@ "test_id_prefix": "ninja://media/capture:capture_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -275,6 +312,9 @@ "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -295,6 +335,9 @@ "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_integration_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -315,6 +358,9 @@ "test_id_prefix": "ninja://fuchsia_web/runners:cast_runner_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -339,7 +385,8 @@ "args": [ "--test-arg=--disable-gpu", "--test-arg=--headless", - "--test-arg=--ozone-platform=headless" + "--test-arg=--ozone-platform=headless", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -361,6 +408,9 @@ "test_id_prefix": "ninja://components:components_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -382,6 +432,9 @@ "test_id_prefix": "ninja://components:components_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -405,7 +458,8 @@ "args": [ "--test-arg=--disable-gpu", "--test-arg=--headless", - "--test-arg=--ozone-platform=headless" + "--test-arg=--ozone-platform=headless", + "--device-spec=x64-emu-large" ], "ci_only": true, "isolate_profile_data": true, @@ -429,6 +483,9 @@ "test_id_prefix": "ninja://content/test:content_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -450,6 +507,9 @@ "test_id_prefix": "ninja://content/test:content_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -470,6 +530,9 @@ "test_id_prefix": "ninja://crypto:crypto_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -490,6 +553,9 @@ "test_id_prefix": "ninja://ui/display:display_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -510,6 +576,9 @@ "test_id_prefix": "ninja://ui/events:events_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -530,6 +599,9 @@ "test_id_prefix": "ninja://components/services/filesystem:filesystem_service_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -550,6 +622,9 @@ "test_id_prefix": "ninja://google_apis/gcm:gcm_unit_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -570,6 +645,9 @@ "test_id_prefix": "ninja://ui/gfx:gfx_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -590,6 +668,9 @@ "test_id_prefix": "ninja://gin:gin_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -610,6 +691,9 @@ "test_id_prefix": "ninja://google_apis:google_apis_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -630,6 +714,9 @@ "test_id_prefix": "ninja://gpu:gpu_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -650,6 +737,9 @@ "test_id_prefix": "ninja://components/gwp_asan:gwp_asan_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -670,6 +760,9 @@ "test_id_prefix": "ninja://headless:headless_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -690,6 +783,9 @@ "test_id_prefix": "ninja://headless:headless_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -710,6 +806,9 @@ "test_id_prefix": "ninja://ipc:ipc_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -730,6 +829,9 @@ "test_id_prefix": "ninja://ui/latency:latency_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -750,6 +852,9 @@ "test_id_prefix": "ninja://media:media_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -770,6 +875,9 @@ "test_id_prefix": "ninja://ui/message_center:message_center_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -790,6 +898,9 @@ "test_id_prefix": "ninja://media/midi:midi_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -810,6 +921,9 @@ "test_id_prefix": "ninja://mojo:mojo_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -831,7 +945,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.net_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -855,7 +970,8 @@ }, { "args": [ - "--test-arg=--ozone-platform=headless" + "--test-arg=--ozone-platform=headless", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -877,6 +993,9 @@ "test_id_prefix": "ninja://ui/ozone/gl:ozone_gl_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -897,6 +1016,9 @@ "test_id_prefix": "ninja://ui/ozone:ozone_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -918,7 +1040,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.services_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -940,6 +1063,9 @@ "test_id_prefix": "ninja://services:services_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -960,6 +1086,9 @@ "test_id_prefix": "ninja://ui/shell_dialogs:shell_dialogs_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -980,6 +1109,9 @@ "test_id_prefix": "ninja://skia:skia_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1000,6 +1132,9 @@ "test_id_prefix": "ninja://ui/snapshot:snapshot_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1020,6 +1155,9 @@ "test_id_prefix": "ninja://sql:sql_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1041,7 +1179,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.ui_base_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1063,6 +1202,9 @@ "test_id_prefix": "ninja://ui/base:ui_base_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1083,6 +1225,9 @@ "test_id_prefix": "ninja://ui/touch_selection:ui_touch_selection_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1103,6 +1248,9 @@ "test_id_prefix": "ninja://ui/tests:ui_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1124,7 +1272,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_examples_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1147,7 +1296,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.views_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1170,7 +1320,8 @@ }, { "args": [ - "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/fuchsia.viz_unittests.filter", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1192,6 +1343,9 @@ "test_id_prefix": "ninja://components/viz:viz_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1212,6 +1366,9 @@ "test_id_prefix": "ninja://fuchsia_web/webengine:web_engine_browsertests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1232,6 +1389,9 @@ "test_id_prefix": "ninja://fuchsia_web/webengine:web_engine_integration_tests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1252,6 +1412,9 @@ "test_id_prefix": "ninja://fuchsia_web/webengine:web_engine_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1272,6 +1435,9 @@ "test_id_prefix": "ninja://ui/wm:wm_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1292,6 +1458,9 @@ "test_id_prefix": "ninja://third_party/blink/renderer/platform/wtf:wtf_unittests/" }, { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_gtest_merge.py" @@ -1314,6 +1483,9 @@ ], "isolated_scripts": [ { + "args": [ + "--device-spec=x64-emu-large" + ], "isolate_profile_data": true, "merge": { "script": "//testing/merge_scripts/standard_isolated_script_merge.py" @@ -1336,7 +1508,8 @@ { "args": [ "--num-retries=3", - "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json" + "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1364,7 +1537,8 @@ { "args": [ "--num-retries=3", - "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json" + "--write-run-histories-to=${ISOLATED_OUTDIR}/run_histories.json", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1399,7 +1573,8 @@ "--stable-jobs", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", "--enforce-browser-version", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1435,7 +1610,8 @@ "--dont-restore-color-profile-after-test", "--test-machine-name", "${buildername}", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1472,7 +1648,8 @@ "--stable-jobs", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", "--enforce-browser-version", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1504,7 +1681,8 @@ "--stable-jobs", "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc", "--enforce-browser-version", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1540,7 +1718,8 @@ "--dont-restore-color-profile-after-test", "--test-machine-name", "${buildername}", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": { @@ -1578,7 +1757,8 @@ "--extra-browser-args=--enable-logging=stderr --js-flags=--expose-gc --use-cmd-decoder=passthrough --use-gl=angle", "--enforce-browser-version", "--dont-restore-color-profile-after-test", - "--jobs=1" + "--jobs=1", + "--device-spec=x64-emu-large" ], "isolate_profile_data": true, "merge": {
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json b/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json index db404f8..8bf2350d 100644 --- a/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json +++ b/infra/config/generated/builders/try/linux-chromeos-rel/targets/chromium.chromiumos.json
@@ -295,7 +295,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 104 + "shards": 112 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/"
diff --git a/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json b/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json index 618c2bf..8ecdb58 100644 --- a/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux-dcheck-off-rel/targets/chromium.linux.json
@@ -233,7 +233,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 30 + "shards": 33 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -1422,7 +1422,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1913,7 +1913,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1943,7 +1943,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 14 + "shards": 13 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json b/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json index 618c2bf..8ecdb58 100644 --- a/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux-full-remote-rel/targets/chromium.linux.json
@@ -233,7 +233,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 30 + "shards": 33 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -1422,7 +1422,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1913,7 +1913,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1943,7 +1943,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 14 + "shards": 13 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json b/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json index 618c2bf..8ecdb58 100644 --- a/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux-rel/targets/chromium.linux.json
@@ -233,7 +233,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 30 + "shards": 33 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -1422,7 +1422,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1913,7 +1913,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1943,7 +1943,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 14 + "shards": 13 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/try/linux-webkit-msan-rel/targets/chromium.memory.json b/infra/config/generated/builders/try/linux-webkit-msan-rel/targets/chromium.memory.json index e66b807..b0fed1b 100644 --- a/infra/config/generated/builders/try/linux-webkit-msan-rel/targets/chromium.memory.json +++ b/infra/config/generated/builders/try/linux-webkit-msan-rel/targets/chromium.memory.json
@@ -117,6 +117,9 @@ "dimensions": { "os": "Ubuntu-22.04" }, + "expiration": 36000, + "hard_timeout": 10800, + "io_timeout": 3600, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", "shards": 18 },
diff --git a/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json b/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json index 618c2bf..8ecdb58 100644 --- a/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json +++ b/infra/config/generated/builders/try/linux_chromium_compile_rel_ng/targets/chromium.linux.json
@@ -233,7 +233,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 30 + "shards": 33 }, "test": "browser_tests", "test_id_prefix": "ninja://chrome/test:browser_tests/" @@ -1422,7 +1422,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1913,7 +1913,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 3 + "shards": 2 }, "test": "blink_wpt_tests", "test_id_prefix": "ninja://:blink_wpt_tests/" @@ -1943,7 +1943,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 14 + "shards": 13 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json index 98257464..b9f03d9 100644 --- a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json +++ b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/targets/chromium.memory.json
@@ -1318,7 +1318,7 @@ "os": "Ubuntu-22.04" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 4 + "shards": 5 }, "test": "unit_tests", "test_id_prefix": "ninja://chrome/test:unit_tests/"
diff --git a/infra/config/generated/builders/try/mac_chromium_11.0_rel_ng/gn-args.json b/infra/config/generated/builders/try/mac_chromium_11.0_rel_ng/gn-args.json index bdfd37b..d4bed86 100644 --- a/infra/config/generated/builders/try/mac_chromium_11.0_rel_ng/gn-args.json +++ b/infra/config/generated/builders/try/mac_chromium_11.0_rel_ng/gn-args.json
@@ -1,8 +1,10 @@ { "gn_args": { "dcheck_always_on": true, + "ffmpeg_branding": "Chrome", "is_component_build": false, "is_debug": false, + "proprietary_codecs": true, "symbol_level": 0, "target_cpu": "x64", "target_os": "mac",
diff --git a/infra/config/generated/builders/try/win-rel/targets/chromium.win.json b/infra/config/generated/builders/try/win-rel/targets/chromium.win.json index 9702b4f..4ce8705e 100644 --- a/infra/config/generated/builders/try/win-rel/targets/chromium.win.json +++ b/infra/config/generated/builders/try/win-rel/targets/chromium.win.json
@@ -1994,7 +1994,7 @@ "os": "Windows-10-19045" }, "service_account": "chromium-tester@chops-service-accounts.iam.gserviceaccount.com", - "shards": 20 + "shards": 15 }, "test": "headless_shell_wpt", "test_id_prefix": "ninja://:headless_shell_wpt/"
diff --git a/infra/config/generated/cq-builders.md b/infra/config/generated/cq-builders.md index 4b463c6..b77d47ee 100644 --- a/infra/config/generated/cq-builders.md +++ b/infra/config/generated/cq-builders.md
@@ -832,7 +832,7 @@ * Experiment percentage: 10.0 * [mac14-arm64-rel](https://ci.chromium.org/p/chromium/builders/try/mac14-arm64-rel) ([definition](https://cs.chromium.org/search?q=+file:/try/.*\.star$+""mac14-arm64-rel"")) - * Experiment percentage: 100.0 + * Experiment percentage: 75.0 ## Mega CQ builders
diff --git a/infra/config/generated/luci/commit-queue.cfg b/infra/config/generated/luci/commit-queue.cfg index 0a7275c..c920ce50 100644 --- a/infra/config/generated/luci/commit-queue.cfg +++ b/infra/config/generated/luci/commit-queue.cfg
@@ -5959,7 +5959,7 @@ } builders { name: "chromium/try/mac14-arm64-rel" - experiment_percentage: 100 + experiment_percentage: 75 location_filters { gerrit_host_regexp: ".*" gerrit_project_regexp: ".*"
diff --git a/infra/config/subprojects/chromium/ci/chromium.fuchsia.star b/infra/config/subprojects/chromium/ci/chromium.fuchsia.star index ca4dd90..d501eba 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fuchsia.star +++ b/infra/config/subprojects/chromium/ci/chromium.fuchsia.star
@@ -300,6 +300,7 @@ "cast_test_lists", ], mixins = [ + "fuchsia-large-device-spec", "isolate_profile_data", "linux-jammy", targets.mixin(
diff --git a/infra/config/subprojects/chromium/ci/chromium.memory.star b/infra/config/subprojects/chromium/ci/chromium.memory.star index 49ff86a..ca1e082 100644 --- a/infra/config/subprojects/chromium/ci/chromium.memory.star +++ b/infra/config/subprojects/chromium/ci/chromium.memory.star
@@ -1248,6 +1248,11 @@ args = [ "-j6", ], + swarming = targets.swarming( + expiration_sec = 36000, + hard_timeout_sec = 10800, + io_timeout_sec = 3600, + ), ), }, ),
diff --git a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star index c11daae..6667a11 100644 --- a/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star +++ b/infra/config/subprojects/chromium/try/tryserver.chromium.mac.star
@@ -306,10 +306,7 @@ contact_team_email = "bling-engprod@google.com", main_list_view = "try", tryjob = try_.job( - # TODO (crbug.com/338209817): move out of - # experimental CQ after confirming it's consistently - # green and fast. - experiment_percentage = 100, + experiment_percentage = 75, ), ) @@ -336,10 +333,8 @@ ], gn_args = gn_args.config( configs = [ + "ci/Mac Builder", "release_try_builder", - "remoteexec", - "mac", - "x64", ], ), builderless = False,
diff --git a/infra/config/targets/README.md b/infra/config/targets/README.md index e0d180d3..a213b03 100644 --- a/infra/config/targets/README.md +++ b/infra/config/targets/README.md
@@ -78,11 +78,6 @@ They can be specified when configuring a basic suite in a matrix compound suite to expand all of the tests in the basic suite with each of the specified variants. - * [cros-skylab-variants.json](./cros-skylab-variants.json), - [lacros-version-skew-variants.json](./lacros-version-skew-variants.json) - - These files are consumed by variants.star to define certain subsets of - variants. Json files are used because they are auto-generated by builders - running periodically and json is easily manipulated programatticaly. ## Tests in starlark
diff --git a/infra/config/targets/autoshard_exceptions.json b/infra/config/targets/autoshard_exceptions.json index 61c5b73..faa51bd 100644 --- a/infra/config/targets/autoshard_exceptions.json +++ b/infra/config/targets/autoshard_exceptions.json
@@ -92,6 +92,38 @@ "shards": 2 } }, + "android-15-x64-rel": { + "android_browsertests": { + "debug": { + "avg_num_builds_per_peak_hour": 41, + "estimated_bot_hour_delta": 0.3, + "prev_avg_pending_time_sec": 21.6, + "prev_p50_pending_time_sec": 1.0, + "prev_p90_pending_time_sec": 68.0, + "prev_percentile_duration_minutes": 17.04, + "prev_shard_count": 12, + "simulated_max_shard_duration": 14.64, + "test_overhead_min": 0.21666666666666667, + "try_builder": "android-x64-rel" + }, + "shards": 14 + }, + "components_browsertests": { + "debug": { + "avg_num_builds_per_peak_hour": 41, + "estimated_bot_hour_delta": 1.37, + "prev_avg_pending_time_sec": 17.4, + "prev_p50_pending_time_sec": 0.0, + "prev_p90_pending_time_sec": 61.0, + "prev_percentile_duration_minutes": 16.52, + "prev_shard_count": 1, + "simulated_max_shard_duration": 9.26, + "test_overhead_min": 2.0, + "try_builder": "android-x64-rel" + }, + "shards": 2 + } + }, "android-oreo-x86-rel": { "content_browsertests": { "debug": { @@ -108,6 +140,21 @@ }, "shards": 70 }, + "content_unittests": { + "debug": { + "avg_num_builds_per_peak_hour": 41, + "estimated_bot_hour_delta": 1.4, + "prev_avg_pending_time_sec": 28.3, + "prev_p50_pending_time_sec": 0.0, + "prev_p90_pending_time_sec": 101.0, + "prev_percentile_duration_minutes": 16.14, + "prev_shard_count": 3, + "simulated_max_shard_duration": 12.62, + "test_overhead_min": 2.05, + "try_builder": "android-x86-rel" + }, + "shards": 4 + }, "unit_tests": { "debug": { "avg_num_builds_per_peak_hour": 99, @@ -123,6 +170,21 @@ }, "shards": 2 }, + "webkit_unit_tests": { + "debug": { + "avg_num_builds_per_peak_hour": 41, + "estimated_bot_hour_delta": 1.12, + "prev_avg_pending_time_sec": 32.9, + "prev_p50_pending_time_sec": 1.0, + "prev_p90_pending_time_sec": 120.0, + "prev_percentile_duration_minutes": 16.04, + "prev_shard_count": 6, + "simulated_max_shard_duration": 13.98, + "test_overhead_min": 1.6333333333333333, + "try_builder": "android-x86-rel" + }, + "shards": 7 + }, "webview_instrumentation_test_apk": { "debug": { "avg_num_builds_per_peak_hour": 89, @@ -223,18 +285,18 @@ }, "browser_tests": { "debug": { - "avg_num_builds_per_peak_hour": 90, - "estimated_bot_hour_delta": 5.4, - "prev_avg_pending_time_sec": 24.7, - "prev_p50_pending_time_sec": 2.0, - "prev_p90_pending_time_sec": 86.0, - "prev_percentile_duration_minutes": 16.07, - "prev_shard_count": 96, - "simulated_max_shard_duration": 14.87, - "test_overhead_min": 0.45, + "avg_num_builds_per_peak_hour": 40, + "estimated_bot_hour_delta": 6.49, + "prev_avg_pending_time_sec": 42.7, + "prev_p50_pending_time_sec": 3.0, + "prev_p90_pending_time_sec": 162.0, + "prev_percentile_duration_minutes": 16.02, + "prev_shard_count": 104, + "simulated_max_shard_duration": 14.96, + "test_overhead_min": 1.2166666666666666, "try_builder": "linux-chromeos-rel" }, - "shards": 104 + "shards": 112 }, "components_unittests": { "debug": { @@ -380,33 +442,33 @@ }, "blink_wpt_tests": { "debug": { - "avg_num_builds_per_peak_hour": 94, - "estimated_bot_hour_delta": -17.62, - "prev_avg_pending_time_sec": 19.0, - "prev_p50_pending_time_sec": 1.0, - "prev_p90_pending_time_sec": 67.0, - "prev_percentile_duration_minutes": 5.21, - "prev_shard_count": 13, - "simulated_max_shard_duration": 14.12, - "test_overhead_min": 1.25, + "avg_num_builds_per_peak_hour": 40, + "estimated_bot_hour_delta": -2.38, + "prev_avg_pending_time_sec": 28.4, + "prev_p50_pending_time_sec": 0.0, + "prev_p90_pending_time_sec": 112.0, + "prev_percentile_duration_minutes": 8.11, + "prev_shard_count": 4, + "simulated_max_shard_duration": 14.44, + "test_overhead_min": 1.7833333333333334, "try_builder": "linux-rel" }, - "shards": 4 + "shards": 2 }, "browser_tests": { "debug": { - "avg_num_builds_per_peak_hour": 90, - "estimated_bot_hour_delta": 3.9, - "prev_avg_pending_time_sec": 20.0, - "prev_p50_pending_time_sec": 1.0, - "prev_p90_pending_time_sec": 68.0, - "prev_percentile_duration_minutes": 16.09, - "prev_shard_count": 27, - "simulated_max_shard_duration": 14.57, - "test_overhead_min": 0.8666666666666667, + "avg_num_builds_per_peak_hour": 40, + "estimated_bot_hour_delta": 0.8, + "prev_avg_pending_time_sec": 35.2, + "prev_p50_pending_time_sec": 2.0, + "prev_p90_pending_time_sec": 139.0, + "prev_percentile_duration_minutes": 16.36, + "prev_shard_count": 30, + "simulated_max_shard_duration": 14.91, + "test_overhead_min": 0.4, "try_builder": "linux-rel" }, - "shards": 30 + "shards": 33 }, "components_unittests": { "debug": { @@ -440,33 +502,33 @@ }, "not_site_per_process_blink_wpt_tests": { "debug": { - "avg_num_builds_per_peak_hour": 103, - "estimated_bot_hour_delta": -4.92, - "prev_avg_pending_time_sec": 19.0, + "avg_num_builds_per_peak_hour": 40, + "estimated_bot_hour_delta": -0.71, + "prev_avg_pending_time_sec": 27.6, "prev_p50_pending_time_sec": 0.0, - "prev_p90_pending_time_sec": 70.0, - "prev_percentile_duration_minutes": 6.97, - "prev_shard_count": 5, - "simulated_max_shard_duration": 10.66, - "test_overhead_min": 1.4333333333333333, + "prev_p90_pending_time_sec": 105.0, + "prev_percentile_duration_minutes": 8.35, + "prev_shard_count": 3, + "simulated_max_shard_duration": 11.99, + "test_overhead_min": 1.0666666666666667, "try_builder": "linux-rel" }, - "shards": 3 + "shards": 2 }, "not_site_per_process_headless_shell_wpt_tests": { "debug": { - "avg_num_builds_per_peak_hour": 94, - "estimated_bot_hour_delta": 15.82, - "prev_avg_pending_time_sec": 20.0, + "avg_num_builds_per_peak_hour": 40, + "estimated_bot_hour_delta": -0.51, + "prev_avg_pending_time_sec": 33.1, "prev_p50_pending_time_sec": 1.0, - "prev_p90_pending_time_sec": 71.0, - "prev_percentile_duration_minutes": 17.57, - "prev_shard_count": 11, - "simulated_max_shard_duration": 14.53, - "test_overhead_min": 3.3666666666666667, + "prev_p90_pending_time_sec": 130.0, + "prev_percentile_duration_minutes": 13.67, + "prev_shard_count": 14, + "simulated_max_shard_duration": 14.66, + "test_overhead_min": 0.7666666666666667, "try_builder": "linux-rel" }, - "shards": 14 + "shards": 13 } }, "Linux Tests (Wayland)": { @@ -671,18 +733,18 @@ }, "unit_tests": { "debug": { - "avg_num_builds_per_peak_hour": 100, - "estimated_bot_hour_delta": 2.19, - "prev_avg_pending_time_sec": 29.4, + "avg_num_builds_per_peak_hour": 41, + "estimated_bot_hour_delta": 0.57, + "prev_avg_pending_time_sec": 26.8, "prev_p50_pending_time_sec": 0.0, - "prev_p90_pending_time_sec": 114.0, - "prev_percentile_duration_minutes": 16.36, - "prev_shard_count": 3, - "simulated_max_shard_duration": 12.6, - "test_overhead_min": 1.3166666666666667, + "prev_p90_pending_time_sec": 98.0, + "prev_percentile_duration_minutes": 16.44, + "prev_shard_count": 4, + "simulated_max_shard_duration": 13.32, + "test_overhead_min": 0.8333333333333334, "try_builder": "linux_chromium_tsan_rel_ng" }, - "shards": 4 + "shards": 5 }, "webkit_unit_tests": { "debug": { @@ -735,18 +797,18 @@ }, "headless_shell_wpt_tests": { "debug": { - "avg_num_builds_per_peak_hour": 96, - "estimated_bot_hour_delta": 12.53, - "prev_avg_pending_time_sec": 155.3, - "prev_p50_pending_time_sec": 5.0, - "prev_p90_pending_time_sec": 582.0, - "prev_percentile_duration_minutes": 16.1, - "prev_shard_count": 18, - "simulated_max_shard_duration": 14.88, - "test_overhead_min": 3.9166666666666665, + "avg_num_builds_per_peak_hour": 39, + "estimated_bot_hour_delta": -10.94, + "prev_avg_pending_time_sec": 58.6, + "prev_p50_pending_time_sec": 2.0, + "prev_p90_pending_time_sec": 238.0, + "prev_percentile_duration_minutes": 12.09, + "prev_shard_count": 20, + "simulated_max_shard_duration": 15.0, + "test_overhead_min": 3.3666666666666667, "try_builder": "win-rel" }, - "shards": 20 + "shards": 15 }, "pixel_browser_tests": { "debug": {
diff --git a/infra/config/targets/cros-skylab-variants.json b/infra/config/targets/cros-skylab-variants.json deleted file mode 100644 index 2858327..0000000 --- a/infra/config/targets/cros-skylab-variants.json +++ /dev/null
@@ -1,64 +0,0 @@ -{ - "CROS_RELEASE_LKGM": { - "skylab": { - "use_lkgm": true - }, - "identifier": "RELEASE_LKGM" - }, - "CROS_PUBLIC_LKGM": { - "skylab": { - "use_lkgm": true, - "bucket": "chromiumos-image-archive", - "public_builder": "cros_test_platform_public", - "public_builder_bucket": "testplatform-public" - }, - "identifier": "PUBLIC_LKGM" - }, - "CROS_JACUZZI_RELEASE_LKGM": { - "skylab": { - "cros_board": "jacuzzi", - "use_lkgm": true - }, - "enabled": true, - "identifier": "JACUZZI_RELEASE_LKGM" - }, - "CROS_VOLTEER_PUBLIC_RELEASE_ASH_LKGM": { - "skylab": { - "cros_board": "volteer", - "cros_model": "voxel", - "bucket": "chromiumos-image-archive", - "dut_pool": "chromium", - "public_builder": "cros_test_platform_public", - "public_builder_bucket": "testplatform-public", - "use_lkgm": true - }, - "identifier": "VOLTEER_PUBLIC_RELEASE_LKGM" - }, - "CROS_GPU_BRYA_RELEASE_LKGM": { - "skylab": { - "cros_board": "brya", - "dut_pool": "chrome-gpu", - "use_lkgm": true - }, - "enabled": true, - "identifier": "GPU_BRYA_RELEASE_LKGM" - }, - "CROS_GPU_CORSOLA_RELEASE_LKGM": { - "skylab": { - "cros_board": "corsola", - "dut_pool": "chrome-gpu", - "use_lkgm": true - }, - "enabled": true, - "identifier": "GPU_CORSOLA_RELEASE_LKGM" - }, - "CROS_GPU_SKYRIM_RELEASE_LKGM": { - "skylab": { - "cros_board": "skyrim", - "dut_pool": "chrome-gpu", - "use_lkgm": true - }, - "enabled": true, - "identifier": "GPU_SKYRIM_RELEASE_LKGM" - } -}
diff --git a/infra/config/targets/mixins.star b/infra/config/targets/mixins.star index 69db61f..369953d 100644 --- a/infra/config/targets/mixins.star +++ b/infra/config/targets/mixins.star
@@ -737,7 +737,7 @@ name = "fuchsia-large-device-spec", generate_pyl_entry = False, args = [ - "--device-spec=virtual_device_large", + "--device-spec=x64-emu-large", ], )
diff --git a/infra/config/targets/variants.star b/infra/config/targets/variants.star index 4b0ab2a..b4a3501e 100644 --- a/infra/config/targets/variants.star +++ b/infra/config/targets/variants.star
@@ -37,6 +37,78 @@ ) targets.variant( + name = "CROS_RELEASE_LKGM", + identifier = "RELEASE_LKGM", + skylab = targets.skylab( + use_lkgm = True, + ), +) + +targets.variant( + name = "CROS_PUBLIC_LKGM", + identifier = "PUBLIC_LKGM", + skylab = targets.skylab( + bucket = "chromiumos-image-archive", + public_builder = "cros_test_platform_public", + public_builder_bucket = "testplatform-public", + use_lkgm = True, + ), +) + +targets.variant( + name = "CROS_JACUZZI_RELEASE_LKGM", + identifier = "JACUZZI_RELEASE_LKGM", + skylab = targets.skylab( + cros_board = "jacuzzi", + use_lkgm = True, + ), +) + +targets.variant( + name = "CROS_VOLTEER_PUBLIC_RELEASE_ASH_LKGM", + identifier = "VOLTEER_PUBLIC_RELEASE_LKGM", + skylab = targets.skylab( + bucket = "chromiumos-image-archive", + cros_board = "volteer", + cros_model = "voxel", + dut_pool = "chromium", + public_builder = "cros_test_platform_public", + public_builder_bucket = "testplatform-public", + use_lkgm = True, + ), +) + +targets.variant( + name = "CROS_GPU_BRYA_RELEASE_LKGM", + identifier = "GPU_BRYA_RELEASE_LKGM", + skylab = targets.skylab( + cros_board = "brya", + dut_pool = "chrome-gpu", + use_lkgm = True, + ), +) + +targets.variant( + name = "CROS_GPU_CORSOLA_RELEASE_LKGM", + identifier = "GPU_CORSOLA_RELEASE_LKGM", + skylab = targets.skylab( + cros_board = "corsola", + dut_pool = "chrome-gpu", + use_lkgm = True, + ), +) + +targets.variant( + name = "CROS_GPU_SKYRIM_RELEASE_LKGM", + identifier = "GPU_SKYRIM_RELEASE_LKGM", + skylab = targets.skylab( + cros_board = "skyrim", + dut_pool = "chrome-gpu", + use_lkgm = True, + ), +) + +targets.variant( name = "DISABLE_FIELD_TRIAL_CONFIG", identifier = "Disable Field Trial Config", generate_pyl_entry = False, @@ -766,22 +838,6 @@ ], ) -# This set of variants is encoded in a json file so that -# chrome/official.infra/lacros-skylab-tests-cros-img-roller can update the -# variant definitions -[targets.variant( - name = name, - enabled = variant.get("enabled"), - identifier = variant["identifier"], - # The cros_chrome_version field isn't used by the generator: it's used by - # the cros skylab test image roller to compare against other data sources - skylab = targets.skylab(**{ - k: v - for k, v in variant["skylab"].items() - if k != "cros_chrome_version" - }), -) for name, variant in json.decode(io.read_file("./cros-skylab-variants.json")).items()] - targets.variant( name = "WIN10_INTEL_UHD_630_STABLE", identifier = "8086:9bc5",
diff --git a/internal b/internal index 5dc66d6..c9e37b1 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit 5dc66d651f301de4c5700ffc5e692a63b1435056 +Subproject commit c9e37b18db937312ecc32ef93d2b370258c2035b
diff --git a/ios/chrome/app/BUILD.gn b/ios/chrome/app/BUILD.gn index 7a20cefb..6615926 100644 --- a/ios/chrome/app/BUILD.gn +++ b/ios/chrome/app/BUILD.gn
@@ -431,6 +431,7 @@ "//ios/chrome/browser/accessibility/model", "//ios/chrome/browser/appearance/ui_bundled", "//ios/chrome/browser/authentication/ui_bundled", + "//ios/chrome/browser/banner_promo/model", "//ios/chrome/browser/bookmarks/model", "//ios/chrome/browser/browsing_data/model", "//ios/chrome/browser/commerce/model/push_notification",
diff --git a/ios/chrome/app/main_controller.mm b/ios/chrome/app/main_controller.mm index 9c51d32..993b455 100644 --- a/ios/chrome/app/main_controller.mm +++ b/ios/chrome/app/main_controller.mm
@@ -71,6 +71,7 @@ #import "ios/chrome/app/variations_app_state_agent.h" #import "ios/chrome/browser/accessibility/model/window_accessibility_change_notifier_app_agent.h" #import "ios/chrome/browser/appearance/ui_bundled/appearance_customization.h" +#import "ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.h" #import "ios/chrome/browser/browsing_data/model/sessions_storage_util.h" #import "ios/chrome/browser/content_settings/model/host_content_settings_map_factory.h" #import "ios/chrome/browser/crash_report/model/crash_helper.h" @@ -929,6 +930,7 @@ #if BUILDFLAG(IOS_CREDENTIAL_PROVIDER_ENABLED) [self.appState addAgent:[[CredentialProviderMigratorAppAgent alloc] init]]; #endif + [self.appState addAgent:[[DefaultBrowserBannerPromoAppAgent alloc] init]]; } #pragma mark - ProfileStateObserver
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 318f4141..e9bcb4a 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -3801,6 +3801,23 @@ <message name="IDS_IOS_PASSWORD_SETTINGS_CREDENTIAL_DELETION_TEXT" desc="Section title in password settings, explaining to the user what data will be deleted. [iOS Only]"> Passwords, passkeys, and other data will be permanently deleted from Google Password Manager </message> + <message name="IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_TITLE" desc="Title of the confirmation alert when the user tap delete all data button. [iOS only]"> + You're about to delete your Google Password Manager data + </message> + <message name="IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_DESCRIPTION" desc="Description of the confirmation alert when the user tap delete all data button. [iOS only]"> + {password, plural, + =0 {{passkey, plural, + =1 {If you continue, your 1 passkey and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.} + other {If you continue, your {passkey} passkeys and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.}}} + =1 {{passkey, plural, + =0 {If you continue, your 1 password and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.} + =1 {If you continue, your 1 password, 1 passkey, and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.} + other {If you continue, your 1 password, {passkeys} passkeys, and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.}}} + other {{passkey, plural, + =0 {If you continue, your {password} passwords and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.} + =1 {If you continue, your {password} passwords, 1 passkey, and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.} + other {If you continue, your {password} passwords, {passkey} passkeys, and other data will be permanently deleted from Google Password Manager. Any accounts you created for sites or apps won't be deleted.}}}} + </message> <message name="IDS_IOS_PASSWORD_SETTINGS_PASSWORD_PLACEHOLDER_TEXT" desc="Placeholder text for the password field when adding a new credential manually via settings [Length: 10em]"> password </message> @@ -4963,7 +4980,7 @@ </message> <message name="IDS_IOS_SETTINGS_AUTOFILL_MIGRATE_ADDRESS_TO_ACCOUNT_CONFIRMATION_TEXT" desc="Text shown to the user after the migration of address from local to account was succesfull [iOS only]"> Address moved to your account <ph name="USER_EMAIL">$1<ex>janedoe@google.com</ex></ph> - </message> + </message> <message name="IDS_IOS_SETTINGS_DOWNLOADS_ACCOUNT_SELECTION_HEADER" desc="Header of Google Photos account selection section in Downloads settings. The section contains the list of accounts on the device among which the user can choose to save images to Google Photos. [iOS only]"> Accounts on this device </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_DESCRIPTION.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_DESCRIPTION.png.sha1 new file mode 100644 index 0000000..420c683 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_DESCRIPTION.png.sha1
@@ -0,0 +1 @@ +b1fa4818b5e1fa973c0a368ecc1b10d3ca7b4387 \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_TITLE.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_TITLE.png.sha1 new file mode 100644 index 0000000..f4730a299 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_TITLE.png.sha1
@@ -0,0 +1 @@ +80ecb42e806b06a571f9e097d44f238f45ba491a \ No newline at end of file
diff --git a/ios/chrome/browser/autofill/model/form_suggestion_controller.mm b/ios/chrome/browser/autofill/model/form_suggestion_controller.mm index e0504ba7..695823b8 100644 --- a/ios/chrome/browser/autofill/model/form_suggestion_controller.mm +++ b/ios/chrome/browser/autofill/model/form_suggestion_controller.mm
@@ -257,7 +257,8 @@ fieldType:base::SysUTF8ToNSString(params.field_type) type:base::SysUTF8ToNSString(params.type) typedValue:base::SysUTF8ToNSString(params.value) - frameID:base::SysUTF8ToNSString(params.frame_id)]; + frameID:base::SysUTF8ToNSString(params.frame_id) + onlyPassword:NO]; BOOL hasUserGesture = params.has_user_gesture;
diff --git a/ios/chrome/browser/banner_promo/OWNERS b/ios/chrome/browser/banner_promo/OWNERS new file mode 100644 index 0000000..87e5b52 --- /dev/null +++ b/ios/chrome/browser/banner_promo/OWNERS
@@ -0,0 +1,2 @@ +rkgibson@google.com +gujen@google.com
diff --git a/ios/chrome/browser/banner_promo/model/BUILD.gn b/ios/chrome/browser/banner_promo/model/BUILD.gn new file mode 100644 index 0000000..f199522 --- /dev/null +++ b/ios/chrome/browser/banner_promo/model/BUILD.gn
@@ -0,0 +1,19 @@ +# Copyright 2024 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +source_set("model") { + sources = [ + "default_browser_banner_promo_app_agent.h", + "default_browser_banner_promo_app_agent.mm", + ] + deps = [ + "//base", + "//ios/chrome/app/application_delegate:observing_app_state_agent", + "//ios/chrome/app/profile", + "//ios/chrome/browser/shared/model/browser", + "//ios/chrome/browser/shared/model/web_state_list", + "//ios/chrome/browser/shared/public/features", + "//ios/web/public", + ] +}
diff --git a/ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.h b/ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.h new file mode 100644 index 0000000..845695e --- /dev/null +++ b/ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.h
@@ -0,0 +1,16 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_BANNER_PROMO_MODEL_DEFAULT_BROWSER_BANNER_PROMO_APP_AGENT_H_ +#define IOS_CHROME_BROWSER_BANNER_PROMO_MODEL_DEFAULT_BROWSER_BANNER_PROMO_APP_AGENT_H_ + +#import "ios/chrome/app/application_delegate/observing_app_state_agent.h" + +// App agent to manage the Default Browser Banner Promo. It observes navigation +// events in all active web states to determine when to show and hide the promo. +@interface DefaultBrowserBannerPromoAppAgent : SceneObservingAppAgent + +@end + +#endif // IOS_CHROME_BROWSER_BANNER_PROMO_MODEL_DEFAULT_BROWSER_BANNER_PROMO_APP_AGENT_H_
diff --git a/ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.mm b/ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.mm new file mode 100644 index 0000000..1c1eb91 --- /dev/null +++ b/ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.mm
@@ -0,0 +1,148 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "ios/chrome/browser/banner_promo/model/default_browser_banner_promo_app_agent.h" + +#import "ios/chrome/app/profile/profile_init_stage.h" +#import "ios/chrome/app/profile/profile_state.h" +#import "ios/chrome/app/profile/profile_state_observer.h" +#import "ios/chrome/browser/shared/model/browser/browser.h" +#import "ios/chrome/browser/shared/model/browser/browser_list.h" +#import "ios/chrome/browser/shared/model/browser/browser_list_factory.h" +#import "ios/chrome/browser/shared/model/browser/browser_list_observer_bridge.h" +#import "ios/chrome/browser/shared/model/web_state_list/active_web_state_observation_forwarder.h" +#import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" +#import "ios/chrome/browser/shared/model/web_state_list/web_state_list_observer_bridge.h" +#import "ios/chrome/browser/shared/public/features/features.h" +#import "ios/web/public/web_state.h" +#import "ios/web/public/web_state_observer_bridge.h" + +@interface DefaultBrowserBannerPromoAppAgent () <BrowserListObserver, + CRWWebStateObserver, + ProfileStateObserver, + WebStateListObserving> + +@end + +@implementation DefaultBrowserBannerPromoAppAgent { + // Observer bridge for observing browser lists. + std::unique_ptr<BrowserListObserverBridge> _browserListObserverBridge; + + // Observer bridge for observing web state lists. + std::unique_ptr<WebStateListObserverBridge> _webStateListObserverBridge; + + // Observer bridge for observing web states. + std::unique_ptr<web::WebStateObserverBridge> _webStateObserverBridge; + + // Forwarder for +} + +- (instancetype)init { + self = [super init]; + if (self) { + _browserListObserverBridge = + std::make_unique<BrowserListObserverBridge>(self); + _webStateListObserverBridge = + std::make_unique<WebStateListObserverBridge>(self); + _webStateObserverBridge = + std::make_unique<web::WebStateObserverBridge>(self); + } + return self; +} + +#pragma mark - SceneStateObserver + +- (void)sceneState:(SceneState*)sceneState + profileStateConnected:(ProfileState*)profileState { + if (!IsDefaultBrowserBannerPromoEnabled()) { + return; + } + [profileState addObserver:self]; +} + +#pragma mark - ProfileStateObserver + +- (void)profileState:(ProfileState*)profileState + didTransitionToInitStage:(ProfileInitStage)nextInitStage + fromInitStage:(ProfileInitStage)fromInitStage { + if (nextInitStage != ProfileInitStage::kFinal) { + return; + } + + BrowserList* browserList = + BrowserListFactory::GetForProfile(profileState.profile); + + browserList->AddObserver(_browserListObserverBridge.get()); + + // Make sure that already-existing browsers get handled. + for (Browser* browser : + browserList->BrowsersOfType(BrowserList::BrowserType::kRegular)) { + [self browserList:browserList browserAdded:browser]; + } +} + +#pragma mark - BrowserListObserver + +- (void)browserList:(const BrowserList*)browserList + browserAdded:(Browser*)browser { + // Only observe web states in regular browsers. + if (browser->type() != Browser::Type::kRegular) { + return; + } + + WebStateList* webStateList = browser->GetWebStateList(); + webStateList->AddObserver(_webStateListObserverBridge.get()); + + web::WebState* webState = webStateList->GetActiveWebState(); + if (webState) { + webState->AddObserver(_webStateObserverBridge.get()); + } +} + +- (void)browserList:(const BrowserList*)browserList + browserRemoved:(Browser*)browser { + WebStateList* webStateList = browser->GetWebStateList(); + webStateList->RemoveObserver(_webStateListObserverBridge.get()); + + web::WebState* webState = webStateList->GetActiveWebState(); + if (webState) { + webState->RemoveObserver(_webStateObserverBridge.get()); + } +} + +- (void)browserListWillShutdown:(BrowserList*)browserList { + // Make sure that already-existing browsers are cleaned up as well. + for (Browser* browser : + browserList->BrowsersOfType(BrowserList::BrowserType::kRegular)) { + [self browserList:browserList browserRemoved:browser]; + } + + browserList->RemoveObserver(_browserListObserverBridge.get()); +} + +#pragma mark - WebStateListObserving + +- (void)didChangeWebStateList:(WebStateList*)webStateList + change:(const WebStateListChange&)change + status:(const WebStateListStatus&)status { + if (!status.active_web_state_change()) { + return; + } + + if (status.old_active_web_state) { + status.old_active_web_state->RemoveObserver(_webStateObserverBridge.get()); + } + if (status.new_active_web_state) { + status.new_active_web_state->AddObserver(_webStateObserverBridge.get()); + } +} + +#pragma mark - CRWWebStateObserver + +- (void)webState:(web::WebState*)webState + didStartNavigation:(web::NavigationContext*)navigationContext { + // TODO(crbug.com/374119252): Handle navigation. +} + +@end
diff --git a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm index f651004..8e8f1c3 100644 --- a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm +++ b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate.mm
@@ -18,6 +18,7 @@ #import "ios/chrome/browser/saved_tab_groups/model/ios_tab_group_action_context.h" #import "ios/chrome/browser/saved_tab_groups/model/ios_tab_group_sync_util.h" #import "ios/chrome/browser/saved_tab_groups/model/tab_group_sync_service_factory.h" +#import "ios/chrome/browser/share_kit/model/share_kit_flow_outcome.h" #import "ios/chrome/browser/share_kit/model/share_kit_join_configuration.h" #import "ios/chrome/browser/share_kit/model/share_kit_manage_configuration.h" #import "ios/chrome/browser/share_kit/model/share_kit_service.h" @@ -36,6 +37,23 @@ namespace collaboration { +namespace { + +// Converts `outcome` between the two enums. +CollaborationControllerDelegate::Outcome ConvertOutcome( + ShareKitFlowOutcome outcome) { + switch (outcome) { + case ShareKitFlowOutcome::kSuccess: + return CollaborationControllerDelegate::Outcome::kSuccess; + case ShareKitFlowOutcome::kFailure: + return CollaborationControllerDelegate::Outcome::kFailure; + case ShareKitFlowOutcome::kCancel: + return CollaborationControllerDelegate::Outcome::kCancel; + } +} + +} // namespace + IOSCollaborationControllerDelegate::IOSCollaborationControllerDelegate( Browser* browser, UIViewController* base_view_controller) @@ -141,6 +159,9 @@ : CollaborationControllerDelegate::Outcome::kFailure; completion_block(outcome); }; + config.completion = ^(ShareKitFlowOutcome outcome) { + completion_block(ConvertOutcome(outcome)); + }; session_id_ = share_kit_service_->JoinTabGroup(config); } @@ -191,6 +212,9 @@ : CollaborationControllerDelegate::Outcome::kFailure; completion_block(outcome); }; + config.completion = ^(ShareKitFlowOutcome outcome) { + completion_block(ConvertOutcome(outcome)); + }; session_id_ = share_kit_service_->ShareTabGroup(config); } @@ -222,7 +246,11 @@ : CollaborationControllerDelegate::Outcome::kFailure; completion_block(outcome); }; - share_kit_service_->ManageTabGroup(config); + config.completion = ^(ShareKitFlowOutcome outcome) { + completion_block(ConvertOutcome(outcome)); + }; + + session_id_ = share_kit_service_->ManageTabGroup(config); } void IOSCollaborationControllerDelegate::PromoteTabGroup(
diff --git a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm index 30a89fc..044441b 100644 --- a/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm +++ b/ios/chrome/browser/collaboration/model/ios_collaboration_controller_delegate_unittest.mm
@@ -16,6 +16,7 @@ #import "components/sync/test/test_sync_service.h" #import "ios/chrome/browser/data_sharing/model/data_sharing_service_factory.h" #import "ios/chrome/browser/saved_tab_groups/model/tab_group_sync_service_factory.h" +#import "ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.h" #import "ios/chrome/browser/share_kit/model/share_kit_service_factory.h" #import "ios/chrome/browser/share_kit/model/test_share_kit_service.h" #import "ios/chrome/browser/shared/model/application_context/application_context.h" @@ -169,6 +170,26 @@ PlatformTest::TearDown(); } + // Returns a FakeShareKitFlowViewController if it is what is presented by + // `base_view_controller`. Returns nil otherwise. + FakeShareKitFlowViewController* ShareKitFlowFromBaseViewController( + UIViewController* base_view_controller) { + UIViewController* presented_view_controller = + base_view_controller.presentedViewController; + if (![presented_view_controller + isKindOfClass:UINavigationController.class]) { + return nil; + } + UINavigationController* navigation_controller = + reinterpret_cast<UINavigationController*>(presented_view_controller); + if (![[navigation_controller topViewController] + isKindOfClass:FakeShareKitFlowViewController.class]) { + return nil; + } + return reinterpret_cast<FakeShareKitFlowViewController*>( + [navigation_controller topViewController]); + } + web::WebTaskEnvironment task_environment_; IOSChromeScopedTestingLocalState scoped_testing_local_state_; base::test::ScopedFeatureList scoped_feature_list_; @@ -187,13 +208,17 @@ TEST_F(IOSCollaborationControllerDelegateTest, ShowShareDialogValid) { InitDelegate(); base::MockCallback<CollaborationControllerDelegate::ResultCallback> - completion_callback; - delegate_->ShowShareDialog(tab_group_->tab_group_id(), - completion_callback.Get()); - EXPECT_TRUE(base_view_controller_.presentedViewController); - // The callback is not expected to be called, as it is called when the - // given ShareKit flow returns, i.e. when the presented view controller is - // dismissed. Here, it's not dismissed. + mock_callback; + EXPECT_CALL(mock_callback, + Run(CollaborationControllerDelegate::Outcome::kSuccess)); + + delegate_->ShowShareDialog(tab_group_->tab_group_id(), mock_callback.Get()); + + FakeShareKitFlowViewController* share_kit_flow_view_controller = + ShareKitFlowFromBaseViewController(base_view_controller_); + EXPECT_TRUE(share_kit_flow_view_controller); + + [share_kit_flow_view_controller accept]; } // Tests `ShowShareDialog` with an invalid tabGroup. @@ -206,31 +231,92 @@ web_state_list_->DeleteGroup(tab_group_); base::MockCallback<CollaborationControllerDelegate::ResultCallback> - completion_callback; - EXPECT_CALL(completion_callback, + mock_callback; + EXPECT_CALL(mock_callback, Run(CollaborationControllerDelegate::Outcome::kFailure)); - delegate_->ShowShareDialog(tab_group_id, completion_callback.Get()); + delegate_->ShowShareDialog(tab_group_id, mock_callback.Get()); EXPECT_FALSE(base_view_controller_.presentedViewController); } -// Tests `ShowJoinDialog`. -TEST_F(IOSCollaborationControllerDelegateTest, ShowJoinDialog) { +// Tests `ShowJoinDialog` and accept. +TEST_F(IOSCollaborationControllerDelegateTest, ShowJoinDialogAccept) { InitDelegate(); base::MockCallback<CollaborationControllerDelegate::ResultCallback> - completion_callback; + mock_callback; + EXPECT_CALL(mock_callback, + Run(CollaborationControllerDelegate::Outcome::kSuccess)); + data_sharing::SharedDataPreview preview_data; delegate_->ShowJoinDialog(data_sharing::GroupToken(), preview_data, - completion_callback.Get()); - EXPECT_TRUE(base_view_controller_.presentedViewController); - // The callback is not expected to be called, as it is called when the - // given ShareKit flow returns, i.e. when the presented view controller is - // dismissed. Here, it's not dismissed. + mock_callback.Get()); + + FakeShareKitFlowViewController* share_kit_flow_view_controller = + ShareKitFlowFromBaseViewController(base_view_controller_); + EXPECT_TRUE(share_kit_flow_view_controller); + + [share_kit_flow_view_controller accept]; } -// Tests `ShowAuthenticationUi` from a share flow when the user chooses to -// cancel the sign in. +// Tests `ShowJoinDialog` and cancel. +TEST_F(IOSCollaborationControllerDelegateTest, ShowJoinDialogCancel) { + InitDelegate(); + base::MockCallback<CollaborationControllerDelegate::ResultCallback> + mock_callback; + EXPECT_CALL(mock_callback, + Run(CollaborationControllerDelegate::Outcome::kCancel)); + + data_sharing::SharedDataPreview preview_data; + delegate_->ShowJoinDialog(data_sharing::GroupToken(), preview_data, + mock_callback.Get()); + + FakeShareKitFlowViewController* share_kit_flow_view_controller = + ShareKitFlowFromBaseViewController(base_view_controller_); + EXPECT_TRUE(share_kit_flow_view_controller); + + [share_kit_flow_view_controller cancel]; +} + +// Tests `ShowManageDialog` and accept. +TEST_F(IOSCollaborationControllerDelegateTest, ShowManageDialogAccept) { + InitDelegate(); + base::MockCallback<CollaborationControllerDelegate::ResultCallback> + mock_callback; + EXPECT_CALL(mock_callback, + Run(CollaborationControllerDelegate::Outcome::kSuccess)); + + data_sharing::SharedDataPreview preview_data; + delegate_->ShowJoinDialog(data_sharing::GroupToken(), preview_data, + mock_callback.Get()); + + FakeShareKitFlowViewController* share_kit_flow_view_controller = + ShareKitFlowFromBaseViewController(base_view_controller_); + EXPECT_TRUE(share_kit_flow_view_controller); + + [share_kit_flow_view_controller accept]; +} + +// Tests `ShowManageDialog` and cancel. +TEST_F(IOSCollaborationControllerDelegateTest, ShowManageDialogCancel) { + InitDelegate(); + base::MockCallback<CollaborationControllerDelegate::ResultCallback> + mock_callback; + EXPECT_CALL(mock_callback, + Run(CollaborationControllerDelegate::Outcome::kCancel)); + + data_sharing::SharedDataPreview preview_data; + delegate_->ShowJoinDialog(data_sharing::GroupToken(), preview_data, + mock_callback.Get()); + + FakeShareKitFlowViewController* share_kit_flow_view_controller = + ShareKitFlowFromBaseViewController(base_view_controller_); + EXPECT_TRUE(share_kit_flow_view_controller); + + [share_kit_flow_view_controller cancel]; +} + +// Tests `ShowAuthenticationUi` when the user chooses to cancel the sign in. TEST_F(IOSCollaborationControllerDelegateTest, - ShowAuthenticationUiShareFlowSignInCanceled) { + ShowAuthenticationUiSignInCanceled) { InitDelegate(); base::MockCallback<CollaborationControllerDelegate::ResultCallback> mock_callback; @@ -250,10 +336,10 @@ delegate_->ShowAuthenticationUi(mock_callback.Get()); } -// Tests `ShowAuthenticationUi` from a share flow when the user sign in and -// accept the sync opt in. +// Tests `ShowAuthenticationUi` when the user sign in and accept the sync opt +// in. TEST_F(IOSCollaborationControllerDelegateTest, - ShowAuthenticationUiShareFlowSyncAccepted) { + ShowAuthenticationUiSyncAccepted) { InitDelegate(); base::MockCallback<CollaborationControllerDelegate::ResultCallback> mock_callback; @@ -275,10 +361,8 @@ delegate_->ShowAuthenticationUi(mock_callback.Get()); } -// Tests `ShowAuthenticationUi` from a share flow when the user sign in but -// don't sync. -TEST_F(IOSCollaborationControllerDelegateTest, - ShowAuthenticationUiShareFlowSyncDenied) { +// Tests `ShowAuthenticationUi` when the user sign in but don't sync. +TEST_F(IOSCollaborationControllerDelegateTest, ShowAuthenticationUiSyncDenied) { InitDelegate(); base::MockCallback<CollaborationControllerDelegate::ResultCallback> mock_callback; @@ -300,36 +384,29 @@ delegate_->ShowAuthenticationUi(mock_callback.Get()); } -// Tests `ShowAuthenticationUi` from a join flow. -TEST_F(IOSCollaborationControllerDelegateTest, ShowAuthenticationUiJoinFlow) { - InitDelegate(); - base::MockCallback<CollaborationControllerDelegate::ResultCallback> - completion_callback; - OCMExpect([application_commands_mock_ - showSignin:[OCMArg checkWithBlock:^BOOL( - ShowSigninCommand* command) { - return command.operation == - AuthenticationOperation::kSheetSigninAndHistorySync; - }] - baseViewController:base_view_controller_]); - delegate_->ShowAuthenticationUi(completion_callback.Get()); -} - -// Tests `ShowAuthenticationUi` from a join flow when being SignedIn only. -TEST_F(IOSCollaborationControllerDelegateTest, - ShowAuthenticationUiSyncJoinFlow) { +// Tests `ShowAuthenticationUi` when the user is SignedIn but not syncing. +TEST_F(IOSCollaborationControllerDelegateTest, ShowAuthenticationUiWithSignIn) { SignIn(); InitDelegate(); base::MockCallback<CollaborationControllerDelegate::ResultCallback> - completion_callback; + mock_callback; + + EXPECT_CALL(mock_callback, + Run(CollaborationControllerDelegate::Outcome::kSuccess)); + OCMExpect([application_commands_mock_ showSignin:[OCMArg checkWithBlock:^BOOL(ShowSigninCommand* command) { + AcceptSyncOptIn(); + command.completion( + SigninCoordinatorResultSuccess, + [FakeSystemIdentity fakeIdentity1]); return command.operation == AuthenticationOperation::kHistorySync; }] baseViewController:base_view_controller_]); - delegate_->ShowAuthenticationUi(completion_callback.Get()); + + delegate_->ShowAuthenticationUi(mock_callback.Get()); } // Tests `NotifySignInAndSyncStatusChange`.
diff --git a/ios/chrome/browser/flags/about_flags.mm b/ios/chrome/browser/flags/about_flags.mm index 901a3c1..08b5bc1 100644 --- a/ios/chrome/browser/flags/about_flags.mm +++ b/ios/chrome/browser/flags/about_flags.mm
@@ -2286,6 +2286,11 @@ FEATURE_WITH_PARAMS_VALUE_TYPE(first_run::kUpdatedFirstRunSequence, kUpdatedFirstRunSequenceVariations, "UpdatedFirstRunSequence")}, + {"set-up-list-without-sign-in-item", + flag_descriptions::kSetUpListWithoutSignInItemName, + flag_descriptions::kSetUpListWithoutSignInItemDescription, + flags_ui::kOsIos, + FEATURE_VALUE_TYPE(set_up_list::kSetUpListWithoutSignInItem)}, }; 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 ab9f55fb..1114afa 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.cc
@@ -1120,6 +1120,11 @@ const char kSetUpListShortenedDurationDescription[] = "Reduces the Set Up List duration in the NTP to the selected parameter."; +const char kSetUpListWithoutSignInItemName[] = + "Set Up List without sign-in item"; +const char kSetUpListWithoutSignInItemDescription[] = + "Removes the sign-in item from the Set Up List."; + const char kShareInWebContextMenuIOSName[] = "Share in web context menu"; const char kShareInWebContextMenuIOSDescription[] = "Enables the Share button in the web context menu in iOS 16.0 and above.";
diff --git a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h index 7ace6f7c..b199619 100644 --- a/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h +++ b/ios/chrome/browser/flags/ios_chrome_flag_descriptions.h
@@ -994,6 +994,11 @@ extern const char kSetUpListShortenedDurationName[]; extern const char kSetUpListShortenedDurationDescription[]; +// Title and description for the flag to remove the sign-in item from the Set Up +// List. +extern const char kSetUpListWithoutSignInItemName[]; +extern const char kSetUpListWithoutSignInItemDescription[]; + // Title and description for the flag to enable the Share button // in the web context menu in iOS. extern const char kShareInWebContextMenuIOSName[];
diff --git a/ios/chrome/browser/ntp/model/features.h b/ios/chrome/browser/ntp/model/features.h index 301d8ce..fe7e5d5 100644 --- a/ios/chrome/browser/ntp/model/features.h +++ b/ios/chrome/browser/ntp/model/features.h
@@ -24,6 +24,9 @@ // Feature to adjust the Set Up List duration. BASE_DECLARE_FEATURE(kSetUpListShortenedDuration); +// Feature to remove the sign-in item in the Set Up List. +BASE_DECLARE_FEATURE(kSetUpListWithoutSignInItem); + // Name of the param that indicates which variation of the kSetUpListInFirstRun // is enabled. The Set Up List items shown depend on the variation. extern const char kSetUpListInFirstRunParam[];
diff --git a/ios/chrome/browser/ntp/model/features.mm b/ios/chrome/browser/ntp/model/features.mm index f7129bc..b5abd45c2 100644 --- a/ios/chrome/browser/ntp/model/features.mm +++ b/ios/chrome/browser/ntp/model/features.mm
@@ -16,6 +16,10 @@ "SetUpListShortenedDuration", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kSetUpListWithoutSignInItem, + "SetUpListWithoutSignInItem", + base::FEATURE_DISABLED_BY_DEFAULT); + const char kSetUpListInFirstRunParam[] = "SetUpListInFirstRunParam"; const char kSetUpListDurationParam[] = "SetUpListDurationParam";
diff --git a/ios/chrome/browser/ntp/model/set_up_list.mm b/ios/chrome/browser/ntp/model/set_up_list.mm index b3451e3c..be2b2ce 100644 --- a/ios/chrome/browser/ntp/model/set_up_list.mm +++ b/ios/chrome/browser/ntp/model/set_up_list.mm
@@ -6,6 +6,7 @@ #import <vector> +#import "base/feature_list.h" #import "base/memory/raw_ptr.h" #import "base/strings/sys_string_conversions.h" #import "components/password_manager/core/browser/password_manager_util.h" @@ -162,7 +163,9 @@ if (IsSigninEnabled(auth_service) && !sync_service->HasDisableReason( syncer::SyncService::DISABLE_REASON_ENTERPRISE_POLICY) && - !HasManagedSyncDataType(sync_service)) { + !HasManagedSyncDataType(sync_service) && + !base::FeatureList::IsEnabled( + set_up_list::kSetUpListWithoutSignInItem)) { items.push_back(SetUpListItemType::kSignInSync); } @@ -300,7 +303,10 @@ switch (set_up_list::GetSetUpListInFirstRunVariation()) { case set_up_list::FirstRunVariationType::kDisabled: - [itemTypes addObject:@(int(SetUpListItemType::kSignInSync))]; + if (!base::FeatureList::IsEnabled( + set_up_list::kSetUpListWithoutSignInItem)) { + [itemTypes addObject:@(int(SetUpListItemType::kSignInSync))]; + } if (_shouldIncludeNotificationItem) { [itemTypes addObject:@(int(SetUpListItemType::kNotifications))]; }
diff --git a/ios/chrome/browser/ntp/ui_bundled/new_tab_page_view_controller.mm b/ios/chrome/browser/ntp/ui_bundled/new_tab_page_view_controller.mm index aa399f4..9955df7e 100644 --- a/ios/chrome/browser/ntp/ui_bundled/new_tab_page_view_controller.mm +++ b/ios/chrome/browser/ntp/ui_bundled/new_tab_page_view_controller.mm
@@ -388,7 +388,7 @@ if (self.feedVisible) { [self updateFeedInsetsForMinimumHeight]; } - [self updateFeedContainerHeight]; + [self updateFeedContainerSizeAndPosition]; }]; } @@ -681,13 +681,6 @@ } - (void)feedLayoutDidEndUpdatesWithType:(FeedLayoutUpdateType)type { - if (_feedContainer) { - // Feed content gets added to the top of the subview array, so after content - // loads the feed container needs to be sent to the back so that it isn't - // in front of the new content and doesn't intercept taps / interactions - // that are meant for the feed content. - [self.collectionView sendSubviewToBack:_feedContainer]; - } [self updateFeedInsetsForMinimumHeight]; // Updating insets can influence contentOffset, so update saved scroll state // after it. This handles what the starting offset be with the feed enabled, @@ -700,7 +693,7 @@ [self setContentOffset:self.savedScrollOffset]; } - [self updateFeedContainerHeight]; + [self updateFeedContainerSizeAndPosition]; } - (void)invalidate { @@ -817,13 +810,7 @@ } [self updateScrollPositionToSave]; - - // The feed model callbacks don't always reliably tell us that the content has - // paginated, so check if the container should be extended. - if (self.collectionView.contentSize.height > - self.feedContainerHeightConstraint.constant) { - [self updateFeedContainerHeight]; - } + [self updateFeedContainerSizeAndPosition]; } - (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView { @@ -1464,7 +1451,7 @@ [_feedContainer.topAnchor constraintEqualToAnchor:self.feedHeaderViewController.view.topAnchor], ]]; - [self updateFeedContainerHeight]; + [self updateFeedContainerSizeAndPosition]; } [NSLayoutConstraint activateConstraints:@[ @@ -1594,8 +1581,8 @@ self.mutator.scrollPositionToSave = scrollPositionToSave; } -// Updates the feed container's height constraint. -- (void)updateFeedContainerHeight { +// Updates the feed container's height constraint and z-position. +- (void)updateFeedContainerSizeAndPosition { if (!_feedContainer) { return; } @@ -1611,6 +1598,12 @@ self.feedContainerHeightConstraint = [_feedContainer.heightAnchor constraintEqualToConstant:containerHeight]; self.feedContainerHeightConstraint.active = YES; + + // Feed content gets added to the top of the subview array, so after content + // loads the feed container needs to be sent to the back so that it isn't + // in front of the new content and doesn't intercept taps / interactions + // that are meant for the feed content. + [self.collectionView sendSubviewToBack:_feedContainer]; } // Updates the width constraint of `moduleLayoutGuide`.
diff --git a/ios/chrome/browser/passwords/model/password_controller_unittest.mm b/ios/chrome/browser/passwords/model/password_controller_unittest.mm index 7539b2b2..9138a49 100644 --- a/ios/chrome/browser/passwords/model/password_controller_unittest.mm +++ b/ios/chrome/browser/passwords/model/password_controller_unittest.mm
@@ -382,7 +382,8 @@ fieldType:@"not_important" type:@"input" typedValue:SysUTF8ToNSString(typed_value) - frameID:SysUTF8ToNSString(main_frame_id)]; + frameID:SysUTF8ToNSString(main_frame_id) + onlyPassword:NO]; [passwordController_.sharedPasswordController checkIfSuggestionsAvailableForForm:form_query hasUserGesture:YES @@ -581,7 +582,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:SysUTF8ToNSString(frame->GetFrameId())]; + frameID:SysUTF8ToNSString(frame->GetFrameId()) + onlyPassword:NO]; NSString* suggestion_text = [NSString stringWithFormat:@"%@ ••••••••", @@ -1503,7 +1505,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:SysUTF8ToNSString(GetMainWebFrameId())]; + frameID:SysUTF8ToNSString(GetMainWebFrameId()) + onlyPassword:NO]; [passwordController_.sharedPasswordController checkIfSuggestionsAvailableForForm:form_query hasUserGesture:YES @@ -1547,7 +1550,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:SysUTF8ToNSString(GetMainWebFrameId())]; + frameID:SysUTF8ToNSString(GetMainWebFrameId()) + onlyPassword:NO]; [passwordController_.sharedPasswordController checkIfSuggestionsAvailableForForm:form_query hasUserGesture:YES @@ -1581,7 +1585,8 @@ fieldType:@"text" type:@"focus" typedValue:@"" - frameID:SysUTF8ToNSString(GetMainWebFrameId())]; + frameID:SysUTF8ToNSString(GetMainWebFrameId()) + onlyPassword:NO]; [passwordController_.sharedPasswordController checkIfSuggestionsAvailableForForm:form_query hasUserGesture:YES @@ -2102,7 +2107,8 @@ fieldType:@"password" type:@"focus" typedValue:@"" - frameID:SysUTF8ToNSString(GetMainWebFrameId())]; + frameID:SysUTF8ToNSString(GetMainWebFrameId()) + onlyPassword:NO]; [passwordController_.sharedPasswordController checkIfSuggestionsAvailableForForm:focus_query hasUserGesture:YES @@ -2144,7 +2150,8 @@ fieldType:@"password" type:@"input" typedValue:@"generated_password_long" - frameID:SysUTF8ToNSString(GetMainWebFrameId())]; + frameID:SysUTF8ToNSString(GetMainWebFrameId()) + onlyPassword:NO]; [passwordController_.sharedPasswordController checkIfSuggestionsAvailableForForm:extend_query hasUserGesture:YES @@ -2186,7 +2193,8 @@ fieldType:@"password" type:@"input" typedValue:@"" - frameID:SysUTF8ToNSString(GetMainWebFrameId())]; + frameID:SysUTF8ToNSString(GetMainWebFrameId()) + onlyPassword:NO]; [passwordController_.sharedPasswordController checkIfSuggestionsAvailableForForm:clear_query hasUserGesture:YES
diff --git a/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm b/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm index 958532d..6e592bb 100644 --- a/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm +++ b/ios/chrome/browser/passwords/ui_bundled/bottom_sheet/password_suggestion_bottom_sheet_mediator.mm
@@ -67,7 +67,7 @@ } // Makes a query to retrieve suggestions from a FormSuggestionProvider from the -// provided `params`. +// provided `params`. Only ask for suggestions with passwords. FormSuggestionProviderQuery* MakeQueryFromParameters( const autofill::FormActivityParams& params) { return [[FormSuggestionProviderQuery alloc] @@ -78,7 +78,8 @@ fieldType:base::SysUTF8ToNSString(params.field_type) type:base::SysUTF8ToNSString(params.type) typedValue:base::SysUTF8ToNSString(params.value) - frameID:base::SysUTF8ToNSString(params.frame_id)]; + frameID:base::SysUTF8ToNSString(params.frame_id) + onlyPassword:YES]; } } // namespace
diff --git a/ios/chrome/browser/price_insights/model/price_insights_feature.mm b/ios/chrome/browser/price_insights/model/price_insights_feature.mm index 887052a..267cd3b 100644 --- a/ios/chrome/browser/price_insights/model/price_insights_feature.mm +++ b/ios/chrome/browser/price_insights/model/price_insights_feature.mm
@@ -6,6 +6,7 @@ #import "base/metrics/field_trial_params.h" #import "components/commerce/core/commerce_feature_list.h" +#import "components/commerce/core/feature_utils.h" #import "components/commerce/core/shopping_service.h" #import "components/variations/service/variations_service_utils.h" #import "ios/chrome/browser/commerce/model/shopping_service_factory.h" @@ -49,7 +50,7 @@ return false; } - return service->IsPriceInsightsEligible(); + return commerce::IsPriceInsightsEligible(service->GetAccountChecker()); } std::string GetLowPriceParamValue() {
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_coordinator.mm b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_coordinator.mm index 3eeb9a2..d9ce7008 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_coordinator.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_coordinator.mm
@@ -315,6 +315,46 @@ completion:nil]; } +- (void)startDeletionFlow { + CredentialCounts counts = [_mediator passwordAndPasskeyCounts]; + NSString* alertDescription = base::SysUTF16ToNSString( + base::i18n::MessageFormatter::FormatWithNamedArgs( + l10n_util::GetStringUTF16( + IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_DESCRIPTION), + "password", counts.passwordCounts, "passkey", counts.passkeyCounts)); + UIAlertController* deletionConfirmation = [UIAlertController + alertControllerWithTitle: + l10n_util::GetNSString( + IDS_IOS_PASSWORD_SETTINGS_DELETE_ALL_CREDENTIALS_TITLE) + message:alertDescription + preferredStyle:UIAlertControllerStyleActionSheet]; + + UIAlertAction* cancelAction = [UIAlertAction + actionWithTitle:l10n_util::GetNSString(IDS_IOS_CANCEL_PASSWORD_DELETION) + style:UIAlertActionStyleCancel + handler:nil]; + [deletionConfirmation addAction:cancelAction]; + + __weak __typeof(self) weakSelf = self; + UIAlertAction* deleteAction = [UIAlertAction + actionWithTitle:l10n_util::GetNSString(IDS_IOS_DELETE_ACTION_TITLE) + style:UIAlertActionStyleDestructive + handler:^(UIAlertAction* action) { + [weakSelf onStartDeletionFlowConfirmed]; + }]; + + [deletionConfirmation addAction:deleteAction]; + + deletionConfirmation.popoverPresentationController.sourceView = + [_passwordSettingsViewController sourceViewForAlerts]; + deletionConfirmation.popoverPresentationController.sourceRect = + [_passwordSettingsViewController sourceRectForCredentialDeletionAlerts]; + + [_passwordSettingsViewController presentViewController:deletionConfirmation + animated:YES + completion:nil]; +} + - (void)showManagedPrefInfoForSourceView:(UIButton*)sourceView { // EnterpriseInfoPopoverViewController automatically handles reenabling the // `sourceView`, so we don't need to add any dismiss handlers or delegation, @@ -760,6 +800,12 @@ completion:nil]; } +// Starts the deletion all credentials flow after the user confirmed the +// corresponding alerts. +- (void)onStartDeletionFlowConfirmed { + // TODO(crbug.com/383851476): implement this. +} + // Starts the export passwords flow after the user confirmed the corresponding // alert. - (void)onStartExportFlowConfirmed {
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.h b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.h index ed7df18..e1a54aae 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.h +++ b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.h
@@ -24,6 +24,11 @@ class PrefService; class TrustedVaultClientBackend; +struct CredentialCounts { + int passwordCounts; + int passkeyCounts; +}; + @protocol ReauthenticationProtocol; @protocol SystemIdentity; @@ -73,6 +78,9 @@ // Detaches observers. - (void)disconnect; +// Get the numbers of saved passwords and passkeys. +- (CredentialCounts)passwordAndPasskeyCounts; + @end #endif // IOS_CHROME_BROWSER_SETTINGS_UI_BUNDLED_PASSWORD_PASSWORD_SETTINGS_PASSWORD_SETTINGS_MEDIATOR_H_
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.mm b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.mm index e6e90f4a..051b42e 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_mediator.mm
@@ -244,6 +244,27 @@ _syncObserver.reset(); } +- (CredentialCounts)passwordAndPasskeyCounts { + int passwordsCount = 0; + int passkeysCount = 0; + for (CredentialUIEntry entry : + _savedPasswordsPresenter->GetSavedCredentials()) { + if (entry.blocked_by_user) { + continue; + } + if (entry.passkey_credential_id.empty()) { + passwordsCount++; + } else { + passkeysCount++; + } + } + struct CredentialCounts credentialCounts; + credentialCounts.passwordCounts = passwordsCount; + credentialCounts.passkeyCounts = passkeysCount; + + return credentialCounts; +} + #pragma mark - PasswordExporterDelegate - (void)showActivityViewWithActivityItems:(NSArray*)activityItems
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.h b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.h index 4f698e1..a4499ef4 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.h +++ b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.h
@@ -18,6 +18,9 @@ // Method invoked when the user requests an export of their saved passwords. - (void)startExportFlow; +// Method invoked when the user starts the deletion of all saved credentials. +- (void)startDeletionFlow; + // Method invoked when more information about a managed setting was requested. // The `sourceView` button will be disabled and should be re-enabled once the // requested info is dismissed. @@ -58,6 +61,9 @@ // alert. - (CGRect)sourceRectForBulkMovePasswordsToAccount; +// Returns a rect suitable for anchoring alerts in the credential deletion flow. +- (CGRect)sourceRectForCredentialDeletionAlerts; + // Returns a rect suitable for anchoring alerts in the password export flow. - (CGRect)sourceRectForPasswordExportAlerts;
diff --git a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.mm b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.mm index 34d7ec8e..5cb416c 100644 --- a/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.mm +++ b/ios/chrome/browser/settings/ui_bundled/password/password_settings/password_settings_view_controller.mm
@@ -228,7 +228,7 @@ .frame; } -- (CGRect)sourceRectForCredentialDeleteAlerts { +- (CGRect)sourceRectForCredentialDeletionAlerts { return [self.tableView cellForRowAtIndexPath:[self.tableViewModel indexPathForItem:_deleteCredentialsItem]] @@ -375,8 +375,7 @@ } case ItemTypeDeleteCredentialsButton: { if (self.canDeleteAllCredentials) { - // TODO(crbug.com/383851476): Update this once the deletion function is - // implemented. + [self.presentationDelegate startDeletionFlow]; } break; }
diff --git a/ios/chrome/browser/share_kit/model/BUILD.gn b/ios/chrome/browser/share_kit/model/BUILD.gn index 9c6d61a..8644770 100644 --- a/ios/chrome/browser/share_kit/model/BUILD.gn +++ b/ios/chrome/browser/share_kit/model/BUILD.gn
@@ -11,6 +11,7 @@ "share_kit_delete_configuration.mm", "share_kit_face_pile_configuration.h", "share_kit_face_pile_configuration.mm", + "share_kit_flow_outcome.h", "share_kit_join_configuration.h", "share_kit_join_configuration.mm", "share_kit_leave_configuration.h",
diff --git a/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.h b/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.h index c0b388f..e2c4b8a1 100644 --- a/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.h +++ b/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.h
@@ -7,8 +7,10 @@ #import <UIKit/UIKit.h> +enum class ShareKitFlowOutcome; + using ShareGroupCompletionBlock = void (^)(NSString* collabID); -using CompletionBlock = void (^)(BOOL result); +using CompletionBlock = void (^)(ShareKitFlowOutcome result); // Different types of fake share kit flows. enum class FakeShareKitFlowType { @@ -41,6 +43,11 @@ - (instancetype)initWithNibName:(NSString*)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil NS_UNAVAILABLE; +// Simulates the user tapping on "save", to be used in unit tests. +- (void)accept; +// Simulates the user tapping on "cancel", to be used in unit tests. +- (void)cancel; + @end #endif // IOS_CHROME_BROWSER_SHARE_KIT_MODEL_FAKE_SHARE_KIT_FLOW_VIEW_CONTROLLER_H_
diff --git a/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.mm b/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.mm index 5120fb2..2c9f39e 100644 --- a/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.mm +++ b/ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/share_kit/model/fake_share_kit_flow_view_controller.h" +#import "ios/chrome/browser/share_kit/model/share_kit_flow_outcome.h" #import "ios/chrome/browser/share_kit/model/test_constants.h" @implementation FakeShareKitFlowViewController { @@ -59,21 +60,33 @@ } } -- (void)handleCancelButton { - if (_completionBlock) { - _completionBlock(NO); - } - [self dismissViewControllerAnimated:YES completion:nil]; -} - -- (void)handleSaveButton { +- (void)accept { if (_sharedGroupCompletionBlock) { _sharedGroupCompletionBlock([[NSUUID UUID] UUIDString]); } if (_completionBlock) { - _completionBlock(YES); + _completionBlock(ShareKitFlowOutcome::kSuccess); } [self dismissViewControllerAnimated:YES completion:nil]; } +- (void)cancel { + if (_completionBlock) { + _completionBlock(ShareKitFlowOutcome::kCancel); + } + [self dismissViewControllerAnimated:YES completion:nil]; +} + +#pragma mark - Private + +// Handler for the "save" button. +- (void)handleSaveButton { + [self accept]; +} + +// Handler for the "cancel" button. +- (void)handleCancelButton { + [self cancel]; +} + @end
diff --git a/ios/chrome/browser/share_kit/model/share_kit_flow_outcome.h b/ios/chrome/browser/share_kit/model/share_kit_flow_outcome.h new file mode 100644 index 0000000..f246fb6 --- /dev/null +++ b/ios/chrome/browser/share_kit/model/share_kit_flow_outcome.h
@@ -0,0 +1,15 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IOS_CHROME_BROWSER_SHARE_KIT_MODEL_SHARE_KIT_FLOW_OUTCOME_H_ +#define IOS_CHROME_BROWSER_SHARE_KIT_MODEL_SHARE_KIT_FLOW_OUTCOME_H_ + +// The outcome of a share kit flow. +enum class ShareKitFlowOutcome { + kSuccess, + kFailure, + kCancel, +}; + +#endif // IOS_CHROME_BROWSER_SHARE_KIT_MODEL_SHARE_KIT_FLOW_OUTCOME_H_
diff --git a/ios/chrome/browser/share_kit/model/share_kit_join_configuration.h b/ios/chrome/browser/share_kit/model/share_kit_join_configuration.h index 415be49..bc7f2af 100644 --- a/ios/chrome/browser/share_kit/model/share_kit_join_configuration.h +++ b/ios/chrome/browser/share_kit/model/share_kit_join_configuration.h
@@ -9,6 +9,8 @@ #import "components/data_sharing/public/group_data.h" +enum class ShareKitFlowOutcome; + // Configuration object for joining a shared group. @interface ShareKitJoinConfiguration : NSObject @@ -22,6 +24,9 @@ // the user successfully joined the group. @property(nonatomic, copy) void (^completionBlock)(BOOL result); +// Executed when the join flow ended. +@property(nonatomic, copy) void (^completion)(ShareKitFlowOutcome outcome); + @end #endif // IOS_CHROME_BROWSER_SHARE_KIT_MODEL_SHARE_KIT_JOIN_CONFIGURATION_H_
diff --git a/ios/chrome/browser/share_kit/model/share_kit_manage_configuration.h b/ios/chrome/browser/share_kit/model/share_kit_manage_configuration.h index 6c5f293..25eb996 100644 --- a/ios/chrome/browser/share_kit/model/share_kit_manage_configuration.h +++ b/ios/chrome/browser/share_kit/model/share_kit_manage_configuration.h
@@ -8,6 +8,7 @@ #import <UIKit/UIKit.h> @protocol ApplicationCommands; +enum class ShareKitFlowOutcome; // Configuration object for managing a shared group. @interface ShareKitManageConfiguration : NSObject @@ -24,6 +25,9 @@ // Executed when the manage flow ended. @property(nonatomic, copy) void (^completionBlock)(BOOL succeeded); +// Executed when the manage flow ended. +@property(nonatomic, copy) void (^completion)(ShareKitFlowOutcome outcome); + @end #endif // IOS_CHROME_BROWSER_SHARE_KIT_MODEL_SHARE_KIT_MANAGE_CONFIGURATION_H_
diff --git a/ios/chrome/browser/share_kit/model/share_kit_share_group_configuration.h b/ios/chrome/browser/share_kit/model/share_kit_share_group_configuration.h index e765223..0dad466 100644 --- a/ios/chrome/browser/share_kit/model/share_kit_share_group_configuration.h +++ b/ios/chrome/browser/share_kit/model/share_kit_share_group_configuration.h
@@ -8,6 +8,7 @@ #import <UIKit/UIKit.h> @protocol ApplicationCommands; +enum class ShareKitFlowOutcome; class TabGroup; // Configuration object for the ShareKit ShareGroup API. @@ -26,6 +27,9 @@ // the user successfully shared the group. @property(nonatomic, copy) void (^completionBlock)(BOOL result); +// Executed when the share flow ended. +@property(nonatomic, copy) void (^completion)(ShareKitFlowOutcome outcome); + @end #endif // IOS_CHROME_BROWSER_SHARE_KIT_MODEL_SHARE_KIT_SHARE_GROUP_CONFIGURATION_H_
diff --git a/ios/chrome/browser/share_kit/model/test_share_kit_service.mm b/ios/chrome/browser/share_kit/model/test_share_kit_service.mm index 2c4bb07..d3e47586 100644 --- a/ios/chrome/browser/share_kit/model/test_share_kit_service.mm +++ b/ios/chrome/browser/share_kit/model/test_share_kit_service.mm
@@ -55,7 +55,7 @@ FakeShareKitFlowViewController* viewController = [[FakeShareKitFlowViewController alloc] initWithType:FakeShareKitFlowType::kShare]; - viewController.completionBlock = config.completionBlock; + viewController.completionBlock = config.completion; // Set the shared group completion block. auto shared_group_completion_block = base::CallbackToBlock( @@ -76,6 +76,7 @@ FakeShareKitFlowViewController* viewController = [[FakeShareKitFlowViewController alloc] initWithType:FakeShareKitFlowType::kManage]; + viewController.completionBlock = config.completion; UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:viewController]; @@ -89,7 +90,7 @@ FakeShareKitFlowViewController* viewController = [[FakeShareKitFlowViewController alloc] initWithType:FakeShareKitFlowType::kJoin]; - viewController.completionBlock = config.completionBlock; + viewController.completionBlock = config.completion; UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:viewController];
diff --git a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm index becef4c..fc85c8a7 100644 --- a/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm +++ b/ios/chrome/browser/ui/content_suggestions/content_suggestions_egtest.mm
@@ -118,6 +118,8 @@ config.features_disabled.push_back(kContentPushNotifications); config.features_disabled.push_back(kIOSTipsNotifications); config.features_disabled.push_back(set_up_list::kSetUpListInFirstRun); + config.features_disabled.push_back( + set_up_list::kSetUpListWithoutSignInItem); } if ([self isRunningTest:@selector(testMVTInMagicStack)]) { std::string enable_mvt_arg = std::string(kMagicStack.name) + ":" + @@ -131,6 +133,8 @@ (testMagicStackCompactedSetUpListCompleteAllItems_v2)]) { config.features_enabled.push_back(set_up_list::kSetUpListInFirstRun); config.additional_args.push_back("--SetUpListInFirstRunParam=1"); + config.features_disabled.push_back( + set_up_list::kSetUpListWithoutSignInItem); } return config; }
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 index 6dcb1b3..deda57a8 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -c6c20e193f3bcfeaf3ee5aec28b55744bcedec91 \ No newline at end of file +88ad49cd45deb3d53ed71c145e4b34d32855cfac \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 index fd467e3..2b2b0bd 100644 --- a/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeExtensionKeychainInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -398bef7ee25e81bee172f1c4624eb8f8e46cf9ba \ No newline at end of file +3f165c54e2eb2e8fb0c1cec4be9489c2aca0fd4c \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index 6bb24c0..e9ae471d 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -41cd589a84f8a241c2f9bf7eac32bf5ee1115713 \ No newline at end of file +a9201ba74d8f8dad2d1f1a08520ed19a1b7ebf8d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 index 07ed38f7..66132ca 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -0dd1f9693c7efb17011d0ca323c56ad136738ef6 \ No newline at end of file +d258469694b5e555dfc41164370cab81bd7e7abe \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index 0902cc2..c57a764 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -356d502a47342980903d6aa035d87ff763abe590 \ No newline at end of file +6a747ec25a60ae0afe1f8bcea80db1f5ebd38c0f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 index c5fe80f..c99e8713 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios_asan.zip.sha1
@@ -1 +1 @@ -244e914efcc09c1beb0b1cd5a4f3491b81d69529 \ No newline at end of file +d18a425f47933aa269f84eb58baebd2f44152647 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 index 1645ba9..9bfeb59 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -af8a9788341534585989eff69ffce617aa8e5b39 \ No newline at end of file +5abadf8a52562999c29a41d886f21e1da08b18af \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 index 2616436..2ac9c929 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -d30b150cf2305fbecd1237a32552bbc396ad40ba \ No newline at end of file +4b9c95c82287c4aa97df988e24904f920393c49f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 index a55da09..ddd5db6 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -f04d1b19eb5f3bb4b57a595bdca3a877b97ccb51 \ No newline at end of file +4d4b5167f3c4e869975bfe4313e60977364d17ea \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 index c83de37..25048090 100644 --- a/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_extension_keychain_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -b240e0a1506de04cc457f58c5e09f5937d276334 \ No newline at end of file +8508521d4bcb9ddcc83bd091b455b41d3a9fd287 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index 0b99608..7ccbc42 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -8d7934ca1225244ff88e438a1443a508ab0a6bfd \ No newline at end of file +75cd4529ea1397e9c8df9576cbf53c2c967e929e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 index 30814924..55d5430 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -913524931425b6b228026f612c93b1b670edfd52 \ No newline at end of file +e2f05f521d31c03623f802a04be956332421c510 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 14aec5ff..ff1387c 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -5288967e7d2c6b00b03d822245b00ab1c5d03494 \ No newline at end of file +75c73527000bcfc94a19f64e11395fed3cea5446 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 96b684f1..0698811 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -0d76a03a9858092cc45fb4e0dcd89c19bfa12e88 \ No newline at end of file +44e5f763b11f4690a7f5cc439fe284dc0f436172 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index e73eb75..e2c447e 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -e3aab78de4a29979d1022ec51704cfc9e1f028ae \ No newline at end of file +c667a035bde53969a5e88abd2502ac20df9bc2e3 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 index f77efca..f065fd1 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -7e3156237c97502c8701fc3064058fda6851cf6e \ No newline at end of file +a8273cf655842bd8f381a0111d057a4c09640435 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index c39aa568..4f3c26e0 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -82a962cf5d2925adc7285c699029cc0b181ac168 \ No newline at end of file +68d4c6ad6d659d2ef0d659ec7d9c99b31941de2e \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 index af928f3..04afd23b 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -a45fed0b0518a92431f463dbf91a06ab12217f61 \ No newline at end of file +b532b4eb8de430e06e273c58f102306093ce3529 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index cdf81b4..aa94a593 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -04fd43ee4283f9706373b942a6d782bb1b8b7a67 \ No newline at end of file +51dfdc488d4ff468dc8b2cd81028a0f0ff2b55ed \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index 6732afe..d3cb27c2 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -2179182c64cf9508b9f9cc728a385f0400a984d1 \ No newline at end of file +3edc277aa680fa4a5582af6629513db1057cbf83 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 85a924f0..da4a9c1 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -38925e075fff7ce45e48d842af1ab848c5353cd3 \ No newline at end of file +d36ee93dc168bef9a52ff94feeb2893ef74f180f \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 index 4574b091..1f2cc20 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -b9bf3bee06d56db2eb9b0b4f9fa1de22e666f02f \ No newline at end of file +155822676fb38728a590edd6211ac0cc05f87b6a \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index 9a86ccc..d4135a6c 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -518ec4dd33d262882507aa32e7a445e08515df4b \ No newline at end of file +3911c025ac7baa9a499d60a234d7b331c329b5d0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 index 32e635c..65bc760b 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -cd4cb8bb01b5ccc5d77fc8aea78b9abd50a806af \ No newline at end of file +83beebde1fae30f045966ebf1480adba511144a2 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index e106b010..55d73d6 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -6d12e09b1f0cb6bb9054f99b9d89c8504a6805ec \ No newline at end of file +2fe1cfb155c6a0e26097bb04cfa373c8b7c26763 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 index 4473cb10..33f617d 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios_asan.zip.sha1
@@ -1 +1 @@ -55a844c323c57418493f05764fcdae6c5fa0d467 \ No newline at end of file +c1db46be5a967c72fa61f0c846f095ab0e09beda \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index d40f955..0763f63 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -6316e5f48a24a9bfe18b48111f60330c1e11cd5c \ No newline at end of file +01cd34fec2d3af18cf79bfc0fa7fd28b8503b081 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 index e51ffb87..632b421 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator_asan.zip.sha1
@@ -1 +1 @@ -f90e8a8ee0a3c4709af9a3cb903ce132046fc5e5 \ No newline at end of file +a3465e220facda7b0101fb118d76cf7b26da3480 \ No newline at end of file
diff --git a/ios/web_view/internal/autofill/cwv_autofill_controller.mm b/ios/web_view/internal/autofill/cwv_autofill_controller.mm index 7ed7c0e..bb6581b1 100644 --- a/ios/web_view/internal/autofill/cwv_autofill_controller.mm +++ b/ios/web_view/internal/autofill/cwv_autofill_controller.mm
@@ -222,7 +222,8 @@ fieldType:fieldType type:_lastFormActivityType typedValue:_lastFormActivityTypedValue - frameID:frameID]; + frameID:frameID + onlyPassword:NO]; // It is necessary to call |checkIfSuggestionsAvailableForForm| before // |retrieveSuggestionsForForm| because the former actually queries the db, // while the latter merely returns them.
diff --git a/media/gpu/test/video_encode_accelerator_tests.cc b/media/gpu/test/video_encode_accelerator_tests.cc index f0be8f1d..a2d3854 100644 --- a/media/gpu/test/video_encode_accelerator_tests.cc +++ b/media/gpu/test/video_encode_accelerator_tests.cc
@@ -337,29 +337,14 @@ }; } // namespace -// Encode video from start to end. Wait for the kFlushDone event at the end of -// the stream, that notifies us all frames have been encoded. -TEST_F(VideoEncoderTest, FlushAtEndOfStream) { - if (g_env->SpatialLayers().size() > 1) - GTEST_SKIP() << "Skip SHMEM input test cases in spatial SVC encoding"; - - auto encoder = CreateVideoEncoder(g_env->Video(), GetDefaultConfig()); - - encoder->Encode(); - EXPECT_TRUE(encoder->WaitForFlushDone()); - - EXPECT_EQ(encoder->GetFlushDoneCount(), 1u); - EXPECT_EQ(encoder->GetFrameReleasedCount(), g_env->Video()->NumFrames()); - EXPECT_TRUE(encoder->WaitForBitstreamProcessors()); -} - // Test initializing the video encoder. The test will be successful if the video // encoder is capable of setting up the encoder for the specified codec and // resolution. The test only verifies initialization and doesn't do any // encoding. TEST_F(VideoEncoderTest, Initialize) { - if (g_env->SpatialLayers().size() > 1) + if (g_env->SpatialLayers().size() > 1) { GTEST_SKIP() << "Skip SHMEM input test cases in spatial SVC encoding"; + } auto encoder = CreateVideoEncoder(g_env->Video(), GetDefaultConfig()); @@ -379,6 +364,23 @@ EXPECT_NE(video_encoder, nullptr); } +// Encode video from start to end. Wait for the kFlushDone event at the end of +// the stream, that notifies us all frames have been encoded. +TEST_F(VideoEncoderTest, FlushAtEndOfStream) { + if (g_env->SpatialLayers().size() > 1) { + GTEST_SKIP() << "Skip SHMEM input test cases in spatial SVC encoding"; + } + + auto encoder = CreateVideoEncoder(g_env->Video(), GetDefaultConfig()); + + encoder->Encode(); + EXPECT_TRUE(encoder->WaitForFlushDone()); + + EXPECT_EQ(encoder->GetFlushDoneCount(), 1u); + EXPECT_EQ(encoder->GetFrameReleasedCount(), g_env->Video()->NumFrames()); + EXPECT_TRUE(encoder->WaitForBitstreamProcessors()); +} + // Test forcing key frames while encoding a video. TEST_F(VideoEncoderTest, ForceKeyFrame) { if (g_env->SpatialLayers().size() > 1) @@ -473,6 +475,36 @@ EXPECT_TRUE(encoder->WaitForBitstreamProcessors()); } +// Execute Flush() in the middle of encoding. Supporting this is required for +// Flush() and ChabgeOptions() in media::VideoEncoder API. +// See media/base/video_encoder.h for detail. +TEST_F(VideoEncoderTest, FlushIntheMiddle) { + if (g_env->SpatialLayers().size() > 1) { + GTEST_SKIP() << "Skip SHMEM input test cases in spatial SVC encoding"; + } + + auto config = GetDefaultConfig(); + + auto encoder = CreateVideoEncoder(g_env->Video(), GetDefaultConfig()); + const size_t middle_frame = config.num_frames_to_encode / 2; + + // Encode until the middle of stream and request force_keyframe. + encoder->EncodeUntil(VideoEncoder::kFrameReleased, middle_frame); + EXPECT_TRUE(encoder->WaitUntilIdle()); + + // Flush in the middle. + encoder->Flush(); + EXPECT_TRUE(encoder->WaitForFlushDone()); + + // Encode until the end of stream. + encoder->Encode(); + + EXPECT_TRUE(encoder->WaitForFlushDone()); + EXPECT_EQ(encoder->GetFlushDoneCount(), 2u); + EXPECT_EQ(encoder->GetFrameReleasedCount(), config.num_frames_to_encode); + EXPECT_TRUE(encoder->WaitForBitstreamProcessors()); +} + // Encode video from start to end. Multiple buffer encodes will be queued in the // encoder, without waiting for the result of the previous encode requests. TEST_F(VideoEncoderTest, FlushAtEndOfStream_MultipleOutstandingEncodes) {
diff --git a/net/http/transport_security_state_static.pins b/net/http/transport_security_state_static.pins index bf75ca6..9cb60d5 100644 --- a/net/http/transport_security_state_static.pins +++ b/net/http/transport_security_state_static.pins
@@ -43,9 +43,9 @@ # hash function for preloaded entries again (we have already done so once). # -# Last updated: 2025-01-05 12:53 UTC +# Last updated: 2025-01-06 12:55 UTC PinsListTimestamp -1736081630 +1736168109 TestSPKI sha256/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
diff --git a/net/http/transport_security_state_static_pins.json b/net/http/transport_security_state_static_pins.json index ee6c368e..9db433b 100644 --- a/net/http/transport_security_state_static_pins.json +++ b/net/http/transport_security_state_static_pins.json
@@ -31,7 +31,7 @@ // the 'static_spki_hashes' and 'bad_static_spki_hashes' fields in 'pinsets' // refer to, and the timestamp at which the pins list was last updated. // -// Last updated: 2025-01-05 12:53 UTC +// Last updated: 2025-01-06 12:55 UTC // { "pinsets": [
diff --git a/services/device/android/java/src/org/chromium/services/device/InterfaceRegistrar.java b/services/device/android/java/src/org/chromium/services/device/InterfaceRegistrar.java index 3ef478d..e0a6d68 100644 --- a/services/device/android/java/src/org/chromium/services/device/InterfaceRegistrar.java +++ b/services/device/android/java/src/org/chromium/services/device/InterfaceRegistrar.java
@@ -7,6 +7,7 @@ import org.jni_zero.CalledByNative; import org.jni_zero.JNINamespace; +import org.chromium.build.annotations.NullMarked; import org.chromium.device.battery.BatteryMonitorFactory; import org.chromium.device.mojom.BatteryMonitor; import org.chromium.device.mojom.NfcProvider; @@ -16,6 +17,7 @@ import org.chromium.services.service_manager.InterfaceRegistry; @JNINamespace("device") +@NullMarked class InterfaceRegistrar { @CalledByNative static void createInterfaceRegistryForContext(long nativeHandle, NfcDelegate nfcDelegate) {
diff --git a/services/network/cors/cors_url_loader.cc b/services/network/cors/cors_url_loader.cc index 8af2876..7c93ab8c 100644 --- a/services/network/cors/cors_url_loader.cc +++ b/services/network/cors/cors_url_loader.cc
@@ -307,7 +307,8 @@ scoped_refptr<SharedDictionaryStorage> shared_dictionary_storage, raw_ptr<mojom::SharedDictionaryAccessObserver> shared_dictionary_observer, NetworkContext* context, - net::CookieSettingOverrides factory_cookie_setting_overrides) + net::CookieSettingOverrides factory_cookie_setting_overrides, + net::CookieSettingOverrides devtools_cookie_setting_overrides) : receiver_(this, std::move(loader_receiver)), process_id_(process_id), request_id_(request_id), @@ -335,7 +336,8 @@ context_(context), shared_dictionary_storage_(std::move(shared_dictionary_storage)), shared_dictionary_observer_(shared_dictionary_observer), - factory_cookie_setting_overrides_(factory_cookie_setting_overrides) { + factory_cookie_setting_overrides_(factory_cookie_setting_overrides), + devtools_cookie_setting_overrides_(devtools_cookie_setting_overrides) { TRACE_EVENT("loading", "CorsURLLoader::CorsURLLoader", perfetto::Flow::ProcessScoped(net_log_.source().id)); CHECK(url_loader_network_service_observer_ != nullptr); @@ -875,7 +877,8 @@ request_.url, request_.site_for_cookies, isolation_info_.top_frame_origin(), network::URLLoader::CalculateCookieSettingOverrides( - factory_cookie_setting_overrides_, request_, + factory_cookie_setting_overrides_, + devtools_cookie_setting_overrides_, request_, /*emit_metrics=*/false)) == net::cookie_util::StorageAccessStatus::kInactive) { // Lower layers will add the Sec-Fetch-Storage-Access header, and the
diff --git a/services/network/cors/cors_url_loader.h b/services/network/cors/cors_url_loader.h index b588c4b..7fb733ba 100644 --- a/services/network/cors/cors_url_loader.h +++ b/services/network/cors/cors_url_loader.h
@@ -90,7 +90,8 @@ scoped_refptr<SharedDictionaryStorage> shared_dictionary_storage, raw_ptr<mojom::SharedDictionaryAccessObserver> shared_dictionary_observer, NetworkContext* context, - net::CookieSettingOverrides factory_cookie_setting_overrides); + net::CookieSettingOverrides factory_cookie_setting_overrides, + net::CookieSettingOverrides devtools_cookie_setting_overrides); CorsURLLoader(const CorsURLLoader&) = delete; CorsURLLoader& operator=(const CorsURLLoader&) = delete; @@ -396,6 +397,7 @@ shared_dictionary_data_pipe_writer_; std::optional<URLLoaderCompletionStatus> deferred_completion_status_; const net::CookieSettingOverrides factory_cookie_setting_overrides_; + const net::CookieSettingOverrides devtools_cookie_setting_overrides_; // Used to provide weak pointers of this class for synchronously calling // URLLoaderClient methods. This should be reset any time
diff --git a/services/network/cors/cors_url_loader_factory.cc b/services/network/cors/cors_url_loader_factory.cc index b31fc29b..c5c7fe6 100644 --- a/services/network/cors/cors_url_loader_factory.cc +++ b/services/network/cors/cors_url_loader_factory.cc
@@ -239,6 +239,8 @@ require_cross_site_request_for_cookies_( params->require_cross_site_request_for_cookies), factory_cookie_setting_overrides_(params->cookie_setting_overrides), + devtools_cookie_setting_overrides_( + params->devtools_cookie_setting_overrides), origin_access_list_(origin_access_list), owner_(owner) { TRACE_EVENT("loading", "CorsURLLoaderFactory::CorsURLLoaderFactory", @@ -475,7 +477,8 @@ shared_dictionary_storage, shared_dictionary_observer_ ? shared_dictionary_observer_.get() : nullptr, - context_, factory_cookie_setting_overrides_); + context_, factory_cookie_setting_overrides_, + devtools_cookie_setting_overrides_); } else { loader = std::make_unique<CorsURLLoader>( std::move(receiver), process_id_, request_id, options, @@ -493,7 +496,8 @@ shared_dictionary_storage, shared_dictionary_observer_ ? shared_dictionary_observer_.get() : nullptr, - context_, factory_cookie_setting_overrides_); + context_, factory_cookie_setting_overrides_, + devtools_cookie_setting_overrides_); } auto* raw_loader = loader.get(); OnCorsURLLoaderCreated(std::move(loader));
diff --git a/services/network/cors/cors_url_loader_factory.h b/services/network/cors/cors_url_loader_factory.h index a85dfa8..d3a4762 100644 --- a/services/network/cors/cors_url_loader_factory.h +++ b/services/network/cors/cors_url_loader_factory.h
@@ -209,6 +209,7 @@ shared_dictionary_observer_; const bool require_cross_site_request_for_cookies_; const net::CookieSettingOverrides factory_cookie_setting_overrides_; + const net::CookieSettingOverrides devtools_cookie_setting_overrides_; // Relative order of `network_loader_factory_` and `loaders_` matters - // URLLoaderFactory needs to live longer than URLLoaders created using the
diff --git a/services/network/cors/cors_url_loader_unittest.cc b/services/network/cors/cors_url_loader_unittest.cc index 1583dba..b6f3574 100644 --- a/services/network/cors/cors_url_loader_unittest.cc +++ b/services/network/cors/cors_url_loader_unittest.cc
@@ -2438,7 +2438,8 @@ request.url, request.site_for_cookies, request.trusted_params->isolation_info.top_frame_origin(), URLLoader::CalculateCookieSettingOverrides( - net::CookieSettingOverrides(), request, + /*factory_overrides=*/net::CookieSettingOverrides(), + /*devtools_overrides=*/net::CookieSettingOverrides(), request, /*emit_metrics=*/false)); }
diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom index 18a5447..2ae706f 100644 --- a/services/network/public/mojom/network_context.mojom +++ b/services/network/public/mojom/network_context.mojom
@@ -901,6 +901,11 @@ // each URLRequest. CookieSettingOverrides cookie_setting_overrides; + // The cookie setting overrides from devtools, only conditionally applied + // on requests from devtools enabled context, i.e. when + // `ResourceRequest::devtools_request_id` is present. + CookieSettingOverrides devtools_cookie_setting_overrides; + // If `require_cross_site_request_for_cookies` is specified, then all // loaded requests must have an empty site_for_cookies to ensure only // SameSite=None cookies can be attached to the request.
diff --git a/services/network/public/mojom/trust_tokens.mojom b/services/network/public/mojom/trust_tokens.mojom index ef73c90..866ecc63 100644 --- a/services/network/public/mojom/trust_tokens.mojom +++ b/services/network/public/mojom/trust_tokens.mojom
@@ -74,6 +74,9 @@ // The operation was executed by a means other than sending the resource // request at hand, so there's no response to provide for the request. kOperationSuccessfullyFulfilledLocally = 11, + + // The limit on issuers per-site was hit. + kSiteIssuerLimit = 12, }; // LINT.ThenChange(//tools/metrics/histograms/metadata/net/enums.xml:TrustTokenOperationStatus)
diff --git a/services/network/trust_tokens/trust_token_query_answerer.cc b/services/network/trust_tokens/trust_token_query_answerer.cc index ae9955d..145cbb3 100644 --- a/services/network/trust_tokens/trust_token_query_answerer.cc +++ b/services/network/trust_tokens/trust_token_query_answerer.cc
@@ -72,7 +72,7 @@ if (!trust_token_store->SetAssociation(issuer, top_frame_origin_)) { std::move(callback).Run(mojom::HasTrustTokensResult::New( - mojom::TrustTokenOperationStatus::kResourceLimited, + mojom::TrustTokenOperationStatus::kSiteIssuerLimit, /*has_trust_tokens=*/false)); return; }
diff --git a/services/network/trust_tokens/trust_token_query_answerer_unittest.cc b/services/network/trust_tokens/trust_token_query_answerer_unittest.cc index ed1dc0ec..4e7c1561 100644 --- a/services/network/trust_tokens/trust_token_query_answerer_unittest.cc +++ b/services/network/trust_tokens/trust_token_query_answerer_unittest.cc
@@ -122,7 +122,7 @@ })); ASSERT_TRUE(result); - EXPECT_EQ(result->status, mojom::TrustTokenOperationStatus::kResourceLimited); + EXPECT_EQ(result->status, mojom::TrustTokenOperationStatus::kSiteIssuerLimit); } TEST(TrustTokenQueryAnswerer, TokenQuerySuccessWithNoTokens) {
diff --git a/services/network/trust_tokens/trust_token_request_issuance_helper.cc b/services/network/trust_tokens/trust_token_request_issuance_helper.cc index 79cd6712..79def6a9 100644 --- a/services/network/trust_tokens/trust_token_request_issuance_helper.cc +++ b/services/network/trust_tokens/trust_token_request_issuance_helper.cc
@@ -153,7 +153,7 @@ if (!token_store_->SetAssociation(*issuer_, top_level_origin_)) { LogOutcome(net_log_, kBegin, "Couldn't set issuer-toplevel association"); std::move(done).Run(std::nullopt, - mojom::TrustTokenOperationStatus::kResourceLimited); + mojom::TrustTokenOperationStatus::kSiteIssuerLimit); return; }
diff --git a/services/network/trust_tokens/trust_token_request_issuance_helper_unittest.cc b/services/network/trust_tokens/trust_token_request_issuance_helper_unittest.cc index a525c48..089076d5 100644 --- a/services/network/trust_tokens/trust_token_request_issuance_helper_unittest.cc +++ b/services/network/trust_tokens/trust_token_request_issuance_helper_unittest.cc
@@ -201,7 +201,7 @@ auto request = MakeURLRequest("https://issuer.com/"); request->set_initiator(issuer); EXPECT_EQ(ExecuteBeginOperationAndWaitForResult(&helper, request.get()), - mojom::TrustTokenOperationStatus::kResourceLimited); + mojom::TrustTokenOperationStatus::kSiteIssuerLimit); } // Check that issuance fails if the number of tokens stored for the issuer is
diff --git a/services/network/trust_tokens/trust_token_request_redemption_helper.cc b/services/network/trust_tokens/trust_token_request_redemption_helper.cc index 90b1bad4..acddf26 100644 --- a/services/network/trust_tokens/trust_token_request_redemption_helper.cc +++ b/services/network/trust_tokens/trust_token_request_redemption_helper.cc
@@ -106,7 +106,7 @@ if (!token_store_->SetAssociation(*issuer_, top_level_origin_)) { LogOutcome(net_log_, kBegin, "Couldn't set issuer-toplevel association"); std::move(done).Run(std::nullopt, - mojom::TrustTokenOperationStatus::kResourceLimited); + mojom::TrustTokenOperationStatus::kSiteIssuerLimit); return; }
diff --git a/services/network/trust_tokens/trust_token_request_redemption_helper_unittest.cc b/services/network/trust_tokens/trust_token_request_redemption_helper_unittest.cc index cb1a540..c58eb7fc 100644 --- a/services/network/trust_tokens/trust_token_request_redemption_helper_unittest.cc +++ b/services/network/trust_tokens/trust_token_request_redemption_helper_unittest.cc
@@ -125,7 +125,7 @@ mojom::TrustTokenOperationStatus result = ExecuteBeginOperationAndWaitForResult(&helper, request.get()); - EXPECT_EQ(result, mojom::TrustTokenOperationStatus::kResourceLimited); + EXPECT_EQ(result, mojom::TrustTokenOperationStatus::kSiteIssuerLimit); } // Check that redemption fails if its key commitment request fails.
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 4db6317..3cab8aa70 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -15,6 +15,7 @@ #include <vector> #include "base/command_line.h" +#include "base/containers/enum_set.h" #include "base/containers/fixed_flat_set.h" #include "base/files/file.h" #include "base/functional/bind.h" @@ -101,6 +102,7 @@ #include "services/network/public/mojom/early_hints.mojom.h" #include "services/network/public/mojom/fetch_api.mojom.h" #include "services/network/public/mojom/http_raw_headers.mojom.h" +#include "services/network/public/mojom/network_context.mojom.h" #include "services/network/public/mojom/network_context_client.mojom.h" #include "services/network/public/mojom/url_loader_factory.mojom.h" #include "services/network/public/mojom/url_response_head.mojom.h" @@ -128,6 +130,17 @@ // Size to allocate for `discard_buffer_`. constexpr size_t kDiscardBufferSize = 128 * 1024; +// TODO(https://crbug.com/375352611): add the check for enabling third-party +// cookies. +constexpr uint64_t kAllowedDevToolsCookieSettingOverrides = + 1u << static_cast<int>( + net::CookieSettingOverride::kForceDisableThirdPartyCookies) | + 1u << static_cast<int>( + net::CookieSettingOverride::kForceEnableThirdPartyCookieMitigations) | + 1u << static_cast<int>(net::CookieSettingOverride::kSkipTPCDMetadataGrant) | + 1u << static_cast<int>( + net::CookieSettingOverride::kSkipTPCDHeuristicsGrant); + constexpr char kActivateStorageAccessHeader[] = "activate-storage-access"; // These values are persisted to logs. Entries should not be renumbered and @@ -791,8 +804,10 @@ /*request_load_flags=*/request.load_flags, /*priority_incremental=*/request.priority_incremental, /*cookie_setting_overrides=*/ - CalculateCookieSettingOverrides(factory_params_->cookie_setting_overrides, - request, /*emit_metrics=*/true), + CalculateCookieSettingOverrides( + factory_params_->cookie_setting_overrides, + factory_params_->devtools_cookie_setting_overrides, request, + /*emit_metrics=*/true), /*shared_dictionary_getter=*/ shared_dictionary_manager ? std::make_optional( @@ -1779,6 +1794,7 @@ // static net::CookieSettingOverrides URLLoader::CalculateCookieSettingOverrides( net::CookieSettingOverrides factory_overrides, + net::CookieSettingOverrides devtools_overrides, const ResourceRequest& request, bool emit_metrics) { net::CookieSettingOverrides overrides(factory_overrides); @@ -1790,6 +1806,14 @@ AddAdsHeuristicCookieSettingOverrides(request.is_ad_tagged, overrides, emit_metrics); + // Only apply the DevTools overrides if the request is from devtools enabled + // context. + if (request.devtools_request_id.has_value()) { + CHECK_EQ(devtools_overrides.ToEnumBitmask() & + ~kAllowedDevToolsCookieSettingOverrides, + 0u); + overrides = base::Union(overrides, devtools_overrides); + } // The `kStorageAccessGrantEligible` override should not be present in // factory_overrides.
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index a9ce96e..bae7c68d 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -317,6 +317,7 @@ // May also emit to histograms. static net::CookieSettingOverrides CalculateCookieSettingOverrides( net::CookieSettingOverrides factory_overrides, + net::CookieSettingOverrides devtools_overrides, const ResourceRequest& request, bool emit_metrics);
diff --git a/services/network/url_loader_unittest.cc b/services/network/url_loader_unittest.cc index 3099d503..4a388994c 100644 --- a/services/network/url_loader_unittest.cc +++ b/services/network/url_loader_unittest.cc
@@ -5436,6 +5436,60 @@ ExpectedCookieSettingOverridesForCrossSiteRedirect())); } +TEST_F(URLLoaderTest, DevToolsCookieSettingOverrides_NotApplied) { + GURL url("http://www.example.com.test/"); + base::RunLoop delete_run_loop; + mojo::PendingRemote<mojom::URLLoader> loader; + + context().mutable_factory_params().process_id = kProcessId; + // This override should only apply conditionally when devtools is enabled. + context().mutable_factory_params().devtools_cookie_setting_overrides = { + net::CookieSettingOverride::kForceDisableThirdPartyCookies}; + + ResourceRequest request = CreateResourceRequest("GET", url); + std::unique_ptr<URLLoader> url_loader = URLLoaderOptions().MakeURLLoader( + context(), DeleteLoaderCallback(&delete_run_loop, &url_loader), + loader.InitWithNewPipeAndPassReceiver(), request, + client()->CreateRemote()); + + client()->RunUntilComplete(); + delete_run_loop.Run(); + + const std::vector<net::CookieSettingOverrides> records = + test_network_delegate()->cookie_setting_overrides_records(); + EXPECT_THAT(records, ElementsAre(net::CookieSettingOverrides(), + net::CookieSettingOverrides())); +} + +TEST_F(URLLoaderTest, DevToolsCookieSettingOverrides_Applied) { + GURL url("http://www.example.com.test/"); + base::RunLoop delete_run_loop; + mojo::PendingRemote<mojom::URLLoader> loader; + + net::CookieSettingOverrides devtools_overrides = { + net::CookieSettingOverride::kForceDisableThirdPartyCookies}; + context().mutable_factory_params().process_id = kProcessId; + // This override should only apply conditionally when devtools is enabled. + context().mutable_factory_params().devtools_cookie_setting_overrides = + devtools_overrides; + + ResourceRequest request = CreateResourceRequest("GET", url); + // `devtools_request_id` is present, meaning devtools is enabled for this + // request. + request.devtools_request_id = "devtools_id"; + std::unique_ptr<URLLoader> url_loader = URLLoaderOptions().MakeURLLoader( + context(), DeleteLoaderCallback(&delete_run_loop, &url_loader), + loader.InitWithNewPipeAndPassReceiver(), request, + client()->CreateRemote()); + + client()->RunUntilComplete(); + delete_run_loop.Run(); + + const std::vector<net::CookieSettingOverrides> records = + test_network_delegate()->cookie_setting_overrides_records(); + EXPECT_THAT(records, ElementsAre(devtools_overrides, devtools_overrides)); +} + INSTANTIATE_TEST_SUITE_P( All, URLLoaderCookieSettingOverridesTest,
diff --git a/services/tracing/perfetto/producer_host.cc b/services/tracing/perfetto/producer_host.cc index 4811b34..e9d890a 100644 --- a/services/tracing/perfetto/producer_host.cc +++ b/services/tracing/perfetto/producer_host.cc
@@ -159,6 +159,11 @@ producer_endpoint_->RegisterDataSource(registration_info); } +void ProducerHost::UpdateDataSource( + const perfetto::DataSourceDescriptor& registration_info) { + producer_endpoint_->UpdateDataSource(registration_info); +} + void ProducerHost::RegisterTraceWriter(uint32_t writer_id, uint32_t target_buffer) { producer_endpoint_->RegisterTraceWriter(writer_id, target_buffer);
diff --git a/services/tracing/perfetto/producer_host.h b/services/tracing/perfetto/producer_host.h index 0d964cde..d57b043a 100644 --- a/services/tracing/perfetto/producer_host.h +++ b/services/tracing/perfetto/producer_host.h
@@ -93,6 +93,8 @@ // provide a specific data source. void RegisterDataSource( const perfetto::DataSourceDescriptor& registration_info) override; + void UpdateDataSource( + const perfetto::DataSourceDescriptor& registration_info) override; // Called by the ProducerClient to associate a TraceWriter with a target // buffer, which is required to support scraping of the SMB by the service.
diff --git a/services/tracing/public/cpp/perfetto/perfetto_traced_process.h b/services/tracing/public/cpp/perfetto/perfetto_traced_process.h index 406a9704..b7f6ea75b 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_traced_process.h +++ b/services/tracing/public/cpp/perfetto/perfetto_traced_process.h
@@ -138,8 +138,7 @@ void OnStart(const perfetto::DataSourceBase::StartArgs&) override; void OnStop(const perfetto::DataSourceBase::StopArgs&) override; void WillClearIncrementalState( - const base::perfetto_track_event::TrackEvent:: - ClearIncrementalStateArgs&) override; + const perfetto::DataSourceBase::ClearIncrementalStateArgs&) override; bool CanAdoptStartupSession(const perfetto::DataSourceConfig&, const perfetto::DataSourceConfig&) override; @@ -309,8 +308,7 @@ template <typename T> void PerfettoTracedProcess::DataSourceProxy<T>::WillClearIncrementalState( - const base::perfetto_track_event::TrackEvent::ClearIncrementalStateArgs& - args) { + const perfetto::DataSourceBase::ClearIncrementalStateArgs& args) { (*data_source_ptr_)->ClearIncrementalState(); }
diff --git a/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc b/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc index bd48148..3a9afab 100644 --- a/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc +++ b/services/tracing/public/cpp/perfetto/perfetto_tracing_backend.cc
@@ -95,7 +95,7 @@ void UpdateDataSource( const perfetto::DataSourceDescriptor& descriptor) override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - NOTREACHED(); + producer_host_->UpdateDataSource(descriptor); } void UnregisterDataSource(const std::string& name) override {
diff --git a/services/tracing/public/mojom/perfetto_service.mojom b/services/tracing/public/mojom/perfetto_service.mojom index fdbe84a2..a969282 100644 --- a/services/tracing/public/mojom/perfetto_service.mojom +++ b/services/tracing/public/mojom/perfetto_service.mojom
@@ -158,6 +158,10 @@ // datasource. RegisterDataSource(DataSourceRegistration registration_info); + // Similar to RegisterDataSource, but allows to update a specific datasource + // that was already registered. + UpdateDataSource(DataSourceRegistration registration_info); + // Called by the ProducerClient to associate a TraceWriter with a target // buffer, which is required to support scraping of the SMB by the service. RegisterTraceWriter(uint32 writer_id, uint32 target_buffer);
diff --git a/testing/buildbot/generate_buildbot_json_coveragetest.py b/testing/buildbot/generate_buildbot_json_coveragetest.py index 9dd4cc4..37da5c2 100755 --- a/testing/buildbot/generate_buildbot_json_coveragetest.py +++ b/testing/buildbot/generate_buildbot_json_coveragetest.py
@@ -19,7 +19,7 @@ pass def main(): - cov = coverage.coverage(include='*generate_buildbot_json.py') + cov = coverage.coverage(data_file=None, include='*generate_buildbot_json.py') cov.start() # //testing/buildbot imports. # pylint: disable=import-outside-toplevel
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 118b41c..31f9668 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -183,6 +183,21 @@ ] } ], + "AddReferringAppInfoToProtegoPings": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "AddReferringAppInfoToProtegoPings" + ] + } + ] + } + ], "AddressInfobarDisplayLength": [ { "platforms": [ @@ -11947,6 +11962,21 @@ ] } ], + "IOSSetUpListWithoutSignInItem": [ + { + "platforms": [ + "ios" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "SetUpListWithoutSignInItem" + ] + } + ] + } + ], "IOSSharedHighlightingColorChange": [ { "platforms": [ @@ -20654,6 +20684,21 @@ ] } ], + "SchoolToolsSpotlight": [ + { + "platforms": [ + "chromeos" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "BocaSpotlight" + ] + } + ] + } + ], "ScreenCaptureKitMacScreen": [ { "platforms": [ @@ -22596,25 +22641,6 @@ ] } ], - "TabStripCollectionStorage": [ - { - "platforms": [ - "chromeos", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "TabStripCollectionStorage" - ] - } - ] - } - ], "TabStripIncognitoMigration": [ { "platforms": [ @@ -22998,6 +23024,21 @@ ] } ], + "TraceBinderIpc": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "TraceBinderIpc" + ] + } + ] + } + ], "TrackingProtection3pcd": [ { "platforms": [ @@ -25346,22 +25387,6 @@ ] } ], - "WebViewFrameRateHints": [ - { - "platforms": [ - "android_webview" - ], - "experiments": [ - { - "name": "Enabled", - "enable_features": [ - "WebViewFrameRateHints" - ], - "min_os_version": "15.0.0" - } - ] - } - ], "WebViewInterceptedCookieHeader": [ { "platforms": [
diff --git a/third_party/PRESUBMIT.py b/third_party/PRESUBMIT.py index 27ea1ba50..275af74 100644 --- a/third_party/PRESUBMIT.py +++ b/third_party/PRESUBMIT.py
@@ -56,8 +56,11 @@ local_path = f.LocalPath() if input_api.os_path.dirname(local_path) == 'third_party': continue + # TODO: Autorolled DEPS should be automatically excluded exclusions = [ 'third_party/android_deps/', + 'third_party/androidx/', + 'third_party/android_build_tools/', 'third_party/blink/', 'third_party/boringssl/', 'third_party/closure_compiler/externs/',
diff --git a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy index 5af95ee..343a01b 100644 --- a/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy +++ b/third_party/android_deps/buildSrc/src/main/groovy/BuildConfigGenerator.groovy
@@ -134,9 +134,6 @@ 'androidx_multidex_multidex', 'androidx_pdf_pdf', 'androidx_privacysandbox_ads_ads_adservices', - 'androidx_slice_slice_builders_java', - 'androidx_slice_slice_core_java', - 'androidx_slice_slice_view_java', 'androidx_test', ]
diff --git a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_test_jvm/3pp/fetch.py b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_test_jvm/3pp/fetch.py index 824dbbf..1e84ec60 100755 --- a/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_test_jvm/3pp/fetch.py +++ b/third_party/android_deps/libs/org_jetbrains_kotlinx_kotlinx_coroutines_test_jvm/3pp/fetch.py
@@ -19,7 +19,7 @@ module_name='kotlinx-coroutines-test-jvm', file_ext='jar', patch_version='cr1', - version_override='1.7.3', + version_override=None, version_filter=None) if __name__ == '__main__':
diff --git a/third_party/android_provider/README.chromium b/third_party/android_provider/README.chromium index eb9fa8d5..6fbda15 100644 --- a/third_party/android_provider/README.chromium +++ b/third_party/android_provider/README.chromium
@@ -1,6 +1,7 @@ Name: MediaStoreUtils Android sample. URL: https://android.googlesource.com/platform/cts/ Version: 50f25a19f2a3de940d6ef7eac84b37d1c62f1b5f +Revision: 50f25a19f2a3de940d6ef7eac84b37d1c62f1b5f License: Apache-2.0 License File: LICENSE Security Critical: yes
diff --git a/third_party/androidx/build.gradle.template b/third_party/androidx/build.gradle.template index d72edd1..bd56c80 100644 --- a/third_party/androidx/build.gradle.template +++ b/third_party/androidx/build.gradle.template
@@ -102,10 +102,6 @@ // succeed again. Deps on it will need to be removed first. compile 'androidx.savedstate:savedstate:{{androidx_dependency_version}}' compile 'androidx.savedstate:savedstate-android:{{androidx_dependency_version}}' - // Slice libraries no longer exist at tip-of-tree (https://crbug.com/385155411) - compile 'androidx.slice:slice-builders:1.1.0-alpha02' - compile 'androidx.slice:slice-core:1.1.0-alpha02' - compile 'androidx.slice:slice-view:1.1.0-alpha02' compile 'androidx.swiperefreshlayout:swiperefreshlayout:{{androidx_dependency_version}}' compile 'androidx.tracing:tracing:{{androidx_dependency_version}}' compile 'androidx.tvprovider:tvprovider:{{androidx_dependency_version}}'
diff --git a/third_party/angle b/third_party/angle index fbaaeb7..1a8d771 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit fbaaeb7b83bce2a6ec8519b4d7f990f0e2feb839 +Subproject commit 1a8d771208818689521fa1746211435d4eb9d476
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 2fdcdec..684697a2 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -829,7 +829,7 @@ BASE_FEATURE(kFencedFramesReportEventHeaderChanges, "FencedFramesReportEventHeaderChanges", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables a bug fix that allows a 'src' allowlist in the |allow| parameter of a // <fencedframe> or <iframe> loaded with a FencedFrameConfig to behave as @@ -2274,10 +2274,6 @@ "RenderSizeInScoreAdBrowserSignals", base::FEATURE_ENABLED_BY_DEFAULT); -BASE_FEATURE(kReportFirstFrameTimeAsRenderTime, - "ReportFirstFrameTimeAsRenderTime", - base::FEATURE_ENABLED_BY_DEFAULT); - BASE_FEATURE(kResamplingInputEvents, "ResamplingInputEvents", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/third_party/blink/public/common/features.h b/third_party/blink/public/common/features.h index 3738dd74..7d5238a3 100644 --- a/third_party/blink/public/common/features.h +++ b/third_party/blink/public/common/features.h
@@ -1489,8 +1489,6 @@ // https://github.com/WICG/turtledove/blob/main/FLEDGE.md#23-scoring-bids BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kRenderSizeInScoreAdBrowserSignals); -BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kReportFirstFrameTimeAsRenderTime); - // Enables resampling input events on main thread. BLINK_COMMON_EXPORT BASE_DECLARE_FEATURE(kResamplingInputEvents); // Enables resampling GestureScroll events on compositor thread.
diff --git a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h index 4925a990..aa95659 100644 --- a/third_party/blink/public/common/renderer_preferences/renderer_preferences.h +++ b/third_party/blink/public/common/renderer_preferences/renderer_preferences.h
@@ -23,14 +23,7 @@ // Note: these must match the values in renderer_preferences.mojom. constexpr uint32_t kDefaultActiveSelectionBgColor = 0xFF1967D2; -#if BUILDFLAG(IS_ANDROID) -// See crbug.com/1445053, but on Android, the selection background color is -// not used, and a much lighter shade of blue is used instead. Therefore, the -// foreground color needs to be dark/black to ensure contrast. -constexpr uint32_t kDefaultActiveSelectionFgColor = 0xFF000000; -#else constexpr uint32_t kDefaultActiveSelectionFgColor = 0xFFFFFFFF; -#endif constexpr uint32_t kDefaultInactiveSelectionBgColor = 0xFFC8C8C8; constexpr uint32_t kDefaultInactiveSelectionFgColor = 0xFF323232;
diff --git a/third_party/blink/public/devtools_protocol/browser_protocol.pdl b/third_party/blink/public/devtools_protocol/browser_protocol.pdl index ed9b88e..d1f03de 100644 --- a/third_party/blink/public/devtools_protocol/browser_protocol.pdl +++ b/third_party/blink/public/devtools_protocol/browser_protocol.pdl
@@ -7436,6 +7436,7 @@ InternalError UnknownError FulfilledLocally + SiteIssuerLimit TrustTokenOperationType type RequestId requestId # Top level origin. The context in which the operation was attempted.
diff --git a/third_party/blink/public/mojom/content_extraction/ai_page_content.mojom b/third_party/blink/public/mojom/content_extraction/ai_page_content.mojom index 31737e8..2345a33 100644 --- a/third_party/blink/public/mojom/content_extraction/ai_page_content.mojom +++ b/third_party/blink/public/mojom/content_extraction/ai_page_content.mojom
@@ -51,6 +51,7 @@ kSection, kAside, kFooter, + kContentHidden, }; struct AIPageContentGeometry {
diff --git a/third_party/blink/public/mojom/renderer_preferences.mojom b/third_party/blink/public/mojom/renderer_preferences.mojom index 99d37be..ab7a2f6d 100644 --- a/third_party/blink/public/mojom/renderer_preferences.mojom +++ b/third_party/blink/public/mojom/renderer_preferences.mojom
@@ -57,11 +57,6 @@ // The colors used in selection text. Currently only used on Linux and Ash. // Note: these must match the values in renderer_preferences.h. uint32 active_selection_bg_color = 0xFF1967D2; - - [EnableIf=is_android] - uint32 active_selection_fg_color = 0xFF000000; - - [EnableIfNot=is_android] uint32 active_selection_fg_color = 0xFFFFFFFF; uint32 inactive_selection_bg_color = 0xFFC8C8C8; uint32 inactive_selection_fg_color = 0xFF323232;
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 81bfb22..59eed74 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
@@ -4623,6 +4623,7 @@ kCanvasTextDirectionGetInherit = 5237, kCanvasTextDirectionSet = 5238, kCanvasTextDirectionSetInherit = 5239, + kTopicsAPIImg = 5240, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots. Also don't add extra
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.cc b/third_party/blink/renderer/core/css/css_property_value_set.cc index 4675138..a59b96d5 100644 --- a/third_party/blink/renderer/core/css/css_property_value_set.cc +++ b/third_party/blink/renderer/core/css/css_property_value_set.cc
@@ -313,6 +313,9 @@ bool MutableCSSPropertyValueSet::RemoveShorthandProperty( CSSPropertyID property_id) { + if (property_id == CSSPropertyID::kAll) { + return RemovePropertiesAffectedByAll(); + } StylePropertyShorthand shorthand = shorthandForProperty(property_id); if (!shorthand.length()) { return false; @@ -671,6 +674,29 @@ return false; } +bool MutableCSSPropertyValueSet::RemovePropertiesAffectedByAll() { + if (property_vector_.empty()) { + return false; + } + + base::span<CSSPropertyValue> properties(property_vector_); + unsigned old_size = property_vector_.size(); + unsigned new_index = 0; + for (unsigned old_index = 0; old_index < old_size; ++old_index) { + const CSSPropertyValue& property = properties[old_index]; + if (CSSProperty::Get(property.PropertyID()).IsAffectedByAll()) { + continue; + } + properties[new_index++] = properties[old_index]; + } + if (new_index != old_size) { + property_vector_.Shrink(new_index); + InvalidateHashIfComputed(); + return true; + } + return false; +} + CSSPropertyValue* MutableCSSPropertyValueSet::FindCSSPropertyWithName( const CSSPropertyName& name) { return const_cast<CSSPropertyValue*>(
diff --git a/third_party/blink/renderer/core/css/css_property_value_set.h b/third_party/blink/renderer/core/css/css_property_value_set.h index 24adc9c..0f774b1 100644 --- a/third_party/blink/renderer/core/css/css_property_value_set.h +++ b/third_party/blink/renderer/core/css/css_property_value_set.h
@@ -343,6 +343,7 @@ template <typename T> // CSSPropertyID or AtomicString bool RemoveProperty(const T& property, String* return_text = nullptr); bool RemovePropertiesInSet(base::span<const CSSProperty* const> set); + bool RemovePropertiesAffectedByAll(); void RemoveEquivalentProperties(const CSSPropertyValueSet*); void RemoveEquivalentProperties(const CSSStyleDeclaration*);
diff --git a/third_party/blink/renderer/core/css/resolver/style_cascade.cc b/third_party/blink/renderer/core/css/resolver/style_cascade.cc index ce6a18e..1284bde 100644 --- a/third_party/blink/renderer/core/css/resolver/style_cascade.cc +++ b/third_party/blink/renderer/core/css/resolver/style_cascade.cc
@@ -1594,7 +1594,7 @@ AtomicString variable_name = ConsumeVariableName(stream); if (variable_name == "safe-area-inset-bottom") { - state_.StyleBuilder().SetReferencesSafeAreaInsetBottom(true); + state_.StyleBuilder().SetHasEnvSafeAreaInsetBottom(); state_.GetDocument() .GetStyleEngine() .SetNeedsToUpdateComplexSafeAreaConstraints(); @@ -1819,7 +1819,8 @@ } void StyleCascade::ApplyIsBottomRelativeToSafeAreaInset() { - if (!map_.NativeBitset().Has(CSSPropertyID::kBottom)) { + if (!state_.StyleBuilder().HasEnvSafeAreaInsetBottom() || + !map_.NativeBitset().Has(CSSPropertyID::kBottom)) { return; }
diff --git a/third_party/blink/renderer/core/css/style_engine.cc b/third_party/blink/renderer/core/css/style_engine.cc index 7499ad27..bce1a95 100644 --- a/third_party/blink/renderer/core/css/style_engine.cc +++ b/third_party/blink/renderer/core/css/style_engine.cc
@@ -214,7 +214,7 @@ if (auto* element = DynamicTo<Element>(current)) { if (const ComputedStyle* style = ComputedStyle::NullifyEnsured(element->GetComputedStyle())) { - if (style->ReferencesSafeAreaInsetBottom() && + if (style->HasEnvSafeAreaInsetBottom() && !style->IsBottomRelativeToSafeAreaInset()) { return true; }
diff --git a/third_party/blink/renderer/core/dom/element.cc b/third_party/blink/renderer/core/dom/element.cc index f7562825..e981bc6 100644 --- a/third_party/blink/renderer/core/dom/element.cc +++ b/third_party/blink/renderer/core/dom/element.cc
@@ -2993,6 +2993,13 @@ } StyleAttributeChanged(params.new_value, params.reason); } else if (IsPresentationAttribute(name)) { + if (name == html_names::kHiddenAttr) { + if (params.new_value == "until-found") { + EnsureDisplayLockContext().SetIsHiddenUntilFoundElement(true); + } else if (DisplayLockContext* context = GetDisplayLockContext()) { + context->SetIsHiddenUntilFoundElement(false); + } + } GetElementData()->SetPresentationAttributeStyleIsDirty(true); SetNeedsStyleRecalc(kLocalStyleChange, StyleChangeReasonForTracing::FromAttribute(name)); @@ -9924,19 +9931,6 @@ element_data.SetPresentationAttributeStyleIsDirty(false); element_data.presentation_attribute_style_ = ComputePresentationAttributeStyle(*this); - - // We could do this in CreatePresentationAttributeStyle or - // HTMLElement::CollectStyleForPresentationAttribute when we actually iterate - // over attributes, but the presentational style gets cached so those - // functions aren't necessarily called every time. This function actually gets - // called every time, so we must do this check here. - AttributeCollection attributes = AttributesWithoutUpdate(); - auto* hidden_attr = attributes.Find(html_names::kHiddenAttr); - if (hidden_attr && hidden_attr->Value() == "until-found") { - EnsureDisplayLockContext().SetIsHiddenUntilFoundElement(true); - } else if (DisplayLockContext* context = GetDisplayLockContext()) { - context->SetIsHiddenUntilFoundElement(false); - } } CSSPropertyValueSet* Element::CreatePresentationAttributeStyle() {
diff --git a/third_party/blink/renderer/core/dom/scroll_marker_group_pseudo_element.cc b/third_party/blink/renderer/core/dom/scroll_marker_group_pseudo_element.cc index 118a757..580eaab 100644 --- a/third_party/blink/renderer/core/dom/scroll_marker_group_pseudo_element.cc +++ b/third_party/blink/renderer/core/dom/scroll_marker_group_pseudo_element.cc
@@ -298,7 +298,13 @@ HeapVector<Member<ScrollMarkerPseudoElement>> selection; if (within_start || within_end) { selection = ChooseReserved(candidates_); - } else { + } + + if (selection.empty()) { + // This is independent of the within_{start, end} check because it can + // happen that we are within the reserved region but the scroll + // targets are positioned such that the first target is beyond the + // reserved region. In this case we should use generic selection. selection = ChooseGeneric(candidates_); }
diff --git a/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc b/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc index 7362e5b..a2a792c 100644 --- a/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc +++ b/third_party/blink/renderer/core/fetch/trust_token_to_mojom.cc
@@ -161,6 +161,9 @@ case TrustTokenOperationStatus::kResourceLimited: return create("Quota hit for Private State Tokens operation", DOMExceptionCode::kOperationError); + case TrustTokenOperationStatus::kSiteIssuerLimit: + return create("Limit hit for Private State Tokens issuers per site", + DOMExceptionCode::kOperationError); case TrustTokenOperationStatus::kUnauthorized: return create( "Private State Tokens API unavailable due to user settings.",
diff --git a/third_party/blink/renderer/core/html/forms/html_option_element.cc b/third_party/blink/renderer/core/html/forms/html_option_element.cc index 4e94b47..dceddadd 100644 --- a/third_party/blink/renderer/core/html/forms/html_option_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_option_element.cc
@@ -668,7 +668,7 @@ mouse_event->button() == static_cast<int16_t>(WebPointerProperties::Button::kLeft)) { select->SelectOptionByPopup(this); - select->HidePopup(); + select->HidePopup(SelectPopupHideBehavior::kNormal); event.SetDefaultHandled(); return; } @@ -684,7 +684,7 @@ if (!(keyboard_event->GetModifiers() & ignore_modifiers)) { if ((key == " " || key == keywords::kCapitalEnter)) { select->SelectOptionByPopup(this); - select->HidePopup(); + select->HidePopup(SelectPopupHideBehavior::kNormal); event.SetDefaultHandled(); return; } @@ -735,10 +735,11 @@ } if (key == keywords::kTab && - !(keyboard_event->GetModifiers() & tab_ignore_modifiers)) { + !(keyboard_event->GetModifiers() & tab_ignore_modifiers) && + !select->IsInDialogMode()) { // TODO(http://crbug.com/1511354): Consider focusing something in this // case. https://github.com/openui/open-ui/issues/1016 - select->HidePopup(); + select->HidePopup(SelectPopupHideBehavior::kNormal); event.SetDefaultHandled(); return; }
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.cc b/third_party/blink/renderer/core/html/forms/html_select_element.cc index aa721745..ccb29e1 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_element.cc
@@ -1886,8 +1886,8 @@ select_type_->ShowPopup(PopupMenu::kOther); } -void HTMLSelectElement::HidePopup() { - select_type_->HidePopup(); +void HTMLSelectElement::HidePopup(SelectPopupHideBehavior behavior) { + select_type_->HidePopup(behavior); } PopupMenu* HTMLSelectElement::PopupForTesting() const {
diff --git a/third_party/blink/renderer/core/html/forms/html_select_element.h b/third_party/blink/renderer/core/html/forms/html_select_element.h index 15552e7..dc4c037 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_element.h
@@ -55,6 +55,11 @@ class HTMLSelectedContentElement; class SelectDescendantsObserver; +enum class SelectPopupHideBehavior { + kNormal, + kNoEventsOrFocusing, +}; + class CORE_EXPORT HTMLSelectElement final : public HTMLFormControlElementWithState, private TypeAheadDataSource { @@ -212,7 +217,7 @@ // the menulist mode. const ComputedStyle* OptionStyle() const; void ShowPopup(); - void HidePopup(); + void HidePopup(SelectPopupHideBehavior); PopupMenu* PopupForTesting() const; void ResetTypeAheadSessionForTesting();
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.cc b/third_party/blink/renderer/core/html/forms/range_input_type.cc index 224429f..e46d06f 100644 --- a/third_party/blink/renderer/core/html/forms/range_input_type.cc +++ b/third_party/blink/renderer/core/html/forms/range_input_type.cc
@@ -356,6 +356,11 @@ "The specified value %s cannot be parsed, or is out of range.", value); } +String RangeInputType::ValueNotEqualText(const Decimal& value) const { + return GetLocale().QueryString(IDS_FORM_VALIDATION_VALUE_NOT_EQUAL, + LocalizeValue(Serialize(value))); +} + String RangeInputType::RangeOverflowText(const Decimal& maximum) const { return GetLocale().QueryString(IDS_FORM_VALIDATION_RANGE_OVERFLOW, LocalizeValue(Serialize(maximum)));
diff --git a/third_party/blink/renderer/core/html/forms/range_input_type.h b/third_party/blink/renderer/core/html/forms/range_input_type.h index 044ab73..4af2e7d 100644 --- a/third_party/blink/renderer/core/html/forms/range_input_type.h +++ b/third_party/blink/renderer/core/html/forms/range_input_type.h
@@ -70,6 +70,7 @@ void SanitizeValueInResponseToMinOrMaxAttributeChange() override; void StepAttributeChanged() override; void WarnIfValueIsInvalid(const String&) const override; + String ValueNotEqualText(const Decimal& value) const override; String RangeOverflowText(const Decimal& maxmum) const override; String RangeUnderflowText(const Decimal& minimum) const override; String RangeInvalidText(const Decimal& minimum,
diff --git a/third_party/blink/renderer/core/html/forms/select_type.cc b/third_party/blink/renderer/core/html/forms/select_type.cc index 1f12278..9ab7851 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.cc +++ b/third_party/blink/renderer/core/html/forms/select_type.cc
@@ -58,6 +58,7 @@ #include "third_party/blink/renderer/core/html/shadow/shadow_element_names.h" #include "third_party/blink/renderer/core/input/event_handler.h" #include "third_party/blink/renderer/core/input/input_device_capabilities.h" +#include "third_party/blink/renderer/core/inspector/console_message.h" #include "third_party/blink/renderer/core/keywords.h" #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/page/autoscroll_controller.h" @@ -103,6 +104,14 @@ IsA<HTMLDivElement>(node); } +void PostChangingAppearanceConsoleWarning(HTMLSelectElement& select) { + select.AddConsoleMessage( + mojom::blink::ConsoleMessageSource::kJavaScript, + mojom::blink::ConsoleMessageLevel::kWarning, + "A customizable-<select> changed its `appearance` property while open. " + "As a result, it was closed to avoid circularity problems."); +} + class PopoverElementForAppearanceBase : public HTMLDivElement { public: explicit PopoverElementForAppearanceBase(Document& document) @@ -197,10 +206,36 @@ void DidRecalcStyle(const StyleRecalcChange change) override { HTMLDivElement::DidRecalcStyle(change); if (auto* style = GetComputedStyle()) { - if (style->EffectiveAppearance() == AppearanceValue::kBaseSelect) { + AppearanceState new_appearance_state = + style->EffectiveAppearance() == AppearanceValue::kBaseSelect + ? AppearanceState::kAppearanceBase + : AppearanceState::kAppearanceNotBase; + auto* select = ParentSelect(); + if (appearance_state_ != AppearanceState::kNoStyle && + appearance_state_ != new_appearance_state && select && + select->PopupIsVisible()) { + // The picker, as the result of CSS, changed `appearance` values upon + // opening. Per spec, we close it in that case, to avoid circularity. + PostChangingAppearanceConsoleWarning(*select); + // Post a task to close the popup, so we don't change style in the + // middle of style recalc. + GetDocument() + .GetTaskRunner(TaskType::kUserInteraction) + ->PostTask(FROM_HERE, + WTF::BindOnce( + [](HTMLSelectElement* select) { + select->HidePopup( + SelectPopupHideBehavior::kNoEventsOrFocusing); + }, + WrapPersistent(select))); + } + if (new_appearance_state == AppearanceState::kAppearanceBase) { UseCounter::Count(GetDocument(), WebFeature::kSelectElementPickerAppearanceBaseSelect); } + appearance_state_ = new_appearance_state; + } else { + appearance_state_ = AppearanceState::kNoStyle; } } @@ -214,6 +249,12 @@ } return nullptr; } + enum AppearanceState { + kNoStyle = 0, + kAppearanceBase = 1, + kAppearanceNotBase = 2, + }; + AppearanceState appearance_state_{AppearanceState::kNoStyle}; }; } // anonymous namespace @@ -253,7 +294,7 @@ const override; Element& InnerElement() const override; void ShowPopup(PopupMenu::ShowEventType type) override; - void HidePopup() override; + void HidePopup(SelectPopupHideBehavior) override; void PopupDidHide() override; bool PopupIsVisible() const override; PopupMenu* PopupForTesting() const override; @@ -463,7 +504,7 @@ !select_->IsDisabledFormControl()) { if (PopupIsVisible()) { if (!IsAppearanceBasePicker()) { - HidePopup(); + HidePopup(SelectPopupHideBehavior::kNormal); } } else { // Save the selection so it can be compared to the new selection @@ -720,6 +761,15 @@ if (IsAppearanceBasePicker()) { popover_->ShowPopoverInternal(select_, /*exception_state=*/nullptr); + if (!IsAppearanceBasePicker()) { + // The picker, as the result of CSS, changed `appearance` values upon + // opening. Per spec, we close it in that case, to avoid circularity. + PostChangingAppearanceConsoleWarning(*select_); + popover_->HidePopoverInternal( + HidePopoverFocusBehavior::kNone, + HidePopoverTransitionBehavior::kNoEventsNoWaiting, + /*exception_state=*/nullptr); + } return; } @@ -776,11 +826,15 @@ cache->DidShowMenuListPopup(select_); } -void MenuListSelectType::HidePopup() { +void MenuListSelectType::HidePopup(SelectPopupHideBehavior behavior) { if (IsAppearanceBasePicker()) { + bool normal_behavior = behavior == SelectPopupHideBehavior::kNormal; popover_->HidePopoverInternal( - HidePopoverFocusBehavior::kFocusPreviousElement, - HidePopoverTransitionBehavior::kFireEventsAndWaitForTransitions, + normal_behavior ? HidePopoverFocusBehavior::kFocusPreviousElement + : HidePopoverFocusBehavior::kNone, + normal_behavior + ? HidePopoverTransitionBehavior::kFireEventsAndWaitForTransitions + : HidePopoverTransitionBehavior::kNoEventsNoWaiting, /*exception_state=*/nullptr); return; } @@ -891,7 +945,7 @@ // want to hide the popover in the case that the user just opened it and we // focused the first option in it. if (native_popup_is_visible_) { - HidePopup(); + HidePopup(SelectPopupHideBehavior::kNormal); } } @@ -932,6 +986,13 @@ bool is_appearance_base_select = style->EffectiveAppearance() == AppearanceValue::kBaseSelect; if (is_appearance_base_select_ != is_appearance_base_select) { + if (PopupIsVisible()) { + // The picker, as the result of CSS, changed `appearance` values upon + // opening. Per spec, we close it in that case, to avoid circularity. + PostChangingAppearanceConsoleWarning(*select_); + HidePopup(SelectPopupHideBehavior::kNoEventsOrFocusing); + } + is_appearance_base_select_ = is_appearance_base_select; // Switching appearance needs layout to be rebuilt because of special // logic in LayoutFlexibleBox::IsChildAllowed which ignores children in @@ -1953,7 +2014,7 @@ NOTREACHED(); } -void SelectType::HidePopup() { +void SelectType::HidePopup(SelectPopupHideBehavior) { NOTREACHED(); }
diff --git a/third_party/blink/renderer/core/html/forms/select_type.h b/third_party/blink/renderer/core/html/forms/select_type.h index 810e2b1..5737393 100644 --- a/third_party/blink/renderer/core/html/forms/select_type.h +++ b/third_party/blink/renderer/core/html/forms/select_type.h
@@ -72,7 +72,7 @@ GetAutofillPreviewElement() const = 0; virtual Element& InnerElement() const; virtual void ShowPopup(PopupMenu::ShowEventType type); - virtual void HidePopup(); + virtual void HidePopup(SelectPopupHideBehavior); virtual void PopupDidHide(); virtual bool PopupIsVisible() const; virtual PopupMenu* PopupForTesting() const;
diff --git a/third_party/blink/renderer/core/html/html_dialog_element.cc b/third_party/blink/renderer/core/html/html_dialog_element.cc index 7681c3d..c2e5547 100644 --- a/third_party/blink/renderer/core/html/html_dialog_element.cc +++ b/third_party/blink/renderer/core/html/html_dialog_element.cc
@@ -142,7 +142,8 @@ } void HTMLDialogElement::close(const String& return_value, - bool ignore_open_attribute) { + bool ignore_open_attribute, + bool async_focus) { // https://html.spec.whatwg.org/C/#close-the-dialog if (is_closing_) { return; @@ -182,8 +183,6 @@ // We should call focus() last since it will fire a focus event which could // modify this element. if (previously_focused_element_) { - FocusOptions* focus_options = FocusOptions::Create(); - focus_options->setPreventScroll(true); Element* previously_focused_element = previously_focused_element_; previously_focused_element_ = nullptr; @@ -191,9 +190,25 @@ FlatTreeTraversal::IsDescendantOf( *GetDocument().FocusedElement(), *this); if (previously_focused_element && (was_modal || descendant_is_focused)) { - previously_focused_element->Focus(FocusParams( - SelectionBehaviorOnFocus::kNone, mojom::blink::FocusType::kScript, - nullptr, focus_options)); + auto focus_fn = [](Element* element) { + FocusOptions* focus_options = FocusOptions::Create(); + focus_options->setPreventScroll(true); + element->Focus(FocusParams(SelectionBehaviorOnFocus::kNone, + mojom::blink::FocusType::kScript, nullptr, + focus_options)); + }; + + if (async_focus) { + CHECK(RuntimeEnabledFeatures::DialogCloseWhenOpenRemovedEnabled()); + GetDocument() + .GetTaskRunner(TaskType::kDOMManipulation) + ->PostTask( + FROM_HERE, + WTF::BindOnce(focus_fn, + WrapWeakPersistent(previously_focused_element))); + } else { + focus_fn(previously_focused_element); + } } } @@ -702,15 +717,14 @@ !is_closing_) { // The open attribute has been removed explicitly, without calling close(). if (RuntimeEnabledFeatures::DialogCloseWhenOpenRemovedEnabled()) { - auto* console_message = MakeGarbageCollected<ConsoleMessage>( + AddConsoleMessage( mojom::blink::ConsoleMessageSource::kOther, mojom::blink::ConsoleMessageLevel::kWarning, "The open attribute was removed from a dialog element while it was " "open. This is not recommended. Please close it using the " "dialog.close() method instead."); - console_message->SetNodes(GetDocument().GetFrame(), {GetDomNodeId()}); - GetDocument().AddConsoleMessage(console_message); - close(/*return_value=*/String(), /*ignore_open_attribute=*/true); + close(/*return_value=*/String(), /*ignore_open_attribute=*/true, + /*async_focus=*/true); } else { GetDocument().AllOpenDialogs().erase(this); if (close_watcher_) {
diff --git a/third_party/blink/renderer/core/html/html_dialog_element.h b/third_party/blink/renderer/core/html/html_dialog_element.h index 4bb5d7c3..d01a628d 100644 --- a/third_party/blink/renderer/core/html/html_dialog_element.h +++ b/third_party/blink/renderer/core/html/html_dialog_element.h
@@ -53,8 +53,13 @@ void Trace(Visitor*) const override; + // ignore_open_attribute ensures that the closing steps are run even if the + // open attribute is removed by script. + // async_focus makes previously_focused_element_ get focused after waiting + // for a task instead of getting focused synchronously. void close(const String& return_value = String(), - bool ignore_open_attribute = false); + bool ignore_open_attribute = false, + bool async_focus = false); void requestClose(ExceptionState& exception_state) { requestClose(String(), exception_state); }
diff --git a/third_party/blink/renderer/core/html/html_image_element.idl b/third_party/blink/renderer/core/html/html_image_element.idl index 2c4624c..15977fa 100644 --- a/third_party/blink/renderer/core/html/html_image_element.idl +++ b/third_party/blink/renderer/core/html/html_image_element.idl
@@ -63,6 +63,9 @@ [MeasureAs=HTMLImageElementY] readonly attribute long y; [CallWith=ScriptState, RaisesException] Promise<undefined> decode(); + + // Topics API (https://github.com/patcg-individual-drafts/topics) + [RuntimeEnabled=TopicsImgAPI, SecureContext, CEReactions, Reflect] attribute boolean browsingTopics; }; HTMLImageElement includes HTMLAttributionSrcElementUtils;
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc index 7a3f6ed..f9274f3 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner.cc
@@ -369,6 +369,11 @@ request->SetSharedStorageWritableOptedIn(true); } + if (browsing_topics_attr_set_) { + DCHECK(is_img); + request->SetBrowsingTopicsEligible(true); + } + return request; } @@ -451,6 +456,8 @@ attributionsrc_attr_set_ = true; } else if (Match(attribute_name, html_names::kSharedstoragewritableAttr)) { shared_storage_writable_opted_in_ = true; + } else if (Match(attribute_name, html_names::kBrowsingtopicsAttr)) { + browsing_topics_attr_set_ = true; } else if (use_data_src_attr_match_for_image_ && Match(attribute_name, html_names::kDataSrcAttr) && img_src_url_.IsNull()) { @@ -818,6 +825,7 @@ const HashSet<String>* disabled_image_types_; bool attributionsrc_attr_set_ = false; bool shared_storage_writable_opted_in_ = false; + bool browsing_topics_attr_set_ = false; std::optional<float> resource_width_; std::optional<float> resource_height_; features::LcppPreloadLazyLoadImageType preload_lazy_load_image_type_;
diff --git a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc index a0df978..0e1fcfb 100644 --- a/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc +++ b/third_party/blink/renderer/core/html/parser/html_preload_scanner_test.cc
@@ -130,6 +130,13 @@ bool expected_shared_storage_writable_opted_in; }; +struct BrowsingTopicsWritableTestCase { + bool use_secure_document_url; + const char* base_url; + const char* input_html; + bool expected_browsing_topics; +}; + class HTMLMockHTMLResourcePreloader : public ResourcePreloader { public: explicit HTMLMockHTMLResourcePreloader(const KURL& document_url) @@ -309,6 +316,16 @@ resource->GetResourceRequest().GetSharedStorageWritableOptedIn()); } + void BrowsingTopicsRequestVerification(Document* document, + bool expected_browsing_topics) { + ASSERT_TRUE(preload_request_.get()); + Resource* resource = preload_request_->Start(document); + ASSERT_TRUE(resource); + + EXPECT_EQ(expected_browsing_topics, + resource->GetResourceRequest().GetBrowsingTopics()); + } + protected: void Preload(std::unique_ptr<PreloadRequest> preload_request) override { preload_request_ = std::move(preload_request); @@ -546,6 +563,20 @@ &GetDocument(), test_case.expected_shared_storage_writable_opted_in); } + void Test(BrowsingTopicsWritableTestCase test_case) { + SCOPED_TRACE(base::StringPrintf("Use secure doc URL: %d; HTML: '%s'", + test_case.use_secure_document_url, + test_case.input_html)); + + HTMLMockHTMLResourcePreloader preloader(GetDocument().Url()); + KURL base_url(test_case.base_url); + scanner_->AppendToEnd(String(test_case.input_html)); + std::unique_ptr<PendingPreloadData> preload_data = scanner_->Scan(base_url); + preloader.TakePreloadData(std::move(preload_data)); + preloader.BrowsingTopicsRequestVerification( + &GetDocument(), test_case.expected_browsing_topics); + } + private: std::unique_ptr<HTMLPreloadScanner> scanner_; }; @@ -1990,4 +2021,42 @@ } } +TEST_F(HTMLPreloadScannerTest, testBrowsingTopics) { + WebRuntimeFeaturesBase::EnableTopicsAPI(true); + static constexpr bool kSecureDocumentUrl = true; + static constexpr bool kInsecureDocumentUrl = false; + + static constexpr char kSecureBaseURL[] = "https://example.test"; + static constexpr char kInsecureBaseURL[] = "http://example.test"; + + BrowsingTopicsWritableTestCase test_cases[] = { + // Insecure context + {kInsecureDocumentUrl, kSecureBaseURL, + "<img src='/image' browsingtopics>", + /*expected_browsing_topics=*/false}, + // No browsingtopics attribute + {kSecureDocumentUrl, kSecureBaseURL, "<img src='/image'>", + /*expected_browsing_topics=*/false}, + // Irrelevant element type + {kSecureDocumentUrl, kSecureBaseURL, + "<video poster='/image' browsingtopics>", + /*expected_browsing_topics=*/false}, + // Secure context, browsingtopics attribute + // Base (initial) URL does not affect SharedStorageWritable eligibility + {kSecureDocumentUrl, kInsecureBaseURL, + "<img src='/image' browsingtopics>", + /*expected_browsing_topics=*/true}, + // Secure context, browsingtopics attribute + {kSecureDocumentUrl, kSecureBaseURL, "<img src='/image' browsingtopics>", + /*expected_browsing_topics=*/true}, + }; + + for (const auto& test_case : test_cases) { + RunSetUp(kViewportDisabled, kPreloadEnabled, + network::mojom::ReferrerPolicy::kDefault, + /*use_secure_document_url=*/test_case.use_secure_document_url); + Test(test_case); + } +} + } // namespace blink
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.cc b/third_party/blink/renderer/core/html/parser/preload_request.cc index 2f5b013..848b9fd 100644 --- a/third_party/blink/renderer/core/html/parser/preload_request.cc +++ b/third_party/blink/renderer/core/html/parser/preload_request.cc
@@ -140,6 +140,12 @@ UseCounter::Count(document, WebFeature::kSharedStorageAPI_Image_Attribute); } + bool browsing_topics = + browsing_topics_eligible_ && RuntimeEnabledFeatures::TopicsAPIEnabled() && + document->domWindow()->IsSecureContext() && + !document->domWindow()->GetSecurityOrigin()->IsOpaque(); + resource_request.SetBrowsingTopics(browsing_topics); + ResourceLoaderOptions options(document->domWindow()->GetCurrentWorld()); options.initiator_info = initiator_info; FetchParameters params(std::move(resource_request), options);
diff --git a/third_party/blink/renderer/core/html/parser/preload_request.h b/third_party/blink/renderer/core/html/parser/preload_request.h index f195db6d..11bbb15f 100644 --- a/third_party/blink/renderer/core/html/parser/preload_request.h +++ b/third_party/blink/renderer/core/html/parser/preload_request.h
@@ -159,6 +159,14 @@ shared_storage_writable_opted_in_ = opted_in; } + // Set whether the preload request is eligible for the Browsing Topics API. + // + // See https://github.com/patcg-individual-drafts/topics/blob/main/README.md + // for the latest version of the Topics API explainer. + void SetBrowsingTopicsEligible(bool flag) { + browsing_topics_eligible_ = flag; + } + bool IsPotentiallyLCPElement() const { return is_potentially_lcp_element_; } bool IsPotentiallyLCPInfluencer() const { @@ -217,6 +225,7 @@ bool is_potentially_lcp_element_ = false; bool is_potentially_lcp_influencer_ = false; bool shared_storage_writable_opted_in_ = false; + bool browsing_topics_eligible_ = false; }; typedef Vector<std::unique_ptr<PreloadRequest>> PreloadRequestStream;
diff --git a/third_party/blink/renderer/core/html/resources/customizable_select.css b/third_party/blink/renderer/core/html/resources/customizable_select.css index 9a99f24..cc06e73 100644 --- a/third_party/blink/renderer/core/html/resources/customizable_select.css +++ b/third_party/blink/renderer/core/html/resources/customizable_select.css
@@ -30,8 +30,9 @@ display: -internal-appearance-auto-base-select(inline-block, inline-flex); gap: -internal-appearance-auto-base-select(initial, 0.5em); border-radius: -internal-appearance-auto-base-select(0, 0.5em); - align-items: -internal-appearance-auto-base-select(center, unset); + /* https://github.com/whatwg/html/issues/10876 */ + user-select: -internal-appearance-auto-base-select(auto, none); } select:not(:-internal-list-box) > button:first-child {
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mobile.cc b/third_party/blink/renderer/core/layout/layout_theme_mobile.cc index afa1a94..8c54617 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mobile.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_mobile.cc
@@ -35,6 +35,15 @@ namespace blink { +Color LayoutThemeMobile::active_selection_background_color_ = + LayoutThemeMobile::kDefaultActiveSelectionBackgroundColor; +Color LayoutThemeMobile::active_selection_foreground_color_ = + LayoutThemeMobile::kDefaultActiveSelectionForegroundColor; +Color LayoutThemeMobile::inactive_selection_background_color_ = + Color::FromRGBA32(kDefaultInactiveSelectionBgColor); +Color LayoutThemeMobile::inactive_selection_foreground_color_ = + Color::FromRGBA32(kDefaultInactiveSelectionFgColor); + scoped_refptr<LayoutTheme> LayoutThemeMobile::Create() { return base::AdoptRef(new LayoutThemeMobile()); } @@ -61,4 +70,58 @@ LayoutThemeDefault::AdjustInnerSpinButtonStyle(builder); } +Color LayoutThemeMobile::PlatformActiveSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const { + return LayoutThemeMobile::active_selection_foreground_color_; +} + +Color LayoutThemeMobile::PlatformActiveSelectionBackgroundColor( + mojom::blink::ColorScheme color_scheme) const { + return LayoutThemeMobile::active_selection_background_color_; +} + +Color LayoutThemeMobile::PlatformInactiveSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const { + return LayoutThemeMobile::inactive_selection_foreground_color_; +} + +Color LayoutThemeMobile::PlatformInactiveSelectionBackgroundColor( + mojom::blink::ColorScheme color_scheme) const { + return LayoutThemeMobile::inactive_selection_background_color_; +} + +void LayoutThemeMobile::SetSelectionColors(Color active_background_color, + Color active_foreground_color, + Color inactive_background_color, + Color inactive_foreground_color) { + bool selection_colors_updated = false; + if (active_selection_background_color_ != active_background_color || + active_selection_foreground_color_ != active_foreground_color || + inactive_selection_background_color_ != inactive_background_color || + inactive_selection_foreground_color_ != inactive_foreground_color) { + active_selection_background_color_ = active_background_color; + active_selection_foreground_color_ = active_foreground_color; + inactive_selection_background_color_ = inactive_background_color; + inactive_selection_foreground_color_ = inactive_foreground_color; + selection_colors_updated = true; + } + // SetSelectionColors is expected to affect both default and mobile layout + // theme. Update the default layout theme selection color if an update is + // needed. Only run PlatformColorsDidChange when needed to minimize the + // recalculation. + if (LayoutThemeDefault::PlatformActiveSelectionBackgroundColor( + mojom::blink::ColorScheme::kLight) != active_background_color || + LayoutThemeDefault::PlatformActiveSelectionForegroundColor( + mojom::blink::ColorScheme::kLight) != active_foreground_color || + LayoutThemeDefault::PlatformInactiveSelectionBackgroundColor( + mojom::blink::ColorScheme::kLight) != inactive_background_color || + LayoutThemeDefault::PlatformInactiveSelectionForegroundColor( + mojom::blink::ColorScheme::kLight) != inactive_foreground_color) { + LayoutThemeDefault::SetSelectionColors( + active_background_color, active_foreground_color, + inactive_background_color, inactive_foreground_color); + } else if (selection_colors_updated) { + PlatformColorsDidChange(); + } +} } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_theme_mobile.h b/third_party/blink/renderer/core/layout/layout_theme_mobile.h index ab0d5a6..a7e25e4e 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_mobile.h +++ b/third_party/blink/renderer/core/layout/layout_theme_mobile.h
@@ -43,19 +43,37 @@ return LayoutThemeMobile::kDefaultTapHighlightColor; } + Color PlatformActiveSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const override; + Color PlatformActiveSelectionBackgroundColor( - mojom::blink::ColorScheme color_scheme) const override { - return LayoutThemeMobile::kDefaultActiveSelectionBackgroundColor; - } + mojom::blink::ColorScheme color_scheme) const override; + + Color PlatformInactiveSelectionForegroundColor( + mojom::blink::ColorScheme color_scheme) const override; + + Color PlatformInactiveSelectionBackgroundColor( + mojom::blink::ColorScheme color_scheme) const override; + + void SetSelectionColors(Color active_background_color, + Color active_foreground_color, + Color inactive_background_color, + Color inactive_foreground_color) override; protected: ~LayoutThemeMobile() override; private: + static Color active_selection_background_color_; + static Color active_selection_foreground_color_; + static Color inactive_selection_background_color_; + static Color inactive_selection_foreground_color_; static constexpr Color kDefaultTapHighlightColor = Color::FromRGBA32(0x6633b5e5); static constexpr Color kDefaultActiveSelectionBackgroundColor = Color::FromRGBA32(0x6633b5e5); + static constexpr Color kDefaultActiveSelectionForegroundColor = + Color::FromRGBA32(0xFF000000); }; } // namespace blink
diff --git a/third_party/blink/renderer/core/layout/layout_theme_test.cc b/third_party/blink/renderer/core/layout/layout_theme_test.cc index f0de70d..c163417 100644 --- a/third_party/blink/renderer/core/layout/layout_theme_test.cc +++ b/third_party/blink/renderer/core/layout/layout_theme_test.cc
@@ -155,4 +155,15 @@ } #endif // !BUILDFLAG(IS_MAC) +#if BUILDFLAG(IS_ANDROID) +TEST_F(LayoutThemeTest, AndroidSelectionColor) { + EXPECT_EQ(Color::FromRGBA32(0xFF000000), + LayoutTheme::GetTheme().ActiveSelectionForegroundColor( + mojom::blink::ColorScheme::kLight)); + EXPECT_EQ(Color::FromRGBA32(0x6633b5e5), + LayoutTheme::GetTheme().ActiveSelectionBackgroundColor( + mojom::blink::ColorScheme::kLight)); +} +#endif // BUILDFLAG(IS_ANDROID) + } // namespace blink
diff --git a/third_party/blink/renderer/core/loader/image_loader.cc b/third_party/blink/renderer/core/loader/image_loader.cc index 402a7c3b..1ca92c4 100644 --- a/third_party/blink/renderer/core/loader/image_loader.cc +++ b/third_party/blink/renderer/core/loader/image_loader.cc
@@ -507,6 +507,14 @@ !SecurityOrigin::Create(url)->IsOpaque(); resource_request.SetSharedStorageWritableOptedIn( shared_storage_writable_opted_in); + if (GetElement()->FastHasAttribute(html_names::kBrowsingtopicsAttr) && + RuntimeEnabledFeatures::TopicsAPIEnabled( + GetElement()->GetExecutionContext()) && + GetElement()->GetExecutionContext()->IsSecureContext()) { + resource_request.SetBrowsingTopics(true); + UseCounter::Count(document, mojom::blink::WebFeature::kTopicsAPIImg); + UseCounter::Count(document, mojom::blink::WebFeature::kTopicsAPIAll); + } } bool page_is_being_dismissed =
diff --git a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc index 91d2aaf..6cbb8ea1 100644 --- a/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc +++ b/third_party/blink/renderer/core/paint/timing/image_paint_timing_detector.cc
@@ -27,6 +27,7 @@ #include "third_party/blink/renderer/platform/heap/thread_state.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/trace_event.h" #include "third_party/blink/renderer/platform/instrumentation/tracing/traced_value.h" +#include "third_party/blink/renderer/platform/runtime_enabled_features.h" namespace blink { @@ -275,8 +276,8 @@ // TODO(crbug.com/364860066): When cleaning up the flag, remove this whole // block. This re-enables the old behavior where animated images were not // reported until fully loaded. - if (!record->loaded && !base::FeatureList::IsEnabled( - features::kReportFirstFrameTimeAsRenderTime)) { + if (!record->loaded && + !RuntimeEnabledFeatures::ReportFirstFrameTimeAsRenderTimeEnabled()) { continue; } @@ -483,8 +484,7 @@ // ImageRecord object. record->first_animated_frame_time = record->media_timing->GetFirstVideoFrameTime(); - if (base::FeatureList::IsEnabled( - features::kReportFirstFrameTimeAsRenderTime)) { + if (RuntimeEnabledFeatures::ReportFirstFrameTimeAsRenderTimeEnabled()) { record->paint_time = record->first_animated_frame_time; // TODO(crbug.com/383568320): this timestamp it not specified, and it's
diff --git a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 index 80431fa..9fcab86 100644 --- a/third_party/blink/renderer/core/style/computed_style_extra_fields.json5 +++ b/third_party/blink/renderer/core/style/computed_style_extra_fields.json5
@@ -156,6 +156,15 @@ default_value: "false", custom_compare: true, }, + // True when at least one env(safe-area-inset-bottom) was resolved + // when producing this ComputedStyle. + { + name: "HasEnvSafeAreaInsetBottom", + field_group: "*", + field_template: "monotonic_flag", + default_value: "false", + custom_compare: true, + }, // Set on parent style when a child explicitly inherits a // non-inherited property { @@ -1351,17 +1360,6 @@ field_group: "*", default_value: "false", invalidate: ["layout"] - }, - // Returns true if any property references the value of - // env(safe-area-inset-bottom). This is used by the Browser - // to decide if dynamic safe area insets should be used in the UX. - { - name: "ReferencesSafeAreaInsetBottom", - inherited: false, - field_template: "primitive", - type_name: "bool", - field_group: "*", - default_value: "false" } ], }
diff --git a/third_party/blink/renderer/core/style/computed_style_test.cc b/third_party/blink/renderer/core/style/computed_style_test.cc index 565162b..aa23700 100644 --- a/third_party/blink/renderer/core/style/computed_style_test.cc +++ b/third_party/blink/renderer/core/style/computed_style_test.cc
@@ -2244,7 +2244,7 @@ EXPECT_TRUE(StyleForElement("t6").IsBottomRelativeToSafeAreaInset()); } -TEST_F(ComputedStyleTest, ReferencesSafeAreaInsetBottom) { +TEST_F(ComputedStyleTest, HasEnvSafeAreaInsetBottom) { Document& document = GetDocument(); document.body()->setInnerHTML(R"HTML( <div id="f1" style="bottom: 5px"></div> @@ -2265,21 +2265,21 @@ )HTML"); document.View()->UpdateAllLifecyclePhasesForTest(); - EXPECT_FALSE(StyleForElement("f1").ReferencesSafeAreaInsetBottom()); - EXPECT_FALSE(StyleForElement("f2").ReferencesSafeAreaInsetBottom()); - EXPECT_FALSE(StyleForElement("f3").ReferencesSafeAreaInsetBottom()); - EXPECT_FALSE(StyleForElement("f4").ReferencesSafeAreaInsetBottom()); - EXPECT_FALSE(StyleForElement("f5").ReferencesSafeAreaInsetBottom()); - EXPECT_FALSE(StyleForElement("f6").ReferencesSafeAreaInsetBottom()); - EXPECT_FALSE(StyleForElement("f7").ReferencesSafeAreaInsetBottom()); - EXPECT_FALSE(StyleForElement("f8").ReferencesSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f1").HasEnvSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f2").HasEnvSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f3").HasEnvSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f4").HasEnvSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f5").HasEnvSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f6").HasEnvSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f7").HasEnvSafeAreaInsetBottom()); + EXPECT_FALSE(StyleForElement("f8").HasEnvSafeAreaInsetBottom()); - EXPECT_TRUE(StyleForElement("t1").ReferencesSafeAreaInsetBottom()); - EXPECT_TRUE(StyleForElement("t2").ReferencesSafeAreaInsetBottom()); - EXPECT_TRUE(StyleForElement("t3").ReferencesSafeAreaInsetBottom()); - EXPECT_TRUE(StyleForElement("t4").ReferencesSafeAreaInsetBottom()); - EXPECT_TRUE(StyleForElement("t5").ReferencesSafeAreaInsetBottom()); - EXPECT_TRUE(StyleForElement("t6").ReferencesSafeAreaInsetBottom()); + EXPECT_TRUE(StyleForElement("t1").HasEnvSafeAreaInsetBottom()); + EXPECT_TRUE(StyleForElement("t2").HasEnvSafeAreaInsetBottom()); + EXPECT_TRUE(StyleForElement("t3").HasEnvSafeAreaInsetBottom()); + EXPECT_TRUE(StyleForElement("t4").HasEnvSafeAreaInsetBottom()); + EXPECT_TRUE(StyleForElement("t5").HasEnvSafeAreaInsetBottom()); + EXPECT_TRUE(StyleForElement("t6").HasEnvSafeAreaInsetBottom()); } } // namespace blink
diff --git a/third_party/blink/renderer/core/timing/performance_event_timing.h b/third_party/blink/renderer/core/timing/performance_event_timing.h index e17e3706..4c46332 100644 --- a/third_party/blink/renderer/core/timing/performance_event_timing.h +++ b/third_party/blink/renderer/core/timing/performance_event_timing.h
@@ -69,6 +69,12 @@ std::optional<PointerId> pointer_id = std::nullopt; bool prevent_counting_as_interaction = false; + + // Set to true when the event's processing time is fully nested under + // another event's processing time, e.g. some synthetic events are + // dispatched with the input events, beforeinput event's processing time is + // nested under keypress event. + bool is_processing_fully_nested_in_another_event = false; }; static PerformanceEventTiming* Create(const AtomicString& event_type,
diff --git a/third_party/blink/renderer/core/timing/window_performance.cc b/third_party/blink/renderer/core/timing/window_performance.cc index 8b1f2a6..d07cd7e2 100644 --- a/third_party/blink/renderer/core/timing/window_performance.cc +++ b/third_party/blink/renderer/core/timing/window_performance.cc
@@ -197,6 +197,22 @@ type == event_type_names::kInput; } +base::TimeDelta TotalNonOverlappingProcessingDuration( + HeapVector<Member<PerformanceEventTiming>> event_timing_entries) { + base::TimeDelta processing_duration; + for (auto entry : event_timing_entries) { + const auto& processing_start_time = + entry->GetEventTimingReportingInfo()->processing_start_time; + const auto& processing_end_time = + entry->GetEventTimingReportingInfo()->processing_end_time; + if (!entry->GetEventTimingReportingInfo() + ->is_processing_fully_nested_in_another_event) { + processing_duration += processing_end_time - processing_start_time; + } + } + return processing_duration; +} + } // namespace constexpr size_t kDefaultVisibilityStateEntrySize = 50; @@ -208,6 +224,14 @@ const char kHistogramEventCreationTimeToEventQueueTimePerAnimationFrame[] = "Blink.Responsiveness.PerAnimationFrame.EventCreationTimeToEventQueueTime"; +const char + kHistogramFirstProcessingStartToLastProcessingEndPerAnimationFrame[] = + "Blink.Responsiveness.PerAnimationFrame." + "FirstProcessingStartToLastProcessingEnd"; +const char kHistogramTotalUnaccountedEventProcessingTimePerAnimationFrame[] = + "Blink.Responsiveness.PerAnimationFrame." + "TotalUnaccountedEventProcessingTime"; + const char kHistogramProcessingEndToRenderStartTimePerAnimationFrame[] = "Blink.Responsiveness.PerAnimationFrame.ProcessingEndToRenderStartTime"; const char kHistogramRenderStartTimeToCommitTimePerAnimationFrame[] = @@ -627,6 +651,18 @@ CHECK(reporting_info); reporting_info->processing_end_time = processing_end; + if (auto pre_iter = std::next(iter); + pre_iter != event_timing_entries_.rend()) { + auto iter_null_time = std::find_if( + event_timing_entries_.begin(), pre_iter.base(), [](const auto& event) { + return event->GetEventTimingReportingInfo() + ->processing_end_time.is_null(); + }); + if (iter_null_time != pre_iter.base()) { + reporting_info->is_processing_fully_nested_in_another_event = true; + } + } + // "Artificial" pointerup events will re-use the same timestamp as the // pointerdown, leading to large delays. crbug.com/1321819. if ((event_type == event_type_names::kPointerup || @@ -957,6 +993,23 @@ first_event_enqueued_to_main_thread_time, base::Milliseconds(1), base::Seconds(60), 50); + // Event Processing duration breakdown. + base::TimeDelta total_processing_duration = + last_event_processing_end_time - first_event_processing_start; + UMA_HISTOGRAM_CUSTOM_TIMES( + kHistogramFirstProcessingStartToLastProcessingEndPerAnimationFrame, + total_processing_duration, base::Milliseconds(1), base::Seconds(60), + 50); + + base::TimeDelta total_accountable_processing_duration = + TotalNonOverlappingProcessingDuration(event_timing_entries_); + base::TimeDelta total_unaccountable_processing_duration = + total_processing_duration - total_accountable_processing_duration; + UMA_HISTOGRAM_CUSTOM_TIMES( + kHistogramTotalUnaccountedEventProcessingTimePerAnimationFrame, + total_unaccountable_processing_duration, base::Milliseconds(1), + base::Seconds(60), 50); + // Presentation delay breakdown. if (!last_event_presentation_time.is_null() && !last_event_commit_finish_time.is_null() && @@ -1007,7 +1060,6 @@ CHECK(!processing_end.is_null()); CHECK(!event_end_time.is_null()); - // Round to 8ms. int rounded_duration = std::round((event_end_time - event_creation_time).InMillisecondsF() / 8) *
diff --git a/third_party/blink/renderer/core/timing/window_performance_test.cc b/third_party/blink/renderer/core/timing/window_performance_test.cc index fa8cdb92..9152b09 100644 --- a/third_party/blink/renderer/core/timing/window_performance_test.cc +++ b/third_party/blink/renderer/core/timing/window_performance_test.cc
@@ -562,6 +562,48 @@ } } +// Test whether we can detect that the event is fully nested in another event +// during the processing time. +TEST_P(WindowPerformanceTest, NestedEventInProcessingTime) { + RegisterKeyboardEvent(event_type_names::kKeydown, GetTimeOrigin(), + GetTimeOrigin() + base::Milliseconds(1), + GetTimeOrigin() + base::Milliseconds(2), 4); + KeyboardEventInit* init = KeyboardEventInit::Create(); + init->setKeyCode(4); + KeyboardEvent* keyboard_event = MakeGarbageCollected<KeyboardEvent>( + event_type_names::kKeypress, init, GetTimeOrigin()); + performance_->EventTimingProcessingStart( + *keyboard_event, GetTimeOrigin() + base::Milliseconds(1), nullptr); + + UIEventInit* event_init = UIEventInit::Create(); + event_init->setBubbles(true); + event_init->setCancelable(false); + event_init->setComposed(true); + UIEvent* event = MakeGarbageCollected<UIEvent>(event_type_names::kBeforeinput, + event_init, GetTimeOrigin()); + performance_->EventTimingProcessingStart( + *event, GetTimeOrigin() + base::Milliseconds(2), nullptr); + + performance_->EventTimingProcessingEnd( + *event, GetTimeOrigin() + base::Milliseconds(4)); + performance_->EventTimingProcessingEnd( + *keyboard_event, GetTimeOrigin() + base::Milliseconds(5)); + + base::TimeTicks presentation_time = GetTimeOrigin() + base::Seconds(6.0); + SimulatePaintAndResolvePresentationPromise(presentation_time); + const auto& entries = + performance_->getBufferedEntriesByType(performance_entry_names::kEvent); + EXPECT_EQ(3u, entries.size()); + EXPECT_EQ(event_type_names::kKeydown, entries.at(0)->name()); + EXPECT_EQ(event_type_names::kKeypress, entries.at(1)->name()); + + PerformanceEventTiming* entry = + static_cast<PerformanceEventTiming*>(entries.at(2).Get()); + EXPECT_EQ(event_type_names::kBeforeinput, entry->name()); + EXPECT_TRUE(entry->GetEventTimingReportingInfo() + ->is_processing_fully_nested_in_another_event); +} + // Test that the 'first-input' is populated after some irrelevant events are // ignored. TEST_P(WindowPerformanceTest, FirstInputAfterIgnored) {
diff --git a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc index 7ff0bcf..b64ce55 100644 --- a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc +++ b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent.cc
@@ -145,6 +145,13 @@ void AddAnnotatedRoles( const LayoutObject& object, Vector<mojom::blink::AIPageContentAnnotatedRole>& annotated_roles) { + const auto& style = object.StyleRef(); + if (style.ContentVisibility() == EContentVisibility::kHidden) { + annotated_roles.push_back( + mojom::blink::AIPageContentAnnotatedRole::kContentHidden); + } + + // Element specific roles below. const auto* element = DynamicTo<HTMLElement>(object.GetNode()); if (!element) { return;
diff --git a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc index 1ad6e689..a993576 100644 --- a/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc +++ b/third_party/blink/renderer/modules/content_extraction/ai_page_content_agent_unittest.cc
@@ -170,6 +170,16 @@ EXPECT_EQ(attributes.annotated_roles[0], expected_role); } + void CheckAnnotatedRoles( + const mojom::blink::AIPageContentNode& node, + const std::vector<mojom::blink::AIPageContentAnnotatedRole>& + expected_roles) { + const auto& attributes = *node.content_attributes; + ASSERT_EQ(attributes.annotated_roles.size(), expected_roles.size()); + EXPECT_THAT(attributes.annotated_roles, + testing::UnorderedElementsAreArray(expected_roles)); + } + void CheckGeometry(const mojom::blink::AIPageContentNode& node, const gfx::Rect& expected_outer_bounding_box, const gfx::Rect& expected_visible_bounding_box) { @@ -1342,7 +1352,13 @@ ASSERT_TRUE(content->root_node); const auto& root = *content->root_node; - EXPECT_TRUE(root.children_nodes.empty()); + EXPECT_EQ(root.children_nodes.size(), 1u); + + const auto& hidden_container = *root.children_nodes[0]; + CheckContainerNode(hidden_container); + CheckAnnotatedRole(hidden_container, + mojom::blink::AIPageContentAnnotatedRole::kContentHidden); + EXPECT_TRUE(hidden_container.children_nodes.empty()); } TEST_F(AIPageContentAgentTest, ContentVisibilityAuto) { @@ -1409,8 +1425,10 @@ const auto& hidden_container = *root.children_nodes[0]; CheckContainerNode(hidden_container); - CheckAnnotatedRole(hidden_container, - mojom::blink::AIPageContentAnnotatedRole::kHeader); + CheckAnnotatedRoles( + hidden_container, + {mojom::blink::AIPageContentAnnotatedRole::kHeader, + mojom::blink::AIPageContentAnnotatedRole::kContentHidden}); EXPECT_EQ(hidden_container.children_nodes.size(), 1u); // The hidden container continues to have an empty layout size even when @@ -1475,7 +1493,14 @@ EXPECT_EQ(iframe_node.children_nodes.size(), 1u); const auto& iframe_root = *iframe_node.children_nodes[0]; - const auto& hidden_text_node = *iframe_root.children_nodes[0]; + EXPECT_EQ(iframe_root.children_nodes.size(), 1u); + const auto& hidden_container = *iframe_root.children_nodes[0]; + CheckContainerNode(hidden_container); + CheckAnnotatedRole(hidden_container, + mojom::blink::AIPageContentAnnotatedRole::kContentHidden); + EXPECT_EQ(hidden_container.children_nodes.size(), 1u); + + const auto& hidden_text_node = *hidden_container.children_nodes[0]; CheckTextNode(hidden_text_node, "hidden text"); ASSERT_TRUE(hidden_text_node.content_attributes->geometry); const auto& hidden_text_geometry = @@ -1525,5 +1550,51 @@ EXPECT_TRUE(hidden_text_geometry.visible_bounding_box.IsEmpty()); } +TEST_F(AIPageContentAgentTest, LineBreak) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + "<div style=\"width: 100px; height:100px\">" + "Lorem Ipsum is simply dummy text of the printing and " + "typesetting industry.<br>Lorem Ipsum has been the " + "industry's standard dummy text ever since the 1500s, " + "when an unknown printer took a galley of type and " + "scrambled it to make a type specimen book. It has " + "survived not only five centuries, but also the leap " + "into electronic typesetting, remaining essentially " + "unchanged. It was popularised in the 1960s with the " + "release of Letraset sheets containing Lorem Ipsum " + "passages, and more recently with desktop publishing " + "software like Aldus PageMaker including versions of " + "Lorem Ipsum." + "</div>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + auto* agent = AIPageContentAgent::GetOrCreateForTesting( + *helper_.LocalMainFrame()->GetFrame()->GetDocument()); + ASSERT_TRUE(agent); + + auto content = agent->GetAIPageContentSync(); + ASSERT_TRUE(content); + ASSERT_TRUE(content->root_node); + + const auto& root = *content->root_node; + EXPECT_EQ(root.children_nodes.size(), 2u); + CheckTextNode(*root.children_nodes[0], + "Lorem Ipsum is simply dummy text of the printing and " + "typesetting industry."); + CheckTextNode( + *root.children_nodes[1], + "Lorem Ipsum has been the industry's standard dummy text ever since the " + "1500s, when an unknown printer took a galley of type and scrambled it " + "to make a type specimen book. It has survived not only five centuries, " + "but also the leap into electronic typesetting, remaining essentially " + "unchanged. It was popularised in the 1960s with the release of Letraset " + "sheets containing Lorem Ipsum passages, and more recently with desktop " + "publishing software like Aldus PageMaker including versions of Lorem " + "Ipsum."); +} + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 406474f3..c7a589a 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -1833,6 +1833,13 @@ browser_process_read_access: true, }, { + name: "FedCmLightweightMode", + depends_on: ["FedCmIdpSigninStatus"], + status: "test", + public: true, + base_feature: "none", + }, + { name: "FedCmMultipleIdentityProviders", depends_on: ["FedCm"], base_feature: "none", @@ -3575,6 +3582,10 @@ status: "stable", }, { + name: "ReportFirstFrameTimeAsRenderTime", + status: "test", + }, + { name: "ResetInputTypeToNoneBeforeCharacterInput", status: "stable", }, @@ -4297,6 +4308,14 @@ public: true, status: "stable", }, + { + // This feature allows calling the Topics API via an image + // attribute. + name: "TopicsImgAPI", + base_feature: "none", + public: true, + status: "experimental", + }, // This is a killswitch for the behavior where popover.showPopover() and // dialog.showModal() throw DOM exceptions if the document isn't active. // This landed in M132, and can be removed in M134.
diff --git a/third_party/blink/renderer/platform/wtf/text/wtf_string.cc b/third_party/blink/renderer/platform/wtf/text/wtf_string.cc index 0eab915..eee9bbf2 100644 --- a/third_party/blink/renderer/platform/wtf/text/wtf_string.cc +++ b/third_party/blink/renderer/platform/wtf/text/wtf_string.cc
@@ -31,7 +31,7 @@ #include "base/functional/callback.h" #include "base/logging.h" #include "base/numerics/safe_conversions.h" -#include "base/strings/string_util.h" +#include "base/strings/span_printf.h" #include "build/build_config.h" #include "third_party/blink/renderer/platform/wtf/dtoa.h" #include "third_party/blink/renderer/platform/wtf/math_extras.h" @@ -205,7 +205,7 @@ Vector<char, kDefaultSize> buffer(kDefaultSize); va_start(args, format); - int length = base::vsnprintf(buffer.data(), buffer.size(), format, args); + int length = base::VSpanPrintf(buffer, format, args); va_end(args); // TODO(esprehn): This can only happen if there's an encoding error, what's @@ -226,7 +226,7 @@ // Not calling va_end/va_start here happens to work on lots of systems, but // fails e.g. on 64bit Linux. va_start(args, format); - length = base::vsnprintf(buffer.data(), buffer.size(), format, args); + length = base::VSpanPrintf(buffer, format, args); va_end(args); }
diff --git a/third_party/blink/web_tests/MSANExpectations b/third_party/blink/web_tests/MSANExpectations index 428783a..7e848b6 100644 --- a/third_party/blink/web_tests/MSANExpectations +++ b/third_party/blink/web_tests/MSANExpectations
@@ -114,6 +114,8 @@ crbug.com/1378044 [ Linux ] external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/basic.any.sharedworker.html [ Timeout ] crbug.com/1378044 [ Linux ] external/wpt/html/semantics/scripting-1/the-script-element/module/dynamic-import/microtasks/basic.any.worker.html [ Timeout ] +# Slow on MSAN +crbug.com/386487960 external/wpt/dom/nodes/Element-classlist.html [ Pass Timeout ] crbug.com/1457275 [ Linux ] external/wpt/dom/ranges/Range-surroundContents.html [ Skip ]
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index f00cb753..8498206 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2707,6 +2707,13 @@ crbug.com/383880384 [ Win ] external/wpt/css/css-properties-values-api/registered-property-change-style-002.html [ Failure Pass ] # ====== New tests from wpt-importer added here ====== +crbug.com/387777047 external/wpt/css/css-align/blocks/align-content-block-012.html [ Failure ] +crbug.com/387626415 external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-not-propagated-to-root.html [ Failure ] +crbug.com/387378127 external/wpt/css/css-scoping/host-multiple-002.html [ Failure ] +crbug.com/387378127 external/wpt/css/css-scoping/host-multiple-005.html [ Failure ] +crbug.com/387378127 external/wpt/css/css-scoping/host-multiple-006.html [ Failure ] +crbug.com/387378128 external/wpt/css/css-text/line-breaking/segment-break-transformation-punctuation-001.html [ Failure ] +crbug.com/387626415 virtual/threaded/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-not-propagated-to-root.html [ Failure ] crbug.com/386860174 [ Win10.20h2 ] external/wpt/css/css-fonts/parsing/font-weight-computed.html [ Crash ] crbug.com/386860174 [ Mac14 ] external/wpt/css/css-fonts/parsing/font-weight-computed.html [ Crash ] crbug.com/386860174 [ Linux ] external/wpt/css/css-fonts/parsing/font-weight-computed.html [ Crash ] @@ -6103,8 +6110,9 @@ crbug.com/384009734 external/wpt/html/semantics/links/links-created-by-a-and-area-elements/target_blank_useractivation_multi_globals.html [ Timeout ] crbug.com/384009734 external/wpt/html/semantics/forms/form-submission-target/form-target-blank-useractivation-multi-globals.html [ Timeout ] crbug.com/384009734 external/wpt/html/browsers/browsing-the-web/navigating-across-documents/cross-origin-top-navigation-with-user-activation-in-parent.window.html [ Timeout ] -crbug.com/384050894 external/wpt/partitioned-popins/partitioned-popins.cookies-allowed.tentative.sub.https.window.html [ Timeout ] -crbug.com/384050894 external/wpt/partitioned-popins/partitioned-popins.cookies-blocked.tentative.sub.https.window.html [ Timeout ] + +# Marked as failing due to different failure output on headless vs content_shell +crbug.com/341935362 virtual/dialog-close-when-open-removed-disabled/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative.html [ Failure ] # CustomizableSelect crbug.com/40146374 virtual/customizable-select-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-appearance-* [ Failure ] @@ -6157,6 +6165,7 @@ crbug.com/40146374 virtual/select-parser-relaxation/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-popover-exit-animation.tentative.html [ Failure ] crbug.com/40146374 virtual/customizable-select-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-second-child-button.tentative.html [ Failure ] crbug.com/40146374 virtual/select-parser-relaxation/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-second-child-button.tentative.html [ Failure ] +crbug.com/40146374 [ Mac ] virtual/customizable-select-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative.html [ Failure ] # Flaky on headless_shell_wpt_tests crbug.com/40146374 external/wpt/html/semantics/forms/the-select-element/customizable-select/select-option-images.tentative.html [ Failure Pass ] @@ -6168,6 +6177,8 @@ crbug.com/366415131 external/wpt/html/semantics/forms/the-select-element/customizable-select/picker-and-slotted.tentative.html [ Failure ] crbug.com/380466909 virtual/popover-anchor-relationships-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-events.tentative.html [ Failure Pass ] +# This fails with !owner_->GetDocument().IsSlotAssignmentRecalcForbidden(). +crbug.com/384394713 external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative.html [ Crash Failure ] ### Tests failing with CSSGapDecorations Enabled: crbug.com/357648037 virtual/css-gap-decorations/animations/interpolation/webkit-column-rule-color-interpolation.html [ Crash Failure Timeout ] @@ -8907,7 +8918,6 @@ # Gardener 2024-12-18 crbug.com/352331034 [ Debug Linux ] external/wpt/html/semantics/embedded-content/the-object-element/object-svg-only-for-print.html [ Failure Pass ] -crbug.com/384875218 external/wpt/partitioned-popins/partitioned-popins.partitions.tentative.https.window.html [ Pass Timeout ] crbug.com/384904807 [ Mac ] http/tests/inspector-protocol/tracing/image-decoding.js [ Failure Pass Timeout ] crbug.com/384863732 virtual/fedcm-multi-idp/external/wpt/fedcm/fedcm-multi-idp/fedcm-multi-idp-mediation-silent.https.html [ Timeout ] crbug.com/384863733 virtual/fedcm-multi-idp/external/wpt/fedcm/fedcm-multi-idp/fedcm-multi-idp-mediation-optional.https.html [ Timeout ]
diff --git a/third_party/blink/web_tests/TestLists/headless_shell.filter b/third_party/blink/web_tests/TestLists/headless_shell.filter index 7e0fb8db..de766ccc 100644 --- a/third_party/blink/web_tests/TestLists/headless_shell.filter +++ b/third_party/blink/web_tests/TestLists/headless_shell.filter
@@ -564,7 +564,7 @@ -external/wpt/css/selectors/open-pseudo.html -external/wpt/css/selectors/remove-hovered-element.html -external/wpt/css/selectors/user-invalid-form-submission-invalidation.html --external/wpt/density-size-correction/* +-external/wpt/density-size-correction/density-corrected-image-in-canvas.html -external/wpt/dom/events/scrolling/input-text-scroll-event-when-using-arrow-keys.html -external/wpt/dom/events/scrolling/scrollend-event-fired-after-snap.html -external/wpt/dom/events/scrolling/scrollend-event-fires-on-visual-viewport.html @@ -651,7 +651,8 @@ -external/wpt/html/browsers/browsing-the-web/overlapping-navigations-and-traversals/same-document-traversal-cross-document-nav.html -external/wpt/html/browsers/browsing-the-web/unloading-documents/prompt/004.html -external/wpt/html/browsers/browsing-the-web/unloading-documents/prompt-and-unload-script-closeable.html --external/wpt/html/browsers/history/the-location-interface/assign_* +-external/wpt/html/browsers/history/the-location-interface/assign_after_load.html +-external/wpt/html/browsers/history/the-location-interface/assign_before_load.html -external/wpt/html/browsers/origin/cross-origin-objects/cross-origin-objects.html -external/wpt/html/browsers/the-window-object/open-close/open-features-is-popup-condition.html* -external/wpt/html/browsers/the-window-object/open-close/open-features-non-integer-width.html @@ -659,43 +660,50 @@ -external/wpt/html/browsers/the-window-object/open-close/open-features-tokenization* -external/wpt/html/browsers/the-window-object/window-open-popup-behavior.html -external/wpt/html/webappapis/system-state-and-capabilities/the-navigator-object/clientinformation.window.html --external/wpt/html/canvas/element/compositing/2d.composite.grid.* --external/wpt/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html --external/wpt/html/canvas/element/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.drawImage.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.fillRect.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.filter.no_shadow.pattern.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.filter.shadow.drawImage.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.filter.shadow.fillRect.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.filter.shadow.pattern.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.drawImage.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.fillRect.html +-external/wpt/html/canvas/element/compositing/2d.composite.grid.no_filter.shadow.pattern.html -external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html -external/wpt/html/canvas/element/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.html -external/wpt/html/canvas/element/filters/2d.filter.layers.dropShadow.tentative.html -external/wpt/html/canvas/element/filters/2d.filter.layers.gaussianBlur.tentative.html --external/wpt/html/canvas/element/layers/2d.layer.clip-inside-and-outside.* --external/wpt/html/canvas/element/layers/2d.layer.clip-outside.* --external/wpt/html/canvas/element/layers/2d.layer.cross-layer-paths.html --external/wpt/html/canvas/element/layers/2d.layer.css-filters.* --external/wpt/html/canvas/element/layers/2d.layer.global-states.filter.no-cxt-filter.* --external/wpt/html/canvas/element/layers/2d.layer.global-states.no-cxt-filter.* --external/wpt/html/canvas/element/layers/2d.layer.non-invertible-matrix.* --external/wpt/html/canvas/element/layers/2d.layer.several-complex.html --external/wpt/html/canvas/element/layers/2d.layer.shadow-from-outside-canvas.long-distance* --external/wpt/html/canvas/element/line-styles/2d.line.invalid.strokestyle.html --external/wpt/html/canvas/element/manual/building-paths/canvas_complexshapes_arcto_001.htm --external/wpt/html/canvas/element/manual/compositing/colr-glyph-composition.html --external/wpt/html/canvas/element/manual/drawing-images-to-the-canvas/image-orientation/drawImage-from-* --external/wpt/html/canvas/element/manual/fill-and-stroke-styles/canvas_colorsandstyles_createlineargradient_001.htm -external/wpt/html/canvas/element/manual/filters/svg-filter-lh-rlh.html --external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-convolve-matrix.html -external/wpt/html/canvas/element/manual/filters/tentative/canvas-filter-object-turbulence.html --external/wpt/html/canvas/element/manual/imagebitmap/canvas-createImageBitmap-video-resize.html --external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-ImageBitmap-video.html --external/wpt/html/canvas/element/manual/wide-gamut-canvas/canvas-display-p3-drawImage-video.html --external/wpt/html/canvas/element/path-objects/2d.path.arc.selfintersect.1.html --external/wpt/html/canvas/element/pixel-manipulation/2d.imageData.put.unchanged.html --external/wpt/html/canvas/element/text/2d.text.draw.fontface.notinpage.html -external/wpt/html/canvas/element/text/direction-inherit-rtl.html -external/wpt/html/canvas/element/text/direction-rtl.html --external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.* --external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.html --external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillText.worker.html --external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.html --external/wpt/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.strokeText.worker.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.drawImage.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.fillRect.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.no_shadow.pattern.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.drawImage.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.fillRect.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.filter.shadow.pattern.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.drawImage.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.fillRect.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.no_shadow.pattern.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.drawImage.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.fillRect.w.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.html +-external/wpt/html/canvas/offscreen/compositing/2d.composite.grid.no_filter.shadow.pattern.w.html -external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.html -external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.dropShadow.tentative.w.html -external/wpt/html/canvas/offscreen/filters/2d.filter.canvasFilterObject.gaussianBlur.tentative.html @@ -704,23 +712,12 @@ -external/wpt/html/canvas/offscreen/filters/2d.filter.layers.dropShadow.tentative.w.html -external/wpt/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.tentative.html -external/wpt/html/canvas/offscreen/filters/2d.filter.layers.gaussianBlur.tentative.w.html --external/wpt/html/canvas/offscreen/layers/2d.layer.clip-inside-and-outside.* --external/wpt/html/canvas/offscreen/layers/2d.layer.clip-outside.* --external/wpt/html/canvas/offscreen/layers/2d.layer.cross-layer-paths.* --external/wpt/html/canvas/offscreen/layers/2d.layer.css-filters.* --external/wpt/html/canvas/offscreen/layers/2d.layer.globalCompositeOperation.w.html --external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.filter.no-cxt-filter.* --external/wpt/html/canvas/offscreen/layers/2d.layer.global-states.no-cxt-filter.* --external/wpt/html/canvas/offscreen/layers/2d.layer.non-invertible-matrix.* --external/wpt/html/canvas/offscreen/layers/2d.layer.shadow-from-outside-canvas.long-distance* --external/wpt/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.html --external/wpt/html/canvas/offscreen/line-styles/2d.line.invalid.strokestyle.worker.html --external/wpt/html/canvas/offscreen/manual/filter/offscreencanvas.filter.w.html --external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.* --external/wpt/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.html --external/wpt/html/canvas/offscreen/path-objects/2d.path.arc.selfintersect.1.worker.html --external/wpt/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.html --external/wpt/html/canvas/offscreen/pixel-manipulation/2d.imageData.get.source.outside.worker.html +-external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.html +-external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.getcontext.worker.html +-external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.resize.html +-external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.html +-external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transfer.to.imagebitmap.w.html +-external/wpt/html/canvas/offscreen/manual/the-offscreen-canvas/offscreencanvas.transferrable.w.html -external/wpt/html/cross-origin-embedder-policy/credentialless/service-worker.https.window.html -external/wpt/html/cross-origin-embedder-policy/reflection-require-corp.tentative.https.any.* -external/wpt/html/cross-origin-embedder-policy/reporting-to-document-reporting-endpoint.https.window.html
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index afb953f..2b5d9ed 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -2237,7 +2237,7 @@ ], "exclusive_tests": "ALL", "args": ["--enable-features=CookieDeprecationFacilitatedTesting:label/label_test"], - "expires": "Dec 30, 2024", + "expires": "Jul 6, 2025", "owners": ["linnan@chromium.org", "johnidel@chromium.org"] }, { @@ -4714,7 +4714,7 @@ ], "args": ["--js-flags=--js-float16array"], "owners": ["syg@chromium.org"], - "expires": "Jan 1, 2025" + "expires": "Mar 1, 2025" }, { "prefix": "single-import-map", @@ -4726,18 +4726,6 @@ "expires": "Jul 1, 2025" }, { - "prefix": "at-property-string-syntax", - "platforms": ["Linux"], - "bases": [ - "external/wpt/css/css-properties-values-api/at-property.html" - ], - "args": [ - "--disable-blink-features=CSSAtPropertyStringSyntax" - ], - "expires": "Jan 1, 2025", - "owners": ["moonira@google.com"] - }, - { "prefix": "devtools-improved-network-error", "platforms": ["Linux"], "bases": [
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 df6851f..183b6fd 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
@@ -4062,6 +4062,13 @@ {} ] ], + "column-scroll-marker-no-content-crash.html": [ + "12879ec6f2f756bd17cdc7591d1dfb8f1cd25384", + [ + null, + {} + ] + ], "ellipsis-with-image-crash.html": [ "42a18d0eb0ede5875e84f0cbf0012d5bc4814479", [ @@ -73032,6 +73039,19 @@ {} ] ], + "align-content-block-012.html": [ + "4e2819651592533ffa3d094925354d5348bb24dc", + [ + null, + [ + [ + "/css/css-align/blocks/align-content-block-012-ref.html", + "==" + ] + ], + {} + ] + ], "align-content-block-break-content-010.html": [ "27a56a608f4d915327d168ddc6ad8075eed095f4", [ @@ -75670,6 +75690,45 @@ {} ] ], + "clip-border-area-on-body-not-propagated-to-root.html": [ + "6530d2aa1f2e7d8b4cd2877eced95bcdd8304895", + [ + null, + [ + [ + "/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root-ref.html", + "==" + ] + ], + {} + ] + ], + "clip-border-area-on-body-propagated-to-root.html": [ + "c1713a108eb3a3d5979c68190d8c142ca5d34611", + [ + null, + [ + [ + "/css/css-backgrounds/reference/green-root-background.html", + "==" + ] + ], + {} + ] + ], + "clip-border-area-on-root.html": [ + "c3e49c8124f5eba79af120c243a1013426bb8d8b", + [ + null, + [ + [ + "/css/css-backgrounds/reference/green-root-background.html", + "==" + ] + ], + {} + ] + ], "clip-border-area.html": [ "cdbb096c701aaccdedb09f96769130154079b0b1", [ @@ -75809,6 +75868,45 @@ } ] ], + "clip-text-on-body-not-propagated-to-root.html": [ + "7a2f36aff6f58da588004910fada6f1cb3b54566", + [ + null, + [ + [ + "/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root-ref.html", + "==" + ] + ], + {} + ] + ], + "clip-text-on-body-propagated-to-root.html": [ + "ad37acb58ead9430d5b87193afca298a2db7deb9", + [ + null, + [ + [ + "/css/css-backgrounds/reference/green-root-background.html", + "==" + ] + ], + {} + ] + ], + "clip-text-on-root.html": [ + "58d29d7d57072e8098414a79b89c27d76d2284d4", + [ + null, + [ + [ + "/css/css-backgrounds/reference/green-root-background.html", + "==" + ] + ], + {} + ] + ], "clip-text-text-decorations.html": [ "e0212b30b37ddbaf618bd1e03595566c73a3140c", [ @@ -138060,6 +138158,19 @@ {} ] ], + "img-src-changes.html": [ + "19e19d7f5d7dd0fb8e2af5ea4e836c45c1d19848", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "implicit-grids": { "grid-support-grid-auto-columns-rows-001.html": [ "e61ced340c610401448bdc0c636a835708fa80b9", @@ -170793,6 +170904,32 @@ {} ] ], + "scrollbar-gutter-root-both-edges.html": [ + "0a312fa72a1b9f2b0d50c067f5e7f3218105021d", + [ + null, + [ + [ + "/css/css-overflow/scrollbar-gutter-root-both-edges-ref.html", + "==" + ] + ], + {} + ] + ], + "scrollbar-gutter-root.html": [ + "08c6f481edd161b24fd48b0c4f8815147905bc57", + [ + null, + [ + [ + "/css/css-overflow/scrollbar-gutter-root-ref.html", + "==" + ] + ], + {} + ] + ], "scrollbar-gutter-rtl-002.html": [ "8d0376defdfc69ecb44fc2134c81573e553db2bb", [ @@ -181081,6 +181218,19 @@ {} ] ], + "host-descendant-003.html": [ + "eb2cc7d343e1c382f693f93ec3de6557dfd8d5ff", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "host-has-001.html": [ "79c89874c63af3b2fa14ed64e0711b006a8032dc", [ @@ -181237,6 +181387,71 @@ {} ] ], + "host-multiple-002.html": [ + "c3f76a5091861a79ed18fda1a6b845d5385d03d6", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "host-multiple-003.html": [ + "97774b5bedf323b43359b06aa8017f440ed77a44", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "host-multiple-004.html": [ + "65a605a922ed2fa58045a59c6ae899034e07ab2e", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "host-multiple-005.html": [ + "d834954f3b3fd29fff1749b0b33755d83980004b", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], + "host-multiple-006.html": [ + "c3f76a5091861a79ed18fda1a6b845d5385d03d6", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "host-nested-001.html": [ "f8e412cc00565c5b20416bee5b88e0cc95ddc6d8", [ @@ -181250,6 +181465,19 @@ {} ] ], + "host-not-001.html": [ + "a5cfcbd8ea7709be52ab2317ce916a620675e1be", + [ + null, + [ + [ + "/css/reference/ref-filled-green-100px-square-only.html", + "==" + ] + ], + {} + ] + ], "host-slotted-001.html": [ "f05b7c729f31a7225809f6166ea0d65be8fa0314", [ @@ -199634,6 +199862,19 @@ {} ] ], + "segment-break-transformation-punctuation-001.html": [ + "68e4589625db3d6aff9127fcc48253aa183135e8", + [ + null, + [ + [ + "/css/css-text/line-breaking/segment-break-transformation-punctuation-001-ref.html", + "==" + ] + ], + {} + ] + ], "segment-break-transformation-removable-1.html": [ "7c2b820bee0022c8ec93ca9c52f52e3f697af883", [ @@ -291234,7 +291475,7 @@ ] ], "input-text-datalist-removal.html": [ - "c85bd288ed519eccfd97f4b07eacb8d2217b5451", + "503b82e001230b2e86cf744a020e174588a40a23", [ null, [ @@ -309442,7 +309683,7 @@ [] ], "idb-partitioned-coverage-iframe.html": [ - "727067a3b77d110dc5c9831404f78cd57924d39d", + "70300686340fc16be4b71114806ac4add73a8df2", [] ], "idb-partitioned-persistence-iframe.html": [ @@ -309450,15 +309691,15 @@ [] ], "idbfactory-origin-isolation-iframe.html": [ - "0f16bcadaadef4e7e151a859d27f7addff971ed6", + "1db0bc36dbc6d7bbb0b03f57c719dc1280919260", [] ], "idbworker.js": [ - "04a421fa38ba67d5a96f6534e961577bc4beeb21", + "031a0a7c15958fbbbcc0d149a528ddd1b2a9bdca", [] ], "interleaved-cursors-common.js": [ - "09ed078c1fcffe20b344760f52dbcfe330ab083c", + "a76ec528c99c72767a7889df1d7d7df582485ce2", [] ], "nested-cloning-common.js": [ @@ -322430,6 +322671,10 @@ "bdf11ba3f5fa084bb3f9a61f72465d0618f8fc2a", [] ], + "align-content-block-012-ref.html": [ + "78686202a893d15d90190ce4a02334a3ac051fa5", + [] + ], "align-content-block-break-content-010-aligned-ref.html": [ "4c92cc9b45fccb0e71446c78d443cac25ce5af60", [] @@ -322909,11 +323154,11 @@ [] ], "animation-name-computed-expected.txt": [ - "3c661c25d415324138fec06f68295d94158715ae", + "005f8e0d4cb9ccc7d1a4b1882ad8ed376375ffd2", [] ], "animation-name-valid-expected.txt": [ - "31f5be6d8c588220b43a74bb831f89e1663791cb", + "3599b277183d6d57c9fb2c6cb1069b765470c565", [] ], "keyframes-name-invalid-expected.txt": [ @@ -323258,6 +323503,10 @@ "455daa7aeabc3fba876eda3d1807b4ddca98c4f9", [] ], + "clip-text-on-body-not-propagated-to-root-ref.html": [ + "5c52749ad3d3b44235c98ce3ce4e916b8059e2f8", + [] + ], "clip-text-text-decorations-ref.html": [ "de819e4678e9c26c81bba94b7662d0fb55e4aa9a", [] @@ -324580,6 +324829,10 @@ "21a22bd273688115b3916691b4c4557f30d063d8", [] ], + "green-root-background.html": [ + "070f1926f437cfdc9b84700b734f4f0ec8f045ee", + [] + ], "inline-background-rtl-001-ref.html": [ "fe2ac8bdb1994fe6bd36ba85d7c71f49b7d7cf89", [] @@ -326849,7 +327102,7 @@ [] ], "relative-color-out-of-gamut-expected.txt": [ - "6e3ddac9c57293700570d252c1507bddc73f4fc3", + "e8123ecb3d08a7a9ff9e56a405e754ffd0af6feb", [] ] }, @@ -343466,6 +343719,10 @@ [] ] }, + "text-box-on-non-root-inline-box-expected.txt": [ + "14160ee489681a0fcd9d1a108686c74373e8ecb8", + [] + ], "text-box-trim-accumulation-001-ref.html": [ "321ae0c1f7a7fda62929b5f2cb6c8566b5f18f93", [] @@ -344221,15 +344478,15 @@ [] ], "counter-increment-valid-expected.txt": [ - "f3822e96ffbf99f1e2f961206b610362bdaf8a6e", + "a07425dc7a58d13ce28da48a1de6cd71ecc9175a", [] ], "counter-reset-valid-expected.txt": [ - "ad2651eb503efce5f058e0ec4707e48d019ee97a", + "8d9ef806c99ed4ef90c8b353fb44f8fb2ccad3c6", [] ], "counter-set-valid-expected.txt": [ - "ea67cfaeef1c15b4fba5440ac47427ff6cdadf45", + "1a1f77d66c863268bc6d978dfd71915806b78672", [] ], "list-style-computed.sub-expected.txt": [ @@ -346450,7 +346707,7 @@ [] ], "cssom-expected.txt": [ - "6ac7e3874c8b576923e9ea1204aa08eaed91f3e7", + "0a8c92e44d89bcb4beb5f0152e03612e97113904", [] ], "has-nesting-ref.html": [ @@ -347347,6 +347604,14 @@ "fe1b96fce8ac4faf2f67e40ca6fbbfd9dad4852e", [] ], + "scrollbar-gutter-root-both-edges-ref.html": [ + "7ee4fb7bb9e4c9f664565ea3d311ca42189f80df", + [] + ], + "scrollbar-gutter-root-ref.html": [ + "06ad9ecb39a39756dddc6e07cbc801f327e1ce24", + [] + ], "scrollbar-gutter-rtl-002-ref.html": [ "e6510a081353db996c4ead14ad6a167b90d48297", [] @@ -350129,7 +350394,7 @@ ], "computedstyle": { "block-level-replaced-elements-affected-by-block-step-size-expected.txt": [ - "0032fc263cb2028625624662d4288458cb206469", + "475a8506a629843dfe63a895bdfd285f3a527590", [] ] }, @@ -350143,7 +350408,7 @@ [] ], "block-step-computed-expected.txt": [ - "cbec96b13fce08ebc311289c287b8dfeb7d91f7d", + "218ee02bfb6189d988095cc049a2768d4d9e1b68", [] ], "block-step-insert-computed-expected.txt": [ @@ -350171,7 +350436,7 @@ [] ], "block-step-valid-expected.txt": [ - "b78d62c59841456c797c71e43e244d0af1448f84", + "147dc6a01784142f9b7e791f3bcdee26f3d1651a", [] ] } @@ -354744,6 +355009,10 @@ "bd348fa50991df3d03baee81fb44d101997a568b", [] ], + "segment-break-transformation-punctuation-001-ref.html": [ + "d339aebda9d2422c29b30d4fbbb43e1911bd498f", + [] + ], "segment-break-transformation-removable-ref.html": [ "0fa64d71dfee76e640870828277fda62c02ad0c8", [] @@ -358235,7 +358504,7 @@ [] ], "rotate-interpolation-math-functions-tentative-expected.txt": [ - "ae4df17e450abe8ef06b26cc1063877324c71e39", + "a68a31e6031139f5f90a5aeba11efd5cc2a29e5a", [] ], "rotate-transform-equivalent-ref.html": [ @@ -358247,7 +358516,7 @@ [] ], "scale-animation-math-functions-tentative-expected.txt": [ - "b506b542dcaed48288c0e82cac4c6f5cbba12f3a", + "9f6d3132711ce646fa083a4c0660d04a7e342ca7", [] ], "scale-animation-on-svg-ref.html": [ @@ -362060,11 +362329,11 @@ [] ], "container-progress-computed.tentative-expected.txt": [ - "b442d7f4e962e39a0aacc39638fd09355068c2ad", + "b4aa1dfc8c26675e391dba701ed385e93d98ec44", [] ], "container-progress-serialize.tentative-expected.txt": [ - "9aa2c83b7eec2f7713ff016421433ec9a9319352", + "9535986095fab893a723da276eb3c5a24e34ba9c", [] ], "ex-calc-expression-001-ref.html": [ @@ -362080,11 +362349,11 @@ [] ], "media-progress-computed.tentative-expected.txt": [ - "4bd1cb8d3f5e08d0c3a908718341853d838af94b", + "ffc650692ceb433663f7d5a3661066b5915e6480", [] ], "media-progress-serialize.tentative-expected.txt": [ - "4b23975c03f311aaf8549024bc92a18d38f1ea3e", + "d637b8032b0d8801298baa7f14f3e68a01931f17", [] ], "minmax-length-percent-serialize-expected.txt": [ @@ -362100,15 +362369,15 @@ [] ], "progress-computed.tentative-expected.txt": [ - "163fea430ca7aac8c788afa572a4bd588fb47e34", + "9bd8f75e2f36a63392026d7dcd12113c66d2e0e7", [] ], "progress-invalid.tentative-expected.txt": [ - "63b59ff8fae3dc15e8c4a838d170a7a096d5e937", + "6b73bfe000f40a7ae37c8fcd607fb1ae6299967c", [] ], "progress-serialize.tentative-expected.txt": [ - "50287214654b2ae01e49efb062d6f48ec32c1fbd", + "14899e37e9382f6e18373aa6a9b068162ae8d116", [] ], "reference": { @@ -366305,6 +366574,10 @@ "c45f8decf388919e994ee795b9e8d633dc6ee31c", [] ], + "cssstyledeclaration-removeProperty-all-expected.txt": [ + "0ce59f44f937cad1706a397b76b0872c7757a745", + [] + ], "flex-serialization-expected.txt": [ "ac76667255ef2b5d6cfaad859b1982a549657a36", [] @@ -366644,15 +366917,15 @@ [] ], "scrollWidthHeight-contain-layout-expected.txt": [ - "042c8eed90149ef3ae55e8045a317c0ca5c35036", + "420f4429be7e7417ae0daf8081dc781fd1b612a9", [] ], "scrollWidthHeight-negative-margin-002-expected.txt": [ - "f0690d432e60a54c58e4cc497d28cc112cee9cbe", + "88a1855454f3303ba1c787eb9c74a9f8e23b082b", [] ], "scrollWidthHeightWhenNotScrollable-expected.txt": [ - "729999dc7061ff46497f00f566e763996ee24a4e", + "08f6e6d17c0c1e8e1e7fac735b002937530d8bf9", [] ], "scrollingElement-expected.txt": [ @@ -371012,7 +371285,7 @@ [] ], "multitest.js": [ - "2d5404ba8989035a99d097f3322e65c7804c0af4", + "5d0a60bf89ee379416631c9701430915ffc43953", [] ], "outdent.js": [ @@ -393090,7 +393363,7 @@ [] ], "input-text-focused-ref.html": [ - "df8ea576069cf84c3a01c996c618103bd9e91323", + "f78a937f17815a6a063a7465bf53fe402cdb671f", [] ] }, @@ -429313,7 +429586,7 @@ ] ], "bindings-inject-keys-bypass.any.js": [ - "a32a7a6633883c122ae7774e74999e5d7844de49", + "0b5a743416eb7671dfe1d75e6a30b8f90452e35c", [ "IndexedDB/bindings-inject-keys-bypass.any.html", { @@ -429392,7 +429665,7 @@ ] ], "bindings-inject-values-bypass.any.js": [ - "03d488480d7e44e905069947593d9c02a94e41ba", + "85dfae6a7c05feacbda271033beabe7b7edef66a", [ "IndexedDB/bindings-inject-values-bypass.any.html", { @@ -429471,7 +429744,7 @@ ] ], "blob-composite-blob-reads.any.js": [ - "7d6ab9be3591ad04b3b2e02e97a2bbdb0dc6c3cc", + "880195ba6daa9016f701bef91f43ea4ef58431b5", [ "IndexedDB/blob-composite-blob-reads.any.html", { @@ -429514,7 +429787,7 @@ ] ], "blob-contenttype.any.js": [ - "2d1d6a1ec99b2b99a318f0ccdcdd30ebabf8752b", + "a77c223bd392171dd5d70c8364aef728a685e248", [ "IndexedDB/blob-contenttype.any.html", { @@ -429557,7 +429830,7 @@ ] ], "blob-delete-objectstore-db.any.js": [ - "1750241df4a63aa41a1be74cd03d9509f5a239e4", + "773099c12c5681cca54216755977900c5d0ef0b0", [ "IndexedDB/blob-delete-objectstore-db.any.html", { @@ -429590,7 +429863,7 @@ ] ], "blob-valid-after-deletion.any.js": [ - "b44fc4e38c359a6e865ad0a3005a292fc89416a5", + "3a10fbde216acfea9251f40f0d26ad2838b64c87", [ "IndexedDB/blob-valid-after-deletion.any.html", { @@ -429623,7 +429896,7 @@ ] ], "blob-valid-before-commit.any.js": [ - "ad8b2a1be20818ffc525bd86d109e93148d7426f", + "a4989ab194186a362bf53cc3f69a0aad29382e99", [ "IndexedDB/blob-valid-before-commit.any.html", { @@ -429656,7 +429929,7 @@ ] ], "clone-before-keypath-eval.any.js": [ - "8344098ae789fd66b95e3dcc71ad41d08ffb9564", + "aeaf21b781b29b067a79f2a4f2bc20ac995a0e33", [ "IndexedDB/clone-before-keypath-eval.any.html", { @@ -429735,7 +430008,7 @@ ] ], "close-in-upgradeneeded.any.js": [ - "3e39360877e39bba0d913ed1fea3b6c649208f14", + "592cb91309716b2cc4e56bb1bb10f44cf19f0426", [ "IndexedDB/close-in-upgradeneeded.any.html", { @@ -429814,7 +430087,7 @@ ] ], "cursor-overloads.any.js": [ - "dd80d2f40382407ac468028c5aa294374f4b561b", + "83a8b9bde2c04aa21e13128fe10698ba36717404", [ "IndexedDB/cursor-overloads.any.html", { @@ -429902,7 +430175,7 @@ ] ], "delete-range.any.js": [ - "b86d646354db3bcdfd28c259b94c666a60ef3ef6", + "11cf5c61093e0f321df6a833aae893183c27a9c6", [ "IndexedDB/delete-range.any.html", { @@ -430014,7 +430287,7 @@ ] ], "error-attributes.any.js": [ - "9b5003040b273b14a086025425a4a0af06e73274", + "eb8d6714d009f39977e1196e35ff88813d92785c", [ "IndexedDB/error-attributes.any.html", { @@ -430093,7 +430366,7 @@ ] ], "event-dispatch-active-flag.any.js": [ - "47c27eadb8ac314ff26d20202c19a95c18bca00b", + "88dac346f7557b8a308dd9a54624afff418558fb", [ "IndexedDB/event-dispatch-active-flag.any.html", { @@ -430181,7 +430454,7 @@ ] ], "fire-error-event-exception.any.js": [ - "ade2a7251e3c0170a9022b962a655cede1df567b", + "baeb33da659a5e238b4060a72f01c2bcc41e51e8", [ "IndexedDB/fire-error-event-exception.any.html", { @@ -430260,7 +430533,7 @@ ] ], "fire-success-event-exception.any.js": [ - "bd757ea6b1f9d7108367fbcd148b04bc9c16327d", + "918aa9eab6b9a9df1b12bdcdc997db0da3b3b49e", [ "IndexedDB/fire-success-event-exception.any.html", { @@ -430569,14 +430842,14 @@ ] ], "idb-binary-key-detached.htm": [ - "a4ce3fbce00917b747c4dd40655cb2d6aa55c63d", + "438e1395f2a2b146bc73ffdd8c9def84fda613c6", [ null, {} ] ], "idb-binary-key-roundtrip.any.js": [ - "0856a05cb64b6e65a9a61f92db57a4eb5e6a4cf7", + "0173dcbe31534dd3c20f9387cfa06aa2fefa685e", [ "IndexedDB/idb-binary-key-roundtrip.any.html", { @@ -430816,42 +431089,42 @@ ] ], "idbcursor-advance-continue-async.htm": [ - "ff3751506358eba6e3e08f7e5a14be38ea9a3e68", + "2490e9e7e0d18ea41a345a70548106842e7aec44", [ null, {} ] ], "idbcursor-advance-exception-order.html": [ - "1dfe4ff55bbf357b6e9959e890b2cfb8917dcaf6", + "1abbc9acc2a20013916b957bf11253dcb6aebb5e", [ null, {} ] ], "idbcursor-advance-invalid.htm": [ - "67c5e93df079b460bd40d707908217003570247d", + "4e8472efd5905e0cf2da33d73a267897e58d6fed", [ null, {} ] ], "idbcursor-advance.htm": [ - "624ed14f1f7568f4d550a866e454fdbbb1b27b53", + "c72ac2f16f4a60666aa2a4023f008c9219681e52", [ null, {} ] ], "idbcursor-continue-exception-order.htm": [ - "29c874fdb6e805de6d5cd7e90130d9e76a95115a", + "6561ec396c23e13df200ed43c7515305ccb7d2ad", [ null, {} ] ], "idbcursor-continue.htm": [ - "db98c2261b1bf09a2be6b1b42d2f52cddcba6347", + "bcb099f309edbb159814ab296a02ebb4bd3e9f3e", [ null, {} @@ -430874,84 +431147,84 @@ ] ], "idbcursor-continuePrimaryKey.htm": [ - "0de88c0aefc93d551acd314f17164f51c6ea948c", + "b45bba7c22138d6f29f980b9a2c1bb87ff5e453d", [ null, {} ] ], "idbcursor-delete-exception-order.htm": [ - "b84ca11ed4d76f91fd36f3fe9843d9ad0c5c9e79", + "72d565749718a624344480d4d336cf23776f71e3", [ null, {} ] ], "idbcursor-direction-index-keyrange.htm": [ - "2b3ff34318dca17a059e2a587870c77df7a2896a", + "c26997c9ff30d15d7ebb106c5d8ed10c4bd4b1ae", [ null, {} ] ], "idbcursor-direction-index.htm": [ - "be22337884c123bd2ae02510df474a3ce9fd8a0b", + "a2adeb73d6bfdabc2af720b745465cb518d896ae", [ null, {} ] ], "idbcursor-direction-objectstore-keyrange.htm": [ - "b458ef0cbf444bd5023b9859a3fe9567e01f91dc", + "e5b5a22de9d0356e45fccb4198c3a141b438f78c", [ null, {} ] ], "idbcursor-direction-objectstore.htm": [ - "c099651a29ecb1d814d9b9a2ea8de92e2ff59a2c", + "cac1a589d78e6ca0a716e60b64634a0e6697f4b1", [ null, {} ] ], "idbcursor-direction.htm": [ - "1f2dedd76b524f8b04e5d78f747880d0609d812a", + "18e3a02ef87a344421355acc3160f8ef7587f5e2", [ null, {} ] ], "idbcursor-iterating-update.htm": [ - "0a7282b68f7d7d06d658448640a78e92a1f85e32", + "00fdb5a0c008bcc1d2f5ebcef8c2bbc0ba517f4b", [ null, {} ] ], "idbcursor-key.htm": [ - "e3b22f8bd6710e33e229e213f0c262ca05189792", + "c1dbbe15038d782575504b5d84b94a4883ab4731", [ null, {} ] ], "idbcursor-primarykey.htm": [ - "d6832c5ede763d4a5f368fbb21019acbe422c42d", + "c32973874870c89b4b0f669f93b4186437fd04aa", [ null, {} ] ], "idbcursor-request-source.html": [ - "8ed4a8dee29a16397f17e79dcdf37afed6b5c3fb", + "9e2f72b4d45beb6941783a08e69a59dafbde5366", [ null, {} ] ], "idbcursor-request.any.js": [ - "2e1216a736ac135ae0c3511b236cc33b627f7d5e", + "b84c83c98a6e6eeca1085fa5c8439204df0115c1", [ "IndexedDB/idbcursor-request.any.html", { @@ -430976,28 +431249,28 @@ ] ], "idbcursor-reused.htm": [ - "feb35a55f8693736f87615fc419bf4142d0e8214", + "30414584fee577a860b01b5b0ca8857738e6494a", [ null, {} ] ], "idbcursor-source.htm": [ - "81acda33ccf12f686a198a3824f300c81d8efa13", + "1882f092942565f927e7bc0eb39ee59ea6809c58", [ null, {} ] ], "idbcursor-update-exception-order.htm": [ - "8ac08635bb4da506d584e6748587e47cfd69afee", + "9324752d5eb7f4d3ccd8c63fd660627a9890f46b", [ null, {} ] ], "idbcursor_advance_index.any.js": [ - "c928bdabd5f589b3c9613721c44850ca39e25bf2", + "379908e1dd653d942315f75f116a381ab3b34861", [ "IndexedDB/idbcursor_advance_index.any.html", { @@ -431076,7 +431349,7 @@ ] ], "idbcursor_advance_objectstore.any.js": [ - "5ce345e8b178221b86c8db5fbb51aa6727a86353", + "bf508be438794273bf0f2aecdd1513ef761e0d0a", [ "IndexedDB/idbcursor_advance_objectstore.any.html", { @@ -431155,7 +431428,7 @@ ] ], "idbcursor_continue_delete_objectstore.any.js": [ - "7c86fab046d13096456d48ef302de51bbe3910f2", + "b25bbdc9106e02d6cdfb83ce11680dcae6cb7459", [ "IndexedDB/idbcursor_continue_delete_objectstore.any.html", { @@ -431234,7 +431507,7 @@ ] ], "idbcursor_continue_index.any.js": [ - "8bf329c467b918a43e516bb1c0def1153e9200d8", + "b7671c4f589c92634ca7607984e7d8fcf6e3ecdd", [ "IndexedDB/idbcursor_continue_index.any.html", { @@ -431313,7 +431586,7 @@ ] ], "idbcursor_continue_invalid.any.js": [ - "b08f362ab2e63f43b68b4ac69d5869a1d6d6f9f2", + "9d4a8be06480d0ecd1ff9316ad29af89a5a58467", [ "IndexedDB/idbcursor_continue_invalid.any.html", { @@ -431392,7 +431665,7 @@ ] ], "idbcursor_continue_objectstore.any.js": [ - "dc6f6b4132ac2f8438407f561c7ba2b3c4c4c7df", + "66af7a9d589ed3d01bcd3e657c7cb8cbe1addffd", [ "IndexedDB/idbcursor_continue_objectstore.any.html", { @@ -431471,7 +431744,7 @@ ] ], "idbcursor_delete_index.any.js": [ - "a4d0614820a188ec50b7490d2d2b2a35f4c358ec", + "76935bad904f498533391fab11fb855af040ef5e", [ "IndexedDB/idbcursor_delete_index.any.html", { @@ -431550,7 +431823,7 @@ ] ], "idbcursor_delete_objectstore.any.js": [ - "0aad5dcfb7737808f3f00219f5fc5612d9e25e4d", + "176423bbce2f1ca70271682c19ae79cc133bef5d", [ "IndexedDB/idbcursor_delete_objectstore.any.html", { @@ -431629,7 +431902,7 @@ ] ], "idbcursor_iterating.any.js": [ - "521ed821c9a82c91aa720ab8b1d3a209201c6821", + "3c0815c374bc511e49669d62905a8be307046cb3", [ "IndexedDB/idbcursor_iterating.any.html", { @@ -431708,7 +431981,7 @@ ] ], "idbcursor_update_index.any.js": [ - "6437a882a6be4e51133fe06540982c7b58ff6bcc", + "b9d7c8c924d22d33b3d91e5d52d7e0f054913467", [ "IndexedDB/idbcursor_update_index.any.html", { @@ -431787,7 +432060,7 @@ ] ], "idbcursor_update_objectstore.any.js": [ - "ca3fd870eb76369efd500f973817cca5be2a0da5", + "3765ef72cfe96e806e63610d97729c65b1d5943f", [ "IndexedDB/idbcursor_update_objectstore.any.html", { @@ -431908,7 +432181,7 @@ ] ], "idbdatabase_createObjectStore.htm": [ - "3379ab58f50d89356ee9d30e6c37a0db9469c72d", + "cf0651ceb50a9060abd0c53b789e9a6c2f1cdfaf", [ null, {} @@ -431938,7 +432211,7 @@ ] ], "idbdatabase_createObjectStore2.htm": [ - "55c73d6228150bc62472e9836594cd677233ee72", + "d5a98ec8ed7ebc0ab7c1cfff9523cd13a581a9cf", [ null, {} @@ -432075,7 +432348,7 @@ ] ], "idbdatabase_transaction.any.js": [ - "17859ec99e68f5191f56597014a74943bc28c86f", + "a6a8900968f1425ad588866b1e691c501a686f6a", [ "IndexedDB/idbdatabase_transaction.any.html", { @@ -432203,7 +432476,7 @@ ] ], "idbfactory-origin-isolation.html": [ - "eaf9800d7c5165fbee3fc6d25e8dfd40508ad84a", + "5d10fb87a7402f621d580f1bedae338cb2c7ef10", [ null, {} @@ -432266,7 +432539,7 @@ ] ], "idbfactory_open.any.js": [ - "edc5d3c8c6c0e9dabeaa814bc10acef0be9282d9", + "aadfc5ce513fcbb712988fd839bbf817ea5acc5a", [ "IndexedDB/idbfactory_open.any.html", { @@ -432345,28 +432618,28 @@ ] ], "idbindex-cross-realm-methods.html": [ - "1e431d3772cd1022eec43a1fddb8e67c78140dda", + "ec45d67bffa61c1bd1157056e0d3b194bfc9b9f4", [ null, {} ] ], "idbindex-getAll-enforcerange.html": [ - "73b55b7d869c352d15e5387c1e9bf6db4ab84b04", + "4e9ad6a1936babbfeee0e7f2905c973ce11faae8", [ null, {} ] ], "idbindex-getAllKeys-enforcerange.html": [ - "31dc787f685202aadf7caa8d8857b731818178f1", + "22c19ece4e39e57f15318dd2a708150c4e95a655", [ null, {} ] ], "idbindex-multientry.any.js": [ - "ee1b651b9f6109dabd848cdde7f085e992a6fbe0", + "e4c27c1f131c03f435e59159b4985a274e8805e2", [ "IndexedDB/idbindex-multientry.any.html", { @@ -432445,35 +432718,35 @@ ] ], "idbindex-objectStore-SameObject.html": [ - "018c818d1dfe37994fd10b0e695a37ce5a366dbd", + "186d0f052fee9856e6a0b5131f74c0a00a9126eb", [ null, {} ] ], "idbindex-query-exception-order.html": [ - "2c1a33511250d2661a72bcd5736fbf6802f770b1", + "5b35a959920776e55ea0b592bb640014f8b5e30c", [ null, {} ] ], "idbindex-rename-abort.html": [ - "07863081b293e57f0700bcabe2c6b953bbbd51c0", + "00e6e36de870b1ea08262bf89f1bf2acce9e69ef", [ null, {} ] ], "idbindex-rename-errors.html": [ - "2339cf10221d8dff73d887f3a694b5c891ae37fe", + "7b6b0f17edfad6842ae136866c9774b0428d9d59", [ null, {} ] ], "idbindex-rename.html": [ - "db06a7e23717a6d84782bd04460f9cc740678a72", + "b6d97e6ae92c71133c0dc7a953051e517f867cca", [ null, { @@ -432482,14 +432755,14 @@ ] ], "idbindex-request-source.html": [ - "72688c467ab0097c8449267a11bd0553221f9717", + "ac4e2847ec9d2528227eaa5d1dc295466555c80f", [ null, {} ] ], "idbindex_count.any.js": [ - "25d743e422f93cf5f069e2d27252d9f6afa8e959", + "ff2c8cef94eb3be9b3a8dd5294a323b5091a1e76", [ "IndexedDB/idbindex_count.any.html", { @@ -432568,7 +432841,7 @@ ] ], "idbindex_get.any.js": [ - "0da228f73825e50c5a19cbf9b7504a946ae7b7df", + "21b66f897820f26a0490c8f97f92eee72c5dadc1", [ "IndexedDB/idbindex_get.any.html", { @@ -433088,7 +433361,7 @@ ] ], "idbindex_getKey.any.js": [ - "677a70e7cb43e4ad2675a8f03413bd55d8e7aa58", + "b16a615b7d10fd1de71230a8d817c54e961af5e5", [ "IndexedDB/idbindex_getKey.any.html", { @@ -433167,14 +433440,14 @@ ] ], "idbindex_indexNames.htm": [ - "7da76021c8c588066cf4b388cdff6de49a065adf", + "72c0cf4d946c62cf68b882d31d856413377e9adb", [ null, {} ] ], "idbindex_keyPath.any.js": [ - "40721462a35803ffe44ace342102e1bf7541c298", + "794dbea08037548bd22f6e41409419a800ba4358", [ "IndexedDB/idbindex_keyPath.any.html", { @@ -433207,7 +433480,7 @@ ] ], "idbindex_openCursor.any.js": [ - "3de4856e2bdc4dc89fad78192b4c064d4c30459b", + "51722915ec438778bb40db11a0bb3167e10b4883", [ "IndexedDB/idbindex_openCursor.any.html", { @@ -433286,7 +433559,7 @@ ] ], "idbindex_openKeyCursor.any.js": [ - "9166ff386cb2896170a2af43e7174397972883fe", + "a14a22fdb97be87def5b2d511ee7c3e3b6781af5", [ "IndexedDB/idbindex_openKeyCursor.any.html", { @@ -433452,84 +433725,84 @@ ] ], "idbobjectstore-add-put-exception-order.html": [ - "bbcc120a7ec90286f26b1a95e5daa0221c169839", + "e5a73d4b9fa038cd35bacedece8ab610582dc468", [ null, {} ] ], "idbobjectstore-clear-exception-order.html": [ - "206d21300a1481fafb13ed6e9ffb8176695b6fdc", + "993704d1d3a588bc122adecc7323a708d5e65393", [ null, {} ] ], "idbobjectstore-cross-realm-methods.html": [ - "edb4b9b3730f79d9994644855c912f37dec3d4a6", + "ae58d7ea9255a1ea518f0a3752f6fda0ad80761b", [ null, {} ] ], "idbobjectstore-delete-exception-order.html": [ - "aa6ae1c2852d93541b8b054acc9c0594d5d75606", + "c33667f4b387355e4b9a4d5ff1ab2fc52b78360c", [ null, {} ] ], "idbobjectstore-deleteIndex-exception-order.html": [ - "48bbe40c4d3d3aecd81186dce53e93e003eddfe8", + "9e9bf1e138c1ec68e934ebbd13c345e42205b165", [ null, {} ] ], "idbobjectstore-getAll-enforcerange.html": [ - "c408aff715d7eaa091f5068098598f2bf3e7bdad", + "4ead24d36a9ef74d2bdf9342c099fd6ad95a7ce8", [ null, {} ] ], "idbobjectstore-getAllKeys-enforcerange.html": [ - "f8e77aecba240521ed7a0201c3d935d3e04253d4", + "527be11565ecbb9544e2b99ee6f15dfacb00ce5c", [ null, {} ] ], "idbobjectstore-index-finished.html": [ - "a45c66ed7059d4d9253e9ca381162cd51e7d19c6", + "be7fe22d75d23551a7b817fe3ce3019372aad003", [ null, {} ] ], "idbobjectstore-query-exception-order.html": [ - "53ae04b08808026aa64776c0ded1e33389902e1c", + "b28572619ef59571befe773a7c1321dacca42bae", [ null, {} ] ], "idbobjectstore-rename-abort.html": [ - "b4bfc914ed7671c5b53dadcaf9cc248c6e33ff9f", + "0a7c54ee58f51927add8ed11aa5817d2b3fdbadd", [ null, {} ] ], "idbobjectstore-rename-errors.html": [ - "de72c5cf48d3d518632a1431fc37f9585526dd05", + "ad2ff9a6577d05029016ec8fbef7fe3acdb74e15", [ null, {} ] ], "idbobjectstore-rename-store.html": [ - "649f9faef38ba359c77fb1c542d5c2ede473d5fb", + "97fa2e0c1fee475b006ff36df7d1099c87ac3190", [ null, { @@ -433538,21 +433811,21 @@ ] ], "idbobjectstore-request-source.html": [ - "c5947564ea1c2fa62c63ef97387dee10cc141962", + "a710bf5270028d6272b7a36559cd77f6ecdf41cf", [ null, {} ] ], "idbobjectstore-transaction-SameObject.html": [ - "2b5a027c459b546234d4e681ff35728d4e80638e", + "39a954018f3940a80ad78907eb8ca65c207b57c9", [ null, {} ] ], "idbobjectstore_add.any.js": [ - "dfc15294e82a66640c853c5ece5f3c4ff3486d8d", + "d56809cfd8cbd6d9dda13535b7463275fdbf8ee2", [ "IndexedDB/idbobjectstore_add.any.html", { @@ -433631,7 +433904,7 @@ ] ], "idbobjectstore_clear.any.js": [ - "f384b6cfc8bfbd211152b6188fbb1c463162bf17", + "b15b99a8cf41c6a8fed8a02df10cf5572ce9a5dc", [ "IndexedDB/idbobjectstore_clear.any.html", { @@ -433710,7 +433983,7 @@ ] ], "idbobjectstore_count.any.js": [ - "c28ba5caf8188a87858f8cf4741dc67f16eb95a7", + "80efabc7376faba1bf49687f738ea6afa657fc93", [ "IndexedDB/idbobjectstore_count.any.html", { @@ -433789,7 +434062,7 @@ ] ], "idbobjectstore_createIndex.any.js": [ - "79df5a77c870a3c0c3d2f57368ddb49a801679f3", + "82d576d8ee15fa049360f9c5e40e60651c2a328d", [ "IndexedDB/idbobjectstore_createIndex.any.html", { @@ -433868,7 +434141,7 @@ ] ], "idbobjectstore_delete.any.js": [ - "0b731f391d0302079e304b10f67a762693f37d95", + "3db010d0c6989b95135657d8be2d3e377512d61f", [ "IndexedDB/idbobjectstore_delete.any.html", { @@ -433947,7 +434220,7 @@ ] ], "idbobjectstore_deleteIndex.any.js": [ - "ed0246e0e79f5270981463b8e0c5fabe257a7dad", + "f9c5f68ba9c93643a55ba39d925f93c2000f74be", [ "IndexedDB/idbobjectstore_deleteIndex.any.html", { @@ -434026,7 +434299,7 @@ ] ], "idbobjectstore_get.any.js": [ - "7e2c2e9b415b3f93c43497e9113f0343bb4e7b2c", + "e8d7f7df066d6bf008d9b6c5b81fe5cfaeb1f848", [ "IndexedDB/idbobjectstore_get.any.html", { @@ -434546,7 +434819,7 @@ ] ], "idbobjectstore_getKey.any.js": [ - "f0dc13d45cfeb950eb73418c3b99414a309b6476", + "e90fdc92de0f5e84503878a6fc31dff725a26df7", [ "IndexedDB/idbobjectstore_getKey.any.html", { @@ -434579,14 +434852,14 @@ ] ], "idbobjectstore_index.htm": [ - "74d473a5ed58c9dc7a6848e3b53cf96ee197efe1", + "3b693f79e70361a3289af137151bb7abfbc75f05", [ null, {} ] ], "idbobjectstore_keyPath.any.js": [ - "b12958bc8aafb5a016b957bb6c82fa0de7c1f418", + "bce825ad1fe39fc3d75498e717abb71fd26106d4", [ "IndexedDB/idbobjectstore_keyPath.any.html", { @@ -434619,28 +434892,28 @@ ] ], "idbobjectstore_openCursor.htm": [ - "3085ecf013a80facce3d39132094e7468c13bc81", + "e144aa5e7f6210424ec56a0e6f7d1fa50a265223", [ null, {} ] ], "idbobjectstore_openCursor_invalid.htm": [ - "e12db3bb64f51aaddb9444a35a4178d9a897edda", + "d40e115d47c8ac48edbe97e8510e992613067e4c", [ null, {} ] ], "idbobjectstore_openKeyCursor.htm": [ - "483fe29a489b58bc66c65ad8ee78420aee7807af", + "b03cc9b7458d20c9ffa2bb8989835aef97d15661", [ null, {} ] ], "idbobjectstore_put.any.js": [ - "89303291e9d6923b4c769f6eddb2360e60e171be", + "2be7a54a8369ab33e3fb2b929385f6627eea3a55", [ "IndexedDB/idbobjectstore_put.any.html", { @@ -434719,49 +434992,49 @@ ] ], "idbrequest-onupgradeneeded.htm": [ - "c156dba619abb15f9d2c9c45cb7a3cf34863dce2", + "73f22697f6eeb8d1a485cff382931f573470b81c", [ null, {} ] ], "idbrequest_error.html": [ - "73dd13383ff343d846f703ebd094e2ea6e320471", + "56d2ddb0083b0c3c3bcaeac61c74c6153e942863", [ null, {} ] ], "idbrequest_result.html": [ - "69c48532463effcac6dcc7d82a7904b76259e890", + "6ec81cc29b8bfaaecb71e273f892bb44833498ae", [ null, {} ] ], "idbtransaction-db-SameObject.html": [ - "5116dff5fff1b7a6ee8e42293634008b60a43158", + "52e0b0f6e6078dd5748d5bd9ab44f3a053b0ee5b", [ null, {} ] ], "idbtransaction-objectStore-exception-order.html": [ - "2ce4e13e2de7bbbced7d3afe069971a888198b9f", + "9b5c4ac4b94605b0d16d3ff8b98cdf73aa0a6c87", [ null, {} ] ], "idbtransaction-objectStore-finished.html": [ - "afe5bec0f850eb5ff51d5ba3767b57ff030d52fe", + "de2cad51afe1b52fcfca88b8ef590b6b9dbc9a1f", [ null, {} ] ], "idbtransaction-oncomplete.htm": [ - "722802c1ccf672dd47712d09284a0ef17cdb7626", + "3ee4ee51ac1b66ed5d170f3e9076014d1722b1ba", [ null, {} @@ -434782,7 +435055,7 @@ ] ], "idbtransaction_objectStoreNames.html": [ - "efec1d24704560f91973eb1be0a101221bac8611", + "e9b725e0395cef68e986eb50a4b2ea2cbee55637", [ null, {} @@ -434895,7 +435168,7 @@ ] ], "index_sort_order.htm": [ - "2f6d474ea67533ce86e2738fb0978f8ee73c776d", + "5af8e6f865ea316362eb69b102033bcbd7fa8161", [ null, {} @@ -434936,7 +435209,7 @@ ] ], "key_valid.html": [ - "678b4c4f4ea312720f1ea7f0a36f07b5cbd6cfd8", + "0cca54cdbb3db3a0ffe3abf317aa7529a98ee49c", [ null, { @@ -434945,7 +435218,7 @@ ] ], "keygenerator.any.js": [ - "90f23ed298102b6bf4490c34ff12de0ac0225877", + "3ed7ba8381ac0e4057949458807df17deef0f3f8", [ "IndexedDB/keygenerator.any.html", { @@ -435015,14 +435288,14 @@ ] ], "keypath-exceptions.htm": [ - "c23d4d226818417479d0c85674b9d99a21cdcd37", + "b0569f9294e2079d5c11bc3d6b5a6a2568302cba", [ null, {} ] ], "keypath-special-identifiers.htm": [ - "55f40314ee7438d6a0c2da157379c179daf3fc85", + "a521ed8bb89c4357fe5bbc0ec1c0737f6ac0c7cf", [ null, {} @@ -435043,7 +435316,7 @@ ] ], "keypath_maxsize.htm": [ - "069f4f7ecaa570785e05c126546179da19dd71e2", + "1abbc1403d4681ff287af0d07537ab5ca7924c9b", [ null, { @@ -435111,7 +435384,7 @@ ] ], "objectstore_keyorder.htm": [ - "ad294f66a1bee16f24f4e3265a594a2cfa37b16a", + "f3f5ae76e7c5d18b33db37689d5e41b1b4bac796", [ null, {} @@ -435634,7 +435907,7 @@ ] ], "structured-clone.any.js": [ - "4a99b61bdad0664fcb95d143eb96112a763d756f", + "99665073d9540f7aed0348f1adffa58d441a2cd7", [ "IndexedDB/structured-clone.any.html?1-20", { @@ -436241,21 +436514,21 @@ ] ], "transaction-abort-request-error.html": [ - "285e1112c04c5257235af3dbd348a4799e9054b8", + "fa828286f4d7c4f9cb0d2a8a7ac561082dbfc4f4", [ null, {} ] ], "transaction-create_in_versionchange.htm": [ - "d5bcfd45d8aba01133eaf3c47f3aca66861126af", + "4659b1593fda6a6f430a053f371d4b02c0a26cbd", [ null, {} ] ], "transaction-deactivation-timing.html": [ - "ae2e6f646348404a522f964a0573e84a18e13b3c", + "4b826f121c07b99781238590295e4eaac5c64fe9", [ null, {} @@ -436269,7 +436542,7 @@ ] ], "transaction-lifetime-empty.html": [ - "86bd41ae62c339d355c089c23bedb9211fd00231", + "ba299fdcd041802b49e41cb87cf4d52a577bab81", [ null, {} @@ -436325,7 +436598,7 @@ ] ], "transaction-scheduling-across-connections.any.js": [ - "06d886fe8319a72c74a054d25b29a01e77e5248f", + "84223a17338224de1e226156dc42efbb3c20fadd", [ "IndexedDB/transaction-scheduling-across-connections.any.html", { @@ -436350,7 +436623,7 @@ ] ], "transaction-scheduling-across-databases.any.js": [ - "09d8ef20d16c490d0266e50eee1911dc1cfc4fce", + "eada0f7e839cc3de7d089b1c52b2a3f283b183b9", [ "IndexedDB/transaction-scheduling-across-databases.any.html", { @@ -436400,7 +436673,7 @@ ] ], "transaction-scheduling-ordering.any.js": [ - "42d056e9a1275fe02562483811c114a9708a2a58", + "95c9bbf3a7689d603b511c7120d87a4a65e1aa0d", [ "IndexedDB/transaction-scheduling-ordering.any.html", { @@ -436425,7 +436698,7 @@ ] ], "transaction-scheduling-ro-waits-for-rw.any.js": [ - "ae0d126808195dda5748c24b0e048d36957a4b5a", + "6457abe802726fe2b2b8caa837d2fbf4ec1ab936", [ "IndexedDB/transaction-scheduling-ro-waits-for-rw.any.html", { @@ -436475,7 +436748,7 @@ ] ], "transaction-scheduling-within-database.any.js": [ - "a9a20bae3a73da145b82dc2803c2429a79e82fed", + "552b4e4b2638bfe751e04c5a699d7a5d275cf429", [ "IndexedDB/transaction-scheduling-within-database.any.html", { @@ -436887,7 +437160,7 @@ ] ], "value.any.js": [ - "d4fa6f520ccca59887288aa1b4fd595506db5608", + "24099a798e6326be7039e48988f4646575140cef", [ "IndexedDB/value.any.html", { @@ -436966,7 +437239,7 @@ ] ], "value_recursive.htm": [ - "e02c908a3528aa0b443fc848efb04c35701d4b03", + "29325a59094d485182f9ddc422435ce54a55a71c", [ null, {} @@ -436991,7 +437264,7 @@ ] ], "writer-starvation.htm": [ - "df9c5dc7577c4d5c3a89f4532ea91b24afe2a065", + "e382139b87da2c380472c6526d24b0bc1ddea014", [ null, { @@ -473113,7 +473386,7 @@ ] ], "animation-name-computed.html": [ - "f05dd8b013c082c70861fc763b0a0f7a2f470e50", + "81f1d411c4300764553d5c091343344f830bdcc0", [ null, {} @@ -473127,7 +473400,7 @@ ] ], "animation-name-valid.html": [ - "1906f9bdb768b9fa41572e37c207183f0f9995d1", + "4c17b876276df006da23629601c3defd8c364017", [ null, {} @@ -475755,7 +476028,7 @@ ] ], "revert-val-006.html": [ - "2b238f6d7e53b35cbdfe98c1fcac3625b9cfd72e", + "2f7d5811990ab001d5a29749eecde68037651403", [ null, {} @@ -486959,6 +487232,13 @@ ] ] }, + "text-box-on-non-root-inline-box.html": [ + "eea80895c5df0c903ad8533dec7a310b4380f998", + [ + null, + {} + ] + ], "text-box-trim-om-001.html": [ "4184dcb638883a948b91b5800e32a2bc0bb6272e", [ @@ -488918,7 +489198,7 @@ ] ], "cssom.html": [ - "226fb791b57240c2f47172de6351549a0e59ed9a", + "c1c620f6bec29efbf6c1e7a8a5a3ef91ad17e403", [ null, {} @@ -490959,7 +491239,7 @@ ] ], "custom-property-animation-used-in-shorthand.html": [ - "63f7fd3fe79bd3f95efe1dc717f0ac5418ad509f", + "70975dfa3780e4306b3d0b16a1521ecd1d97ff81", [ null, {} @@ -502622,7 +502902,7 @@ ] ], "animation-name.html": [ - "df5d44ae38f4f8f3be4d6e2ec5863ca408d4483f", + "7de53f188fa877b01874b5722dfdd6f34b166d76", [ null, {} @@ -505001,6 +505281,13 @@ {} ] ], + "attr-null-namespace.xhtml": [ + "a9bf9b0adddcb8d9674c5c7b154a6f9bb1e39240", + [ + null, + {} + ] + ], "attr-pseudo-elem-invalidation.html": [ "d1db96ecd063e9d74e83e4507e8d167a55d43935", [ @@ -506450,6 +506737,13 @@ {} ] ], + "dynamic-stylesheet-animations.html": [ + "d737d3ab570075e3d88ea827d2296c74e5f35033", + [ + null, + {} + ] + ], "event-pseudo-name.html": [ "d77c8173456d6190c8d663656fa7b94958100b91", [ @@ -508289,6 +508583,13 @@ {} ] ], + "cssstyledeclaration-removeProperty-all.html": [ + "6e9caacd2353d36cb835ec8d10b6c989f11c1053", + [ + null, + {} + ] + ], "cssstyledeclaration-setter-attr.html": [ "20837052e39368455dedc6ce8901709cc00817cf", [ @@ -680809,6 +681110,13 @@ {} ] ], + "getElementById-dynamic-002.html": [ + "8fb1934c60753c39c081fa97987bbdf1cc68a521", + [ + null, + {} + ] + ], "historical.html": [ "4fa8be1dbc9537b904d51b74e8de37dc36a471d6", [ @@ -703343,7 +703651,7 @@ ] ], "GlobalEventHandlers-onclick.html": [ - "0fdde778cc8863600ecdcc57a6d6281b52a777d4", + "83b957256bee93dce6d48f1d999ef368d30c6404", [ null, {} @@ -703711,21 +704019,21 @@ ] ], "default-policy-callback-arguments.html": [ - "3e591bd63b1d5164f17d8bf82d77d3b359e79902", + "7a256ee17b00a6cdff6cdc0c8be773bbbb9a21d1", [ null, {} ] ], "default-policy-report-only.html": [ - "9d5f83e8939d754962545ac38fadf51256faf39c", + "3716e1bebe5e52a2baafded9ebf086a61c37ad74", [ null, {} ] ], "default-policy.html": [ - "47fdf1b1d4489c73ba5e304fe311027acf626881", + "19643c95b982a7563f549cf46ae08facbacd2819", [ null, {} @@ -738081,7 +738389,7 @@ ] ], "equal.https.any.js": [ - "d8278bc607db5f49aabf96bae0fbf1633d16d4ab", + "dd68fc795428d8fe98934411cc2e8e1d1c554243", [ "webnn/conformance_tests/equal.https.any.html?cpu", { @@ -740271,7 +740579,7 @@ ] ], "greater.https.any.js": [ - "41408be41206503e46e49f5e25a4c6a559e13bd3", + "b2e4d62adb1fe46a14509c3a43192441b551802b", [ "webnn/conformance_tests/greater.https.any.html?cpu", { @@ -740490,7 +740798,7 @@ ] ], "greater_or_equal.https.any.js": [ - "19818cd7e46ede13f866bb22ad146d4672059d28", + "b6308dcb813ae06fcae5659542d2c07e95940e0e", [ "webnn/conformance_tests/greater_or_equal.https.any.html?cpu", { @@ -742680,7 +742988,7 @@ ] ], "lesser.https.any.js": [ - "f514c3d16aeb26c747d0c8c949ddcebbb8ef9af5", + "8e71fc491c957962bdc8795cd504c49edd65f7ab", [ "webnn/conformance_tests/lesser.https.any.html?cpu", { @@ -742899,7 +743207,7 @@ ] ], "lesser_or_equal.https.any.js": [ - "751d35a8a98a3b51ed62f37d2c123c744be866f3", + "20139daddef9253b193aa886f2950daed85dbfe9", [ "webnn/conformance_tests/lesser_or_equal.https.any.html?cpu", { @@ -804713,6 +805021,15 @@ ] ] }, + "css-nesting": { + "mixed-declarations-rules.html": [ + "fbc9b54717c91d74b20d5739e746e2287871c92b", + [ + null, + {} + ] + ] + }, "css-overflow": { "overflow-alignment-block-001.html": [ "20192eb2f10ab73a4107b3ddb78efed55f4a127c", @@ -807403,7 +807720,7 @@ }, "navigation_failed": { "navigation_failed.py": [ - "bf72e6e4278adc364f15f1ab3cbe4f6b7ae100f0", + "85cab4d7d97cd38d49da3637a833d4c684a326ed", [ null, {} @@ -807677,7 +807994,7 @@ "input": { "perform_actions": { "invalid.py": [ - "0ed9fa3b4bf1e202ae9ec8f16db6195ddb3419c9", + "ad7dab399350c01771a6f4238bdd64bf2985d3d6", [ null, { @@ -807686,7 +808003,7 @@ ] ], "key.py": [ - "567400c4e899579e77cc541d369993ce2c7bd54c", + "beadf2792059ae32c9fcf406ac4d79da088648cc", [ null, {}
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html index 8467ab6..f37a8972 100644 --- a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-default.tentative.https.sub.html
@@ -3,7 +3,9 @@ <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> <script src=/browsing-topics/resources/header-util.sub.js></script> + <script src=/browsing-topics/resources/load_img.sub.js></script> <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script> + <script src=/common/utils.js></script> <script> 'use strict'; const header = 'Default permissions policy'; @@ -39,6 +41,18 @@ assert_equals(topics_header, EMPTY_TOPICS_HEADER); }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics fetch request.'); + promise_test(async t => { + let topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true); + assert_equals(topics_header, EMPTY_TOPICS_HEADER); + }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin topics img request.'); + + promise_test(async t => { + let topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false); + assert_equals(topics_header, EMPTY_TOPICS_HEADER); + }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics img request.'); + async_test(t => { test_topics_iframe_navigation_header( t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true,
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html index 23bac438..1a3737c 100644 --- a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-none.tentative.https.sub.html
@@ -3,7 +3,9 @@ <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> <script src=/browsing-topics/resources/header-util.sub.js></script> + <script src=/browsing-topics/resources/load_img.sub.js></script> <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script> + <script src=/common/utils.js></script> <script> 'use strict'; const header = 'permissions policy header browsing-topics=()'; @@ -44,6 +46,18 @@ assert_equals(topics_header, "NO_TOPICS_HEADER"); }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics fetch request.'); + promise_test(async t => { + let topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true); + assert_equals(topics_header, "NO_TOPICS_HEADER"); + }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the same-origin topics img request.'); + + promise_test(async t => { + let topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false); + assert_equals(topics_header, "NO_TOPICS_HEADER"); + }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics img request.'); + async_test(t => { test_topics_iframe_navigation_header( t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true,
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html index 91ee4f0..3d0de47 100644 --- a/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/browsing-topics-permissions-policy-self.tentative.https.sub.html
@@ -3,7 +3,9 @@ <script src=/resources/testharness.js></script> <script src=/resources/testharnessreport.js></script> <script src=/browsing-topics/resources/header-util.sub.js></script> + <script src=/browsing-topics/resources/load_img.sub.js></script> <script src=/browsing-topics/resources/permissions-policy-util.sub.js></script> + <script src=/common/utils.js></script> <script> 'use strict'; const header = 'permissions policy header browsing-topics=(self)'; @@ -51,6 +53,18 @@ assert_equals(topics_header, "NO_TOPICS_HEADER"); }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the redirect of a topics fetch request, where the redirect has a cross-origin URL.'); + promise_test(async t => { + let topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true); + assert_equals(topics_header, EMPTY_TOPICS_HEADER); + }, header + 'allows the \'Sec-Browsing-Topics\' header to be sent for the same-origin topics img request.'); + + promise_test(async t => { + let topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/false); + assert_equals(topics_header, "NO_TOPICS_HEADER"); + }, header + 'disallows the \'Sec-Browsing-Topics\' header to be sent for the cross-origin topics img request.'); + async_test(t => { test_topics_iframe_navigation_header( t, /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true,
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/img-topics-attribute.tentative.https.html b/third_party/blink/web_tests/external/wpt/browsing-topics/img-topics-attribute.tentative.https.html new file mode 100644 index 0000000..a87aea04 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/img-topics-attribute.tentative.https.html
@@ -0,0 +1,23 @@ +<!doctype html> +<body> + <script src=/resources/testharness.js></script> + <script src=/resources/testharnessreport.js></script> + <script src=/common/utils.js></script> + <script src=/browsing-topics/resources/load_img.sub.js></script> + <script> + const EMPTY_TOPICS_HEADER = '();p=P0000000000000000000000000000000'; + + promise_test(async () => { + const topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/false, /*is_same_origin=*/true); + assert_equals(topics_header, 'NO_TOPICS_HEADER'); + }, 'test <img src=[url]></img>'); + promise_test(async () => { + const topics_header = await load_topics_image( + /*has_browsing_topics_attribute=*/true, /*is_same_origin=*/true); + assert_equals(topics_header, EMPTY_TOPICS_HEADER); + }, 'test <img browsingtopics src=[url]></img>'); + + </script> +</body> +
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/resources/check-topics-request-header-in-img.py b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/check-topics-request-header-in-img.py new file mode 100644 index 0000000..d5ab1ab --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/check-topics-request-header-in-img.py
@@ -0,0 +1,35 @@ +def main(request, response): + """ + This file is intended to be requested twice to verify that the correct headers + are included for images. + 1. Make an initial request for an img. The `sec-browsing-topics` header will + be stored for step 2. The request will be redirected to an image. + 2. Make a request with the query parameter set. The stashed header from the + first step will be returned in the response content. + + Parameters: + `token` should be a unique UUID request parameter for the duration of this + request. It will get stored in the server stash and will be used later in + a query request. + `query` should be a request parameter indicating the request would like + to know the last `sec-browsing-topics` header with that token. + """ + + token = request.GET.first(b"token", None) + is_query = request.GET.first(b"query", None) is not None + topics_header = request.headers.get(b"sec-browsing-topics", b"NO_TOPICS_HEADER") + + queried_topics_header = b"NO_PREVIOUS_REQUEST" + with request.server.stash.lock: + value = request.server.stash.take(token) + if value is not None: + queried_topics_header = value + if not is_query: + request.server.stash.put(token, topics_header) + + if is_query: + return (200, [(b"Access-Control-Allow-Origin", b"*")], queried_topics_header) + + headers = [(b"Location", "pixel.png"), + (b"Access-Control-Allow-Origin", b"*")] + return 301, headers, b""
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/resources/load_img.sub.js b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/load_img.sub.js new file mode 100644 index 0000000..35da085 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/load_img.sub.js
@@ -0,0 +1,39 @@ +// Poll the server for the test result. +async function get_stashed_topics_header(url) { + for (let i = 0; i < 30; ++i) { + const response = await fetch(url + '&query'); + let stashed_topics_header = await response.text(); + + if (!stashed_topics_header || (stashed_topics_header === 'NO_PREVIOUS_REQUEST')) { + await new Promise(resolve => step_timeout(resolve, 100)); + continue; + } + return stashed_topics_header; + } + assert_true(false, 'timeout'); +} + +// Load an image and poll for the topics header that +// check-topics-request-header-in-img.py should stash. +function load_topics_image(has_browsing_topics_attribute, is_same_origin) { + let stash_id = token(); + const sameOriginSrc = `/browsing-topics/resources/` + + `check-topics-request-header-in-img.py?token=${stash_id}`; + const crossOriginSrc = 'https://{{domains[www]}}:{{ports[https][0]}}' + + sameOriginSrc; + + const url = is_same_origin ? sameOriginSrc : crossOriginSrc + + let image = document.createElement('img'); + image.src = url; + + if (has_browsing_topics_attribute) { + image.browsingTopics = true; + } + + image.decode().then(() => { + document.body.appendChild(image); + }); + + return get_stashed_topics_header(url); +} \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/browsing-topics/resources/pixel.png b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/pixel.png new file mode 100644 index 0000000..818c71d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/browsing-topics/resources/pixel.png Binary files differ
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/blocks/align-content-block-012-ref.html b/third_party/blink/web_tests/external/wpt/css/css-align/blocks/align-content-block-012-ref.html new file mode 100644 index 0000000..7868620 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-align/blocks/align-content-block-012-ref.html
@@ -0,0 +1,228 @@ +<!DOCTYPE html> +<title>CSS Box Alignment: align-content on large block container</title> +<link rel="help" href="https://www.w3.org/TR/css-align-3/#align-block"> +<link rel="author" title="Elika J. Etemad" href="http://fantasai.inkedblade.net/contact"> +<style title="Needed for automation; delete to review/debug"> + @import "/fonts/ahem.css"; + html { font: 15px/1 Ahem; max-width: 800px; } +</style> +<style> + .test { height: 3em; margin: 0.5em 1.25em; box-sizing: border-box; + /* show bounds of test box without interfering with margin-collapsing */ + border-left: solid blue 5px; + /* ensure bullet follows first line */ + display: list-item; + /* don't wrap, as that will throw off the reference */ + white-space: nowrap; } + /* cram into 800x600 */ + html { max-height: 600px; columns: 3 } + .wrapper { break-inside: avoid; border: solid 2px gray; } + /* predictability */ + input { height: 4px; margin: 0; vertical-align: 4px; } + img { height: 8px }</style> +<body> +<div class="wrapper"> + <div class="test" style="" title="start"> + STRT + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 1em" title="center"> + CNTR + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 2em" title="end"> + ENDD + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="" title="baseline"> + BSLN + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 2em" title="last baseline"> + LBSL + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="" title="flex-start"> + FSTR + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 2em" title="flex-end"> + FEND + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="" title="unsafe start"> + USTR + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 1em" title="unsafe center"> + UCNT + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 2em" title="unsafe end"> + UEND + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="" title="safe start"> + SSTR + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 1em" title="safe center"> + SCNT + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 2em" title="safe end"> + SEND + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 1em" title="space-evenly"> + SEVN + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="" title="space-between"> + SBTW + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="padding-top: 1em" title="space-around"> + SARN + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="" title="normal"> + NRML + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<p> + <button onclick="document.querySelector('style[title]').textContent = 'html { font-size: 12px; }'">Show Text</button> +</p> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-align/blocks/align-content-block-012.html b/third_party/blink/web_tests/external/wpt/css/css-align/blocks/align-content-block-012.html new file mode 100644 index 0000000..4e281965 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-align/blocks/align-content-block-012.html
@@ -0,0 +1,235 @@ +<!DOCTYPE html> +<title>CSS Box Alignment: align-content on large block container</title> +<link rel="help" href="https://www.w3.org/TR/css-align-3/#align-block"> +<link rel="author" title="Elika J. Etemad" href="http://fantasai.inkedblade.net/contact"> +<link rel="match" href="align-content-block-012-ref.html"> +<style title="Needed for automation; delete to review/debug"> + @import "/fonts/ahem.css"; + html { font: 15px/1 Ahem; max-width: 800px; } +</style> + +<style> + .test { height: 3em; margin: 0.5em 1.25em; + /* show bounds of test box without interfering with margin-collapsing */ + border-left: solid blue 5px; + /* ensure bullet follows first line */ + display: list-item; + /* don't wrap, as that will throw off the reference */ + white-space: nowrap; } + + /* cram into 800x600 */ + html { max-height: 600px; columns: 3 } + .wrapper { break-inside: avoid; border: solid 2px gray; } + + /* predictability */ + input { height: 4px; margin: 0; vertical-align: 4px; } + img { height: 8px } +</style> + +<body> +<div class="wrapper"> + <div class="test" style="align-content: start" title="start"> + STRT + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: center" title="center"> + CNTR + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: end" title="end"> + ENDD + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: baseline" title="baseline"> + BSLN + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: last baseline" title="last baseline"> + LBSL + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: flex-start" title="flex-start"> + FSTR + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: flex-end" title="flex-end"> + FEND + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: unsafe start" title="unsafe start"> + USTR + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: unsafe center" title="unsafe center"> + UCNT + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: unsafe end" title="unsafe end"> + UEND + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: safe start" title="safe start"> + SSTR + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: safe center" title="safe center"> + SCNT + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: safe end" title="safe end"> + SEND + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: space-evenly" title="space-evenly"> + SEVN + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: space-between" title="space-between"> + SBTW + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: space-around" title="space-around"> + SARN + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> +<div class="wrapper"> + <div class="test" style="align-content: normal" title="normal"> + NRML + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + <span> + x + <input type=checkbox> + <img src='../../support/swatch-orange.png'> + </div> + </div> +</div> + +<p> + <button onclick="document.querySelector('style[title]').textContent = 'html { font-size: 12px; }'">Show Text</button> +</p> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed-expected.txt index 3c661c2..005f8e0d4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed-expected.txt
@@ -1,5 +1,40 @@ This is a testharness.js-based test. [FAIL] Property animation-name value '"something"' assert_true: '"something"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"---\\22---"' + assert_true: '"---\\22---"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"multi word string"' + assert_true: '"multi word string"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"none"' + assert_true: '"none"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"none", "INITIAL", "inherit"' + assert_true: '"none", "INITIAL", "inherit"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"none", both, ease-in' + assert_true: '"none", both, ease-in' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"NoNe"' + assert_true: '"NoNe"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"initial"' + assert_true: '"initial"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"INITIAL"' + assert_true: '"INITIAL"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"inherit"' + assert_true: '"inherit"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"INHERIT"' + assert_true: '"INHERIT"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"revert"' + assert_true: '"revert"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"REVERT"' + assert_true: '"REVERT"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"revert-layer"' + assert_true: '"revert-layer"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"REVERT-LAYER"' + assert_true: '"REVERT-LAYER"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"unset"' + assert_true: '"unset"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"UNSET"' + assert_true: '"UNSET"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"default"' + assert_true: '"default"' is a supported value for animation-name. expected true got false +[FAIL] Property animation-name value '"DEFAULT"' + assert_true: '"DEFAULT"' is a supported value for animation-name. expected true got false Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed.html index f05dd8b0..81f1d411 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-computed.html
@@ -13,6 +13,7 @@ <div id="target"></div> <script> test_computed_value("animation-name", 'none'); +test_computed_value("animation-name", 'NONE', 'none'); test_computed_value("animation-name", 'foo'); test_computed_value("animation-name", 'Both'); @@ -20,13 +21,28 @@ test_computed_value("animation-name", 'infinite'); test_computed_value("animation-name", 'paused'); test_computed_value("animation-name", 'first, second, third'); -test_computed_value("animation-name", '"something"', ["something", '"something"']); -// TODO: Test more strings, after https://github.com/w3c/csswg-drafts/issues/2435 -// is resolved. -// Examples that need testing either here or in animation-name-invalid.html : -// '"Initial"', '"initial"', '"None"', '"Default"', '" x "', "1", '" "', '""', -// '"multi word string"', '"---\\22---"' +test_computed_value("animation-name", '"something"', 'something'); +test_computed_value("animation-name", '"---\\22---"', '---\\\"---'); +test_computed_value("animation-name", '"multi word string"', 'multi\\ word\\ string'); + +// Restricted keywords as strings +test_computed_value("animation-name", '"none"'); +test_computed_value("animation-name", '"none", "INITIAL", "inherit"'); +test_computed_value("animation-name", '"none", both, ease-in'); +test_computed_value("animation-name", '"NoNe"'); +test_computed_value("animation-name", '"initial"'); +test_computed_value("animation-name", '"INITIAL"'); +test_computed_value("animation-name", '"inherit"'); +test_computed_value("animation-name", '"INHERIT"'); +test_computed_value("animation-name", '"revert"'); +test_computed_value("animation-name", '"REVERT"'); +test_computed_value("animation-name", '"revert-layer"'); +test_computed_value("animation-name", '"REVERT-LAYER"'); +test_computed_value("animation-name", '"unset"'); +test_computed_value("animation-name", '"UNSET"'); +test_computed_value("animation-name", '"default"'); +test_computed_value("animation-name", '"DEFAULT"'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid-expected.txt index 31f5be6..3599b277 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid-expected.txt
@@ -1,11 +1,40 @@ This is a testharness.js-based test. -[FAIL] e.style['animation-name'] = "\\"string\\"" should set the property value - assert_not_equals: property should be set got disallowed value "" -[FAIL] e.style['animation-name'] = "\\"multi word string\\"" should set the property value - assert_not_equals: property should be set got disallowed value "" -[FAIL] e.style['animation-name'] = "\\"initial\\"" should set the property value +[FAIL] e.style['animation-name'] = "\\"something\\"" should set the property value assert_not_equals: property should be set got disallowed value "" [FAIL] e.style['animation-name'] = "\\"---\\\\22---\\"" should set the property value assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"multi word string\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"none\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"none\\", \\"INITIAL\\", \\"inherit\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"none\\", both, ease-in" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"NoNe\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"initial\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"INITIAL\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"inherit\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"INHERIT\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"revert\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"REVERT\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"revert-layer\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"REVERT-LAYER\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"unset\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"UNSET\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"default\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" +[FAIL] e.style['animation-name'] = "\\"DEFAULT\\"" should set the property value + assert_not_equals: property should be set got disallowed value "" Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid.html b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid.html index 1906f9bd..4c17b876 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-animations/parsing/animation-name-valid.html
@@ -11,6 +11,7 @@ </head> <body> <script> +test_valid_value("animation-name", 'none'); test_valid_value("animation-name", 'NONE', 'none'); test_valid_value("animation-name", 'foo'); @@ -20,10 +21,27 @@ test_valid_value("animation-name", 'paused'); test_valid_value("animation-name", 'first, second, third'); -test_valid_value("animation-name", '"string"', ['"string"', "string"]); -test_valid_value("animation-name", '"multi word string"', ['"multi word string"', "multi\\ word\\ string"]); +test_valid_value("animation-name", '"something"', 'something'); +test_valid_value("animation-name", '"---\\22---"', '---\\\"---'); +test_valid_value("animation-name", '"multi word string"', 'multi\\ word\\ string'); + +// Restricted keywords as strings +test_valid_value("animation-name", '"none"'); +test_valid_value("animation-name", '"none", "INITIAL", "inherit"'); +test_valid_value("animation-name", '"none", both, ease-in'); +test_valid_value("animation-name", '"NoNe"'); test_valid_value("animation-name", '"initial"'); -test_valid_value("animation-name", '"---\\22---"', ['\"---\\\"---\"', '---\\\"---']); +test_valid_value("animation-name", '"INITIAL"'); +test_valid_value("animation-name", '"inherit"'); +test_valid_value("animation-name", '"INHERIT"'); +test_valid_value("animation-name", '"revert"'); +test_valid_value("animation-name", '"REVERT"'); +test_valid_value("animation-name", '"revert-layer"'); +test_valid_value("animation-name", '"REVERT-LAYER"'); +test_valid_value("animation-name", '"unset"'); +test_valid_value("animation-name", '"UNSET"'); +test_valid_value("animation-name", '"default"'); +test_valid_value("animation-name", '"DEFAULT"'); </script> </body> </html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-not-propagated-to-root.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-not-propagated-to-root.html new file mode 100644 index 0000000..6530d2a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-not-propagated-to-root.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<title>background-clip:border-area on the root</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#propdef-background-clip"> +<link rel="match" href="clip-text-on-body-not-propagated-to-root-ref.html"> +<style> +html, body { + box-sizing: border-box; + height: 100%; + margin: 0; +} +html { + background-color: white; +} +body { + border: 20px solid transparent; + background-color: green; + background-clip: border-area; + padding: 10px; +} +</style> + +There should be a 20px green border around the edge of the viewport. This text should be black on a white background. \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-propagated-to-root.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-propagated-to-root.html new file mode 100644 index 0000000..c1713a1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-body-propagated-to-root.html
@@ -0,0 +1,21 @@ +<!DOCTYPE html> +<title>background-clip:border-area on the root</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#propdef-background-clip"> +<link rel="match" href="../reference/green-root-background.html"> +<style> +html, body { + box-sizing: border-box; + height: 100%; + margin: 0; +} +html { + color: transparent; + border: 20px solid transparent; +} +body { + background-color: green; + background-clip: border-area; +} +</style> + +The border should not be visible; the page should be entirely green.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-root.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-root.html new file mode 100644 index 0000000..c3e49c81 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-border-area-on-root.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>background-clip:border-area on the root</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-3/#propdef-background-clip"> +<link rel="match" href="../reference/green-root-background.html"> +<style> +html, body { + box-sizing: border-box; + height: 100%; + margin: 0; +} +html { + height: 100%; + color: transparent; + border: 20px solid transparent; + background-color: green; + background-clip: border-area; +} +</style> + +The border should not be visible; the page should be entirely green.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root-ref.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root-ref.html new file mode 100644 index 0000000..5c52749a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root-ref.html
@@ -0,0 +1,13 @@ +<!DOCTYPE html> +<link rel="stylesheet" href="/fonts/ahem.css"> +<style> +html { + font-size: 24px; + background-color: white; + color: green; + font-family: Ahem; +} +</style> + +This text should be green<br> +on a white background. \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root.html new file mode 100644 index 0000000..7a2f36a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-not-propagated-to-root.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>background-clip:text on the root</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-4/#valdef-background-clip-text"> +<link rel="stylesheet" href="/fonts/ahem.css"> +<link rel="match" href="clip-text-on-body-not-propagated-to-root-ref.html"> +<style> +html { + background-color: white; + font-size: 24px; + color: transparent; + font-family: Ahem; +} +body { + background-color: green; + background-clip: text; +} +</style> + +This text should be green<br> +on a white background. \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-propagated-to-root.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-propagated-to-root.html new file mode 100644 index 0000000..ad37acb5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-body-propagated-to-root.html
@@ -0,0 +1,16 @@ +<!DOCTYPE html> +<title>background-clip:text on the root</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-4/#valdef-background-clip-text"> +<link rel="match" href="../reference/green-root-background.html"> +<style> +html { + font-size: 80px; + color: transparent; + background-color: green; +} +body { + background-clip: text; +} +</style> + +This text should not be visible; the page should be entirely green.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-root.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-root.html new file mode 100644 index 0000000..58d29d7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/background-clip/clip-text-on-root.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<title>background-clip:text on the root</title> +<link rel="help" href="https://drafts.csswg.org/css-backgrounds-4/#valdef-background-clip-text"> +<link rel="match" href="../reference/green-root-background.html"> +<style> +html { + font-size: 80px; + color: transparent; + background-color: green; + background-clip: text; +} +</style> + +This text should not be visible; the page should be entirely green.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/green-root-background.html b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/green-root-background.html new file mode 100644 index 0000000..070f192 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-backgrounds/reference/green-root-background.html
@@ -0,0 +1,6 @@ +<!DOCTYPE html> +<style> +:root { + background-color: green; +} +</style>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-grid/img-src-changes.html b/third_party/blink/web_tests/external/wpt/css/css-grid/img-src-changes.html new file mode 100644 index 0000000..19e19d7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-grid/img-src-changes.html
@@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html> +<link rel="author" title="Sammy Gill" href="mailto:sammy.gill@apple.com"> +<link rel="match" href="../reference/ref-filled-green-100px-square-only.html"> +<link rel="help" href="https://drafts.csswg.org/css-grid/"> +<meta name="assert" content="Grid goes through layout when image src changes"> +<style> +div { + display: grid; +} +img { + width: 100px; + height: 100%; +} +</style> +<body> +<p>Test passes if there is a filled green square.</p> +<div> +<img src=""> +</div> +</body> +<script> +document.body.offsetHeight; +document.querySelector("img").src = "grid-items/support/100x100-green.png"; +</script> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box-expected.txt new file mode 100644 index 0000000..14160ee --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +[FAIL] .aqua 1 + assert_equals: \n<span class="aqua" style="text-box: ex alphabetic;" data-offset-y="16" data-expected-height="2">ApÉx</span>\nheight expected 2 but got 14 +[FAIL] .aqua 3 + assert_equals: \n<span class="aqua" style="text-box: trim-end text alphabetic;" data-offset-y="8" data-expected-height="10">ApÉx</span>\nheight expected 10 but got 14 +[FAIL] .aqua 4 + assert_equals: \n<div class="aqua" data-expected-height="18">\n <span style="font-size: 18px; text-box: ex alphabetic;">ApÉx</span>\n</div>\nheight expected 18 but got 21 +Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box.html b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box.html new file mode 100644 index 0000000..eea80895 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box.html
@@ -0,0 +1,28 @@ +<!DOCTYPE html> +<title>text-box on non-root inline box does not affect layout bounds only the box's size.</title> +<link rel="help" href="https://drafts.csswg.org/css-inline-3/#text-box-trim"> +<link rel="help" href="https://drafts.csswg.org/css-inline-3/#text-box-edge"> +<style> +@import "support/TestMetricsFont.css"; + +div { + font-family: MetricsTestFont; + font-size: 12px; +} +.aqua { + background-color: aqua; +} +</style> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script src="/resources/check-layout-th.js"></script> +<body onload="checkLayout('.aqua')"> +<div> + <span class=aqua style="text-box: ex alphabetic;" data-offset-y=16 data-expected-height=2>ApÉx</span> + <span class=aqua style="text-box: trim-start cap alphabetic; data-offset-y=14 data-expected-height=10">ApÉx</span> + <span class=aqua style="text-box: trim-end text alphabetic;" data-offset-y=8 data-expected-height=10>ApÉx</span> +</div> +<div class=aqua data-expected-height=18> + <span style="font-size: 18px; text-box: ex alphabetic;">ApÉx</span> +</div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom-expected.txt index 6ac7e38..0a8c92e4 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom-expected.txt
@@ -1,5 +1,6 @@ This is a testharness.js-based test. [FAIL] CSSStyleRule is a CSSGroupingRule assert_equals: expected function "function CSSGroupingRule() { [native code] }" but got function "function CSSRule() { [native code] }" +[FAIL] Manipulation of nested declarations through CSSOM + assert_equals: expected "3" but got "1" Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom.html b/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom.html index 226fb79..c1c620f6 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom.html +++ b/third_party/blink/web_tests/external/wpt/css/css-nesting/cssom.html
@@ -185,4 +185,41 @@ assert_equals(getComputedStyle(inner1).zIndex, '1'); assert_equals(getComputedStyle(inner2).zIndex, '1'); }, 'Mutating the selectorText of outer rule invalidates inner rules'); + + // CSSNestedDeclarations + test((t) => { + const main = document.createElement('main'); + main.innerHTML = ` + <style id="main_ss"> + div { + z-index: 1; + &.test { foo:bar; } + } + </style> + <div id="outer" class="test"> + </div> + `; + document.documentElement.append(main); + t.add_cleanup(() => main.remove()); + assert_equals(getComputedStyle(outer).zIndex, '1'); + const main_ss = document.getElementById("main_ss").sheet; + const rule = main_ss.cssRules[0]; + assert_equals(rule.cssRules.length, 1); + rule.insertRule('z-index: 3;'); + assert_equals(rule.cssRules.length, 2); + assert_equals(getComputedStyle(outer).zIndex, '3'); + + // Throw only when no valid declaration https://github.com/w3c/csswg-drafts/issues/10520 + assert_throws_dom('SyntaxError', () => { rule.insertRule('nothing-to-insert-because-invalid-property-should-throw: 2;'); }); + assert_equals(rule.cssRules.length, 2); + + // Test the insertion of nested declarations inside grouping rule + rule.insertRule('@media screen { a { color: blue; }}',2); + assert_equals(rule.cssRules.length, 3); + const mediaRule = rule.cssRules[2]; + mediaRule.insertRule('z-index: 3;'); + assert_equals(mediaRule.cssRules.length, 2); + assert_throws_dom('SyntaxError', () => { mediaRule.insertRule('nothing-to-insert-because-invalid-property-should-throw: 2;'); }); + }, 'Manipulation of nested declarations through CSSOM'); + </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-nesting/mixed-declarations-rules.html b/third_party/blink/web_tests/external/wpt/css/css-nesting/mixed-declarations-rules.html new file mode 100644 index 0000000..fbc9b547 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-nesting/mixed-declarations-rules.html
@@ -0,0 +1,20 @@ +<!DOCTYPE html> +<title>Mixed declarations and rules</title> +<link rel="help" href="https://drafts.csswg.org/css-nesting/#nested-declarations-rule"> + +<style> +div { + width: 100px; + height: 100px; + background-color: blue; + @media all { + background-color: red; + } + background-color: green; +} +</style> + +<body> + <p>Tests pass if <strong>block is green</strong></p> + <div class="test"></div> +</body>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-selection-in-padded-scroller.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-selection-in-padded-scroller.html new file mode 100644 index 0000000..94e84d27 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scroll-marker-selection-in-padded-scroller.html
@@ -0,0 +1,173 @@ +<!DOCTYPE html> +<html> + +<head> + <meta charset="utf-8"> + <title>CSS Test: scroll tracking for ::scroll-markers when scroll containers has large padding </title> + <link rel="help" href="https://drafts.csswg.org/css-overflow-5/#scroll-marker-pseudo"> + <script src="/resources/testharness.js"></script> + <script src="/resources/testharnessreport.js"></script> + <script src="/resources/testdriver.js"></script> + <script src="/resources/testdriver-actions.js"></script> + <script src="/resources/testdriver-vendor.js"></script> + <script src="support/scroll-marker-support.js"></script> + <script src="/dom/events/scrolling/scroll_support.js"></script> +</head> + +<body> + <style> + .wrapper { + display: grid; + justify-content: center; + } + + .carousel { + display: grid; + grid-auto-flow: column; + width: 1600px; + height: 512px; + overflow-x: scroll; + scroll-snap-type: x mandatory; + list-style-type: none; + scroll-behavior: smooth; + border: solid 2px grey; + padding-top: 10%; + text-align: center; + counter-set: markeridx; + + &>.item { + scroll-snap-align: center; + height: 80%; + width: 318px; + border: 1px solid; + place-content: center; + + &::scroll-marker { + content: counter(markeridx); + counter-increment: markeridx; + align-content: center; + text-align: center; + width: 35px; + height: 35px; + border: 3px solid gray; + border-radius: 50%; + margin: 3px; + background-color: red; + } + + &::scroll-marker:target-current { + background-color: green; + } + } + + &>.padding { + width: 1600px; + height: 90%; + border: solid 1px green; + } + + scroll-marker-group: after; + + &::scroll-marker-group { + height: 45px; + display: flex; + align-items: center; + justify-content: center; + border: solid 1px black; + border-radius: 30px; + } + } + </style> + <div class="wrapper"> + <div class="carousel" id="carousel"> + <div class="padding"></div> + <div class="item" tabindex=0>1</div> + <div class="item" tabindex=0>2</div> + <div class="item" tabindex=0>3</div> + <div class="item" tabindex=0>4</div> + <div class="item" tabindex=0>5</div> + <div class="item" tabindex=0>6</div> + <div class="item" tabindex=0>7</div> + <div class="item" tabindex=0>8</div> + <div class="item" tabindex=0>9</div> + <div class="item" tabindex=0>10</div> + <div class="item" tabindex=0>11</div> + <div class="item" tabindex=0>12</div> + <div class="item" tabindex=0>13</div> + <div class="item" tabindex=0>14</div> + <div class="item" tabindex=0>15</div> + <div class="item" tabindex=0>16</div> + <div class="padding"></div> + </div> + </div> + <script> + const carousel = document.getElementById("carousel"); + const items = carousel.querySelectorAll(".item"); + + RED = "rgb(255, 0, 0)"; + GREEN = "rgb(0, 128, 0)"; + + let current_expected_marker_idx = null; + let current_request_id = null; + + function watchFrames() { + current_request_id = requestAnimationFrame(() => { + if (current_expected_marker_idx !== null) { + verifySelectedMarker(current_expected_marker_idx, items, GREEN, RED); + } + current_request_id = requestAnimationFrame(watchFrames); + }); + } + + // The distribute range[1] is a portion of the scroll range in which we + // determine the active scroll-marker in a way that accounts for unreachable + // scroll targets[2]. + // This tests what happens when we scroll into the distribute range in a + // layout scenario where (because of the padding) there is no scroll target + // in the distribute range. + // [1] https://drafts.csswg.org/css-overflow-5/#:~:text=distribute%20range + // [2] https://github.com/w3c/csswg-drafts/issues/11165 + async function scroll_test(t, scrollAmount) { + await waitForCompositorCommit(); + const initial_offset = carousel.scrollLeft; + + // Watch every frame, verifying the selected marker. + watchFrames(); + + const scrollend_promise = + waitForScrollEndFallbackToDelayWithoutScrollEvent(carousel); + const actions_promise = new test_driver.Actions().scroll(0, 0, + scrollAmount, 0, { origin: carousel }).send(); + + await Promise.all([actions_promise, scrollend_promise]); + + assert_equals(carousel.scrollLeft, initial_offset, + "carousel is snapped back to initial position."); + cancelAnimationFrame(current_request_id); + + current_expected_marker_idx = null; + current_request_id = null; + } + + promise_test(async (t) => { + await waitForCompositorCommit(); + current_expected_marker_idx = 0; + // Scroll left padding into view. + const scrollAmount = -carousel.clientWidth; + await scroll_test(t, scrollAmount); + verifySelectedMarker(0, items, GREEN, RED); + }, "scroll-marker selection at left edge with padding"); + + promise_test(async (t) => { + await waitForCompositorCommit(); + await waitForScrollReset(t, carousel, carousel.scrollWidth, 0); + current_expected_marker_idx = 15; + // Scroll right padding into view. + const scrollAmount = carousel.clientWidth; + await scroll_test(t, scrollAmount); + verifySelectedMarker(15, items, GREEN, RED); + }, "scroll-marker selection at right edge with padding"); + </script> +</body> + +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-both-edges-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-both-edges-ref.html new file mode 100644 index 0000000..7ee4fb7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-both-edges-ref.html
@@ -0,0 +1,50 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Overflow: scrollbar-gutter on the root element</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#scrollbar-gutter-property"> + +<style> + html { + background-color: blue; + margin: 10px; + padding: 10px; + border: 5px solid black; + } + + body { + margin: 10px; + padding: 10px; + border: 5px solid green; + } + + #abspos { + position:absolute; + top: 150px; + left: 15px; + background-color: green; + width: 80px; + height: 100px; + transform: translateZ(0); + } + + p { + background-color: purple; + color: white; + } +</style> + +<div id="outer" style="width: 100px; height: 100px; overflow: scroll; left: -200px; position: absolute;"> + <div id="inner" style="width: 100%; height: 200%;"></div> +</div> + +<script> + var outer = document.getElementById("outer"); + var inner = document.getElementById("inner"); + // Compute scrollbar gutter size and add it as margin to the root element + var scrollbarWidthPlusMargin = String((outer.offsetWidth - inner.offsetWidth) + 10) + "px"; + document.documentElement.style.marginRight = scrollbarWidthPlusMargin; + document.documentElement.style.marginLeft = scrollbarWidthPlusMargin; +</script> + +<p id="content">Should not have space around me in the inline axis.</p> +<div id="abspos"></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-both-edges.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-both-edges.html new file mode 100644 index 0000000..0a312fa7 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-both-edges.html
@@ -0,0 +1,38 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Overflow: scrollbar-gutter on the root element</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#scrollbar-gutter-property"> +<link rel="match" href="scrollbar-gutter-root-both-edges-ref.html"> + +<style> + body,html { + background-color: blue; + margin: 10px; + padding: 10px; + border: 5px solid black; + } + + body{ + border: 5px solid green; + } + + +:root { + scrollbar-gutter: stable both-edges; +} +p { + background-color: purple; + color: white; +} +div { + position:absolute; + left:-20px; + top:150px; + background-color: green; + width: 100px; + height: 100px; + transform: translateZ(0); +} +</style> +<p id="content">Should not have space around me in the inline axis.</p> +<div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-ref.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-ref.html new file mode 100644 index 0000000..06ad9ecb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root-ref.html
@@ -0,0 +1,47 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Overflow: scrollbar-gutter on the root element</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#scrollbar-gutter-property"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1874093"> + +<style> + html { + background-color: blue; + margin: 10px; + padding: 10px; + border: 5px solid black; + } + + body { + margin: 10px; + padding: 10px; + border: 5px solid green; + } + + #abspos { + position:absolute; + top:150px; + left: 0px; + background-color: green; + width: 80px; + height: 100px; + transform: translateZ(0); + } + + p { + background-color: purple; + color: white; + } +</style> +<div id="outer" style="width: 100px; height: 100px; overflow: scroll; left: -200px; position: absolute;"> + <div id="inner" style="width: 100%; height: 200%;"></div> +</div> +<script> + var outer = document.getElementById("outer"); + var inner = document.getElementById("inner"); + // Compute scrollbar gutter size and add it as margin to the root element + document.documentElement.style.marginRight = String((outer.offsetWidth - inner.offsetWidth) + 10) + "px"; +</script> + +<p id="content">Should not have space around me in the inline axis.</p> +<div id="abspos"> </div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root.html new file mode 100644 index 0000000..08c6f48 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/scrollbar-gutter-root.html
@@ -0,0 +1,38 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Overflow: scrollbar-gutter on the root element</title> +<link rel="help" href="https://drafts.csswg.org/css-overflow-4/#scrollbar-gutter-property"> +<link rel="match" href="scrollbar-gutter-root-ref.html"> + +<style> + body,html { + background-color: blue; + margin: 10px; + padding: 10px; + border: 5px solid black; + } + + body{ + border: 5px solid green; + } + + +:root { + scrollbar-gutter: stable; +} +p { + background-color: purple; + color: white; +} +div { + position:absolute; + left:-20px; + top:150px; + background-color: green; + width: 100px; + height: 100px; + transform: translateZ(0); +} +</style> +<p id="content">Should not have space around me in the inline axis.</p> +<div></div>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/support/scroll-marker-support.js b/third_party/blink/web_tests/external/wpt/css/css-overflow/support/scroll-marker-support.js new file mode 100644 index 0000000..2a047f72 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/support/scroll-marker-support.js
@@ -0,0 +1,14 @@ + +// Helper function to assert that the correct scroll-marker among those in the +// provided list is selected. +function verifySelectedMarker(selected_idx, items, selected_color, + unselected_color) { + for (let idx = items.length - 1; idx >= 0; --idx) { + const should_be_selected = idx == selected_idx; + let expected_color = should_be_selected ? selected_color : unselected_color; + const color = + getComputedStyle(items[idx], "::scroll-marker").backgroundColor; + assert_equals(color, expected_color, + `marker ${idx} should be ${should_be_selected ? "" : "un"}selected.`); + } +}
diff --git a/third_party/blink/web_tests/external/wpt/css/css-overflow/targeted-scroll-marker-selection.tentative.html b/third_party/blink/web_tests/external/wpt/css/css-overflow/targeted-scroll-marker-selection.tentative.html index 0f1f664..2364072 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-overflow/targeted-scroll-marker-selection.tentative.html +++ b/third_party/blink/web_tests/external/wpt/css/css-overflow/targeted-scroll-marker-selection.tentative.html
@@ -12,6 +12,7 @@ <script src="/resources/testdriver-vendor.js"></script> <script src="/css/css-transitions/support/helper.js"></script> <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="support/scroll-marker-support.js"></script> </head> <body> @@ -187,17 +188,6 @@ RED = "rgb(255, 0, 0)"; GREEN = "rgb(0, 128, 0)"; - function verifySelectedMarker(selected_idx) { - for (let idx = 0; idx < items.length; idx++) { - const should_be_selected = idx == selected_idx - let expected_color = should_be_selected ? GREEN : RED; - const color = - getComputedStyle(items[idx], "::scroll-marker").backgroundColor; - assert_equals(color, expected_color, - `marker ${idx} should be ${should_be_selected ? "" : "un"}selected.`); - } - } - const max_scroll_offset = carousel.scrollWidth - carousel.clientWidth; async function testTargetedHasActiveMarker(test, element, expected_idx) { // Start from somewhere in the middle, ensuring that scrolling to the @@ -210,7 +200,7 @@ const scrollend_promise = waitForScrollendEventNoTimeout(carousel); element.scrollIntoView({behavior: "smooth"}); await scrollend_promise; - verifySelectedMarker(expected_idx); + verifySelectedMarker(expected_idx, items, GREEN, RED); } promise_test(async(t) => {
diff --git a/third_party/blink/web_tests/external/wpt/css/css-pseudo/input-element-pseudo-open.optional.html b/third_party/blink/web_tests/external/wpt/css/css-pseudo/input-element-pseudo-open.optional.html index 815594f..f590234c5 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-pseudo/input-element-pseudo-open.optional.html +++ b/third_party/blink/web_tests/external/wpt/css/css-pseudo/input-element-pseudo-open.optional.html
@@ -11,6 +11,8 @@ varies across browsers and platforms. This test reflects picker support in desktop chromium. --> +<button>reset</button> + <div class=supported> <input type=date> <input type=datetime-local> @@ -38,8 +40,7 @@ assert_true(input.matches(':open'), 'Should match :open after opening the picker.'); - await test_driver.bless(); - input.blur(); + await test_driver.click(document.querySelector('button')); assert_false(input.matches(':open'), 'Should not match :open after closing the picker.'); }, `CSS :open for <input type=${inputType}>`);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/host-descendant-003.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-descendant-003.html new file mode 100644 index 0000000..eb2cc7d3 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-descendant-003.html
@@ -0,0 +1,31 @@ +<!doctype html> +<meta charset="utf-8"> +<title>:host combined with :not</title> +<link rel="help" href="https://drafts.csswg.org/selectors/#featureless"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<style> +my-host { + display: block; + width: 100px; + height: 100px; + background: red; +} +</style> +<p>Test passes if there is a filled green square.</p> +<my-host id="host"></my-host> +<script> + host.attachShadow({mode: "open"}).innerHTML = ` + <style> + :host > div { + background-color: red; + width: 100%; + height: 100%; + } + :host > :not(span) { + background-color: green; + } + </style> + <div></div> + `; + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-002.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-002.html new file mode 100644 index 0000000..c3f76a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-002.html
@@ -0,0 +1,23 @@ +<!doctype html> +<meta charset="utf-8"> +<title>:host</title> +<link rel="help" href="https://drafts.csswg.org/selectors/#featureless"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div id=host> +</div> +<script> + host.attachShadow({mode: "open"}).innerHTML = ` + <style> + :host { + width: 100px; + height: 100px; + background-color: red; + } + :not(:not(:host)):host { + background-color: green; + } + </style> + `; + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-003.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-003.html new file mode 100644 index 0000000..97774b5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-003.html
@@ -0,0 +1,23 @@ +<!doctype html> +<meta charset="utf-8"> +<title>:host</title> +<link rel="help" href="https://drafts.csswg.org/selectors/#featureless"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div id=host> +</div> +<script> + host.attachShadow({mode: "open"}).innerHTML = ` + <style> + :host { + width: 100px; + height: 100px; + background-color: red; + } + :is(div, :host) { + background-color: green; + } + </style> + `; + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-004.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-004.html new file mode 100644 index 0000000..65a605a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-004.html
@@ -0,0 +1,23 @@ +<!doctype html> +<meta charset="utf-8"> +<title>:host</title> +<link rel="help" href="https://drafts.csswg.org/selectors/#featureless"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div id=host> +</div> +<script> + host.attachShadow({mode: "open"}).innerHTML = ` + <style> + :host { + width: 100px; + height: 100px; + background-color: red; + } + :not(div, :not(:host)) { + background-color: green; + } + </style> + `; + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-005.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-005.html new file mode 100644 index 0000000..d834954f --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-005.html
@@ -0,0 +1,23 @@ +<!doctype html> +<meta charset="utf-8"> +<title>:host</title> +<link rel="help" href="https://drafts.csswg.org/selectors/#featureless"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div id=host> +</div> +<script> + host.attachShadow({mode: "open"}).innerHTML = ` + <style> + :host { + width: 100px; + height: 100px; + background-color: red; + } + :is(:host):host { + background-color: green; + } + </style> + `; + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-006.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-006.html new file mode 100644 index 0000000..c3f76a5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-multiple-006.html
@@ -0,0 +1,23 @@ +<!doctype html> +<meta charset="utf-8"> +<title>:host</title> +<link rel="help" href="https://drafts.csswg.org/selectors/#featureless"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div id=host> +</div> +<script> + host.attachShadow({mode: "open"}).innerHTML = ` + <style> + :host { + width: 100px; + height: 100px; + background-color: red; + } + :not(:not(:host)):host { + background-color: green; + } + </style> + `; + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-scoping/host-not-001.html b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-not-001.html new file mode 100644 index 0000000..a5cfcbd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-scoping/host-not-001.html
@@ -0,0 +1,41 @@ +<!doctype html> +<meta charset="utf-8"> +<title>:host combined with :not</title> +<link rel="help" href="https://drafts.csswg.org/selectors/#featureless"> +<link rel="match" href="/css/reference/ref-filled-green-100px-square-only.html"> +<p>Test passes if there is a filled green square.</p> +<div id=host> +</div> +<script> + host.attachShadow({mode: "open"}).innerHTML = ` + <style> + :host { + width: 100px; + height: 100px; + background-color: green; + } + div:host { + background-color: red; + } + :not(div):host { + background-color: red; + } + :host:not(div) { + background-color: red; + } + :host:is(div) { + background-color: red; + } + :is(div):host { + background-color: red; + } + :host:not(:hover) { + background-color: red; + } + :host:not(:defined) { + background-color: red; + } + </style> + `; + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/segment-break-transformation-punctuation-001-ref.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/segment-break-transformation-punctuation-001-ref.html new file mode 100644 index 0000000..d339aeb --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/segment-break-transformation-punctuation-001-ref.html
@@ -0,0 +1,7 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Segment break transformation: CJK punctuation</title> +<link rel="author" href="mailto:jkew@mozilla.com"> + +<p lang="ja">本システムはサポート切れのブラウザに対応しません。Internet Explorerをお使いの場合、Edge・Chrome・Firefoxなどに移行してください。(EdgeはChromium阪をお使いください)</p> +<p lang="ja">ユーザメイ「ジョン・スミス」、ID「smith」ノアカウントヲショウキョシマス。y/N</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/segment-break-transformation-punctuation-001.html b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/segment-break-transformation-punctuation-001.html new file mode 100644 index 0000000..68e4589 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-text/line-breaking/segment-break-transformation-punctuation-001.html
@@ -0,0 +1,29 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>Segment break transformation: CJK punctuation</title> +<link rel="author" href="mailto:jkew@mozilla.com"> +<link rel="match" href="segment-break-transformation-punctuation-001-ref.html"> +<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1935148"> +<meta name="flags" content="should" /> + +<p lang="ja"> + 本システムはサポート切れのブラウザに対応しません。 + Internet Explorerをお使いの場合、 + Edge + ・ + Chrome + ・ + Firefoxなどに移行してください。 + (EdgeはChromium阪をお使いください) +</p> +<p lang="ja"> + ユーザメイ + 「ジョン + ・ + スミス」 + 、 + ID + 「smith」 + ノアカウントヲショウキョシマス。 + y/N +</p>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name-expected.txt b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name-expected.txt index da8c2b5..3bb4c80 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name-expected.txt +++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name-expected.txt
@@ -1,7 +1,5 @@ This is a testharness.js-based test. [FAIL] Can set 'animation-name' to the 'custom-ident' keyword: custom-ident Failed to execute 'set' on 'StylePropertyMap': Invalid type for property -[FAIL] 'animation-name' does not support '"foo"' - assert_not_equals: Unsupported value must not be null got disallowed value null Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name.html b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name.html index df5d44a..7de53f1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name.html +++ b/third_party/blink/web_tests/external/wpt/css/css-typed-om/the-stylepropertymap/properties/animation-name.html
@@ -20,8 +20,4 @@ { syntax: 'custom-ident' }, ]); -runUnsupportedPropertyTests('animation-name', [ - '"foo"' -]); - </script>
diff --git a/third_party/blink/web_tests/external/wpt/css/css-view-transitions/dynamic-stylesheet-animations.html b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/dynamic-stylesheet-animations.html new file mode 100644 index 0000000..d737d3a --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/css-view-transitions/dynamic-stylesheet-animations.html
@@ -0,0 +1,116 @@ +<!DOCTYPE html> +<html> +<title>View transitions: Dynamic stylesheet sets correct animations</title> +<link rel="author" title="Tim Nguyen" href="https://github.com/nt1m"> +<link rel="help" href="https://drafts.csswg.org/css-view-transitions/#setup-transition-pseudo-elements-algorithm"> + +<style> +:root { view-transition-name: none; } +#target { + view-transition-name: target; + background: red; + width: 100px; + height: 100px; +} +html::view-transition-group(*) { + animation-timing-function: steps(2, start); + animation-play-state: paused; +} +html::view-transition-old(*), +html::view-transition-new(*) { + animation-play-state: paused; +} +</style> + +<div id="target"></div> + +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> +promise_test(async () => { + let vt = document.startViewTransition(() => { + target.style.backgroundColor = "green"; + }); + + await vt.ready; + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-group(target)").animationName, + "-ua-view-transition-group-anim-target", + "Animation on group when there are 2 snapshots" + ); + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-old(target)").animationName, + "-ua-view-transition-fade-out, -ua-mix-blend-mode-plus-lighter", + "Two animations when there are 2 snapshots" + ); + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-new(target)").animationName, + "-ua-view-transition-fade-in, -ua-mix-blend-mode-plus-lighter", + "Two animations when there are 2 snapshots" + ); + await vt.skipTransition(); +}, "Both old and new snapshots"); + +promise_test(async () => { + let vt = await document.startViewTransition(() => { + target.remove(); + }); + + await vt.ready; + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-group(target)").animationName, + "none", + "No animation on group when one snapshot is missing" + ); + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-old(target)").animationName, + "-ua-view-transition-fade-out", + "Only one animation for old snapshot when new snapshot is missing" + ); + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-new(target)").animationName, + "none", + "No animation since the snapshot is not generated" + ); + + await vt.skipTransition(); +}, "Only old snapshot"); + +promise_test(async () => { + let vt = await document.startViewTransition(() => { + const div = document.createElement("div"); + div.id = "target"; + document.body.append(div); + }); + + await vt.ready; + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-group(target)").animationName, + "none", + "No animation on group when one snapshot is missing" + ); + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-old(target)").animationName, + "none", + "No animation since the snapshot is not generated" + ); + + assert_equals( + getComputedStyle(document.documentElement, "::view-transition-new(target)").animationName, + "-ua-view-transition-fade-in", + "Only one animation for new snapshot when old snapshot is missing" + ); + await vt.skipTransition(); +}, "Only new snapshot"); +</script> + +</body> +</html>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-all-shorthand-expected.txt b/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-all-shorthand-expected.txt new file mode 100644 index 0000000..731b006 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-all-shorthand-expected.txt
@@ -0,0 +1,7 @@ +This is a testharness.js-based test. +[FAIL] getPropertyValue('all') returns empty string when single property overriden + assert_equals: expected "" but got "revert" +[FAIL] setProperty('all') sets all property values + assert_equals: expected "revert" but got "" +Harness: the test ran to completion. +
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-all-shorthand.html b/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-all-shorthand.html new file mode 100644 index 0000000..05d64587 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-all-shorthand.html
@@ -0,0 +1,54 @@ +<!DOCTYPE html> +<title>CSSOM Test: Passing "all" shorthand to property methods</title> +<link rel="help" href="https://drafts.csswg.org/css-cascade/#all-shorthand"> +<link rel="help" href="https://drafts.csswg.org/cssom/#dom-cssstyledeclaration-removeproperty"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + const style = document.createElement("div").style; + + test((t) => { + t.add_cleanup(() => { style.cssText = ""; } ); + style.cssText = "width: 50px"; + assert_equals(style.getPropertyValue("all"), ""); + }, "getPropertyValue('all') returns empty string"); + + test((t) => { + t.add_cleanup(() => { style.cssText = ""; } ); + style.cssText = "all: revert"; + assert_equals(style.getPropertyValue("all"), "revert"); + }, "getPropertyValue('all') returns css-wide keyword if possible"); + + test((t) => { + t.add_cleanup(() => { style.cssText = ""; } ); + style.cssText = "all: revert; width: 50px"; + assert_equals(style.getPropertyValue("all"), ""); + }, "getPropertyValue('all') returns empty string when single property overriden"); + + test((t) => { + t.add_cleanup(() => { style.cssText = ""; } ); + style.setProperty("all", "revert"); + assert_equals(style.getPropertyValue("width"), "revert"); + assert_equals(style.getPropertyValue("color"), "revert"); + }, "setProperty('all') sets all property values"); + + test((t) => { + t.add_cleanup(() => { style.cssText = ""; } ); + style.cssText = "width: 50px; color: green; direction: rtl"; + assert_equals(style.getPropertyValue("width"), "50px"); + assert_equals(style.getPropertyValue("color"), "green"); + assert_equals(style.getPropertyValue("direction"), "rtl"); + style.removeProperty("all"); + assert_equals(style.getPropertyValue("width"), ""); + assert_equals(style.getPropertyValue("color"), ""); + assert_equals(style.getPropertyValue("direction"), "rtl"); + }, "removeProperty('all') removes all declarations affected by 'all'"); + + test((t) => { + t.add_cleanup(() => { style.cssText = ""; } ); + style.cssText = "all: revert"; + style.removeProperty("all"); + assert_equals(style.getPropertyValue("all"), ""); + }, "removeProperty('all') removes an 'all' declaration"); + +</script>
diff --git a/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-removeProperty-all.html b/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-removeProperty-all.html new file mode 100644 index 0000000..6e9caac --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/cssom/cssstyledeclaration-removeProperty-all.html
@@ -0,0 +1,17 @@ +<!DOCTYPE html> +<meta charset="utf-8"> +<title>CSSStyleDeclaration.removeProperty("all")</title> +<link rel="author" title="Emilio Cobos Álvarez" href="mailto:emilio@crisal.io"> +<link rel="author" title="Mozilla" href="https://mozilla.org"> +<link rel="help" href="https://drafts.csswg.org/cssom-1/#dom-cssstyledeclaration-removeproperty"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<script> + test(function() { + let style = document.createElement("div").style; + style.width = "40px"; + assert_equals(style.length, 1, "setter should work as expected"); + style.removeProperty("all"); + assert_equals(style.length, 0, "all is a shorthand of all properties, so should remove the property"); + }); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scroll_support.js b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scroll_support.js index 1cde3a1..c94803a 100644 --- a/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scroll_support.js +++ b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/scroll_support.js
@@ -63,7 +63,7 @@ // promise is not resolved until the scrollend event is received. async function waitForScrollReset(test, scroller, x = 0, y = 0) { return new Promise(resolve => { - if (scroller.scrollTop == x && scroller.scrollLeft == y) { + if (scroller.scrollLeft == x && scroller.scrollTop == y) { resolve(); } else { const eventTarget =
diff --git a/third_party/blink/web_tests/external/wpt/editing/data/multitest.js b/third_party/blink/web_tests/external/wpt/editing/data/multitest.js index 2d5404b..5d0a60bf 100644 --- a/third_party/blink/web_tests/external/wpt/editing/data/multitest.js +++ b/third_party/blink/web_tests/external/wpt/editing/data/multitest.js
@@ -3250,4 +3250,11 @@ "<table><tbody><tr><th>a</th><th><br></th><th><br></th><th><b>B</b></th><th>e</th></tr></tbody></table>"], [true,true], {}], + +// Preseve the collapsible white-space after the style is cleared. +["<p><b>abc[]</b></p>", + [["inserttext"," "],["bold",""],["inserttext","d"]], + "<p><b>abc </b>d</p>", + [true,true,true], + {}], ]
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative.html index b335db07..a6292902 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative.html
@@ -7,21 +7,55 @@ <script src="/resources/testdriver.js"></script> <script src="/resources/testdriver-vendor.js"></script> <style> - select, - select::picker(select) { + select, select::picker(select) { appearance: base-select; } </style> + <select id="target"> <div></div> <span></span> - <a id="interactive1" href="https://www.example.com/">Interactive element</a> + <a id="interactive1" href="https://www.example.com/">Elephant</a> <option id="option1">Tiger</option> + <option id="option2">Kangaroo</option> + <button id="interactive2">Dolphin</button> + <option id="option3">Giraffe</option> + <button id="interactive3">Panda</button> + <hr/> + <button id="interactive4">Zebra</button> + <button id="interactive5">Koala</button> + <option id="option4"> + <button id="interactive6">Hippopotamus</button> + </option> + <option id="option5">Rhinoceros</option> + <option id="option6"> + <button id="interactive7">Flamingo</button> + </option> + <option id="option7"> + <button id="interactive8">Crocodile</button> + </option> + <optgroup> + <option id="option8">Polar Bear</option> + </optgroup> + <option id="option9"> + <button id="interactive9">Chimpanzee</button> + </option> + <optgroup> + <option id="option10"> + <button id="interactive10">Ostrich</button> + </option> + </optgroup> + <optgroup> + <option id="option11"> + <button id="interactive11">Wolf</button> + </option> + </optgroup> </select> + <script> -const Enter = '\uE007'; const Space = ' '; const Tab = '\uE004'; +const ArrowDown = '\uE015'; promise_test(async (t) => { assert_false( @@ -42,8 +76,195 @@ interactive1, 'The anchor should be focused.' ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + option1, + 'The option should be focused.' + ); + await test_driver.send_keys(document.activeElement, Space); + assert_false( + target.matches(':open'), + 'The select should be closed.' + ); }, 'In dialog mode the first focusable element should get focus.'); +promise_test(async (t) => { + assert_false( + target.matches(':open'), + 'The select should initially be closed.' + ); + + target.focus(); + assert_equals( + document.activeElement, + target, + 'The select should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Space); + assert_equals( + document.activeElement, + interactive1, + 'The anchor should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + option1, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + option2, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive2, + 'The button should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + option3, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive3, + 'The anchor should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive4, + 'The anchor should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive5, + 'The button should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + option4, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive6, + 'The button should be focused.' + ); + + await test_driver.send_keys(document.activeElement, ArrowDown); + assert_equals( + document.activeElement, + option5, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + option6, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive7, + 'The button should be focused.' + ); + + await test_driver.send_keys(document.activeElement, ArrowDown); + assert_equals( + document.activeElement, + option7, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive8, + 'The button should be focused.' + ); + + await test_driver.send_keys(document.activeElement, ArrowDown); + assert_equals( + document.activeElement, + option8, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, ArrowDown); + assert_equals( + document.activeElement, + option9, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive9, + 'The button should be focused.' + ); + + await test_driver.send_keys(document.activeElement, ArrowDown); + assert_equals( + document.activeElement, + option10, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive10, + 'The button should be focused.' + ); + + await test_driver.send_keys(document.activeElement, ArrowDown); + assert_equals( + document.activeElement, + option11, + 'The option should be focused.' + ); + + await test_driver.send_keys(document.activeElement, Tab); + assert_equals( + document.activeElement, + interactive11, + 'The button should be focused.' + ); + + option11.focus(); + await test_driver.send_keys(document.activeElement, Space); + assert_false( + target.matches(':open'), + 'The select should be closed.' + ); +}, 'In dialog mode tab should not close the picker.'); + </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative-expected.txt b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative-expected.txt deleted file mode 100644 index 8cdb454e..0000000 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative-expected.txt +++ /dev/null
@@ -1,17 +0,0 @@ -This is a testharness.js-based test. -[FAIL] Basic functionality of select picker with appearance:auto - assert_equals: expected "none" but got "base-select" -[FAIL] Basic functionality of select picker with appearance:none - assert_equals: expected "none" but got "base-select" -[FAIL] Switching appearance in popover-open should close the picker - assert_equals: expected "none" but got "base-select" -[FAIL] Switching appearance in JS after picker is open should close the picker - assert_equals: expected "none" but got "base-select" -[FAIL] The select picker is closed if the <select> appearance value is changed via CSS while the picker is open - assert_false: picker should get closed when the appearance value changes expected false got true -[FAIL] The select picker is closed if the ::picker() appearance value is changed via CSS while the picker is open - assert_false: setup expected false got true -[FAIL] The select picker is closed if the <select> inline appearance value is changed while the picker is open - assert_false: setup expected false got true -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative.html index 75cb63f..09bea44 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/customizable-select/switch-picker-appearance.tentative.html
@@ -14,10 +14,10 @@ </select> <style> - select#test1::picker(select) { + #test1::picker(select) { background-color: red; } - select#test1::picker(select):popover-open { + #test1::picker(select):popover-open { background-color: green; } </style> @@ -33,7 +33,7 @@ t.add_cleanup(() => style.remove()); assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red); - style.innerHTML = '::picker(select) {appearance: base-select}'; + style.innerHTML = '#test1::picker(select) {appearance: base-select}'; assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'base-select'); assert_equals(getComputedStyle(select1,'::picker(select)').backgroundColor,red,'still closed, so popover-open doesn\'t match'); @@ -57,7 +57,7 @@ document.head.append(style); t.add_cleanup(() => style.remove()); assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); - style.innerHTML = '::picker(select) {appearance: auto}'; + style.innerHTML = '#test1::picker(select) {appearance: auto}'; assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'auto'); await test_driver.bless('showPicker'); select1.showPicker(); @@ -72,7 +72,7 @@ document.head.append(style); t.add_cleanup(() => style.remove()); assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); - style.innerHTML = '::picker(select) {appearance: none}'; + style.innerHTML = '#test1::picker(select) {appearance: none}'; assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); await test_driver.bless('showPicker'); select1.showPicker(); @@ -88,8 +88,8 @@ t.add_cleanup(() => style.remove()); assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); style.innerHTML = ` - ::picker(select) {appearance: base-select} - ::picker(select):popover-open {appearance: auto} + #test1::picker(select) {appearance: base-select} + #test1::picker(select):popover-open {appearance: auto} `; assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'base-select'); await test_driver.bless('showPicker'); @@ -109,18 +109,17 @@ document.head.append(style); t.add_cleanup(() => style.remove()); assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); - style.innerHTML = '::picker(select) {appearance: none}'; + style.innerHTML = '#test1::picker(select) {appearance: base-select}'; assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'base-select'); await test_driver.bless('showPicker'); select1.showPicker(); assert_true(select1.matches(':open')); style.remove(); - assert_false(select1.matches(':open'),'changing appearance while the picker is open should close it'); assert_equals(getComputedStyle(select1,'::picker(select)').appearance,'none'); + assert_false(select1.matches(':open'),'changing appearance while the picker is open should close it'); }, 'Switching appearance in JS after picker is open should close the picker'); </script> - <button id=reset>Reset</button> <select id=test2> <button><selectedcontent></selectedcontent></button> @@ -130,13 +129,13 @@ </select> <style> - select#test2, ::picker(select) { + #test2, #test2::picker(select) { appearance: base-select; } - select#test2.controlswitch:open { + #test2.controlswitch:open { appearance: auto; } - select#test2.pickerswitch:open::picker(select) { + #test2.pickerswitch:open::picker(select) { appearance: auto; } </style> @@ -200,7 +199,7 @@ assert_equals(getComputedStyle(select2).appearance,'base-select'); t.add_cleanup(() => select2.removeAttribute('style')); select2.setAttribute('style','appearance:auto'); - assert_false(select2.matches(':open'),'Adding inline style should close the picker'); assert_equals(getComputedStyle(select2).appearance,'auto','appearance should still be auto from inline style'); + assert_false(select2.matches(':open'),'Adding inline style should close the picker'); },'The select picker is closed if the <select> inline appearance value is changed while the picker is open'); </script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative.html index 5c2e70f..4ccac5b3 100644 --- a/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative.html +++ b/third_party/blink/web_tests/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative.html
@@ -7,14 +7,20 @@ <script src="/resources/testdriver-vendor.js"></script> <button>button</button> -<dialog>hello world</dialog> +<dialog> + <button>button in dialog</button> +</dialog> <script> const dialog = document.querySelector('dialog'); const button = document.querySelector('button'); +const dialogbutton = document.querySelector('dialog > button'); promise_test(async t => { + button.focus(); dialog.showModal(); + assert_equals(document.activeElement, dialogbutton, + '<button> in <dialog> should be focused after opening.'); let closeFired = false; let cancelFired = false; @@ -22,9 +28,13 @@ dialog.addEventListener('cancel', () => cancelFired = true); dialog.removeAttribute('open'); + assert_equals(document.activeElement, dialogbutton, + '<button> in <dialog> should still be focused immediately after removing open.'); await new Promise(resolve => t.step_timeout(resolve, 0)); await new Promise(requestAnimationFrame); + assert_equals(document.activeElement, button, + 'Previously focused element should be focused after waiting for a task.'); assert_false(dialog.matches(':modal'), 'The dialog should not match :modal after closing.'); assert_false(cancelFired, @@ -40,7 +50,10 @@ }, 'Removing the open attribute from an open modal dialog should run the closing algorithm.'); promise_test(async t => { + button.focus(); dialog.show(); + assert_equals(document.activeElement, dialogbutton, + '<button> in <dialog> should be focused after opening.'); let closeFired = false; let cancelFired = false; @@ -48,9 +61,13 @@ dialog.addEventListener('cancel', () => cancelFired = true); dialog.removeAttribute('open'); + assert_equals(document.activeElement, dialogbutton, + '<button> in <dialog> should still be focused immediately after removing open.'); await new Promise(resolve => t.step_timeout(resolve, 0)); await new Promise(requestAnimationFrame); + assert_equals(document.activeElement, button, + 'Previously focused element should be focused after waiting for a task.'); assert_false(cancelFired, 'The cancel event should not fire when removing the open attribute.'); assert_true(closeFired,
diff --git a/third_party/blink/web_tests/external/wpt/lint.ignore b/third_party/blink/web_tests/external/wpt/lint.ignore index 759ef41c..0019090 100644 --- a/third_party/blink/web_tests/external/wpt/lint.ignore +++ b/third_party/blink/web_tests/external/wpt/lint.ignore
@@ -302,6 +302,7 @@ SET TIMEOUT: xhr/resources/init.htm SET TIMEOUT: xhr/resources/xmlhttprequest-timeout.js SET TIMEOUT: fenced-frame/resolve-to-config-promise.https.html +SET TIMEOUT: partitioned-popins/partitioned-popins.partitions.tentative.https.window.js # generate_tests implementation and sample usage GENERATE_TESTS: resources/test/tests/functional/generate-callback.html
diff --git a/third_party/blink/web_tests/external/wpt/partitioned-popins/partitioned-popins.partitions.tentative.https.window.js b/third_party/blink/web_tests/external/wpt/partitioned-popins/partitioned-popins.partitions.tentative.https.window.js index a414d9a..0f1a7c0a 100644 --- a/third_party/blink/web_tests/external/wpt/partitioned-popins/partitioned-popins.partitions.tentative.https.window.js +++ b/third_party/blink/web_tests/external/wpt/partitioned-popins/partitioned-popins.partitions.tentative.https.window.js
@@ -28,7 +28,11 @@ /*options=*/ { features: "popin" }); assert_equals(await popin.executeScript(() => { return window.popinContextType(); }), "partitioned"); test.add_cleanup(async () => { - await popin.executeScript(() => { window.close(); }); + await popin.executeScript(() => { + // We need to delay the window closing until the next event cycle to + // ensure the execution of the script via remote context returns properly. + setTimeout(() => window.close(), 0); + }); }); return popin; }
diff --git a/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin-iframe.html b/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin-iframe.html index 5a2fa1c..174e97d 100644 --- a/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin-iframe.html +++ b/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin-iframe.html
@@ -16,7 +16,7 @@ message += getCookieMessage(document.cookie, "FirstParty", "", id); message += getCookieMessage(document.cookie, "ThirdParty", "", id); await test_driver.set_permission({ name: 'storage-access' }, 'granted'); - await test_driver.bless("fake user interaction", () => document.requestStorageAccess()); + await document.requestStorageAccess(); document.cookie = "FirstPartyStrictAfterRSA=" + id + "; SameSite=Strict; Secure"; document.cookie = "FirstPartyLaxAfterRSA=" + id + "; SameSite=Lax; Secure"; document.cookie = "FirstPartyNoneAfterRSA=" + id + "; SameSite=None; Secure";
diff --git a/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin.sub.py b/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin.sub.py index cebcb411..54188d3 100644 --- a/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin.sub.py +++ b/third_party/blink/web_tests/external/wpt/partitioned-popins/resources/partitioned-popins.cookies-popin.sub.py
@@ -43,7 +43,7 @@ message += getCookieMessage(document.cookie, "FirstParty", "Popin", id); message += getCookieMessage(document.cookie, "ThirdParty", "Popin", id); await test_driver.set_permission({ name: 'storage-access' }, 'granted'); - await test_driver.bless("fake user interaction", () => document.requestStorageAccess()); + await document.requestStorageAccess(); document.cookie = "FirstPartyStrictPopinAfterRSA=" + id + "; SameSite=Strict; Secure"; document.cookie = "FirstPartyLaxPopinAfterRSA=" + id + "; SameSite=Lax; Secure"; document.cookie = "FirstPartyNonePopinAfterRSA=" + id + "; SameSite=None; Secure";
diff --git a/third_party/blink/web_tests/external/wpt/shadow-dom/getElementById-dynamic-002.html b/third_party/blink/web_tests/external/wpt/shadow-dom/getElementById-dynamic-002.html new file mode 100644 index 0000000..8fb1934 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/shadow-dom/getElementById-dynamic-002.html
@@ -0,0 +1,20 @@ +<!doctype html> +<title>Shadow DOM: Modifying an element ID inside a disconnected shadow root does not break getElementById</title> +<link rel="help" href="https://dom.spec.whatwg.org/#dom-nonelementparentnode-getelementbyid"> +<link rel="author" name="Simon Wülker"> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> +<div id="host"></div> +<script> +test(function() { + let host = document.getElementById("host"); + host.attachShadow({ mode: "open" }).innerHTML = `<div id="test-id"></div>`; + let element = host.shadowRoot.getElementById("test-id"); + assert_true(!!element); + + host.remove(); + host.shadowRoot.getElementById("test-id").id = "new-id"; + + assert_equals(host.shadowRoot.getElementById("new-id"), element); +}, "ShadowRoot.getElementById works on elements whose id was modified after the root was disconnected"); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/GlobalEventHandlers-onclick.html b/third_party/blink/web_tests/external/wpt/trusted-types/GlobalEventHandlers-onclick.html index 0fdde77..83b9572 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/GlobalEventHandlers-onclick.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/GlobalEventHandlers-onclick.html
@@ -19,74 +19,29 @@ el.setAttribute('onclick', script); container.appendChild(el); el.click(); -}, "a.setAttribte('onclick') sets a trusted script."); +}, "a.setAttribute('onclick') sets a trusted script."); // Unsuitable TrustedType assignments do throw. -async_test(t => { +test(t => { window.onclickFail1 = t.unreached_func(); let script = policy_html.createHTML("window.onclickFail1();"); let el = document.createElement('a'); - try { + assert_throws_js(TypeError, () => { el.setAttribute('onclick', script); container.appendChild(el); el.click(); - } catch (e) { - t.done(); - } - assert_unreached(); + }); }, "a.setAttribute('onclick') sets an unsuitable trusted type."); // So do plain test assignments. -async_test(t => { +test(t => { window.onclickFail2 = t.unreached_func(); let el = document.createElement('a'); - try { + assert_throws_js(TypeError, () => { el.setAttribute("onclick", "window.onclickFail2();"); container.appendChild(el); el.click(); - } catch (e) { - t.done(); - } - assert_unreached(); + }); }, "a.setAttribute('click') sets a test string."); -/* -// Trusted Type assignments via property access does not throw. -async_test(t => { - window.onclickDone2 = t.step_func_done(); - let script = policy.createScript("window.onclickDone2();"); - let el = document.createElement('a'); - el.onclick = script; - container.appendChild(el); - el.click(); -}, "a.onclick assigned via policy (successful Script transformation)."); -// Unsuitable TrustedType assignments do throw. -async_test(t => { - window.onclickFail3 = t.unreached_func(); - let script = policy_html.createHTML("window.onclickFail3();"); - let el = document.createElement('a'); - try { - el.onclick = script; - container.appendChild(el); - el.click(); - } catch (e) { - t.done(); - } - assert_unreached(); -}, "a.onclick assigned via an unsuitable policy."); - -// So do plain test assignments. -async_test(t => { - window.onclickFail4 = t.unreached_func(); - let el = document.createElement('a'); - try { - el.onclick = window.onclickFail4(); - container.appendChild(el); - el.click(); - } catch (e) { - t.done(); - } - assert_unreached(); -}, "a.onclick assigned a test string."); -*/ </script>
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-callback-arguments.html b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-callback-arguments.html index 3e591bd..7a256ee 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-callback-arguments.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-callback-arguments.html
@@ -17,17 +17,6 @@ assert_equals(args[0], current_case[0], "Expecting the value."); assert_equals(args[1], current_case[1], "Expecting the type name."); assert_equals(args[2], current_case[2], "Expecting the sink name."); - switch (args[1]) { - case TrustedScriptURL: - assert_equals(args[2], 'HTMLScriptElement src'); - break; - case TrustedHTML: - assert_equals(args[2], 'Element innerHTML'); - break; - case TrustedScript: - assert_equals(args[2], 'HTMLScriptElement text'); - break; - } return args[0]; }
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.html b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.html index 9d5f83e8..3716e1b 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy-report-only.html
@@ -54,7 +54,7 @@ }); // A trusted type policy that forces a number of edge cases. -function policy(str, type, sink) { +function policy(str, trustedTypeName, sink) { if (str == "throw") throw RangeError(); else if (str == "null") @@ -66,16 +66,18 @@ else if (str == "done") return null; else { - switch (type) { - case TrustedScriptURL: + switch (trustedTypeName) { + case "TrustedScriptURL": assert_equals(sink, 'HTMLScriptElement src'); break; - case TrustedHTML: + case "TrustedHTML": assert_equals(sink, 'Element innerHTML'); break; - case TrustedScript: + case "TrustedScript": assert_equals(sink, 'HTMLScriptElement text'); break; + default: + assert_unreached(`Unknown trusted type name '${trustedTypeName}'`); } return "sanitized: " + str; }
diff --git a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.html b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.html index 47fdf1b1..19643c9 100644 --- a/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.html +++ b/third_party/blink/web_tests/external/wpt/trusted-types/default-policy.html
@@ -54,7 +54,7 @@ }); // A trusted type policy that forces a number of edge cases. -function policy(str, type, sink) { +function policy(str, trustedTypeName, sink) { if (str == "throw") throw RangeError(); else if (str == "null") @@ -66,16 +66,18 @@ else if (str == "done") return null; else { - switch (type) { - case TrustedScriptURL: + switch (trustedTypeName) { + case "TrustedScriptURL": assert_equals(sink, 'HTMLScriptElement src'); break; - case TrustedHTML: + case "TrustedHTML": assert_equals(sink, 'Element innerHTML'); break; - case TrustedScript: + case "TrustedScript": assert_equals(sink, 'HTMLScriptElement text'); break; + default: + assert_unreached(`Unknown trusted type name '${trustedTypeName}'`); } return "sanitized: " + str; }
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/navigation_failed/navigation_failed.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/navigation_failed/navigation_failed.py index bf72e6e4..85cab4d 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/navigation_failed/navigation_failed.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/browsing_context/navigation_failed/navigation_failed.py
@@ -9,6 +9,7 @@ pytestmark = pytest.mark.asyncio +NAVIGATION_ABORTED_EVENT = "browsingContext.navigationAborted" NAVIGATION_FAILED_EVENT = "browsingContext.navigationFailed" NAVIGATION_STARTED_EVENT = "browsingContext.navigationStarted" USER_PROMPT_OPENED_EVENT = "browsingContext.userPromptOpened" @@ -233,12 +234,26 @@ slow_page_url = url( "/webdriver/tests/bidi/browsing_context/support/empty.html?pipe=trickle(d10)" ) - await subscribe_events(events=[NAVIGATION_FAILED_EVENT]) + # Depending on implementation, the `trickle(d10)` page can or can not yet + # create a new document. Depending on this, `aborted` or `failed` event + # should be emitted. + await subscribe_events( + events=[NAVIGATION_ABORTED_EVENT, NAVIGATION_FAILED_EVENT]) result = await bidi_session.browsing_context.navigate( context=new_tab["context"], url=slow_page_url, wait="none" ) - on_navigation_failed = wait_for_event(NAVIGATION_FAILED_EVENT) + + events = [] + + async def on_event(method, data): + events.append(data) + + remove_listener_1 = bidi_session.add_event_listener( + NAVIGATION_ABORTED_EVENT, on_event) + remove_listener_2 = bidi_session.add_event_listener(NAVIGATION_FAILED_EVENT, + on_event) + second_url = inline("<div>foo</div>") # Trigger the second navigation which should fail the first one. @@ -246,11 +261,13 @@ context=new_tab["context"], url=second_url, wait="none" ) - event = await wait_for_future_safe(on_navigation_failed) + wait = AsyncPoll(bidi_session, timeout=1) + await wait.until(lambda _: len(events) > 0) + assert len(events) == 1 - # Make sure that the first navigation failed. + # Make sure that the first navigation failed or aborted. assert_navigation_info( - event, + events[0], { "context": new_tab["context"], "navigation": result["navigation"], @@ -258,6 +275,9 @@ }, ) + remove_listener_1() + remove_listener_2() + async def test_with_new_navigation_inside_page( bidi_session, @@ -282,18 +302,34 @@ </html> """ ) - await subscribe_events(events=[NAVIGATION_FAILED_EVENT]) - on_navigation_failed = wait_for_event(NAVIGATION_FAILED_EVENT) + + # Depending on implementation, the `trickle(d10)` page can or can not yet + # create a new document. Depending on this, `aborted` or `failed` event + # should be emitted. + await subscribe_events( + events=[NAVIGATION_ABORTED_EVENT, NAVIGATION_FAILED_EVENT]) + + events = [] + + async def on_event(method, data): + events.append(data) + + remove_listener_1 = bidi_session.add_event_listener( + NAVIGATION_ABORTED_EVENT, on_event) + remove_listener_2 = bidi_session.add_event_listener(NAVIGATION_FAILED_EVENT, + on_event) result = await bidi_session.browsing_context.navigate( context=new_tab["context"], url=slow_page_url, wait="none" ) - event = await wait_for_future_safe(on_navigation_failed) + wait = AsyncPoll(bidi_session, timeout=1) + await wait.until(lambda _: len(events) > 0) + assert len(events) == 1 # Make sure that the first navigation failed. assert_navigation_info( - event, + events[0], { "context": new_tab["context"], "navigation": result["navigation"], @@ -301,6 +337,9 @@ }, ) + remove_listener_1() + remove_listener_2() + @pytest.mark.parametrize("type_hint", ["tab", "window"]) async def test_close_context( @@ -315,19 +354,35 @@ slow_page_url = url( "/webdriver/tests/bidi/browsing_context/support/empty.html?pipe=trickle(d10)" ) - await subscribe_events(events=[NAVIGATION_FAILED_EVENT]) + # Depending on implementation, the `trickle(d10)` page can or can not yet + # create a new document. Depending on this, `aborted` or `failed` event + # should be emitted. + await subscribe_events( + events=[NAVIGATION_ABORTED_EVENT, NAVIGATION_FAILED_EVENT]) result = await bidi_session.browsing_context.navigate( context=new_context["context"], url=slow_page_url, wait="none" ) - on_navigation_failed = wait_for_event(NAVIGATION_FAILED_EVENT) + events = [] + + async def on_event(method, data): + events.append(data) + + remove_listener_1 = bidi_session.add_event_listener( + NAVIGATION_ABORTED_EVENT, on_event) + remove_listener_2 = bidi_session.add_event_listener(NAVIGATION_FAILED_EVENT, + on_event) + await bidi_session.browsing_context.close(context=new_context["context"]) - event = await wait_for_future_safe(on_navigation_failed) + + wait = AsyncPoll(bidi_session, timeout=1) + await wait.until(lambda _: len(events) > 0) + assert len(events) == 1 # Make sure that the navigation failed. assert_navigation_info( - event, + events[0], { "context": new_context["context"], "navigation": result["navigation"], @@ -335,6 +390,9 @@ }, ) + remove_listener_1() + remove_listener_2() + async def test_close_iframe( bidi_session, @@ -348,9 +406,13 @@ iframe_url = inline("<div>foo</div>") page_url = inline(f"<iframe src={iframe_url}></iframe") - await subscribe_events(events=[NAVIGATION_FAILED_EVENT]) + # Depending on implementation, the `trickle(d10)` page can or can not yet + # create a new document. Depending on this, `aborted` or `failed` event + # should be emitted. + await subscribe_events( + events=[NAVIGATION_ABORTED_EVENT, NAVIGATION_FAILED_EVENT]) - result = await bidi_session.browsing_context.navigate( + await bidi_session.browsing_context.navigate( context=new_tab["context"], url=page_url, wait="complete" ) @@ -365,14 +427,26 @@ context=iframe_context, url=slow_page_url, wait="none" ) - on_navigation_failed = wait_for_event(NAVIGATION_FAILED_EVENT) + events = [] + + async def on_event(method, data): + events.append(data) + + remove_listener_1 = bidi_session.add_event_listener( + NAVIGATION_ABORTED_EVENT, on_event) + remove_listener_2 = bidi_session.add_event_listener(NAVIGATION_FAILED_EVENT, + on_event) + # Reload the top context to destroy the iframe. await bidi_session.browsing_context.reload(context=new_tab["context"], wait="none") - event = await wait_for_future_safe(on_navigation_failed) + + wait = AsyncPoll(bidi_session, timeout=1) + await wait.until(lambda _: len(events) > 0) + assert len(events) == 1 # Make sure that the iframe navigation failed. assert_navigation_info( - event, + events[0], { "context": iframe_context, "navigation": result["navigation"], @@ -380,6 +454,9 @@ }, ) + remove_listener_1() + remove_listener_2() + @pytest.mark.capabilities({"unhandledPromptBehavior": {"beforeUnload": "ignore"}}) async def test_with_beforeunload_prompt(
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/invalid.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/invalid.py index 0ed9fa3..ad7dab39 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/invalid.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/invalid.py
@@ -377,9 +377,16 @@ @pytest.mark.parametrize( "value", - ["fa", "\u0BA8\u0BBFb", "\u0BA8\u0BBF\u0BA8", "\u1100\u1161\u11A8c"], + [ + "fa", # 2 symbols. + "\U0001F604a", # "😄a" a codepoint with a symbol. + "\u0BA8\u0BBFa", # "நிa" a grapheme with a symbol. + "\u1100\u1161\u11A8a", # "각a" a grapheme with a symbol. + "\u2764\ufe0fa", # "❤️a" a grapheme with a symbol. + "\U0001F604\U0001F60D", # "😄😍" 2 graphemes. + ], ) -async def test_params_key_action_value_invalid_multiple_codepoints( +async def test_params_key_action_value_invalid_multiple_graphemes( perform_actions, value): actions = [ create_key_action("keyDown", {"value": value}),
diff --git a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/key.py b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/key.py index 567400c..beadf27 100644 --- a/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/key.py +++ b/third_party/blink/web_tests/external/wpt/webdriver/tests/bidi/input/perform_actions/key.py
@@ -71,13 +71,13 @@ @pytest.mark.parametrize( "value", [ - ("\U0001F604"), - ("\U0001F60D"), - ("\u0BA8\u0BBF"), - ("\u1100\u1161\u11A8"), + "\U0001F604", # "😄" (\ud83d\ude04), a single surrogate codepoint. + "\u0BA8\u0BBF", # "நி" (\u0BA8\u0BBF), a grapheme containing several chars. + "\u1100\u1161\u11A8", # "각" (\u1100\u1161\u11A8), a grapheme containing several chars. + "\u2764\ufe0f", # "❤️" (\u2764\ufe0f), a grapheme containing several codepoints. ], ) -async def test_key_codepoint( +async def test_key_grapheme( bidi_session, top_context, setup_key_test, value ): # Not using send_keys() because we always want to treat value as
diff --git a/third_party/blink/web_tests/platform/linux/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box-expected.txt b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box-expected.txt new file mode 100644 index 0000000..4c1d9d7 --- /dev/null +++ b/third_party/blink/web_tests/platform/linux/external/wpt/css/css-inline/text-box-trim/text-box-on-non-root-inline-box-expected.txt
@@ -0,0 +1,8 @@ +This is a testharness.js-based test. +[FAIL] .aqua 1 + assert_equals: \n<span class="aqua" style="text-box: ex alphabetic;" data-offset-y="16" data-expected-height="2">ApÉx</span>\nheight expected 2 but got 15 +[FAIL] .aqua 3 + assert_equals: \n<span class="aqua" style="text-box: trim-end text alphabetic;" data-offset-y="8" data-expected-height="10">ApÉx</span>\nheight expected 10 but got 15 +[FAIL] .aqua 4 + assert_equals: \n<div class="aqua" data-expected-height="18">\n <span style="font-size: 18px; text-box: ex alphabetic;">ApÉx</span>\n</div>\nheight expected 18 but got 21 +Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/storage/indexeddb/aborted-versionchange-closes-expected.txt b/third_party/blink/web_tests/storage/indexeddb/aborted-versionchange-closes-expected.txt index 5d20c3498..43130d51 100644 --- a/third_party/blink/web_tests/storage/indexeddb/aborted-versionchange-closes-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/aborted-versionchange-closes-expected.txt
@@ -30,7 +30,7 @@ onTransactionAbort(): sawTransactionAbort = true creating a transaction should fail because connection is closed: -Expecting exception from db.transaction('store', 'readonly', {durability: 'relaxed'}) +Expecting exception from db.transaction('store', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError' @@ -40,7 +40,7 @@ onOpenError(): PASS sawTransactionAbort is true creating a transaction should fail because connection is closed: -Expecting exception from db.transaction('store', 'readonly', {durability: 'relaxed'}) +Expecting exception from db.transaction('store', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError'
diff --git a/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata-expected.txt b/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata-expected.txt index e028fa47..d4501f6f1 100644 --- a/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata-expected.txt
@@ -17,10 +17,10 @@ validateResult(blob): PASS blob.size == test_content.length is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(blob, 'blobkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('blobkey') PASS event.target.result.size == test_content.length is true @@ -32,10 +32,10 @@ validateResult(file): PASS file.name == fileInput.files[0].name is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(file, 'filekey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('filekey') PASS event.target.result.name == fileInput.files[0].name is true @@ -47,10 +47,10 @@ validateResult(newFile): PASS newFile.name == newFile.name is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(newFile, 'newFilekey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('newFilekey') PASS event.target.result.name == newFile.name is true @@ -62,17 +62,17 @@ validateResult(filelist): PASS filelist[1].name == fileInput.files[1].name is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(filelist, 'filelistkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('filelistkey') PASS event.target.result[1].name == fileInput.files[1].name is true testCursor(): -transaction = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readonly') store = transaction.objectStore('storeName') request = store.openCursor() PASS cursor.value.size == test_content.length is true
diff --git a/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata.html b/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata.html index 4ebad07..e513740 100644 --- a/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata.html +++ b/third_party/blink/web_tests/storage/indexeddb/blob-basics-metadata.html
@@ -69,7 +69,7 @@ function testCursor() { preamble(); - evalAndLog("transaction = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('storeName', 'readonly')"); transaction.onerror = unexpectedErrorCallback; transaction.onabort = unexpectedAbortCallback; evalAndLog("store = transaction.objectStore('storeName')"); @@ -114,7 +114,7 @@ debug(""); debug("validateResult(" + variable + "):"); shouldBeTrue(variable + validation); - evalAndLog("transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('storeName', 'readwrite')"); evalAndLog("store = transaction.objectStore('storeName')"); evalAndLog("store.put(" + variable + ", '" + keyName + "')"); transaction.onerror = unexpectedErrorCallback; @@ -130,7 +130,7 @@ function doRead(keyName, onSuccess) { - evalAndLog("transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('storeName', 'readwrite')"); evalAndLog("store = transaction.objectStore('storeName')"); evalAndLog("request = store.get('" + keyName + "')"); request.onsuccess = onSuccess;
diff --git a/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db-expected.txt b/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db-expected.txt index b0f3a5f..f260a06a 100644 --- a/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db-expected.txt
@@ -20,7 +20,7 @@ didDeleteObjectStore(): -trans = db.transaction('store1', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store1', 'readwrite') store1 = trans.objectStore('store1') store1.put(blobB, key) db.close()
diff --git a/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db.html b/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db.html index 904f4ef..6f983852 100644 --- a/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db.html +++ b/third_party/blink/web_tests/storage/indexeddb/blob-delete-objectstore-db.html
@@ -44,7 +44,7 @@ { preamble(); blobBContent = "Second blob content"; - evalAndLog("trans = db.transaction('store1', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store1', 'readwrite')"); evalAndLog("store1 = trans.objectStore('store1')"); blobB = new Blob([blobBContent], {"type" : "text/plain"}); evalAndLog("store1.put(blobB, key)");
diff --git a/third_party/blink/web_tests/storage/indexeddb/closed-cursor-expected.txt b/third_party/blink/web_tests/storage/indexeddb/closed-cursor-expected.txt index 399ccdf..e01b3ba 100644 --- a/third_party/blink/web_tests/storage/indexeddb/closed-cursor-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/closed-cursor-expected.txt
@@ -15,7 +15,7 @@ onOpen(): db = event.target.result -tx = db.transaction('store', 'readonly', {durability: 'relaxed'}) +tx = db.transaction('store', 'readonly') store = tx.objectStore('store') cursorRequest = store.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/closed-cursor.html b/third_party/blink/web_tests/storage/indexeddb/closed-cursor.html index 74bd492..98f3e56 100644 --- a/third_party/blink/web_tests/storage/indexeddb/closed-cursor.html +++ b/third_party/blink/web_tests/storage/indexeddb/closed-cursor.html
@@ -18,7 +18,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("tx = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readonly')"); evalAndLog("store = tx.objectStore('store')"); evalAndLog("cursorRequest = store.openCursor()"); cursorRequest.onsuccess = function openCursorSuccess(evt) {
diff --git a/third_party/blink/web_tests/storage/indexeddb/constructed-file-attributes.html b/third_party/blink/web_tests/storage/indexeddb/constructed-file-attributes.html index f49b4a41..2ba99ac 100644 --- a/third_party/blink/web_tests/storage/indexeddb/constructed-file-attributes.html +++ b/third_party/blink/web_tests/storage/indexeddb/constructed-file-attributes.html
@@ -31,11 +31,11 @@ type: 'application/x-special-snowflake', lastModified: party_time }); - var tx = db.transaction('store', 'readwrite', {durability: 'relaxed'}); + var tx = db.transaction('store', 'readwrite'); tx.objectStore('store').put(file, 'key'); tx.oncomplete = t.step_func(function() { - var tx = db.transaction('store', 'readonly', {durability: 'relaxed'}); + var tx = db.transaction('store', 'readonly'); tx.objectStore('store').get('key').onsuccess = t.step_func(function(e) { var result = e.target.result;
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-after-range-bug.html b/third_party/blink/web_tests/storage/indexeddb/cursor-after-range-bug.html index 7871673..2742af9 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-after-range-bug.html +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-after-range-bug.html
@@ -13,7 +13,7 @@ store.put(i, i); }, function(t, db) { - var transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}); + var transaction = db.transaction('store', 'readonly'); var store = transaction.objectStore('store'); var req = store.openCursor(); var last_cursor;
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-cast-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-cast-expected.txt index f03f6ff..8781c41 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-cast-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-cast-expected.txt
@@ -15,7 +15,7 @@ verifyWrappers(): db = event.target.result -tx = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +tx = db.transaction('store', 'readwrite') request = tx.objectStore('store').openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-cast.html b/third_party/blink/web_tests/storage/indexeddb/cursor-cast.html index 4d9abf7..181e693 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-cast.html +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-cast.html
@@ -18,7 +18,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("tx = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readwrite')"); evalAndLog("request = tx.objectStore('store').openCursor()"); request.onsuccess = function onOpenCursorSuccess(evt) {
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-continue-dir-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-continue-dir-expected.txt index 3e889d8..98dd2873 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-continue-dir-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-continue-dir-expected.txt
@@ -16,7 +16,7 @@ store.put(8,8) store.put(9,9) store.put(10,10) -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store') request = store.openCursor(IDBKeyRange.bound(-Infinity, Infinity), 'next') cursor = request.result
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-finished-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-finished-expected.txt index 748100b..e53ee58 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-finished-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-finished-expected.txt
@@ -22,7 +22,7 @@ onOpenSuccess(): db = event.target.result -transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readwrite') store = transaction.objectStore('store') count = 0 cursorRequest = store.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-key-order-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-key-order-expected.txt index 10c66d9..a2fe62c98 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-key-order-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-key-order-expected.txt
@@ -9,7 +9,7 @@ populating store... -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') store = trans.objectStore('store'); store.put(0, -Infinity) store.put(1, -Number.MAX_VALUE) @@ -64,7 +64,7 @@ iterating cursor... -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store'); count = 0 curreq = store.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-leak.html b/third_party/blink/web_tests/storage/indexeddb/cursor-leak.html index c794280..1f1018b 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-leak.html +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-leak.html
@@ -25,7 +25,7 @@ // evalAndLog() is not used as that generates new DOM nodes. db = evt.target.result; - tx = db.transaction('store', 'readonly', {durability: 'relaxed'}); + tx = db.transaction('store', 'readonly'); store = tx.objectStore('store'); cursorRequest = store.openCursor(); cursorRequest.onsuccess = function() {
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-overloads-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-overloads-expected.txt index b038285..0f5fb95b 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-overloads-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-overloads-expected.txt
@@ -11,7 +11,7 @@ verifyOverloads(): -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store') index = store.index('index') store.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-overloads.html b/third_party/blink/web_tests/storage/indexeddb/cursor-overloads.html index 4b93c91..4dfbfe2 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-overloads.html +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-overloads.html
@@ -18,7 +18,7 @@ { debug(""); debug("verifyOverloads():"); - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); evalAndLog("store = trans.objectStore('store')"); evalAndLog("index = store.index('index')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-prev-no-duplicate-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-prev-no-duplicate-expected.txt index 935bc4315e..451ba02f3 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-prev-no-duplicate-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-prev-no-duplicate-expected.txt
@@ -10,7 +10,7 @@ populating store... -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') store = trans.objectStore('store'); store.put({sorted: 3, value: 111}, 1) store.put({sorted: 2, value: 222}, 2)
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-primary-key-order-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-primary-key-order-expected.txt index c512b48..25cb6b4 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-primary-key-order-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-primary-key-order-expected.txt
@@ -10,7 +10,7 @@ populating store... -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') store = trans.objectStore('store'); store.put({"indexKey":0,"count":0}, 'c') store.put({"indexKey":0,"count":1}, 'b') @@ -31,7 +31,7 @@ iterating cursor... -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store'); index = store.index('index'); cursorRequest = index.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-properties-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-properties-expected.txt index 53f6d9f..caa3db4 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-properties-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-properties-expected.txt
@@ -16,7 +16,7 @@ onOpenSuccess(): db = event.target.result -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store') index = store.index('index')
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle-expected.txt index 77ec78a..b0f17c1 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle-expected.txt
@@ -14,7 +14,7 @@ onOpen(): db = event.target.result -tx = db.transaction('store', 'readonly', {durability: 'relaxed'}) +tx = db.transaction('store', 'readonly') store = tx.objectStore('store') cursorRequest = store.openCursor() otherRequest = store.get(0)
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle.html b/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle.html index 50f59ef4..84285c6f6 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle.html +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-request-cycle.html
@@ -28,7 +28,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("tx = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readonly')"); evalAndLog("store = tx.objectStore('store')"); evalAndLog("cursorRequest = store.openCursor()");
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-reverse-bug-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-reverse-bug-expected.txt index 4d38872..17f7ad0 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-reverse-bug-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-reverse-bug-expected.txt
@@ -10,13 +10,13 @@ populating store... -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') store = trans.objectStore('store'); store.put(1, 1) store.put(2, 2) store.put(3, 3) testCursor() -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store'); index = store.index('index'); upperBound: 7 open: false expected: 3 @@ -35,7 +35,7 @@ PASS cursor.key is test.expected PASS cursor.primaryKey is test.expected testCursor() -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store'); index = store.index('index'); upperBound: 7 open: true expected: 3 @@ -54,7 +54,7 @@ PASS cursor.key is test.expected PASS cursor.primaryKey is test.expected testCursor() -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store'); index = store.index('index'); upperBound: 3 open: false expected: 3 @@ -73,7 +73,7 @@ PASS cursor.key is test.expected PASS cursor.primaryKey is test.expected testCursor() -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store'); index = store.index('index'); upperBound: 3 open: true expected: 2
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-update-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-update-expected.txt index a2a792fd..6d1db1f 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-update-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-update-expected.txt
@@ -199,7 +199,7 @@ keyCursor() PASS counter is 5 openBasicCursor() -trans = db.transaction('basicStore', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('basicStore', 'readonly') trans.objectStore('basicStore') objectStore.openCursor(keyRange) attemptUpdate()
diff --git a/third_party/blink/web_tests/storage/indexeddb/cursor-value-expected.txt b/third_party/blink/web_tests/storage/indexeddb/cursor-value-expected.txt index 7245cdcb..6256875 100644 --- a/third_party/blink/web_tests/storage/indexeddb/cursor-value-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/cursor-value-expected.txt
@@ -9,7 +9,7 @@ testCursor(): -transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readwrite') store = transaction.objectStore('store') store.put({a: 1, b: 10}, 'key1') store.put({a: 2, b: 20}, 'key2') @@ -128,7 +128,7 @@ ensureModificationsNotPersisted(): -transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readonly') store = transaction.objectStore('store') request = store.openCursor() cursor = request.result
diff --git a/third_party/blink/web_tests/storage/indexeddb/database-basics-expected.txt b/third_party/blink/web_tests/storage/indexeddb/database-basics-expected.txt index cdf74ec6..77854207 100644 --- a/third_party/blink/web_tests/storage/indexeddb/database-basics-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/database-basics-expected.txt
@@ -6,7 +6,7 @@ indexedDB.deleteDatabase(dbname) indexedDB.open(dbname) Test that you can't open a transaction while in a versionchange transaction -Expecting exception from db.transaction("doesntExist", "readonly", {durability: "relaxed"}) +Expecting exception from db.transaction("doesntExist", "readonly") PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError' @@ -46,7 +46,7 @@ PASS db.objectStoreNames.contains('test123') is true db.close() Now that the connection is closed, transaction creation should fail -Expecting exception from db.transaction('test123', 'readonly', {durability: 'relaxed'}) +Expecting exception from db.transaction('test123', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError'
diff --git a/third_party/blink/web_tests/storage/indexeddb/database-close-expected.txt b/third_party/blink/web_tests/storage/indexeddb/database-close-expected.txt index 4171103..b8be451c 100644 --- a/third_party/blink/web_tests/storage/indexeddb/database-close-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/database-close-expected.txt
@@ -12,8 +12,8 @@ testClose(): Create transactions using connection: -trans1 = connection.transaction('store', 'readonly', {durability: 'relaxed'}) -trans2 = connection.transaction('store', 'readonly', {durability: 'relaxed'}) +trans1 = connection.transaction('store', 'readonly') +trans2 = connection.transaction('store', 'readonly') Close the connection: @@ -30,7 +30,7 @@ NOTE: Once the closePending flag has been set to true no new transactions can be created using connection. All functions that create transactions first check the closePending flag first and throw an exception if it is true. -Expecting exception from trans3 = connection.transaction('store', 'readonly', {durability: 'relaxed'}) +Expecting exception from trans3 = connection.transaction('store', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError'
diff --git a/third_party/blink/web_tests/storage/indexeddb/database-closepending-flag-expected.txt b/third_party/blink/web_tests/storage/indexeddb/database-closepending-flag-expected.txt index b6e1986..e69a3df 100644 --- a/third_party/blink/web_tests/storage/indexeddb/database-closepending-flag-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/database-closepending-flag-expected.txt
@@ -9,13 +9,13 @@ First, verify that the database connection is not closed: -PASS transaction = connection.transaction('store', 'readonly', {durability: 'relaxed'}) did not throw exception. +PASS transaction = connection.transaction('store', 'readonly') did not throw exception. Database closing steps "1. Set the internal closePending flag of connection to true." connection.close() -Expecting exception from connection.transaction('store', 'readonly', {durability: 'relaxed'}) +Expecting exception from connection.transaction('store', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError' @@ -41,7 +41,7 @@ IDBDatabase.transaction(): "...if this method is called on a IDBDatabase instance where the closePending flag is set, a InvalidStateError exception must be thrown." -Expecting exception from connection.transaction('store', 'readonly', {durability: 'relaxed'}) +Expecting exception from connection.transaction('store', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError' @@ -54,7 +54,7 @@ connection = request.result versionChangeWasFired = false connection.onversionchange = function () { versionChangeWasFired = true; } -transaction = connection.transaction('store', 'readonly', {durability: 'relaxed'}) +transaction = connection.transaction('store', 'readonly') connection.close() closePending is set, but active transaction will keep connection from closing request = indexedDB.open(dbname, 3) @@ -70,7 +70,7 @@ connection = request.result versionChangeWasFired = false connection.onversionchange = function () { versionChangeWasFired = true; } -transaction = connection.transaction('store', 'readonly', {durability: 'relaxed'}) +transaction = connection.transaction('store', 'readonly') connection.close() closePending is set, but active transaction will keep connection from closing request = indexedDB.deleteDatabase(dbname)
diff --git a/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction-expected.txt b/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction-expected.txt index 47671633..98a876e 100644 --- a/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction-expected.txt
@@ -9,7 +9,7 @@ Start a transaction against the first database: -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') trans.objectStore('store').get(0)
diff --git a/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction.html b/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction.html index 5779400..67b4af6 100644 --- a/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction.html +++ b/third_party/blink/web_tests/storage/indexeddb/deletedatabase-transaction.html
@@ -14,7 +14,7 @@ function startTransaction() { debug(""); debug("Start a transaction against the first database:"); - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); evalAndLog("trans.objectStore('store').get(0)"); debug("");
diff --git a/third_party/blink/web_tests/storage/indexeddb/empty-blob-file-expected.txt b/third_party/blink/web_tests/storage/indexeddb/empty-blob-file-expected.txt index 3098238..c808e81b 100644 --- a/third_party/blink/web_tests/storage/indexeddb/empty-blob-file-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/empty-blob-file-expected.txt
@@ -15,10 +15,10 @@ validateResult(blob): PASS blob.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(blob, 'blobkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('blobkey') PASS event.target.result.size == 0 is true @@ -30,10 +30,10 @@ validateResult(blob): PASS blob.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(blob, 'blobkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('blobkey') PASS event.target.result.size == 0 is true @@ -45,10 +45,10 @@ validateResult(blob): PASS blob.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(blob, 'blobkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('blobkey') PASS event.target.result.size == 0 is true @@ -60,10 +60,10 @@ validateResult(blob): PASS blob.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(blob, 'blobkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('blobkey') PASS event.target.result.size == 0 is true @@ -76,10 +76,10 @@ validateResult(blob): PASS blob.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(blob, 'blobkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('blobkey') PASS event.target.result.size == 0 is true @@ -92,10 +92,10 @@ validateResult(blob): PASS blob.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(blob, 'blobkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('blobkey') PASS event.target.result.size == 0 is true @@ -107,10 +107,10 @@ validateResult(file): PASS file.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(file, 'filekey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('filekey') PASS event.target.result.size == 0 is true @@ -122,10 +122,10 @@ validateResult(fileList): PASS fileList.length == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(fileList, 'fileListkey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('fileListkey') PASS event.target.result.length == 0 is true
diff --git a/third_party/blink/web_tests/storage/indexeddb/empty-blob-file.html b/third_party/blink/web_tests/storage/indexeddb/empty-blob-file.html index d6dc205..1daef10 100644 --- a/third_party/blink/web_tests/storage/indexeddb/empty-blob-file.html +++ b/third_party/blink/web_tests/storage/indexeddb/empty-blob-file.html
@@ -94,7 +94,7 @@ debug(""); debug("validateResult(" + variable + "):"); shouldBeTrue(variable + validation); - evalAndLog("transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('storeName', 'readwrite')"); evalAndLog("store = transaction.objectStore('storeName')"); evalAndLog("store.put(" + variable + ", '" + keyName + "')"); transaction.onerror = unexpectedErrorCallback; @@ -110,7 +110,7 @@ function doRead(keyName, onSuccess) { - evalAndLog("transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('storeName', 'readwrite')"); evalAndLog("store = transaction.objectStore('storeName')"); evalAndLog("request = store.get('" + keyName + "')"); request.onsuccess = onSuccess;
diff --git a/third_party/blink/web_tests/storage/indexeddb/empty-crash.html b/third_party/blink/web_tests/storage/indexeddb/empty-crash.html index 89da8f3..673f840 100644 --- a/third_party/blink/web_tests/storage/indexeddb/empty-crash.html +++ b/third_party/blink/web_tests/storage/indexeddb/empty-crash.html
@@ -15,7 +15,7 @@ open.onsuccess = function() { db = open.result; - var tx = db.transaction('store', 'readonly', {durability: 'relaxed'}); + var tx = db.transaction('store', 'readonly'); var req = tx.objectStore('store').get(0); req.onsuccess = function() { frameElement.parentNode.removeChild(frameElement);
diff --git a/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file-expected.txt b/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file-expected.txt index 9a39218..10f82d7 100644 --- a/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file-expected.txt
@@ -16,10 +16,10 @@ validateResult(file): PASS file.size == 0 is true -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.put(file, 'filekey') -transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') request = store.get('filekey') PASS event.target.result.size == 0 is true
diff --git a/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file.html b/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file.html index eb549b8..a3aa6850 100644 --- a/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file.html +++ b/third_party/blink/web_tests/storage/indexeddb/empty-filesystem-file.html
@@ -29,7 +29,7 @@ debug(""); debug("validateResult(" + variable + "):"); shouldBeTrue(variable + validation); - evalAndLog("transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('storeName', 'readwrite')"); evalAndLog("store = transaction.objectStore('storeName')"); evalAndLog("store.put(" + variable + ", '" + keyName + "')"); transaction.onerror = unexpectedErrorCallback; @@ -45,7 +45,7 @@ function doRead(keyName, onSuccess) { - evalAndLog("transaction = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('storeName', 'readwrite')"); evalAndLog("store = transaction.objectStore('storeName')"); evalAndLog("request = store.get('" + keyName + "')"); request.onsuccess = onSuccess;
diff --git a/third_party/blink/web_tests/storage/indexeddb/exceptions-expected.txt b/third_party/blink/web_tests/storage/indexeddb/exceptions-expected.txt index 5cf9b8b..a8b4c9e2 100644 --- a/third_party/blink/web_tests/storage/indexeddb/exceptions-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/exceptions-expected.txt
@@ -98,13 +98,13 @@ IDBDatabase.transaction() If this method is called on IDBDatabase object for which a "versionchange" transaction is still running, a InvalidStateError exception must be thrown. -Expecting exception from db.transaction('store', 'readonly', {durability: 'relaxed'}) +Expecting exception from db.transaction('store', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError' Exception message: Failed to execute 'transaction' on 'IDBDatabase': A version change transaction is running. One of the names provided in the storeNames argument doesn't exist in this database. -Expecting exception from db.transaction('no-such-store', 'readonly', {durability: 'relaxed'}) +Expecting exception from db.transaction('no-such-store', 'readonly') PASS Exception was thrown. PASS code is DOMException.NOT_FOUND_ERR PASS ename is 'NotFoundError' @@ -144,7 +144,7 @@ Prepare an object store and index from an inactive transaction for later use. -finishedTransaction = inactiveTransaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +finishedTransaction = inactiveTransaction = db.transaction('store', 'readonly') storeFromInactiveTransaction = inactiveTransaction.objectStore('store') indexFromInactiveTransaction = storeFromInactiveTransaction.index('index') request = storeFromInactiveTransaction.openCursor() @@ -152,9 +152,9 @@ 3.2.5 Object Store -ro_transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +ro_transaction = db.transaction('store', 'readonly') storeFromReadOnlyTransaction = ro_transaction.objectStore('store') -rw_transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +rw_transaction = db.transaction('store', 'readwrite') store = rw_transaction.objectStore('store') @@ -391,7 +391,7 @@ One more IDBObjectStore.createIndex() test: If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError. -Expecting exception from db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store').createIndex('fail', 'keyPath') +Expecting exception from db.transaction('store', 'readonly').objectStore('store').createIndex('fail', 'keyPath') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError' @@ -400,7 +400,7 @@ One more IDBObjectStore.deleteIndex() test: If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError. -Expecting exception from db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store').deleteIndex('fail', 'keyPath') +Expecting exception from db.transaction('store', 'readonly').objectStore('store').deleteIndex('fail', 'keyPath') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError' @@ -408,8 +408,8 @@ 3.2.6 Index -indexFromReadOnlyTransaction = db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store').index('index') -index = db.transaction('store', 'readwrite', {durability: 'relaxed'}).objectStore('store').index('index') +indexFromReadOnlyTransaction = db.transaction('store', 'readonly').objectStore('store').index('index') +index = db.transaction('store', 'readwrite').objectStore('store').index('index') IDBIndex.count() @@ -630,7 +630,7 @@ PASS code is 0 PASS ename is 'TransactionInactiveError' Exception message: Failed to execute 'update' on 'IDBCursor': The transaction has finished. -readOnlyTransaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +readOnlyTransaction = db.transaction('store', 'readonly') request = readOnlyTransaction.objectStore('store').openCursor() cursorFromReadOnlyTransaction = request.result @@ -664,7 +664,7 @@ PASS ename is 'InvalidStateError' Exception message: Failed to execute 'abort' on 'IDBTransaction': The transaction has finished. If the requested object store is not in this transaction's scope. -Expecting exception from db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('otherStore') +Expecting exception from db.transaction('store', 'readonly').objectStore('otherStore') PASS Exception was thrown. PASS code is DOMException.NOT_FOUND_ERR PASS ename is 'NotFoundError'
diff --git a/third_party/blink/web_tests/storage/indexeddb/factory-deletedatabase-expected.txt b/third_party/blink/web_tests/storage/indexeddb/factory-deletedatabase-expected.txt index d52aaff7..83fcf5c 100644 --- a/third_party/blink/web_tests/storage/indexeddb/factory-deletedatabase-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/factory-deletedatabase-expected.txt
@@ -9,7 +9,7 @@ store.createIndex('indexName', '') PASS store.indexNames.contains('indexName') is true store.add('value', 'key') -db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +db.transaction('storeName', 'readwrite') store = transaction.objectStore('storeName') store.get('key') PASS event.target.result is "value"
diff --git a/third_party/blink/web_tests/storage/indexeddb/index-count-expected.txt b/third_party/blink/web_tests/storage/indexeddb/index-count-expected.txt index 6061034a..87abb56 100644 --- a/third_party/blink/web_tests/storage/indexeddb/index-count-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/index-count-expected.txt
@@ -12,7 +12,7 @@ verifying count without range -trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readonly') PASS trans is non-null. store = trans.objectStore('storeName') PASS store is non-null. @@ -24,7 +24,7 @@ verifying count with range -trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readonly') PASS trans is non-null. store = trans.objectStore('storeName') PASS store is non-null. @@ -87,7 +87,7 @@ verifying count with key -trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readonly') PASS trans is non-null. store = trans.objectStore('storeName') PASS store is non-null.
diff --git a/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-oncomplete-expected.txt b/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-oncomplete-expected.txt index 2ec63212..0f37bad 100644 --- a/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-oncomplete-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-oncomplete-expected.txt
@@ -24,7 +24,7 @@ PASS event.target.result is undefined. PASS event.target.error is non-null. PASS event.target.error.name is "AbortError" -Expecting exception from transaction = db.transaction('os', 'readwrite', {durability: 'relaxed'}) +Expecting exception from transaction = db.transaction('os', 'readwrite') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError'
diff --git a/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt b/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt index 4c843ac..0003faab 100644 --- a/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/intversion-close-in-upgradeneeded-expected.txt
@@ -30,7 +30,7 @@ Verify that the old connection is unchanged and was closed: PASS db is non-null. PASS db.version is 7 -Expecting exception from db.transaction('os', 'readonly', {durability: 'relaxed'}) +Expecting exception from db.transaction('os', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError'
diff --git a/third_party/blink/web_tests/storage/indexeddb/intversion-open-in-upgradeneeded-expected.txt b/third_party/blink/web_tests/storage/indexeddb/intversion-open-in-upgradeneeded-expected.txt index bf6bad6..03c9977 100644 --- a/third_party/blink/web_tests/storage/indexeddb/intversion-open-in-upgradeneeded-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/intversion-open-in-upgradeneeded-expected.txt
@@ -29,7 +29,7 @@ db = event.target.result PASS db.version is 1 Start a transaction to ensure the connection is still open. -transaction = db.transaction('os', 'readonly', {durability: 'relaxed'}) +transaction = db.transaction('os', 'readonly') onVersionChange():
diff --git a/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle-expected.txt b/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle-expected.txt index ac6ee7c..9c7638f 100644 --- a/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle-expected.txt
@@ -14,7 +14,7 @@ onOpen(): db = event.target.result -tx = db.transaction('store', 'readonly', {durability: 'relaxed'}) +tx = db.transaction('store', 'readonly') store = tx.objectStore('store') cursorRequest = store.openKeyCursor() otherRequest = store.get(0)
diff --git a/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle.html b/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle.html index b952d88..b16176d2 100644 --- a/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle.html +++ b/third_party/blink/web_tests/storage/indexeddb/key-cursor-request-cycle.html
@@ -28,7 +28,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("tx = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readonly')"); evalAndLog("store = tx.objectStore('store')"); evalAndLog("cursorRequest = store.openKeyCursor()");
diff --git a/third_party/blink/web_tests/storage/indexeddb/key-generator-expected.txt b/third_party/blink/web_tests/storage/indexeddb/key-generator-expected.txt index 6345cfe2..bbda6a1 100644 --- a/third_party/blink/web_tests/storage/indexeddb/key-generator-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/key-generator-expected.txt
@@ -166,7 +166,7 @@ db.createObjectStore('store', {autoIncrement: true}) -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') request = trans.objectStore('store').put('value1') PASS request.result is 1 trans.objectStore('store').clear() @@ -175,7 +175,7 @@ request = indexedDB.open(dbname) db = request.result -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') request = trans.objectStore('store').put('value2') PASS request.result is 2
diff --git a/third_party/blink/web_tests/storage/indexeddb/key-type-array-expected.txt b/third_party/blink/web_tests/storage/indexeddb/key-type-array-expected.txt index 3161e8a3..6c11a32 100644 --- a/third_party/blink/web_tests/storage/indexeddb/key-type-array-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/key-type-array-expected.txt
@@ -8,7 +8,7 @@ db.createObjectStore('store'); -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') store = trans.objectStore('store') @@ -181,7 +181,7 @@ PASS getreq.result is "value27" -trans = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('store', 'readwrite') store = trans.objectStore('store')
diff --git a/third_party/blink/web_tests/storage/indexeddb/keypath-intrinsic-properties-expected.txt b/third_party/blink/web_tests/storage/indexeddb/keypath-intrinsic-properties-expected.txt index 25935cd..1dfa1603 100644 --- a/third_party/blink/web_tests/storage/indexeddb/keypath-intrinsic-properties-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/keypath-intrinsic-properties-expected.txt
@@ -13,7 +13,7 @@ testKeyPaths(): -transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readwrite') store = transaction.objectStore('store') store.put({"id":"id#0","string":"","array":[],"blob":new Blob([""],{type:"type 0"})}) store.put({"id":"id#1","string":"xx","array":["x","x","x"],"blob":new Blob(["xxxx"],{type:"type 1"})})
diff --git a/third_party/blink/web_tests/storage/indexeddb/lazy-index-population-expected.txt b/third_party/blink/web_tests/storage/indexeddb/lazy-index-population-expected.txt index 406ce45..d8df3f5 100644 --- a/third_party/blink/web_tests/storage/indexeddb/lazy-index-population-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/lazy-index-population-expected.txt
@@ -9,7 +9,7 @@ store = connection.createObjectStore('store') store.createIndex('index1', 'name', {unique: true}) Verify that uniqueness constraints are enforced with a pre-existing index: -trans = connection.transaction('store', 'readwrite', {durability: 'relaxed'}) +trans = connection.transaction('store', 'readwrite') store = trans.objectStore('store') request1 = store.put({name: 'bob'}, 1) request2 = store.put({name: 'bob'}, 2)
diff --git a/third_party/blink/web_tests/storage/indexeddb/lazy-index-population.html b/third_party/blink/web_tests/storage/indexeddb/lazy-index-population.html index b69b611e6..aae18ab 100644 --- a/third_party/blink/web_tests/storage/indexeddb/lazy-index-population.html +++ b/third_party/blink/web_tests/storage/indexeddb/lazy-index-population.html
@@ -17,7 +17,7 @@ function verifyPreExistingIndex() { debug("Verify that uniqueness constraints are enforced with a pre-existing index:"); - evalAndLog("trans = connection.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = connection.transaction('store', 'readwrite')"); evalAndLog("store = trans.objectStore('store')"); evalAndLog("request1 = store.put({name: 'bob'}, 1)"); evalAndLog("request2 = store.put({name: 'bob'}, 2)");
diff --git a/third_party/blink/web_tests/storage/indexeddb/lazy-index-types-expected.txt b/third_party/blink/web_tests/storage/indexeddb/lazy-index-types-expected.txt index 3a808555..fe400ad 100644 --- a/third_party/blink/web_tests/storage/indexeddb/lazy-index-types-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/lazy-index-types-expected.txt
@@ -31,7 +31,7 @@ onSuccess(): db = event.target.result -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') store = trans.objectStore('store') greedyIndex = store.index('greedy-index') request = greedyIndex.count()
diff --git a/third_party/blink/web_tests/storage/indexeddb/metadata-race-expected.txt b/third_party/blink/web_tests/storage/indexeddb/metadata-race-expected.txt index c92b2a0..b44d3bd 100644 --- a/third_party/blink/web_tests/storage/indexeddb/metadata-race-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/metadata-race-expected.txt
@@ -19,13 +19,13 @@ In multiprocess mode, 'complete' event may be dispatched before the 'success' arrives with updated metadata. Ensure the new metadata is still used for transactions. -store = db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store') +store = db.transaction('store', 'readonly').objectStore('store') PASS index = store.index('index') did not throw exception. onOpenSuccess(): db = event.target.result -store = db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store') +store = db.transaction('store', 'readonly').objectStore('store') PASS index = store.index('index') did not throw exception. PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/storage/indexeddb/metadata-race.html b/third_party/blink/web_tests/storage/indexeddb/metadata-race.html index 30f20e3b..05dcb92 100644 --- a/third_party/blink/web_tests/storage/indexeddb/metadata-race.html +++ b/third_party/blink/web_tests/storage/indexeddb/metadata-race.html
@@ -23,7 +23,7 @@ debug("In multiprocess mode, 'complete' event may be dispatched before\n" + "the 'success' arrives with updated metadata. Ensure the new metadata\n" + "is still used for transactions."); - evalAndLog("store = db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store')"); + evalAndLog("store = db.transaction('store', 'readonly').objectStore('store')"); shouldNotThrow("index = store.index('index')"); } @@ -31,7 +31,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("store = db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store')"); + evalAndLog("store = db.transaction('store', 'readonly').objectStore('store')"); shouldNotThrow("index = store.index('index')"); finishJSTest(); }
diff --git a/third_party/blink/web_tests/storage/indexeddb/microtasks.html b/third_party/blink/web_tests/storage/indexeddb/microtasks.html index dbf2086ea..ecea742 100644 --- a/third_party/blink/web_tests/storage/indexeddb/microtasks.html +++ b/third_party/blink/web_tests/storage/indexeddb/microtasks.html
@@ -22,7 +22,7 @@ }, function(t, db) { Promise.resolve().then(t.step_func(function() { - var tx = db.transaction('store', 'readonly', {durability: 'relaxed'}); + var tx = db.transaction('store', 'readonly'); var request = tx.objectStore('store').get(0); request.onerror = t.unreached_func('request should not fail'); request.onsuccess = t.step_func(function() { @@ -46,7 +46,7 @@ function(t, db) { var aesAlgorithmKeyGen = {name: "AES-CBC", length: 128}; crypto.subtle.generateKey(aesAlgorithmKeyGen, false, ["encrypt"]).then(t.step_func(function() { - var tx = db.transaction('store', 'readonly', {durability: 'relaxed'}); + var tx = db.transaction('store', 'readonly'); var request = tx.objectStore('store').get(0); request.onerror = t.unreached_func('request should not fail'); request.onsuccess = t.step_func(function() { @@ -70,7 +70,7 @@ function(t, db) { var tx; Promise.resolve().then(function() { - tx = db.transaction('store', 'readonly', {durability: 'relaxed'}); + tx = db.transaction('store', 'readonly'); assert_true(isTransactionActive(tx, 'store'), 'Transaction should be active when created'); }).then(t.step_func(function() { @@ -91,7 +91,7 @@ db.createObjectStore('store'); }, function(t, db) { - var tx = db.transaction('store', 'readonly', {durability: 'relaxed'}); + var tx = db.transaction('store', 'readonly'); var request = tx.objectStore('store').get(0); request.onerror = t.unreached_func('request should not fail'); request.onsuccess = t.step_func(function() {
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/autoincrement-indexes-expected.txt b/third_party/blink/web_tests/storage/indexeddb/mozilla/autoincrement-indexes-expected.txt index 644acbe..50b27c8 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/autoincrement-indexes-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/autoincrement-indexes-expected.txt
@@ -14,7 +14,7 @@ key = event.target.result; PASS key == null is false expected key is 1 -objectStore = db.transaction('autoincrement-id', 'readonly', {durability: 'relaxed'}).objectStore('autoincrement-id'); +objectStore = db.transaction('autoincrement-id', 'readonly').objectStore('autoincrement-id'); first = objectStore.index('first'); request = first.get('foo'); PASS event.target.result.id is key
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/clear-expected.txt b/third_party/blink/web_tests/storage/indexeddb/mozilla/clear-expected.txt index cb15a77..20a9402 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/clear-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/clear-expected.txt
@@ -7,14 +7,14 @@ indexedDB.open(dbname) objectStore = db.createObjectStore('foo', { autoIncrement: true }); request = objectStore.add({}); -Expecting exception from db.transaction('foo', 'readonly', {durability: 'relaxed'}).objectStore('foo').clear(); +Expecting exception from db.transaction('foo', 'readonly').objectStore('foo').clear(); PASS Exception was thrown. PASS code is 0 PASS ename is 'ReadOnlyError' Exception message: Failed to execute 'clear' on 'IDBObjectStore': The transaction is read-only. -db.transaction('foo', 'readwrite', {durability: 'relaxed'}) +db.transaction('foo', 'readwrite') transaction.objectStore('foo').clear(); -request = db.transaction('foo', 'readonly', {durability: 'relaxed'}).objectStore('foo').openCursor(); +request = db.transaction('foo', 'readonly').objectStore('foo').openCursor(); cursor = request.result; PASS cursor is null PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-expected.txt b/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-expected.txt index 79d5def..1f1c8b02 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-expected.txt
@@ -86,7 +86,7 @@ objectStoreDataNameSort = [ 1, 4, 5, 2, 3 ] -trans = db.transaction('foo', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('foo', 'readwrite') objectStore = trans.objectStore('foo') request = objectStore.index('name').openCursor() trans.oncomplete = checkMutatingCursorResults
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-objectstore-only-expected.txt b/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-objectstore-only-expected.txt index 54e60480..28cca24 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-objectstore-only-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/cursor-mutation-objectstore-only-expected.txt
@@ -59,7 +59,7 @@ count = 0; sawAdded = false; sawRemoved = false; -request = db.transaction('foo', 'readwrite', {durability: 'relaxed'}).objectStore('foo').openCursor(); +request = db.transaction('foo', 'readwrite').objectStore('foo').openCursor(); iterateMutatingCursor(): event.target.transaction.oncomplete = checkMutatingCursorResults; cursor = event.target.result;
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/object-identity-expected.txt b/third_party/blink/web_tests/storage/indexeddb/mozilla/object-identity-expected.txt index 95719334..e3c95ce 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/object-identity-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/object-identity-expected.txt
@@ -12,7 +12,7 @@ index1 = objectStore1.createIndex('bar', 'key'); index2 = objectStore2.index('bar'); PASS index1 === index2 is true -transaction = db.transaction('foo', 'readonly', {durability: 'relaxed'}); +transaction = db.transaction('foo', 'readonly'); objectStore3 = transaction.objectStore('foo'); objectStore3.someProperty = 'xyz' objectStore4 = transaction.objectStore('foo');
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/odd-result-order-expected.txt b/third_party/blink/web_tests/storage/indexeddb/mozilla/odd-result-order-expected.txt index fca3faf..8221c74 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/odd-result-order-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/odd-result-order-expected.txt
@@ -13,7 +13,7 @@ checkDatabaseType(): PASS db instanceof IDBDatabase is true addRecord(): -objectStore = db.transaction('foo', 'readwrite', {durability: 'relaxed'}).objectStore('foo'); +objectStore = db.transaction('foo', 'readwrite').objectStore('foo'); data = { key: 5, index: 10 }; request = objectStore.add(data); addSuccess(): @@ -21,7 +21,7 @@ key = request.result; checkAddedKey(): PASS key is data.key -objectStore = db.transaction('foo', 'readonly', {durability: 'relaxed'}).objectStore('foo'); +objectStore = db.transaction('foo', 'readonly').objectStore('foo'); request = objectStore.get(data.key); getSuccess(): record = null; @@ -30,7 +30,7 @@ PASS record.key is data.key PASS record.index is data.index deleteRecord(): -objectStore = db.transaction('foo', 'readwrite', {durability: 'relaxed'}).objectStore('foo'); +objectStore = db.transaction('foo', 'readwrite').objectStore('foo'); request = objectStore.delete(data.key); deleteSuccess(): PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/autoincrement-indexes.js b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/autoincrement-indexes.js index 6468f513..e85bf9a 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/autoincrement-indexes.js +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/autoincrement-indexes.js
@@ -36,7 +36,7 @@ function setVersionComplete() { - objectStore = evalAndLog("objectStore = db.transaction('autoincrement-id', 'readonly', {durability: 'relaxed'}).objectStore('autoincrement-id');"); + objectStore = evalAndLog("objectStore = db.transaction('autoincrement-id', 'readonly').objectStore('autoincrement-id');"); first = evalAndLog("first = objectStore.index('first');"); request = evalAndLog("request = first.get('foo');"); request.onsuccess = checkFirstIndexAndPrepareSecond;
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/clear.js b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/clear.js index a01bbe5..962dfb4b 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/clear.js +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/clear.js
@@ -23,8 +23,8 @@ function clear() { - evalAndExpectException("db.transaction('foo', 'readonly', {durability: 'relaxed'}).objectStore('foo').clear();", "0", "'ReadOnlyError'"); - transaction = evalAndLog("db.transaction('foo', 'readwrite', {durability: 'relaxed'})"); + evalAndExpectException("db.transaction('foo', 'readonly').objectStore('foo').clear();", "0", "'ReadOnlyError'"); + transaction = evalAndLog("db.transaction('foo', 'readwrite')"); evalAndLog("transaction.objectStore('foo').clear();"); transaction.oncomplete = cleared; transaction.onabort = unexpectedAbortCallback; @@ -32,7 +32,7 @@ function cleared() { - request = evalAndLog("request = db.transaction('foo', 'readonly', {durability: 'relaxed'}).objectStore('foo').openCursor();"); + request = evalAndLog("request = db.transaction('foo', 'readonly').objectStore('foo').openCursor();"); request.onsuccess = areWeClearYet; request.onerror = unexpectedErrorCallback; }
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation-objectstore-only.js b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation-objectstore-only.js index ab2e58c..f402f66 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation-objectstore-only.js +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation-objectstore-only.js
@@ -69,7 +69,7 @@ sawAdded = evalAndLog("sawAdded = false;"); sawRemoved = evalAndLog("sawRemoved = false;"); - request = evalAndLog("request = db.transaction('foo', 'readwrite', {durability: 'relaxed'}).objectStore('foo').openCursor();"); + request = evalAndLog("request = db.transaction('foo', 'readwrite').objectStore('foo').openCursor();"); request.onsuccess = iterateMutatingCursor; request.onerror = unexpectedErrorCallback; }
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation.js b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation.js index bbf1288..1ddb869 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation.js +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/cursor-mutation.js
@@ -98,7 +98,7 @@ debug(""); - trans = evalAndLog("trans = db.transaction('foo', 'readwrite', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('foo', 'readwrite')"); objectStore = evalAndLog("objectStore = trans.objectStore('foo')"); request = evalAndLog("request = objectStore.index('name').openCursor()"); request.onerror = unexpectedErrorCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/object-identity.js b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/object-identity.js index 0bdf1c3..a12b0b4 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/object-identity.js +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/object-identity.js
@@ -27,7 +27,7 @@ function testIdentitySomeMore() { - transaction = evalAndLog("transaction = db.transaction('foo', 'readonly', {durability: 'relaxed'});"); + transaction = evalAndLog("transaction = db.transaction('foo', 'readonly');"); objectStore3 = evalAndLog("objectStore3 = transaction.objectStore('foo');"); evalAndLog("objectStore3.someProperty = 'xyz'"); objectStore4 = evalAndLog("objectStore4 = transaction.objectStore('foo');");
diff --git a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/odd-result-order.js b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/odd-result-order.js index 7637d87e..d70d07c7 100644 --- a/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/odd-result-order.js +++ b/third_party/blink/web_tests/storage/indexeddb/mozilla/resources/odd-result-order.js
@@ -41,7 +41,7 @@ function addRecord() { debug("addRecord():"); - objectStore = evalAndLog("objectStore = db.transaction('foo', 'readwrite', {durability: 'relaxed'}).objectStore('foo');"); + objectStore = evalAndLog("objectStore = db.transaction('foo', 'readwrite').objectStore('foo');"); data = evalAndLog("data = { key: 5, index: 10 };"); request = evalAndLog("request = objectStore.add(data);"); request.onsuccess = addSuccess; @@ -62,7 +62,7 @@ { debug("checkAddedKey():"); shouldBe("key", "data.key"); - objectStore = evalAndLog("objectStore = db.transaction('foo', 'readonly', {durability: 'relaxed'}).objectStore('foo');"); + objectStore = evalAndLog("objectStore = db.transaction('foo', 'readonly').objectStore('foo');"); request = evalAndLog("request = objectStore.get(data.key);"); request.onsuccess = getSuccess; request.onerror = unexpectedErrorCallback; @@ -89,7 +89,7 @@ function deleteRecord() { debug("deleteRecord():"); - objectStore = evalAndLog("objectStore = db.transaction('foo', 'readwrite', {durability: 'relaxed'}).objectStore('foo');"); + objectStore = evalAndLog("objectStore = db.transaction('foo', 'readwrite').objectStore('foo');"); request = evalAndLog("request = objectStore.delete(data.key);"); request.onsuccess = deleteSuccess; request.onerror = unexpectedErrorCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/objectstore-autoincrement-expected.txt b/third_party/blink/web_tests/storage/indexeddb/objectstore-autoincrement-expected.txt index 92313c7db..9be0109 100644 --- a/third_party/blink/web_tests/storage/indexeddb/objectstore-autoincrement-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/objectstore-autoincrement-expected.txt
@@ -60,7 +60,7 @@ addAdamSuccess(): PASS event.target.result is 1 testLongKeyPath(): -trans = db.transaction('StoreWithLongKeyPath', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('StoreWithLongKeyPath', 'readwrite') store = trans.objectStore('StoreWithLongKeyPath') store.add({foo: 'bar'}) store.add({foo: 'bar', a: {}})
diff --git a/third_party/blink/web_tests/storage/indexeddb/objectstore-count-expected.txt b/third_party/blink/web_tests/storage/indexeddb/objectstore-count-expected.txt index 1bad8ef..a5f9551 100644 --- a/third_party/blink/web_tests/storage/indexeddb/objectstore-count-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/objectstore-count-expected.txt
@@ -10,7 +10,7 @@ verifying count without range -trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readonly') PASS trans is non-null. store = trans.objectStore('storeName') PASS store is non-null. @@ -20,7 +20,7 @@ verifying count with range -trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readonly') PASS trans is non-null. store = trans.objectStore('storeName') PASS store is non-null. @@ -81,7 +81,7 @@ verifying count with key -trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readonly') PASS trans is non-null. store = trans.objectStore('storeName') PASS store is non-null.
diff --git a/third_party/blink/web_tests/storage/indexeddb/open-during-transaction-expected.txt b/third_party/blink/web_tests/storage/indexeddb/open-during-transaction-expected.txt index 3508338..5b36004 100644 --- a/third_party/blink/web_tests/storage/indexeddb/open-during-transaction-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/open-during-transaction-expected.txt
@@ -11,7 +11,7 @@ starting transaction state = 'starting' -trans = dbc1.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +trans = dbc1.transaction('storeName', 'readwrite') the transaction is kept alive with a series of puts until opens are complete
diff --git a/third_party/blink/web_tests/storage/indexeddb/optional-arguments-expected.txt b/third_party/blink/web_tests/storage/indexeddb/optional-arguments-expected.txt index 332780f..477220d 100644 --- a/third_party/blink/web_tests/storage/indexeddb/optional-arguments-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/optional-arguments-expected.txt
@@ -12,7 +12,7 @@ store = db.createObjectStore('store', {keyPath: 'id'}) store.createIndex('by_name', 'name', {unique: true}) store.put({id: 1, name: 'a'}) -tx = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +tx = db.transaction('store', 'readwrite') store = tx.objectStore('store') index = store.index('by_name') PASS IDBKeyRange.lowerBound(0).lowerOpen is false
diff --git a/third_party/blink/web_tests/storage/indexeddb/optional-arguments.html b/third_party/blink/web_tests/storage/indexeddb/optional-arguments.html index 17987d4..9033be7d 100644 --- a/third_party/blink/web_tests/storage/indexeddb/optional-arguments.html +++ b/third_party/blink/web_tests/storage/indexeddb/optional-arguments.html
@@ -18,7 +18,7 @@ function checkOptionalArguments(event) { - evalAndLog("tx = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readwrite')"); tx.oncomplete = finishJSTest; evalAndLog("store = tx.objectStore('store')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/pending-activity-expected.txt b/third_party/blink/web_tests/storage/indexeddb/pending-activity-expected.txt index a118c6dc..989317a 100644 --- a/third_party/blink/web_tests/storage/indexeddb/pending-activity-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/pending-activity-expected.txt
@@ -13,7 +13,7 @@ testTransaction(): -transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readonly') transaction.oncomplete = transactionOnComplete transaction = null self.gc() @@ -21,7 +21,7 @@ testRequest(): -transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readonly') store = transaction.objectStore('store') request = store.get(0) request.onsuccess = requestOnSuccess @@ -31,7 +31,7 @@ testCursorRequest(): -transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readonly') store = transaction.objectStore('store') request = store.openCursor() request.onsuccess = cursorRequestOnFirstSuccess
diff --git a/third_party/blink/web_tests/storage/indexeddb/pending-activity-workers-expected.txt b/third_party/blink/web_tests/storage/indexeddb/pending-activity-workers-expected.txt index 7ec30cd4..7c62ea1 100644 --- a/third_party/blink/web_tests/storage/indexeddb/pending-activity-workers-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/pending-activity-workers-expected.txt
@@ -12,14 +12,14 @@ [Worker] store.put(0, 0) [Worker] [Worker] testTransaction(): -[Worker] transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +[Worker] transaction = db.transaction('store', 'readonly') [Worker] transaction.oncomplete = transactionOnComplete [Worker] transaction = null [Worker] self.gc() PASS [Worker] Transaction 'complete' event fired. [Worker] [Worker] testRequest(): -[Worker] transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +[Worker] transaction = db.transaction('store', 'readonly') [Worker] store = transaction.objectStore('store') [Worker] request = store.get(0) [Worker] request.onsuccess = requestOnSuccess @@ -28,7 +28,7 @@ PASS [Worker] Request 'success' event fired. [Worker] [Worker] testCursorRequest(): -[Worker] transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +[Worker] transaction = db.transaction('store', 'readonly') [Worker] store = transaction.objectStore('store') [Worker] request = store.openCursor() [Worker] request.onsuccess = cursorRequestOnFirstSuccess
diff --git a/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation-expected.txt b/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation-expected.txt index efe516c..8edde01 100644 --- a/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation-expected.txt
@@ -20,7 +20,7 @@ doPrefetchInvalidationTest(): -store = db.transaction('store', 'readwrite', {durability: 'relaxed'}).objectStore('store') +store = db.transaction('store', 'readwrite').objectStore('store') Populate the store with 200 records. cursorRequest = store.openCursor() @@ -43,7 +43,7 @@ doPrefetchInvalidationTest(): -store = db.transaction('store', 'readwrite', {durability: 'relaxed'}).objectStore('store') +store = db.transaction('store', 'readwrite').objectStore('store') Populate the store with 200 records. cursorRequest = store.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation.html b/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation.html index 3e6866f..ef2c843 100644 --- a/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation.html +++ b/third_party/blink/web_tests/storage/indexeddb/prefetch-invalidation.html
@@ -39,7 +39,7 @@ debug(""); debug("-------------------------------------------"); preamble(); - evalAndLog("store = db.transaction('store', 'readwrite', {durability: 'relaxed'}).objectStore('store')"); + evalAndLog("store = db.transaction('store', 'readwrite').objectStore('store')"); debug("Populate the store with 200 records."); for (var i = 0; i < 200; ++i) store.put(i, i);
diff --git a/third_party/blink/web_tests/storage/indexeddb/prefetch-race-expected.txt b/third_party/blink/web_tests/storage/indexeddb/prefetch-race-expected.txt index 8bb4659..3d89bb9 100644 --- a/third_party/blink/web_tests/storage/indexeddb/prefetch-race-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/prefetch-race-expected.txt
@@ -15,7 +15,7 @@ onOpenSuccess(): db = event.target.result -tx = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +tx = db.transaction('store', 'readwrite') store = tx.objectStore('store') request = store.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/prefetch-race.html b/third_party/blink/web_tests/storage/indexeddb/prefetch-race.html index b222111c..ec1b7af 100644 --- a/third_party/blink/web_tests/storage/indexeddb/prefetch-race.html +++ b/third_party/blink/web_tests/storage/indexeddb/prefetch-race.html
@@ -21,7 +21,7 @@ preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("tx = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readwrite')"); evalAndLog("store = tx.objectStore('store')"); evalAndLog("request = store.openCursor()");
diff --git a/third_party/blink/web_tests/storage/indexeddb/request-continue-abort-expected.txt b/third_party/blink/web_tests/storage/indexeddb/request-continue-abort-expected.txt index 3041bf52..11777eb 100644 --- a/third_party/blink/web_tests/storage/indexeddb/request-continue-abort-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/request-continue-abort-expected.txt
@@ -9,7 +9,7 @@ testCursor: -transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readwrite') store = transaction.objectStore('store') store.add('value1', 'key1') store.add('value2', 'key2')
diff --git a/third_party/blink/web_tests/storage/indexeddb/request-leak-expected.txt b/third_party/blink/web_tests/storage/indexeddb/request-leak-expected.txt index 6b5a04a..837624e 100644 --- a/third_party/blink/web_tests/storage/indexeddb/request-leak-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/request-leak-expected.txt
@@ -15,7 +15,7 @@ onOpen(): db = event.target.result -tx = db.transaction('store', 'readonly', {durability: 'relaxed'}) +tx = db.transaction('store', 'readonly') store = tx.objectStore('store') request = store.get('key')
diff --git a/third_party/blink/web_tests/storage/indexeddb/request-leak.html b/third_party/blink/web_tests/storage/indexeddb/request-leak.html index 44efa06..d7eaf30 100644 --- a/third_party/blink/web_tests/storage/indexeddb/request-leak.html +++ b/third_party/blink/web_tests/storage/indexeddb/request-leak.html
@@ -25,7 +25,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("tx = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readonly')"); evalAndLog("store = tx.objectStore('store')"); evalAndLog("request = store.get('key')"); tx.oncomplete = function onTransactionComplete() {
diff --git a/third_party/blink/web_tests/storage/indexeddb/request-result-cache-expected.txt b/third_party/blink/web_tests/storage/indexeddb/request-result-cache-expected.txt index 28100d5..aa00cfb 100644 --- a/third_party/blink/web_tests/storage/indexeddb/request-result-cache-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/request-result-cache-expected.txt
@@ -14,7 +14,7 @@ onOpen(): db = event.target.result -tx = db.transaction('store', 'readonly', {durability: 'relaxed'}) +tx = db.transaction('store', 'readonly') store = tx.objectStore('store') cursorRequest = store.openCursor()
diff --git a/third_party/blink/web_tests/storage/indexeddb/request-result-cache.html b/third_party/blink/web_tests/storage/indexeddb/request-result-cache.html index 35840f63..214ab81 100644 --- a/third_party/blink/web_tests/storage/indexeddb/request-result-cache.html +++ b/third_party/blink/web_tests/storage/indexeddb/request-result-cache.html
@@ -19,7 +19,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("tx = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("tx = db.transaction('store', 'readonly')"); evalAndLog("store = tx.objectStore('store')"); evalAndLog("cursorRequest = store.openCursor()");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/aborted-versionchange-closes.js b/third_party/blink/web_tests/storage/indexeddb/resources/aborted-versionchange-closes.js index d46b74c..ff480a68 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/aborted-versionchange-closes.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/aborted-versionchange-closes.js
@@ -46,7 +46,7 @@ preamble(evt); evalAndLog("sawTransactionAbort = true"); debug("creating a transaction should fail because connection is closed:"); - evalAndExpectException("db.transaction('store', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('store', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); } function onOpenError(evt) @@ -54,6 +54,6 @@ preamble(evt); shouldBeTrue("sawTransactionAbort"); debug("creating a transaction should fail because connection is closed:"); - evalAndExpectException("db.transaction('store', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('store', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); finishJSTest(); }
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-continue-dir.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-continue-dir.js index 9514c046..e1d7fbac 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-continue-dir.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-continue-dir.js
@@ -17,7 +17,7 @@ function testCursors() { - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); evalAndLog("store = trans.objectStore('store')"); testForwardCursor(); }
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-finished.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-finished.js index c3594854..f8b9d79 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-finished.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-finished.js
@@ -38,7 +38,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readwrite')"); evalAndLog("store = transaction.objectStore('store')"); evalAndLog("count = 0"); evalAndLog("cursorRequest = store.openCursor()");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-key-order.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-key-order.js index 757ad22..489df44 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-key-order.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-key-order.js
@@ -118,7 +118,7 @@ { debug(""); debug("populating store..."); - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); evalAndLog("store = trans.objectStore('store');"); trans.onerror = unexpectedErrorCallback; trans.onabort = unexpectedAbortCallback; @@ -133,7 +133,7 @@ { debug(""); debug("iterating cursor..."); - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); evalAndLog("store = trans.objectStore('store');"); trans.onerror = unexpectedErrorCallback; trans.onabort = unexpectedAbortCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-prev-no-duplicate.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-prev-no-duplicate.js index b3278c8..e754ae3 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-prev-no-duplicate.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-prev-no-duplicate.js
@@ -17,7 +17,7 @@ { debug(""); debug("populating store..."); - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); evalAndLog("store = trans.objectStore('store');"); trans.onerror = unexpectedErrorCallback; trans.onabort = unexpectedAbortCallback; @@ -170,7 +170,7 @@ function runTest(openCursor, expectation, callback) { - trans = db.transaction('store', 'readonly', {durability: 'relaxed'}); + trans = db.transaction('store', 'readonly'); // expose these for code in openCursor store = trans.objectStore('store');
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-primary-key-order.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-primary-key-order.js index 94787f9..51805b72 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-primary-key-order.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-primary-key-order.js
@@ -37,7 +37,7 @@ { debug(""); debug("populating store..."); - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); evalAndLog("store = trans.objectStore('store');"); trans.onerror = unexpectedErrorCallback; trans.onabort = unexpectedAbortCallback; @@ -56,7 +56,7 @@ { debug(""); debug("iterating cursor..."); - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); evalAndLog("store = trans.objectStore('store');"); evalAndLog("index = store.index('index');"); trans.onerror = unexpectedErrorCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-properties.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-properties.js index aa5eb2c2..dbe9a85 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-properties.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-properties.js
@@ -34,7 +34,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); trans.onabort = unexpectedAbortCallback; evalAndLog("store = trans.objectStore('store')"); evalAndLog("index = store.index('index')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-reverse-bug.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-reverse-bug.js index 32338b9..e8c11a9 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-reverse-bug.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-reverse-bug.js
@@ -17,7 +17,7 @@ { debug(""); debug("populating store..."); - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); evalAndLog("store = trans.objectStore('store');"); trans.onerror = unexpectedErrorCallback; trans.onabort = unexpectedAbortCallback; @@ -47,7 +47,7 @@ test = tests.shift(); - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); trans.onerror = unexpectedErrorCallback; trans.onabort = unexpectedAbortCallback; trans.oncomplete = testCursor;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-update.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-update.js index ba34e72..2d4970ee 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-update.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-update.js
@@ -189,7 +189,7 @@ function testReadOnly() { debug("openBasicCursor()"); - evalAndLog("trans = db.transaction('basicStore', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('basicStore', 'readonly')"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = transactionComplete;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-value.js b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-value.js index a97cab4..03bc9bb 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/cursor-value.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/cursor-value.js
@@ -16,7 +16,7 @@ { debug(""); debug("testCursor():"); - evalAndLog("transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readwrite')"); evalAndLog("store = transaction.objectStore('store')"); evalAndLog("store.put({a: 1, b: 10}, 'key1')"); evalAndLog("store.put({a: 2, b: 20}, 'key2')"); @@ -92,7 +92,7 @@ { debug(""); debug("ensureModificationsNotPersisted():"); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("store = transaction.objectStore('store')"); evalAndLog("request = store.openCursor()"); request.onerror = unexpectedErrorCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/database-basics.js b/third_party/blink/web_tests/storage/indexeddb/resources/database-basics.js index da6fbf4..04a22bd 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/database-basics.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/database-basics.js
@@ -10,7 +10,7 @@ { db = event.target.result; debug("Test that you can't open a transaction while in a versionchange transaction"); - evalAndExpectException('db.transaction("doesntExist", "readonly", {durability: "relaxed"})', + evalAndExpectException('db.transaction("doesntExist", "readonly")', "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); shouldBe("db.version", "1"); @@ -70,7 +70,7 @@ { evalAndLog("db.close()"); debug("Now that the connection is closed, transaction creation should fail"); - evalAndExpectException("db.transaction('test123', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('test123', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); debug("Call twice, make sure it's harmless"); evalAndLog("db.close()"); finishJSTest();
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/database-close.js b/third_party/blink/web_tests/storage/indexeddb/resources/database-close.js index 4493392c..48a349a 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/database-close.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/database-close.js
@@ -20,10 +20,10 @@ debug("testClose():"); debug("Create transactions using connection:"); - evalAndLog("trans1 = connection.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans1 = connection.transaction('store', 'readonly')"); trans1.onabort = unexpectedAbortCallback; - evalAndLog("trans2 = connection.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans2 = connection.transaction('store', 'readonly')"); trans2.onabort = unexpectedAbortCallback; debug(""); @@ -65,7 +65,7 @@ debug(""); debug("NOTE: Once the closePending flag has been set to true no new transactions can be created using connection. All functions that create transactions first check the closePending flag first and throw an exception if it is true."); debug(""); - evalAndExpectException("trans3 = connection.transaction('store', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("trans3 = connection.transaction('store', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); debug(""); debug("NOTE: Once the connection is closed, this can unblock the steps for deleting a database, which waits for connections to a given database to be closed before continuing.");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/database-closepending-flag.js b/third_party/blink/web_tests/storage/indexeddb/resources/database-closepending-flag.js index 45ab4ce..efba22e 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/database-closepending-flag.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/database-closepending-flag.js
@@ -17,13 +17,13 @@ { debug(""); debug("First, verify that the database connection is not closed:"); - shouldNotThrow("transaction = connection.transaction('store', 'readonly', {durability: 'relaxed'})"); + shouldNotThrow("transaction = connection.transaction('store', 'readonly')"); debug(""); debug("Database closing steps"); debug("\"1. Set the internal closePending flag of connection to true.\""); evalAndLog("connection.close()"); - evalAndExpectException("connection.transaction('store', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("connection.transaction('store', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); debug("\"2. Wait for all transactions created using connection to complete. Once they are complete, connection is closed.\""); evalAndLog("transaction.oncomplete = testIDBDatabaseName"); @@ -68,7 +68,7 @@ debug(""); debug("IDBDatabase.transaction():"); debug("\"...if this method is called on a IDBDatabase instance where the closePending flag is set, a InvalidStateError exception must be thrown.\""); - evalAndExpectException("connection.transaction('store', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("connection.transaction('store', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); testVersionChangeTransactionSteps(); } @@ -87,7 +87,7 @@ evalAndLog("connection = request.result"); evalAndLog("versionChangeWasFired = false"); evalAndLog("connection.onversionchange = function () { versionChangeWasFired = true; }"); - evalAndLog("transaction = connection.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = connection.transaction('store', 'readonly')"); evalAndLog("connection.close()"); debug("closePending is set, but active transaction will keep connection from closing"); @@ -128,7 +128,7 @@ evalAndLog("connection = request.result"); evalAndLog("versionChangeWasFired = false"); evalAndLog("connection.onversionchange = function () { versionChangeWasFired = true; }"); - evalAndLog("transaction = connection.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = connection.transaction('store', 'readonly')"); evalAndLog("connection.close()"); debug("closePending is set, but active transaction will keep connection from closing");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/database-wrapper.js b/third_party/blink/web_tests/storage/indexeddb/resources/database-wrapper.js index 02ef6ce4..0d653a3 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/database-wrapper.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/database-wrapper.js
@@ -43,7 +43,7 @@ // All these local references should get collected, but the database's // wrapper shouldn't get collected before the database itself. - var transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}); + var transaction = db.transaction('store', 'readonly'); var objectStore = transaction.objectStore('store'); var request = objectStore.get(0); request.onsuccess = function() {
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/exceptions.js b/third_party/blink/web_tests/storage/indexeddb/resources/exceptions.js index 63774c6..55f100ef2 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/exceptions.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/exceptions.js
@@ -84,14 +84,14 @@ debug(""); debug("IDBDatabase.transaction()"); debug('If this method is called on IDBDatabase object for which a "versionchange" transaction is still running, a InvalidStateError exception must be thrown.'); - evalAndExpectException("db.transaction('store', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('store', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); }; } function checkTransactionAndObjectStoreExceptions() { debug("One of the names provided in the storeNames argument doesn't exist in this database."); - evalAndExpectException("db.transaction('no-such-store', 'readonly', {durability: 'relaxed'})", "DOMException.NOT_FOUND_ERR", "'NotFoundError'"); + evalAndExpectException("db.transaction('no-such-store', 'readonly')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'"); debug("The value for the mode parameter is invalid."); evalAndExpectExceptionClass("db.transaction('store', 'invalid-mode')", "TypeError"); debug("The 'versionchange' value for the mode parameter can only be set internally during upgradeneeded."); @@ -116,7 +116,7 @@ { debug(""); debug("Prepare an object store and index from an inactive transaction for later use."); - evalAndLog("finishedTransaction = inactiveTransaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("finishedTransaction = inactiveTransaction = db.transaction('store', 'readonly')"); inactiveTransaction.onabort = unexpectedAbortCallback; evalAndLog("storeFromInactiveTransaction = inactiveTransaction.objectStore('store')"); evalAndLog("indexFromInactiveTransaction = storeFromInactiveTransaction.index('index')"); @@ -132,9 +132,9 @@ { debug(""); debug("3.2.5 Object Store"); - evalAndLog("ro_transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("ro_transaction = db.transaction('store', 'readonly')"); evalAndLog("storeFromReadOnlyTransaction = ro_transaction.objectStore('store')"); - evalAndLog("rw_transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("rw_transaction = db.transaction('store', 'readwrite')"); evalAndLog("store = rw_transaction.objectStore('store')"); debug(""); @@ -285,12 +285,12 @@ debug(""); debug("One more IDBObjectStore.createIndex() test:"); debug('If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError.'); - evalAndExpectException("db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store').createIndex('fail', 'keyPath')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('store', 'readonly').objectStore('store').createIndex('fail', 'keyPath')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); debug(""); debug("One more IDBObjectStore.deleteIndex() test:"); debug('If this function is called from outside a "versionchange" transaction callback ... the implementation must throw a DOMException of type InvalidStateError.'); - evalAndExpectException("db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store').deleteIndex('fail', 'keyPath')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('store', 'readonly').objectStore('store').deleteIndex('fail', 'keyPath')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); testIndex(); } @@ -298,8 +298,8 @@ { debug(""); debug("3.2.6 Index"); - evalAndLog("indexFromReadOnlyTransaction = db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('store').index('index')"); - evalAndLog("index = db.transaction('store', 'readwrite', {durability: 'relaxed'}).objectStore('store').index('index')"); + evalAndLog("indexFromReadOnlyTransaction = db.transaction('store', 'readonly').objectStore('store').index('index')"); + evalAndLog("index = db.transaction('store', 'readwrite').objectStore('store').index('index')"); debug(""); debug("IDBIndex.count()"); @@ -471,7 +471,7 @@ // Can't have both transactions running at once, so these tests must be separated out. function makeReadOnlyCursor() { - evalAndLog("readOnlyTransaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("readOnlyTransaction = db.transaction('store', 'readonly')"); evalAndLog("request = readOnlyTransaction.objectStore('store').openCursor()"); request.onerror = unexpectedErrorCallback; request.onsuccess = function() { @@ -505,7 +505,7 @@ debug("If this transaction is finished, throw a DOMException of type InvalidStateError. "); evalAndExpectException("finishedTransaction.abort()", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); debug("If the requested object store is not in this transaction's scope."); - evalAndExpectException("db.transaction('store', 'readonly', {durability: 'relaxed'}).objectStore('otherStore')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'"); + evalAndExpectException("db.transaction('store', 'readonly').objectStore('otherStore')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'"); finishJSTest(); }
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/factory-deletedatabase.js b/third_party/blink/web_tests/storage/indexeddb/resources/factory-deletedatabase.js index aa4de86..78edfb2e 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/factory-deletedatabase.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/factory-deletedatabase.js
@@ -21,7 +21,7 @@ function getValue() { - transaction = evalAndLog("db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + transaction = evalAndLog("db.transaction('storeName', 'readwrite')"); transaction.onabort = unexpectedErrorCallback; var store = evalAndLog("store = transaction.objectStore('storeName')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/index-count.js b/third_party/blink/web_tests/storage/indexeddb/resources/index-count.js index f28381b4..247476f 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/index-count.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/index-count.js
@@ -26,7 +26,7 @@ { debug(""); debug("verifying count without range"); - trans = evalAndLog("trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('storeName', 'readonly')"); shouldBeNonNull("trans"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = verifyCountWithRange; @@ -49,7 +49,7 @@ { debug(""); debug("verifying count with range"); - trans = evalAndLog("trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('storeName', 'readonly')"); shouldBeNonNull("trans"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = verifyCountWithKey; @@ -94,7 +94,7 @@ { debug(""); debug("verifying count with key"); - trans = evalAndLog("trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('storeName', 'readonly')"); shouldBeNonNull("trans"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = finishJSTest;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/index-duplicate-keypaths.js b/third_party/blink/web_tests/storage/indexeddb/resources/index-duplicate-keypaths.js index ef1c2949b..5f696bd5 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/index-duplicate-keypaths.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/index-duplicate-keypaths.js
@@ -22,7 +22,7 @@ }; function storeCollidedStoreIndexData() { - var trans = db.transaction('collideWithIndex', 'readwrite', {durability: 'relaxed'}); + var trans = db.transaction('collideWithIndex', 'readwrite'); objectStore = trans.objectStore('collideWithIndex'); index = objectStore.index('foo'); @@ -59,7 +59,7 @@ function storeCollidedAutoIncrementData() { - var trans = db.transaction('collideWithAutoIncrement', 'readwrite', {durability: 'relaxed'}); + var trans = db.transaction('collideWithAutoIncrement', 'readwrite'); objectStore = trans.objectStore('collideWithAutoIncrement'); index = objectStore.index('foo');
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-oncomplete.js b/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-oncomplete.js index 8ad164bd..e652fd2 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-oncomplete.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-oncomplete.js
@@ -48,7 +48,7 @@ shouldBeUndefined("event.target.result"); shouldBeNonNull("event.target.error"); shouldBeEqualToString("event.target.error.name", "AbortError"); - evalAndExpectException("transaction = db.transaction('os', 'readwrite', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("transaction = db.transaction('os', 'readwrite')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); finishJSTest(); }
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-upgradeneeded.js b/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-upgradeneeded.js index 3eefce7..3f2dcc4a 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-upgradeneeded.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/intversion-close-in-upgradeneeded.js
@@ -53,7 +53,7 @@ debug("Verify that the old connection is unchanged and was closed:"); shouldBeNonNull("db"); shouldBe('db.version', "7"); - evalAndExpectException("db.transaction('os', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('os', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); finishJSTest(); }
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/intversion-open-in-upgradeneeded.js b/third_party/blink/web_tests/storage/indexeddb/resources/intversion-open-in-upgradeneeded.js index 243fb179..ae49a6e8 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/intversion-open-in-upgradeneeded.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/intversion-open-in-upgradeneeded.js
@@ -51,7 +51,7 @@ db = evalAndLog("db = event.target.result"); shouldBe('db.version', "1"); debug("Start a transaction to ensure the connection is still open."); - evalAndLog("transaction = db.transaction('os', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('os', 'readonly')"); } function onVersionChange(evt)
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/key-generator.js b/third_party/blink/web_tests/storage/indexeddb/resources/key-generator.js index d762289..4893109 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/key-generator.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/key-generator.js
@@ -232,7 +232,7 @@ function doFirstWrite() { debug(""); - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); trans.onabort = unexpectedAbortCallback; evalAndLog("request = trans.objectStore('store').put('value1')"); request.onerror = unexpectedErrorCallback; @@ -254,7 +254,7 @@ } function doSecondWrite() { - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); trans.onabort = unexpectedAbortCallback; evalAndLog("request = trans.objectStore('store').put('value2')"); request.onerror = unexpectedErrorCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/key-type-array.js b/third_party/blink/web_tests/storage/indexeddb/resources/key-type-array.js index 6e7eb61..0c8c082 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/key-type-array.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/key-type-array.js
@@ -16,7 +16,7 @@ function testValidArrayKeys() { - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); evalAndLog("store = trans.objectStore('store')"); debug(""); @@ -99,7 +99,7 @@ function testInvalidArrayKeys() { - evalAndLog("trans = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readwrite')"); evalAndLog("store = trans.objectStore('store')"); debug("");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/keypath-intrinsic-properties.js b/third_party/blink/web_tests/storage/indexeddb/resources/keypath-intrinsic-properties.js index 990de24..30f9afd 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/keypath-intrinsic-properties.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/keypath-intrinsic-properties.js
@@ -21,7 +21,7 @@ { preamble(); - transaction = evalAndLog("transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + transaction = evalAndLog("transaction = db.transaction('store', 'readwrite')"); transaction.onabort = unexpectedAbortCallback; store = evalAndLog("store = transaction.objectStore('store')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/lazy-index-types.js b/third_party/blink/web_tests/storage/indexeddb/resources/lazy-index-types.js index 746cb66..5b7a1d6a 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/lazy-index-types.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/lazy-index-types.js
@@ -60,7 +60,7 @@ { preamble(evt); evalAndLog("db = event.target.result"); - evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('store', 'readonly')"); trans.onabort = unexpectedAbortCallback; evalAndLog("store = trans.objectStore('store')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-autoincrement.js b/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-autoincrement.js index fbb17f94..2e9ad7bc 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-autoincrement.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-autoincrement.js
@@ -131,7 +131,7 @@ function testLongKeyPath() { debug("testLongKeyPath():"); - trans = evalAndLog("trans = db.transaction('StoreWithLongKeyPath', 'readwrite', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('StoreWithLongKeyPath', 'readwrite')"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = finishJSTest;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-count.js b/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-count.js index 8518b31..04fef7f 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-count.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/objectstore-count.js
@@ -24,7 +24,7 @@ { debug(""); debug("verifying count without range"); - trans = evalAndLog("trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('storeName', 'readonly')"); shouldBeNonNull("trans"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = verifyCountWithRange; @@ -45,7 +45,7 @@ { debug(""); debug("verifying count with range"); - trans = evalAndLog("trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('storeName', 'readonly')"); shouldBeNonNull("trans"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = verifyCountWithKey; @@ -88,7 +88,7 @@ { debug(""); debug("verifying count with key"); - trans = evalAndLog("trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('storeName', 'readonly')"); shouldBeNonNull("trans"); trans.onabort = unexpectedAbortCallback; trans.oncomplete = finishJSTest;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/open-during-transaction.js b/third_party/blink/web_tests/storage/indexeddb/resources/open-during-transaction.js index 1a07ebb..19a56a7 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/open-during-transaction.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/open-during-transaction.js
@@ -20,7 +20,7 @@ { debug("starting transaction"); evalAndLog("state = 'starting'"); - evalAndLog("trans = dbc1.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = dbc1.transaction('storeName', 'readwrite')"); debug("the transaction is kept alive with a series of puts until opens are complete"); (function keepAlive() {
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/pending-activity.js b/third_party/blink/web_tests/storage/indexeddb/resources/pending-activity.js index 2d6dfbd2..e432ebff 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/pending-activity.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/pending-activity.js
@@ -18,7 +18,7 @@ function testTransaction() { preamble(); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("transaction.oncomplete = transactionOnComplete"); evalAndLog("transaction = null"); evalAndLog("self.gc()"); @@ -33,7 +33,7 @@ function testRequest() { preamble(); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("store = transaction.objectStore('store')"); evalAndLog("request = store.get(0)"); evalAndLog("request.onsuccess = requestOnSuccess"); @@ -50,7 +50,7 @@ function testCursorRequest() { preamble(); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("store = transaction.objectStore('store')"); evalAndLog("request = store.openCursor()"); evalAndLog("request.onsuccess = cursorRequestOnFirstSuccess");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/request-continue-abort.js b/third_party/blink/web_tests/storage/indexeddb/resources/request-continue-abort.js index 5fcccfd4..ca32dd2 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/request-continue-abort.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/request-continue-abort.js
@@ -18,7 +18,7 @@ { debug(""); debug("testCursor:"); - evalAndLog("transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readwrite')"); evalAndLog("store = transaction.objectStore('store')"); request = evalAndLog("store.add('value1', 'key1')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-active-flag.js b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-active-flag.js index 3a5fc7d..2f7f150 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-active-flag.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-active-flag.js
@@ -18,7 +18,7 @@ { debug(""); debug("runTransaction():"); - evalAndLog("transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readwrite')"); debug(""); debug("Verify that transactions are created with |active| flag set:");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-and-objectstore-calls.js b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-and-objectstore-calls.js index 67f14c5..2eaf1d7 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-and-objectstore-calls.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-and-objectstore-calls.js
@@ -50,7 +50,7 @@ debug(""); debug("Passing a string as the first argument is a shortcut for just one object store:"); - trans = evalAndLog("trans = db.transaction('a', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('a', 'readonly')"); evalAndLog("trans.objectStore('a')"); evalAndExpectException("trans.objectStore('b')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'"); evalAndExpectException("trans.objectStore('x')", "DOMException.NOT_FOUND_ERR", "'NotFoundError'");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-complete-workers.js b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-complete-workers.js index d2a7534..e72fa3a 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-complete-workers.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-complete-workers.js
@@ -18,7 +18,7 @@ { debug(""); debug("createTransaction():"); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("store = transaction.objectStore('store')"); transaction.onerror = unexpectedErrorCallback; transaction.onabort = unexpectedAbortCallback; @@ -36,7 +36,7 @@ { debug(""); debug("recursionTest():"); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("store = transaction.objectStore('store')"); transaction.oncomplete = transactionCompleted; transaction.onabort = unexpectedAbortCallback; @@ -73,7 +73,7 @@ debug(""); debug("timeoutTest():"); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("store = transaction.objectStore('store')"); transaction.onabort = unexpectedAbortCallback; transaction.oncomplete = function () { @@ -100,7 +100,7 @@ // FIXME: Should be able to stop the error here, but it isn't an Event object. // evalAndLog("event.preventDefault()"); evalAndLog("self.onerror = self.old_onerror"); - evalAndLog("transaction = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + evalAndLog("transaction = db.transaction('store', 'readonly')"); evalAndLog("store = transaction.objectStore('store')"); transaction.onerror = unexpectedErrorCallback; transaction.onabort = unexpectedAbortCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-crash-on-abort.js b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-crash-on-abort.js index cf33dd1..7c21197 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-crash-on-abort.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-crash-on-abort.js
@@ -15,7 +15,7 @@ function setVersionComplete() { - evalAndLog("db.transaction('foo', 'readonly', {durability: 'relaxed'})"); + evalAndLog("db.transaction('foo', 'readonly')"); evalAndLog("self.gc()"); finishJSTest(); }
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-error.js b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-error.js index bc5dd99..135e5b6 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-error.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-error.js
@@ -18,7 +18,7 @@ function startTest() { debug(""); - evalAndLog("trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('storeName', 'readonly')"); debug(""); debug("IDBTransaction.error should be null if transaction is not finished:"); @@ -42,7 +42,7 @@ { debug(""); debug("If the transaction is aborted due to a request error that is not prevented, IDBTransaction.error should match:"); - evalAndLog("trans = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('storeName', 'readwrite')"); evalAndLog("request = trans.objectStore('storeName').add('value2', 'key')"); request.onsuccess = unexpectedSuccessCallback; request.onerror = function() { @@ -66,7 +66,7 @@ { debug(""); debug("If the transaction is aborted due to an exception thrown from event callback, IDBTransaction.error should be AbortError:"); - evalAndLog("trans = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('storeName', 'readwrite')"); evalAndLog("request = trans.objectStore('storeName').add('value2', 'key')"); request.onsuccess = unexpectedSuccessCallback; request.onerror = function() { @@ -100,7 +100,7 @@ { debug(""); debug("If the transaction is aborted due to an error during commit, IDBTransaction.error should reflect that error:"); - evalAndLog("trans = db.transaction('storeName', 'readwrite', {durability: 'relaxed'})"); + evalAndLog("trans = db.transaction('storeName', 'readwrite')"); evalAndLog("request = trans.objectStore('storeName').add({id: 1}, 'record1')"); request.onerror = unexpectedErrorCallback; evalAndLog("request = trans.objectStore('storeName').add({id: 1}, 'record2')");
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-read-only.js b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-read-only.js index 611e969..7ac4a1b 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/transaction-read-only.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/transaction-read-only.js
@@ -16,13 +16,13 @@ function setVersionDone() { - trans = evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('store', 'readonly')"); evalAndExpectException("trans.objectStore('store').put('a', 'b')", "0", "'ReadOnlyError'"); - trans = evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('store', 'readonly')"); evalAndExpectException("trans.objectStore('store').delete('x')", "0", "'ReadOnlyError'"); - trans = evalAndLog("trans = db.transaction('store', 'readonly', {durability: 'relaxed'})"); + trans = evalAndLog("trans = db.transaction('store', 'readonly')"); cur = evalAndLog("cur = trans.objectStore('store').openCursor()"); cur.onsuccess = gotCursor; cur.onerror = unexpectedErrorCallback;
diff --git a/third_party/blink/web_tests/storage/indexeddb/resources/version-change-exclusive.js b/third_party/blink/web_tests/storage/indexeddb/resources/version-change-exclusive.js index cd940da..70c93b6 100644 --- a/third_party/blink/web_tests/storage/indexeddb/resources/version-change-exclusive.js +++ b/third_party/blink/web_tests/storage/indexeddb/resources/version-change-exclusive.js
@@ -23,7 +23,7 @@ evalAndLog("self.state = 'VERSION_CHANGE started'"); self.store = evalAndLog("store = db.createObjectStore('test-store')"); - evalAndExpectException("db.transaction('test-store', 'readonly', {durability: 'relaxed'})", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); + evalAndExpectException("db.transaction('test-store', 'readonly')", "DOMException.INVALID_STATE_ERR", "'InvalidStateError'"); self.count = 0; do_async_puts();
diff --git a/third_party/blink/web_tests/storage/indexeddb/transaction-active-flag-expected.txt b/third_party/blink/web_tests/storage/indexeddb/transaction-active-flag-expected.txt index e5dc19f4..2daeff6 100644 --- a/third_party/blink/web_tests/storage/indexeddb/transaction-active-flag-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/transaction-active-flag-expected.txt
@@ -10,7 +10,7 @@ runTransaction(): -transaction = db.transaction('store', 'readwrite', {durability: 'relaxed'}) +transaction = db.transaction('store', 'readwrite') Verify that transactions are created with |active| flag set:
diff --git a/third_party/blink/web_tests/storage/indexeddb/transaction-and-objectstore-calls-expected.txt b/third_party/blink/web_tests/storage/indexeddb/transaction-and-objectstore-calls-expected.txt index 9b3ecee..2c17e89 100644 --- a/third_party/blink/web_tests/storage/indexeddb/transaction-and-objectstore-calls-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/transaction-and-objectstore-calls-expected.txt
@@ -73,7 +73,7 @@ Passing a string as the first argument is a shortcut for just one object store: -trans = db.transaction('a', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('a', 'readonly') trans.objectStore('a') Expecting exception from trans.objectStore('b') PASS Exception was thrown.
diff --git a/third_party/blink/web_tests/storage/indexeddb/transaction-complete-workers-expected.txt b/third_party/blink/web_tests/storage/indexeddb/transaction-complete-workers-expected.txt index 367a2cd..1eda8aac 100644 --- a/third_party/blink/web_tests/storage/indexeddb/transaction-complete-workers-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/transaction-complete-workers-expected.txt
@@ -11,7 +11,7 @@ [Worker] db.createObjectStore('store') [Worker] [Worker] createTransaction(): -[Worker] transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +[Worker] transaction = db.transaction('store', 'readonly') [Worker] store = transaction.objectStore('store') PASS [Worker] Transaction completed [Worker] Expecting exception from store.get(0) @@ -21,7 +21,7 @@ [Worker] Exception message: Failed to execute 'get' on 'IDBObjectStore': The transaction has finished. [Worker] [Worker] recursionTest(): -[Worker] transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +[Worker] transaction = db.transaction('store', 'readonly') [Worker] store = transaction.objectStore('store') [Worker] store.get(0) PASS [Worker] transaction is active @@ -54,7 +54,7 @@ [Worker] setTimeout(timeoutTest, 0) [Worker] [Worker] timeoutTest(): -[Worker] transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +[Worker] transaction = db.transaction('store', 'readonly') [Worker] store = transaction.objectStore('store') PASS [Worker] transaction started in setTimeout() callback completed [Worker] Expecting exception from store.get(0) @@ -69,7 +69,7 @@ [Worker] [Worker] errorHandler(): [Worker] self.onerror = self.old_onerror -[Worker] transaction = db.transaction('store', 'readonly', {durability: 'relaxed'}) +[Worker] transaction = db.transaction('store', 'readonly') [Worker] store = transaction.objectStore('store') Got expected error from worker, ignoring event.preventDefault()
diff --git a/third_party/blink/web_tests/storage/indexeddb/transaction-crash-on-abort-expected.txt b/third_party/blink/web_tests/storage/indexeddb/transaction-crash-on-abort-expected.txt index 6ff3786f..9746cdf 100644 --- a/third_party/blink/web_tests/storage/indexeddb/transaction-crash-on-abort-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/transaction-crash-on-abort-expected.txt
@@ -6,7 +6,7 @@ indexedDB.deleteDatabase(dbname) indexedDB.open(dbname) db.createObjectStore('foo') -db.transaction('foo', 'readonly', {durability: 'relaxed'}) +db.transaction('foo', 'readonly') self.gc() PASS successfullyParsed is true
diff --git a/third_party/blink/web_tests/storage/indexeddb/transaction-error-expected.txt b/third_party/blink/web_tests/storage/indexeddb/transaction-error-expected.txt index a465bca0..1644c171 100644 --- a/third_party/blink/web_tests/storage/indexeddb/transaction-error-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/transaction-error-expected.txt
@@ -10,7 +10,7 @@ store.add('value', 'key') -trans = db.transaction('storeName', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readonly') IDBTransaction.error should be null if transaction is not finished: @@ -27,7 +27,7 @@ If the transaction is aborted due to a request error that is not prevented, IDBTransaction.error should match: -trans = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readwrite') request = trans.objectStore('storeName').add('value2', 'key') PASS request.result is undefined. PASS request.error is non-null. @@ -41,7 +41,7 @@ If the transaction is aborted due to an exception thrown from event callback, IDBTransaction.error should be AbortError: -trans = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readwrite') request = trans.objectStore('storeName').add('value2', 'key') PASS request.result is undefined. PASS request.error is non-null. @@ -55,7 +55,7 @@ If the transaction is aborted due to an error during commit, IDBTransaction.error should reflect that error: -trans = db.transaction('storeName', 'readwrite', {durability: 'relaxed'}) +trans = db.transaction('storeName', 'readwrite') request = trans.objectStore('storeName').add({id: 1}, 'record1') request = trans.objectStore('storeName').add({id: 1}, 'record2') request = indexedDB.open(dbname, 2)
diff --git a/third_party/blink/web_tests/storage/indexeddb/transaction-read-only-expected.txt b/third_party/blink/web_tests/storage/indexeddb/transaction-read-only-expected.txt index 3977a46..5c5392c 100644 --- a/third_party/blink/web_tests/storage/indexeddb/transaction-read-only-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/transaction-read-only-expected.txt
@@ -7,19 +7,19 @@ indexedDB.open(dbname) store = db.createObjectStore('store') store.put('x', 'y') -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') Expecting exception from trans.objectStore('store').put('a', 'b') PASS Exception was thrown. PASS code is 0 PASS ename is 'ReadOnlyError' Exception message: Failed to execute 'put' on 'IDBObjectStore': The transaction is read-only. -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') Expecting exception from trans.objectStore('store').delete('x') PASS Exception was thrown. PASS code is 0 PASS ename is 'ReadOnlyError' Exception message: Failed to execute 'delete' on 'IDBObjectStore': The transaction is read-only. -trans = db.transaction('store', 'readonly', {durability: 'relaxed'}) +trans = db.transaction('store', 'readonly') cur = trans.objectStore('store').openCursor() PASS !event.target.result is false Expecting exception from event.target.result.delete()
diff --git a/third_party/blink/web_tests/storage/indexeddb/version-change-exclusive-expected.txt b/third_party/blink/web_tests/storage/indexeddb/version-change-exclusive-expected.txt index 4ffb82fd..653d954 100644 --- a/third_party/blink/web_tests/storage/indexeddb/version-change-exclusive-expected.txt +++ b/third_party/blink/web_tests/storage/indexeddb/version-change-exclusive-expected.txt
@@ -11,7 +11,7 @@ starting work in VERSION_CHANGE transaction self.state = 'VERSION_CHANGE started' store = db.createObjectStore('test-store') -Expecting exception from db.transaction('test-store', 'readonly', {durability: 'relaxed'}) +Expecting exception from db.transaction('test-store', 'readonly') PASS Exception was thrown. PASS code is DOMException.INVALID_STATE_ERR PASS ename is 'InvalidStateError'
diff --git a/third_party/blink/web_tests/virtual/at-property-string-syntax/README.md b/third_party/blink/web_tests/virtual/at-property-string-syntax/README.md deleted file mode 100644 index a2327c9b..0000000 --- a/third_party/blink/web_tests/virtual/at-property-string-syntax/README.md +++ /dev/null
@@ -1 +0,0 @@ -This directory is for testing <string> syntax in @property when CSSAtPropertyStringSyntax flag is disabled (https://crbug.com/357751736). \ No newline at end of file
diff --git a/third_party/blink/web_tests/virtual/at-property-string-syntax/external/wpt/css/css-properties-values-api/at-property-expected.txt b/third_party/blink/web_tests/virtual/at-property-string-syntax/external/wpt/css/css-properties-values-api/at-property-expected.txt deleted file mode 100644 index 2331c6cd..0000000 --- a/third_party/blink/web_tests/virtual/at-property-string-syntax/external/wpt/css/css-properties-values-api/at-property-expected.txt +++ /dev/null
@@ -1,30 +0,0 @@ -This is a testharness.js-based test. -Found 13 FAIL, 0 TIMEOUT, 0 NOTRUN. -[FAIL] Rule applied [<string>, 'foo bar', false] - assert_equals: expected "\\"foo bar\\"" but got "" -[FAIL] Rule applied [<string>, 'foo bar' , false] - assert_equals: expected "\\"foo bar\\"" but got "" -[FAIL] Rule applied [<string>, '"foo" bar', false] - assert_equals: expected "\\"\\\\\\"foo\\\\\\" bar\\"" but got "" -[FAIL] Rule applied [<string>, "bar baz", false] - assert_equals: expected "\\"bar baz\\"" but got "" -[FAIL] Rule applied [<string>, "bar 'baz'", false] - assert_equals: expected "\\"bar 'baz'\\"" but got "" -[FAIL] Rule applied [<string>+, 'foo' 'bar', false] - assert_equals: expected "\\"foo\\" \\"bar\\"" but got "" -[FAIL] Rule applied [<string>#, 'foo', 'bar', false] - assert_equals: expected "\\"foo\\", \\"bar\\"" but got "" -[FAIL] Rule applied [<string>+ | <string>#, 'foo' 'bar', false] - assert_equals: expected "\\"foo\\" \\"bar\\"" but got "" -[FAIL] Rule applied [<string>+ | <string>#, 'foo' 'bar', false] - assert_equals: expected "\\"foo\\" \\"bar\\"" but got "" -[FAIL] Rule applied [<string>+ | <string>#, 'foo' "bar", false] - assert_equals: expected "\\"foo\\" \\"bar\\"" but got "" -[FAIL] Rule applied [<string># | <string>+, 'foo', 'bar', false] - assert_equals: expected "\\"foo\\", \\"bar\\"" but got "" -[FAIL] Rule applied [<string># | <string>+, 'foo', 'bar' , false] - assert_equals: expected "\\"foo\\", \\"bar\\"" but got "" -[FAIL] Rule applied [<string># | <string>+, "foo", 'bar', false] - assert_equals: expected "\\"foo\\", \\"bar\\"" but got "" -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/customizable-select-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt b/third_party/blink/web_tests/virtual/customizable-select-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt index bb56e6a3..32e12fa 100644 --- a/third_party/blink/web_tests/virtual/customizable-select-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt +++ b/third_party/blink/web_tests/virtual/customizable-select-disabled/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt
@@ -1,5 +1,7 @@ This is a testharness.js-based test. [FAIL] In dialog mode the first focusable element should get focus. promise_test: Unhandled rejection with value: object "ReferenceError: interactive1 is not defined" +[FAIL] In dialog mode tab should not close the picker. + assert_false: The select should initially be closed. expected false got true Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/dialog-close-when-open-removed-disabled/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative-expected.txt b/third_party/blink/web_tests/virtual/dialog-close-when-open-removed-disabled/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative-expected.txt deleted file mode 100644 index 9568648..0000000 --- a/third_party/blink/web_tests/virtual/dialog-close-when-open-removed-disabled/external/wpt/html/semantics/interactive-elements/the-dialog-element/dialog-close-via-attribute.tentative-expected.txt +++ /dev/null
@@ -1,7 +0,0 @@ -This is a testharness.js-based test. -[FAIL] Removing the open attribute from an open modal dialog should run the closing algorithm. - assert_false: The dialog should not match :modal after closing. expected false got true -[FAIL] Removing the open attribute from an open non-modal dialog should fire a close event. - assert_true: The close event should be fired when removing the open attribute. expected true got false -Harness: the test ran to completion. -
diff --git a/third_party/blink/web_tests/virtual/select-parser-relaxation/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt b/third_party/blink/web_tests/virtual/select-parser-relaxation/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt index 494bf88..aebef54 100644 --- a/third_party/blink/web_tests/virtual/select-parser-relaxation/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt +++ b/third_party/blink/web_tests/virtual/select-parser-relaxation/external/wpt/html/semantics/forms/the-select-element/customizable-select/select-dialog-mode-focus.tentative-expected.txt
@@ -1,4 +1,7 @@ This is a testharness.js-based test. [FAIL] In dialog mode the first focusable element should get focus. + assert_equals: The anchor should be focused. expected Element node <a id="interactive1" href="https://www.example.com/">Elep... but got Element node <select id="target">\n <div></div>\n <span></span>\n <a i... +[FAIL] In dialog mode tab should not close the picker. + assert_false: The select should initially be closed. expected false got true Harness: the test ran to completion.
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt index fab3936..d2e582e 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/element-instance-property-listing-expected.txt
@@ -692,6 +692,7 @@ property alt property attributionSrc property border + property browsingTopics property complete property crossOrigin property currentSrc
diff --git a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt index 608b51a5..d17468f 100644 --- a/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/virtual/stable/webexposed/global-interface-listing-expected.txt
@@ -3895,6 +3895,7 @@ getter alt getter attributionSrc getter border + getter browsingTopics getter complete getter crossOrigin getter currentSrc @@ -3925,6 +3926,7 @@ setter alt setter attributionSrc setter border + setter browsingTopics setter crossOrigin setter decoding setter fetchPriority @@ -5004,6 +5006,7 @@ getter alt getter attributionSrc getter border + getter browsingTopics getter complete getter crossOrigin getter currentSrc @@ -5034,6 +5037,7 @@ setter alt setter attributionSrc setter border + setter browsingTopics setter crossOrigin setter decoding setter fetchPriority
diff --git a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt index 48c11264..7bd5528 100644 --- a/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/element-instance-property-listing-expected.txt
@@ -728,6 +728,7 @@ property alt property attributionSrc property border + property browsingTopics property complete property crossOrigin property currentSrc
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 cbdabfe..cca620b 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
@@ -4333,6 +4333,7 @@ getter alt getter attributionSrc getter border + getter browsingTopics getter complete getter crossOrigin getter currentSrc @@ -4363,6 +4364,7 @@ setter alt setter attributionSrc setter border + setter browsingTopics setter crossOrigin setter decoding setter fetchPriority @@ -5488,6 +5490,7 @@ getter alt getter attributionSrc getter border + getter browsingTopics getter complete getter crossOrigin getter currentSrc @@ -5518,6 +5521,7 @@ setter alt setter attributionSrc setter border + setter browsingTopics setter crossOrigin setter decoding setter fetchPriority
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-overflow/unreachable-scroll-markers.html b/third_party/blink/web_tests/wpt_internal/css/css-overflow/unreachable-scroll-markers.html index f3a7f1d..0cf9949 100644 --- a/third_party/blink/web_tests/wpt_internal/css/css-overflow/unreachable-scroll-markers.html +++ b/third_party/blink/web_tests/wpt_internal/css/css-overflow/unreachable-scroll-markers.html
@@ -12,6 +12,7 @@ <script src="/resources/testdriver-vendor.js"></script> <script src="/css/css-transitions/support/helper.js"></script> <script src="/dom/events/scrolling/scroll_support.js"></script> + <script src="/css/css-overflow/support/scroll-marker-support.js"></script> </head> <body> @@ -117,17 +118,6 @@ RED = "rgb(255, 0, 0)"; GREEN = "rgb(0, 128, 0)"; - function verifySelectedMarker(selected_idx) { - for (let idx = 0; idx < items.length; ++idx) { - const should_be_selected = idx == selected_idx - let expected_color = should_be_selected ? GREEN : RED; - const color = - getComputedStyle(items[idx], "::scroll-marker").backgroundColor; - assert_equals(color, expected_color, - `marker ${idx} should be ${should_be_selected ? "" : "un"}selected.`); - } - } - async function test_unreachable(idx, dragAmount, targetLower, targetUpper) { const scroll_promise = new Promise((resolve) => { carousel.addEventListener("scroll", () => { @@ -158,7 +148,7 @@ assert_less_than_equal(carousel.scrollLeft, targetUpper, `scrolled within region reserved for unreachable ${idx}.`); - verifySelectedMarker(idx); + verifySelectedMarker(idx, items, GREEN, RED); // Complete the scroll gesture. actions_promise = actions.pointerUp().send(); @@ -195,7 +185,7 @@ let scrollend_promise = waitForScrollendEventNoTimeout(carousel); carousel.scrollLeft = maxScrollOffset; await scrollend_promise; - verifySelectedMarker(15); + verifySelectedMarker(15, items, GREEN, RED); await test_unreachable(14, delta_x, maxScrollOffset - 2 * allocation_per_target_within_reserved, @@ -204,7 +194,7 @@ scrollend_promise = waitForScrollendEventNoTimeout(carousel); carousel.scrollLeft = 0; await scrollend_promise; - verifySelectedMarker(0); + verifySelectedMarker(0, items, GREEN, RED); }, "scroll-marker whose originating element cannot be scroll-aligned is " + "selected when scrolling within 1/8 of the scroll port."); </script>
diff --git a/third_party/boringssl/src b/third_party/boringssl/src index 281352b..5a2194f 160000 --- a/third_party/boringssl/src +++ b/third_party/boringssl/src
@@ -1 +1 @@ -Subproject commit 281352b8c65da0831269ab4c6614d3b431a6e93d +Subproject commit 5a2194f43d8801335e4b20040156686eb4247b22
diff --git a/third_party/catapult b/third_party/catapult index 86d6f8e..b3934f5 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit 86d6f8ee6130eb3d6a43db7ac883c7d39df1c158 +Subproject commit b3934f5a9aa01f3a1a1421db86ba0da90b601020
diff --git a/third_party/chromite b/third_party/chromite index 249badc..bcc0e90 160000 --- a/third_party/chromite +++ b/third_party/chromite
@@ -1 +1 @@ -Subproject commit 249badca44938d6d13d343e99744f1b0e280b919 +Subproject commit bcc0e90690a83cc09d4bc39860cf152a47b38347
diff --git a/third_party/chromium-variations b/third_party/chromium-variations index 18d4fbe..0fcd7c5 160000 --- a/third_party/chromium-variations +++ b/third_party/chromium-variations
@@ -1 +1 @@ -Subproject commit 18d4fbe9a192d85aa079810a063f63f6a37f2de9 +Subproject commit 0fcd7c5b11aca584c5c03b2af870c9f3af6c631c
diff --git a/third_party/crossbench b/third_party/crossbench index a6013e9..1b41ed2 160000 --- a/third_party/crossbench +++ b/third_party/crossbench
@@ -1 +1 @@ -Subproject commit a6013e985a417f6b0a721b1455a6fff3c70410e4 +Subproject commit 1b41ed2574ef931f2d1157ebb153c9d552f69670
diff --git a/third_party/dawn b/third_party/dawn index 6b0812e..68ff61c 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit 6b0812ec42b723b52efa7a8294a841c0299e8de8 +Subproject commit 68ff61cfd4c1384a7a305e0c30c608aedaba95d3
diff --git a/third_party/depot_tools b/third_party/depot_tools index 58625e8..93954a5 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit 58625e82c685426d441be5b422c9ad88e4867d20 +Subproject commit 93954a51a1c0c113bd057704c883e3de0d20db31
diff --git a/third_party/devtools-frontend/src b/third_party/devtools-frontend/src index d79204f..585254f 160000 --- a/third_party/devtools-frontend/src +++ b/third_party/devtools-frontend/src
@@ -1 +1 @@ -Subproject commit d79204f9f7ad19bf39cedba661b2fcebdf3e368a +Subproject commit 585254f2d2596090823c971b90d4fd321011b01c
diff --git a/third_party/glslang/README.chromium b/third_party/glslang/README.chromium index f2343042..4590fa8b 100644 --- a/third_party/glslang/README.chromium +++ b/third_party/glslang/README.chromium
@@ -2,7 +2,7 @@ Short Name: glslang URL: https://github.com/KhronosGroup/glslang Version: N/A -Revision: 541733a66b1cf4465559c78a8bd857606ac76123 +Revision: DEPS Security Critical: yes Shipped: no License: MIT
diff --git a/third_party/libaom/README.chromium b/third_party/libaom/README.chromium index fb515272..fe7efca 100644 --- a/third_party/libaom/README.chromium +++ b/third_party/libaom/README.chromium
@@ -2,7 +2,7 @@ Short Name: libaom URL: https://aomedia.googlesource.com/aom/ Version: N/A -Revision: 76df9967c206eb1200f5ecb1fd928a3d88c2648d +Revision: 0c13a5d54053f82bf8500b421b5cdefb1cc1b3ed CPEPrefix: cpe:/a:aomedia:aomedia:3.11.0 License: BSD-2-Clause, Patent License File: source/libaom/LICENSE, source/libaom/PATENTS
diff --git a/third_party/libaom/source/config/config/aom_version.h b/third_party/libaom/source/config/config/aom_version.h index 6d28d53..f560a6c 100644 --- a/third_party/libaom/source/config/config/aom_version.h +++ b/third_party/libaom/source/config/config/aom_version.h
@@ -14,9 +14,9 @@ #define VERSION_MAJOR 3 #define VERSION_MINOR 11 #define VERSION_PATCH 0 -#define VERSION_EXTRA "161-g76df9967c2" +#define VERSION_EXTRA "163-g0c13a5d540" #define VERSION_PACKED \ ((VERSION_MAJOR << 16) | (VERSION_MINOR << 8) | (VERSION_PATCH)) -#define VERSION_STRING_NOSP "3.11.0-161-g76df9967c2" -#define VERSION_STRING " 3.11.0-161-g76df9967c2" +#define VERSION_STRING_NOSP "3.11.0-163-g0c13a5d540" +#define VERSION_STRING " 3.11.0-163-g0c13a5d540" #endif // AOM_VERSION_H_
diff --git a/third_party/libaom/source/libaom b/third_party/libaom/source/libaom index 76df996..0c13a5d 160000 --- a/third_party/libaom/source/libaom +++ b/third_party/libaom/source/libaom
@@ -1 +1 @@ -Subproject commit 76df9967c206eb1200f5ecb1fd928a3d88c2648d +Subproject commit 0c13a5d54053f82bf8500b421b5cdefb1cc1b3ed
diff --git a/third_party/libavif/src b/third_party/libavif/src index 7cc2ffc..e9a27bc 160000 --- a/third_party/libavif/src +++ b/third_party/libavif/src
@@ -1 +1 @@ -Subproject commit 7cc2ffc34e4db627f8392a055649704d99d444a8 +Subproject commit e9a27bc6a84f01b6670c05c301c445f33a464992
diff --git a/third_party/llvm-libc/src b/third_party/llvm-libc/src index b0c04a4..039fea2 160000 --- a/third_party/llvm-libc/src +++ b/third_party/llvm-libc/src
@@ -1 +1 @@ -Subproject commit b0c04a4ce44caf3bcb5dffc315d7cc58c20f4ba7 +Subproject commit 039fea2058d14b408637a931b36a717169617227
diff --git a/third_party/node/node_modules.tar.gz.sha1 b/third_party/node/node_modules.tar.gz.sha1 index dccf6a5..a2b035c3 100644 --- a/third_party/node/node_modules.tar.gz.sha1 +++ b/third_party/node/node_modules.tar.gz.sha1
@@ -1 +1 @@ -ebd90b44f16134e47ba772b349418c9d5b701d40 +59332695e189485e2e2b06e60e4d49d3d54b8e92
diff --git a/third_party/node/package-lock.json b/third_party/node/package-lock.json index 500005b6..e39d4f6 100644 --- a/third_party/node/package-lock.json +++ b/third_party/node/package-lock.json
@@ -36,7 +36,7 @@ "html-minifier": "4.0.0", "lit": "3.0.2", "svgo": "3.0.2", - "terser": "5.31.6", + "terser": "5.37.0", "typescript": "5.7.2" } }, @@ -2214,9 +2214,9 @@ } }, "node_modules/terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dependencies": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2", @@ -3927,9 +3927,9 @@ } }, "terser": { - "version": "5.31.6", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", - "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "requires": { "@jridgewell/source-map": "^0.3.3", "acorn": "^8.8.2",
diff --git a/third_party/node/package.json b/third_party/node/package.json index f7ff0ef..023d939c 100644 --- a/third_party/node/package.json +++ b/third_party/node/package.json
@@ -31,7 +31,7 @@ "html-minifier": "4.0.0", "lit": "3.0.2", "svgo": "3.0.2", - "terser": "5.31.6", + "terser": "5.37.0", "typescript": "5.7.2" } }
diff --git a/third_party/perfetto b/third_party/perfetto index aa33545..2473cc9 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit aa335456a8b3c7fb70ec60f6c6f4c455c7efdcf3 +Subproject commit 2473cc95bc0d2d0c3c240be49ce4c2d0dc48edd4
diff --git a/third_party/skia b/third_party/skia index 472faa8..77f4941 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 472faa80deaf1f357b285b38360a63d8f03484c6 +Subproject commit 77f4941092ac586c9a6db4e477203cf7e2f4633b
diff --git a/third_party/spirv-cross/README.chromium b/third_party/spirv-cross/README.chromium index 80e21858..464180ab 100644 --- a/third_party/spirv-cross/README.chromium +++ b/third_party/spirv-cross/README.chromium
@@ -2,7 +2,7 @@ Short Name: SPIRV-Cross URL: https://github.com/KhronosGroup/SPIRV-Cross Version: N/A -Revision: b8fcf307f1f347089e3c46eb4451d27f32ebc8d3 +Revision: DEPS Security Critical: yes Shipped: no License: Apache-2.0
diff --git a/third_party/spirv-headers/README.chromium b/third_party/spirv-headers/README.chromium index 4a37b85..f2b82c52 100644 --- a/third_party/spirv-headers/README.chromium +++ b/third_party/spirv-headers/README.chromium
@@ -2,7 +2,7 @@ Short Name: spirv-headers URL: https://github.com/KhronosGroup/SPIRV-Headers.git Version: N/A -Revision: 49a1fceb9b1d087f3c25ad5ec077bb0e46231297 +Revision: DEPS Security Critical: yes Shipped: yes License: MIT
diff --git a/third_party/spirv-tools/README.chromium b/third_party/spirv-tools/README.chromium index 581b0276..19c80f0 100644 --- a/third_party/spirv-tools/README.chromium +++ b/third_party/spirv-tools/README.chromium
@@ -2,7 +2,7 @@ Short Name: SPIRV-Tools URL: https://github.com/KhronosGroup/SPIRV-Tools.git Version: N/A -Revision: 199038f10cbe56bf7cbfeb5472eb0a25af2f09f5 +Revision: DEPS Security Critical: yes Shipped: yes License: Apache-2.0
diff --git a/third_party/vulkan-headers/README.chromium b/third_party/vulkan-headers/README.chromium index 6b66f87..0f7f626 100644 --- a/third_party/vulkan-headers/README.chromium +++ b/third_party/vulkan-headers/README.chromium
@@ -1,8 +1,8 @@ Name: Vulkan API headers Short Name: Vulkan URL: https://github.com/KhronosGroup/Vulkan-Headers -Version: 1.2.140 -Revision: 9250d5ae8f50202005233dc0512a1d460c8b4833 +Version: N/A +Revision: DEPS Security Critical: yes Shipped: yes License: Apache-2.0
diff --git a/third_party/webgpu-cts/src b/third_party/webgpu-cts/src index 3faf2bf..d3fec1f 160000 --- a/third_party/webgpu-cts/src +++ b/third_party/webgpu-cts/src
@@ -1 +1 @@ -Subproject commit 3faf2bf1b08d4fcad605450a53b24a4ddd5f46d2 +Subproject commit d3fec1ffa922e8da4a5cf6da9fd77190ea8c23cf
diff --git a/third_party/webrtc b/third_party/webrtc index d7b2f85..cbe3044 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit d7b2f8560a4980111501dd8c0bdf19ae86287e41 +Subproject commit cbe304455fe0ae24622252ef8a0707a555fa5caf
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index eb5d7e9..cb5b9122 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -10956,6 +10956,7 @@ <int value="5237" label="CanvasTextDirectionGetInherit"/> <int value="5238" label="CanvasTextDirectionSet"/> <int value="5239" label="CanvasTextDirectionSetInherit"/> + <int value="5240" label="TopicsAPIImg"/> </enum> <!-- LINT.ThenChange(//third_party/blink/public/mojom/use_counter/metrics/web_feature.mojom:WebFeature) --> @@ -16553,6 +16554,8 @@ <int value="-1552898031" label="SingleTabMode:enabled"/> <int value="-1551839190" label="EarlyDocumentSwapForBackForwardTransitions:enabled"/> + <int value="-1551497821" + label="AccessibilityManifestV3EnhancedNetworkTts:disabled"/> <int value="-1551197844" label="AssistMultiWord:enabled"/> <int value="-1550675387" label="CriticalPersistedTabData:enabled"/> <int value="-1550541457" label="DisplayIdentification:disabled"/> @@ -23018,6 +23021,7 @@ <int value="1038264914" label="PerDeskShelf:enabled"/> <int value="1038408747" label="CrOSLateBootBluetoothAudioLEAudioOnly:disabled"/> + <int value="1038416445" label="FedCmLightweightMode:disabled"/> <int value="1038818497" label="WebAssemblyGarbageCollection:enabled"/> <int value="1038906720" label="SharedHighlightingManager:disabled"/> <int value="1039085120" @@ -23794,6 +23798,7 @@ <int value="1327928774" label="ClipboardHistorySimpleRender:enabled"/> <int value="1328029475" label="TerminalAlternativeRenderer:disabled"/> <int value="1330264457" label="OmniboxUIExperimentVerticalLayout:disabled"/> + <int value="1330592192" label="FedCmLightweightMode:enabled"/> <int value="1331098784" label="ReducedReferrerGranularity:enabled"/> <int value="1332120969" label="ChromeDuet:disabled"/> <int value="1332891404" @@ -25270,6 +25275,8 @@ <int value="1898286738" label="EnableRFC8925:disabled"/> <int value="1899111954" label="WebRtcMetronomeTaskQueue:disabled"/> <int value="1899248188" label="MediaApp:disabled"/> + <int value="1899572583" + label="AccessibilityManifestV3EnhancedNetworkTts:enabled"/> <int value="1900508100" label="PasswordViewPageInSettings:enabled"/> <int value="1900529524" label="disable-touch-drag-drop"/> <int value="1901640438" label="EnableLauncherSearchNormalization:disabled"/>
diff --git a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS index 0e67d85..29942516 100644 --- a/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS +++ b/tools/metrics/histograms/metadata/METRIC_REVIEWER_OWNERS
@@ -217,6 +217,7 @@ guiperez@google.com olivierrobin@chromium.org sebsg@chromium.org +rkgibson@google.com # language perrier@chromium.org curranmax@chromium.org
diff --git a/tools/metrics/histograms/metadata/android/enums.xml b/tools/metrics/histograms/metadata/android/enums.xml index d7f9b26..57aac26 100644 --- a/tools/metrics/histograms/metadata/android/enums.xml +++ b/tools/metrics/histograms/metadata/android/enums.xml
@@ -1247,6 +1247,13 @@ <int value="2" label="Multiple user profiles"/> </enum> +<enum name="NavigationDirection"> + <summary>The direction of the navigation.</summary> + <int value="0" label="ForwardNavigation"/> + <int value="1" label="BackwardNavigation"/> + <int value="2" label="DifferentTab"/> +</enum> + <enum name="NavigationInterceptResult"> <int value="0" label="Created external intent"/> <int value="1" label="Created external intent with tab clobbering"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 23d62e7..4395a91 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -793,6 +793,18 @@ </summary> </histogram> +<histogram name="Android.BackPress.Backfalsing" enum="NavigationDirection" + expires_after="2025-05-27"> + <owner>eleanorlee@google.com</owner> + <owner>lazzzis@chromium.org</owner> + <owner>clank-app-team@google.com</owner> + <summary> + Recorded when a user navigates to a URL and a backfalsing event happens. + Recorded for both swipes and clicks in both 3-button mode and gesture + navigation mode. Android only. + </summary> +</histogram> + <histogram name="Android.BackPress.Failure" enum="BackPressConsumer" expires_after="2025-06-22"> <owner>lazzzis@chromium.org</owner> @@ -2038,6 +2050,19 @@ </summary> </histogram> +<histogram name="Android.Hub.ToolbarPresentOnAnimation" enum="Boolean" + expires_after="2025-01-06"> + <owner>skym@chromium.org</owner> + <owner>ckitagawa@chromium.org</owner> + <summary> + The shrink/expand animation is supposed to change the color of the toolbar. + But there's currently a rare crash where the toolbar is not present. Either + it hasn't been created yet or has already been torn down. This metric + captures if the toolbar is present or not, which should help us measure the + effectiveness of future mitigations. + </summary> +</histogram> + <histogram name="Android.HubSearch.SearchBoxEntrypointV2" enum="HubSearchEntrypoint" expires_after="2025-06-08"> <owner>bjfong@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/arc/histograms.xml b/tools/metrics/histograms/metadata/arc/histograms.xml index 197a645a..3d36ba2 100644 --- a/tools/metrics/histograms/metadata/arc/histograms.xml +++ b/tools/metrics/histograms/metadata/arc/histograms.xml
@@ -319,7 +319,6 @@ <histogram name="Arc.Anr.{AnrPeriod}" units="ANRs" expires_after="2025-06-08"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <owner>arc-performance@google.com</owner> <summary> ANR rate separated by {AnrPeriod} as ANR count happened in this period. @@ -341,7 +340,6 @@ <histogram name="Arc.Anr.{AnrSource}" enum="ArcAnr" expires_after="2025-06-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <owner>arc-performance@google.com</owner> <summary> Counts ANR events in the system separated by ANR type and {AnrSource}. @@ -871,7 +869,7 @@ </histogram> <histogram name="Arc.ContainerLifetimeEvent" enum="ArcContainerLifetimeEvent" - expires_after="2025-01-05"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <summary> The number of ARC container lifetime events. One START event and up to one @@ -884,7 +882,7 @@ </histogram> <histogram name="Arc.ContainerRestartAfterCrashCount" units="units" - expires_after="2025-05-11"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <summary> The number of times ARC container crashes and automatically restarts in one @@ -896,9 +894,8 @@ </histogram> <histogram name="Arc.CpuRestrictionDisabled{ArcThrottleObservers}" units="ms" - expires_after="2025-06-08"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <owner>arc-performance@google.com</owner> <summary> Records the time that throttling was disabled due to a particular throttle @@ -923,9 +920,8 @@ </histogram> <histogram name="Arc.CpuRestrictionVmResult" enum="ArcCpuRestrictionVmResult" - expires_after="2024-09-15"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <owner>arc-performance@google.com</owner> <summary> Records the result of setting ARC CPU restrictions in ARCVM. @@ -976,14 +972,14 @@ </histogram> <histogram name="Arc.DataRemoved.Success" enum="Boolean" - expires_after="2024-09-01"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-core@google.com</owner> <summary>True if data was successfully removed on request.</summary> </histogram> <histogram name="Arc.DataRestore.Duration" units="ms" - expires_after="2025-03-30"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -993,7 +989,7 @@ </histogram> <histogram name="Arc.DataRestore.Status" enum="ArcDataRestoreStatus" - expires_after="2025-05-11"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-core@google.com</owner> <summary> @@ -1103,7 +1099,7 @@ </histogram> <histogram name="Arc.FirstAppLaunchDelay.TimeDelta" units="ms" - expires_after="2025-06-08"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> @@ -1117,9 +1113,8 @@ </histogram> <histogram name="Arc.FirstAppLaunchDelay.TimeDeltaUntilAppLaunch" units="ms" - expires_after="2024-11-17"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> How long the user sees the spinning icon waiting for ARC boot. This metric is not recorded at all if the user launches apps only after ARC is booted. @@ -1130,7 +1125,7 @@ </histogram> <histogram name="Arc.FirstAppLaunchRequest.TimeDelta" units="ms" - expires_after="2024-03-01"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> @@ -1250,46 +1245,6 @@ </summary> </histogram> -<histogram name="Arc.IconLoadFromFileTime.compressedFirst5" units="ms" - expires_after="2021-03-11"> - <owner>khmel@google.com</owner> - <owner>lgcheng@google.com</owner> - <summary> - Elapsed time of first 5 compressed app icons is loaded from file system. - Recorded when the app icon loading completes. - </summary> -</histogram> - -<histogram name="Arc.IconLoadFromFileTime.compressedOthers" units="ms" - expires_after="2021-03-11"> - <owner>khmel@google.com</owner> - <owner>lgcheng@google.com</owner> - <summary> - Elapsed time of other compressed app icons is loaded from file system. - Recorded when the app icon loading completes. - </summary> -</histogram> - -<histogram name="Arc.IconLoadFromFileTime.uncompressedFirst5" units="ms" - expires_after="2021-03-11"> - <owner>khmel@google.com</owner> - <owner>lgcheng@google.com</owner> - <summary> - Elapsed time of first 5 uncompressed app icons is loaded from file system. - Recorded when the app icon loading completes. - </summary> -</histogram> - -<histogram name="Arc.IconLoadFromFileTime.uncompressedOthers" units="ms" - expires_after="2021-03-11"> - <owner>khmel@google.com</owner> - <owner>lgcheng@google.com</owner> - <summary> - Elapsed time of other uncompressed app icons is loaded from file system. - Recorded when the app icon loading completes. - </summary> -</histogram> - <histogram name="Arc.IdleManager.ScreenOffTime" units="ms" expires_after="2025-06-22"> <owner>raging@google.com</owner> @@ -1417,7 +1372,7 @@ <histogram name="Arc.LoadAverageX100PerProcessor15MinutesAfterArcStart.{ArcBootType}" - units="0.01 jobs/processor" expires_after="2024-11-03"> + units="0.01 jobs/processor" expires_after="2025-09-01"> <owner>hashimoto@google.com</owner> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> @@ -1430,7 +1385,7 @@ <histogram name="Arc.LoadAverageX100PerProcessor1MinuteAfterArcStart.{ArcBootType}" - units="0.01 jobs/processor" expires_after="2023-11-01"> + units="0.01 jobs/processor" expires_after="2025-09-01"> <owner>hashimoto@google.com</owner> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> @@ -1443,7 +1398,7 @@ <histogram name="Arc.LoadAverageX100PerProcessor5MinutesAfterArcStart.{ArcBootType}" - units="0.01 jobs/processor" expires_after="2023-11-01"> + units="0.01 jobs/processor" expires_after="2025-09-01"> <owner>hashimoto@google.com</owner> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> @@ -1715,7 +1670,7 @@ </histogram> <histogram name="Arc.PlayAutoInstallRequest.State{ArcUserTypes}" - enum="ArcPlayAutoInstallRequestState" expires_after="2024-07-01"> + enum="ArcPlayAutoInstallRequestState" expires_after="2025-09-01"> <owner>jhorwich@google.com</owner> <owner>khmel@google.com</owner> <owner>arc-core@google.com</owner> @@ -1728,7 +1683,7 @@ </histogram> <histogram name="Arc.PlayAutoInstallRequest.TimeDelta{ArcUserTypes}" units="ms" - expires_after="2024-07-01"> + expires_after="2025-09-01"> <owner>jhorwich@google.com</owner> <owner>khmel@google.com</owner> <owner>arc-core@google.com</owner> @@ -1742,7 +1697,7 @@ </histogram> <histogram name="Arc.PlayStoreLaunch.TimeDelta" units="ms" - expires_after="2024-03-01"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> @@ -1817,7 +1772,7 @@ </histogram> <histogram name="Arc.PlayStoreShown.TimeDelta{ArcUserTypes}" units="ms" - expires_after="2024-03-01"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> @@ -2042,9 +1997,8 @@ <histogram name="Arc.Runtime.Performance.CommitDeviation2{ArcPerformanceAppCategories}" - units="microseconds" expires_after="2025-06-08"> + units="microseconds" expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> Standard deviation for commit time delta from ideal time. Only collected if the user has app syncing enabled and doesn't have a custom passphrase set. @@ -2057,9 +2011,8 @@ </histogram> <histogram name="Arc.Runtime.Performance.FPS2{ArcPerformanceAppCategories}" - units="fps" expires_after="2025-06-08"> + units="fps" expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> Render frames per second. Only collected if the user has app syncing enabled and doesn't have a custom passphrase set. {ArcPerformanceAppCategories} @@ -2071,9 +2024,8 @@ </histogram> <histogram name="Arc.Runtime.Performance.Generic.FirstFrameRendered" units="ms" - expires_after="2025-06-08"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> Time (in ms) between an app launch request and the detection of the first rendered frame. Recorded when the frame is detected by the first commit to @@ -2082,9 +2034,8 @@ </histogram> <histogram name="Arc.Runtime.Performance.Generic.FrameTime" units="ms" - expires_after="2025-05-04"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> 95 percent of the frames in the first 5 minutes after app launch took shorter time (in ms) than this value. @@ -2092,9 +2043,8 @@ </histogram> <histogram name="Arc.Runtime.Performance.Generic.Jankiness" units="%" - expires_after="2025-05-25"> + expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> Percentage ratio of janky frames to total frames recorded in a 5 minute interval. @@ -2103,8 +2053,8 @@ <histogram name="Arc.Runtime.Performance.JanksPercentage2{ArcPerformanceAppCategories}" - units="%" expires_after="2025-06-08"> - <owner>alanding@google.com</owner> + units="%" expires_after="2025-09-01"> + <owner>khmel@google.com</owner> <owner>matvore@google.com</owner> <summary> Percentage of the number of present frames during the tracing period which @@ -2119,8 +2069,8 @@ <histogram name="Arc.Runtime.Performance.JanksPerMinute2{ArcPerformanceAppCategories}" - units="count" expires_after="2025-06-22"> - <owner>alanding@google.com</owner> + units="count" expires_after="2025-09-01"> + <owner>khmel@google.com</owner> <owner>matvore@google.com</owner> <summary> Count of the number of UI janks per minute that occured during the tracing @@ -2135,7 +2085,7 @@ <histogram name="Arc.Runtime.Performance.PerceivedFPS2{ArcPerformanceAppCategories}" - units="fps" expires_after="2025-06-22"> + units="fps" expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>matvore@google.com</owner> <summary> @@ -2151,9 +2101,8 @@ <histogram name="Arc.Runtime.Performance.PresentDeviation2{ArcPerformanceAppCategories}" - units="microseconds" expires_after="2024-07-07"> + units="microseconds" expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> Standard deviation for present time delta from ideal time. Only collected if the user has app syncing enabled and doesn't have a custom passphrase set. @@ -2167,9 +2116,8 @@ <histogram name="Arc.Runtime.Performance.RenderQuality2{ArcPerformanceAppCategories}" - units="%" expires_after="2025-06-08"> + units="%" expires_after="2025-09-01"> <owner>khmel@google.com</owner> - <owner>alanding@google.com</owner> <summary> Render quality with maximum 100%. Only collected if the user has app syncing enabled and doesn't have a custom passphrase set. @@ -2205,7 +2153,7 @@ </histogram> <histogram name="Arc.Session.HasWebViewUsage" enum="Boolean" - expires_after="2023-12-24"> + expires_after="2025-09-01"> <owner>hungmn@google.com</owner> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> @@ -2327,7 +2275,7 @@ </histogram> <histogram name="Arc.UiAvailable.AlreadyProvisioned.TimeDelta{ArcUserTypes}" - units="ms" expires_after="2025-06-08"> + units="ms" expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> @@ -2340,7 +2288,7 @@ </histogram> <histogram name="Arc.UiAvailable.InSessionProvisioning.TimeDelta{ArcUserTypes}" - units="ms" expires_after="2025-06-08"> + units="ms" expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> @@ -2353,7 +2301,7 @@ </histogram> <histogram name="Arc.UiAvailable.OobeProvisioning.TimeDelta{ArcUserTypes}" - units="ms" expires_after="2025-06-08"> + units="ms" expires_after="2025-09-01"> <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> @@ -2800,8 +2748,8 @@ </histogram> <histogram name="Arc.Wayland.LateTiming.Duration{WaylandEventType}" units="ms" - expires_after="2025-02-23"> - <owner>alanding@google.com</owner> + expires_after="2025-09-01"> + <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> The duration of the Wayland client event processing time in ARC. This metric @@ -2814,8 +2762,8 @@ </histogram> <histogram name="Arc.Wayland.LateTiming.Event" enum="WaylandTimingEvent" - expires_after="2025-06-29"> - <owner>alanding@google.com</owner> + expires_after="2025-09-01"> + <owner>khmel@google.com</owner> <owner>arc-performance@google.com</owner> <summary> Wayland client event message type in ARC. This metric is recorded when the
diff --git a/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml b/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml index 654d176..329f9a5 100644 --- a/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml +++ b/tools/metrics/histograms/metadata/attribution_reporting/histograms.xml
@@ -1202,7 +1202,7 @@ </histogram> <histogram name="Conversions.SentVerboseDebugReportType4" - enum="ConversionVerboseDebugReportType" expires_after="2025-01-05"> + enum="ConversionVerboseDebugReportType" expires_after="2025-06-30"> <owner>tquintanilla@chromium.org</owner> <owner>linnan@chromium.org</owner> <owner>measurement-api-dev+metrics@google.com</owner> @@ -1439,7 +1439,7 @@ </histogram> <histogram name="Conversions.ValidReportsInDatabase" units="Reports" - expires_after="2025-01-05"> + expires_after="2025-06-30"> <owner>tquintanilla@chromium.org</owner> <owner>apaseltiner@chromium.org</owner> <owner>measurement-api-dev+metrics@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/blink/histograms.xml b/tools/metrics/histograms/metadata/blink/histograms.xml index 593760b..8b54c2c 100644 --- a/tools/metrics/histograms/metadata/blink/histograms.xml +++ b/tools/metrics/histograms/metadata/blink/histograms.xml
@@ -1152,7 +1152,7 @@ </histogram> <histogram name="Blink.FedCm.AccountChosenPosition.Desktop" units="count" - expires_after="2025-07-04"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1163,7 +1163,7 @@ </histogram> <histogram name="Blink.FedCm.AccountLabel.NumMatchingAccounts" - enum="FedCmNumAccounts" expires_after="2025-02-12"> + enum="FedCmNumAccounts" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1173,14 +1173,14 @@ </histogram> <histogram name="Blink.FedCm.AccountsDialogShown" enum="BooleanHit" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary>Records a 1 each time an accounts dialog is shown.</summary> </histogram> <histogram name="Blink.FedCm.AccountsRequestSent" enum="BooleanHit" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1189,7 +1189,7 @@ </histogram> <histogram name="Blink.FedCm.AccountsSize.Raw" units="accounts" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1200,7 +1200,7 @@ </histogram> <histogram name="Blink.FedCm.AccountsSize.ReadyToShow" units="accounts" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1211,7 +1211,7 @@ </histogram> <histogram name="Blink.FedCm.Android.ActivityDestroyedWhileCctShown" - enum="BooleanHit" expires_after="2025-02-12"> + enum="BooleanHit" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1222,7 +1222,7 @@ </histogram> <histogram name="Blink.FedCm.ApprovedClientsExistence" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1232,7 +1232,7 @@ </histogram> <histogram name="Blink.FedCm.ApprovedClientsSize" units="clients" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1243,7 +1243,7 @@ </histogram> <histogram name="Blink.FedCm.AutoReauthn.BlockedByContentSettings" - enum="Boolean" expires_after="2025-06-22"> + enum="Boolean" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -1256,7 +1256,7 @@ </histogram> <histogram name="Blink.FedCm.AutoReauthn.BlockedByEmbargo" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -1269,7 +1269,7 @@ </histogram> <histogram name="Blink.FedCm.AutoReauthn.BlockedByPreventSilentAccess" - enum="Boolean" expires_after="2025-04-13"> + enum="Boolean" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1281,7 +1281,7 @@ </histogram> <histogram name="Blink.FedCm.AutoReauthn.ReturningAccounts" - enum="FedCmNumAccounts" expires_after="2025-06-22"> + enum="FedCmNumAccounts" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -1294,7 +1294,7 @@ </histogram> <histogram name="Blink.FedCm.AutoReauthn.Succeeded" enum="Boolean" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -1310,7 +1310,7 @@ </histogram> <histogram name="Blink.FedCm.AutoReauthn.TimeFromEmbargoWhenBlocked" units="ms" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -1325,7 +1325,7 @@ </histogram> <histogram name="Blink.FedCm.Button.AccountChooserResult" - enum="FedCmAccountChooserResult" expires_after="2025-06-22"> + enum="FedCmAccountChooserResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1338,7 +1338,7 @@ </histogram> <histogram name="Blink.FedCm.Button.DisclosureDialogResult" - enum="FedCmDisclosureDialogResult" expires_after="2025-06-22"> + enum="FedCmDisclosureDialogResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1351,7 +1351,7 @@ </histogram> <histogram name="Blink.FedCm.Button.LoadingDialogResult" - enum="FedCmLoadingDialogResult" expires_after="2025-04-13"> + enum="FedCmLoadingDialogResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1365,7 +1365,7 @@ </histogram> <histogram name="Blink.FedCm.Button.LoadingStatePopupInteraction" - enum="FedCmPopupInteraction" expires_after="2025-06-22"> + enum="FedCmPopupInteraction" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1376,7 +1376,7 @@ </histogram> <histogram name="Blink.FedCm.Button.UseOtherAccountPopupInteraction" - enum="FedCmPopupInteraction" expires_after="2025-06-22"> + enum="FedCmPopupInteraction" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1387,7 +1387,7 @@ </histogram> <histogram name="Blink.FedCm.CancelReason" enum="FedCmCancelReason" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1400,7 +1400,7 @@ </histogram> <histogram name="Blink.FedCm.ChooseAnAccountSelected.Desktop" enum="BooleanHit" - expires_after="2025-07-04"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1411,7 +1411,7 @@ </histogram> <histogram name="Blink.FedCm.ClosedSheetType.Android" enum="FedCmSheetType" - expires_after="2025-05-11"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1433,7 +1433,7 @@ </histogram> <histogram name="Blink.FedCm.CloseVerifySheet.Android" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1443,7 +1443,7 @@ </histogram> <histogram name="Blink.FedCm.CloseVerifySheet.Desktop" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1453,7 +1453,7 @@ </histogram> <histogram name="Blink.FedCm.ContinueOn.PopupWindowResult" - enum="FedCmContinueOnPopupResult" expires_after="2025-06-22"> + enum="FedCmContinueOnPopupResult" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1465,7 +1465,7 @@ </histogram> <histogram name="Blink.FedCm.ContinueOn.PopupWindowStatus" - enum="FedCmContinueOnPopupStatus" expires_after="2025-06-22"> + enum="FedCmContinueOnPopupStatus" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1488,7 +1488,7 @@ </histogram> <histogram name="Blink.FedCm.DomainHint.NumMatchingAccounts" - enum="FedCmNumAccounts" expires_after="2025-06-22"> + enum="FedCmNumAccounts" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1498,7 +1498,7 @@ </histogram> <histogram name="Blink.FedCm.Error.ErrorDialogResult" - enum="FedCmErrorDialogResult" expires_after="2025-06-22"> + enum="FedCmErrorDialogResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1508,7 +1508,7 @@ </histogram> <histogram name="Blink.FedCm.Error.ErrorDialogType" enum="FedCmErrorDialogType" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1517,7 +1517,7 @@ </histogram> <histogram name="Blink.FedCm.Error.ErrorUrlType" enum="FedCmErrorUrlType" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1528,7 +1528,7 @@ </histogram> <histogram name="Blink.FedCm.Error.TokenResponseType" - enum="FedCmTokenResponseType" expires_after="2025-06-22"> + enum="FedCmTokenResponseType" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1538,7 +1538,7 @@ </histogram> <histogram name="Blink.FedCm.IdentityProvidersCount" units="count" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1550,7 +1550,7 @@ </histogram> <histogram name="Blink.FedCm.IdpSigninRequestInitiatedByUser" - enum="BooleanYesNo" expires_after="2025-06-22"> + enum="BooleanYesNo" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1562,7 +1562,7 @@ </histogram> <histogram name="Blink.FedCm.IdpSigninStatus.ClosePopupWindowReason" - enum="FedCmClosePopupWindowReason" expires_after="2025-06-22"> + enum="FedCmClosePopupWindowReason" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1573,7 +1573,7 @@ <histogram name="Blink.FedCm.IdpSigninStatus.IdpClosePopupToBrowserShowAccountsDuration" - units="ms" expires_after="2025-02-12"> + units="ms" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1585,7 +1585,7 @@ </histogram> <histogram name="Blink.FedCm.IdpSigninStatus.MismatchDialogResult" - enum="FedCmMismatchDialogResult" expires_after="2025-06-22"> + enum="FedCmMismatchDialogResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1595,7 +1595,7 @@ </histogram> <histogram name="Blink.FedCm.IdpSigninStatus.PopupWindowResult" - enum="FedCmPopupWindowResult" expires_after="2025-06-22"> + enum="FedCmPopupWindowResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1605,7 +1605,7 @@ </histogram> <histogram name="Blink.FedCm.IdpSigninStatus.ShowPopupWindowResult" - enum="FedCmShowPopupWindowResult" expires_after="2025-04-13"> + enum="FedCmShowPopupWindowResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1616,7 +1616,7 @@ </histogram> <histogram name="Blink.FedCm.IdpSignoutRequestInitiatedByUser" - enum="BooleanYesNo" expires_after="2025-06-22"> + enum="BooleanYesNo" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1628,7 +1628,7 @@ </histogram> <histogram name="Blink.FedCm.IsSignInUser" enum="Boolean" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1638,7 +1638,7 @@ </histogram> <histogram name="Blink.FedCm.JavaObjectCreationOutcome.Button" - enum="FedCmJavaObjectCreationOutcome" expires_after="2025-04-13"> + enum="FedCmJavaObjectCreationOutcome" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1650,7 +1650,7 @@ </histogram> <histogram name="Blink.FedCm.JavaObjectCreationOutcome.Widget" - enum="FedCmJavaObjectCreationOutcome" expires_after="2025-04-13"> + enum="FedCmJavaObjectCreationOutcome" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1662,7 +1662,7 @@ </histogram> <histogram name="Blink.FedCm.LifecycleStateFailureReason" - enum="FedCmLifecycleStateFailureReason" expires_after="2025-04-13"> + enum="FedCmLifecycleStateFailureReason" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1672,7 +1672,7 @@ </histogram> <histogram name="Blink.FedCm.LoginHint.NumMatchingAccounts" - enum="FedCmNumAccounts" expires_after="2025-06-22"> + enum="FedCmNumAccounts" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1682,14 +1682,14 @@ </histogram> <histogram name="Blink.FedCm.MismatchDialogShown" enum="BooleanHit" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary>Records a 1 each time a mismatch dialog is shown.</summary> </histogram> <histogram name="Blink.FedCm.MismatchDialogType" enum="FedCmMismatchDialogType" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1701,7 +1701,7 @@ </histogram> <histogram name="Blink.FedCm.MultipleRequestsFromDifferentIdPs" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1712,7 +1712,7 @@ </histogram> <histogram name="Blink.FedCm.MultipleRequestsRpMode" - enum="FedCmMultipleRequestsRpMode" expires_after="2025-06-22"> + enum="FedCmMultipleRequestsRpMode" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1722,7 +1722,7 @@ </histogram> <histogram name="Blink.FedCm.NumRequestsPerDocument" units="count" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1736,7 +1736,7 @@ </histogram> <histogram name="Blink.FedCm.Popup.DialogType" enum="FedCmDialogType" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1747,7 +1747,7 @@ </histogram> <histogram name="Blink.FedCm.PreventSilentAccessFrameType" - enum="FedCmRequesterFrameType" expires_after="2025-04-13"> + enum="FedCmRequesterFrameType" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1760,7 +1760,7 @@ </histogram> <histogram name="Blink.FedCm.RpContext" enum="FedCmRpContext" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1770,7 +1770,7 @@ </histogram> <histogram name="Blink.FedCm.RpMode" enum="FedCmRpMode" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1781,7 +1781,7 @@ </histogram> <histogram name="Blink.FedCm.RpParametersAndScopeState" - enum="FedCmRpParameters" expires_after="2025-04-13"> + enum="FedCmRpParameters" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1793,7 +1793,7 @@ </histogram> <histogram name="Blink.FedCm.SetLoginStatusIgnored" - enum="FedCmSetLoginStatusIgnoredReason" expires_after="2025-02-12"> + enum="FedCmSetLoginStatusIgnoredReason" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1803,7 +1803,7 @@ </histogram> <histogram name="Blink.FedCm.SignInStatusSetToSignout.NetError" - enum="NetErrorCodes" expires_after="2025-06-22"> + enum="NetErrorCodes" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1814,7 +1814,7 @@ </histogram> <histogram name="Blink.FedCm.SignUp.PrivacyPolicyClicked" enum="BooleanHit" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1824,7 +1824,7 @@ </histogram> <histogram name="Blink.FedCm.SignUp.TermsOfServiceClicked" enum="BooleanHit" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1834,7 +1834,7 @@ </histogram> <histogram name="Blink.FedCm.Status.AccountsResponseInvalidReason" - enum="FedCmAccountsResponseInvalidReason" expires_after="2025-02-12"> + enum="FedCmAccountsResponseInvalidReason" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1844,7 +1844,7 @@ </histogram> <histogram name="Blink.FedCm.Status.Csp" enum="FedCmCspStatus" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary>Records the result of CSP checks in the FedCM API.</summary> @@ -1861,7 +1861,7 @@ </histogram> <histogram name="Blink.FedCm.Status.IdpSigninMatch" - enum="FedCmIdpSigninMatchStatus" expires_after="2025-06-22"> + enum="FedCmIdpSigninMatchStatus" expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1874,7 +1874,7 @@ </histogram> <histogram name="Blink.FedCm.Status.MediationRequirement" - enum="CredentialManagerMediationRequirement" expires_after="2025-06-22"> + enum="CredentialManagerMediationRequirement" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1885,7 +1885,7 @@ </histogram> <histogram name="Blink.FedCm.Status.RequestIdToken" - enum="FedCmRequestIdTokenStatus" expires_after="2025-06-22"> + enum="FedCmRequestIdTokenStatus" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1894,7 +1894,7 @@ </histogram> <histogram name="Blink.FedCm.Status.SignInStateMatch" - enum="FedCmSignInStateMatchStatus" expires_after="2025-04-13"> + enum="FedCmSignInStateMatchStatus" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1904,7 +1904,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.AccountsDialogShownDuration2" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1920,7 +1920,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.CancelOnDialog" units="ms" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1934,7 +1934,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.ContinueOn.Response" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1946,7 +1946,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.ContinueOn.TurnaroundTime" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>cbiesinger@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1958,7 +1958,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.ContinueOnDialog" units="ms" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1981,7 +1981,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.GetUserInfoToButtonMode" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -1994,7 +1994,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.IdTokenResponse" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2005,7 +2005,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.MismatchDialogShownDuration" units="ms" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2018,7 +2018,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.ShowAccountsDialog" units="ms" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2028,7 +2028,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.ShowAccountsDialogBreakdown.AccountsFetch" - units="ms" expires_after="2025-06-22"> + units="ms" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2040,7 +2040,7 @@ <histogram name="Blink.FedCm.Timing.ShowAccountsDialogBreakdown.ClientMetadataFetch" - units="ms" expires_after="2025-06-22"> + units="ms" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2054,7 +2054,7 @@ <histogram name="Blink.FedCm.Timing.ShowAccountsDialogBreakdown.WellKnownAndConfigFetch" - units="ms" expires_after="2025-04-13"> + units="ms" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2065,7 +2065,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.TurnaroundTime" units="ms" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2076,7 +2076,7 @@ </histogram> <histogram name="Blink.FedCm.Timing.WellKnownAndConfigFetch" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2093,7 +2093,7 @@ </histogram> <histogram name="Blink.FedCm.UseOtherAccountResult" - enum="FedCmUseOtherAccountResult" expires_after="2025-04-20"> + enum="FedCmUseOtherAccountResult" expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2107,7 +2107,7 @@ </histogram> <histogram name="Blink.FedCm.UserInfo.NumAccounts" enum="FedCmNumAccounts" - expires_after="2025-04-20"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2128,7 +2128,7 @@ </histogram> <histogram name="Blink.FedCm.UserInfo.TimeToRequestCompleted" units="ms" - expires_after="2025-04-20"> + expires_after="2025-08-12"> <owner>npm@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2139,7 +2139,7 @@ </histogram> <histogram name="Blink.FedCm.VerifyingDialogResult" - enum="FedCmVerifyingDialogResult" expires_after="2025-04-13"> + enum="FedCmVerifyingDialogResult" expires_after="2025-08-12"> <owner>tanzachary@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2150,7 +2150,7 @@ </histogram> <histogram name="Blink.FedCm.WebContentsActive" enum="Boolean" - expires_after="2025-04-13"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -2160,7 +2160,7 @@ </histogram> <histogram name="Blink.FedCm.WebContentsVisible" enum="Boolean" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -4297,6 +4297,26 @@ </histogram> <histogram + name="Blink.Responsiveness.PerAnimationFrame.FirstProcessingStartToLastProcessingEnd" + units="ms" expires_after="2025-10-30"> + <owner>sullivan@chromium.org</owner> + <owner>mmocny@chromium.org</owner> + <owner>speed-metrics-dev@chromium.org</owner> + <owner>chrome-analysis-team@google.com</owner> + <summary> + Blink.Responsiveness.PerAnimationFrame.* is a family of metrics representing + the sub-parts (aka breakdowns) of Interactions. Reported per Animation Frame + which includes at least one Event Timing which is a part of an interaction + (as in INP). All subparts are based on Event Timing API measurements (and + so, do not include continuous events, like scrolling). + + This subpart represents the duration from the time when the first event + starts processing on the main thread to when the last event finishes + processing. + </summary> +</histogram> + +<histogram name="Blink.Responsiveness.PerAnimationFrame.ProcessingEndToPresentationTime" units="ms" expires_after="2025-10-30"> <owner>sullivan@chromium.org</owner> @@ -4356,6 +4376,26 @@ </histogram> <histogram + name="Blink.Responsiveness.PerAnimationFrame.TotalUnaccountedEventProcessingTime" + units="ms" expires_after="2025-10-30"> + <owner>sullivan@chromium.org</owner> + <owner>mmocny@chromium.org</owner> + <owner>speed-metrics-dev@chromium.org</owner> + <owner>chrome-analysis-team@google.com</owner> + <summary> + Blink.Responsiveness.PerAnimationFrame.* is a family of metrics representing + the sub-parts (aka breakdowns) of Interactions. Reported per Animation Frame + which includes at least one Event Timing which is a part of an interaction + (as in INP). All subparts are based on Event Timing API measurements (and + so, do not include continuous events, like scrolling). + + This subpart represents the total unaccounted duration (idle time) within + the processing time range which is from the time when the first event starts + processing on the main thread to when the last event finishes processing. + </summary> +</histogram> + +<histogram name="Blink.Responsiveness.UserInteraction.MaxEventDuration.{InteractionType}" units="ms" expires_after="never"> <!-- expires-never: Supports guardrail metric debugging --> @@ -4569,7 +4609,7 @@ </histogram> <histogram name="Blink.Sms.BackendAvailability" - enum="WebOTPBackendAvailability" expires_after="2025-02-12"> + enum="WebOTPBackendAvailability" expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -4589,7 +4629,7 @@ </histogram> <histogram name="Blink.Sms.Receive.Infobar" enum="WebOTPServiceInfobarAction" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4600,7 +4640,7 @@ </histogram> <histogram name="Blink.Sms.Receive.Outcome" enum="WebOTPServiceOutcome" - expires_after="2025-06-22"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4608,7 +4648,7 @@ </histogram> <histogram name="Blink.Sms.Receive.SmsParsingStatus" enum="SmsParsingStatus" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary> @@ -4620,7 +4660,7 @@ </histogram> <histogram name="Blink.Sms.Receive.TimeCancel" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4631,7 +4671,7 @@ </histogram> <histogram name="Blink.Sms.Receive.TimeCancelOnKeyboardDismissal" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4642,7 +4682,7 @@ </histogram> <histogram name="Blink.Sms.Receive.TimeCancelOnSuccess" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4653,7 +4693,7 @@ </histogram> <histogram name="Blink.Sms.Receive.TimeContinueOnSuccess" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4664,7 +4704,7 @@ </histogram> <histogram name="Blink.Sms.Receive.TimeSmsReceive" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4675,7 +4715,7 @@ </histogram> <histogram name="Blink.Sms.Receive.TimeSuccess" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4687,7 +4727,7 @@ </histogram> <histogram name="Blink.Sms.Receive.TimeUserCancel" units="ms" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>goto@chromium.org</owner> <owner>web-identity-eng@google.com</owner> @@ -4699,7 +4739,7 @@ </histogram> <histogram name="Blink.Sms.WebContentsVisibleOnReceive" enum="Boolean" - expires_after="2025-02-12"> + expires_after="2025-08-12"> <owner>yigu@chromium.org</owner> <owner>web-identity-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/bookmarks/histograms.xml b/tools/metrics/histograms/metadata/bookmarks/histograms.xml index 558c89f..c42db094 100644 --- a/tools/metrics/histograms/metadata/bookmarks/histograms.xml +++ b/tools/metrics/histograms/metadata/bookmarks/histograms.xml
@@ -473,7 +473,7 @@ </histogram> <histogram name="Bookmarks.ReorderDropTarget{ParentNode}" - enum="BookmarkReorderDropTarget" expires_after="2025-01-05"> + enum="BookmarkReorderDropTarget" expires_after="2025-07-05"> <owner>msalama@chromium.org</owner> <owner>chrome-signin-team@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/browsing_topics/enums.xml b/tools/metrics/histograms/metadata/browsing_topics/enums.xml index 0f0c1a3..58cb10c 100644 --- a/tools/metrics/histograms/metadata/browsing_topics/enums.xml +++ b/tools/metrics/histograms/metadata/browsing_topics/enums.xml
@@ -33,6 +33,8 @@ <int value="3" label="observe via fetch-like api"/> <int value="4" label="get via iframe attribute api"/> <int value="5" label="observe via iframe attribute api"/> + <int value="6" label="get via img attribute api"/> + <int value="7" label="observe via img attribute api"/> </enum> <enum name="BrowsingTopicsCalculatorResultStatus">
diff --git a/tools/metrics/histograms/metadata/chromeos/histograms.xml b/tools/metrics/histograms/metadata/chromeos/histograms.xml index f2242e6..3a8ddbd 100644 --- a/tools/metrics/histograms/metadata/chromeos/histograms.xml +++ b/tools/metrics/histograms/metadata/chromeos/histograms.xml
@@ -1155,7 +1155,7 @@ </histogram> <histogram name="ChromeOS.CWP.CollectProcessTypes" - enum="ChromeOSProcessTypeCollectionStatus" expires_after="2025-01-19"> + enum="ChromeOSProcessTypeCollectionStatus" expires_after="2026-01-19"> <owner>gmx@google.com</owner> <owner>cwp-team@google.com</owner> <summary> @@ -1221,8 +1221,9 @@ </histogram> <histogram name="ChromeOS.CWP.RecordPerf" enum="ChromeOSProfileRecordStatus" - expires_after="2025-01-14"> + expires_after="2026-01-14"> <owner>shantuo@google.com</owner> + <owner>gmx@google.com</owner> <owner>cwp-team@google.com</owner> <summary> A count of the various outcomes related to recording the profile data
diff --git a/tools/metrics/histograms/metadata/commerce/histograms.xml b/tools/metrics/histograms/metadata/commerce/histograms.xml index a98d9b0..25270ce 100644 --- a/tools/metrics/histograms/metadata/commerce/histograms.xml +++ b/tools/metrics/histograms/metadata/commerce/histograms.xml
@@ -619,7 +619,7 @@ </histogram> <histogram name="Commerce.PriceInsights.BuyingOptionsClicked" - enum="PriceInsightsPriceBucket" expires_after="2025-02-06"> + enum="PriceInsightsPriceBucket" expires_after="2025-06-22"> <owner>mdjones@chromium.org</owner> <owner>ayman@chromium.org</owner> <owner>qib@google.com</owner> @@ -835,7 +835,7 @@ </histogram> <histogram name="Commerce.ShoppingService.ProductInfo.FallbackDataUsed" - enum="Boolean" expires_after="2025-02-01"> + enum="Boolean" expires_after="2025-06-08"> <owner>ayman@chromium.org</owner> <owner>mdjones@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index 099f86a..351e53b 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -781,17 +781,6 @@ </summary> </histogram> -<histogram name="Compositing.SkiaRenderer.SkippedOverlayRenderPassDrawQuadSize" - units="pixels" expires_after="2024-11-03"> - <owner>magchen@chromium.org</owner> - <owner>ccameron@chromium.org</owner> - <owner>chrome-gpu-metric-alerts@chromium.org</owner> - <summary> - Pixel size for a skipped overlay render pass draw quad. Recorded in - SkiaRenderer ScheduleOverlays. - </summary> -</histogram> - <histogram name="Compositing.SurfaceAggregator.AggregateUs" units="microseconds" expires_after="2025-06-01"> <owner>kylechar@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/enterprise/histograms.xml b/tools/metrics/histograms/metadata/enterprise/histograms.xml index 246f4e12..7580bbfd 100644 --- a/tools/metrics/histograms/metadata/enterprise/histograms.xml +++ b/tools/metrics/histograms/metadata/enterprise/histograms.xml
@@ -3509,7 +3509,7 @@ </histogram> <histogram name="Enterprise.UserInfoFetch.HttpErrorCode" - enum="CombinedHttpResponseAndNetErrorCode" expires_after="2025-02-12"> + enum="CombinedHttpResponseAndNetErrorCode" expires_after="2025-06-12"> <owner>vincb@google.com</owner> <owner>zmin@chromium.org</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/families/enums.xml b/tools/metrics/histograms/metadata/families/enums.xml index 23f1719..06105ed 100644 --- a/tools/metrics/histograms/metadata/families/enums.xml +++ b/tools/metrics/histograms/metadata/families/enums.xml
@@ -146,6 +146,8 @@ </int> </enum> +<!-- LINT.IfChange(FamilyLinkUserLocalWebApprovalResult) --> + <enum name="FamilyLinkUserLocalWebApprovalResult"> <summary> The result of local web approval request. Reported by the browser once @@ -164,6 +166,8 @@ <int value="3" label="Error">An error occured during the request flow.</int> </enum> +<!-- LINT.ThenChange(//components/supervised_user/core/common/supervised_user_constants.h:LocalApprovalResult) --> + <enum name="FamilyLinkUserLogSegment"> <summary> Filters family link user metrics into categories of interest. @@ -190,6 +194,8 @@ </int> </enum> +<!-- LINT.IfChange(FamilyLinkUserParentAccessWidgetError) --> + <enum name="FamilyLinkUserParentAccessWidgetError"> <summary> Error that occurs in the parent access widget. ChromeOS only. @@ -214,6 +220,8 @@ </int> </enum> +<!-- LINT.ThenChange(//components/supervised_user/core/common/supervised_user_constants.h:ParentAccessWidgetError) --> + <enum name="FamilyLinkUserParentAccessWidgetShowDialogError"> <summary> Error that prevents the parent access widget dialog from showing. ChromeOS
diff --git a/tools/metrics/histograms/metadata/feature_engagement/OWNERS b/tools/metrics/histograms/metadata/feature_engagement/OWNERS index a230d67..39a5104 100644 --- a/tools/metrics/histograms/metadata/feature_engagement/OWNERS +++ b/tools/metrics/histograms/metadata/feature_engagement/OWNERS
@@ -7,3 +7,6 @@ # Desktop User Education: dfried@chromium.org + +# iOS User Education: +rkgibson@google.com
diff --git a/tools/metrics/histograms/metadata/fingerprinting_protection/histograms.xml b/tools/metrics/histograms/metadata/fingerprinting_protection/histograms.xml index e2305a4..e9cf2be 100644 --- a/tools/metrics/histograms/metadata/fingerprinting_protection/histograms.xml +++ b/tools/metrics/histograms/metadata/fingerprinting_protection/histograms.xml
@@ -257,6 +257,39 @@ </histogram> <histogram + name="FingerprintingProtection.PageLoad.RefreshCount.SiteHasBreakageException" + enum="BooleanAvailable" expires_after="2025-07-01"> + <owner>aabeshouse@google.com</owner> + <owner>rizvis@google.com</owner> + <owner>trishalfonso@google.com</owner> + <owner>thesalsa@google.com</owner> + <owner>tanub@google.com</owner> + <summary> + When a document loads, records if the site has an exception created by the + refresh count breakage heuristic. In that case, fingerprinting protection + filtering is disabled due to the exception. + </summary> +</histogram> + +<histogram + name="FingerprintingProtection.PageLoad.RefreshCount.SiteHasBreakageExceptionWallDuration" + units="microseconds" expires_after="2025-07-01"> + <owner>aabeshouse@google.com</owner> + <owner>rizvis@google.com</owner> + <owner>trishalfonso@google.com</owner> + <owner>thesalsa@google.com</owner> + <owner>tanub@google.com</owner> + <summary> + See + `FingerprintingProtection.PageLoad.RefreshCount.SiteHasBreakageException`. + Measures the wall time taken to check for a breakage exception. + + This metric uses UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES to acccount for + clients with low-resolution clocks. + </summary> +</histogram> + +<histogram name="FingerprintingProtection.PageLoad.RootNavigation.ActivationState" enum="SubresourceFilterActivationState" expires_after="2025-07-01"> <owner>rizvis@google.com</owner> @@ -373,6 +406,38 @@ </summary> </histogram> +<histogram + name="FingerprintingProtection.WebContentsObserver.RefreshCount.AddBreakageException" + enum="BooleanAvailable" expires_after="2025-07-01"> + <owner>aabeshouse@google.com</owner> + <owner>rizvis@google.com</owner> + <owner>trishalfonso@google.com</owner> + <owner>thesalsa@google.com</owner> + <owner>tanub@google.com</owner> + <summary> + Logs when a breakage exception is added based on the refresh count + heuristic. + </summary> +</histogram> + +<histogram + name="FingerprintingProtection.WebContentsObserver.RefreshCount.AddBreakageExceptionWallDuration" + units="microseconds" expires_after="2025-07-01"> + <owner>aabeshouse@google.com</owner> + <owner>rizvis@google.com</owner> + <owner>trishalfonso@google.com</owner> + <owner>thesalsa@google.com</owner> + <owner>tanub@google.com</owner> + <summary> + See + `FingerprintingProtection.WebContentsObserver.RefreshCount.AddBreakageException`. + Measures the wall time taken to add a breakage exception. + + This metric uses UMA_HISTOGRAM_CUSTOM_MICROSECONDS_TIMES to acccount for + clients with low-resolution clocks. + </summary> +</histogram> + <histogram name="FingerprintingProtection.WriteRuleset.Result" enum="SubresourceFilterWriteRulesetResult" expires_after="2025-06-29"> <owner>rizvis@google.com</owner>
diff --git a/tools/metrics/histograms/metadata/gpu/enums.xml b/tools/metrics/histograms/metadata/gpu/enums.xml index 1a9cdbe..fee495480 100644 --- a/tools/metrics/histograms/metadata/gpu/enums.xml +++ b/tools/metrics/histograms/metadata/gpu/enums.xml
@@ -416,6 +416,15 @@ <int value="18" label="ANGLE Metal NULL"/> </enum> +<enum name="FrameIntervalMatcherType"> + <int value="0" label="kNone"/> + <int value="1" label="kInputBoost"/> + <int value="2" label="kOnlyVideo"/> + <int value="3" label="kVideoConference"/> + <int value="4" label="kOnlyAnimatingImage"/> + <int value="5" label="kOnlyScrollBarFadeOut"/> +</enum> + <enum name="GLImplementation"> <int value="0" label="kGLImplementationNone"/> <int value="1" label="kGLImplementationDesktopGL"/>
diff --git a/tools/metrics/histograms/metadata/gpu/histograms.xml b/tools/metrics/histograms/metadata/gpu/histograms.xml index 918d6e6f..6feefcd 100644 --- a/tools/metrics/histograms/metadata/gpu/histograms.xml +++ b/tools/metrics/histograms/metadata/gpu/histograms.xml
@@ -663,7 +663,7 @@ </histogram> <histogram name="GPU.DirectComposition.IsUnderlay" enum="BooleanUnderlay" - expires_after="2025-01-14"> + expires_after="2026-01-14"> <owner>magchen@chromium.org</owner> <owner>zmo@chromium.org</owner> <owner>chrome-gpu-metric-alerts@chromium.org</owner> @@ -891,9 +891,10 @@ </histogram> <histogram name="GPU.GLImplementation" enum="GLImplementation" - expires_after="2025-02-10"> + expires_after="2026-02-10"> <owner>magchen@chromium.org</owner> <owner>zmo@chromium.org</owner> + <owner>chrome-gpu-metric-alerts@chromium.org</owner> <summary> Records the OpenGL implementation mode. Recorded during GPU process initilization. @@ -1275,9 +1276,10 @@ </histogram> <histogram name="Gpu.OutputSurface.ScheduleOverlaysUs" units="microseconds" - expires_after="2025-01-05"> + expires_after="2026-01-05"> <owner>magchen@chromium.org</owner> <owner>ccameron@chromium.org</owner> + <owner>chrome-gpu-metric-alerts@chromium.org</owner> <summary> The time that the GPU's main CPU thread spends producing pending CALayer tree on Mac. Recorded when Skia output surface schedules overlays at every @@ -2050,6 +2052,27 @@ </token> </histogram> +<histogram name="Viz.FrameIntervalDecider.ResultMatcherType" + enum="FrameIntervalMatcherType" expires_after="M143"> + <owner>boliu@chromium.org</owner> + <owner>chrome-gpu-metric-alerts@chromium.org</owner> + <summary> + Frame interval matcher type matched current frame. Recorded every viz frame, + sub-sampled by base::ShouldLogHistogramForCpuReductionExperiment. + </summary> +</histogram> + +<histogram name="Viz.FrameIntervalDecider.ResultTimeDelta" units="ms" + expires_after="M143"> + <owner>boliu@chromium.org</owner> + <owner>chrome-gpu-metric-alerts@chromium.org</owner> + <summary> + Frame interval decider result interval. Recorded every viz frame but only if + the result variant is an interval time delta, sub-sampled by + base::ShouldLogHistogramForCpuReductionExperiment + </summary> +</histogram> + <histogram name="Viz.FrameSink.GpuBusyDuration" units="microseconds" expires_after="2024-10-20"> <owner>sashamcintosh@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/installer/histograms.xml b/tools/metrics/histograms/metadata/installer/histograms.xml index 6fc4ea2..4930b70 100644 --- a/tools/metrics/histograms/metadata/installer/histograms.xml +++ b/tools/metrics/histograms/metadata/installer/histograms.xml
@@ -46,7 +46,7 @@ </histogram> <histogram name="Installer.Postinstall.EfiBootEntryCount" units="entries" - expires_after="2025-01-01"> + expires_after="2025-05-04"> <owner>tbrandston@google.com</owner> <owner>chromeos-flex-eng@google.com</owner> <summary> @@ -64,7 +64,7 @@ </histogram> <histogram name="Installer.Postinstall.EfiBootEntryFailedLoad" units="entries" - expires_after="2025-01-01"> + expires_after="2025-05-04"> <owner>tbrandston@google.com</owner> <owner>chromeos-flex-eng@google.com</owner> <summary> @@ -109,7 +109,7 @@ </histogram> <histogram name="Installer.Postinstall.ManagedEfiBootEntryCount" - units="entries" expires_after="2025-01-01"> + units="entries" expires_after="2025-05-04"> <owner>tbrandston@google.com</owner> <owner>chromeos-flex-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/interstitial/histograms.xml b/tools/metrics/histograms/metadata/interstitial/histograms.xml index 3e3010d..4e24d474 100644 --- a/tools/metrics/histograms/metadata/interstitial/histograms.xml +++ b/tools/metrics/histograms/metadata/interstitial/histograms.xml
@@ -92,7 +92,7 @@ </histogram> <histogram name="interstitial.enterprise_block.decision" - enum="SecurityInterstitialDecision" expires_after="2025-01-21"> + enum="SecurityInterstitialDecision" expires_after="2026-01-21"> <owner>domfc@chromium.org</owner> <owner>dpr-eng@google.com</owner> <summary> @@ -102,7 +102,7 @@ </histogram> <histogram name="interstitial.enterprise_block.decision.repeat_visit" - enum="SecurityInterstitialDecision" expires_after="2025-01-21"> + enum="SecurityInterstitialDecision" expires_after="2026-01-21"> <owner>domfc@chromium.org</owner> <owner>dpr-eng@google.com</owner> <summary> @@ -122,7 +122,7 @@ </histogram> <histogram name="interstitial.enterprise_warn.decision" - enum="SecurityInterstitialDecision" expires_after="2025-01-21"> + enum="SecurityInterstitialDecision" expires_after="2026-01-21"> <owner>domfc@chromium.org</owner> <owner>dpr-eng@google.com</owner> <summary> @@ -132,7 +132,7 @@ </histogram> <histogram name="interstitial.enterprise_warn.decision.repeat_visit" - enum="SecurityInterstitialDecision" expires_after="2025-01-21"> + enum="SecurityInterstitialDecision" expires_after="2026-01-21"> <owner>domfc@chromium.org</owner> <owner>dpr-eng@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/ios/OWNERS b/tools/metrics/histograms/metadata/ios/OWNERS index f1b7e52a..a3756fe8 100644 --- a/tools/metrics/histograms/metadata/ios/OWNERS +++ b/tools/metrics/histograms/metadata/ios/OWNERS
@@ -4,4 +4,5 @@ # Use chromium-metrics-reviews@google.com as a backup. ginnyhuang@chromium.org olivierrobin@chromium.org -sebsg@chromium.org \ No newline at end of file +sebsg@chromium.org +rkgibson@google.com
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index a0caf2c..88df7a9 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -3121,7 +3121,7 @@ </histogram> <histogram name="IOS.OverflowMenu.Customization.ActionAdded" - enum="IOSOverflowMenuAction" expires_after="2025-02-10"> + enum="IOSOverflowMenuAction" expires_after="2025-06-29"> <owner>rkgibson@google.com</owner> <owner>bling-mony-pod@google.com</owner> <summary>The action added during an overflow menu customization.</summary> @@ -3182,7 +3182,7 @@ </histogram> <histogram name="IOS.OverflowMenu.Customization.DestinationAdded" - enum="IOSOverflowMenuDestination" expires_after="2025-02-10"> + enum="IOSOverflowMenuDestination" expires_after="2025-06-29"> <owner>rkgibson@google.com</owner> <owner>bling-mony-pod@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/net/enums.xml b/tools/metrics/histograms/metadata/net/enums.xml index 4e7f44e..cf38288d 100644 --- a/tools/metrics/histograms/metadata/net/enums.xml +++ b/tools/metrics/histograms/metadata/net/enums.xml
@@ -2738,6 +2738,7 @@ <int value="9" label="Internal error"/> <int value="10" label="Unknown error"/> <int value="11" label="Operation fulfilled locally"/> + <int value="12" label="Per-site issuer limit reached"/> </enum> <!-- LINT.ThenChange(//services/network/public/mojom/trust_tokens.mojom:TrustTokenOperationStatus) -->
diff --git a/tools/metrics/histograms/metadata/platform/enums.xml b/tools/metrics/histograms/metadata/platform/enums.xml index 3dd105d..9810391 100644 --- a/tools/metrics/histograms/metadata/platform/enums.xml +++ b/tools/metrics/histograms/metadata/platform/enums.xml
@@ -2580,10 +2580,12 @@ <int value="487001745" label="IFX 9655 rev 38 fw 4.34 build 03f2"/> <int value="488674186" label="CROS Cr50 0.6.201"/> <int value="498251593" label="CROS Cr50 0.5.4"/> + <int value="500048220" label="CROS Cr50 0.5.271"/> <int value="517482723" label="IFX 9655 rev 38 fw 4.32 build 036f"/> <int value="533446617" label="CROS Cr50 0.5.111"/> <int value="544519086" label="CROS Ti50 0.23.121"/> <int value="545386023" label="IFX 9670 rev 15 fw 6.43 build 00f3"/> + <int value="545848779" label="CROS Cr50 0.5.270"/> <int value="555754648" label="CROS Ti50 0.23.21"/> <int value="562513455" label="CROS Cr50 0.4.12"/> <int value="563952990" label="CROS Cr50 0.6.51"/> @@ -2629,17 +2631,20 @@ <int value="921986551" label="CROS Cr50 0.6.70"/> <int value="928190862" label="CROS Cr50 0.0.17"/> <int value="928401938" label="CROS Cr50 ro 0.0.11 rw w0.4.24"/> + <int value="940410042" label="CROS Cr50 0.6.270"/> <int value="941521429" label="CROS Ti50 0.24.112"/> <int value="946990224" label="CROS Ti50 0.23.71"/> <int value="961500628" label="CROS Cr50 0.5.11"/> <int value="969849518" label="CROS Cr50 0.4.9 Flags 0x10(pre-pvt)"/> <int value="973237052" label="CROS Cr50 0.6.241"/> + <int value="984841079" label="CROS Ti50 0.23.122"/> <int value="987235505" label="CROS Cr50 0.0.20"/> <int value="987973414" label="IFX 9670 rev 15 fw 6.40 build 00be"/> <int value="1001367086" label="CROS Cr50 0.3.15"/> <int value="1009763914" label="CROS Cr50 0.4.10"/> <int value="1013730596" label="CROS Cr50 0.0.26 Flags 0x10(pre-pvt)"/> <int value="1013974746" label="CROS Ti50 0.24.100"/> + <int value="1020513847" label="CROS Cr50 0.6.271"/> <int value="1026059105" label="CROS Cr50 0.3.4"/> <int value="1039624416" label="CROS Cr50 0.3.10"/> <int value="1048372479" label="CROS Cr50 0.6.4"/> @@ -2675,6 +2680,7 @@ <int value="1353576267" label="IFX 9635 fw 3.18 build 0009"/> <int value="1366252830" label="CROS Ti50 0.0.15"/> <int value="1374260250" label="CROS Cr50 0.6.7"/> + <int value="1387509141" label="CROS Ti50 0.24.132"/> <int value="1389941253" label="CROS Cr50 0.5.140"/> <int value="1393226923" label="CROS Ti50 0.23.120"/> <int value="1394118225" label="CROS Cr50 0.6.6"/> @@ -2712,6 +2718,7 @@ <int value="1716634300" label="IFX 9645 rev 45 fw 133.32 build 0050"/> <int value="1716937628" label="CROS Cr50 0.6.190"/> <int value="1717226620" label="CROS Cr50 0.4.14 Flags 0x10(pre-pvt)"/> + <int value="1730776982" label="CROS Ti50 0.24.140"/> <int value="1733077393" label="IFX 9645 rev 49 fw 133.33 build 00e3"/> <int value="1734763743" label="CROS Ti50 0.24.12"/> <int value="1758758919" label="CROS Cr50 0.6.130"/>
diff --git a/tools/metrics/histograms/metadata/privacy/histograms.xml b/tools/metrics/histograms/metadata/privacy/histograms.xml index be528a7c..f6a9d427 100644 --- a/tools/metrics/histograms/metadata/privacy/histograms.xml +++ b/tools/metrics/histograms/metadata/privacy/histograms.xml
@@ -1901,7 +1901,7 @@ <histogram name="PrivacySandbox.TrackingProtection.SilentOnboardingStartup.EligibleToOnboardedDuration" - units="ms" expires_after="2025-02-10"> + units="ms" expires_after="2025-07-06"> <owner>linnan@google.com</owner> <owner>koilos@google.com</owner> <summary>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/enums.xml b/tools/metrics/histograms/metadata/safe_browsing/enums.xml index 56f2520..a4bd6c8 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/enums.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/enums.xml
@@ -192,6 +192,11 @@ <int value="26" label="dangerous download canceled on profile closure"/> </enum> +<enum name="DisplayPersistentNotificationEvents"> + <int value="0" label="Request to display persistent notification"/> + <int value="1" label="Finished displaying persistent notification"/> +</enum> + <enum name="SafeBrowsingAllowlistAsyncMatch"> <int value="0" label="ASYNC"/> <int value="1" label="MATCH"/>
diff --git a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml index bcf48bd..3d37701 100644 --- a/tools/metrics/histograms/metadata/safe_browsing/histograms.xml +++ b/tools/metrics/histograms/metadata/safe_browsing/histograms.xml
@@ -2060,6 +2060,22 @@ </summary> </histogram> +<histogram + name="SafeBrowsing.NotificationContentDetection.DisplayPersistentNotificationEvent" + enum="DisplayPersistentNotificationEvents" expires_after="2025-07-02"> + <owner>skrakowi@chromium.org</owner> + <owner>chrome-counter-abuse-alerts@google.com</owner> + <summary> + Records 2 events for displaying a persistent notification for the feature + that shows warnings for suspicious notifications. The first event is logged + when a request is made to check the model, where the notification would + otherwise be displayed immediately. The second event is logged when the + notification content detection code actually displays the notification. This + histogram is temporary for validating the correctness of the suspicious + notification warning feature and the two event counts should match. + </summary> +</histogram> + <histogram name="SafeBrowsing.NotificationContentDetection.SuspiciousScore" units="score" expires_after="2025-10-22"> <owner>skrakowi@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/tab/enums.xml b/tools/metrics/histograms/metadata/tab/enums.xml index 0d358bf2..43e506a 100644 --- a/tools/metrics/histograms/metadata/tab/enums.xml +++ b/tools/metrics/histograms/metadata/tab/enums.xml
@@ -72,6 +72,16 @@ <!-- LINT.ThenChange(//components/saved_tab_groups/internal/tab_group_sync_metrics_logger_impl.h:DeviceType) --> +<!-- LINT.IfChange(DiscardPageOnUIThreadOutcome) --> + +<enum name="DiscardPageOnUIThreadOutcome"> + <int value="0" label="Success"/> + <int value="1" label="NoContents"/> + <int value="2" label="DiscardTabFailure"/> +</enum> + +<!-- LINT.ThenChange(//chrome/browser/performance_manager/mechanisms/page_discarder.cc:DiscardPageOnUIThreadOutcome) --> + <enum name="ExternalLauncherOption"> <int value="0" label="Cancel"/> <int value="1" label="Open"/>
diff --git a/tools/metrics/histograms/metadata/tab/histograms.xml b/tools/metrics/histograms/metadata/tab/histograms.xml index 51b8236..7a82ac2 100644 --- a/tools/metrics/histograms/metadata/tab/histograms.xml +++ b/tools/metrics/histograms/metadata/tab/histograms.xml
@@ -139,6 +139,19 @@ </summary> </histogram> +<histogram name="Discarding.DiscardPageOnUIThreadOutcome" + enum="DiscardPageOnUIThreadOutcome" expires_after="2025-03-01"> + <owner>fdoray@chromium.org</owner> + <owner>joenotcharles@chromium.org</owner> + <summary> + Reports the outcome of each discard tab attempt by the + DiscardPagesOnUIThread function. Will be used to validate that the number of + failures does not increase if DiscardAttemptMarker is retired (it was + introduced to prevent repeated attempts to discard a non-discardable tab, + but that shouldn't happen in practice). + </summary> +</histogram> + <histogram name="Discarding.DiscardsDrivenByStaleSignal" units="tabs" expires_after="2025-06-08"> <owner>kalutes@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/windows/histograms.xml b/tools/metrics/histograms/metadata/windows/histograms.xml index fbd453c..8d50e8d 100644 --- a/tools/metrics/histograms/metadata/windows/histograms.xml +++ b/tools/metrics/histograms/metadata/windows/histograms.xml
@@ -288,6 +288,16 @@ </summary> </histogram> +<histogram name="Windows.Win11UpgradeEligible" enum="BooleanEnabled" + expires_after="2025-06-01"> + <owner>estalin@chromium.org</owner> + <owner>davidbienvenu@chromium.org</owner> + <summary> + Records only on Win10 if the current hardware is capable of being upgraded + to Win11. This is recorded once per browser session, on startup. + </summary> +</histogram> + </histograms> </histogram-configuration>
diff --git a/tools/metrics/ukm/gen_builders.py b/tools/metrics/ukm/gen_builders.py index dd14cb6..0545443 100755 --- a/tools/metrics/ukm/gen_builders.py +++ b/tools/metrics/ukm/gen_builders.py
@@ -44,7 +44,7 @@ Returns: A dict of the data not including any obsolete events or metrics. """ - with open(path) as ukm_file: + with open(path, encoding='utf-8') as ukm_file: data = ukm_model.UKM_XML_TYPE.Parse(ukm_file.read()) event_tag = ukm_model._EVENT_TYPE.tag metric_tag = ukm_model._METRIC_TYPE.tag
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index ca603fb..3da288e6 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -1,28 +1,28 @@ { "trace_processor_shell": { "linux_arm64": { - "hash": "47a61090ce7cf012e52d8850bddeea68162bbb3b", - "full_remote_path": "perfetto-luci-artifacts/79e2dcdef714a3d7f6e09a115cd9fba0c04c7689/linux-arm64/trace_processor_shell" + "hash": "67d97568b642115ddbe7b22432c554d38b921326", + "full_remote_path": "perfetto-luci-artifacts/v49.0/linux-arm64/trace_processor_shell" }, "win": { - "hash": "61520ff113d241210a7d24964e8ff1be7b857d15", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/522ede17aa6880e302642a4147b9f511d15ddd8e/trace_processor_shell.exe" + "hash": "48313b646effd813890aa16dba2b8281fc50a514", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/c95351731d30d4cbeed2690ade79adc2cafdd803/trace_processor_shell.exe" }, "linux_arm": { - "hash": "f92983e30310bbb0af7a96b2e23484a0e561de42", - "full_remote_path": "perfetto-luci-artifacts/79e2dcdef714a3d7f6e09a115cd9fba0c04c7689/linux-arm/trace_processor_shell" + "hash": "a15d8362d80cfd7cd8d785cf6afc22586de688cd", + "full_remote_path": "perfetto-luci-artifacts/v49.0/linux-arm/trace_processor_shell" }, "mac": { "hash": "f5d83eca972747f7c3db9f35c07ed57902418e8c", "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/881ad50c05049ca13d4b34e4f92f4167de5ac52a/trace_processor_shell" }, "mac_arm64": { - "hash": "cf2f8bfcbf9accef95e800881a62e64224e5df6e", - "full_remote_path": "perfetto-luci-artifacts/79e2dcdef714a3d7f6e09a115cd9fba0c04c7689/mac-arm64/trace_processor_shell" + "hash": "e557fb197b57f78806219716af4abdbaa5b099ce", + "full_remote_path": "perfetto-luci-artifacts/v49.0/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "2ec31f962899180f3f0d4a37a5934fd1cfa192e4", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/522ede17aa6880e302642a4147b9f511d15ddd8e/trace_processor_shell" + "hash": "fc7471b0a33d2bbc20ba38120dc153f6aef7a92f", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/6533b84406eee1552b1d2221b7e490a2124297e0/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/typescript/validate_tsconfig.py b/tools/typescript/validate_tsconfig.py index 753d822..2c23e223 100644 --- a/tools/typescript/validate_tsconfig.py +++ b/tools/typescript/validate_tsconfig.py
@@ -167,6 +167,7 @@ # TODO(crbug.com/373951324): Migrate offline dino game to TypeScript. 'components/neterror/resources', 'components/policy/resources/webui', + 'content/browser/webrtc/resources', 'ui/webui/resources/js', 'ui/webui/resources/mojo',
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index d654bcc5..2691625 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -250,6 +250,14 @@ return base::FeatureList::IsEnabled(::features::kAccessibilityShakeToLocate); } +BASE_FEATURE(kAccessibilityManifestV3EnhancedNetworkTts, + "AccessibilityManifestV3EnhancedNetworkTts", + base::FEATURE_DISABLED_BY_DEFAULT); +bool IsAccessibilityManifestV3EnabledForEnhancedNetworkTts() { + return base::FeatureList::IsEnabled( + ::features::kAccessibilityManifestV3EnhancedNetworkTts); +} + #endif // BUILDFLAG(IS_CHROMEOS) #if !BUILDFLAG(IS_ANDROID)
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h index 8b91efc..caae223 100644 --- a/ui/accessibility/accessibility_features.h +++ b/ui/accessibility/accessibility_features.h
@@ -192,6 +192,9 @@ AX_BASE_EXPORT BASE_DECLARE_FEATURE(kAccessibilitySlowKeys); AX_BASE_EXPORT bool IsAccessibilitySlowKeysEnabled(); +AX_BASE_EXPORT BASE_DECLARE_FEATURE(kAccessibilityManifestV3EnhancedNetworkTts); +AX_BASE_EXPORT bool IsAccessibilityManifestV3EnabledForEnhancedNetworkTts(); + #endif // BUILDFLAG(IS_CHROMEOS) #if !BUILDFLAG(IS_ANDROID)
diff --git a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java index 230d80a..807ddf0 100644 --- a/ui/android/java/src/org/chromium/ui/DropdownAdapter.java +++ b/ui/android/java/src/org/chromium/ui/DropdownAdapter.java
@@ -25,7 +25,6 @@ import androidx.core.view.ViewCompat; import org.chromium.build.annotations.NullMarked; -import org.chromium.build.annotations.NullUnmarked; import org.chromium.build.annotations.Nullable; import java.util.List; @@ -35,7 +34,7 @@ @NullMarked public class DropdownAdapter extends ArrayAdapter<DropdownItem> { private final Context mContext; - private final Set<Integer> mSeparators; + private final @Nullable Set<Integer> mSeparators; private final boolean mAreAllItemsEnabled; private final int mLabelMargin; @@ -46,7 +45,9 @@ * @param separators Set of positions that separate {@code items}. */ public DropdownAdapter( - Context context, List<? extends DropdownItem> items, Set<Integer> separators) { + Context context, + List<? extends DropdownItem> items, + @Nullable Set<Integer> separators) { super(context, R.layout.dropdown_item); mContext = context; addAll(items); @@ -66,11 +67,12 @@ return true; } - @NullUnmarked @Override public View getView(int position, @Nullable View convertView, ViewGroup parent) { - View layout = convertView; - if (convertView == null) { + View layout; + if (convertView != null) { + layout = convertView; + } else { LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); layout = inflater.inflate(R.layout.dropdown_item, null);
diff --git a/ui/android/java/src/org/chromium/ui/InsetObserver.java b/ui/android/java/src/org/chromium/ui/InsetObserver.java index cf26c5e..105b91be 100644 --- a/ui/android/java/src/org/chromium/ui/InsetObserver.java +++ b/ui/android/java/src/org/chromium/ui/InsetObserver.java
@@ -100,7 +100,7 @@ InsetConsumerSource.APP_HEADER_COORDINATOR_CAPTION, InsetConsumerSource.EDGE_TO_EDGE_CONTROLLER_IMPL, InsetConsumerSource.EDGE_TO_EDGE_LAYOUT_COORDINATOR, - InsetConsumerSource.APP_HEADER_COORDINATOR_IME, + InsetConsumerSource.APP_HEADER_COORDINATOR_BOTTOM, InsetConsumerSource.COUNT }) @Retention(RetentionPolicy.SOURCE) @@ -112,7 +112,7 @@ int APP_HEADER_COORDINATOR_CAPTION = 2; int EDGE_TO_EDGE_CONTROLLER_IMPL = 3; int EDGE_TO_EDGE_LAYOUT_COORDINATOR = 4; - int APP_HEADER_COORDINATOR_IME = 5; + int APP_HEADER_COORDINATOR_BOTTOM = 5; // Update this whenever a consumer source is added or removed. int COUNT = 6;
diff --git a/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java b/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java index 8f7af3a..e139dc88 100644 --- a/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java +++ b/ui/android/java/src/org/chromium/ui/base/IntentRequestTracker.java
@@ -115,5 +115,5 @@ * @param errorId The error ID used if the intent encounters an error. * @return int The request code for the intent. */ - int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId); + int showCancelableIntent(Intent intent, IntentCallback callback, @Nullable Integer errorId); }
diff --git a/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java b/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java index c98d358d..a84b3e9 100644 --- a/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java +++ b/ui/android/java/src/org/chromium/ui/base/IntentRequestTrackerImpl.java
@@ -35,7 +35,7 @@ // Ideally, this would be a SparseArray<String>, but there's no easy way to store a // SparseArray<String> in a bundle during saveInstanceState(). So we use a HashMap and suppress // the Android lint warning "UseSparseArrays". - private HashMap<Integer, String> mIntentErrors; + private HashMap<Integer, @Nullable String> mIntentErrors; /** * Creates an instance of the class. @@ -48,7 +48,7 @@ } /* package */ int showCancelableIntent( - PendingIntent intent, IntentCallback callback, Integer errorId) { + PendingIntent intent, IntentCallback callback, @Nullable Integer errorId) { int requestCode = generateNextRequestCode(); if (!mDelegate.startIntentSenderForResult(intent.getIntentSender(), requestCode)) { @@ -61,7 +61,7 @@ @Override public int showCancelableIntent( - @Nullable Intent intent, IntentCallback callback, Integer errorId) { + @Nullable Intent intent, IntentCallback callback, @Nullable Integer errorId) { int requestCode = generateNextRequestCode(); if (!mDelegate.startActivityForResult(intent, requestCode)) { @@ -73,7 +73,7 @@ } /* package */ int showCancelableIntent( - Callback<Integer> intentTrigger, IntentCallback callback, Integer errorId) { + Callback<Integer> intentTrigger, IntentCallback callback, @Nullable Integer errorId) { int requestCode = generateNextRequestCode(); intentTrigger.onResult(requestCode); @@ -128,7 +128,7 @@ Object errors = bundle.getSerializable(WindowAndroid.WINDOW_CALLBACK_ERRORS); if (errors instanceof HashMap) { @SuppressWarnings("unchecked") - HashMap<Integer, String> intentErrors = (HashMap<Integer, String>) errors; + HashMap<Integer, String> intentErrors = (HashMap<Integer, @Nullable String>) errors; mIntentErrors = intentErrors; } } @@ -139,7 +139,8 @@ return requestCode; } - private void storeCallbackData(int requestCode, IntentCallback callback, Integer errorId) { + private void storeCallbackData( + int requestCode, IntentCallback callback, @Nullable Integer errorId) { mOutstandingIntents.put(requestCode, callback); mIntentErrors.put( requestCode,
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 4c8baedc..2319993d 100644 --- a/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java +++ b/ui/android/java/src/org/chromium/ui/base/WindowAndroid.java
@@ -391,7 +391,8 @@ * results, or null if no message is required. * @return Whether the intent was shown. */ - public boolean showIntent(PendingIntent intent, IntentCallback callback, Integer errorId) { + public boolean showIntent( + PendingIntent intent, IntentCallback callback, @Nullable Integer errorId) { if (mIntentRequestTracker == null) { Log.d(TAG, "Can't show intent as context is not an Activity: " + intent); return false; @@ -407,7 +408,8 @@ * results, or null if no message is required. * @return Whether the intent was shown. */ - public boolean showIntent(@Nullable Intent intent, IntentCallback callback, Integer errorId) { + public boolean showIntent( + @Nullable Intent intent, IntentCallback callback, @Nullable Integer errorId) { if (mIntentRequestTracker == null) { Log.d(TAG, "Can't show intent as context is not an Activity: " + intent); return false; @@ -425,7 +427,7 @@ * START_INTENT_FAILURE if failed. */ public int showCancelableIntent( - PendingIntent intent, IntentCallback callback, Integer errorId) { + PendingIntent intent, IntentCallback callback, @Nullable Integer errorId) { if (mIntentRequestTracker == null) { Log.d(TAG, "Can't show intent as context is not an Activity: " + intent); return START_INTENT_FAILURE; @@ -442,7 +444,8 @@ * @return A non-negative request code that could be used for finishActivity, or * START_INTENT_FAILURE if failed. */ - public int showCancelableIntent(Intent intent, IntentCallback callback, Integer errorId) { + public int showCancelableIntent( + Intent intent, IntentCallback callback, @Nullable Integer errorId) { if (mIntentRequestTracker == null) { Log.d(TAG, "Can't show intent as context is not an Activity: " + intent); return START_INTENT_FAILURE; @@ -451,7 +454,7 @@ } public int showCancelableIntent( - Callback<Integer> intentTrigger, IntentCallback callback, Integer errorId) { + Callback<Integer> intentTrigger, IntentCallback callback, @Nullable Integer errorId) { if (mIntentRequestTracker == null) { Log.d(TAG, "Can't show intent as context is not an Activity"); return START_INTENT_FAILURE;
diff --git a/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java b/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java index eaf7eba4d..bff3a105 100644 --- a/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java +++ b/ui/android/junit/src/org/chromium/ui/InsetObserverTest.java
@@ -144,7 +144,7 @@ public void applyInsets_withMultipleInsetConsumers() { // Add consumers in reverse order of priority. mInsetObserver.addInsetsConsumer( - mInsetsConsumer1, InsetConsumerSource.APP_HEADER_COORDINATOR_IME); + mInsetsConsumer1, InsetConsumerSource.APP_HEADER_COORDINATOR_BOTTOM); mInsetObserver.addInsetsConsumer( mInsetsConsumer2, InsetConsumerSource.DEFERRED_IME_WINDOW_INSET_APPLICATION_CALLBACK);
diff --git a/ui/gfx/geometry/decomposed_transform.h b/ui/gfx/geometry/decomposed_transform.h index e93a5dc..d134ad5 100644 --- a/ui/gfx/geometry/decomposed_transform.h +++ b/ui/gfx/geometry/decomposed_transform.h
@@ -5,6 +5,8 @@ #ifndef UI_GFX_GEOMETRY_DECOMPOSED_TRANSFORM_H_ #define UI_GFX_GEOMETRY_DECOMPOSED_TRANSFORM_H_ +#include <array> + #include "base/component_export.h" #include "base/dcheck_is_on.h" #include "ui/gfx/geometry/quaternion.h" @@ -16,10 +18,10 @@ struct COMPONENT_EXPORT(GEOMETRY) DecomposedTransform { // The default constructor initializes the components in such a way that // will compose the identity transform. - double translate[3] = {0, 0, 0}; - double scale[3] = {1, 1, 1}; - double skew[3] = {0, 0, 0}; - double perspective[4] = {0, 0, 0, 1}; + std::array<double, 3u> translate = {0, 0, 0}; + std::array<double, 3u> scale = {1, 1, 1}; + std::array<double, 3u> skew = {0, 0, 0}; + std::array<double, 4u> perspective = {0, 0, 0, 1}; Quaternion quaternion; std::string ToString() const;
diff --git a/ui/gfx/geometry/matrix44.cc b/ui/gfx/geometry/matrix44.cc index d573e7e2..9f0f930 100644 --- a/ui/gfx/geometry/matrix44.cc +++ b/ui/gfx/geometry/matrix44.cc
@@ -266,7 +266,7 @@ SetCol(1, c1 + c0 * tan_skew_x); } -void Matrix44::ApplyDecomposedSkews(const double skews[3]) { +void Matrix44::ApplyDecomposedSkews(base::span<const double, 3> skews) { Double4 c0 = Col(0); Double4 c1 = Col(1); Double4 c2 = Col(2);
diff --git a/ui/gfx/geometry/matrix44.h b/ui/gfx/geometry/matrix44.h index ffe82221..b3a342a 100644 --- a/ui/gfx/geometry/matrix44.h +++ b/ui/gfx/geometry/matrix44.h
@@ -14,6 +14,7 @@ #include "base/check_op.h" #include "base/component_export.h" +#include "base/containers/span.h" #include "ui/gfx/geometry/double4.h" namespace gfx { @@ -157,7 +158,7 @@ // this = this * |0 1 skew[2] 0| // |0 0 1 0| // |0 0 0 1| - void ApplyDecomposedSkews(const double skews[3]); + void ApplyDecomposedSkews(base::span<const double, 3> skews); // this = this * perspective. void ApplyPerspectiveDepth(double perspective);
diff --git a/ui/gfx/geometry/transform_util.cc b/ui/gfx/geometry/transform_util.cc index 4829035..9ea598f 100644 --- a/ui/gfx/geometry/transform_util.cc +++ b/ui/gfx/geometry/transform_util.cc
@@ -25,9 +25,9 @@ namespace { template <int n> -void Combine(double* out, - const double* a, - const double* b, +void Combine(std::array<double, n>& out, + const std::array<double, n> a, + const std::array<double, n> b, double scale_a, double scale_b) { for (int i = 0; i < n; ++i)
diff --git a/ui/views/animation/flood_fill_ink_drop_ripple.cc b/ui/views/animation/flood_fill_ink_drop_ripple.cc index 0870cd9..501c020 100644 --- a/ui/views/animation/flood_fill_ink_drop_ripple.cc +++ b/ui/views/animation/flood_fill_ink_drop_ripple.cc
@@ -284,10 +284,13 @@ // Returns the InkDropState sub animation duration for the given |state|. base::TimeDelta FloodFillInkDropRipple::GetAnimationDuration( AnimationSubState state) { - if (!PlatformStyle::kUseRipples || - !gfx::Animation::ShouldRenderRichAnimation() || - (GetInkDropHost() && GetInkDropHost()->GetMode() == - InkDropHost::InkDropMode::ON_NO_ANIMATE)) { + if constexpr (!PlatformStyle::kUseRipples) { + return base::TimeDelta(); + } + if (!gfx::Animation::ShouldRenderRichAnimation() || + (GetInkDropHost() && + GetInkDropHost()->GetMode() == + InkDropHost::InkDropMode::ON_NO_ANIMATE)) { return base::TimeDelta(); }
diff --git a/ui/views/animation/square_ink_drop_ripple.cc b/ui/views/animation/square_ink_drop_ripple.cc index dea2c0f..5fe7a86 100644 --- a/ui/views/animation/square_ink_drop_ripple.cc +++ b/ui/views/animation/square_ink_drop_ripple.cc
@@ -119,10 +119,12 @@ // Returns the InkDropState sub animation duration for the given |state|. base::TimeDelta GetAnimationDuration(InkDropHost* ink_drop_host, InkDropSubAnimations state) { - if (!PlatformStyle::kUseRipples || - !gfx::Animation::ShouldRenderRichAnimation() || - (ink_drop_host && - ink_drop_host->GetMode() == InkDropHost::InkDropMode::ON_NO_ANIMATE)) { + if constexpr (!PlatformStyle::kUseRipples) { + return base::TimeDelta(); + } + if (!gfx::Animation::ShouldRenderRichAnimation() || + (ink_drop_host && ink_drop_host->GetMode() == + InkDropHost::InkDropMode::ON_NO_ANIMATE)) { return base::TimeDelta(); }
diff --git a/ui/views/controls/button/label_button_unittest.cc b/ui/views/controls/button/label_button_unittest.cc index 0f0f7aa9d..43ad213 100644 --- a/ui/views/controls/button/label_button_unittest.cc +++ b/ui/views/controls/button/label_button_unittest.cc
@@ -942,11 +942,6 @@ dummy_widget_ = CreateTopLevelPlatformWidget(); MakeButtonAsContent(test_widget_)->SetID(1); - - style_of_inactive_widget_ = - PlatformStyle::kInactiveWidgetControlsAppearDisabled - ? Button::STATE_DISABLED - : Button::STATE_NORMAL; } void TearDown() override { @@ -979,7 +974,10 @@ raw_ptr<Widget> test_widget_ = nullptr; raw_ptr<Widget> dummy_widget_ = nullptr; - Button::ButtonState style_of_inactive_widget_; + static constexpr Button::ButtonState style_of_inactive_widget_ = + PlatformStyle::kInactiveWidgetControlsAppearDisabled + ? Button::STATE_DISABLED + : Button::STATE_NORMAL; }; TEST_F(LabelButtonVisualStateTest, IndependentWidget) {
diff --git a/ui/views/controls/button/md_text_button_unittest.cc b/ui/views/controls/button/md_text_button_unittest.cc index adccc39..2699625d 100644 --- a/ui/views/controls/button/md_text_button_unittest.cc +++ b/ui/views/controls/button/md_text_button_unittest.cc
@@ -33,7 +33,7 @@ TEST_F(MdTextButtonTest, BackgroundColorChangesWithWidgetActivation) { // Test whether the button's background color changes when its containing // widget's activation changes. - if (!PlatformStyle::kInactiveWidgetControlsAppearDisabled) { + if constexpr (!PlatformStyle::kInactiveWidgetControlsAppearDisabled) { GTEST_SKIP() << "Button colors do not change with widget activation here."; }
diff --git a/ui/views/controls/combobox/combobox_unittest.cc b/ui/views/controls/combobox/combobox_unittest.cc index 303116f..b519e18 100644 --- a/ui/views/controls/combobox/combobox_unittest.cc +++ b/ui/views/controls/combobox/combobox_unittest.cc
@@ -833,7 +833,7 @@ ui::KeyEvent return_press(ui::EventType::kKeyPressed, ui::VKEY_RETURN, ui::EF_NONE); - if (PlatformStyle::kReturnClicksFocusedControl) { + if constexpr (PlatformStyle::kReturnClicksFocusedControl) { EXPECT_TRUE(combobox()->OnKeyPressed(return_press)); EXPECT_EQ(2, menu_show_count_); } else {
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 68d61ad..3c062fd9 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -615,18 +615,20 @@ menu_start_mouse_press_loc_ = View::ConvertPointToScreen( static_cast<View*>(event->target()), static_cast<const ui::MouseEvent*>(event)->location()); - } else if (views::PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard && - !IsEditableCombobox() && - (source_type == ui::mojom::MenuSourceType::kKeyboard || - is_key_event)) { - // On Windows, we want to select the first menu item when the menu is - // opened via keyboard. This is because NVDA expects the focus to be on - // a menu item when the menu is opened via keyboard. - direction_is_down = - !(is_key_event && event->AsKeyEvent()->key_code() == ui::VKEY_UP); - to_select = FindInitialSelectableMenuItem( - root, direction_is_down ? INCREMENT_SELECTION_DOWN - : INCREMENT_SELECTION_UP); + } else if constexpr (views::PlatformStyle:: + kAutoSelectFirstMenuItemFromKeyboard) { + if (!IsEditableCombobox() && + (source_type == ui::mojom::MenuSourceType::kKeyboard || + is_key_event)) { + // On Windows, we want to select the first menu item when the menu is + // opened via keyboard. This is because NVDA expects the focus to be + // on a menu item when the menu is opened via keyboard. + direction_is_down = + !(is_key_event && event->AsKeyEvent()->key_code() == ui::VKEY_UP); + to_select = FindInitialSelectableMenuItem( + root, direction_is_down ? INCREMENT_SELECTION_DOWN + : INCREMENT_SELECTION_UP); + } } } }
diff --git a/ui/views/controls/menu/menu_item_view_unittest.cc b/ui/views/controls/menu/menu_item_view_unittest.cc index 56c7241..4392e4a 100644 --- a/ui/views/controls/menu/menu_item_view_unittest.cc +++ b/ui/views/controls/menu/menu_item_view_unittest.cc
@@ -624,17 +624,10 @@ // The selected bit and selection based state should both update for all menu // items while they and their anscestors remain part of the menu. - if (views::PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard) { - // On Windows, we automatically select the first item when the menu is - // opened from the keyboard. - EXPECT_TRUE(submenu_item->IsSelected()); - EXPECT_TRUE(submenu_item->last_paint_as_selected_for_testing()); - } else { - // On other platforms, we don't automatically select the first item when the - // menu is opened from the keyboard. - EXPECT_FALSE(submenu_item->IsSelected()); - EXPECT_FALSE(submenu_item->last_paint_as_selected_for_testing()); - } + EXPECT_EQ(submenu_item->IsSelected(), + views::PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard); + EXPECT_EQ(submenu_item->last_paint_as_selected_for_testing(), + views::PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard); submenu_item->SetSelected(true); EXPECT_TRUE(submenu_item->IsSelected()); @@ -680,15 +673,8 @@ MenuAnchorPosition::kTopLeft, ui::mojom::MenuSourceType::kKeyboard); - if (views::PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard) { - // On Windows, we automatically select the first item when the menu is - // opened from the keyboard. - EXPECT_TRUE(child_menu_item->last_paint_as_selected_for_testing()); - } else { - // On other platforms, we don't automatically select the first item when the - // menu is opened from the keyboard. - EXPECT_FALSE(child_menu_item->last_paint_as_selected_for_testing()); - } + EXPECT_EQ(child_menu_item->last_paint_as_selected_for_testing(), + views::PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard); child_menu_item->SetSelected(true); EXPECT_TRUE(child_menu_item->IsSelected());
diff --git a/ui/views/controls/table/table_header.cc b/ui/views/controls/table/table_header.cc index e7bbbfd..2c279e9 100644 --- a/ui/views/controls/table/table_header.cc +++ b/ui/views/controls/table/table_header.cc
@@ -71,7 +71,7 @@ // HighlightPathGenerator: SkPath GetHighlightPath(const View* view) override { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { return SkPath(); }
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index b0d2d5ef..950787bf 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -156,7 +156,7 @@ // HighlightPathGenerator: SkPath GetHighlightPath(const views::View* view) override { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { return SkPath(); } @@ -607,6 +607,12 @@ return false; } + if constexpr (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if (HandleKeyPressedForKeyboardNavigationByCell(event)) { + return true; + } + } + switch (event.key_code()) { case ui::VKEY_A: // control-a selects all. @@ -662,60 +668,67 @@ #endif return true; - case ui::VKEY_LEFT: - if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { - const AdvanceDirection direction = base::i18n::IsRTL() - ? AdvanceDirection::kIncrement - : AdvanceDirection::kDecrement; - if (IsCmdOrCtrl(event)) { - if (active_visible_column_index_.has_value() && header_) { - header_->ResizeColumnViaKeyboard( - active_visible_column_index_.value(), direction); - UpdateFocusRings(); - } - } else { - AdvanceActiveVisibleColumn(direction); - } - return true; - } + default: break; + } - case ui::VKEY_RIGHT: + if (observer_) { + observer_->OnKeyDown(event.key_code()); + } + return false; +} + +bool TableView::HandleKeyPressedForKeyboardNavigationByCell( + const ui::KeyEvent& event) { + switch (event.key_code()) { + case ui::VKEY_LEFT: { + const AdvanceDirection direction = base::i18n::IsRTL() + ? AdvanceDirection::kIncrement + : AdvanceDirection::kDecrement; + if (IsCmdOrCtrl(event)) { + if (active_visible_column_index_.has_value() && header_) { + header_->ResizeColumnViaKeyboard(active_visible_column_index_.value(), + direction); + UpdateFocusRings(); + } + } else { + AdvanceActiveVisibleColumn(direction); + } + return true; + } + + case ui::VKEY_RIGHT: { // TODO(crbug.com/40773239): Update TableView to support keyboard // navigation to table cells on Mac when "Full keyboard access" is // specified. - if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { - const AdvanceDirection direction = base::i18n::IsRTL() - ? AdvanceDirection::kDecrement - : AdvanceDirection::kIncrement; - if (IsCmdOrCtrl(event)) { - if (active_visible_column_index_.has_value() && header_) { - header_->ResizeColumnViaKeyboard( - active_visible_column_index_.value(), direction); - UpdateFocusRings(); - } - } else { - AdvanceActiveVisibleColumn(direction); + const AdvanceDirection direction = base::i18n::IsRTL() + ? AdvanceDirection::kDecrement + : AdvanceDirection::kIncrement; + if (IsCmdOrCtrl(event)) { + if (active_visible_column_index_.has_value() && header_) { + header_->ResizeColumnViaKeyboard(active_visible_column_index_.value(), + direction); + UpdateFocusRings(); } - return true; + } else { + AdvanceActiveVisibleColumn(direction); } - break; + return true; + } // Currently there are TableView clients that take an action when the return // key is pressed and there is an active selection in the body. To avoid // breaking these cases only allow toggling sort order with the return key // when the table header is active. case ui::VKEY_RETURN: - if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell && - active_visible_column_index_.has_value() && header_row_is_active_) { + if (active_visible_column_index_.has_value() && header_row_is_active_) { ToggleSortOrder(active_visible_column_index_.value()); return true; } break; case ui::VKEY_SPACE: - if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell && - active_visible_column_index_.has_value()) { + if (active_visible_column_index_.has_value()) { ToggleSortOrder(active_visible_column_index_.value()); return true; } @@ -724,10 +737,6 @@ default: break; } - - if (observer_) { - observer_->OnKeyDown(event.key_code()); - } return false; } @@ -1208,6 +1217,7 @@ if (schedule_paint) { SchedulePaint(); + UpdateFocusRings(); } } @@ -1675,10 +1685,11 @@ size_t model_index = ViewToModel(view_index); // We only need to update the name if the column is visible. - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell && - visible_columns_.size()) { - ax_row->GetCustomData().SetName( - model_->GetText(model_index, GetVisibleColumn(0).column.id)); + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if (visible_columns_.size()) { + ax_row->GetCustomData().SetName( + model_->GetText(model_index, GetVisibleColumn(0).column.id)); + } } for (auto& ax_cell : ax_row->children()) { @@ -1751,7 +1762,7 @@ selected); // Select/Unselect the cell. - if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { for (size_t cell = 0; cell < ax_row->children().size(); cell++) { if (cell == GetActiveVisibleColumnIndex()) { ax_row->children()[cell]->GetCustomData().AddBoolAttribute( @@ -1780,8 +1791,10 @@ void TableView::UpdateAccessibleSelectionForColumnIndex( size_t visible_column_index) const { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell || - visible_column_index >= visible_columns_.size()) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + return; + } + if (visible_column_index >= visible_columns_.size()) { return; } @@ -1804,7 +1817,7 @@ row_data.AddIntAttribute(ax::mojom::IntAttribute::kTableRowIndex, static_cast<int32_t>(row_index)); - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { row_data.AddState(ax::mojom::State::kFocusable); row_data.AddAction(ax::mojom::Action::kFocus); row_data.AddAction(ax::mojom::Action::kScrollToMakeVisible); @@ -1838,7 +1851,7 @@ cell_data.AddIntAttribute(ax::mojom::IntAttribute::kTableCellRowIndex, static_cast<int32_t>(row_index)); - if (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { cell_data.AddState(ax::mojom::State::kFocusable); cell_data.AddAction(ax::mojom::Action::kFocus); cell_data.AddAction(ax::mojom::Action::kScrollLeft); @@ -2092,7 +2105,7 @@ size_t active_row = ModelToView(selection_model_.active().value()); AXVirtualView* ax_row = GetVirtualAccessibilityBodyRow(active_row); - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { if (ax_row) { ax_row->NotifyAccessibilityEvent(ax::mojom::Event::kSelection); GetViewAccessibility().OverrideFocus(ax_row);
diff --git a/ui/views/controls/table/table_view.h b/ui/views/controls/table/table_view.h index 01025447..1bab286 100644 --- a/ui/views/controls/table/table_view.h +++ b/ui/views/controls/table/table_view.h
@@ -501,6 +501,10 @@ // Updates the focus rings of the TableView and the TableHeader if necessary. void UpdateFocusRings(); + // Handles key events for keyboard navigation by cell. Returns true if the + // event was handled. + bool HandleKeyPressedForKeyboardNavigationByCell(const ui::KeyEvent& event); + // TODO(327473315): Only one of raw_ptr in this class is dangling. Find which // one. raw_ptr<ui::TableModel, LeakedDanglingUntriaged> model_ = nullptr;
diff --git a/ui/views/controls/table/table_view_unittest.cc b/ui/views/controls/table/table_view_unittest.cc index 5aa543df..ce459194 100644 --- a/ui/views/controls/table/table_view_unittest.cc +++ b/ui/views/controls/table/table_view_unittest.cc
@@ -1028,7 +1028,7 @@ // Verifies resizing a column works with the keyboard. // The resize keyboard amount is 5 pixels. TEST_P(TableViewTest, ResizeViaKeyboard) { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { GTEST_SKIP() << "platform doesn't support table keyboard navigation"; } @@ -1232,7 +1232,7 @@ // Verifies that pressing the space bar when a particular visible column is // active will sort by that column. TEST_P(TableViewTest, SortOnSpaceBar) { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { GTEST_SKIP() << "platform doesn't support table keyboard navigation"; } @@ -1911,7 +1911,7 @@ // Verifies left/right correctly navigate through visible columns. TEST_P(TableViewTest, KeyLeftRight) { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { GTEST_SKIP() << "platform doesn't support table keyboard navigation"; } @@ -2009,7 +2009,7 @@ // Verify table view that the left/right navigation scrolls the visible rect // correctly. TEST_P(TableViewTest, KeyLeftRightScrollRectToVisibleInTableView) { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { GTEST_SKIP() << "platform doesn't support table keyboard navigation"; } @@ -2051,7 +2051,7 @@ // Verify table header that the left/right navigation scrolls the visible rect // correctly. TEST_P(TableViewTest, KeyLeftRightScrollRectToVisibleInTableHeader) { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { GTEST_SKIP() << "platform doesn't support table keyboard navigation"; } @@ -2086,7 +2086,7 @@ // switching between different rows when the layout is RTL or LTR. use_rtl() // returns true for testing the RTL layout and false for testing the LTR layout TEST_P(TableViewTest, KeyUpDownHorizontalScrollbarStability) { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { GTEST_SKIP() << "platform doesn't support table keyboard navigation"; } EXPECT_FALSE(base::i18n::IsRTL()); @@ -2447,7 +2447,7 @@ // Ensure that the TableView's header columns are keyboard accessible. // Tests for crbug.com/1189851. TEST_P(TableViewTest, TableHeaderColumnAccessibleViewsFocusable) { - if (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { + if constexpr (!PlatformStyle::kTableViewSupportsKeyboardNavigationByCell) { GTEST_SKIP() << "platform doesn't support table keyboard navigation"; }
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index e31ea23..33afc532 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -702,7 +702,8 @@ } ui::Cursor Textfield::GetCursor(const ui::MouseEvent& event) { - bool platform_arrow = PlatformStyle::kTextfieldUsesDragCursorWhenDraggable; + constexpr bool platform_arrow = + PlatformStyle::kTextfieldUsesDragCursorWhenDraggable; bool in_selection = GetRenderText()->IsPointInSelection(event.location()); bool drag_event = event.type() == ui::EventType::kMouseDragged; bool text_cursor =
diff --git a/ui/views/controls/tree/tree_view.cc b/ui/views/controls/tree/tree_view.cc index 0f24437..2232ddc3 100644 --- a/ui/views/controls/tree/tree_view.cc +++ b/ui/views/controls/tree/tree_view.cc
@@ -1182,9 +1182,10 @@ drawing_provider()->GetBackgroundColorForNode(this, node->model_node()); // Paint the row background. - if (PlatformStyle::kTreeViewSelectionPaintsEntireRow && - selected_node_ == node) { - canvas->FillRect(GetBackgroundBoundsForNode(node), selected_row_bg_color); + if constexpr (PlatformStyle::kTreeViewSelectionPaintsEntireRow) { + if (selected_node_ == node) { + canvas->FillRect(GetBackgroundBoundsForNode(node), selected_row_bg_color); + } } if (!model_->GetChildren(node->model_node()).empty()) { @@ -1207,9 +1208,10 @@ } // Paint the background on the selected row. - if (!PlatformStyle::kTreeViewSelectionPaintsEntireRow && - node == selected_node_) { - canvas->FillRect(text_bounds, selected_row_bg_color); + if constexpr (!PlatformStyle::kTreeViewSelectionPaintsEntireRow) { + if (node == selected_node_) { + canvas->FillRect(text_bounds, selected_row_bg_color); + } } // Paint the auxiliary text. @@ -1423,7 +1425,7 @@ // If the entire row gets a selected background, clicking anywhere in the row // serves to hit this node. - if (PlatformStyle::kTreeViewSelectionPaintsEntireRow) { + if constexpr (PlatformStyle::kTreeViewSelectionPaintsEntireRow) { return node; } gfx::Rect bounds(GetForegroundBoundsForNodeImpl(node, row, depth));
diff --git a/ui/views/selection_controller_unittest.cc b/ui/views/selection_controller_unittest.cc index 85098e4..d963e06 100644 --- a/ui/views/selection_controller_unittest.cc +++ b/ui/views/selection_controller_unittest.cc
@@ -182,7 +182,7 @@ SetText("abc def"); RightMouseDown(CenterRight(BoundsOfChar(0))); - if (PlatformStyle::kSelectAllOnRightClickWhenUnfocused) { + if constexpr (PlatformStyle::kSelectAllOnRightClickWhenUnfocused) { EXPECT_EQ("abc def", GetSelectedText()); } else { EXPECT_EQ("", GetSelectedText()); @@ -192,7 +192,7 @@ TEST_F(SelectionControllerTest, RightClickSelectsWord) { SetText("abc def"); RightMouseDown(CenterRight(BoundsOfChar(5)), true); - if (PlatformStyle::kSelectWordOnRightClick) { + if constexpr (PlatformStyle::kSelectWordOnRightClick) { EXPECT_EQ("def", GetSelectedText()); } else { EXPECT_EQ("", GetSelectedText());
diff --git a/ui/views/style/platform_style.cc b/ui/views/style/platform_style.cc index 192a7f80..b91d45a 100644 --- a/ui/views/style/platform_style.cc +++ b/ui/views/style/platform_style.cc
@@ -22,41 +22,8 @@ namespace views { -#if BUILDFLAG(IS_WIN) -const bool PlatformStyle::kIsOkButtonLeading = true; -const bool PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard = true; -#else -const bool PlatformStyle::kIsOkButtonLeading = false; -const bool PlatformStyle::kAutoSelectFirstMenuItemFromKeyboard = false; -#endif - #if !BUILDFLAG(IS_MAC) -const int PlatformStyle::kMinLabelButtonWidth = 70; -const int PlatformStyle::kMinLabelButtonHeight = 33; -const bool PlatformStyle::kDialogDefaultButtonCanBeCancel = true; -const bool PlatformStyle::kSelectWordOnRightClick = false; -const bool PlatformStyle::kSelectAllOnRightClickWhenUnfocused = false; -const Button::KeyClickAction PlatformStyle::kKeyClickActionOnSpace = - Button::KeyClickAction::kOnKeyRelease; -const bool PlatformStyle::kReturnClicksFocusedControl = true; -const bool PlatformStyle::kTableViewSupportsKeyboardNavigationByCell = true; -const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = false; -const bool PlatformStyle::kUseRipples = true; -const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = true; -const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = false; -const View::FocusBehavior PlatformStyle::kDefaultFocusBehavior = - View::FocusBehavior::ALWAYS; - -// Linux clips bubble windows that extend outside their parent window -// bounds. -const bool PlatformStyle::kAdjustBubbleIfOffscreen = -#if BUILDFLAG(IS_LINUX) - false; -#else - true; -#endif - // static std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar( ScrollBar::Orientation orientation) {
diff --git a/ui/views/style/platform_style.h b/ui/views/style/platform_style.h index 5e05a0c2..59d9211 100644 --- a/ui/views/style/platform_style.h +++ b/ui/views/style/platform_style.h
@@ -27,57 +27,70 @@ // Whether the ok button is in the leading position (left in LTR) in a // typical Cancel/OK button group. - static const bool kIsOkButtonLeading; - - // Minimum size for platform-styled buttons. - static const int kMinLabelButtonWidth; - static const int kMinLabelButtonHeight; + static constexpr bool kIsOkButtonLeading = BUILDFLAG(IS_WIN); // Whether the default button for a dialog can be the Cancel button. - static const bool kDialogDefaultButtonCanBeCancel; + static constexpr bool kDialogDefaultButtonCanBeCancel = !BUILDFLAG(IS_MAC); // Whether right clicking on text, selects the word under cursor. - static const bool kSelectWordOnRightClick; + static constexpr bool kSelectWordOnRightClick = BUILDFLAG(IS_MAC); // Whether right clicking inside an unfocused text view selects all the text. - static const bool kSelectAllOnRightClickWhenUnfocused; + static constexpr bool kSelectAllOnRightClickWhenUnfocused = BUILDFLAG(IS_MAC); // Whether the Space key clicks a button on key press or key release. - static const Button::KeyClickAction kKeyClickActionOnSpace; + static constexpr Button::KeyClickAction kKeyClickActionOnSpace = +#if BUILDFLAG(IS_MAC) + Button::KeyClickAction::kOnKeyPress; +#else + Button::KeyClickAction::kOnKeyRelease; +#endif // Whether the Return key clicks the focused control (on key press). // Otherwise, Return does nothing unless it is handled by an accelerator. - static const bool kReturnClicksFocusedControl; + // On Mac, the Return key is used to perform the default action even when a + // control is focused. + static constexpr bool kReturnClicksFocusedControl = !BUILDFLAG(IS_MAC); // Whether cursor left and right can be used in a TableView to select and // resize columns and whether a focus ring should be shown around the active // cell. - static const bool kTableViewSupportsKeyboardNavigationByCell; + static constexpr bool kTableViewSupportsKeyboardNavigationByCell = + !BUILDFLAG(IS_MAC); // Whether selecting a row in a TreeView selects the entire row or only the // label for that row. - static const bool kTreeViewSelectionPaintsEntireRow; + static constexpr bool kTreeViewSelectionPaintsEntireRow = BUILDFLAG(IS_MAC); // Whether ripples should be used for visual feedback on control activation. - static const bool kUseRipples; + static constexpr bool kUseRipples = !BUILDFLAG(IS_MAC); // Whether text fields should use a "drag" cursor when not actually // dragging but available to do so. - static const bool kTextfieldUsesDragCursorWhenDraggable; + static constexpr bool kTextfieldUsesDragCursorWhenDraggable = + !BUILDFLAG(IS_MAC); // Whether controls in inactive widgets appear disabled. - static const bool kInactiveWidgetControlsAppearDisabled; + static constexpr bool kInactiveWidgetControlsAppearDisabled = + BUILDFLAG(IS_MAC); // Default setting at bubble creation time for whether arrow will be adjusted - // for bubbles going off-screen to bring more bubble area into view. - static const bool kAdjustBubbleIfOffscreen; + // for bubbles going off-screen to bring more bubble area into view. Linux + // clips bubble windows that extend outside their parent window bounds. + static constexpr bool kAdjustBubbleIfOffscreen = !BUILDFLAG(IS_LINUX); // Default focus behavior on the platform. - static const View::FocusBehavior kDefaultFocusBehavior; + static constexpr View::FocusBehavior kDefaultFocusBehavior = +#if BUILDFLAG(IS_MAC) + View::FocusBehavior::ACCESSIBLE_ONLY; +#else + View::FocusBehavior::ALWAYS; +#endif - // On Windows, the first menu item is automatically selected when a menu is - // opened with the keyboard. - static const bool kAutoSelectFirstMenuItemFromKeyboard; + // On Windows, the first menu item is automatically selected when a menu + // is opened with the keyboard. + static constexpr bool kAutoSelectFirstMenuItemFromKeyboard = + BUILDFLAG(IS_WIN); // Creates the default scrollbar for the given orientation. static std::unique_ptr<ScrollBar> CreateScrollBar(
diff --git a/ui/views/style/platform_style_mac.mm b/ui/views/style/platform_style_mac.mm index b42155a..5202556 100644 --- a/ui/views/style/platform_style_mac.mm +++ b/ui/views/style/platform_style_mac.mm
@@ -33,27 +33,6 @@ namespace views { -const int PlatformStyle::kMinLabelButtonWidth = 32; -const int PlatformStyle::kMinLabelButtonHeight = 30; -const bool PlatformStyle::kDialogDefaultButtonCanBeCancel = false; -const bool PlatformStyle::kSelectWordOnRightClick = true; -const bool PlatformStyle::kSelectAllOnRightClickWhenUnfocused = true; -const bool PlatformStyle::kTextfieldUsesDragCursorWhenDraggable = false; -const bool PlatformStyle::kTableViewSupportsKeyboardNavigationByCell = false; -const bool PlatformStyle::kTreeViewSelectionPaintsEntireRow = true; -const bool PlatformStyle::kUseRipples = false; -const bool PlatformStyle::kInactiveWidgetControlsAppearDisabled = true; -const bool PlatformStyle::kAdjustBubbleIfOffscreen = true; -const View::FocusBehavior PlatformStyle::kDefaultFocusBehavior = - View::FocusBehavior::ACCESSIBLE_ONLY; - -const Button::KeyClickAction PlatformStyle::kKeyClickActionOnSpace = - Button::KeyClickAction::kOnKeyPress; - -// On Mac, the Return key is used to perform the default action even when a -// control is focused. -const bool PlatformStyle::kReturnClicksFocusedControl = false; - // static std::unique_ptr<ScrollBar> PlatformStyle::CreateScrollBar( ScrollBar::Orientation orientation) {
diff --git a/ui/views/widget/widget_unittest.cc b/ui/views/widget/widget_unittest.cc index eb94ab7..5cec238b 100644 --- a/ui/views/widget/widget_unittest.cc +++ b/ui/views/widget/widget_unittest.cc
@@ -3542,7 +3542,7 @@ }; TEST_F(WidgetTest, LockParentPaintAsActive) { - if (!PlatformStyle::kInactiveWidgetControlsAppearDisabled) { + if constexpr (!PlatformStyle::kInactiveWidgetControlsAppearDisabled) { return; }
diff --git a/ui/views/window/dialog_client_view.cc b/ui/views/window/dialog_client_view.cc index 9910cfb9..7e96a16 100644 --- a/ui/views/window/dialog_client_view.cc +++ b/ui/views/window/dialog_client_view.cc
@@ -556,7 +556,7 @@ } void DialogClientView::UpdateButtonsFromModel() { - if (PlatformStyle::kIsOkButtonLeading) { + if constexpr (PlatformStyle::kIsOkButtonLeading) { UpdateDialogButton(&ok_button_, ui::mojom::DialogButton::kOk); UpdateDialogButton(&cancel_button_, ui::mojom::DialogButton::kCancel); } else {
diff --git a/ui/views/window/dialog_client_view_unittest.cc b/ui/views/window/dialog_client_view_unittest.cc index 7c7019a..356d7493 100644 --- a/ui/views/window/dialog_client_view_unittest.cc +++ b/ui/views/window/dialog_client_view_unittest.cc
@@ -258,8 +258,6 @@ // Test that views inside the dialog client view have the correct focus order. TEST_F(DialogClientViewTest, SetupFocusChain) { - const bool kIsOkButtonOnLeftSide = PlatformStyle::kIsOkButtonLeading; - delegate()->GetContentsView()->SetFocusBehavior(View::FocusBehavior::ALWAYS); // Initially the dialog client view only contains the content view. EXPECT_EQ(delegate()->GetContentsView(), @@ -269,7 +267,7 @@ SetDialogButtons(static_cast<int>(ui::mojom::DialogButton::kOk) | static_cast<int>(ui::mojom::DialogButton::kCancel)); - if (kIsOkButtonOnLeftSide) { + if constexpr (PlatformStyle::kIsOkButtonLeading) { EXPECT_EQ(client_view()->ok_button(), FocusableViewAfter(delegate()->GetContentsView())); EXPECT_EQ(client_view()->cancel_button(),