diff --git a/DEPS b/DEPS index 99705f4..9abebd80 100644 --- a/DEPS +++ b/DEPS
@@ -305,19 +305,19 @@ # 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': 'a60d46ccb6f87592fb259207f7a7dc29797258fe', + 'src_internal_revision': '796b60e971aab3ab6e82cb1514b01b17a06c62dc', # 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': '3480f588eb09d25a4b1c15e643197a1eef058718', + 'skia_revision': 'e4dc4fdb541d30b786d373b09217d769d06ed946', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling V8 # and whatever else without interference from each other. - 'v8_revision': '033fd2f04cb7ff9d69cbaf0876e808186ca2dc5c', + 'v8_revision': '99022d9158c6e40babc442b84dc0b60ed64cd378', # 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': 'f9685fdb79805ace8376705bafb024a1bd64c05a', + 'angle_revision': '17977bb088acae8e114bae7f1ae92326b5fe8d1d', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -329,7 +329,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': '08a77f3d88475b092c365d12576de078a54a6d91', + 'boringssl_revision': 'ed44d6f8deb450d8178908027ff46a0252b2d405', # 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. @@ -373,7 +373,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling catapult # and whatever else without interference from each other. - 'catapult_revision': '179e38564ddc7cdf0b58d5c923f2c5c3b132899a', + 'catapult_revision': '423d5e63ff44523b3e2895d94165b80d4a003227', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling CrossBench # and whatever else without interference from each other. @@ -421,7 +421,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': 'd1ef389738224f8a92c5a4557a812db47cf042cc', + 'dawn_revision': '895a2f1fc2a1e02c99b3b9522fbb4474b0c8da93', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -529,7 +529,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. - 'compiler_rt_revision': '5436a04e9d9f47771ae83ac5942e1d0e690baf76', + 'compiler_rt_revision': '75e783208e3c6a8c6236cc9f45d11d10f601c14f', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling clusterfuzz-data # and whatever else without interference from each other. @@ -1201,7 +1201,7 @@ 'packages': [ { 'package': 'chromium/chrome/android/orderfiles/arm64', - 'version': 'GqmrYkmJMgA4l2sZT4qSIi1g6Tp7B-QvZLrcOlMEUe8C', + 'version': 'Ja235hBXF0gUw-zfldml6WY02SgCPeQ34fbrQ67VIrsC', }, ], 'condition': 'checkout_android', @@ -1223,7 +1223,7 @@ 'packages': [ { 'package': 'chromium/android_webview/tools/orderfiles/arm64', - 'version': '2f46Njln16sr_t17cz1_oEgJAbTaqHEI45x1V5Kb9_gC', + 'version': 'oyb8wPBAwpY2mlqf65dx00Eqbi8o-WKKm1bn0QBTx9UC', }, ], 'condition': 'checkout_android', @@ -1231,7 +1231,7 @@ }, 'src/chrome/browser/resources/preinstalled_web_apps/internal': { - 'url': Var('chrome_git') + '/chrome/components/default_apps.git' + '@' + '656ac90405cdbb7d7ab05c54a1628c6d7418832e', + 'url': Var('chrome_git') + '/chrome/components/default_apps.git' + '@' + '73cc53e1db0fddd9fb797c40c6085579b27e7bf3', 'condition': 'checkout_src_internal', }, @@ -1395,7 +1395,7 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chromium_linux64', - 'version': 'version:2@1521004', + 'version': 'version:2@1522001', }, ], }, @@ -1406,7 +1406,7 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chromium_mac_amd64', - 'version': 'version:2@1521006', + 'version': 'version:2@1522001', }, ], }, @@ -1417,7 +1417,7 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chromium_mac_arm64', - 'version': 'version:2@1521003', + 'version': 'version:2@1522002', }, ], }, @@ -1428,7 +1428,7 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chromium_win_arm64', - 'version': 'version:2@1521006', + 'version': 'version:2@1522002', }, ], }, @@ -1439,7 +1439,7 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chromium_win_x86', - 'version': 'version:2@1521014', + 'version': 'version:2@1522001', }, ], }, @@ -1450,7 +1450,7 @@ 'packages': [ { 'package': 'chromium/third_party/updater/chromium_win_x86_64', - 'version': 'version:2@1521004', + 'version': 'version:2@1522003', }, ], }, @@ -1528,7 +1528,7 @@ 'packages': [ { 'package': 'chromium/third_party/enterprise_companion/chromium_linux64', - 'version': 'VuY7G-r5ROPn1RhaX-CO0-h0tv3tf8OoFdXn4UWvQmAC', + 'version': 'EN1Ts3o9uW-pnurxVE-DhJOd0UTRmNVI-EzKSQGbMwIC', }, ], }, @@ -1539,7 +1539,7 @@ 'packages': [ { 'package': 'chromium/third_party/enterprise_companion/chromium_mac_amd64', - 'version': 'X3YlXY7g01u10ZlwzhHD5DkS8y__F7FqPuMHNhEokwkC', + 'version': 'IzWyA5LaAxmFfpKgsiU1tdk8W263wTOZyr1jgYd_8NQC', }, ], }, @@ -1550,7 +1550,7 @@ 'packages': [ { 'package': 'chromium/third_party/enterprise_companion/chromium_mac_arm64', - 'version': '9TRuQAdh6f-LzeVpjGzo0V_-DI03ThMrX_ZwBxS69boC', + 'version': 'LRUUeVy1xpQNgpOvSgIHyarpgDydm5h0KJeH8c6HVAkC', }, ], }, @@ -1561,7 +1561,7 @@ 'packages': [ { 'package': 'chromium/third_party/enterprise_companion/chromium_win_x86', - 'version': 'wvssxH76sPWNlIHFyrVUwfBiuHJtkAxe388mehyw-LUC', + 'version': 'bfUQts1yi4CTddqaVCCva6R5rg0gRXkQcI0hV62R6vUC', }, ], }, @@ -1572,7 +1572,7 @@ 'packages': [ { 'package': 'chromium/third_party/enterprise_companion/chromium_win_x86_64', - 'version': 'LLRKSK0DCJFxGt0AOSmULvF76jMXd6DRzGB9RYso-RUC', + 'version': 'x5fCUnkpRA6UoJKtg1V0oCM2dxLIGmJwjLL9eg9kVPQC', }, ], }, @@ -1608,7 +1608,7 @@ 'packages': [ { 'package': 'chromium/chrome/test/data/variations/cipd', - 'version': 'OzNQYR2vrh1kpdTAezDqPscQVyG_8OXtcHwmh3ej024C', + 'version': 'WD_CViMxB7xbucef237Tu2k5m57qF9uogU9WYarMUkoC', }, ], 'dep_type': 'cipd', @@ -1619,7 +1619,7 @@ 'src/clank': { 'url': Var('chrome_git') + '/clank/internal/apps.git' + '@' + - 'e77b8efbb4d973044f6b8d448e2c578c0900db51', + 'e1b431c9a8ec43eb47ae9e1bca1e1bfe86ee5445', 'condition': 'checkout_android and checkout_src_internal', }, @@ -1719,7 +1719,7 @@ 'packages': [ { 'package': 'chromium/third_party/androidx', - 'version': 'fyinP9RshUI8vASuLvf1tuBf8jI4KnxUWd6QzLb1b5YC', + 'version': 'DeEJdhsAl-OeZqdi5R97nLaquqMpvsCmeySRp4nK1hIC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2055,7 +2055,7 @@ Var('chromium_git') + '/chromium/web-tests.git' + '@' + Var('crossbench_web_tests_revision'), 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8fc14e1deafc4356319f2534de813899a3e01094', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '8c6304befd2205384c73e73d214848e57d9a0239', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), @@ -2605,7 +2605,7 @@ Var('pdfium_git') + '/pdfium.git' + '@' + Var('pdfium_revision'), 'src/third_party/perfetto': - Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + 'ff11fbe7c825083afe471945766e615bc675800b', + Var('chromium_git') + '/external/github.com/google/perfetto.git' + '@' + 'd7ea394300667faed7b239e087a51447586a3132', 'src/base/tracing/test/data': { 'bucket': 'perfetto', @@ -2796,7 +2796,7 @@ 'packages': [ { 'package': 'chromium/third_party/r8', - 'version': 'llWUebGsQPrzc7z3fwJF78NcrdGs1wrUhy0Y-0Wrb-4C', + 'version': '2aBDG942g42qUBPPInGETRHusdxru1U3anwJI_QX5wIC', }, ], 'condition': 'checkout_android and non_git_source', @@ -2924,7 +2924,7 @@ 'dep_type': 'cipd', }, - 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@cd34cfe6a579d03c0675b32844599294773634aa', + 'src/third_party/vulkan-deps': '{chromium_git}/vulkan-deps@90603b2036a87d17dde4d38f5fa16fc770961e94', 'src/third_party/glslang/src': '{chromium_git}/external/github.com/KhronosGroup/glslang@f6652dcf751920b1fbc132619b0e84ef3d6e77c4', 'src/third_party/spirv-cross/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Cross@b8fcf307f1f347089e3c46eb4451d27f32ebc8d3', 'src/third_party/spirv-headers/src': '{chromium_git}/external/github.com/KhronosGroup/SPIRV-Headers@a5164829e8f0255392c481696b63763a5e80be3c', @@ -2933,7 +2933,7 @@ 'src/third_party/vulkan-loader/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Loader@385716f0a63fe2c26e54a5140c9877a80da66592', 'src/third_party/vulkan-tools/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Tools@faf69f66f2d9ba782fe37cabd19b9742f9f62eb3', 'src/third_party/vulkan-utility-libraries/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-Utility-Libraries@a1e45945b3a84140956dc4672684090cf8e636a4', - 'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@07a7e8afd318ba34ac2a999002e6602d88205c41', + 'src/third_party/vulkan-validation-layers/src': '{chromium_git}/external/github.com/KhronosGroup/Vulkan-ValidationLayers@1acbea52c1e445b9398ecc228cb3bb115d97aac5', 'src/third_party/vulkan_memory_allocator': Var('chromium_git') + '/external/github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator.git' + '@' + 'cb0597213b0fcb999caa9ed08c2f88dc45eb7d50', @@ -2976,7 +2976,7 @@ Var('chromium_git') + '/webpagereplay.git' + '@' + Var('webpagereplay_revision'), 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + '85cbfaf6b96394215415527d67546d4bd872208a', + Var('webrtc_git') + '/src.git' + '@' + '661a2e642d3bec939e203650fb0b86e1af815c63', # 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. @@ -3757,7 +3757,7 @@ 'src/ios_internal': { 'url': Var('chrome_git') + '/chrome/ios_internal.git' + '@' + - 'deec601008dc93b675f5a8d94df26732d38a3d59', + 'f34aa19784ed9d36ae10f877a4347e2e23aab6cb', 'condition': 'checkout_ios and checkout_src_internal', },
diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java index 0790e03..a2bbe16 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/services/JsSandboxServiceTest.java
@@ -983,6 +983,7 @@ @Test @LargeTest + @DisabledTest(message = "crbug.com/450361757") public void testArrayBufferSizeEnforced() throws Throwable { final long maxHeapSize = REASONABLE_HEAP_SIZE; // V8 cannot sparsely allocate array buffers, so no fill required.
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index bcf6c95b..f60ca4d 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -2954,11 +2954,11 @@ </message> <!-- Status tray charging strings. --> - <message name="IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_TITLE" desc="The title of a notification indicating that an incompatible charger has been connected, and no charging will occur." translateable="false"> - Incompatible charger + <message name="IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_TITLE" desc="The title of a notification indicating that an incompatible charger has been connected, and no charging will occur."> + Can't charge device </message> - <message name="IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_MESSAGE" desc="The message body of a notification indicating that an incompatible charger has been connected, and that the user needs to connect a more powerful one." translateable="false"> - Connect an adapter with more watts (W) to charge your device. + <message name="IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_MESSAGE" desc="The message body of a notification indicating that an incompatible charger has been connected, and that the user needs to connect a more powerful one."> + Try a charger with more watts (W) or use your original charger. </message> <message name="IDS_ASH_STATUS_TRAY_LOW_POWER_CHARGER_TITLE" desc="The title of a notification indicating that a low-current USB charger has been connected."> Low-power charger connected @@ -3117,8 +3117,8 @@ <message name="IDS_ASH_STATUS_TRAY_BATTERY_CHARGING_UNRELIABLE_ACCESSIBLE" desc="The message used by accessibility to indicate that battery charging is unreliable."> Plugged in to a low-power charger. Battery charging may not be reliable. </message> - <message name="IDS_ASH_STATUS_TRAY_BATTERY_INCOMPATIBLE_CHARGER_ACCESSIBLE" desc="The message used by accessibility to announce that an incompatible charger is connected." translateable="false"> - Plugged in to an incompatible charger. Connect the original charger (or a similar wattage charger) to charge your device. + <message name="IDS_ASH_STATUS_TRAY_BATTERY_INCOMPATIBLE_CHARGER_ACCESSIBLE" desc="The message used by accessibility to announce that an incompatible charger is connected."> + Device plugged in, but not charging. Try a charger with more watts (W) or use your original charger. </message> <message name="IDS_ASH_STATUS_TRAY_BATTERY_STATUS_SEPARATOR" desc="The separator symbol between battery percentage string and battery remaining time string"> ''' - '''
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_BATTERY_INCOMPATIBLE_CHARGER_ACCESSIBLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_BATTERY_INCOMPATIBLE_CHARGER_ACCESSIBLE.png.sha1 new file mode 100644 index 0000000..91f9b48b --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_BATTERY_INCOMPATIBLE_CHARGER_ACCESSIBLE.png.sha1
@@ -0,0 +1 @@ +d9dc5f401a9d66176191a9c8adb0c3671b42a806 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_MESSAGE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_MESSAGE.png.sha1 new file mode 100644 index 0000000..91f9b48b --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_MESSAGE.png.sha1
@@ -0,0 +1 @@ +d9dc5f401a9d66176191a9c8adb0c3671b42a806 \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_TITLE.png.sha1 b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_TITLE.png.sha1 new file mode 100644 index 0000000..91f9b48b --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_STATUS_TRAY_INCOMPATIBLE_CHARGER_TITLE.png.sha1
@@ -0,0 +1 @@ +d9dc5f401a9d66176191a9c8adb0c3671b42a806 \ No newline at end of file
diff --git a/ash/system/brightness/unified_brightness_view_unittest.cc b/ash/system/brightness/unified_brightness_view_unittest.cc index 7f7ac031..4da89275 100644 --- a/ash/system/brightness/unified_brightness_view_unittest.cc +++ b/ash/system/brightness/unified_brightness_view_unittest.cc
@@ -14,6 +14,7 @@ #include "ash/wm/window_util.h" #include "base/memory/raw_ptr.h" #include "ui/base/l10n/l10n_util.h" +#include "ui/display/test/display_manager_test_api.h" #include "ui/gfx/vector_icon_types.h" #include "ui/views/accessibility/view_accessibility.h" #include "ui/views/controls/image_view.h" @@ -114,6 +115,9 @@ // letting them get through to the slider. Effectively the `slider_button` is // part of the slider in the brightness view. TEST_F(UnifiedBrightnessViewTest, SliderButtonClickThrough) { + display::test::DisplayManagerTestApi(display_manager()) + .SetFirstDisplayAsInternalDisplay(); + controller()->UpdateBrightnessSlider(); slider()->SetValue(1.0); EXPECT_FLOAT_EQ(unified_brightness_view()->slider()->GetValue(), 1.0);
diff --git a/ash/system/unified/unified_system_tray_controller.cc b/ash/system/unified/unified_system_tray_controller.cc index 57a221d6..e2e1aed9 100644 --- a/ash/system/unified/unified_system_tray_controller.cc +++ b/ash/system/unified/unified_system_tray_controller.cc
@@ -94,9 +94,13 @@ pagination_controller_ = std::make_unique<PaginationController>( model_->pagination_model(), PaginationController::SCROLL_AXIS_HORIZONTAL, base::BindRepeating(&RecordPageSwitcherSourceByEventType)); + + display::Screen::Get()->AddObserver(this); } -UnifiedSystemTrayController::~UnifiedSystemTrayController() = default; +UnifiedSystemTrayController::~UnifiedSystemTrayController() { + display::Screen::Get()->RemoveObserver(this); +} void UnifiedSystemTrayController::AddObserver(Observer* observer) { if (observer) { @@ -138,6 +142,7 @@ base::Unretained(this)))); unified_brightness_view_ = qs_view->AddSliderView(brightness_slider_controller_->CreateView()); + UpdateBrightnessSlider(); qs_view->SetMaxHeight(max_height); @@ -494,4 +499,40 @@ } } +void UnifiedSystemTrayController::UpdateBrightnessSlider() const { + if (!unified_brightness_view_) { + return; + } + auto* slider = + views::AsViewClass<UnifiedBrightnessView>(unified_brightness_view_) + ->slider(); + for (const display::Display& display : + display::Screen::Get()->GetAllDisplays()) { + if (display.IsInternal()) { + slider->SetEnabled(true); + return; + } + } + slider->SetEnabled(false); +} + +bool UnifiedSystemTrayController::GetBrightnessSliderEnabledForTesting() const { + if (!unified_brightness_view_) { + return false; + } + return views::AsViewClass<UnifiedBrightnessView>(unified_brightness_view_) + ->slider() + ->GetEnabled(); +} + +void UnifiedSystemTrayController::OnDisplayAdded( + const display::Display& new_display) { + UpdateBrightnessSlider(); +} + +void UnifiedSystemTrayController::OnDisplaysRemoved( + const display::Displays& removed_displays) { + UpdateBrightnessSlider(); +} + } // namespace ash
diff --git a/ash/system/unified/unified_system_tray_controller.h b/ash/system/unified/unified_system_tray_controller.h index 5202649..b4d5ec8 100644 --- a/ash/system/unified/unified_system_tray_controller.h +++ b/ash/system/unified/unified_system_tray_controller.h
@@ -5,15 +5,21 @@ #ifndef ASH_SYSTEM_UNIFIED_UNIFIED_SYSTEM_TRAY_CONTROLLER_H_ #define ASH_SYSTEM_UNIFIED_UNIFIED_SYSTEM_TRAY_CONTROLLER_H_ +#include <memory> + #include "ash/ash_export.h" #include "ash/system/audio/unified_volume_slider_controller.h" #include "ash/system/media/quick_settings_media_view_controller.h" #include "ash/system/time/calendar_metrics.h" #include "ash/system/unified/quick_settings_view.h" #include "ash/system/unified/unified_system_tray_model.h" +#include "base/memory/raw_ptr.h" #include "base/memory/safety_checks.h" #include "base/memory/scoped_refptr.h" #include "components/global_media_controls/public/constants.h" +#include "ui/display/display_observer.h" +#include "ui/views/controls/slider.h" +#include "ui/views/view.h" namespace ash { @@ -27,7 +33,8 @@ // Controller class of `QuickSettingsView`. Handles events of the view. class ASH_EXPORT UnifiedSystemTrayController - : public UnifiedVolumeSliderController::Delegate { + : public UnifiedVolumeSliderController::Delegate, + public display::DisplayObserver { // Do not remove this macro! // The macro is maintained by the memory safety team. ADVANCED_MEMORY_SAFETY_CHECKS(); @@ -127,6 +134,10 @@ // UnifiedVolumeSliderController::Delegate: void OnAudioSettingsButtonClicked() override; + // display::DisplayObserver: + void OnDisplayAdded(const display::Display& new_display) override; + void OnDisplaysRemoved(const display::Displays& removed_displays) override; + // Sets whether the quick settings view should show the media view. void SetShowMediaView(bool show_media_view); @@ -170,6 +181,10 @@ void ShutDownDetailedViewController(); + // Enable or disable the brightness slider view. + void UpdateBrightnessSlider() const; + bool GetBrightnessSliderEnabledForTesting() const; + private: friend class AccessibilityFeaturePodControllerTest; friend class SystemTrayTestApi;
diff --git a/ash/system/unified/unified_system_tray_unittest.cc b/ash/system/unified/unified_system_tray_unittest.cc index 8c7a296..ee66929 100644 --- a/ash/system/unified/unified_system_tray_unittest.cc +++ b/ash/system/unified/unified_system_tray_unittest.cc
@@ -64,6 +64,7 @@ #include "ui/chromeos/styles/cros_tokens_color_mappings.h" #include "ui/display/display.h" #include "ui/display/screen.h" +#include "ui/display/test/display_manager_test_api.h" #include "ui/events/event_constants.h" #include "ui/message_center/message_center.h" #include "ui/views/accessibility/view_accessibility.h" @@ -864,6 +865,40 @@ tray->CloseBubble(); } +TEST_P(UnifiedSystemTrayTest, BrightnessSliderDisabledInDockedMode) { + const int64_t internal_display_id = + display::test::DisplayManagerTestApi(display_manager()) + .SetFirstDisplayAsInternalDisplay(); + const auto internal_info = + display_manager()->GetDisplayInfo(internal_display_id); + constexpr int64_t external_id = 210000010; + + const auto external_info = + display::ManagedDisplayInfo::CreateFromSpecWithID("400x300", external_id); + + std::vector<display::ManagedDisplayInfo> display_info_list; + display_info_list.push_back(internal_info); + display_info_list.push_back(external_info); + display_manager()->OnNativeDisplaysChanged(display_info_list); + EXPECT_EQ(2U, display_manager()->GetNumDisplays()); + + auto* tray = GetPrimaryUnifiedSystemTray(); + tray->ShowBubble(); + + EXPECT_TRUE(tray->bubble() + ->unified_system_tray_controller() + ->GetBrightnessSliderEnabledForTesting()); + + display_info_list.clear(); + display_info_list.push_back(external_info); + display_manager()->OnNativeDisplaysChanged(display_info_list); + EXPECT_EQ(1U, display_manager()->GetNumDisplays()); + + EXPECT_FALSE(tray->bubble() + ->unified_system_tray_controller() + ->GetBrightnessSliderEnabledForTesting()); +} + // Tests that there's no bubble in the kiosk mode. TEST_P(UnifiedSystemTrayTest, NoBubbleAndNoDetailedViewInKioskMode) { SimulateKioskMode(user_manager::UserType::kKioskChromeApp);
diff --git a/ash/webui/boca_ui/boca_app_page_handler.cc b/ash/webui/boca_ui/boca_app_page_handler.cc index 7777de8..d375b12 100644 --- a/ash/webui/boca_ui/boca_app_page_handler.cc +++ b/ash/webui/boca_ui/boca_app_page_handler.cc
@@ -650,6 +650,7 @@ std::move(callback).Run(std::nullopt); return; } + GetSessionManager()->EndSpotlightSession(base::DoNothing()); EndViewScreenSessionInternal(id, std::move(callback)); } @@ -774,7 +775,11 @@ &BocaAppHandler::OnEndViewScreenResponseForPresentStudentScreen, weak_ptr_factory_.GetWeakPtr(), session->session_id(), std::move(student), receiver_id, std::move(callback)); - EndViewScreenSessionInternal(student_id, std::move(end_view_screen_cb)); + auto end_spotlight_cb = + base::BindOnce(&BocaAppHandler::EndViewScreenSessionInternal, + weak_ptr_factory_.GetWeakPtr(), std::move(student_id), + std::move(end_view_screen_cb)); + GetSessionManager()->EndSpotlightSession(std::move(end_spotlight_cb)); } void BocaAppHandler::StopPresentingStudentScreen( @@ -1339,10 +1344,6 @@ EndViewScreenSessionCallback callback) { CHECK(spotlight_service_); - if (ash::features::IsBocaSpotlightRobotRequesterEnabled()) { - GetSessionManager()->EndSpotlightSession(); - } - spotlight_service_->UpdateViewScreenState( id, ::boca::ViewScreenConfig::INACTIVE, base_url_, base::BindOnce( @@ -1402,17 +1403,8 @@ std::move(callback).Run(false); return; } - // Delay presentation to increase the likelihood the host receives the - // inactive connection notification and can accept the new one. - // TODO(crbug.com/445259545): The race condition is still there even with the - // delay. Update the host side to allow new connection even if the previous - // one is ongoing and then remove this delay. - base::SequencedTaskRunner::GetCurrentDefault()->PostDelayedTask( - FROM_HERE, - base::BindOnce(&BocaAppHandler::PresentStudentScreenInternal, - weak_ptr_factory_.GetWeakPtr(), session_id, - std::move(student), receiver_id, std::move(callback)), - base::Seconds(5)); + PresentStudentScreenInternal(session_id, std::move(student), receiver_id, + std::move(callback)); } TeacherScreenPresenter* BocaAppHandler::teacher_screen_presenter() {
diff --git a/ash/webui/boca_ui/boca_app_page_handler_unittest.cc b/ash/webui/boca_ui/boca_app_page_handler_unittest.cc index 4bddb6e6..a95575e 100644 --- a/ash/webui/boca_ui/boca_app_page_handler_unittest.cc +++ b/ash/webui/boca_ui/boca_app_page_handler_unittest.cc
@@ -315,6 +315,7 @@ GetStudentActiveDeviceId, (std::string_view), (override)); + MOCK_METHOD(void, EndSpotlightSession, (base::OnceClosure), (override)); ~MockSessionManager() override = default; }; @@ -2626,6 +2627,7 @@ TEST_F(BocaAppPageHandlerProducerTest, EndViewScreenSessionSucceeded) { const std::string student_id = "123"; + EXPECT_CALL(*session_manager(), EndSpotlightSession).Times(1); EXPECT_CALL( *spotlight_service(), UpdateViewScreenState(student_id, ::boca::ViewScreenConfig::INACTIVE, @@ -2649,6 +2651,7 @@ ON_CALL(*session_manager(), GetStudentScreenPresenter) .WillByDefault(Return(student_screen_presenter.get())); ON_CALL(*student_screen_presenter, IsPresenting).WillByDefault(Return(true)); + EXPECT_CALL(*session_manager(), EndSpotlightSession).Times(0); EXPECT_CALL(*spotlight_service(), UpdateViewScreenState).Times(0); boca_app_handler()->EndViewScreenSession("student-id", future.GetCallback()); @@ -2659,6 +2662,7 @@ base::HistogramTester histogram_tester; const std::string student_id = "123"; + EXPECT_CALL(*session_manager(), EndSpotlightSession).Times(1); EXPECT_CALL( *spotlight_service(), UpdateViewScreenState(student_id, ::boca::ViewScreenConfig::INACTIVE, @@ -3103,6 +3107,8 @@ EXPECT_CALL(*session_manager(), GetCurrentSession()) .WillRepeatedly(Return(&session)); boca_app_handler()->OnSessionStarted("session_id", ::boca::UserIdentity()); + EXPECT_CALL(*session_manager(), EndSpotlightSession) + .WillOnce([](base::OnceClosure callback) { std::move(callback).Run(); }); EXPECT_CALL(*spotlight_service(), UpdateViewScreenState) .WillOnce([](std::string, ::boca::ViewScreenConfig::ViewScreenState, std::string, ViewScreenRequestCallback callback) { @@ -3123,7 +3129,6 @@ boca_app_handler()->PresentStudentScreen(student_identity_mojom->Clone(), kReceiverId, success_future.GetCallback()); - task_environment()->FastForwardBy(base::Seconds(5)); EXPECT_TRUE(success_future.Get()); EXPECT_EQ(student_identity.gaia_id(), student_identity_mojom->id); EXPECT_EQ(student_identity.full_name(), student_identity_mojom->name); @@ -3145,6 +3150,8 @@ EXPECT_CALL(*session_manager(), GetCurrentSession()) .WillRepeatedly(Return(&session)); boca_app_handler()->OnSessionStarted("session_id", ::boca::UserIdentity()); + EXPECT_CALL(*session_manager(), EndSpotlightSession) + .WillOnce([](base::OnceClosure callback) { std::move(callback).Run(); }); EXPECT_CALL(*spotlight_service(), UpdateViewScreenState) .WillOnce([](std::string, ::boca::ViewScreenConfig::ViewScreenState, std::string, ViewScreenRequestCallback callback) { @@ -3163,7 +3170,6 @@ mojom::Identity::New(kActiveStudentId, "student name", "student@email.com", std::nullopt), kReceiverId, success_future.GetCallback()); - task_environment()->FastForwardBy(base::Seconds(5)); EXPECT_FALSE(success_future.Get()); } @@ -3178,6 +3184,8 @@ EXPECT_CALL(*session_manager(), GetCurrentSession()) .WillRepeatedly(Return(&session)); boca_app_handler()->OnSessionStarted("session_id", ::boca::UserIdentity()); + EXPECT_CALL(*session_manager(), EndSpotlightSession) + .WillOnce([](base::OnceClosure callback) { std::move(callback).Run(); }); EXPECT_CALL(*spotlight_service(), UpdateViewScreenState) .WillOnce([](std::string, ::boca::ViewScreenConfig::ViewScreenState, std::string, ViewScreenRequestCallback callback) { @@ -3198,15 +3206,21 @@ std::make_unique<MockStudentScreenPresenter>(); ON_CALL(*session_manager(), GetStudentScreenPresenter) .WillByDefault(Return(student_screen_presenter.get())); + ON_CALL(*session_manager(), GetStudentActiveDeviceId) + .WillByDefault(Return(kStudentDeviceId)); base::test::TestFuture<bool> success_future; + ViewScreenRequestCallback view_screen_update_cb; ::boca::Session session = GetCommonActiveSessionProto(); EXPECT_CALL(*session_manager(), GetCurrentSession()) .WillRepeatedly(Return(&session)); boca_app_handler()->OnSessionStarted("session_id", ::boca::UserIdentity()); + EXPECT_CALL(*session_manager(), EndSpotlightSession) + .WillOnce([](base::OnceClosure callback) { std::move(callback).Run(); }); EXPECT_CALL(*spotlight_service(), UpdateViewScreenState) - .WillOnce([](std::string, ::boca::ViewScreenConfig::ViewScreenState, - std::string, ViewScreenRequestCallback callback) { - std::move(callback).Run(true); + .WillOnce([&view_screen_update_cb]( + std::string, ::boca::ViewScreenConfig::ViewScreenState, + std::string, ViewScreenRequestCallback callback) { + view_screen_update_cb = std::move(callback); }); EXPECT_CALL(*student_screen_presenter, Start).Times(0); boca_app_handler()->PresentStudentScreen( @@ -3214,7 +3228,7 @@ "student@email.com", std::nullopt), kReceiverId, success_future.GetCallback()); session.set_session_state(::boca::Session::PAST); - task_environment()->FastForwardBy(base::Seconds(5)); + std::move(view_screen_update_cb).Run(true); EXPECT_FALSE(success_future.Get()); } @@ -3228,6 +3242,8 @@ EXPECT_CALL(*session_manager(), GetCurrentSession()) .WillRepeatedly(Return(&session)); boca_app_handler()->OnSessionStarted("session_id", ::boca::UserIdentity()); + EXPECT_CALL(*session_manager(), EndSpotlightSession) + .WillOnce([](base::OnceClosure callback) { std::move(callback).Run(); }); EXPECT_CALL(*spotlight_service(), UpdateViewScreenState) .WillOnce([](std::string, ::boca::ViewScreenConfig::ViewScreenState, std::string, ViewScreenRequestCallback callback) { @@ -3240,7 +3256,6 @@ mojom::Identity::New(kActiveStudentId, "student name", "student@email.com", std::nullopt), kReceiverId, success_future.GetCallback()); - task_environment()->FastForwardBy(base::Seconds(5)); EXPECT_FALSE(success_future.Get()); }
diff --git a/base/memory/memory_pressure_listener.h b/base/memory/memory_pressure_listener.h index 7805d87..46c8e6d 100644 --- a/base/memory/memory_pressure_listener.h +++ b/base/memory/memory_pressure_listener.h
@@ -51,7 +51,8 @@ kResourcePool = 21, kOnDeviceTailModelService = 22, kGpuChannelManager = 23, - kSharedDictionaryManagerOnDisk = 24, + // Deprecated. + // kSharedDictionaryManagerOnDisk = 24, kSharedDictionaryManager = 25, kHistoryBackend = 26, kMediaUrlIndex = 27,
diff --git a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py b/buildtools/reclient_cfgs/fetch_reclient_cfgs.py deleted file mode 100755 index 4f136f5..0000000 --- a/buildtools/reclient_cfgs/fetch_reclient_cfgs.py +++ /dev/null
@@ -1,16 +0,0 @@ -#!/usr/bin/env python3 -# 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. -"""This script is used to fetch reclient cfgs. - -This is renamed to configure_reclient_cfgs.py, delete this file if there are no -reference to this file. -""" - -import sys - -import configure_reclient_cfgs - -if __name__ == '__main__': - sys.exit(configure_reclient_cfgs.main())
diff --git a/buildtools/third_party/libc++/BUILD.gn b/buildtools/third_party/libc++/BUILD.gn index c0c6cfb9..f1ac049d 100644 --- a/buildtools/third_party/libc++/BUILD.gn +++ b/buildtools/third_party/libc++/BUILD.gn
@@ -126,7 +126,7 @@ } } -if (use_clang_modules && use_xcode_symlinks) { +if (use_clang_modules && use_xcode_symlinks && !use_autogenerated_modules) { # sysroot_modulemaps can be inside the build directory. This no-op action # declares the modulemap files as outputs to satisfy GN's dependency # tracking when other targets use them as inputs.
diff --git a/buildtools/third_party/libc++/modules.gni b/buildtools/third_party/libc++/modules.gni index a4d2635..adbdc7e 100644 --- a/buildtools/third_party/libc++/modules.gni +++ b/buildtools/third_party/libc++/modules.gni
@@ -35,21 +35,6 @@ public_deps = [] } - if (use_xcode_symlinks) { - # The `copy_sysroot_modulemaps` action depends on SDK paths that differ - # between macOS and iOS, so it must be built with the correct toolchain - # for the target OS. - toolchain = "//build/toolchain/mac:clang_$target_cpu" - if (is_ios || target_environment == "catalyst") { - toolchain = "//build/toolchain/ios:ios_clang_$target_cpu" - } else if (target_os == "ios" && is_mac) { - toolchain = "//build/toolchain/mac:clang_$host_cpu" - } - public_deps += [ - "//buildtools/third_party/libc++:copy_sysroot_modulemaps($toolchain)", - ] - } - # Implicit module maps won't work on apple because we're currently # missing some dependencies. if (use_autogenerated_modules) { @@ -73,6 +58,19 @@ # intentionally disabled because it's broken (eg. Darwin.modulemap). cflags += [ clang_arg_prefix + "-fno-implicit-module-maps" ] } else { + if (use_xcode_symlinks) { + # The `copy_sysroot_modulemaps` action depends on SDK paths that differ + # between macOS and iOS, so it must be built with the correct toolchain + # for the target OS. + toolchain = "//build/toolchain/mac:clang_$target_cpu" + if (is_ios || target_environment == "catalyst") { + toolchain = "//build/toolchain/ios:ios_clang_$target_cpu" + } else if (target_os == "ios" && is_mac) { + toolchain = "//build/toolchain/mac:clang_$host_cpu" + } + public_deps += [ "//buildtools/third_party/libc++:copy_sysroot_modulemaps($toolchain)" ] + } + if (!defined(public_configs)) { public_configs = [] }
diff --git a/cc/DEPS b/cc/DEPS index 69aab669..17c1fe4 100644 --- a/cc/DEPS +++ b/cc/DEPS
@@ -74,6 +74,9 @@ "+gpu/command_buffer/common/command_buffer_id.h", "+gpu/command_buffer/common/constants.h", ], + "gpu_image_decode_cache_unittest\.cc" : [ + "+gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h", + ], "oop_pixeltest\.cc" : [ "+gpu/command_buffer/client", "+gpu/command_buffer/common",
diff --git a/cc/paint/paint_op_raster_fuzzer.cc b/cc/paint/paint_op_raster_fuzzer.cc index def3b5c2..8eb0891 100644 --- a/cc/paint/paint_op_raster_fuzzer.cc +++ b/cc/paint/paint_op_raster_fuzzer.cc
@@ -85,7 +85,6 @@ SkImageInfo image_info = SkImageInfo::MakeN32( kRasterDimension, kRasterDimension, kOpaque_SkAlphaType); - context_provider->BindToCurrentSequence(); sk_sp<SkSurface> surface = SkSurfaces::RenderTarget( context_provider->GrContext(), skgpu::Budgeted::kYes, image_info); SkCanvas* canvas = surface->getCanvas();
diff --git a/cc/paint/transfer_cache_fuzzer.cc b/cc/paint/transfer_cache_fuzzer.cc index 8f34017..07a58fe 100644 --- a/cc/paint/transfer_cache_fuzzer.cc +++ b/cc/paint/transfer_cache_fuzzer.cc
@@ -64,7 +64,7 @@ base::span<const uint8_t> span(unaligned_data, size - unaligned_gap); #endif - if (!entry->Deserialize(context_provider->GrContext(), + if (!entry->Deserialize(/*gr_context=*/nullptr, /*graphite_recorder=*/nullptr, span)) { return 0; }
diff --git a/cc/raster/raster_buffer_provider_perftest.cc b/cc/raster/raster_buffer_provider_perftest.cc index 89314f6c..a017a18 100644 --- a/cc/raster/raster_buffer_provider_perftest.cc +++ b/cc/raster/raster_buffer_provider_perftest.cc
@@ -38,7 +38,6 @@ #include "testing/gtest/include/gtest/gtest.h" #include "testing/perf/perf_result_reporter.h" #include "third_party/khronos/GLES2/gl2.h" -#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" namespace cc { namespace { @@ -113,9 +112,6 @@ return raster_context_.get(); } gpu::ContextSupport* ContextSupport() override { return &support_; } - class GrDirectContext* GrContext() override { - return nullptr; - } gpu::SharedImageInterface* SharedImageInterface() override { if (!test_context_provider_) { test_context_provider_ = viz::TestContextProvider::CreateRaster();
diff --git a/cc/tiles/gpu_image_decode_cache_unittest.cc b/cc/tiles/gpu_image_decode_cache_unittest.cc index 22d5e616..7528359 100644 --- a/cc/tiles/gpu_image_decode_cache_unittest.cc +++ b/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -39,6 +39,7 @@ #include "gpu/command_buffer/common/command_buffer_id.h" #include "gpu/command_buffer/common/constants.h" #include "gpu/config/gpu_finch_features.h" +#include "gpu/skia_bindings/gl_bindings_skia_cmd_buffer.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -57,6 +58,8 @@ #include "third_party/skia/include/gpu/ganesh/GrBackendSurface.h" #include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" #include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" +#include "third_party/skia/include/gpu/ganesh/gl/GrGLDirectContext.h" +#include "third_party/skia/include/gpu/ganesh/gl/GrGLInterface.h" using testing::_; using testing::StrictMock; @@ -320,10 +323,16 @@ context_provider_ = GPUImageDecodeTestMockContextProvider::Create( &transfer_cache_helper_, advertise_accelerated_decoding_); context_provider_->BindToCurrentSequence(); + sk_sp<const GrGLInterface> gr_interface = + skia_bindings::CreateGLES2InterfaceBindings( + context_provider_->UnboundTestContextGL(), + context_provider_->ContextSupport()); + gr_context_ = GrDirectContexts::MakeGL(std::move(gr_interface)); + ASSERT_TRUE(!!gr_context_); { viz::RasterContextProvider::ScopedRasterContextLock context_lock( context_provider_.get()); - transfer_cache_helper_.SetGrContext(context_provider_->GrContext()); + transfer_cache_helper_.SetGrContext(gr_context_.get()); max_texture_size_ = context_provider_->ContextCapabilities().max_texture_size; } @@ -609,6 +618,7 @@ // on |transfer_cache_helper_|. TransferCacheTestHelper transfer_cache_helper_; scoped_refptr<GPUImageDecodeTestMockContextProvider> context_provider_; + sk_sp<GrDirectContext> gr_context_; // Only used when |do_yuv_decode_| is true. SkYUVAPixmapInfo::DataType yuv_data_type_ =
diff --git a/chrome/VERSION b/chrome/VERSION index 720c91c5..8c049f7 100644 --- a/chrome/VERSION +++ b/chrome/VERSION
@@ -1,4 +1,4 @@ MAJOR=143 MINOR=0 -BUILD=7461 +BUILD=7462 PATCH=0
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsIphMessageCardViewModel.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsIphMessageCardViewModel.java index 720dc7f..48d2708 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsIphMessageCardViewModel.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/ArchivedTabsIphMessageCardViewModel.java
@@ -4,9 +4,25 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.ACTION_BUTTON_VISIBLE; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.DISMISS_BUTTON_CONTENT_DESCRIPTION; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.ICON_PROVIDER; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.IS_ICON_VISIBLE; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.IS_INCOGNITO; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MESSAGE_CARD_VISIBILITY_CONTROL_IN_REGULAR_AND_INCOGNITO_MODE; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MESSAGE_IDENTIFIER; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MESSAGE_TYPE; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.MessageCardScope.REGULAR; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW; +import static org.chromium.chrome.browser.tasks.tab_management.MessageCardViewProperties.VIEW_AS_ACTION_BUTTON; +import static org.chromium.chrome.browser.tasks.tab_management.MessageService.DEFAULT_MESSAGE_IDENTIFIER; +import static org.chromium.chrome.browser.tasks.tab_management.ResizableMessageCardViewProperties.ALL_KEYS; 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.MESSAGE; +import static org.chromium.chrome.browser.tasks.tab_management.TabSwitcherMessageManager.MessageType.ARCHIVED_TABS_IPH_MESSAGE; import android.content.Context; @@ -37,34 +53,25 @@ String dismissButtonContextDescription = context.getString(R.string.accessibility_tab_suggestion_dismiss_button); - return new PropertyModel.Builder(ResizableMessageCardViewProperties.ALL_KEYS) - .with(MessageCardViewProperties.MESSAGE_TYPE, MessageType.ARCHIVED_TABS_IPH_MESSAGE) + return new PropertyModel.Builder(ALL_KEYS) + .with(MESSAGE_TYPE, ARCHIVED_TABS_IPH_MESSAGE) + .with(MESSAGE_IDENTIFIER, DEFAULT_MESSAGE_IDENTIFIER) .with( - MessageCardViewProperties.MESSAGE_IDENTIFIER, - MessageService.DEFAULT_MESSAGE_IDENTIFIER) - .with( - MessageCardViewProperties.ICON_PROVIDER, + ICON_PROVIDER, (callback) -> { callback.onResult( AppCompatResources.getDrawable( context, R.drawable.archived_tab_icon)); }) - .with( - MessageCardViewProperties.MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER, - serviceDismissActionProvider) - .with(MessageCardViewProperties.MESSAGE_SERVICE_ACTION_PROVIDER, actionProvider) - .with( - MessageCardViewProperties.DISMISS_BUTTON_CONTENT_DESCRIPTION, - dismissButtonContextDescription) - .with(MessageCardViewProperties.VIEW_AS_ACTION_BUTTON, true) - .with(MessageCardViewProperties.ACTION_BUTTON_VISIBLE, false) - .with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, true) - .with(MessageCardViewProperties.IS_ICON_VISIBLE, true) - .with(MessageCardViewProperties.IS_INCOGNITO, false) - .with( - MessageCardViewProperties - .MESSAGE_CARD_VISIBILITY_CONTROL_IN_REGULAR_AND_INCOGNITO_MODE, - MessageCardViewProperties.MessageCardScope.BOTH) + .with(MESSAGE_SERVICE_DISMISS_ACTION_PROVIDER, serviceDismissActionProvider) + .with(MESSAGE_SERVICE_ACTION_PROVIDER, actionProvider) + .with(DISMISS_BUTTON_CONTENT_DESCRIPTION, dismissButtonContextDescription) + .with(VIEW_AS_ACTION_BUTTON, true) + .with(ACTION_BUTTON_VISIBLE, false) + .with(SHOULD_KEEP_AFTER_REVIEW, true) + .with(IS_ICON_VISIBLE, true) + .with(IS_INCOGNITO, false) + .with(MESSAGE_CARD_VISIBILITY_CONTROL_IN_REGULAR_AND_INCOGNITO_MODE, REGULAR) .with(CARD_TYPE, MESSAGE) .with(CARD_ALPHA, 1f) .build();
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageCardViewModel.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageCardViewModel.java index 91d471b..9c9feee3 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageCardViewModel.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageCardViewModel.java
@@ -58,7 +58,7 @@ dismissButtonContextDescription) .with(MessageCardViewProperties.SHOULD_KEEP_AFTER_REVIEW, true) .with(MessageCardViewProperties.IS_ICON_VISIBLE, false) - .with(MessageCardViewProperties.IS_INCOGNITO, false) + .with(MessageCardViewProperties.IS_INCOGNITO, data.isIncognito()) .with( MessageCardViewProperties .MESSAGE_CARD_VISIBILITY_CONTROL_IN_REGULAR_AND_INCOGNITO_MODE,
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageService.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageService.java index 58cbb0a..bd058d2 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageService.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageService.java
@@ -24,12 +24,15 @@ import org.chromium.components.feature_engagement.Tracker; import org.chromium.ui.modelutil.PropertyModel; +import java.util.function.Supplier; + /** One of the concrete {@link MessageService} that only serves {@link MessageType.IPH}. */ @NullMarked public class IphMessageService extends MessageService<@MessageType Integer, @UiType Integer> { private static boolean sSkipIphInTests = true; private final TabSwitcherIphController mIphController; + private final Supplier<Profile> mProfileSupplier; private Tracker mTracker; private final Callback<Boolean> mInitializedCallback = @@ -44,12 +47,15 @@ static class IphMessageData { private final MessageCardView.ActionProvider mAcceptActionProvider; private final MessageCardView.ActionProvider mDismissActionProvider; + private final boolean mIsIncognito; IphMessageData( MessageCardView.ActionProvider acceptActionProvider, - MessageCardView.ActionProvider dismissActionProvider) { + MessageCardView.ActionProvider dismissActionProvider, + boolean isIncognito) { mAcceptActionProvider = acceptActionProvider; mDismissActionProvider = dismissActionProvider; + mIsIncognito = isIncognito; } /** @@ -65,16 +71,22 @@ MessageCardView.ActionProvider getDismissActionProvider() { return mDismissActionProvider; } + + /** Returns whether the message card is to be themed for incognito */ + boolean isIncognito() { + return mIsIncognito; + } } - IphMessageService(Profile profile, TabSwitcherIphController controller) { + IphMessageService(Supplier<Profile> profileSupplier, TabSwitcherIphController controller) { super( MessageType.IPH, UiType.IPH_MESSAGE, R.layout.tab_grid_message_card_item, MessageCardViewBinder::bind); mIphController = controller; - mTracker = TrackerFactory.getTrackerForProfile(profile); + mTracker = TrackerFactory.getTrackerForProfile(profileSupplier.get()); + mProfileSupplier = profileSupplier; } @VisibleForTesting @@ -124,7 +136,10 @@ private PropertyModel buildModel( Context context, ServiceDismissActionProvider<@MessageType Integer> serviceActionProvider) { + boolean isIncognito = mProfileSupplier.get().isIncognitoBranded(); return IphMessageCardViewModel.create( - context, serviceActionProvider, new IphMessageData(this::review, this::dismiss)); + context, + serviceActionProvider, + new IphMessageData(this::review, this::dismiss, isIncognito)); } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderCoordinator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderCoordinator.java index c1428580..19a833b4 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderCoordinator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderCoordinator.java
@@ -8,12 +8,10 @@ import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; -import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tasks.tab_management.MessageCardView.ServiceDismissActionProvider; import org.chromium.chrome.browser.tasks.tab_management.MessageService.Message; import java.util.List; -import java.util.function.Supplier; /** * This is the coordinator for MessageCardProvider component. This component is used to build a @@ -29,12 +27,8 @@ private @Nullable MessageHostDelegate<MessageT, UiT> mMessageHostDelegate; MessageCardProviderCoordinator( - Context context, - Supplier<Profile> profileSupplier, - ServiceDismissActionProvider<MessageT> serviceDismissActionProvider) { - mMediator = - new MessageCardProviderMediator<>( - context, profileSupplier, serviceDismissActionProvider); + Context context, ServiceDismissActionProvider<MessageT> serviceDismissActionProvider) { + mMediator = new MessageCardProviderMediator<>(context, serviceDismissActionProvider); } /**
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediator.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediator.java index 8712a4f..2fa672e 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediator.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediator.java
@@ -10,7 +10,6 @@ import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; -import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tasks.tab_management.MessageCardView.ServiceDismissActionProvider; import org.chromium.chrome.browser.tasks.tab_management.MessageService.Message; import org.chromium.chrome.browser.tasks.tab_management.MessageService.MessageModelFactory; @@ -21,7 +20,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.function.Supplier; /** * This is a {@link MessageObserver} that creates and owns different {@link PropertyModel} based on @@ -33,16 +31,12 @@ @NullMarked public class MessageCardProviderMediator<MessageT, UiT> implements MessageObserver<MessageT> { private final Context mContext; - private final Supplier<Profile> mProfileSupplier; private final ServiceDismissActionProvider<MessageT> mServiceDismissActionProvider; private final Map<MessageT, MessageService<MessageT, UiT>> mMessageServices = new HashMap<>(); public MessageCardProviderMediator( - Context context, - Supplier<Profile> profileSupplier, - ServiceDismissActionProvider<MessageT> serviceDismissActionProvider) { + Context context, ServiceDismissActionProvider<MessageT> serviceDismissActionProvider) { mContext = context; - mProfileSupplier = profileSupplier; mServiceDismissActionProvider = serviceDismissActionProvider; } @@ -55,13 +49,7 @@ public @Nullable Message<MessageT> getNextMessageItemForType(MessageT messageType) { MessageService<MessageT, UiT> service = mMessageServices.get(messageType); if (service == null) return null; - - Message<MessageT> message = service.getNextMessageItem(); - if (message == null) return null; - - PropertyModel model = message.model; - maybeSetCardIncognitoStatus(model); - return message; + return service.getNextMessageItem(); } /** @@ -82,7 +70,6 @@ if (service == null) return; PropertyModel model = factory.build(mContext, this::invalidateShownMessage); - maybeSetCardIncognitoStatus(model); service.addMessage(new Message<>(type, model)); } @@ -131,12 +118,4 @@ Map<MessageT, MessageService<MessageT, UiT>> getMessageServicesMap() { return mMessageServices; } - - private void maybeSetCardIncognitoStatus(PropertyModel model) { - if (model.containsKey(MessageCardViewProperties.IS_INCOGNITO)) { - model.set( - MessageCardViewProperties.IS_INCOGNITO, - mProfileSupplier.get().isOffTheRecord()); - } - } }
diff --git a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMessageManager.java b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMessageManager.java index e34589d..861afabf 100644 --- a/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMessageManager.java +++ b/chrome/android/features/tab_ui/java/src/org/chromium/chrome/browser/tasks/tab_management/TabSwitcherMessageManager.java
@@ -231,16 +231,9 @@ mDesktopWindowStateManager = desktopWindowStateManager; mLayoutStateProviderSupplier = layoutStateProviderSupplier; - Supplier<Profile> profileSupplier = - () -> { - TabGroupModelFilter tabGroupModelFilter = - mCurrentTabGroupModelFilterSupplier.get(); - assumeNonNull(tabGroupModelFilter); - return assumeNonNull(tabGroupModelFilter.getTabModel().getProfile()); - }; mMessageCardProviderCoordinator = new MessageCardProviderCoordinator<@MessageType Integer, @UiType Integer>( - activity, profileSupplier, this::dismissHandler); + activity, this::dismissHandler); mTabGridIphDialogCoordinator = new TabGridIphDialogCoordinator(activity, mModalDialogManager); @@ -345,7 +338,7 @@ mMessageCardProviderCoordinator.subscribeMessageService(mArchivedTabsMessageService); IphMessageService iphMessageService = - new IphMessageService(profile, mTabGridIphDialogCoordinator); + new IphMessageService(this::getCurrentProfile, mTabGridIphDialogCoordinator); mMessageCardProviderCoordinator.subscribeMessageService(iphMessageService); if (IncognitoReauthManager.isIncognitoReauthFeatureAvailable() @@ -598,9 +591,7 @@ if (!shouldShowMessages()) return; TabListCoordinator tabListCoordinator = mTabListCoordinatorSupplier.get(); assert tabListCoordinator != null; - - assert assumeNonNull(mCurrentTabGroupModelFilterSupplier.get()).getTabModel().getProfile() - != null; + assert getCurrentProfile() != null; sAppendedMessagesForTesting = false; List<MessageService<@MessageType Integer, @UiType Integer>> messageServices = @@ -714,4 +705,10 @@ removeAllAppendedMessage(); } } + + private Profile getCurrentProfile() { + TabGroupModelFilter tabGroupModelFilter = mCurrentTabGroupModelFilterSupplier.get(); + assumeNonNull(tabGroupModelFilter); + return assumeNonNull(tabGroupModelFilter.getTabModel().getProfile()); + } }
diff --git a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderTest.java b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderTest.java index d5d12523..426ba45 100644 --- a/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderTest.java +++ b/chrome/android/features/tab_ui/javatests/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderTest.java
@@ -157,7 +157,7 @@ mCoordinator = new MessageCardProviderCoordinator<>( - sActivity, () -> mProfile, mServiceDismissActionProvider); + sActivity, mServiceDismissActionProvider); mCoordinator.subscribeMessageService(mTestingService); mCoordinator.subscribeMessageService(mPriceService); });
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageServiceUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageServiceUnitTest.java index b6b3925..4dd2052 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageServiceUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/IphMessageServiceUnitTest.java
@@ -4,13 +4,13 @@ package org.chromium.chrome.browser.tasks.tab_management; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -49,7 +49,7 @@ public void setUp() { IphMessageService.setSkipIphInTestsForTesting(false); TrackerFactory.setTrackerForTests(mTracker); - mIphMessageService = new IphMessageService(mProfile, mIphController); + mIphMessageService = new IphMessageService(() -> mProfile, mIphController); } @Test @@ -70,8 +70,7 @@ public void testAddObserver_NotInitialized() { doReturn(false).when(mTracker).isInitialized(); mIphMessageService.addObserver(mMessageObserver); - Assert.assertTrue( - mIphMessageService.getObserversForTesting().hasObserver(mMessageObserver)); + assertTrue(mIphMessageService.getObserversForTesting().hasObserver(mMessageObserver)); verify(mTracker, times(1)) .addOnInitializedCallback(mIphMessageService.getInitializedCallbackForTesting()); } @@ -83,8 +82,7 @@ .wouldTriggerHelpUi(eq(FeatureConstants.TAB_GROUPS_DRAG_AND_DROP_FEATURE)); doReturn(true).when(mTracker).isInitialized(); mIphMessageService.addObserver(mMessageObserver); - Assert.assertTrue( - mIphMessageService.getObserversForTesting().hasObserver(mMessageObserver)); + assertTrue(mIphMessageService.getObserversForTesting().hasObserver(mMessageObserver)); verify(mMessageObserver, times(1)).messageReady(eq(MessageType.IPH), any()); }
diff --git a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediatorUnitTest.java b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediatorUnitTest.java index 6c86f3f..d331bc57 100644 --- a/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediatorUnitTest.java +++ b/chrome/android/features/tab_ui/junit/src/org/chromium/chrome/browser/tasks/tab_management/MessageCardProviderMediatorUnitTest.java
@@ -5,10 +5,13 @@ package org.chromium.chrome.browser.tasks.tab_management; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -29,7 +32,6 @@ import org.chromium.base.test.BaseRobolectricTestRunner; import org.chromium.chrome.browser.price_tracking.PriceDropNotificationManagerImpl; -import org.chromium.chrome.browser.profiles.Profile; import org.chromium.chrome.browser.tasks.tab_management.MessageCardView.ServiceDismissActionProvider; import org.chromium.chrome.browser.tasks.tab_management.MessageService.Message; import org.chromium.chrome.browser.tasks.tab_management.PriceMessageService.PriceMessageType; @@ -38,7 +40,6 @@ import org.chromium.ui.modelutil.PropertyModel; import java.util.List; -import java.util.function.Supplier; /** Unit tests for {@link MessageCardProviderMediator}. */ @RunWith(BaseRobolectricTestRunner.class) @@ -55,13 +56,8 @@ @Mock private Resources mResourcesMock; - @Mock private Profile mProfileMock; - @Mock private Profile mIncognitoProfileMock; - @Mock private PriceMessageService.PriceMessageData mPriceMessageData; - @Mock private Supplier<Profile> mProfileSupplier; - @Mock private IphMessageService.IphMessageData mIphMessageData; @Mock @@ -70,13 +66,8 @@ @Before public void setUp() { - - doReturn(true).when(mIncognitoProfileMock).isOffTheRecord(); - doReturn(mProfileMock).when(mProfileSupplier).get(); doNothing().when(mServiceDismissActionProvider).dismiss(anyInt()); - mMediator = - new MessageCardProviderMediator<>( - mContext, mProfileSupplier, mServiceDismissActionProvider); + mMediator = new MessageCardProviderMediator<>(mContext, mServiceDismissActionProvider); mMediator.addMessageService(initService(MessageType.FOR_TESTING)); mMediator.addMessageService(initService(MessageType.PRICE_MESSAGE)); mMediator.addMessageService(initService(MessageType.IPH)); @@ -97,7 +88,7 @@ a, b, mPriceMessageData, - new PriceDropNotificationManagerImpl(mProfileMock))); + new PriceDropNotificationManagerImpl(mock()))); break; case MessageType.IPH: when(mIphMessageData.getDismissActionProvider()).thenReturn(() -> {}); @@ -124,7 +115,7 @@ enqueueMessageItem(MessageType.FOR_TESTING, TESTING_ACTION); assertNotNull(mMediator.getNextMessageItemForType(MessageType.FOR_TESTING)); - Assert.assertTrue(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); + assertTrue(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); assertNotNull(getShownMessageFromService(MessageType.FOR_TESTING)); } @@ -133,14 +124,14 @@ enqueueMessageItem(MessageType.PRICE_MESSAGE, -1); assertNotNull(mMediator.getNextMessageItemForType(MessageType.PRICE_MESSAGE)); - Assert.assertTrue(getMessageItemsForService(MessageType.PRICE_MESSAGE).isEmpty()); + assertTrue(getMessageItemsForService(MessageType.PRICE_MESSAGE).isEmpty()); assertNotNull(getShownMessageFromService(MessageType.PRICE_MESSAGE)); enqueueMessageItem(MessageType.FOR_TESTING, TESTING_ACTION); assertNotNull(mMediator.getNextMessageItemForType(MessageType.PRICE_MESSAGE)); assertNotNull(mMediator.getNextMessageItemForType(MessageType.FOR_TESTING)); - Assert.assertTrue(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); + assertTrue(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); assertNotNull(getShownMessageFromService(MessageType.FOR_TESTING)); } @@ -243,7 +234,7 @@ mMediator.messageInvalidate(MessageType.PRICE_MESSAGE); Assert.assertNull(getShownMessageFromService(MessageType.PRICE_MESSAGE)); - Assert.assertTrue(getMessageItemsForService(MessageType.PRICE_MESSAGE).isEmpty()); + assertTrue(getMessageItemsForService(MessageType.PRICE_MESSAGE).isEmpty()); // Testing multiple Messages has the same type. enqueueMessageItem(MessageType.FOR_TESTING, TESTING_ACTION); @@ -251,7 +242,7 @@ mMediator.messageInvalidate(MessageType.FOR_TESTING); Assert.assertNull(getShownMessageFromService(MessageType.FOR_TESTING)); - Assert.assertTrue(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); + assertTrue(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); } @Test @@ -263,7 +254,7 @@ verify(mServiceDismissActionProvider).dismiss(anyInt()); Assert.assertNull(getShownMessageFromService(MessageType.PRICE_MESSAGE)); - Assert.assertTrue(getMessageItemsForService(MessageType.PRICE_MESSAGE).isEmpty()); + assertTrue(getMessageItemsForService(MessageType.PRICE_MESSAGE).isEmpty()); // Testing multiple Messages has the same type. enqueueMessageItem(MessageType.FOR_TESTING, TESTING_ACTION); @@ -272,7 +263,7 @@ mMediator.getNextMessageItemForType(MessageType.FOR_TESTING); mMediator.invalidateShownMessage(MessageType.FOR_TESTING); Assert.assertNull(getShownMessageFromService(MessageType.FOR_TESTING)); - Assert.assertFalse(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); + assertFalse(getMessageItemsForService(MessageType.FOR_TESTING).isEmpty()); } @Test @@ -322,36 +313,15 @@ } @Test - public void getNextMessageItemForTypeTest_UpdateIncognito() { - enqueueMessageItem(MessageType.IPH, -1); - - PropertyModel messageModel = mMediator.getNextMessageItemForType(MessageType.IPH).model; - Assert.assertFalse(messageModel.get(MessageCardViewProperties.IS_INCOGNITO)); - - doReturn(mIncognitoProfileMock).when(mProfileSupplier).get(); - messageModel = mMediator.getNextMessageItemForType(MessageType.IPH).model; - Assert.assertTrue(messageModel.get(MessageCardViewProperties.IS_INCOGNITO)); - } - - @Test - public void getNextMessageItemForTypeTest_UpdateIncognito_NoShownMessage() { - enqueueMessageItem(MessageType.IPH, -1); - - doReturn(mIncognitoProfileMock).when(mProfileSupplier).get(); - PropertyModel messageModel = mMediator.getNextMessageItemForType(MessageType.IPH).model; - Assert.assertTrue(messageModel.get(MessageCardViewProperties.IS_INCOGNITO)); - } - - @Test public void isMessageShownTest() { - Assert.assertFalse( + assertFalse( mMediator.isMessageShown( MessageType.PRICE_MESSAGE, PriceMessageType.PRICE_WELCOME)); enqueueMessageItem(MessageType.PRICE_MESSAGE, -1); // Mock pulling this message, which will move the message from mMessageItems to // mShownMessageItems. mMediator.getNextMessageItemForType(MessageType.PRICE_MESSAGE); - Assert.assertTrue( + assertTrue( mMediator.isMessageShown( MessageType.PRICE_MESSAGE, PriceMessageType.PRICE_WELCOME)); }
diff --git a/chrome/android/java/res/values/ids.xml b/chrome/android/java/res/values/ids.xml index f720733..9bfc863 100644 --- a/chrome/android/java/res/values/ids.xml +++ b/chrome/android/java/res/values/ids.xml
@@ -59,6 +59,7 @@ <item type="id" name="contextmenu_share_page" /> <item type="id" name="contextmenu_print_page" /> <item type="id" name="contextmenu_inspect_element" /> + <item type="id" name="contextmenu_view_page_source" /> <!-- Custom Tab Group --> <item type="id" name="contextmenu_open_in_new_chrome_tab" />
diff --git a/chrome/android/java/res/values/styles.xml b/chrome/android/java/res/values/styles.xml index 90e058e..6fd6594 100644 --- a/chrome/android/java/res/values/styles.xml +++ b/chrome/android/java/res/values/styles.xml
@@ -573,6 +573,8 @@ --> <style name="ModernToolbarPopupTheme"> <item name="android:listChoiceIndicatorSingle">@drawable/checkmark_selection_drawable</item> + <item name="android:itemTextAppearance">@style/TextAppearance.DensityAdaptive.TextLarge.Primary</item> + <item name="listPreferredItemHeightSmall">?attr/listItemHeight</item> </style> <style name="Theme.Chromium.Widget" parent="Theme.BrowserUI.DayNight" />
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java index da41ade8..3dbbc8f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBaseAppCompatActivity.java
@@ -410,9 +410,7 @@ mInsetObserver, EdgeToEdgeUtils.isUseBackupNavbarInsetsEnabled(), EdgeToEdgeFieldTrialImpl.getBackupNavbarInsetsOverrides(), - ChromeFeatureList.sEdgeToEdgeUseBackupNavbarInsetsUseTappable - .getValue(), - ChromeFeatureList.sEdgeToEdgeUseBackupNavbarInsetsUseTappable + ChromeFeatureList.sEdgeToEdgeUseBackupNavbarInsetsUseGestures .getValue()); } return mEdgeToEdgeLayoutCoordinator;
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java index 949e80a..5b280cc 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelper.java
@@ -385,6 +385,7 @@ StripLayoutTab stripTab = findTabById(tab.getId()); assumeNonNull(stripTab); stripTab.setIsPinned(isPinned); + setAccessibilityDescription(stripTab, tab); mPinnedTabCount += isPinned ? 1 : -1; // Compute each view's ideal position to get ready for the tab move animation @@ -729,35 +730,35 @@ NEW_TAB_BUTTON_HOVER_BACKGROUND_PRESSED_OPACITY); // Primary container for default bg color. - int BackgroundDefaultTint = TabUiThemeProvider.getDefaultNtbContainerColor(context); + int backgroundDefaultTint = TabUiThemeProvider.getDefaultNtbContainerColor(context); // Primary @ 20% for default pressed bg color. - int BackgroundPressedTint = + int backgroundPressedTint = ColorUtils.setAlphaComponentWithFloat( SemanticColorUtils.getDefaultIconColorAccent1(context), NEW_TAB_BUTTON_DEFAULT_PRESSED_OPACITY); // gm3_baseline_surface_container_dark for incognito bg color. - int BackgroundIncognitoDefaultTint = + int backgroundIncognitoDefaultTint = context.getColor(R.color.tab_strip_bg_incognito_default_tint); // gm3_baseline_surface_container_highest_dark for incognito pressed bg color - int BackgroundIncognitoPressedTint = + int backgroundIncognitoPressedTint = context.getColor(R.color.tab_strip_bg_incognito_pressed_tint); // Tab strip redesign new tab button night mode bg color. if (ColorUtils.inNightMode(context)) { // colorSurfaceContainerLow for night mode bg color. - BackgroundDefaultTint = SemanticColorUtils.getColorSurfaceContainerLow(context); + backgroundDefaultTint = SemanticColorUtils.getColorSurfaceContainerLow(context); // colorSurfaceContainerHighest for pressed night mode bg color. - BackgroundPressedTint = SemanticColorUtils.getColorSurfaceContainerHighest(context); + backgroundPressedTint = SemanticColorUtils.getColorSurfaceContainerHighest(context); } mNewTabButton.setBackgroundTint( - BackgroundDefaultTint, - BackgroundPressedTint, - BackgroundIncognitoDefaultTint, - BackgroundIncognitoPressedTint, + backgroundDefaultTint, + backgroundPressedTint, + backgroundIncognitoDefaultTint, + backgroundIncognitoPressedTint, apsBackgroundHoveredTint, apsBackgroundPressedTint, apsBackgroundIncognitoHoveredTint,
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java index aabc0a5..cb92de7 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuItem.java
@@ -75,6 +75,7 @@ Item.SAVE_PAGE, Item.SHARE_PAGE, Item.PRINT_PAGE, + Item.VIEW_PAGE_SOURCE, Item.INSPECT_ELEMENT, }) @Retention(RetentionPolicy.SOURCE) @@ -131,9 +132,10 @@ int SHARE_PAGE = 39; int PRINT_PAGE = 40; // Developer Group - int INSPECT_ELEMENT = 41; + int VIEW_PAGE_SOURCE = 41; + int INSPECT_ELEMENT = 42; // ALWAYS UPDATE! - int NUM_ENTRIES = 42; + int NUM_ENTRIES = 43; } /** Mapping from {@link Item} to the ID found in the ids.xml. */ @@ -179,6 +181,7 @@ R.id.contextmenu_save_page, // Item.SAVE_PAGE R.id.contextmenu_share_page, // Item.SHARE_PAGE R.id.contextmenu_print_page, // Item.PRINT_PAGE + R.id.contextmenu_view_page_source, // Item.VIEW_PAGE_SOURCE R.id.contextmenu_inspect_element, // Item.INSPECT_ELEMENT }; @@ -225,6 +228,7 @@ R.string.contextmenu_save_page, // Item.SAVE_PAGE R.string.contextmenu_share_page, // Item.SHARE_PAGE R.string.contextmenu_print_page, // Item.PRINT_PAGE + R.string.contextmenu_view_page_source, // Item.VIEW_PAGE_SOURCE R.string.contextmenu_inspect_element, // Item.INSPECT_ELEMENT };
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java index a0abf7a..e557a03 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java
@@ -177,7 +177,7 @@ static class ContextMenuUma { // Note: these values must match the ContextMenuOptionAndroid enum in enums.xml. // Only add values to the end, right before NUM_ENTRIES! - // LINT.IfChange(Action) + // LINT.IfChange(ContextMenuUma.Action) @IntDef({ Action.OPEN_IN_NEW_TAB, Action.OPEN_IN_INCOGNITO_TAB, @@ -226,6 +226,7 @@ Action.ENTER_PICTURE_IN_PICTURE, Action.EXIT_PICTURE_IN_PICTURE, Action.OPEN_IN_INCOGNITO_WINDOW, + Action.VIEW_PAGE_SOURCE, }) @Retention(RetentionPolicy.SOURCE) public @interface Action { @@ -281,7 +282,8 @@ int ENTER_PICTURE_IN_PICTURE = 49; int EXIT_PICTURE_IN_PICTURE = 50; int OPEN_IN_INCOGNITO_WINDOW = 51; - int NUM_ENTRIES = 52; + int VIEW_PAGE_SOURCE = 52; + int NUM_ENTRIES = 53; } // LINT.ThenChange(/tools/metrics/histograms/enums.xml:ContextMenuOptionAndroid) @@ -424,6 +426,11 @@ && DeviceInput.supportsPrecisionPointer(); } + @VisibleForTesting + boolean shouldShowViewPageSourceMenu() { + return DevToolsWindowAndroid.canViewSource(getProfile(), mItemDelegate.getWebContents()); + } + @Override public List<ModelList> buildContextMenu() { int nextCustomMenuItemId = CUSTOM_MENU_ITEM_ID_START; @@ -714,6 +721,11 @@ if (shouldShowDeveloperMenu()) { ModelList developerGroup = new ModelList(); + if (mParams.isPage() + && shouldShowEmptySpaceContextMenu() + && shouldShowViewPageSourceMenu()) { + developerGroup.add(createListItem(Item.VIEW_PAGE_SOURCE)); + } developerGroup.add(createListItem(Item.INSPECT_ELEMENT)); groupedItems.add(developerGroup); } @@ -1075,6 +1087,9 @@ mParams.getReferrer(), /* navigateToTab= */ true, /* additionalNavigationParams= */ null); + } else if (itemId == R.id.contextmenu_view_page_source) { + recordContextMenuSelection(ContextMenuUma.Action.VIEW_PAGE_SOURCE); + mItemDelegate.getWebContents().getMainFrame().viewSource(); } else if (itemId == R.id.contextmenu_inspect_element) { recordContextMenuSelection(ContextMenuUma.Action.INSPECT_ELEMENT); mNativeDelegate.inspectElement(
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 249736a..f16fd3f 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
@@ -1275,7 +1275,10 @@ mProgressBarCoordinator = new LoadProgressCoordinator( - mActivityTabProvider, mToolbar.getProgressBar(), topControlsStacker); + mActivityTabProvider, + mToolbar.getProgressBar(), + topControlsStacker, + mBrowserControlsSizer); mToolbar.setToolbarColorObserver(statusBarColorController); mActivityTabTabObserver = @@ -1950,7 +1953,8 @@ ? mHomePageButtonsCoordinator : mHomeButtonCoordinator, mExtensionToolbarCoordinator, - topControlsStacker); + topControlsStacker, + mBrowserControlsSizer); mHomepageStateListener = () -> {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java index 48fea35..10b6f83 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulatorTest.java
@@ -166,27 +166,29 @@ } private void initializePopulator(@ContextMenuMode int mode, ContextMenuParams params) { - initializePopulator(mode, params, false, true); - } - - private void initializePopulator( - @ContextMenuMode int mode, ContextMenuParams params, boolean shouldShowDeveloperMenu) { - initializePopulator(mode, params, shouldShowDeveloperMenu, true); + initializePopulator(mode, params, false, false, true); } private void initializePopulator( @ContextMenuMode int mode, ContextMenuParams params, boolean shouldShowDeveloperMenu, + boolean shouldShowViewPageSourceMenu, boolean supportPrint) { - initializePopulator(mode, params, List.of(), shouldShowDeveloperMenu, supportPrint); + initializePopulator( + mode, + params, + List.of(), + shouldShowDeveloperMenu, + shouldShowViewPageSourceMenu, + supportPrint); } private void initializePopulator( @ContextMenuMode int mode, ContextMenuParams params, List<CustomContentAction> actions) { - initializePopulator(mode, params, actions, false, true); + initializePopulator(mode, params, actions, false, false, true); } private void initializePopulator( @@ -194,6 +196,7 @@ ContextMenuParams params, List<CustomContentAction> actions, boolean shouldShowDeveloperMenu, + boolean shouldShowViewPageSourceMenu, boolean supportPrint) { mPopulator = Mockito.spy( @@ -211,6 +214,7 @@ doReturn(true).when(mPopulator).shouldShowEmptySpaceContextMenu(); doReturn(true).when(mExternalAuthUtils).isGoogleSigned(IntentHandler.PACKAGE_GSA); doReturn(shouldShowDeveloperMenu).when(mPopulator).shouldShowDeveloperMenu(); + doReturn(shouldShowViewPageSourceMenu).when(mPopulator).shouldShowViewPageSourceMenu(); doReturn(supportPrint).when(mItemDelegate).isPrintSupported(); } @@ -398,7 +402,8 @@ }; checkMenuOptions(expected5); - initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true); + initializePopulator( + ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true, false, true); int[] expected6Tab1 = { R.id.contextmenu_open_in_new_tab, R.id.contextmenu_open_in_new_tab_in_group, @@ -902,7 +907,8 @@ }; checkMenuOptions(expected5Tab1, expected2Tab2); - initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true); + initializePopulator( + ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true, false, true); int[] expected6Tab1 = { R.id.contextmenu_open_in_new_tab, R.id.contextmenu_open_in_new_tab_in_group, @@ -1152,7 +1158,8 @@ }; checkMenuOptions(expected5); - initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true); + initializePopulator( + ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true, false, true); int[] expected2Tab1 = { R.id.contextmenu_open_image_in_new_tab, R.id.contextmenu_open_image_in_ephemeral_tab, @@ -1843,20 +1850,27 @@ int[][] expected = { {R.id.contextmenu_save_page, R.id.contextmenu_share_page, R.id.contextmenu_print_page}, - {R.id.contextmenu_inspect_element}, + {R.id.contextmenu_view_page_source, R.id.contextmenu_inspect_element}, }; - initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true); - checkMenuOptions(expected); - - initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params, true); - checkMenuOptions(expected); - - initializePopulator(ChromeContextMenuPopulator.ContextMenuMode.WEB_APP, params, true); + initializePopulator( + ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, true, true, true); checkMenuOptions(expected); initializePopulator( - ChromeContextMenuPopulator.ContextMenuMode.NETWORK_BOUND_TAB, params, true); + ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params, true, true, true); + checkMenuOptions(expected); + + initializePopulator( + ChromeContextMenuPopulator.ContextMenuMode.WEB_APP, params, true, true, true); + checkMenuOptions(expected); + + initializePopulator( + ChromeContextMenuPopulator.ContextMenuMode.NETWORK_BOUND_TAB, + params, + true, + true, + true); checkMenuOptions(expected); } @@ -1938,19 +1952,23 @@ }; initializePopulator( - ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, false, false); + ChromeContextMenuPopulator.ContextMenuMode.NORMAL, params, false, false, false); checkMenuOptions(expected); initializePopulator( - ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params, false, false); + ChromeContextMenuPopulator.ContextMenuMode.CUSTOM_TAB, params, false, false, false); checkMenuOptions(expected); initializePopulator( - ChromeContextMenuPopulator.ContextMenuMode.WEB_APP, params, false, false); + ChromeContextMenuPopulator.ContextMenuMode.WEB_APP, params, false, false, false); checkMenuOptions(expected); initializePopulator( - ChromeContextMenuPopulator.ContextMenuMode.NETWORK_BOUND_TAB, params, false, false); + ChromeContextMenuPopulator.ContextMenuMode.NETWORK_BOUND_TAB, + params, + false, + false, + false); checkMenuOptions(expected); }
diff --git a/chrome/browser/BUILD.gn b/chrome/browser/BUILD.gn index ee59bdc..0034af19 100644 --- a/chrome/browser/BUILD.gn +++ b/chrome/browser/BUILD.gn
@@ -2171,6 +2171,7 @@ "//components/custom_handlers", "//components/data_sharing/internal", "//components/data_sharing/internal:personal_collaboration_data_internal", + "//components/data_sharing/migration/internal", "//components/data_sharing/public", "//components/data_sharing/public:personal_collaboration_data", "//components/device_event_log", @@ -7137,6 +7138,9 @@ "shutdown_signal_handlers_posix.cc", "shutdown_signal_handlers_posix.h", ] + if (!is_mac) { + deps += [ "//components/os_crypt/async/browser:posix_key_provider" ] + } } if (is_win || is_linux || is_chromeos) {
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 47fa197..2e8b681 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -13311,6 +13311,13 @@ flag_descriptions::kPasskeyUnlockErrorUiDescription, kOsDesktop, FEATURE_VALUE_TYPE(device::kPasskeyUnlockErrorUi)}, #endif + +#if BUILDFLAG(IS_CHROMEOS) + {"vids-app-preinstall", flag_descriptions::kVidsAppPreinstallName, + flag_descriptions::kVidsAppPreinstallDescription, kOsCrOS, + FEATURE_VALUE_TYPE(chromeos::features::kVidsAppPreinstall)}, +#endif + // Add new entries above this line. // NOTE: Adding a new flag requires adding a corresponding entry to enum
diff --git a/chrome/browser/ai/ai_context_bound_object_set.cc b/chrome/browser/ai/ai_context_bound_object_set.cc index 67a293a..5f81c24de 100644 --- a/chrome/browser/ai/ai_context_bound_object_set.cc +++ b/chrome/browser/ai/ai_context_bound_object_set.cc
@@ -30,6 +30,6 @@ } } -size_t AIContextBoundObjectSet::GetSizeForTesting() { +size_t AIContextBoundObjectSet::GetSize() const { return context_bound_object_set_.size(); }
diff --git a/chrome/browser/ai/ai_context_bound_object_set.h b/chrome/browser/ai/ai_context_bound_object_set.h index efd70c6..b79bd5b7 100644 --- a/chrome/browser/ai/ai_context_bound_object_set.h +++ b/chrome/browser/ai/ai_context_bound_object_set.h
@@ -21,8 +21,8 @@ // Add an `AIContextBoundObject` into the set. void AddContextBoundObject(std::unique_ptr<AIContextBoundObject> object); - // Returns the size of user data set for testing purpose. - size_t GetSizeForTesting(); + // Returns the size of set. + size_t GetSize() const; // Remove the `AIContextBoundObject` from the set. void RemoveContextBoundObject(AIContextBoundObject* object);
diff --git a/chrome/browser/ai/ai_manager.cc b/chrome/browser/ai/ai_manager.cc index e8d31c2..9569841 100644 --- a/chrome/browser/ai/ai_manager.cc +++ b/chrome/browser/ai/ai_manager.cc
@@ -864,8 +864,13 @@ // the reason. if (eligibility != optimization_guide::OnDeviceModelEligibilityReason::kSuccess) { + // If context_bound_object_set_ size or model_download_progress_manager_ + // reporters are non-zero, it implies that a download is pending. + // TODO(crbug.com/444320307): Make this more robust by actually checking + // opt-guide download status. bool is_downloading = - model_download_progress_manager_.GetNumberOfReporters() >= 1; + model_download_progress_manager_.GetNumberOfReporters() >= 1 || + context_bound_object_set_.GetSize() >= 1; std::move(callback).Run( ConvertOnDeviceModelEligibilityReasonToModelAvailabilityCheckResult( eligibility, is_downloading));
diff --git a/chrome/browser/ai/ai_manager.h b/chrome/browser/ai/ai_manager.h index 8e506eb..d92bc72 100644 --- a/chrome/browser/ai/ai_manager.h +++ b/chrome/browser/ai/ai_manager.h
@@ -62,7 +62,7 @@ void AddReceiver(mojo::PendingReceiver<blink::mojom::AIManager> receiver); size_t GetContextBoundObjectSetSizeForTesting() { - return context_bound_object_set_.GetSizeForTesting(); + return context_bound_object_set_.GetSize(); } size_t GetDownloadProgressObserversSizeForTesting() {
diff --git a/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.cc b/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.cc index ef868ee..18d050d 100644 --- a/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.cc +++ b/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.cc
@@ -71,9 +71,9 @@ } void SensitivityPersistedTabDataAndroid::OnPageContentAnnotated( - const GURL& url, + const page_content_annotations::HistoryVisit& visit, const page_content_annotations::PageContentAnnotationsResult& result) { - if (tab_->GetURL() != url) { + if (tab_->GetURL() != visit.url) { return; } set_sensitivity_score(result.GetContentVisibilityScore());
diff --git a/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.h b/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.h index 84a206f..6e6a792 100644 --- a/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.h +++ b/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android.h
@@ -43,7 +43,7 @@ // page_content_annotations::PageContentAnnotationsService::PageContentAnnotationsObserver void OnPageContentAnnotated( - const GURL& url, + const page_content_annotations::HistoryVisit& visit, const page_content_annotations::PageContentAnnotationsResult& result) override;
diff --git a/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android_browsertest.cc b/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android_browsertest.cc index e3a6e7c..ce86dd69 100644 --- a/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android_browsertest.cc +++ b/chrome/browser/android/persisted_tab_data/sensitivity_persisted_tab_data_android_browsertest.cc
@@ -18,6 +18,7 @@ #include "url/gurl.h" namespace { +using page_content_annotations::HistoryVisit; const char kSensitiveRelUrl[] = "/android/sensitive.html"; const char kNonSensitiveRelUrl[] = "/android/hello.html"; const char kNonSensitiveRelUrl2[] = "/android/second.html"; @@ -166,7 +167,8 @@ EXPECT_EQ(tab_android->GetURL().spec(), sensitive_url.spec()); - sptda->OnPageContentAnnotated(sensitive_url, kSensitiveResult); + sptda->OnPageContentAnnotated(HistoryVisit({}, sensitive_url), + kSensitiveResult); EXPECT_TRUE(sptda->is_sensitive()); EXPECT_FLOAT_EQ(0.1, sptda->sensitivity_score()); } @@ -183,7 +185,8 @@ new SensitivityPersistedTabDataAndroid(tab_android); EXPECT_EQ(tab_android->GetURL().spec(), non_sensitive_url.spec()); - sptda->OnPageContentAnnotated(non_sensitive_url, kNonSensitiveResult); + sptda->OnPageContentAnnotated(HistoryVisit({}, non_sensitive_url), + kNonSensitiveResult); EXPECT_FALSE(sptda->is_sensitive()); EXPECT_FLOAT_EQ(0.7, sptda->sensitivity_score()); } @@ -207,9 +210,12 @@ EXPECT_EQ(tab_android->GetURL().spec(), sensitive_url.spec()); // Annotate both sensitive and non-sensitive tabs - sptda->OnPageContentAnnotated(non_sensitive_url, kNonSensitiveResult); - sptda->OnPageContentAnnotated(sensitive_url, kSensitiveResult); - sptda->OnPageContentAnnotated(non_sensitive_url2, kNonSensitiveResult2); + sptda->OnPageContentAnnotated(HistoryVisit({}, non_sensitive_url), + kNonSensitiveResult); + sptda->OnPageContentAnnotated(HistoryVisit({}, sensitive_url), + kSensitiveResult); + sptda->OnPageContentAnnotated(HistoryVisit({}, non_sensitive_url2), + kNonSensitiveResult2); tab_android->SetUserData(SensitivityPersistedTabDataAndroid::UserDataKey(), nullptr);
diff --git a/chrome/browser/android/tab_storage_packager_android.cc b/chrome/browser/android/tab_storage_packager_android.cc index ba6b30a1..5d5f8730 100644 --- a/chrome/browser/android/tab_storage_packager_android.cc +++ b/chrome/browser/android/tab_storage_packager_android.cc
@@ -13,8 +13,7 @@ #include "base/token.h" #include "chrome/browser/android/tab_android.h" #include "chrome/browser/tab/android_tab_package.h" -#include "chrome/browser/tab/collection_storage_package.h" -#include "chrome/browser/tab/storage_id_mapping.h" +#include "chrome/browser/tab/storage_package.h" #include "chrome/browser/tab/tab_storage_package.h" #include "chrome/browser/tab/tab_storage_packager.h" #include "components/tabs/public/direct_child_walker.h" @@ -31,40 +30,12 @@ Java_TabStoragePackager_create(env, reinterpret_cast<intptr_t>(this))); } -void TabStoragePackagerAndroid::Package(const TabInterface* tab) { +std::unique_ptr<StoragePackage> TabStoragePackagerAndroid::Package( + const TabInterface* tab) { JNIEnv* env = base::android::AttachCurrentThread(); Java_TabStoragePackager_packageTab(env, java_obj_, static_cast<const TabAndroid*>(tab)); -} - -void TabStoragePackagerAndroid::Package(const TabCollection* collection, - StorageIdMapping& mapping) { - tabs_pb::Children children_proto; - class ChildProcessor : public DirectChildWalker::Processor { - public: - ChildProcessor(tabs_pb::Children& children_proto, StorageIdMapping& mapping) - : children_proto_(children_proto), mapping_(mapping) {} - - void ProcessTab(const TabInterface* tab) override { - children_proto_->add_storage_id(mapping_->GetStorageId(tab)); - } - void ProcessCollection(const TabCollection* collection) override { - children_proto_->add_storage_id(mapping_->GetStorageId(collection)); - } - - private: - raw_ref<tabs_pb::Children> children_proto_; - raw_ref<StorageIdMapping> mapping_; - }; - - ChildProcessor processor(children_proto, mapping); - DirectChildWalker walker(collection, &processor); - walker.Walk(); - - // TODO(https://crbug.com/448875689): Fill this package with collection - // specific data. - package_ = - std::make_unique<CollectionStoragePackage>(std::move(children_proto)); + return ReleasePackage(); } void TabStoragePackagerAndroid::ConsolidatePackageData(
diff --git a/chrome/browser/android/tab_storage_packager_android.h b/chrome/browser/android/tab_storage_packager_android.h index 495f499..eb6e1d7b 100644 --- a/chrome/browser/android/tab_storage_packager_android.h +++ b/chrome/browser/android/tab_storage_packager_android.h
@@ -15,10 +15,8 @@ #include "components/tabs/public/tab_interface.h" namespace tabs { -class StorageIdMapping; class StoragePackage; class TabInterface; -class TabCollection; // This class is the Android implementation of the TabStoragePackager. class TabStoragePackagerAndroid : public TabStoragePackager { @@ -30,11 +28,8 @@ TabStoragePackagerAndroid& operator=(const TabStoragePackagerAndroid&) = delete; - // TabStoragePackager overrides: - void Package(const TabInterface* tab) override; - void Package(const TabCollection* collection, - StorageIdMapping& mapping) override; - std::unique_ptr<StoragePackage> ReleasePackage() override; + // TabStoragePackager override: + std::unique_ptr<StoragePackage> Package(const TabInterface* tab) override; void ConsolidatePackageData( JNIEnv* env, @@ -48,9 +43,11 @@ base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); private: - std::unique_ptr<StoragePackage> package_; + std::unique_ptr<StoragePackage> ReleasePackage(); + // A reference to the Java version of this class. base::android::ScopedJavaGlobalRef<jobject> java_obj_; + std::unique_ptr<StoragePackage> package_; }; } // namespace tabs
diff --git a/chrome/browser/ash/app_mode/kiosk_troubleshooting_tools_browsertest.cc b/chrome/browser/ash/app_mode/kiosk_troubleshooting_tools_browsertest.cc index 119cbef..6fe92f6 100644 --- a/chrome/browser/ash/app_mode/kiosk_troubleshooting_tools_browsertest.cc +++ b/chrome/browser/ash/app_mode/kiosk_troubleshooting_tools_browsertest.cc
@@ -69,8 +69,9 @@ MixinBasedInProcessBrowserTest::SetUpOnMainThread(); event_generator_ = std::make_unique<ui::test::EventGenerator>( ash::Shell::Get()->GetPrimaryRootWindow()); + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(WaitKioskLaunched()); - SelectFirstBrowser(); + SetBrowser(browser_created_observer.Wait()); ExpectOnlyKioskAppOpen(); }
diff --git a/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc b/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc index d6e9d4f..1848638 100644 --- a/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc +++ b/chrome/browser/ash/app_mode/test/kiosk_iwa_device_attributes_browsertest.cc
@@ -23,6 +23,7 @@ #include "chrome/browser/web_applications/isolated_web_apps/test/isolated_web_app_builder.h" #include "chrome/browser/web_applications/isolated_web_apps/test/isolated_web_app_test_update_server.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "chromeos/ash/components/settings/cros_settings_names.h" #include "chromeos/ash/components/system/fake_statistics_provider.h" #include "chromeos/ash/components/system/statistics_provider.h" @@ -237,9 +238,10 @@ void LaunchIwaKiosk() { ASSERT_TRUE(LaunchAppManually(TheKioskApp())); + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(WaitKioskLaunched()); + SetBrowser(browser_created_observer.Wait()); - SelectFirstBrowser(); ASSERT_NE(web_contents(), nullptr); ASSERT_EQ(web_contents()->GetVisibleURL(), kAppOrigin.GetURL()); ASSERT_TRUE(WaitForLoadStop(web_contents()));
diff --git a/chrome/browser/ash/app_mode/test/kiosk_iwa_permissions_browsertest.cc b/chrome/browser/ash/app_mode/test/kiosk_iwa_permissions_browsertest.cc index 78b5c0b..9b8b4cb 100644 --- a/chrome/browser/ash/app_mode/test/kiosk_iwa_permissions_browsertest.cc +++ b/chrome/browser/ash/app_mode/test/kiosk_iwa_permissions_browsertest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/web_applications/isolated_web_apps/test/isolated_web_app_builder.h" #include "chrome/browser/web_applications/isolated_web_apps/test/isolated_web_app_test_update_server.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/web_package/signed_web_bundles/signed_web_bundle_id.h" #include "components/web_package/test_support/signed_web_bundles/key_pair.h" #include "components/webapps/isolated_web_apps/scheme.h" @@ -179,10 +180,10 @@ void SetUpOnMainThread() override { MixinBasedInProcessBrowserTest::SetUpOnMainThread(); - + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(WaitKioskLaunched()); + SetBrowser(browser_created_observer.Wait()); - SelectFirstBrowser(); ASSERT_NE(web_contents(), nullptr); ASSERT_EQ(web_contents()->GetVisibleURL(), kExpectedOrigin.GetURL()); WaitForPageLoad(web_contents());
diff --git a/chrome/browser/ash/crosapi/vpn_service_ash.cc b/chrome/browser/ash/crosapi/vpn_service_ash.cc index b411c64..886a6c70 100644 --- a/chrome/browser/ash/crosapi/vpn_service_ash.cc +++ b/chrome/browser/ash/crosapi/vpn_service_ash.cc
@@ -36,12 +36,6 @@ std::move(callback).Run(nullptr); } -void RunWarningCallback( - crosapi::VpnServiceForExtensionAsh::SuccessCallback callback, - const std::string& /*warning*/) { - std::move(callback).Run(); -} - void RunFailureCallback(SuccessOrFailureCallback callback, const std::string& error_name, const std::string& error_message) { @@ -264,60 +258,6 @@ weak_factory_.GetWeakPtr(), std::move(failure))); } -void VpnServiceForExtensionAsh::SetParameters(base::Value::Dict parameters, - SetParametersCallback callback) { - if (!OwnsActiveConfiguration()) { - RunFailureCallback(std::move(callback), /*error_name=*/{}, - "Unauthorized access."); - return; - } - - auto [success, failure] = AdaptCallback(std::move(callback)); - ash::ShillThirdPartyVpnDriverClient::Get()->SetParameters( - active_configuration_->object_path(), std::move(parameters), - base::BindOnce(&RunWarningCallback, std::move(success)), - std::move(failure)); -} - -void VpnServiceForExtensionAsh::SendPacket(const std::vector<uint8_t>& data, - SendPacketCallback callback) { - if (!OwnsActiveConfiguration()) { - RunFailureCallback(std::move(callback), /*error_name=*/{}, - "Unauthorized access."); - return; - } - - if (data.empty()) { - RunFailureCallback(std::move(callback), /*error_name=*/{}, - "Can't send an empty packet."); - return; - } - - auto [success, failure] = AdaptCallback(std::move(callback)); - ash::ShillThirdPartyVpnDriverClient::Get()->SendPacket( - active_configuration_->object_path(), - std::vector<char>(data.begin(), data.end()), std::move(success), - std::move(failure)); -} - -void VpnServiceForExtensionAsh::NotifyConnectionStateChanged( - bool connection_success, - NotifyConnectionStateChangedCallback callback) { - if (!OwnsActiveConfiguration()) { - RunFailureCallback(std::move(callback), /*error_name=*/{}, - "Unauthorized access."); - return; - } - - auto [success, failure] = AdaptCallback(std::move(callback)); - ash::ShillThirdPartyVpnDriverClient::Get()->UpdateConnectionState( - active_configuration_->object_path(), - connection_success - ? base::to_underlying(api_vpn::VpnConnectionState::kConnected) - : base::to_underlying(api_vpn::VpnConnectionState::kFailure), - std::move(success), std::move(failure)); -} - void VpnServiceForExtensionAsh::BindPepperVpnProxyObserver( const std::string& configuration_name, mojo::PendingRemote<crosapi::mojom::PepperVpnProxyObserver> @@ -376,6 +316,14 @@ DestroyConfigurationInternal(configuration); } +std::optional<std::string> +VpnServiceForExtensionAsh::GetActiveConfigurationObjectPath() const { + if (active_configuration_) { + return active_configuration_->object_path(); + } + return std::nullopt; +} + bool VpnServiceForExtensionAsh::OwnsActiveConfiguration() const { return !!active_configuration_; } @@ -540,8 +488,13 @@ if (!service) { return; } - service->NotifyConnectionStateChanged( - /*connection_success=*/false, base::DoNothing()); + if (std::optional<std::string> object_path = + service->GetActiveConfigurationObjectPath()) { + ash::ShillThirdPartyVpnDriverClient::Get()->UpdateConnectionState( + *object_path, + base::to_underlying(api_vpn::VpnConnectionState::kFailure), + base::DoNothing(), base::DoNothing()); + } if (destroy_configurations) { service->DestroyAllConfigurations();
diff --git a/chrome/browser/ash/crosapi/vpn_service_ash.h b/chrome/browser/ash/crosapi/vpn_service_ash.h index 8d6f7ff..a248573 100644 --- a/chrome/browser/ash/crosapi/vpn_service_ash.h +++ b/chrome/browser/ash/crosapi/vpn_service_ash.h
@@ -79,13 +79,6 @@ CreateConfigurationCallback) override; void DestroyConfiguration(const std::string& configuration_name, DestroyConfigurationCallback) override; - void SetParameters(base::Value::Dict parameters, - SetParametersCallback) override; - void SendPacket(const std::vector<uint8_t>& data, - SendPacketCallback) override; - void NotifyConnectionStateChanged( - bool connection_success, - NotifyConnectionStateChangedCallback) override; void BindPepperVpnProxyObserver( const std::string& configuration_name, mojo::PendingRemote<crosapi::mojom::PepperVpnProxyObserver> @@ -96,6 +89,10 @@ void OnConfigurationRemoved(const std::string& service_path, const std::string& guid) override; + // Returns the object path of the active configuration if it exists. + // Otherwise, returns std::nullopt. + std::optional<std::string> GetActiveConfigurationObjectPath() const; + bool OwnsActiveConfiguration() const; bool HasConfigurationForServicePath(const std::string& service_path) const; @@ -205,6 +202,10 @@ void OnVpnExtensionsChanged( base::flat_set<std::string> vpn_extensions) override; + // Always returns a valid pointer. + VpnServiceForExtensionAsh* GetVpnServiceForExtension( + const std::string& extension_id); + private: friend class chromeos::VpnProviderApiTest; friend class VpnServiceForExtensionAsh; @@ -217,9 +218,6 @@ const std::string& service_path, std::optional<base::Value::Dict> configuration_properties); - // Always returns a valid pointer. - VpnServiceForExtensionAsh* GetVpnServiceForExtension( - const std::string& extension_id); // Ids of enabled vpn extensions. base::flat_set<std::string> vpn_extensions_;
diff --git a/chrome/browser/ash/extensions/default_app_order.cc b/chrome/browser/ash/extensions/default_app_order.cc index d69eb2b..a56dced 100644 --- a/chrome/browser/ash/extensions/default_app_order.cc +++ b/chrome/browser/ash/extensions/default_app_order.cc
@@ -149,6 +149,8 @@ ash::kNotebookLmAppId, + ash::kVidsAppId, + arc::kYoutubeAppId, extension_misc::kYoutubeAppId, ash::kYoutubeAppId,
diff --git a/chrome/browser/ash/input_method/assistive_suggester.cc b/chrome/browser/ash/input_method/assistive_suggester.cc index 7ca53145..c3736c0 100644 --- a/chrome/browser/ash/input_method/assistive_suggester.cc +++ b/chrome/browser/ash/input_method/assistive_suggester.cc
@@ -208,9 +208,7 @@ } bool AssistiveSuggester::IsEmojiSuggestAdditionEnabled() { - return profile_->GetPrefs()->GetBoolean( - prefs::kEmojiSuggestionEnterpriseAllowed) && - profile_->GetPrefs()->GetBoolean(prefs::kEmojiSuggestionEnabled); + return false; } bool AssistiveSuggester::IsMultiWordSuggestEnabled() {
diff --git a/chrome/browser/ash/input_method/assistive_suggester_unittest.cc b/chrome/browser/ash/input_method/assistive_suggester_unittest.cc index 59e50ba7..238275b1 100644 --- a/chrome/browser/ash/input_method/assistive_suggester_unittest.cc +++ b/chrome/browser/ash/input_method/assistive_suggester_unittest.cc
@@ -190,18 +190,6 @@ EXPECT_FALSE(assistive_suggester_->IsAssistiveFeatureEnabled()); } -TEST_F(AssistiveSuggesterTest, EmojiSuggestion_BothPrefsEnabledTrue) { - base::test::ScopedFeatureList feature_list; - feature_list.InitWithFeatures( - /*enabled_features=*/{}, - /*disabled_features=*/{features::kAssistMultiWord}); - profile_->GetPrefs()->SetBoolean(prefs::kEmojiSuggestionEnterpriseAllowed, - true); - profile_->GetPrefs()->SetBoolean(prefs::kEmojiSuggestionEnabled, true); - - EXPECT_TRUE(assistive_suggester_->IsAssistiveFeatureEnabled()); -} - TEST_F(AssistiveSuggesterTest, EmojiSuggestion_BothPrefsEnabledFalse) { base::test::ScopedFeatureList feature_list; feature_list.InitWithFeatures( @@ -1179,25 +1167,6 @@ EXPECT_FALSE(suggestion_handler_->GetShowingSuggestion()); } -TEST_F(AssistiveSuggesterEmojiTest, ShouldRecordNotAllowedWhenSwitchDisabled) { - // TODO(b/242472734): Allow enabled suggestions passed without replace. - assistive_suggester_ = std::make_unique<AssistiveSuggester>( - suggestion_handler_.get(), profile_.get(), - std::make_unique<FakeSuggesterSwitch>(EnabledSuggestions{ - .emoji_suggestions = false, - })); - assistive_suggester_->get_emoji_suggester_for_testing() - ->LoadEmojiMapForTesting(kEmojiData); - assistive_suggester_->OnActivate(kUsEnglishEngineId); - assistive_suggester_->OnFocus(5, empty_context); - - assistive_suggester_->OnSurroundingTextChanged(u"arrow ", gfx::Range(6)); - - histogram_tester_.ExpectTotalCount("InputMethod.Assistive.NotAllowed", 1); - histogram_tester_.ExpectUniqueSample("InputMethod.Assistive.NotAllowed", - AssistiveType::kEmoji, 1); -} - TEST_F(AssistiveSuggesterEmojiTest, ShouldRecordDisabledReasonWhenSwitchDisabled) { // TODO(b/242472734): Allow enabled suggestions passed without replace. @@ -1218,13 +1187,4 @@ DisabledReason::kUrlOrAppNotAllowed, 1); } -TEST_F(AssistiveSuggesterEmojiTest, ShouldReturnPrefixBasedEmojiSuggestions) { - assistive_suggester_->OnActivate(kUsEnglishEngineId); - assistive_suggester_->OnFocus(5, empty_context); - assistive_suggester_->OnSurroundingTextChanged(u"arrow ", gfx::Range(6)); - - EXPECT_TRUE(suggestion_handler_->GetShowingSuggestion()); - EXPECT_EQ(suggestion_handler_->GetSuggestionText(), u"←;↑;→"); -} - } // namespace ash::input_method
diff --git a/chrome/browser/ash/input_method/native_input_method_engine_without_ime_service_browsertest.cc b/chrome/browser/ash/input_method/native_input_method_engine_without_ime_service_browsertest.cc index d1d9400..29f50fc 100644 --- a/chrome/browser/ash/input_method/native_input_method_engine_without_ime_service_browsertest.cc +++ b/chrome/browser/ash/input_method/native_input_method_engine_without_ime_service_browsertest.cc
@@ -219,37 +219,6 @@ } // namespace IN_PROC_BROWSER_TEST_F(NativeInputMethodEngineWithoutImeServiceTest, - SuggestEmoji) { - base::HistogramTester histogram_tester; - engine_->Enable(kEngineIdUs); - TextInputTestHelper helper(GetBrowserInputMethod()); - SetUpTextInput(helper); - const std::u16string prefix_text = u"happy "; - const std::u16string expected_result_text = u"happy 😀"; - - helper.GetTextInputClient()->InsertText( - prefix_text, - ui::TextInputClient::InsertTextCursorBehavior::kMoveCursorAfterText); - helper.WaitForSurroundingTextChanged(prefix_text); - // Selects first emoji. - DispatchKeyPress(ui::VKEY_DOWN, false); - DispatchKeyPress(ui::VKEY_RETURN, false); - helper.WaitForSurroundingTextChanged(expected_result_text); - - EXPECT_EQ(expected_result_text, helper.GetSurroundingText()); - histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Match", - AssistiveType::kEmoji, 1); - histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Disabled.Emoji", - DisabledReason::kNone, 1); - histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Coverage", - AssistiveType::kEmoji, 1); - histogram_tester.ExpectUniqueSample("InputMethod.Assistive.Success", - AssistiveType::kEmoji, 1); - - SetFocus(nullptr); -} - -IN_PROC_BROWSER_TEST_F(NativeInputMethodEngineWithoutImeServiceTest, DismissEmojiSuggestionWhenUsersContinueTyping) { base::HistogramTester histogram_tester; engine_->Enable(kEngineIdUs);
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_accelerator_browsertest.cc b/chrome/browser/ash/login/app_mode/test/kiosk_accelerator_browsertest.cc index 88ea577..d9cd1da 100644 --- a/chrome/browser/ash/login/app_mode/test/kiosk_accelerator_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/test/kiosk_accelerator_browsertest.cc
@@ -15,6 +15,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "chrome/test/base/ui_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" @@ -52,7 +53,9 @@ void SetUpOnMainThread() override { MixinBasedInProcessBrowserTest::SetUpOnMainThread(); + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(WaitKioskLaunched()); + SetBrowser(browser_created_observer.Wait()); } KioskMixin kiosk_{ @@ -64,7 +67,6 @@ }; IN_PROC_BROWSER_TEST_F(WebKioskAcceleratorTest, AcceleratorsDontCloseSession) { - SelectFirstBrowser(); ASSERT_EQ(BrowserList::GetInstance()->size(), 1u); ASSERT_FALSE(PressCloseTabAccelerator(browser())); ASSERT_FALSE(PressCloseWindowAccelerator(browser())); @@ -77,8 +79,6 @@ } IN_PROC_BROWSER_TEST_F(WebKioskAcceleratorTest, ZoomAccelerators) { - SelectFirstBrowser(); - BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); ASSERT_NE(browser_view, nullptr); content::WebContents* web_contents = browser_view->GetActiveWebContents();
diff --git a/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc b/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc index 9de0ac3..463fa1a 100644 --- a/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/test/kiosk_enterprise_input_api_browsertest.cc
@@ -151,14 +151,15 @@ MixinBasedInProcessBrowserTest::SetUpOnMainThread(); ExtensionTestMessageListener extension_ready("ready"); extension_ready.set_extension_id(std::string(kExtensionId)); + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(kiosk::test::WaitKioskLaunched()); + SetBrowser(browser_created_observer.Wait()); // `chrome.runtime` only gets defined once the page finishes loading. ASSERT_TRUE(WaitForLoadStop(&GetAppWebContents())); ASSERT_TRUE(extension_ready.WaitUntilSatisfied()); } content::WebContents& GetAppWebContents() { - SelectFirstBrowser(); BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); return CHECK_DEREF(browser_view->GetActiveWebContents());
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_browser_permissions_browsertest.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_browser_permissions_browsertest.cc index 15c7847..8044553a 100644 --- a/chrome/browser/ash/login/app_mode/test/web_kiosk_browser_permissions_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_browser_permissions_browsertest.cc
@@ -13,6 +13,7 @@ #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" #include "content/public/browser/web_contents.h" #include "content/public/test/browser_test.h" @@ -63,8 +64,9 @@ void SetUpOnMainThread() override { MixinBasedInProcessBrowserTest::SetUpOnMainThread(); + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(WaitKioskLaunched()); - SelectFirstBrowser(); + SetBrowser(browser_created_observer.Wait()); } content::WebContents* GetKioskAppWebContents() {
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc index d90adc2..77197e9 100644 --- a/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_device_attributes_browsertest.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "chromeos/ash/components/system/fake_statistics_provider.h" #include "chromeos/ash/components/system/statistics_provider.h" #include "components/permissions/features.h" @@ -122,8 +123,9 @@ void SetUpOnMainThread() override { MixinBasedInProcessBrowserTest::SetUpOnMainThread(); + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(WaitKioskLaunched()); - SelectFirstBrowser(); + SetBrowser(browser_created_observer.Wait()); } protected:
diff --git a/chrome/browser/ash/login/app_mode/test/web_kiosk_media_ui_browsertest.cc b/chrome/browser/ash/login/app_mode/test/web_kiosk_media_ui_browsertest.cc index 9d94724..48ff4ce5 100644 --- a/chrome/browser/ash/login/app_mode/test/web_kiosk_media_ui_browsertest.cc +++ b/chrome/browser/ash/login/app_mode/test/web_kiosk_media_ui_browsertest.cc
@@ -62,13 +62,13 @@ }; IN_PROC_BROWSER_TEST_F(WebKioskMediaUITest, MediaTrayStaysPinnedInKiosk) { + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(WaitKioskLaunched()); + SetBrowser(browser_created_observer.Wait()); ash::MediaTray::SetPinnedToShelf(false); ASSERT_FALSE(ash::MediaTray::IsPinnedToShelf()); - SelectFirstBrowser(); - MediaNotificationServiceFactory::GetForProfile(GetProfile()) ->ShowDialogAsh(DummyPresentationContext(CHECK_DEREF(browser())));
diff --git a/chrome/browser/ash/login/test/DEPS b/chrome/browser/ash/login/test/DEPS index db05db1..d6046835 100644 --- a/chrome/browser/ash/login/test/DEPS +++ b/chrome/browser/ash/login/test/DEPS
@@ -29,6 +29,7 @@ "+chrome/browser/lifetime", "+chrome/browser/profiles", "+chrome/browser/ui/ash", + "+chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h", "+chrome/browser/ui/webui/ash/login", "+chrome/browser/ui/webui/signin", "+chrome/common/chrome_paths.h",
diff --git a/chrome/browser/ash/login/test/logged_in_user_mixin.cc b/chrome/browser/ash/login/test/logged_in_user_mixin.cc index 8d799adf..f1bbe85d 100644 --- a/chrome/browser/ash/login/test/logged_in_user_mixin.cc +++ b/chrome/browser/ash/login/test/logged_in_user_mixin.cc
@@ -12,6 +12,7 @@ #include "chrome/browser/ash/login/test/cryptohome_mixin.h" #include "chrome/browser/ash/login/test/login_manager_mixin.h" #include "chrome/browser/ash/login/test/user_auth_config.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/test/base/fake_gaia_mixin.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" @@ -160,7 +161,7 @@ login_manager_.WaitForActiveSession(); // If should_launch_browser was set to true, then ensures // InProcessBrowserTest::browser() doesn't return nullptr. - test_base_->SelectFirstBrowser(); + test_base_->SetBrowser(GetLastActiveBrowserWindowInterfaceWithAnyProfile()); } }
diff --git a/chrome/browser/auxiliary_search/auxiliary_search_donation_service.cc b/chrome/browser/auxiliary_search/auxiliary_search_donation_service.cc index e075fbb..6b095c5 100644 --- a/chrome/browser/auxiliary_search/auxiliary_search_donation_service.cc +++ b/chrome/browser/auxiliary_search/auxiliary_search_donation_service.cc
@@ -24,8 +24,15 @@ } void AuxiliarySearchDonationService::OnPageContentAnnotated( - const GURL& url, + const page_content_annotations::HistoryVisit& visit, const page_content_annotations::PageContentAnnotationsResult& result) { + // Ignore annotations from remote visits (navigation ID is 0). + if (result.GetType() != + page_content_annotations::AnnotationType::kContentVisibility || + visit.navigation_id == 0) { + return; + } + // TODO: b/432359106 - Implement this using FetchAndRankHelper and // AuxiliarySearchDonor }
diff --git a/chrome/browser/auxiliary_search/auxiliary_search_donation_service.h b/chrome/browser/auxiliary_search/auxiliary_search_donation_service.h index 02e10d8..f122f8a 100644 --- a/chrome/browser/auxiliary_search/auxiliary_search_donation_service.h +++ b/chrome/browser/auxiliary_search/auxiliary_search_donation_service.h
@@ -12,7 +12,6 @@ namespace page_content_annotations { class PageContentAnnotationsResult; } -class GURL; // AuxiliarySearchDonationService manages donation of Chrome data to AppSearch. // Currently only donates browsing history data. @@ -30,7 +29,7 @@ // ::PageContentAnnotationsService // ::PageContentAnnotationsObserver void OnPageContentAnnotated( - const GURL& url, + const page_content_annotations::HistoryVisit& visit, const page_content_annotations::PageContentAnnotationsResult& result) override;
diff --git a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarUtils.java b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarUtils.java index f14ab23ce..e307b99 100644 --- a/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarUtils.java +++ b/chrome/browser/bookmarks/android/java/src/org/chromium/chrome/browser/bookmarks/bar/BookmarkBarUtils.java
@@ -152,7 +152,7 @@ * therefore if the feature should be exposed to the user. If true, user flows such as keyboard * shortcuts, IPH, settings toggles, device policies, etc should be present. This value should * always return the same value for a device. Compatible devices include Desktop, large tablets, - * and foldables. + * and (unfolded) foldables. * * <p>Check this value when determining which user actions to expose to users for the Bookmark * Bar. @@ -170,8 +170,7 @@ return sDeviceBookmarkBarCompatibleForTesting; } return ChromeFeatureList.sAndroidBookmarkBar.isEnabled() - && (DeviceFormFactor.isNonMultiDisplayContextOnTablet(context) - || DeviceInfo.isFoldable()); + && DeviceFormFactor.isNonMultiDisplayContextOnTablet(context); } /**
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc index 8e56f02..448b630b 100644 --- a/chrome/browser/browser_process_impl.cc +++ b/chrome/browser/browser_process_impl.cc
@@ -259,12 +259,15 @@ #if BUILDFLAG(IS_LINUX) #include "chrome/browser/browser_features.h" -#include "components/os_crypt/async/browser/fallback_linux_key_provider.h" #include "components/os_crypt/async/browser/freedesktop_secret_key_provider.h" #include "components/os_crypt/async/browser/secret_portal_key_provider.h" #include "components/password_manager/core/browser/password_manager_switches.h" #endif +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) +#include "components/os_crypt/async/browser/posix_key_provider.h" +#endif + #if BUILDFLAG(IS_MAC) #include "components/os_crypt/async/browser/keychain_key_provider.h" #endif @@ -1404,15 +1407,25 @@ base::FeatureList::IsEnabled( features::kUseFreedesktopSecretKeyProviderForEncryption), l10n_util::GetStringUTF8(IDS_PRODUCT_NAME), nullptr)); - providers.emplace_back( - /*precedence=*/5u, - std::make_unique<os_crypt_async::FallbackLinuxKeyProvider>( - base::FeatureList::IsEnabled( - features::kUseFreedesktopSecretKeyProviderForEncryption))); } } #endif // BUILDFLAG(IS_LINUX) +#if BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) + // On Linux, this is used if the other key providers are disabled or not + // available. On other POSIX systems, this is the only key provider. +#if BUILDFLAG(IS_LINUX) + const bool use_posix_key_provider_for_encryption = + base::FeatureList::IsEnabled( + features::kUseFreedesktopSecretKeyProviderForEncryption); +#else + const bool use_posix_key_provider_for_encryption = true; +#endif // BUILDFLAG(IS_LINUX) + providers.emplace_back( + /*precedence=*/5u, std::make_unique<os_crypt_async::PosixKeyProvider>( + use_posix_key_provider_for_encryption)); +#endif // BUILDFLAG(IS_POSIX) && !BUILDFLAG(IS_MAC) + #if BUILDFLAG(IS_MAC) if (base::FeatureList::IsEnabled(features::kUseKeychainKeyProvider)) { providers.emplace_back(std::make_pair(
diff --git a/chrome/browser/chrome_shared_array_buffer_browsertest.cc b/chrome/browser/chrome_shared_array_buffer_browsertest.cc index a35cceb..6f18e838 100644 --- a/chrome/browser/chrome_shared_array_buffer_browsertest.cc +++ b/chrome/browser/chrome_shared_array_buffer_browsertest.cc
@@ -60,9 +60,10 @@ // the preference, so it can't create renderers with SABs enabled by policy. // Create a new browser that will pick up the preference and enable SABs for // new renderer processes. - Browser* new_browser = CreateBrowser(browser()->profile()); + BrowserWindowInterface* const new_browser = + CreateBrowser(browser()->profile()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(new_browser); ASSERT_EQ(browser(), new_browser); // Clear existing spares and navigate the new browser to 'localhost', so the
diff --git a/chrome/browser/chromeos/app_mode/kiosk_app_level_logs_browsertest.cc b/chrome/browser/chromeos/app_mode/kiosk_app_level_logs_browsertest.cc index 8041c07..5fd2499 100644 --- a/chrome/browser/chromeos/app_mode/kiosk_app_level_logs_browsertest.cc +++ b/chrome/browser/chromeos/app_mode/kiosk_app_level_logs_browsertest.cc
@@ -16,6 +16,7 @@ #include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/common/pref_names.h" #include "chrome/test/base/mixin_based_in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/prefs/pref_service.h" #include "content/public/common/content_switches.h" #include "content/public/test/browser_test.h" @@ -185,8 +186,9 @@ void SetUpOnMainThread() override { KioskAppLevelLogsTestBase::SetUpOnMainThread(); + ui_test_utils::BrowserCreatedObserver browser_created_observer; ASSERT_TRUE(ash::kiosk::test::WaitKioskLaunched()); - SelectFirstBrowser(); + SetBrowser(browser_created_observer.Wait()); ExpectOnlyKioskAppOpen(); }
diff --git a/chrome/browser/chromeos/cros_apps/api/cros_apps_api_access_control_browsertest.cc b/chrome/browser/chromeos/cros_apps/api/cros_apps_api_access_control_browsertest.cc index 419b2b9..39ae42a 100644 --- a/chrome/browser/chromeos/cros_apps/api/cros_apps_api_access_control_browsertest.cc +++ b/chrome/browser/chromeos/cros_apps/api/cros_apps_api_access_control_browsertest.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" +#include "chrome/test/base/ui_test_utils.h" #include "chromeos/constants/chromeos_features.h" #include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" @@ -86,9 +87,9 @@ // Create the browser with a default WebContents for running the tests. Browser::CreateParams params(profile, /*user_gesture=*/true); - Browser::Create(params); + BrowserWindowInterface* const new_browser = Browser::Create(params); CHECK_EQ(1u, BrowserList::GetInstance()->size()); - SelectFirstBrowser(); + SetBrowser(new_browser); browser()->window()->Show(); std::unique_ptr<content::WebContents> web_contents_to_add =
diff --git a/chrome/browser/chromeos/extensions/vpn_provider/BUILD.gn b/chrome/browser/chromeos/extensions/vpn_provider/BUILD.gn index 96f3bba..e0d861de 100644 --- a/chrome/browser/chromeos/extensions/vpn_provider/BUILD.gn +++ b/chrome/browser/chromeos/extensions/vpn_provider/BUILD.gn
@@ -23,6 +23,7 @@ "//base", "//chrome/browser/profiles:profile", "//chrome/common/extensions/api", + "//chromeos/ash/components/dbus/shill", "//chromeos/ash/components/login/login_state", "//chromeos/crosapi/mojom", "//components/keyed_service/content",
diff --git a/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.cc b/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.cc index 787c84fe3..459f426 100644 --- a/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.cc +++ b/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.cc
@@ -10,10 +10,12 @@ #include "base/containers/contains.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" +#include "base/types/cxx23_to_underlying.h" #include "chrome/browser/ash/crosapi/crosapi_ash.h" #include "chrome/browser/ash/crosapi/crosapi_manager.h" #include "chrome/browser/ash/crosapi/vpn_service_ash.h" #include "chrome/common/extensions/api/vpn_provider.h" +#include "chromeos/ash/components/dbus/shill/shill_third_party_vpn_driver_client.h" #include "content/public/browser/browser_context.h" #include "extensions/browser/event_router.h" #include "extensions/browser/extension_event_histogram_value.h" @@ -173,6 +175,19 @@ ->DispatchEventToExtension(extension_id, std::move(event)); } +bool VpnService::OwnsActiveConfiguration( + const std::string& extension_id) const { + return GetActiveConfigurationObjectPath(extension_id).has_value(); +} + +std::optional<std::string> VpnService::GetActiveConfigurationObjectPath( + const std::string& extension_id) const { + // Peek into VpnServiceAsh directly (this call does not go through mojo). + return GetVpnService() + ->GetVpnServiceForExtension(extension_id) + ->GetActiveConfigurationObjectPath(); +} + void VpnService::SendOnPlatformMessageToExtension( const std::string& extension_id, const std::string& configuration_name, @@ -207,28 +222,58 @@ base::Value::Dict parameters, SuccessCallback success, FailureCallback failure) { - GetVpnServiceForExtension(extension_id) - ->SetParameters(std::move(parameters), - AdaptCallback(std::move(success), std::move(failure))); + if (!OwnsActiveConfiguration(extension_id)) { + RunFailureCallback(std::move(failure), /*error_name=*/{}, + "Unauthorized access."); + return; + } + + ash::ShillThirdPartyVpnDriverClient::Get()->SetParameters( + GetActiveConfigurationObjectPath(extension_id).value(), + std::move(parameters), + base::IgnoreArgs<const std::string&>(std::move(success)), + std::move(failure)); } void VpnService::SendPacket(const std::string& extension_id, const std::vector<char>& data, SuccessCallback success, FailureCallback failure) { - GetVpnServiceForExtension(extension_id) - ->SendPacket(std::vector<uint8_t>(data.begin(), data.end()), - AdaptCallback(std::move(success), std::move(failure))); + if (!OwnsActiveConfiguration(extension_id)) { + RunFailureCallback(std::move(failure), /*error_name=*/{}, + "Unauthorized access."); + return; + } + + if (data.empty()) { + RunFailureCallback(std::move(failure), /*error_name=*/{}, + "Can't send an empty packet."); + return; + } + + ash::ShillThirdPartyVpnDriverClient::Get()->SendPacket( + GetActiveConfigurationObjectPath(extension_id).value(), data, + std::move(success), std::move(failure)); } void VpnService::NotifyConnectionStateChanged(const std::string& extension_id, bool connection_success, SuccessCallback success, FailureCallback failure) { - GetVpnServiceForExtension(extension_id) - ->NotifyConnectionStateChanged( - connection_success, - AdaptCallback(std::move(success), std::move(failure))); + if (!OwnsActiveConfiguration(extension_id)) { + RunFailureCallback(std::move(failure), /*error_name=*/{}, + "Unauthorized access."); + return; + } + + ash::ShillThirdPartyVpnDriverClient::Get()->UpdateConnectionState( + GetActiveConfigurationObjectPath(extension_id).value(), + connection_success + ? base::to_underlying( + extensions::api::vpn_provider::VpnConnectionState::kConnected) + : base::to_underlying( + extensions::api::vpn_provider::VpnConnectionState::kFailure), + std::move(success), std::move(failure)); } void VpnService::Shutdown() { @@ -276,7 +321,7 @@ } // static -crosapi::mojom::VpnService* VpnService::GetVpnService() { +crosapi::VpnServiceAsh* VpnService::GetVpnService() { // CrosapiManager may not be initialized. // TODO(crbug.com/40225953): Assert it's only happening in tests. if (!crosapi::CrosapiManager::IsInitialized()) {
diff --git a/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.h b/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.h index e5518a79..a6acdcfb 100644 --- a/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.h +++ b/chrome/browser/chromeos/extensions/vpn_provider/vpn_service.h
@@ -39,6 +39,10 @@ } // namespace extensions +namespace crosapi { +class VpnServiceAsh; +} + namespace chromeos { class VpnServiceForExtension @@ -125,7 +129,7 @@ friend class VpnServiceForExtension; friend class VpnServiceFactory; - static crosapi::mojom::VpnService* GetVpnService(); + static crosapi::VpnServiceAsh* GetVpnService(); mojo::Remote<crosapi::mojom::VpnServiceForExtension>& GetVpnServiceForExtension(const std::string& extension_id); @@ -134,6 +138,10 @@ void SendToExtension(const std::string& extension_id, std::unique_ptr<extensions::Event> event); + bool OwnsActiveConfiguration(const std::string& extension_id) const; + std::optional<std::string> GetActiveConfigurationObjectPath( + const std::string& extension_id) const; + void SendOnPlatformMessageToExtension(const std::string& extension_id, const std::string& configuration_name, uint32_t platform_message);
diff --git a/chrome/browser/client_hints/client_hints_browsertest.cc b/chrome/browser/client_hints/client_hints_browsertest.cc index 0abe25e..164c2ec 100644 --- a/chrome/browser/client_hints/client_hints_browsertest.cc +++ b/chrome/browser/client_hints/client_hints_browsertest.cc
@@ -1843,9 +1843,10 @@ expected_full_version_list); // Restart the browser, create a new browser to mock the restart process. - Browser* new_browser = CreateBrowser(browser()->profile()); + BrowserWindowInterface* const new_browser = + CreateBrowser(browser()->profile()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(new_browser); ASSERT_EQ(browser(), new_browser); // First request with new browser should expect the high-entropy client hints
diff --git a/chrome/browser/devtools/protocol/user_reidentification_issues_browsertest.cc b/chrome/browser/devtools/protocol/user_reidentification_issues_browsertest.cc index 593a97d..d9b01d3f 100644 --- a/chrome/browser/devtools/protocol/user_reidentification_issues_browsertest.cc +++ b/chrome/browser/devtools/protocol/user_reidentification_issues_browsertest.cc
@@ -8,6 +8,7 @@ #include "base/test/scoped_feature_list.h" #include "chrome/browser/fingerprinting_protection/fingerprinting_protection_filter_browser_test_harness.h" #include "chrome/browser/ui/browser.h" +#include "chrome/test/base/ui_test_utils.h" #include "components/fingerprinting_protection_filter/common/fingerprinting_protection_filter_features.h" #include "components/fingerprinting_protection_filter/interventions/common/interventions_features.h" #include "content/public/test/browser_test.h" @@ -164,9 +165,10 @@ Enabled_Incognito_SubframeDocumentLoadIssueReported) { // Close normal browser and switch the test's browser instance to an incognito // instance. - Browser* incognito = CreateIncognitoBrowser(browser()->profile()); + BrowserWindowInterface* const incognito = + CreateIncognitoBrowser(browser()->profile()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(incognito); ASSERT_EQ(browser(), incognito); ASSERT_TRUE(embedded_test_server()->Start());
diff --git a/chrome/browser/enterprise/signin/profile_management_disclaimer_service_browsertest.cc b/chrome/browser/enterprise/signin/profile_management_disclaimer_service_browsertest.cc index 882420a..2f68520 100644 --- a/chrome/browser/enterprise/signin/profile_management_disclaimer_service_browsertest.cc +++ b/chrome/browser/enterprise/signin/profile_management_disclaimer_service_browsertest.cc
@@ -269,9 +269,10 @@ } void ReplaceCurrentBrowserWithNewOne() { - Browser* new_browser = CreateBrowser(browser()->profile()); + BrowserWindowInterface* const new_browser = + CreateBrowser(browser()->profile()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(new_browser); ASSERT_EQ(browser(), new_browser); }
diff --git a/chrome/browser/extensions/api/automation/automation_apitest.cc b/chrome/browser/extensions/api/automation/automation_apitest.cc index e5e88c4..b5e7449 100644 --- a/chrome/browser/extensions/api/automation/automation_apitest.cc +++ b/chrome/browser/extensions/api/automation/automation_apitest.cc
@@ -742,12 +742,12 @@ screen->SetDisplayForNewWindows(display2); // Run the test in the browser in the non-primary display. // Open a browser on the secondary display, which is default for new windows. - CreateBrowser(profile()); + BrowserWindowInterface* const new_browser = CreateBrowser(profile()); // Close the browser which was already opened on the primary display. CloseBrowserSynchronously(browser()); // Sets browser() to return the one created above, instead of the one which // was closed. - SelectFirstBrowser(); + SetBrowser(new_browser); // The test will run in browser(). ASSERT_TRUE( CreateExtensionAndRunTest("desktop/hit_test.js", kPermissionsWindows))
diff --git a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc index 7509645..ee11cd44 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_browsertest.cc
@@ -111,24 +111,15 @@ namespace extensions { namespace downloads = api::downloads; -// TODO(crbug.com/405219117): Enable more tests on desktop Android. -#if BUILDFLAG(ENABLE_EXTENSIONS) - namespace { const char kFirstDownloadUrl[] = "/download1"; const char kSecondDownloadUrl[] = "/download2"; const int kDownloadSize = 1024 * 10; -void OnFileDeleted(bool success) {} +#if BUILDFLAG(ENABLE_EXTENSIONS) -// Comparator that orders download items by their ID. Can be used with -// std::sort. -struct DownloadIdComparator { - bool operator() (DownloadItem* first, DownloadItem* second) { - return first->GetId() < second->GetId(); - } -}; +void OnFileDeleted(bool success) {} bool IsDownloadExternallyRemoved(download::DownloadItem* item) { return item->GetFileExternallyRemoved(); @@ -144,6 +135,16 @@ base::Unretained(prompt))); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) + +// Comparator that orders download items by their ID. Can be used with +// std::sort. +struct DownloadIdComparator { + bool operator()(DownloadItem* first, DownloadItem* second) { + return first->GetId() < second->GetId(); + } +}; + class DownloadsEventsListener : public EventRouter::TestObserver { public: explicit DownloadsEventsListener(Profile* profile) @@ -374,11 +375,18 @@ second_extension_ = LoadExtensionInternal(name, false); } + Profile* current_profile() { return current_profile_; } + +#if BUILDFLAG(ENABLE_EXTENSIONS) + Browser* current_browser() { return current_browser_; } + content::RenderProcessHost* AddFilenameDeterminer() { ExtensionDownloadsEventRouter::SetDetermineFilenameTimeoutSecondsForTesting( 2); // TODO(crbug.com/405219117): Add special navigation for Android here as - // NavigateToURLInNewTab() does not take a browser/profile. + // the call to chrome::AddSelectedTabWithURL() requires current_browser() + // but our usual replacement NavigateToURLInNewTab() does not take a browser + // or profile. content::WebContents* tab = chrome::AddSelectedTabWithURL( current_browser(), extension_->GetResourceURL("empty.html"), ui::PAGE_TRANSITION_LINK); @@ -388,6 +396,7 @@ GetExtensionId()); return tab->GetPrimaryMainFrame()->GetProcess(); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) void RemoveFilenameDeterminer(content::RenderProcessHost* host) { EventRouter::Get(current_profile()) @@ -395,9 +404,6 @@ host, GetExtensionId()); } - Browser* current_browser() { return current_browser_; } - Profile* current_profile() { return current_profile_; } - // InProcessBrowserTest void SetUpOnMainThread() override { ExtensionApiTest::SetUpOnMainThread(); @@ -432,18 +438,25 @@ second_extension_ = nullptr; current_profile_ = nullptr; incognito_profile_ = nullptr; +#if BUILDFLAG(ENABLE_EXTENSIONS) current_browser_ = nullptr; incognito_browser_ = nullptr; +#endif ExtensionApiTest::TearDownOnMainThread(); } void GoOnTheRecord() { +#if BUILDFLAG(ENABLE_EXTENSIONS) current_browser_ = browser(); - current_profile_ = current_browser_->profile(); +#endif + current_profile_ = profile(); if (events_listener_.get()) events_listener_->UpdateProfile(current_profile()); } +#if BUILDFLAG(ENABLE_EXTENSIONS) + // TODO(crbug.com/405219117): Support incognito. This may require support for + // CreateBrowserWindow() with incognito profiles on Android. void GoOffTheRecord() { if (!incognito_browser_) { incognito_browser_ = CreateIncognitoBrowser(); @@ -458,6 +471,7 @@ if (events_listener_.get()) events_listener_->UpdateProfile(current_profile()); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) bool WaitFor(const std::string& event_name, const std::string& json_args) { return events_listener_->WaitFor(current_profile(), event_name, json_args); @@ -489,10 +503,8 @@ return extension_->url().spec(); } content::StoragePartitionConfig GetExtensionStoragePartitionConfig() { - return browser() - ->profile() - ->GetDownloadManager() - ->GetStoragePartitionConfigForSiteUrl(extension_->url()); + return profile()->GetDownloadManager()->GetStoragePartitionConfigForSiteUrl( + extension_->url()); } std::string GetExtensionId() { return extension_->id(); @@ -805,8 +817,10 @@ raw_ptr<const Extension> second_extension_ = nullptr; raw_ptr<Profile> current_profile_ = nullptr; raw_ptr<Profile> incognito_profile_ = nullptr; +#if BUILDFLAG(ENABLE_EXTENSIONS) raw_ptr<Browser> current_browser_ = nullptr; raw_ptr<Browser> incognito_browser_ = nullptr; +#endif std::unique_ptr<DownloadsEventsListener> events_listener_; std::unique_ptr<net::test_server::ControllableHttpResponse> first_download_; @@ -964,6 +978,10 @@ } // namespace +#if BUILDFLAG(ENABLE_EXTENSIONS) +// The open dialog is not yet implemented on desktop Android. Also, Java-side +// org.chromium.ui.permissions.ContextualNotificationPermissionRequester may +// need to be initialized in android_browsertests for this test to pass. IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_Open) { platform_util::internal::DisableShellOperationsForTesting(); @@ -1028,6 +1046,7 @@ EXPECT_TRUE(download_item->GetOpened()); } +// Flaky on desktop Android. IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_PauseResumeCancelErase) { DownloadItem* download_item = CreateFirstSlowTestDownload(); @@ -1119,6 +1138,7 @@ ASSERT_TRUE(result_list[0].is_int()); EXPECT_EQ(id, result_list[0].GetInt()); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_Open_Remove_Open) { @@ -1162,8 +1182,11 @@ return function; } +#if BUILDFLAG(ENABLE_EXTENSIONS) + // Test downloads.getFileIcon() on in-progress, finished, cancelled and deleted // download items. +// Flaky on desktop Android. IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_FileIcon_Active) { DownloadItem* download_item = CreateFirstSlowTestDownload(); @@ -1250,6 +1273,7 @@ EXPECT_STREQ(errors::kInvalidId, error.c_str()); } +#endif // BUILDFLAG(ENABLE_EXTENSIONS) // Test that we can acquire file icons for history downloads regardless of // whether they exist or not. If the file doesn't exist we should receive a @@ -1288,6 +1312,9 @@ } } +// TODO(crbug.com/405219117): Enable more tests on desktop Android. +#if BUILDFLAG(ENABLE_EXTENSIONS) + // Test passing the empty query to search(). IN_PROC_BROWSER_TEST_F(DownloadExtensionTest, DownloadExtensionTest_SearchEmptyQuery) { @@ -4586,8 +4613,6 @@ ASSERT_TRUE(RunExtensionTest("downloads")) << message_; } -// TODO(crbug.com/405219117): Enable more tests on desktop Android. -#if BUILDFLAG(ENABLE_EXTENSIONS) TEST(ExtensionDetermineDownloadFilenameInternal, ExtensionDetermineDownloadFilenameInternal) { std::string winner_id; @@ -4638,6 +4663,5 @@ warnings.begin()->warning_type()); EXPECT_EQ("incumbent", warnings.begin()->extension_id()); } -#endif // BUILDFLAG(ENABLE_EXTENSIONS) } // namespace extensions
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 c0a50bb..ebb7a16 100644 --- a/chrome/browser/extensions/api/web_request/web_request_apitest.cc +++ b/chrome/browser/extensions/api/web_request/web_request_apitest.cc
@@ -6156,6 +6156,93 @@ WaitForPreflightResponse(); } +// Tests that an extension can successfully use 'extraHeaders' and +// 'declarativeNetRequest' (with header-dependent rules) while handling +// 'onAuthRequired' for a CORS preflight request. +// Regression test for crbug.com/444248440. +IN_PROC_BROWSER_TEST_P(ProxyCORSWebRequestApiTestWithContextTypeMv3, + PreflightOnAuthRequiredWithExtraHeadersDNR) { + static constexpr char kManifest[] = R"({ + "name": "MV3 CORS Preflight webRequest.OnAuthRequired extraHeaders DNR", + "version": "0.1", + "manifest_version": 3, + "permissions": [ + "webRequest", + "webRequestAuthProvider", + "declarativeNetRequest" + ], + "host_permissions": [ "http://127.0.0.1/*", "http://cors.test/*" ], + "background": { "service_worker": "background.js" }, + "declarative_net_request": { + "rule_resources": [{ + "id": "ruleset_1", + "enabled": true, + "path": "rules.json" + }] + } + })"; + + static constexpr char kBackgroundJs[] = + R"(chrome.webRequest.onAuthRequired.addListener(details => { + const authCredentials = { username: '%s', password: '%s' }; + setTimeout(() => { + chrome.test.succeed(); + }, 0); + return {authCredentials}; + }, + { urls: ['<all_urls>'] }, + // 'extraHeaders' is necessary to hit the critical path. + ['blocking', 'extraHeaders']);)"; + + // Use a DNR rule that depends on response headers. By including + // 'responseHeaders' in the condition, the rule cannot be evaluated until + // headers are received. + // This ensures `RulesetManager::HasRulesets(kOnHeadersReceived)` returns + // true, forcing the call to `EvaluateRequestWithHeaders`. + static constexpr char kRulesJson[] = R"([ + { + "id": 1, + "priority": 1, + "action": { "type": "block" }, + "condition": { + "urlFilter": "*", + "responseHeaders": [{"header": "header-that-forces-evaluation"}] + } + } + ])"; + + TestExtensionDir test_dir; + test_dir.WriteManifest(kManifest); + test_dir.WriteFile( + FILE_PATH_LITERAL("background.js"), + base::StringPrintf(kBackgroundJs, kCORSProxyUser, kCORSProxyPass)); + test_dir.WriteFile(FILE_PATH_LITERAL("rules.json"), kRulesJson); + + const Extension* extension = LoadExtension(test_dir.UnpackedPath()); + ASSERT_TRUE(extension) << message_; + + ResultCatcher result_catcher; + preflight_waiter_ = std::make_unique<base::RunLoop>(); + + ASSERT_TRUE(NavigateToURL(GetActiveWebContents(), + embedded_test_server()->GetURL("/empty.html"))); + + // Send a CORS preflight request which requires proxy auth. + // This triggers the sequence: + // - Preflight + // - Auth Challenge + // - HandleAuthRequest (with extraHeaders) + // - HandleResponseOrRedirectHeaders + // - WebRequestEventRouter::OnHeadersReceived + // - RulesetManager::HasRulesets(kOnHeadersReceived) == true + // - RulesetManager::EvaluateRequestWithHeaders(nullptr) + // - Graceful handling of headers == nullptr. + ExecuteCorsPreflightedRequest(); + + EXPECT_TRUE(result_catcher.GetNextResult()); + WaitForPreflightResponse(); +} + // Depends on declarativeWebRequest. crbug.com/332512510. class ExtensionWebRequestApiFencedFrameTest : public ExtensionWebRequestApiTest {
diff --git a/chrome/browser/file_system_access/file_system_access_features.cc b/chrome/browser/file_system_access/file_system_access_features.cc index 30476e4a..2cc7e5e 100644 --- a/chrome/browser/file_system_access/file_system_access_features.cc +++ b/chrome/browser/file_system_access/file_system_access_features.cc
@@ -12,7 +12,7 @@ // already has permissions, which can happen the destination path was once // granted permission for a different file that has since been removed. BASE_FEATURE(kFileSystemAccessMoveWithOverwrite, - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); // Enables persistent permissions for the File System Access API. BASE_FEATURE(kFileSystemAccessPersistentPermissions,
diff --git a/chrome/browser/fingerprinting_protection/fingerprinting_protection_filter_user_bypass_browsertest.cc b/chrome/browser/fingerprinting_protection/fingerprinting_protection_filter_user_bypass_browsertest.cc index fc014156..1b248b7a 100644 --- a/chrome/browser/fingerprinting_protection/fingerprinting_protection_filter_user_bypass_browsertest.cc +++ b/chrome/browser/fingerprinting_protection/fingerprinting_protection_filter_user_bypass_browsertest.cc
@@ -107,9 +107,10 @@ // Close normal browser and switch the test's browser instance to an incognito // instance. - Browser* incognito = CreateIncognitoBrowser(browser()->profile()); + BrowserWindowInterface* incognito = + CreateIncognitoBrowser(browser()->profile()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(incognito); ASSERT_EQ(browser(), incognito); // TODO(https://crbug.com/358371545): Test console messaging for subframe
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index 4d71ea1..e587a24 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -10344,6 +10344,11 @@ "expiry_milestone": 145 }, { + "name": "vids-app-preinstall", + "owners": [ "alancutter@chromium.org", "cros-ca-eng@google.com" ], + "expiry_milestone": 150 + }, + { "name": "view-transition-on-navigation", "owners": [ "khushalsagar@chromium.org", "vmpstr@chromium.org", "chrishtr@chromium.org" ], "expiry_milestone" : 130
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index 7d93033..a106f98c 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -4316,6 +4316,10 @@ "Displays an updated UI for video picture-in-picture controls from its 2024" "UI update"; +const char kVidsAppPreinstallName[] = "Vids app preinstall"; +const char kVidsAppPreinstallDescription[] = + "Preinstalls the Vids app on ChromeOS."; + const char kV8VmFutureName[] = "Future V8 VM features"; const char kV8VmFutureDescription[] = "This enables upcoming and experimental V8 VM features. "
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index 9f9043a..2bf60e5 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -2500,6 +2500,9 @@ extern const char kGroupPromoPrototypeCpaDescription[]; #endif // BUILDFLAG(IS_ANDROID) +extern const char kVidsAppPreinstallName[]; +extern const char kVidsAppPreinstallDescription[]; + extern const char kV8VmFutureName[]; extern const char kV8VmFutureDescription[];
diff --git a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java index 54cc9ea..49e2878 100644 --- a/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java +++ b/chrome/browser/flags/android/java/src/org/chromium/chrome/browser/flags/ChromeFeatureList.java
@@ -1613,10 +1613,6 @@ newStringCachedFeatureParam( EDGE_TO_EDGE_USE_BACKUP_NAVBAR_INSETS, "e2e_backup_navbar_insets_oem_list", ""); - public static final BooleanCachedFeatureParam sEdgeToEdgeUseBackupNavbarInsetsUseTappable = - newBooleanCachedFeatureParam( - EDGE_TO_EDGE_USE_BACKUP_NAVBAR_INSETS, "use_tappable_element", true); - public static final BooleanCachedFeatureParam sEdgeToEdgeUseBackupNavbarInsetsUseGestures = newBooleanCachedFeatureParam( EDGE_TO_EDGE_USE_BACKUP_NAVBAR_INSETS, "use_gesture_insets", false); @@ -1795,7 +1791,6 @@ sEdgeToEdgeUseBackupNavbarInsetsOemList, sEdgeToEdgeUseBackupNavbarInsetsOemMinVersions, sEdgeToEdgeUseBackupNavbarInsetsUseGestures, - sEdgeToEdgeUseBackupNavbarInsetsUseTappable, sLoadNativeEarlyConcurrentLoad, sMagicStackAndroidShowAllModules, sMaliciousApkDownloadCheckTelemetryOnly,
diff --git a/chrome/browser/glic/browser_ui/glic_border_view.cc b/chrome/browser/glic/browser_ui/glic_border_view.cc index acae757..8579137 100644 --- a/chrome/browser/glic/browser_ui/glic_border_view.cc +++ b/chrome/browser/glic/browser_ui/glic_border_view.cc
@@ -289,10 +289,21 @@ } bool ShouldShowBorderAnimation() { - if (!context_access_indicator_enabled_ || - !glic_focused_contents_in_current_view_) { + if (!glic_focused_contents_in_current_view_) { return false; } + + // For multi-instance we rely on the sharing manager signal for everything + // else. + if (base::FeatureList::IsEnabled(features::kGlicMultiInstance)) { + return true; + } + + // Remaining single instance checks. + if (!context_access_indicator_enabled_) { + return false; + } + return IsGlicWindowShowing(); }
diff --git a/chrome/browser/glic/service/glic_instance_impl.cc b/chrome/browser/glic/service/glic_instance_impl.cc index 02a93c9..7568ffe5 100644 --- a/chrome/browser/glic/service/glic_instance_impl.cc +++ b/chrome/browser/glic/service/glic_instance_impl.cc
@@ -9,6 +9,7 @@ #include "base/functional/bind.h" #include "base/logging.h" #include "base/notimplemented.h" +#include "base/task/sequenced_task_runner.h" #include "chrome/browser/contextual_cueing/contextual_cueing_service.h" #include "chrome/browser/contextual_cueing/contextual_cueing_service_factory.h" #include "chrome/browser/glic/fre/glic_fre_controller.h" @@ -28,11 +29,13 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_window.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/browser/ui/tabs/public/tab_features.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/common/actor_webui.mojom.h" #include "components/tabs/public/tab_interface.h" +#include "content/public/browser/browser_thread.h" #include "content/public/browser/web_contents_observer.h" #include "mojo/public/cpp/bindings/callback_helpers.h" #include "third_party/abseil-cpp/absl/functional/overload.h" @@ -75,8 +78,7 @@ content::WebContents::FromRenderFrameHost(source_render_frame_host)); auto* glic_embedder = instance_->GetEmbedderForTab(source_tab); - // Ensure the previous side panel was active. If so, then deactivate it and - // open it in the new tab. + // Only bind if the previous instance was active. if (glic_embedder && glic_embedder->IsShowing()) { instance_->Show(GlicInstanceImpl::EmbedderType::kSidePanel, tab_to_bind); } @@ -148,7 +150,14 @@ embedder_to_show = GetActiveEmbedder(); } else { DeactivateCurrentEmbedder(); - embedder_to_show = CreateActiveEmbedderFor(new_key); + if (type == EmbedderType::kSidePanel) { + embedder_to_show = CreateActiveEmbedderForSidePanel(tab); + } else { + embedder_to_show = + CreateActiveEmbedderForFloaty(tab->GetBrowserWindowInterface()); + } + CHECK(embedder_to_show); + host_.SetDelegate(embedder_to_show->GetHostEmbedderDelegate()); SetActiveEmbedderAndNotifyStateChange(new_key); } @@ -156,6 +165,10 @@ embedder_to_show->Show(); } +void GlicInstanceImpl::Detach(tabs::TabInterface* tab) { + Show(EmbedderType::kFloating, tab); +} + void GlicInstanceImpl::Close(EmbedderType type, tabs::TabInterface* tab) { EmbedderKey key = GetEmbedderKey(type, tab); auto* embedder = GetEmbedderForKey(key); @@ -300,10 +313,7 @@ } void GlicInstanceImpl::UnbindTab(tabs::TabInterface* tab) { - if (active_embedder_key_.has_value() && - active_embedder_key_.value() == EmbedderKey(tab)) { - DeactivateCurrentEmbedder(); - } + MaybeDeactivateEmbedderAndCloseHostUi(EmbedderKey(tab)); embedders_.erase(EmbedderKey(tab)); } @@ -446,28 +456,21 @@ ClearActiveEmbedderAndNotifyStateChange(); } -GlicUiEmbedder* GlicInstanceImpl::CreateActiveEmbedderFor( - const EmbedderKey& key) { - GlicUiEmbedder* embedder_ptr = nullptr; - std::visit(absl::Overload{ - [&](FloatingEmbedderKey) { - auto [entry_iter, _] = embedders_.try_emplace(key); - entry_iter->second.embedder = - std::make_unique<GlicFloatingUi>(profile_, *this); - embedder_ptr = entry_iter->second.embedder.get(); - }, - [&](tabs::TabInterface* tab) { - auto& entry = BindTab(tab); - entry.embedder = std::make_unique<GlicSidePanelUi>( - profile_, tab->GetWeakPtr(), *this); - embedder_ptr = entry.embedder.get(); - }, - }, - key); +GlicUiEmbedder* GlicInstanceImpl::CreateActiveEmbedderForSidePanel( + tabs::TabInterface* tab) { + auto& entry = BindTab(tab); + entry.embedder = + std::make_unique<GlicSidePanelUi>(profile_, tab->GetWeakPtr(), *this); + return entry.embedder.get(); +} - CHECK(embedder_ptr); - host_.SetDelegate(embedder_ptr->GetHostEmbedderDelegate()); - return embedder_ptr; +GlicUiEmbedder* GlicInstanceImpl::CreateActiveEmbedderForFloaty( + BrowserWindowInterface* browser) { + GlicInstanceImpl::EmbedderKey key = FloatingEmbedderKey(); + auto [entry_iter, _] = embedders_.try_emplace(key); + entry_iter->second.embedder = + std::make_unique<GlicFloatingUi>(profile_, browser, *this); + return entry_iter->second.embedder.get(); } void GlicInstanceImpl::ShowInactiveSidePanelEmbedderFor( @@ -515,10 +518,6 @@ std::move(options)); } -void GlicInstanceImpl::Detach() { - Show(EmbedderType::kFloating, nullptr); -} - void GlicInstanceImpl::OnBoundTabDestroyed(tabs::TabInterface* tab, const InstanceId& instance_id) { UnbindTab(tab); @@ -555,6 +554,16 @@ // TODO: Figure out what else should go into host_.PanelWasClosed() and // maybe call it here. DeactivateCurrentEmbedder(); + // Post a task to maybe activate another embedder. This is to avoid a race + // condition where the deactivation of an old embedder (e.g. during a tab + // switch) tries to show the new embedder before the browser's own tab + // activation logic has had a chance to run. By posting, we allow the + // synchronous activation logic to complete, and then this task will run + // and activate a foreground embedder only if one isn't already active. + base::SequencedTaskRunner::GetCurrentDefault()->PostTask( + FROM_HERE, + base::BindOnce(&GlicInstanceImpl::MaybeActivateForegroundEmbedder, + weak_ptr_factory_.GetWeakPtr())); } } @@ -619,4 +628,20 @@ return panel_state; } +// If no embedder is active, finds an embedder associated with an active +// tab and activates it. Note: The order is not guaranteed to be MRU. +void GlicInstanceImpl::MaybeActivateForegroundEmbedder() { + if (active_embedder_key_.has_value()) { + return; + } + for (auto const& [key, entry] : embedders_) { + if (auto* tab = std::get_if<tabs::TabInterface*>(&key)) { + if (entry.embedder->IsShowing()) { + Show(EmbedderType::kSidePanel, *tab); + return; + } + } + } +} + } // namespace glic
diff --git a/chrome/browser/glic/service/glic_instance_impl.h b/chrome/browser/glic/service/glic_instance_impl.h index bb4c838..f241eba 100644 --- a/chrome/browser/glic/service/glic_instance_impl.h +++ b/chrome/browser/glic/service/glic_instance_impl.h
@@ -99,8 +99,6 @@ std::optional<std::string> conversation_id() const; base::CallbackListSubscription RegisterStateChange( StateChangeCallback callback) override; - // Opens the floating UI for this instance - void Detach() override; // Host::InstanceDelegate: void CreateTab( @@ -148,6 +146,8 @@ void WillCloseFor(tabs::TabInterface* tab) override; void Attach(tabs::TabInterface* tab) override; void NotifyPanelStateChanged() override; + // Opens the floating UI for this instance + void Detach(tabs::TabInterface* tab) override; // Host::InstanceInterface: mojom::PanelState GetPanelState() override; @@ -191,7 +191,9 @@ GlicUiEmbedder* GetActiveEmbedder(); GlicUiEmbedder* GetEmbedderForKey(EmbedderKey key); void DeactivateCurrentEmbedder(); - GlicUiEmbedder* CreateActiveEmbedderFor(const EmbedderKey& key); + GlicUiEmbedder* CreateActiveEmbedderForSidePanel(tabs::TabInterface* tab); + GlicUiEmbedder* CreateActiveEmbedderForFloaty( + BrowserWindowInterface* browser); void ShowInactiveSidePanelEmbedderFor(tabs::TabInterface* tab); void SetActiveEmbedderAndNotifyStateChange( std::optional<EmbedderKey> new_key); @@ -207,6 +209,8 @@ callback, std::vector<std::string> returned_suggestions); void MaybeDeactivateEmbedderAndCloseHostUi(EmbedderKey key); + + void MaybeActivateForegroundEmbedder(); EmbedderEntry& BindTab(tabs::TabInterface* tab); using StateChangeCallbackList =
diff --git a/chrome/browser/glic/service/glic_ui_embedder.h b/chrome/browser/glic/service/glic_ui_embedder.h index a87a862..a32d0f8 100644 --- a/chrome/browser/glic/service/glic_ui_embedder.h +++ b/chrome/browser/glic/service/glic_ui_embedder.h
@@ -29,7 +29,7 @@ virtual void WillCloseFor(tabs::TabInterface* tab) = 0; virtual Host& host() = 0; virtual void Attach(tabs::TabInterface* tab) = 0; - virtual void Detach() = 0; + virtual void Detach(tabs::TabInterface* tab) = 0; // Called after the value of GetPanelState() changes. virtual void NotifyPanelStateChanged() = 0; };
diff --git a/chrome/browser/glic/widget/glic_floating_ui.cc b/chrome/browser/glic/widget/glic_floating_ui.cc index 2f5acd5..26923c5 100644 --- a/chrome/browser/glic/widget/glic_floating_ui.cc +++ b/chrome/browser/glic/widget/glic_floating_ui.cc
@@ -12,20 +12,32 @@ #include "chrome/browser/glic/widget/glic_view.h" #include "chrome/browser/glic/widget/glic_widget.h" #include "chrome/browser/glic/widget/glic_window_animator.h" - -namespace { - -// constexpr static int kDraggableAreaHeight = 44; - -} // namespace +#include "chrome/common/chrome_features.h" namespace glic { +// static +gfx::Size GlicFloatingUi::GetDefaultSize() { + return {features::kGlicMultiInstanceFloatyWidth.Get(), + features::kGlicMultiInstanceFloatyHeight.Get()}; +} + +// end static + GlicFloatingUi::GlicFloatingUi(Profile* profile, + BrowserWindowInterface* browser, + GlicUiEmbedder::Delegate& delegate) + : GlicFloatingUi( + profile, + GlicWidget::GetInitialBounds(browser, + GlicFloatingUi::GetDefaultSize()), + delegate) {} + +GlicFloatingUi::GlicFloatingUi(Profile* profile, + gfx::Rect initial_bounds, GlicUiEmbedder::Delegate& delegate) : profile_(profile), delegate_(delegate) { - LOG(ERROR) << "tnp: Floating UI created"; - CreateAndSetupWidget(); + CreateAndSetupWidget(initial_bounds); panel_state_.kind = mojom::PanelState_Kind::kDetached; } @@ -39,10 +51,6 @@ return panel_state_; } -GlicWindowAnimator* GlicFloatingUi::window_animator() { - return glic_window_animator_.get(); -} - GlicWidget* GlicFloatingUi::GetGlicWidget() const { return glic_widget_.get(); } @@ -54,9 +62,8 @@ return nullptr; } -void GlicFloatingUi::CreateAndSetupWidget() { - glic_widget_ = - GlicWidget::Create(profile_, gfx::Rect(10, 10, 400, 400), nullptr, true); +void GlicFloatingUi::CreateAndSetupWidget(gfx::Rect initial_bounds) { + glic_widget_ = GlicWidget::Create(profile_, initial_bounds, nullptr, true); // TODO: Setup Hotkeys and AccessibilityText GetGlicWidget()->SetZOrderLevel(ui::ZOrderLevel::kFloatingWindow); @@ -73,13 +80,11 @@ void GlicFloatingUi::Resize(const gfx::Size& size, base::TimeDelta duration, base::OnceClosure callback) { - glic_size_ = size; - // TODO: Don't animate while the user is manually resizing the widget. if (glic_window_animator_ && IsShowing()) { glic_window_animator_->AnimateSize( - GlicWidget::GetLastRequestedSizeClamped(GetGlicWidget(), glic_size_), - duration, std::move(callback)); + GlicWidget::ClampSize(size, GetGlicWidget()), duration, + std::move(callback)); } else { base::SequencedTaskRunner::GetCurrentDefault()->PostTask( FROM_HERE, std::move(callback)); @@ -93,21 +98,6 @@ } } -// void GlicFloatingUi::SetDraggingAreasAndWatchForMouseEvents() { -// if (window_event_observer_) { -// return; -// } - -// window_event_observer_ = -// std::make_unique<WindowEventObserver>(this, GetGlicView()); - -// if (!draggable_area_) { -// // Set the draggable area to the top bar of the window. -// GetGlicView()->SetDraggableAreas( -// {{0, 0, GetGlicView()->width(), kDraggableAreaHeight}}); -// } -// } - void GlicFloatingUi::EnableDragResize(bool enabled) { NOTIMPLEMENTED(); } @@ -130,7 +120,6 @@ } void GlicFloatingUi::Show() { - LOG(ERROR) << "tnp: Floating UI show"; GetGlicWidget()->Show(); GetGlicView()->SetWebContents(delegate_->host().webui_contents()); GetGlicView()->UpdateBackgroundColor();
diff --git a/chrome/browser/glic/widget/glic_floating_ui.h b/chrome/browser/glic/widget/glic_floating_ui.h index e722f90c..67fc84d 100644 --- a/chrome/browser/glic/widget/glic_floating_ui.h +++ b/chrome/browser/glic/widget/glic_floating_ui.h
@@ -12,6 +12,8 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" +class BrowserWindowInterface; + namespace glic { class GlicWindowAnimator; @@ -21,9 +23,16 @@ // A stub implementation of GlicUiEmbedder for floating UIs. class GlicFloatingUi : public GlicUiEmbedder, public Host::EmbedderDelegate { public: - GlicFloatingUi(Profile* profile, GlicUiEmbedder::Delegate& delegate); + GlicFloatingUi(Profile* profile, + BrowserWindowInterface* browser, + GlicUiEmbedder::Delegate& delegate); + GlicFloatingUi(Profile* profile, + gfx::Rect initial_bounds, + GlicUiEmbedder::Delegate& delegate); ~GlicFloatingUi() override; + static gfx::Size GetDefaultSize(); + // GlicUiEmbedder: Host::EmbedderDelegate* GetHostEmbedderDelegate() override; void Show() override; @@ -49,12 +58,10 @@ mojom::WebClientHandler::SwitchConversationCallback callback) override; void ClosePanel() override; - GlicWindowAnimator* window_animator(); - private: GlicWidget* GetGlicWidget() const; GlicView* GetGlicView() const; - void CreateAndSetupWidget(); + void CreateAndSetupWidget(gfx::Rect initial_bounds); // void SetDraggingAreasAndWatchForMouseEvents(); // Used to monitor key and mouse events from native window. @@ -63,7 +70,6 @@ std::unique_ptr<GlicWindowAnimator> glic_window_animator_; std::unique_ptr<GlicWidget> glic_widget_; - std::optional<gfx::Size> glic_size_; mojom::PanelState panel_state_; raw_ptr<Profile> profile_;
diff --git a/chrome/browser/glic/widget/glic_inactive_side_panel_ui.cc b/chrome/browser/glic/widget/glic_inactive_side_panel_ui.cc index b51f596..b4be3f1 100644 --- a/chrome/browser/glic/widget/glic_inactive_side_panel_ui.cc +++ b/chrome/browser/glic/widget/glic_inactive_side_panel_ui.cc
@@ -28,7 +28,6 @@ // Using `new` to access a private constructor. auto inactive_side_panel = base::WrapUnique(new GlicInactiveSidePanelUi(tab, delegate)); - inactive_side_panel->VisibilityChanged(/*visible=*/true); // Capture screenshot asynchronously and update the inactive panel. inactive_side_panel->inactive_view_controller_.CaptureScreenshot( @@ -57,18 +56,11 @@ base::WeakPtr<tabs::TabInterface> tab, GlicUiEmbedder::Delegate& delegate) : tab_(tab), delegate_(delegate) { - if (!tab_ || !tab_->GetTabFeatures()) { + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator) { return; } - auto* glic_side_panel_coordinator = - tab_->GetTabFeatures()->glic_side_panel_coordinator(); - - panel_visibility_subscription_ = - glic_side_panel_coordinator->AddVisibilityCallback( - base::BindRepeating(&GlicInactiveSidePanelUi::VisibilityChanged, - weak_ptr_factory_.GetWeakPtr())); - auto view = inactive_view_controller_.CreateView(); scoped_view_observation_.Observe(view.get()); glic_side_panel_coordinator->SetContentsView(std::move(view)); @@ -96,24 +88,27 @@ } bool GlicInactiveSidePanelUi::IsShowing() const { - return is_showing_; + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator) { + return false; + } + return glic_side_panel_coordinator->IsShowing(); } void GlicInactiveSidePanelUi::Show() { - if (!tab_ || !tab_->GetTabFeatures()) { + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator) { return; } - SidePanelRegistry* registry = tab_->GetTabFeatures()->side_panel_registry(); - SidePanelEntry* glic_entry = - registry->GetEntryForKey(SidePanelEntry::Key(SidePanelEntry::Id::kGlic)); - if (glic_entry) { - registry->SetActiveEntry(glic_entry); - } + glic_side_panel_coordinator->Show(); } void GlicInactiveSidePanelUi::Close() { - // TODO: implement close. - NOTIMPLEMENTED(); + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator) { + return; + } + glic_side_panel_coordinator->Close(); } views::View* GlicInactiveSidePanelUi::GetView() { @@ -135,8 +130,12 @@ NOTREACHED() << "The embedder is already inactive."; } -void GlicInactiveSidePanelUi::VisibilityChanged(bool visible) { - is_showing_ = visible; +GlicSidePanelCoordinator* GlicInactiveSidePanelUi::GetGlicSidePanelCoordinator() + const { + if (!tab_ || !tab_->GetTabFeatures()) { + return nullptr; + } + return tab_->GetTabFeatures()->glic_side_panel_coordinator(); } } // namespace glic
diff --git a/chrome/browser/glic/widget/glic_inactive_side_panel_ui.h b/chrome/browser/glic/widget/glic_inactive_side_panel_ui.h index fdd4042..3fc85dd 100644 --- a/chrome/browser/glic/widget/glic_inactive_side_panel_ui.h +++ b/chrome/browser/glic/widget/glic_inactive_side_panel_ui.h
@@ -53,21 +53,18 @@ void OnViewFocused(views::View* observed_view) override; void OnViewIsDeleting(views::View* observed_view) override; - void VisibilityChanged(bool visible); - private: explicit GlicInactiveSidePanelUi(base::WeakPtr<tabs::TabInterface> tab, GlicUiEmbedder::Delegate& delegate); + GlicSidePanelCoordinator* GetGlicSidePanelCoordinator() const; InactiveViewController inactive_view_controller_; base::WeakPtr<tabs::TabInterface> tab_; raw_ref<GlicUiEmbedder::Delegate> delegate_; - bool is_showing_ = false; base::ScopedObservation<views::View, views::ViewObserver> scoped_view_observation_{this}; - base::CallbackListSubscription panel_visibility_subscription_; base::WeakPtrFactory<GlicInactiveSidePanelUi> weak_ptr_factory_{this}; };
diff --git a/chrome/browser/glic/widget/glic_side_panel_ui.cc b/chrome/browser/glic/widget/glic_side_panel_ui.cc index 7337ded..4c291c1 100644 --- a/chrome/browser/glic/widget/glic_side_panel_ui.cc +++ b/chrome/browser/glic/widget/glic_side_panel_ui.cc
@@ -27,15 +27,15 @@ base::WeakPtr<tabs::TabInterface> tab, GlicUiEmbedder::Delegate& delegate) : profile_(profile), tab_(tab), delegate_(delegate) { - if (!tab_ || !tab_->GetTabFeatures()) { + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator) { return; } - auto* glic_side_panel_coordinator = - tab_->GetTabFeatures()->glic_side_panel_coordinator(); panel_visibility_subscription_ = - glic_side_panel_coordinator->AddVisibilityCallback(base::BindRepeating( - &GlicSidePanelUi::VisibilityChanged, weak_ptr_factory_.GetWeakPtr())); + glic_side_panel_coordinator->AddStateCallback( + base::BindRepeating(&GlicSidePanelUi::SidePanelStateChanged, + weak_ptr_factory_.GetWeakPtr())); glic_side_panel_coordinator->SetContentsView(CreateView(profile_)); panel_state_.kind = mojom::PanelState_Kind::kAttached; @@ -81,7 +81,10 @@ } void GlicSidePanelUi::Detach() { - delegate_->Detach(); + if (!tab_) { + return; + } + delegate_->Detach(tab_.get()); } void GlicSidePanelUi::SetMinimumWidgetSize(const gfx::Size& size) { @@ -89,11 +92,11 @@ } bool GlicSidePanelUi::IsShowing() const { - if (!tab_) { + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator) { return false; } - // If this embedder is active, side panel must be showing. - return true; + return glic_side_panel_coordinator->IsShowing(); } void GlicSidePanelUi::Focus() { @@ -103,10 +106,11 @@ } } -void GlicSidePanelUi::VisibilityChanged(bool visible) { +void GlicSidePanelUi::SidePanelStateChanged( + GlicSidePanelCoordinator::State state) { // Showing only happens through glic entrypoint, hiding can also be triggered // by side panel coordinator when replacing glic with another entry. - if (!visible && tab_) { + if (state != GlicSidePanelCoordinator::State::kShown && tab_) { delegate_->WillCloseFor(tab_.get()); } } @@ -119,26 +123,24 @@ } void GlicSidePanelUi::Show() { - if (!tab_) { + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator) { return; } panel_state_.kind = mojom::PanelState_Kind::kAttached; delegate_->NotifyPanelStateChanged(); - auto* side_panel_coordinator = - tab_->GetBrowserWindowInterface()->GetFeatures().side_panel_coordinator(); - side_panel_coordinator->Show(SidePanelEntry::Id::kGlic); + glic_side_panel_coordinator->Show(); Focus(); } void GlicSidePanelUi::Close() { - if (!tab_ || !IsShowing()) { + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + if (!glic_side_panel_coordinator || !IsShowing()) { return; } panel_state_.kind = mojom::PanelState_Kind::kHidden; delegate_->NotifyPanelStateChanged(); - auto* side_panel_coordinator = - tab_->GetBrowserWindowInterface()->GetFeatures().side_panel_coordinator(); - side_panel_coordinator->Close(); + glic_side_panel_coordinator->Close(); } void GlicSidePanelUi::ClosePanel() { @@ -152,8 +154,16 @@ } views::View* GlicSidePanelUi::GetView() { - return tab_ ? tab_->GetTabFeatures()->glic_side_panel_coordinator()->GetView() - : nullptr; + auto* glic_side_panel_coordinator = GetGlicSidePanelCoordinator(); + return glic_side_panel_coordinator ? glic_side_panel_coordinator->GetView() + : nullptr; +} + +GlicSidePanelCoordinator* GlicSidePanelUi::GetGlicSidePanelCoordinator() const { + if (!tab_ || !tab_->GetTabFeatures()) { + return nullptr; + } + return tab_->GetTabFeatures()->glic_side_panel_coordinator(); } } // namespace glic
diff --git a/chrome/browser/glic/widget/glic_side_panel_ui.h b/chrome/browser/glic/widget/glic_side_panel_ui.h index 52ede2d..9027a45 100644 --- a/chrome/browser/glic/widget/glic_side_panel_ui.h +++ b/chrome/browser/glic/widget/glic_side_panel_ui.h
@@ -60,9 +60,10 @@ bool IsShowing() const override; void ClosePanel() override; - void VisibilityChanged(bool visible); + void SidePanelStateChanged(GlicSidePanelCoordinator::State state); private: + GlicSidePanelCoordinator* GetGlicSidePanelCoordinator() const; base::CallbackListSubscription panel_visibility_subscription_; std::unique_ptr<views::View> CreateView(Profile* profile); mojom::PanelState panel_state_;
diff --git a/chrome/browser/glic/widget/glic_widget.cc b/chrome/browser/glic/widget/glic_widget.cc index 7c7854c..3bcaa2d 100644 --- a/chrome/browser/glic/widget/glic_widget.cc +++ b/chrome/browser/glic/widget/glic_widget.cc
@@ -9,15 +9,24 @@ #include "chrome/browser/shell_integration_linux.h" #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" +#include "chrome/browser/ui/browser_element_identifiers.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/browser/ui/views/chrome_widget_sublevel.h" +#include "chrome/browser/ui/views/interaction/browser_elements_views.h" +#include "chrome/browser/ui/views/tabs/glic_button.h" #include "chrome/common/chrome_features.h" +#include "ui/base/base_window.h" #include "ui/base/l10n/l10n_util.h" #include "ui/color/color_provider_key.h" +#include "ui/display/display.h" +#include "ui/display/display_finder.h" #include "ui/display/screen.h" #include "ui/gfx/geometry/insets.h" #include "ui/gfx/geometry/outsets.h" #include "ui/gfx/geometry/rounded_corners_f.h" #include "ui/views/widget/native_widget.h" +#include "ui/views/widget/widget.h" #include "ui/views/widget/widget_delegate.h" #if BUILDFLAG(IS_OZONE) @@ -39,6 +48,7 @@ constexpr float kGlicWidgetCornerRadius = 12; constexpr int kMaxWidgetSize = 16'384; +constexpr int kInitialPositionBuffer = 4; // For resizeable windows, there may be an invisible border which affects the // widget size. Given a target rect, this method provides the outsets which @@ -81,6 +91,58 @@ : views::Widget::InitParams::TYPE_WINDOW_FRAMELESS; } +display::Display GetDisplayForOpeningDetached() { + // Get the Display for the most recently active browser. If there was no + // recently active browser, use the primary display. + BrowserWindowInterface* const bwi = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); + ui::BaseWindow* const window = bwi ? bwi->GetWindow() : nullptr; + if (window) { + const std::optional<display::Display> widget_display = + views::Widget::GetWidgetForNativeWindow(window->GetNativeWindow()) + ->GetNearestDisplay(); + if (widget_display) { + return *widget_display; + } + } + return display::Screen::Get()->GetPrimaryDisplay(); +} + +std::optional<gfx::Rect> GetInitialDetachedBoundsFromBrowser( + BrowserWindowInterface* browser, + const gfx::Size& target_size) { + if (!browser) { + return std::nullopt; + } + + // Set the origin so the top right of the glic widget meets the bottom left + // of the glic button. + GlicButton* glic_button = GlicButton::FromBrowser(browser); + if (!glic_button) { + return std::nullopt; + } + gfx::Rect glic_button_inset_bounds = glic_button->GetBoundsWithInset(); + + gfx::Point origin(glic_button_inset_bounds.x() - target_size.width() - + kInitialPositionBuffer, + glic_button_inset_bounds.bottom() + kInitialPositionBuffer); + gfx::Rect bounds = {origin, target_size}; + + return GlicWidget::IsWidgetLocationAllowed(bounds) + ? std::make_optional(bounds) + : std::nullopt; +} + +gfx::Rect GetInitialDetachedBoundsNoBrowser(const gfx::Size& target_size) { + // Get the default position offset equal distances from the top right corner + // of the work area (which excludes system UI such as the taskbar). + display::Display display = GetDisplayForOpeningDetached(); + gfx::Point top_right = display.work_area().top_right(); + int initial_x = + top_right.x() - target_size.width() - kDefaultDetachedTopRightDistance; + int initial_y = top_right.y() + kDefaultDetachedTopRightDistance; + return {{initial_x, initial_y}, target_size}; +} } // namespace class GlicWidgetDelegate : public views::WidgetDelegate { @@ -122,32 +184,64 @@ GlicWidget::~GlicWidget() = default; -// static +// Static gfx::Size GlicWidget::GetInitialSize() { return {features::kGlicInitialWidth.Get(), features::kGlicInitialHeight.Get()}; } -// static -gfx::Size GlicWidget::GetLastRequestedSizeClamped( - const GlicWidget* glic_widget, - std::optional<gfx::Size> glic_size) { - gfx::Size min = GlicWidget::GetInitialSize(); +gfx::Rect GlicWidget::GetInitialBounds(BrowserWindowInterface* browser, + gfx::Size target_size) { + std::optional<gfx::Rect> bounds_with_browser = + GetInitialDetachedBoundsFromBrowser(browser, target_size); + return bounds_with_browser.value_or( + GetInitialDetachedBoundsNoBrowser(target_size)); +} + +gfx::Size GlicWidget::ClampSize(std::optional<gfx::Size> current_size, + const GlicWidget* glic_widget) { + gfx::Size min = GetInitialSize(); if (glic_widget) { gfx::Size widget_min = glic_widget->GetMinimumSize(); if (!widget_min.IsEmpty()) { min = widget_min; } } - constexpr gfx::Size max(kMaxWidgetSize, kMaxWidgetSize); - gfx::Size result = glic_size.value_or(min); - result.SetToMax(min); - result.SetToMin(max); - return result; + gfx::Size clamped_size = current_size.value_or(min); + clamped_size.SetToMax(min); + clamped_size.SetToMin(max); + return clamped_size; } +bool GlicWidget::IsWidgetLocationAllowed(const gfx::Rect& bounds) { + const std::vector<display::Display>& displays = + display::Screen::Get()->GetAllDisplays(); + + // Calculate inset corners to allow part of the widget to be off screen. + std::array<gfx::Point, 4> inset_points = { + // top-left: Allow 40% on left and |kInitialPositionBuffer| on top. + gfx::Point(bounds.x() + bounds.width() * .4, + bounds.y() + kInitialPositionBuffer), + // top-right: Allow 40% on right and |kInitialPositionBuffer| on top. + gfx::Point(bounds.right() - bounds.width() * .4, + bounds.y() + kInitialPositionBuffer), + // bottom-left: Allow 40% on left and 70% on bottom. + gfx::Point(bounds.x() + bounds.width() * .4, + bounds.bottom() - bounds.height() * .7), + // bottom-right: Allow 40% on right and 70% on bottom. + gfx::Point(bounds.right() - bounds.width() * .4, + bounds.bottom() - bounds.height() * .7), + }; + // Check that all four points are on an existing display. + return std::ranges::all_of(inset_points, [&](gfx::Point p) { + return display::FindDisplayContainingPoint(displays, p) != displays.end(); + }); +} + +// End Static + std::unique_ptr<GlicWidget> GlicWidget::Create( Profile* profile, const gfx::Rect& initial_bounds,
diff --git a/chrome/browser/glic/widget/glic_widget.h b/chrome/browser/glic/widget/glic_widget.h index 6b3e57b5..0d8988a5 100644 --- a/chrome/browser/glic/widget/glic_widget.h +++ b/chrome/browser/glic/widget/glic_widget.h
@@ -18,7 +18,12 @@ #include "ui/gfx/geometry/size.h" #include "ui/views/widget/widget.h" +class BrowserWindowInterface; + namespace glic { +// Distance the detached window should be from the top and the right of the +// display when opened unassociated to a browser. +inline constexpr static int kDefaultDetachedTopRightDistance = 48; class GlicView; @@ -31,8 +36,20 @@ GlicWidget& operator=(const GlicWidget&) = delete; ~GlicWidget() override; + // Returns the initial size for the single instance floating window. static gfx::Size GetInitialSize(); + static gfx::Rect GetInitialBounds(BrowserWindowInterface* browser, + gfx::Size target_size); + + // Return `current_size` or the default minimum size if not provided. + // The return value is clamped to fit between the minimum and maximum sizes. + static gfx::Size ClampSize(std::optional<gfx::Size> current_size, + const GlicWidget* glic_widget); + + // True if |bounds| is an allowed position the Widget can be shown in. + static bool IsWidgetLocationAllowed(const gfx::Rect& bounds); + // Create a widget with the given bounds. static std::unique_ptr<GlicWidget> Create( Profile* profile,
diff --git a/chrome/browser/glic/widget/glic_window_controller.h b/chrome/browser/glic/widget/glic_window_controller.h index 2559cb3f..45ae556 100644 --- a/chrome/browser/glic/widget/glic_window_controller.h +++ b/chrome/browser/glic/widget/glic_window_controller.h
@@ -43,10 +43,6 @@ } namespace glic { -// Distance the detached window should be from the top and the right of the -// display when opened unassociated to a browser. -inline constexpr static int kDefaultDetachedTopRightDistance = 48; - DECLARE_CUSTOM_ELEMENT_EVENT_TYPE(kGlicWidgetAttached); class GlicWidget;
diff --git a/chrome/browser/glic/widget/glic_window_controller_impl.cc b/chrome/browser/glic/widget/glic_window_controller_impl.cc index 80b6bd9b2..cae7ed35 100644 --- a/chrome/browser/glic/widget/glic_window_controller_impl.cc +++ b/chrome/browser/glic/widget/glic_window_controller_impl.cc
@@ -89,7 +89,6 @@ // Default value for adding a buffer to the attachment zone. constexpr static int kAttachmentBuffer = 20; -constexpr static int kInitialPositionBuffer = 4; constexpr static int kDraggableAreaHeight = 44; constexpr static base::TimeDelta kAnimationDuration = base::Milliseconds(300); @@ -108,55 +107,6 @@ return panel_state; } -GlicButton* GetGlicButton(BrowserWindowInterface& browser) { - return BrowserElementsViews::From(&browser)->GetViewAs<glic::GlicButton>( - kGlicButtonElementId); -} - -display::Display GetDisplayForOpeningDetached() { - // Get the Display for the most recently active browser. If there was no - // recently active browser, use the primary display. - BrowserWindowInterface* const bwi = - GetLastActiveBrowserWindowInterfaceWithAnyProfile(); - ui::BaseWindow* const window = bwi ? bwi->GetWindow() : nullptr; - if (window) { - const std::optional<display::Display> widget_display = - views::Widget::GetWidgetForNativeWindow(window->GetNativeWindow()) - ->GetNearestDisplay(); - if (widget_display) { - return *widget_display; - } - } - return display::Screen::Get()->GetPrimaryDisplay(); -} - -// True if |bounds| is an allowed position the Widget can be shown in. -bool IsWidgetLocationAllowed(const gfx::Rect& bounds) { - const std::vector<display::Display>& displays = - display::Screen::Get()->GetAllDisplays(); - - // Calculate inset corners to allow part of the widget to be off screen. - std::array<gfx::Point, 4> inset_points = { - // top-left: Allow 40% on left and |kInitialPositionBuffer| on top. - gfx::Point(bounds.x() + bounds.width() * .4, - bounds.y() + kInitialPositionBuffer), - // top-right: Allow 40% on right and |kInitialPositionBuffer| on top. - gfx::Point(bounds.right() - bounds.width() * .4, - bounds.y() + kInitialPositionBuffer), - // bottom-left: Allow 40% on left and 70% on bottom. - gfx::Point(bounds.x() + bounds.width() * .4, - bounds.bottom() - bounds.height() * .7), - // bottom-right: Allow 40% on right and 70% on bottom. - gfx::Point(bounds.right() - bounds.width() * .4, - bounds.bottom() - bounds.height() * .7), - }; - - // Check that all four points are on an existing display. - return std::ranges::all_of(inset_points, [&](gfx::Point p) { - return display::FindDisplayContainingPoint(displays, p) != displays.end(); - }); -} - std::optional<int> GetOptionalIntPreference(PrefService* prefs, std::string_view path) { const PrefService::Preference& pref = @@ -807,12 +757,12 @@ } gfx::Rect GlicWindowControllerImpl::GetInitialBounds(Browser* browser) { - gfx::Size target_size = - GlicWidget::GetLastRequestedSizeClamped(GetGlicWidget(), glic_size_); + gfx::Size target_size = GlicWidget::ClampSize(glic_size_, GetGlicWidget()); // Reset previous position if it results in an invalid location. if (previous_position_.has_value() && - !IsWidgetLocationAllowed({previous_position_.value(), target_size})) { + !GlicWidget::IsWidgetLocationAllowed( + {previous_position_.value(), target_size})) { previous_position_.reset(); } // Use the previous position if there is one. @@ -820,45 +770,7 @@ return {previous_position_.value(), target_size}; } - std::optional<gfx::Rect> bounds_with_browser = - GetInitialDetachedBoundsFromBrowser(browser, target_size); - return bounds_with_browser.value_or( - GetInitialDetachedBoundsNoBrowser(target_size)); -} - -gfx::Rect GlicWindowControllerImpl::GetInitialDetachedBoundsNoBrowser( - const gfx::Size& target_size) { - // Get the default position offset equal distances from the top right corner - // of the work area (which excludes system UI such as the taskbar). - display::Display display = GetDisplayForOpeningDetached(); - gfx::Point top_right = display.work_area().top_right(); - int initial_x = - top_right.x() - target_size.width() - kDefaultDetachedTopRightDistance; - int initial_y = top_right.y() + kDefaultDetachedTopRightDistance; - return {{initial_x, initial_y}, target_size}; -} - -std::optional<gfx::Rect> -GlicWindowControllerImpl::GetInitialDetachedBoundsFromBrowser( - Browser* browser, - const gfx::Size& target_size) { - if (!browser) { - return std::nullopt; - } - - // Set the origin so the top right of glic meets the bottom left of the glic - // button. - GlicButton* glic_button = GetGlicButton(*browser); - CHECK(glic_button); - gfx::Rect glic_button_inset_bounds = glic_button->GetBoundsWithInset(); - - gfx::Point origin(glic_button_inset_bounds.x() - target_size.width() - - kInitialPositionBuffer, - glic_button_inset_bounds.bottom() + kInitialPositionBuffer); - gfx::Rect bounds = {origin, target_size}; - - return IsWidgetLocationAllowed(bounds) ? std::make_optional(bounds) - : std::nullopt; + return GlicWidget::GetInitialBounds(browser, target_size); } void GlicWindowControllerImpl::MaybeResetPanelPostionOnShow( @@ -1048,7 +960,7 @@ // Trigger custom event for testing. views::ElementTrackerViews::GetInstance()->NotifyCustomEvent( - kGlicWidgetAttached, GetGlicButton(*browser)); + kGlicWidgetAttached, GlicButton::FromBrowser(browser)); AfterViewShown(); } @@ -1070,8 +982,8 @@ // animate this transition. if (in_resizable_state && !user_resizing_) { glic_window_animator_->AnimateSize( - GlicWidget::GetLastRequestedSizeClamped(GetGlicWidget(), glic_size_), - duration, std::move(callback)); + GlicWidget::ClampSize(glic_size_, GetGlicWidget()), duration, + std::move(callback)); } else { // If the glic window is closed, or the widget isn't ready (e.g. because // it's currently still animating closed) immediately post the callback. @@ -1380,7 +1292,7 @@ scoped_glic_button_indicator_.reset(); return; } - GlicButton* glic_button = GetGlicButton(*browser); + GlicButton* glic_button = GlicButton::FromBrowser(browser); // If there isn't an existing scoped indicator for this button, create one. if (!scoped_glic_button_indicator_ || scoped_glic_button_indicator_->GetGlicButton() != glic_button) { @@ -1561,8 +1473,7 @@ if (!IsDetached()) { return; } - const auto target_size = - GlicWidget::GetLastRequestedSizeClamped(GetGlicWidget(), glic_size_); + const auto target_size = GlicWidget::ClampSize(glic_size_, GetGlicWidget()); if (target_size != glic_window_animator_->GetCurrentTargetBounds().size()) { glic_window_animator_->AnimateSize( target_size, animate ? kAnimationDuration : base::Milliseconds(0),
diff --git a/chrome/browser/glic/widget/glic_window_controller_impl.h b/chrome/browser/glic/widget/glic_window_controller_impl.h index 313d27d..0e40e3f 100644 --- a/chrome/browser/glic/widget/glic_window_controller_impl.h +++ b/chrome/browser/glic/widget/glic_window_controller_impl.h
@@ -187,16 +187,6 @@ // on the Mac, all special activation and visibility properties are cleared. void SetGlicWindowToFloatingMode(bool floating); - // Return the default detached bounds which are just below the tab strip - // button on the active browser. - std::optional<gfx::Rect> GetInitialDetachedBoundsFromBrowser( - Browser* browser, - const gfx::Size& target_size); - - // Return the default detached bounds when there is no active browser. The - // position is relative to the top right of the current display. - gfx::Rect GetInitialDetachedBoundsNoBrowser(const gfx::Size& target_size); - // Check if the panel position should be reset based on `window_config_`. // Update `window_config_` that the panel was shown. void MaybeResetPanelPostionOnShow(mojom::InvocationSource source);
diff --git a/chrome/browser/new_tab_page/ntp_promo/ntp_promo_interactive_uitest.cc b/chrome/browser/new_tab_page/ntp_promo/ntp_promo_interactive_uitest.cc index 4b2f2fb..0fa6c6f6 100644 --- a/chrome/browser/new_tab_page/ntp_promo/ntp_promo_interactive_uitest.cc +++ b/chrome/browser/new_tab_page/ntp_promo/ntp_promo_interactive_uitest.cc
@@ -50,6 +50,10 @@ #include "ui/views/interaction/polling_view_observer.h" #include "url/gurl.h" +#if BUILDFLAG(IS_MAC) +#include "base/mac/mac_util.h" +#endif // BUILDFLAG(IS_MAC) + namespace { using ntp_promo::mojom::ShowNtpPromosResult; @@ -253,15 +257,6 @@ } } - auto WaitForAndScrollToElement( - const ui::ElementIdentifier& ntp_id, - const WebContentsInteractionTestUtil::DeepQuery& query) { - auto steps = Steps(WaitForElementExists(ntp_id, query), - ScrollIntoView(ntp_id, query)); - AddDescriptionPrefix(steps, __func__); - return steps; - } - auto GetActionButtonPath() const { return GetFirstPromoPath() + kActionIconId; } @@ -271,7 +266,7 @@ auto WaitForPromoIcon(std::string_view expected_icon) { const auto path = GetPromoIconPath(); auto steps = Steps( - WaitForAndScrollToElement(kNtpElementId, path), + WaitForElementVisible(kNtpElementId, path), // Verify the icon shows the correct image. CheckJsResultAt(kNtpElementId, path, "el => el.icon", expected_icon)); AddDescriptionPrefix(steps, __func__); @@ -285,16 +280,14 @@ case Eligibility::kEligible: steps += WaitForPromoIcon(std::string("ntp-promo:") + std::string(expected_icon)); - steps += - WaitForAndScrollToElement(kNtpElementId, GetActionButtonPath()); + steps += WaitForElementVisible(kNtpElementId, GetActionButtonPath()); break; case Eligibility::kCompleted: steps += WaitForPromoIcon("cr:check"); if (GetParam().promo_type == NtpBrowserPromoType::kSimple) { - steps += EnsureNotPresent(kNtpElementId, GetActionButtonPath()); + steps += EnsureNotVisible(kNtpElementId, GetActionButtonPath()); } else { - steps += - WaitForAndScrollToElement(kNtpElementId, GetActionButtonPath()); + steps += WaitForElementVisible(kNtpElementId, GetActionButtonPath()); } break; case Eligibility::kIneligible: @@ -381,6 +374,13 @@ }); IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, TestPromoEligible) { + // TODO(crbug.com/445214951): Flaky on mac-vm builder for macOS 15. +#if BUILDFLAG(IS_MAC) + if (base::mac::MacOSMajorVersion() == 15 && base::mac::IsVirtualMachine()) { + GTEST_SKIP() << "Disabled on macOS Sequoia for virtual machines."; + } +#endif // BUILDFLAG(IS_MAC) + InstallTestPromo(Eligibility::kEligible); RunTestSequence( InstrumentTab(kNtpElementId), @@ -403,7 +403,13 @@ CheckShowMetrics(ShowNtpPromosResult::kShown)); } -IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, TestPromoCompleted) { +// TODO(crbug.com/448993914): Re-enable this test +#if BUILDFLAG(IS_MAC) +#define MAYBE_TestPromoCompleted DISABLED_TestPromoCompleted +#else +#define MAYBE_TestPromoCompleted TestPromoCompleted +#endif +IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, MAYBE_TestPromoCompleted) { InstallTestPromo(Eligibility::kCompleted); RunTestSequence( InstrumentTab(kNtpElementId), @@ -415,7 +421,7 @@ Then(WaitForPromoVisible(Eligibility::kCompleted, kSignInIconName), VerifyTestPromoText(), CheckShowMetrics(ShowNtpPromosResult::kShown)), - Else(EnsureNotPresent(kNtpElementId, GetFirstPromoPath()), + Else(EnsureNotVisible(kNtpElementId, GetFirstPromoPath()), CheckShowMetrics(ShowNtpPromosResult::kNotShownNoPromos)))); } @@ -449,8 +455,8 @@ InstallTestPromo(Eligibility::kEligible); RunTestSequence(InstrumentTab(kNtpElementId), NavigateWebContents(kNtpElementId, GURL(kNtpURL)), - WaitForAndScrollToElement(kNtpElementId, kPathToModules), - EnsureNotPresent(kNtpElementId, GetFirstPromoPath()), + WaitForElementVisible(kNtpElementId, kPathToModules), + EnsureNotVisible(kNtpElementId, GetFirstPromoPath()), CheckShowMetrics(ShowNtpPromosResult::kNotShownDueToPolicy)); } @@ -466,7 +472,7 @@ InstallTestPromo(Eligibility::kEligible); RunTestSequence(InstrumentTab(kNtpElementId), NavigateWebContents(kNtpElementId, GURL(kNtpURL)), - WaitForAndScrollToElement(kNtpElementId, GetFirstPromoPath()), + WaitForElementVisible(kNtpElementId, GetFirstPromoPath()), EnsureNotVisible(kNtpElementId, kPathToModules), CheckShowMetrics(ShowNtpPromosResult::kShown)); } @@ -476,7 +482,14 @@ // or run these tests on ChromeOS. #if !BUILDFLAG(IS_CHROMEOS) -IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, SigninPromoAppearsAndIsClickable) { +// TODO(crbug.com/448993914): Re-enable this test +#if BUILDFLAG(IS_MAC) +#define MAYBE_SigninPromoAppearsAndIsClickable \ + DISABLED_SigninPromoAppearsAndIsClickable +#else +#define MAYBE_SigninPromoAppearsAndIsClickable SigninPromoAppearsAndIsClickable +#endif +IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, MAYBE_SigninPromoAppearsAndIsClickable) { ClearRegisteredPromosExcept(kNtpSignInPromoId); RunTestSequence( InstrumentTab(kNtpElementId), @@ -500,7 +513,16 @@ #endif // !BUILDFLAG(IS_CHROMEOS) -IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, ExtensionsPromoAppearsAndIsClickable) { +// TODO(crbug.com/448993914): Re-enable this test +#if BUILDFLAG(IS_MAC) +#define MAYBE_ExtensionsPromoAppearsAndIsClickable \ + DISABLED_ExtensionsPromoAppearsAndIsClickable +#else +#define MAYBE_ExtensionsPromoAppearsAndIsClickable \ + ExtensionsPromoAppearsAndIsClickable +#endif +IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, + MAYBE_ExtensionsPromoAppearsAndIsClickable) { ClearRegisteredPromosExcept(kNtpExtensionsPromoId); RunTestSequence( InstrumentTab(kNtpElementId), @@ -522,8 +544,16 @@ // TODD(https://crbug.com/433607240): Check model, histograms. } +// TODO(crbug.com/448993914): Re-enable this test +#if BUILDFLAG(IS_MAC) +#define MAYBE_CustomizationPromoAppearsAndIsClickable \ + DISABLED_CustomizationPromoAppearsAndIsClickable +#else +#define MAYBE_CustomizationPromoAppearsAndIsClickable \ + CustomizationPromoAppearsAndIsClickable +#endif IN_PROC_BROWSER_TEST_P(NtpPromoUiTest, - CustomizationPromoAppearsAndIsClickable) { + MAYBE_CustomizationPromoAppearsAndIsClickable) { ClearRegisteredPromosExcept(kNtpCustomizationPromoId); RunTestSequence( InstrumentTab(kNtpElementId), @@ -634,7 +664,8 @@ RunTestSequence( InstrumentTab(kNtpElementId), NavigateWebContents(kNtpElementId, GURL(kNtpURL)), - WaitForAndScrollToElement(kNtpElementId, GetFirstPromoPath()), + WaitForElementVisible(kNtpElementId, GetFirstPromoPath()), + ScrollIntoView(kNtpElementId, GetPromosPath()), SetOnIncompatibleAction(OnIncompatibleAction::kSkipTest, "Screenshots not captured on this platform."), ScreenshotWebUi(kNtpElementId, GetPromosPath(),
diff --git a/chrome/browser/page_content_annotations/android/page_content_extraction_tab_model_observer_android.h b/chrome/browser/page_content_annotations/android/page_content_extraction_tab_model_observer_android.h index be274ee2..afb9471 100644 --- a/chrome/browser/page_content_annotations/android/page_content_extraction_tab_model_observer_android.h +++ b/chrome/browser/page_content_annotations/android/page_content_extraction_tab_model_observer_android.h
@@ -5,6 +5,7 @@ #ifndef CHROME_BROWSER_PAGE_CONTENT_ANNOTATIONS_ANDROID_PAGE_CONTENT_EXTRACTION_TAB_MODEL_OBSERVER_ANDROID_H_ #define CHROME_BROWSER_PAGE_CONTENT_ANNOTATIONS_ANDROID_PAGE_CONTENT_EXTRACTION_TAB_MODEL_OBSERVER_ANDROID_H_ +#include "base/memory/raw_ptr.h" #include "base/scoped_multi_source_observation.h" #include "base/scoped_observation.h" #include "base/supports_user_data.h" @@ -49,7 +50,7 @@ private: void RunStartupMetricsComputation(); - raw_ptr<Profile> profile_; + const raw_ptr<Profile> profile_; const raw_ptr<PageContentExtractionService> service_; base::ScopedMultiSourceObservation<TabModel, TabModelObserver>
diff --git a/chrome/browser/page_content_annotations/annotate_page_content_request.cc b/chrome/browser/page_content_annotations/annotate_page_content_request.cc index d6de0d9..f1c0111 100644 --- a/chrome/browser/page_content_annotations/annotate_page_content_request.cc +++ b/chrome/browser/page_content_annotations/annotate_page_content_request.cc
@@ -6,7 +6,6 @@ #include "base/feature_list.h" #include "base/metrics/histogram_macros.h" -#include "base/notimplemented.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" #include "base/trace_event/trace_event.h" @@ -61,10 +60,8 @@ if (TabAndroid* tab = TabAndroid::FromWebContents(web_contents)) { return tab->GetAndroidId(); } -#else - // Implement an usable tab ID for other platforms. - NOTIMPLEMENTED(); #endif + // TODO(440643544): Implement an usable tab ID for other platforms. return std::nullopt; }
diff --git a/chrome/browser/page_content_annotations/page_content_annotations_service_browsertest.cc b/chrome/browser/page_content_annotations/page_content_annotations_service_browsertest.cc index f50bd46b7..0883ba4 100644 --- a/chrome/browser/page_content_annotations/page_content_annotations_service_browsertest.cc +++ b/chrome/browser/page_content_annotations/page_content_annotations_service_browsertest.cc
@@ -77,7 +77,7 @@ : public PageContentAnnotationsService::PageContentAnnotationsObserver { public: void OnPageContentAnnotated( - const GURL& url, + const HistoryVisit& visit, const PageContentAnnotationsResult& result) override { last_page_content_annotations_result_ = result; }
diff --git a/chrome/browser/page_content_annotations/page_content_extraction_service.cc b/chrome/browser/page_content_annotations/page_content_extraction_service.cc index 9078e22..6d40050f71 100644 --- a/chrome/browser/page_content_annotations/page_content_extraction_service.cc +++ b/chrome/browser/page_content_annotations/page_content_extraction_service.cc
@@ -45,12 +45,14 @@ PageContentExtractionService::PageContentExtractionService( os_crypt_async::OSCryptAsync* os_crypt_async, - const base::FilePath& profile_path) { - if (base::FeatureList::IsEnabled(features::kPageContentCache)) { - page_content_cache_handler_ = - std::make_unique<PageContentCacheHandler>(os_crypt_async, profile_path); - } -} + const base::FilePath& profile_path) + : is_page_content_cache_enabled_( + base::FeatureList::IsEnabled(features::kPageContentCache)), + page_content_cache_handler_( + is_page_content_cache_enabled_ + ? std::make_unique<PageContentCacheHandler>(os_crypt_async, + profile_path) + : nullptr) {} PageContentExtractionService::~PageContentExtractionService() { ClearAllUserData(); @@ -80,7 +82,7 @@ observer.OnPageContentExtracted(page, page_content); } - if (!page_content_cache_handler_) { + if (!is_page_content_cache_enabled_) { return; } @@ -102,7 +104,7 @@ } void PageContentExtractionService::OnTabClosed(int64_t tab_id) { - if (page_content_cache_handler_) { + if (is_page_content_cache_enabled_) { page_content_cache_handler_->OnTabClosed(tab_id); } } @@ -111,7 +113,7 @@ std::optional<int64_t> tab_id, content::WebContents* web_contents, content::Visibility visibility) { - if (page_content_cache_handler_) { + if (is_page_content_cache_enabled_) { std::optional<ExtractedPageContentResult> extracted_result = GetCachedContentsFromWebContents(web_contents); if (extracted_result) { @@ -125,14 +127,14 @@ void PageContentExtractionService::OnNewNavigation( std::optional<int64_t> tab_id, content::WebContents* web_contents) { - if (page_content_cache_handler_) { + if (is_page_content_cache_enabled_) { page_content_cache_handler_->OnNewNavigation( tab_id, ToWebStateWrapper(web_contents)); } } PageContentCache* PageContentExtractionService::GetPageContentCache() { - return page_content_cache_handler_ + return is_page_content_cache_enabled_ ? page_content_cache_handler_->page_content_cache() : nullptr; }
diff --git a/chrome/browser/page_content_annotations/page_content_extraction_service.h b/chrome/browser/page_content_annotations/page_content_extraction_service.h index 74f6d95..9de0ce6 100644 --- a/chrome/browser/page_content_annotations/page_content_extraction_service.h +++ b/chrome/browser/page_content_annotations/page_content_extraction_service.h
@@ -89,7 +89,8 @@ base::ObserverList<Observer> observers_; - std::unique_ptr<PageContentCacheHandler> page_content_cache_handler_; + const bool is_page_content_cache_enabled_; + const std::unique_ptr<PageContentCacheHandler> page_content_cache_handler_; }; } // namespace page_content_annotations
diff --git a/chrome/browser/pdf/pdf_extension_test.cc b/chrome/browser/pdf/pdf_extension_test.cc index 3c96fe1..b3a6a3d 100644 --- a/chrome/browser/pdf/pdf_extension_test.cc +++ b/chrome/browser/pdf/pdf_extension_test.cc
@@ -47,12 +47,8 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_finder.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/tabs/tab_enums.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" -#include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/zoom/chrome_zoom_level_prefs.h" #include "chrome/common/chrome_features.h" #include "chrome/common/chrome_paths.h" @@ -1263,7 +1259,7 @@ // Zoom PDF via script. #if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC) - EXPECT_FALSE(ZoomBubbleCoordinator::From(browser())->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); #endif ASSERT_TRUE(content::ExecJs(extension_host, "while (viewer.viewport.getZoom() < 1) {" @@ -1275,7 +1271,7 @@ watcher.Wait(); #if defined(TOOLKIT_VIEWS) && !BUILDFLAG(IS_MAC) - EXPECT_FALSE(ZoomBubbleCoordinator::From(browser())->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); #endif }
diff --git a/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc b/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc index 6b258aa1..4826c2d 100644 --- a/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc +++ b/chrome/browser/preloading/prefetch/search_prefetch/search_prefetch_service_browsertest.cc
@@ -4295,9 +4295,10 @@ void SetUpOnMainThread() override { // Close normal browser and switch the test's browser instance to an // incognito instance. - Browser* incognito = CreateIncognitoBrowser(browser()->profile()); + BrowserWindowInterface* const incognito = + CreateIncognitoBrowser(browser()->profile()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(incognito); ASSERT_EQ(browser(), incognito); SearchPrefetchBaseBrowserTest::SetUpOnMainThread();
diff --git a/chrome/browser/resources/BUILD.gn b/chrome/browser/resources/BUILD.gn index 59843eaa..d90f15b 100644 --- a/chrome/browser/resources/BUILD.gn +++ b/chrome/browser/resources/BUILD.gn
@@ -62,6 +62,7 @@ "privacy_sandbox:resources", "privacy_sandbox/internals:resources", "profile_internals:resources", + "reload_button:resources", "search_engine_choice:resources", "settings:resources", "settings_shared:resources",
diff --git a/chrome/browser/resources/ash/settings/os_languages_page/input_page.html b/chrome/browser/resources/ash/settings/os_languages_page/input_page.html index f1f12388d..79c3955b 100644 --- a/chrome/browser/resources/ash/settings/os_languages_page/input_page.html +++ b/chrome/browser/resources/ash/settings/os_languages_page/input_page.html
@@ -213,8 +213,7 @@ </template> <template is="dom-if" if="[[hasOptionsPageInSettings_(item.id)]]"> - <div class="internal-wrapper" - hidden="[[!item.hasOptionsPage]]"> + <div class="internal-wrapper"> <cr-icon-button class="subpage-arrow" aria-label$="[[getOpenOptionsPageLabel_( item.displayName)]]"
diff --git a/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json.jinja2 b/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json.jinja2 index 0ad66318..9fe13e8 100644 --- a/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json.jinja2 +++ b/chrome/browser/resources/chromeos/input_method/google_xkb_manifest.json.jinja2
@@ -56,8 +56,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=xkb:us::eng" + ] }, { "name": "__MSG_keyboard_indonesian__", @@ -68,8 +67,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=xkb:us::ind" + ] }, { "name": "__MSG_keyboard_filipino__", @@ -80,8 +78,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=xkb:us::fil" + ] }, { "name": "__MSG_keyboard_malay__", @@ -92,8 +89,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=xkb:us::msa" + ] }, { "name": "__MSG_keyboard_us_international__", @@ -105,8 +101,7 @@ ], "layouts": [ "us(intl)" - ], - "options_page": "hmm_options.html?code=xkb:us:intl:eng" + ] }, { "name": "__MSG_keyboard_us_international_pc__", @@ -118,8 +113,7 @@ ], "layouts": [ "us(intl_pc)" - ], - "options_page": "hmm_options.html?code=xkb:us:intl_pc:eng" + ] }, { "name": "__MSG_keyboard_netherlands__", @@ -130,8 +124,7 @@ ], "layouts": [ "us(intl)" - ], - "options_page": "hmm_options.html?code=xkb:us:intl:nld" + ] }, { "name": "__MSG_keyboard_netherlands_us_international_pc__", @@ -142,8 +135,7 @@ ], "layouts": [ "us(intl_pc)" - ], - "options_page": "hmm_options.html?code=xkb:us:intl_pc:nld" + ] }, { "name": "__MSG_keyboard_us_extended__", @@ -155,8 +147,7 @@ ], "layouts": [ "us(altgr-intl)" - ], - "options_page": "hmm_options.html?code=xkb:us:altgr-intl:eng" + ] }, { "name": "__MSG_keyboard_us_dvorak__", @@ -168,8 +159,7 @@ ], "layouts": [ "us(dvorak)" - ], - "options_page": "hmm_options.html?code=xkb:us:dvorak:eng" + ] }, { "name": "__MSG_keyboard_us_dvp__", @@ -181,8 +171,7 @@ ], "layouts": [ "us(dvp)" - ], - "options_page": "hmm_options.html?code=xkb:us:dvp:eng" + ] }, { "name": "__MSG_keyboard_us_colemak__", @@ -194,8 +183,7 @@ ], "layouts": [ "us(colemak)" - ], - "options_page": "hmm_options.html?code=xkb:us:colemak:eng" + ] }, { "name": "__MSG_keyboard_us_workman__", @@ -207,8 +195,7 @@ ], "layouts": [ "us(workman)" - ], - "options_page": "hmm_options.html?code=xkb:us:workman:eng" + ] }, { "name": "__MSG_keyboard_us_workman_international__", @@ -220,8 +207,7 @@ ], "layouts": [ "us(workman-intl)" - ], - "options_page": "hmm_options.html?code=xkb:us:workman-intl:eng" + ] }, { "name": "__MSG_keyboard_belgian_dutch__", @@ -231,8 +217,7 @@ ], "layouts": [ "be" - ], - "options_page": "hmm_options.html?code=xkb:be::nld" + ] }, { "name": "__MSG_keyboard_french__", @@ -243,8 +228,7 @@ ], "layouts": [ "fr(oss)" - ], - "options_page": "hmm_options.html?code=xkb:fr::fra" + ] }, { "name": "__MSG_keyboard_french_bepo__", @@ -255,8 +239,7 @@ ], "layouts": [ "fr(bepo)" - ], - "options_page": "hmm_options.html?code=xkb:fr:bepo:fra" + ] }, { "name": "__MSG_keyboard_belgian_french__", @@ -266,8 +249,7 @@ ], "layouts": [ "be" - ], - "options_page": "hmm_options.html?code=xkb:be::fra" + ] }, { "name": "__MSG_keyboard_faroese__", @@ -277,8 +259,7 @@ ], "layouts": [ "fo" - ], - "options_page": "hmm_options.html?code=xkb:fo::fao" + ] }, { "name": "__MSG_keyboard_canadian_french__", @@ -289,8 +270,7 @@ ], "layouts": [ "ca" - ], - "options_page": "hmm_options.html?code=xkb:ca::fra" + ] }, { "name": "__MSG_keyboard_swiss_french__", @@ -301,8 +281,7 @@ ], "layouts": [ "ch(fr)" - ], - "options_page": "hmm_options.html?code=xkb:ch:fr:fra" + ] }, { "name": "__MSG_keyboard_canadian_multilingual__", @@ -313,8 +292,7 @@ ], "layouts": [ "ca(multix)" - ], - "options_page": "hmm_options.html?code=xkb:ca:multix:fra" + ] }, { "name": "__MSG_keyboard_german__", @@ -327,8 +305,7 @@ ], "layouts": [ "de" - ], - "options_page": "hmm_options.html?code=xkb:de::ger" + ] }, { "name": "__MSG_keyboard_german_neo_2__", @@ -342,8 +319,7 @@ ], "layouts": [ "de(neo)" - ], - "options_page": "hmm_options.html?code=xkb:de:neo:ger" + ] }, { "name": "__MSG_keyboard_belgian_german__", @@ -353,8 +329,7 @@ ], "layouts": [ "be" - ], - "options_page": "hmm_options.html?code=xkb:be::ger" + ] }, { "name": "__MSG_keyboard_swiss__", @@ -365,8 +340,7 @@ ], "layouts": [ "ch" - ], - "options_page": "hmm_options.html?code=xkb:ch::ger" + ] }, { "name": "__MSG_keyboard_japanese__", @@ -377,8 +351,7 @@ ], "layouts": [ "jp" - ], - "options_page": "hmm_options.html?code=xkb:jp::jpn" + ] }, { "name": "__MSG_keyboard_russian__", @@ -388,8 +361,7 @@ ], "layouts": [ "ru" - ], - "options_page": "hmm_options.html?code=xkb:ru::rus" + ] }, { "name": "__MSG_keyboard_russian_phonetic__", @@ -399,8 +371,7 @@ ], "layouts": [ "ru(phonetic)" - ], - "options_page": "hmm_options.html?code=xkb:ru:phonetic:rus" + ] }, { "name": "__MSG_keyboard_brazilian__", @@ -411,8 +382,7 @@ ], "layouts": [ "br" - ], - "options_page": "hmm_options.html?code=xkb:br::por" + ] }, { "name": "__MSG_keyboard_portuguese_us_international__", @@ -423,8 +393,7 @@ ], "layouts": [ "us(intl)" - ], - "options_page": "hmm_options.html?code=xkb:us:intl:por" + ] }, { "name": "__MSG_keyboard_portuguese_us_international_pc__", @@ -435,8 +404,7 @@ ], "layouts": [ "us(intl_pc)" - ], - "options_page": "hmm_options.html?code=xkb:us:intl_pc:por" + ] }, { "name": "__MSG_keyboard_bulgarian__", @@ -446,8 +414,7 @@ ], "layouts": [ "bg" - ], - "options_page": "hmm_options.html?code=xkb:bg::bul" + ] }, { "name": "__MSG_keyboard_bulgarian_phonetic__", @@ -457,8 +424,7 @@ ], "layouts": [ "bg(phonetic)" - ], - "options_page": "hmm_options.html?code=xkb:bg:phonetic:bul" + ] }, { "name": "__MSG_keyboard_canadian_english__", @@ -469,8 +435,7 @@ ], "layouts": [ "ca(eng)" - ], - "options_page": "hmm_options.html?code=xkb:ca:eng:eng" + ] }, { "name": "__MSG_keyboard_czech__", @@ -480,8 +445,7 @@ ], "layouts": [ "cz" - ], - "options_page": "hmm_options.html?code=xkb:cz::cze" + ] }, { "name": "__MSG_keyboard_czech_qwerty__", @@ -492,8 +456,7 @@ ], "layouts": [ "cz(qwerty)" - ], - "options_page": "hmm_options.html?code=xkb:cz:qwerty:cze" + ] }, { "name": "__MSG_keyboard_estonian__", @@ -503,8 +466,7 @@ ], "layouts": [ "ee" - ], - "options_page": "hmm_options.html?code=xkb:ee::est" + ] }, { "name": "__MSG_keyboard_spanish__", @@ -515,8 +477,7 @@ ], "layouts": [ "es" - ], - "options_page": "hmm_options.html?code=xkb:es::spa" + ] }, { "name": "__MSG_keyboard_catalan__", @@ -527,8 +488,7 @@ ], "layouts": [ "es(cat)" - ], - "options_page": "hmm_options.html?code=xkb:es:cat:cat" + ] }, { "name": "__MSG_keyboard_danish__", @@ -538,8 +498,7 @@ ], "layouts": [ "dk" - ], - "options_page": "hmm_options.html?code=xkb:dk::dan" + ] }, { "name": "__MSG_keyboard_greek__", @@ -549,8 +508,7 @@ ], "layouts": [ "gr" - ], - "options_page": "hmm_options.html?code=xkb:gr::gre" + ] }, { "name": "__MSG_keyboard_hebrew__", @@ -560,8 +518,7 @@ ], "layouts": [ "il" - ], - "options_page": "hmm_options.html?code=xkb:il::heb" + ] }, { "name": "__MSG_keyboard_latin_american__", @@ -573,8 +530,7 @@ ], "layouts": [ "latam" - ], - "options_page": "hmm_options.html?code=xkb:latam::spa" + ] }, { "name": "__MSG_keyboard_lithuanian__", @@ -584,8 +540,7 @@ ], "layouts": [ "lt" - ], - "options_page": "hmm_options.html?code=xkb:lt::lit" + ] }, { "name": "__MSG_keyboard_latvian__", @@ -595,8 +550,7 @@ ], "layouts": [ "lv(apostrophe)" - ], - "options_page": "hmm_options.html?code=xkb:lv:apostrophe:lav" + ] }, { "name": "__MSG_keyboard_croatian__", @@ -606,8 +560,7 @@ ], "layouts": [ "hr" - ], - "options_page": "hmm_options.html?code=xkb:hr::scr" + ] }, { "name": "__MSG_keyboard_uk__", @@ -618,8 +571,7 @@ ], "layouts": [ "gb(extd)" - ], - "options_page": "hmm_options.html?code=xkb:gb:extd:eng" + ] }, { "name": "__MSG_keyboard_english_india__", @@ -631,8 +583,7 @@ ], "layouts": [ "in(eng)" - ], - "options_page": "hmm_options.html?code=xkb:in::eng" + ] }, { "name": "__MSG_keyboard_english_pakistan__", @@ -644,8 +595,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=xkb:pk::eng" + ] }, { "name": "__MSG_keyboard_english_south_africa__", @@ -657,8 +607,7 @@ ], "layouts": [ "gb(extd)" - ], - "options_page": "hmm_options.html?code=xkb:za:gb:eng" + ] }, { "name": "__MSG_keyboard_uk_dvorak__", @@ -670,8 +619,7 @@ ], "layouts": [ "gb(dvorak)" - ], - "options_page": "hmm_options.html?code=xkb:gb:dvorak:eng" + ] }, { "name": "__MSG_keyboard_finnish__", @@ -681,8 +629,7 @@ ], "layouts": [ "fi" - ], - "options_page": "hmm_options.html?code=xkb:fi::fin" + ] }, { "name": "__MSG_keyboard_hungarian__", @@ -692,8 +639,7 @@ ], "layouts": [ "hu" - ], - "options_page": "hmm_options.html?code=xkb:hu::hun" + ] }, { "name": "__MSG_keyboard_hungarian_qwerty__", @@ -703,8 +649,7 @@ ], "layouts": [ "hu(qwerty)" - ], - "options_page": "hmm_options.html?code=xkb:hu:qwerty:hun" + ] }, { "name": "__MSG_keyboard_italian__", @@ -715,8 +660,7 @@ ], "layouts": [ "it" - ], - "options_page": "hmm_options.html?code=xkb:it::ita" + ] }, { "name": "__MSG_keyboard_icelandic__", @@ -726,8 +670,7 @@ ], "layouts": [ "is" - ], - "options_page": "hmm_options.html?code=xkb:is::ice" + ] }, { "name": "__MSG_keyboard_norwegian__", @@ -739,8 +682,7 @@ ], "layouts": [ "no" - ], - "options_page": "hmm_options.html?code=xkb:no::nob" + ] }, { "name": "__MSG_keyboard_polish__", @@ -750,8 +692,7 @@ ], "layouts": [ "pl" - ], - "options_page": "hmm_options.html?code=xkb:pl::pol" + ] }, { "name": "__MSG_keyboard_portuguese__", @@ -762,8 +703,7 @@ ], "layouts": [ "pt" - ], - "options_page": "hmm_options.html?code=xkb:pt::por" + ] }, { "name": "__MSG_keyboard_romanian__", @@ -773,8 +713,7 @@ ], "layouts": [ "ro" - ], - "options_page": "hmm_options.html?code=xkb:ro::rum" + ] }, { "name": "__MSG_keyboard_romanian_standard__", @@ -784,8 +723,7 @@ ], "layouts": [ "ro(std)" - ], - "options_page": "hmm_options.html?code=xkb:ro:std:rum" + ] }, { "name": "__MSG_keyboard_swedish__", @@ -795,8 +733,7 @@ ], "layouts": [ "se" - ], - "options_page": "hmm_options.html?code=xkb:se::swe" + ] }, { "name": "__MSG_keyboard_slovak__", @@ -806,8 +743,7 @@ ], "layouts": [ "sk" - ], - "options_page": "hmm_options.html?code=xkb:sk::slo" + ] }, { "name": "__MSG_keyboard_slovenian__", @@ -817,8 +753,7 @@ ], "layouts": [ "si" - ], - "options_page": "hmm_options.html?code=xkb:si::slv" + ] }, { "name": "__MSG_keyboard_serbian__", @@ -828,8 +763,7 @@ ], "layouts": [ "rs" - ], - "options_page": "hmm_options.html?code=xkb:rs::srp" + ] }, { "name": "__MSG_keyboard_turkish__", @@ -839,8 +773,7 @@ ], "layouts": [ "tr" - ], - "options_page": "hmm_options.html?code=xkb:tr::tur" + ] }, { "name": "__MSG_keyboard_turkish_f__", @@ -850,8 +783,7 @@ ], "layouts": [ "tr(f)" - ], - "options_page": "hmm_options.html?code=xkb:tr:f:tur" + ] }, { "name": "__MSG_keyboard_ukrainian__", @@ -861,8 +793,7 @@ ], "layouts": [ "ua" - ], - "options_page": "hmm_options.html?code=xkb:ua::ukr" + ] }, { "name": "__MSG_keyboard_belarusian__", @@ -872,8 +803,7 @@ ], "layouts": [ "by" - ], - "options_page": "hmm_options.html?code=xkb:by::bel" + ] }, { "name": "__MSG_keyboard_armenian_phonetic__", @@ -883,8 +813,7 @@ ], "layouts": [ "am(phonetic)" - ], - "options_page": "hmm_options.html?code=xkb:am:phonetic:arm" + ] }, { "name": "__MSG_keyboard_georgian__", @@ -894,8 +823,7 @@ ], "layouts": [ "ge" - ], - "options_page": "hmm_options.html?code=xkb:ge::geo" + ] }, { "name": "__MSG_keyboard_mongolian__", @@ -905,8 +833,7 @@ ], "layouts": [ "mn" - ], - "options_page": "hmm_options.html?code=xkb:mn::mon" + ] }, { "name": "__MSG_keyboard_irish__", @@ -916,8 +843,7 @@ ], "layouts": [ "ie" - ], - "options_page": "hmm_options.html?code=xkb:ie::ga" + ] }, { "name": "__MSG_keyboard_maltese__", @@ -927,8 +853,7 @@ ], "layouts": [ "mt" - ], - "options_page": "hmm_options.html?code=xkb:mt::mlt" + ] }, { "name": "__MSG_keyboard_macedonian__", @@ -938,8 +863,7 @@ ], "layouts": [ "mk" - ], - "options_page": "hmm_options.html?code=xkb:mk::mkd" + ] }, { "name": "__MSG_keyboard_kazakh__", @@ -949,8 +873,7 @@ ], "layouts": [ "kz" - ], - "options_page": "hmm_options.html?code=xkb:kz::kaz" + ] }, { "name": "__MSG_inputmethod_pinyin__", @@ -962,8 +885,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=zh-t-i0-pinyin" + ] }, { "name": "__MSG_inputmethod_traditional_pinyin__", @@ -975,8 +897,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=zh-hant-t-i0-pinyin" + ] }, { "name": "__MSG_inputmethod_cangjie__", @@ -1059,8 +980,7 @@ ], "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=zh-hant-t-i0-und" + ] }, { "name": "__MSG_transliteration_am__", @@ -1229,8 +1149,7 @@ "language": "ko", "layouts": [ "us" - ], - "options_page": "hmm_options.html?code=ko-t-i0-und" + ] }, { "name": "__MSG_inputmethod_mozc_us__", @@ -1239,8 +1158,7 @@ "language": "ja", "layouts": [ "us" - ], - "options_page": "mozc_option.html" + ] }, { "name": "__MSG_inputmethod_mozc_jp__", @@ -1249,8 +1167,7 @@ "language": "ja", "layouts": [ "jp" - ], - "options_page": "mozc_option.html" + ] }, { "name": "__MSG_keyboard_bengali_phonetic__", @@ -1442,8 +1359,7 @@ ], "layouts": [ "us" - ], - "options_page": "LEGACY-required-otherwise-options-does-not-load.html" + ] }, { "name": "__MSG_keyboard_vietnamese_viqr__", @@ -1463,8 +1379,7 @@ ], "layouts": [ "us" - ], - "options_page": "LEGACY-required-otherwise-options-does-not-load.html" + ] }, { "name": "__MSG_keyboard_arabic__",
diff --git a/chrome/browser/resources/new_tab_page/modules/tab_groups/module.css b/chrome/browser/resources/new_tab_page/modules/tab_groups/module.css index 0ce01de..352dad0 100644 --- a/chrome/browser/resources/new_tab_page/modules/tab_groups/module.css +++ b/chrome/browser/resources/new_tab_page/modules/tab_groups/module.css
@@ -162,7 +162,6 @@ } cr-icon { - --iron-icon-fill-color: currentColor; width: 20px; height: 20px; flex-shrink: 0;
diff --git a/chrome/browser/resources/new_tab_page/modules/tab_groups/module.html b/chrome/browser/resources/new_tab_page/modules/tab_groups/module.html index adc8121c..1d0ccec7 100644 --- a/chrome/browser/resources/new_tab_page/modules/tab_groups/module.html +++ b/chrome/browser/resources/new_tab_page/modules/tab_groups/module.html
@@ -73,7 +73,7 @@ class="create-new-tab-group" @click="${() => this.onCreateNewTabGroupClick_(false)}"> <div class="row-content"> - <cr-icon id="createNewsTabGroupIcon" + <cr-icon id="createNewTabGroupIcon" icon="tab_groups:create_new_tab_group" slot="icon"> </cr-icon> <div id="createNewTabGroupText" class="tab-group-title">
diff --git a/chrome/browser/resources/omnibox_popup/BUILD.gn b/chrome/browser/resources/omnibox_popup/BUILD.gn index d91610f..cab2412 100644 --- a/chrome/browser/resources/omnibox_popup/BUILD.gn +++ b/chrome/browser/resources/omnibox_popup/BUILD.gn
@@ -8,10 +8,15 @@ build_webui("build") { grd_prefix = "omnibox_popup" - static_files = [ "omnibox_popup.html" ] + static_files = [ + "omnibox_popup.html", + "omnibox_popup_full.html", + ] ts_files = [ "app.html.ts", "app.ts", + "full_app.html.ts", + "full_app.ts", "omnibox_popup.ts", ] css_files = [ "app.css" ]
diff --git a/chrome/browser/resources/omnibox_popup/app.css b/chrome/browser/resources/omnibox_popup/app.css index 7154441b..2b70777a1 100644 --- a/chrome/browser/resources/omnibox_popup/app.css +++ b/chrome/browser/resources/omnibox_popup/app.css
@@ -21,10 +21,11 @@ font-size: 14.6px; /* closely resembles the omnibox input font size. */ /* Colors used in the cr-searchbox results dropdown */ --color-searchbox-answer-icon-background: var(--color-omnibox-answer-icon-g-m3-background); - --color-searchbox-answer-icon-foreground: var(--color-omnibox-results-starter-pack-icon); - --color-searchbox-results-action-chip-focus-outline: var(--color-omnibox-results-button-icon-selected); + --color-searchbox-answer-icon-foreground: var(--color-omnibox-answer-icon-g-m3-foreground); + --color-searchbox-results-action-chip-focus-outline: var(--color-omnibox-results-focus-indicator); --color-searchbox-results-action-chip: var(--color-omnibox-results-button-border); --color-searchbox-results-action-chip-icon: var(--color-omnibox-results-button-icon); + --color-searchbox-results-action-chip-icon-selected: var(--color-omnibox-results-button-icon-selected); --color-searchbox-results-background: var(--color-omnibox-results-background); --color-searchbox-results-background-hovered: var(--color-omnibox-results-background-hovered); --color-searchbox-results-background-selected: var(--color-omnibox-results-background-selected); @@ -39,6 +40,7 @@ --color-searchbox-results-icon-container-background: unset; --color-searchbox-results-icon-focused-outline: var(--color-omnibox-results-focus-indicator); --color-searchbox-results-icon-selected: var(--color-omnibox-results-icon-selected); + --color-searchbox-results-starter-pack-icon: var(--color-omnibox-results-starter-pack-icon); --color-searchbox-results-typed-prefix: unset; --color-searchbox-results-url-selected: var(--color-omnibox-results-url-selected); --color-searchbox-results-url: var(--color-omnibox-results-url);
diff --git a/chrome/browser/resources/omnibox_popup/full_app.html.ts b/chrome/browser/resources/omnibox_popup/full_app.html.ts new file mode 100644 index 0000000..fa054b76 --- /dev/null +++ b/chrome/browser/resources/omnibox_popup/full_app.html.ts
@@ -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. + +import {html} from '//resources/lit/v3_0/lit.rollup.js'; + +import type {OmniboxFullAppElement} from './full_app.js'; + +export function getHtml(this: OmniboxFullAppElement) { + // clang-format off + return html`<!--_html_template_start_--> +<cr-searchbox></cr-searchbox> +<!--_html_template_end_-->`; + // clang-format on +}
diff --git a/chrome/browser/resources/omnibox_popup/full_app.ts b/chrome/browser/resources/omnibox_popup/full_app.ts new file mode 100644 index 0000000..e5da124 --- /dev/null +++ b/chrome/browser/resources/omnibox_popup/full_app.ts
@@ -0,0 +1,49 @@ +// 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 '//resources/cr_components/searchbox/searchbox.js'; +import '/strings.m.js'; + +import {EventTracker} from '//resources/js/event_tracker.js'; +import {CrLitElement} from '//resources/lit/v3_0/lit.rollup.js'; + +import {getHtml} from './full_app.html.js'; + +export class OmniboxFullAppElement extends CrLitElement { + static get is() { + return 'omnibox-full-app'; + } + + override render() { + return getHtml.bind(this)(); + } + + private isDebug_: boolean = + new URLSearchParams(window.location.search).has('debug'); + private eventTracker_ = new EventTracker(); + + override connectedCallback() { + super.connectedCallback(); + + if (!this.isDebug_) { + this.eventTracker_.add( + document.documentElement, 'contextmenu', (e: Event) => { + e.preventDefault(); + }); + } + } + + override disconnectedCallback() { + super.disconnectedCallback(); + this.eventTracker_.removeAll(); + } +} + +declare global { + interface HTMLElementTagNameMap { + 'omnibox-full-app': OmniboxFullAppElement; + } +} + +customElements.define(OmniboxFullAppElement.is, OmniboxFullAppElement);
diff --git a/chrome/browser/resources/omnibox_popup/omnibox_popup.ts b/chrome/browser/resources/omnibox_popup/omnibox_popup.ts index 2de456e..87b50d7b 100644 --- a/chrome/browser/resources/omnibox_popup/omnibox_popup.ts +++ b/chrome/browser/resources/omnibox_popup/omnibox_popup.ts
@@ -3,3 +3,4 @@ // found in the LICENSE file. import './app.js'; +import './full_app.js';
diff --git a/chrome/browser/resources/omnibox_popup/omnibox_popup_full.html b/chrome/browser/resources/omnibox_popup/omnibox_popup_full.html new file mode 100644 index 0000000..23517b7 --- /dev/null +++ b/chrome/browser/resources/omnibox_popup/omnibox_popup_full.html
@@ -0,0 +1,30 @@ +<!doctype html> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> +<head> + <meta charset="utf-8"> + <title>Omnibox Popup</title> + <link rel="stylesheet" href="//resources/css/text_defaults_md.css"> + <link rel="stylesheet" href="chrome://theme/colors.css?sets=ui,chrome"> + <style> + html { + height: auto; + overflow: hidden; + + /* Note: Needed to prevent a horizontal scrollbar when this UI is shown + via OmniboxPopupPresenter (not reproducible in a tab). */ + max-width: 100vw; + } + + body { + background-color: var(--color-omnibox-results-background); + height: auto; + margin: 0; + overflow: hidden; + } + </style> +</head> +<body> + <omnibox-full-app></omnibox-full-app> +</body> +<script type="module" src="omnibox_popup.js"></script> +</html>
diff --git a/chrome/browser/resources/preinstalled_web_apps/internal b/chrome/browser/resources/preinstalled_web_apps/internal index 656ac90..73cc53e 160000 --- a/chrome/browser/resources/preinstalled_web_apps/internal +++ b/chrome/browser/resources/preinstalled_web_apps/internal
@@ -1 +1 @@ -Subproject commit 656ac90405cdbb7d7ab05c54a1628c6d7418832e +Subproject commit 73cc53e1db0fddd9fb797c40c6085579b27e7bf3
diff --git a/chrome/browser/resources/preinstalled_web_apps/resources.grd b/chrome/browser/resources/preinstalled_web_apps/resources.grd index 104274a..c381d755 100644 --- a/chrome/browser/resources/preinstalled_web_apps/resources.grd +++ b/chrome/browser/resources/preinstalled_web_apps/resources.grd
@@ -23,6 +23,7 @@ <include name="IDR_PREINSTALLED_WEB_APPS_GEMINI_ICON_192_PNG" file="internal/gemini_192.png" type="BINDATA" /> <include name="IDR_PREINSTALLED_WEB_APPS_GOOGLE_CALENDAR_ICON_192_PNG" file="internal/google_calendar_192.png" type="BINDATA" /> <include name="IDR_PREINSTALLED_WEB_APPS_NOTEBOOK_LM_ICON_512_PNG" file="internal/notebook_lm_512.png" type="BINDATA" /> + <include name="IDR_PREINSTALLED_WEB_APPS_VIDS_ICON_144_PNG" file="internal/vids_144.png" type="BINDATA" /> </if> </includes> </release>
diff --git a/chrome/browser/resources/reload_button/BUILD.gn b/chrome/browser/resources/reload_button/BUILD.gn new file mode 100644 index 0000000..5124fd8 --- /dev/null +++ b/chrome/browser/resources/reload_button/BUILD.gn
@@ -0,0 +1,30 @@ +# 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("//ui/webui/resources/tools/build_webui.gni") + +assert(!is_android) + +build_webui("build") { + grd_prefix = "reload_button" + + static_files = [ + "reload_button.html", + "reload_button.css", + ] + + ts_files = [ + "app.ts", + "app.html.ts", + ] + css_files = [ "app.css" ] + + webui_context_type = "trusted" + + ts_deps = [ + "//third_party/lit/v3_0:build_ts", + "//ui/webui/resources/cr_elements:build_ts", + "//ui/webui/resources/js:build_ts", + ] +}
diff --git a/chrome/browser/resources/reload_button/DIR_METADATA b/chrome/browser/resources/reload_button/DIR_METADATA new file mode 100644 index 0000000..15e6292 --- /dev/null +++ b/chrome/browser/resources/reload_button/DIR_METADATA
@@ -0,0 +1,4 @@ +buganizer_public: { + component_id: 1456991 +} +team_email: "chrome-waap-eng@google.com"
diff --git a/chrome/browser/resources/reload_button/OWNERS b/chrome/browser/resources/reload_button/OWNERS new file mode 100644 index 0000000..d000fa86 --- /dev/null +++ b/chrome/browser/resources/reload_button/OWNERS
@@ -0,0 +1 @@ +file://chrome/browser/ui/webui/reload_button/OWNERS
diff --git a/chrome/browser/resources/reload_button/app.css b/chrome/browser/resources/reload_button/app.css new file mode 100644 index 0000000..5c40df2 --- /dev/null +++ b/chrome/browser/resources/reload_button/app.css
@@ -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. */ + +/* #css_wrapper_metadata_start + * #type=style-lit + * #scheme=relative + * #import=//resources/cr_elements/cr_icons_lit.css.js + * #include=cr-icons-lit + * #css_wrapper_metadata_end */ + +cr-icon-button { + --cr-icon-button-icon-size: 20px; + --cr-icon-button-margin-end: 0; + --cr-icon-button-margin-start: 0; + --cr-icon-button-size: 32px; + --cr-icon-button-fill-color: var(--color-toolbar-button-icon); +} +
diff --git a/chrome/browser/resources/reload_button/app.html.ts b/chrome/browser/resources/reload_button/app.html.ts new file mode 100644 index 0000000..b4b35a7 --- /dev/null +++ b/chrome/browser/resources/reload_button/app.html.ts
@@ -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. + +import {html} from '//resources/lit/v3_0/lit.rollup.js'; + +import type {ReloadButtonAppElement} from './app.js'; + +export function getHtml(this: ReloadButtonAppElement) { + return html`<!--_html_template_start_--> +<cr-icon-button class="${this.reloadOrStopIcon_}" + @click="${this.onReloadOrStopClick_}"> +</cr-icon-button> +<!--_html_template_end_-->`; +}
diff --git a/chrome/browser/resources/reload_button/app.ts b/chrome/browser/resources/reload_button/app.ts new file mode 100644 index 0000000..d637e83 --- /dev/null +++ b/chrome/browser/resources/reload_button/app.ts
@@ -0,0 +1,53 @@ +// 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 '//resources/cr_elements/cr_button/cr_button.js'; +import '//resources/cr_elements/cr_icon_button/cr_icon_button.js'; +import '//resources/cr_elements/icons.html.js'; + +import {CrLitElement} from '//resources/lit/v3_0/lit.rollup.js'; + +import {getCss} from './app.css.js'; +import {getHtml} from './app.html.js'; + +export class ReloadButtonAppElement extends CrLitElement { + static get is() { + return 'reload-button-app'; + } + + static override get styles() { + return getCss(); + } + + override render() { + return getHtml.bind(this)(); + } + + static override get properties() { + return { + reloadOrStopIcon_: {state: true, type: String}, + }; + } + + protected accessor reloadOrStopIcon_: string = 'icon-refresh'; + + protected setReloadStopState(isLoading: boolean) { + this.reloadOrStopIcon_ = isLoading ? 'icon-clear' : 'icon-refresh'; + } + + // TODO(crbug.com/444358999): implement the reload logic + protected onReloadOrStopClick_(_: Event) { + this.reloadOrStopIcon_ = this.reloadOrStopIcon_ === 'icon-refresh' ? + 'icon-clear' : + 'icon-refresh'; + } +} + +declare global { + interface HTMLElementTagNameMap { + 'reload-button-app': ReloadButtonAppElement; + } +} + +customElements.define(ReloadButtonAppElement.is, ReloadButtonAppElement);
diff --git a/chrome/browser/resources/reload_button/reload_button.css b/chrome/browser/resources/reload_button/reload_button.css new file mode 100644 index 0000000..4b0ed503 --- /dev/null +++ b/chrome/browser/resources/reload_button/reload_button.css
@@ -0,0 +1,13 @@ +/* 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. */ + +/* #css_wrapper_metadata_start + * #type=style-lit + * #scheme=relative + * #css_wrapper_metadata_end */ + +body { + margin: 0; + overflow: hidden; +}
diff --git a/chrome/browser/resources/reload_button/reload_button.html b/chrome/browser/resources/reload_button/reload_button.html new file mode 100644 index 0000000..78cd854 --- /dev/null +++ b/chrome/browser/resources/reload_button/reload_button.html
@@ -0,0 +1,8 @@ +<!doctype html> +<html dir="$i18n{textdirection}" lang="$i18n{language}"> + <meta charset="utf-8"> + <link rel="stylesheet" href="chrome://theme/colors.css?sets=ui,chrome"> + <link rel="stylesheet" href="reload_button.css"> + <reload-button-app></reload-button-app> + <script type="module" src="app.js"></script> +</html>
diff --git a/chrome/browser/resources/settings/privacy_page/cookies_page.html b/chrome/browser/resources/settings/privacy_page/cookies_page.html index 6bd53628..b59fd01 100644 --- a/chrome/browser/resources/settings/privacy_page/cookies_page.html +++ b/chrome/browser/resources/settings/privacy_page/cookies_page.html
@@ -205,7 +205,7 @@ </template> <settings-do-not-track-toggle id="doNotTrack" prefs="{{prefs}}"> </settings-do-not-track-toggle> - <cr-link-row id="site-data-trigger" class="hr" + <cr-link-row id="siteDataTrigger" class="hr" on-click="onSiteDataClick_" label="$i18n{cookiePageAllSitesLink}" role-description="$i18n{subpageArrowRoleDescription}"> </cr-link-row>
diff --git a/chrome/browser/resources/settings/privacy_page/cookies_page.ts b/chrome/browser/resources/settings/privacy_page/cookies_page.ts index 621a29f..49f05fb6 100644 --- a/chrome/browser/resources/settings/privacy_page/cookies_page.ts +++ b/chrome/browser/resources/settings/privacy_page/cookies_page.ts
@@ -239,7 +239,7 @@ return new Map([ [ `${routes.SITE_SETTINGS_ALL.path}_${routes.COOKIES.path}`, - '#site-data-trigger', + '#siteDataTrigger', ], ]); }
diff --git a/chrome/browser/resources/settings/privacy_page/personalization_options.html b/chrome/browser/resources/settings/privacy_page/personalization_options.html index 4eea720d..7adae56 100644 --- a/chrome/browser/resources/settings/privacy_page/personalization_options.html +++ b/chrome/browser/resources/settings/privacy_page/personalization_options.html
@@ -18,7 +18,7 @@ padding: var(--settings-signin-choice-padding, 10px 0px 10px); } - #label-wrapper { + #labelWrapper { margin-inline-end: 20px; } @@ -28,7 +28,7 @@ <div id="chromeSigninUserChoiceSetting" class="hr cr-row" role="group" hidden="[[!chromeSigninUserChoiceInfo_.shouldShowSettings]]" aria-label="$i18n{chromeSigninChoiceTitle}"> - <div id="label-wrapper" class="flex"> + <div id="labelWrapper" class="flex"> <div> $i18n{chromeSigninChoiceTitle} </div>
diff --git a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html index c5d1b69..b43bf69 100644 --- a/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html +++ b/chrome/browser/resources/settings/privacy_page/security_keys_credential_management_dialog.html
@@ -42,13 +42,13 @@ text-align: start; } - #site-header, - #user-display-name-header, - #user-name-header { + #siteHeader, + #userDisplayNameHeader, + #userNameHeader { font-weight: bold; } - #site-header { + #siteHeader { margin-inline-start: 1rem; } @@ -82,13 +82,13 @@ <div id="credentials"> <div id="header" class="list-item column-header"> - <div class="site" id="site-header"> + <div class="site" id="siteHeader"> $i18n{securityKeysCredentialWebsiteLabel} </div> - <div class="user-display-name" id="user-display-name-header"> + <div class="user-display-name" id="userDisplayNameHeader"> $i18n{securityKeysCredentialDisplayNameLabel} </div> - <div class="user-name" id="user-name-header"> + <div class="user-name" id="userNameHeader"> $i18n{securityKeysCredentialUsernameLabel} </div> <div class="icon-placeholder"></div>
diff --git a/chrome/browser/resources/side_panel/read_anything/app.ts b/chrome/browser/resources/side_panel/read_anything/app.ts index c1dcceca..b842cd1 100644 --- a/chrome/browser/resources/side_panel/read_anything/app.ts +++ b/chrome/browser/resources/side_panel/read_anything/app.ts
@@ -508,8 +508,9 @@ protected onKeyDown_(e: KeyboardEvent) { if (e.key === 'k') { e.stopPropagation(); + e.preventDefault(); + this.speechController_.onPlayPauseKeyPress(this.$.container); } - this.speechController_.onPlayPauseKeyPress(this.$.container); } }
diff --git a/chrome/browser/resources/tab_search/split_view/app.ts b/chrome/browser/resources/tab_search/split_view/app.ts index e86a8c4..1f2af3ac 100644 --- a/chrome/browser/resources/tab_search/split_view/app.ts +++ b/chrome/browser/resources/tab_search/split_view/app.ts
@@ -11,7 +11,7 @@ import {CrLitElement} from 'chrome://resources/lit/v3_0/lit.rollup.js'; import type {SelectableLazyListElement} from '../selectable_lazy_list.js'; -import {normalizeURL, TabData, TabItemType} from '../tab_data.js'; +import {getDisplayHostnameForUrl, normalizeURL, TabData, TabItemType} from '../tab_data.js'; import type {ProfileData, Tab, TabsRemovedInfo, TabUpdateInfo} from '../tab_search.mojom-webui.js'; import type {TabSearchApiProxy} from '../tab_search_api_proxy.js'; import {TabSearchApiProxyImpl} from '../tab_search_api_proxy.js'; @@ -210,8 +210,9 @@ private getTabData_(tab: Tab, inActiveWindow: boolean, type: TabItemType): TabData { - const tabData = - new TabData(tab, type, new URL(normalizeURL(tab.url.url)).hostname); + const displayUrl = + getDisplayHostnameForUrl(new URL(normalizeURL(tab.url.url))); + const tabData = new TabData(tab, type, displayUrl); if (type === TabItemType.OPEN_TAB) { tabData.inActiveWindow = inActiveWindow;
diff --git a/chrome/browser/resources/tab_search/tab_data.ts b/chrome/browser/resources/tab_search/tab_data.ts index 56f4a5d..5eb3d2e 100644 --- a/chrome/browser/resources/tab_search/tab_data.ts +++ b/chrome/browser/resources/tab_search/tab_data.ts
@@ -118,6 +118,18 @@ return url || 'about:blank'; } +export function getDisplayHostnameForUrl(url: URL): string { + if (url.protocol === 'blob:') { + return loadTimeData.getString('blobUrlSource'); + } else if (url.protocol === 'file:') { + return loadTimeData.getString('fileUrlSource'); + } else if (url.protocol === 'about:' && url.pathname === 'blank') { + return 'about:blank'; + } else { + return url.hostname; + } +} + export function getTitle(data: TabData|TabGroupData): string|undefined { if (data.type === TabItemType.RECENTLY_CLOSED_TAB_GROUP) { return undefined;
diff --git a/chrome/browser/resources/tab_search/tab_search_page.ts b/chrome/browser/resources/tab_search/tab_search_page.ts index 3dbd50776..c45a68c 100644 --- a/chrome/browser/resources/tab_search/tab_search_page.ts +++ b/chrome/browser/resources/tab_search/tab_search_page.ts
@@ -26,7 +26,7 @@ import {search} from './search.js'; import type {SelectableLazyListElement} from './selectable_lazy_list.js'; import {NO_SELECTION, selectorNavigationKeys} from './selectable_lazy_list.js'; -import {ariaLabel, getHostname, getTabGroupTitle, getTitle, type ItemData, normalizeURL, TabData, TabGroupData, TabItemType, tokenEquals, tokenToString} from './tab_data.js'; +import {ariaLabel, getDisplayHostnameForUrl, getHostname, getTabGroupTitle, getTitle, type ItemData, normalizeURL, TabData, TabGroupData, TabItemType, tokenEquals, tokenToString} from './tab_data.js'; import type {ProfileData, RecentlyClosedTab, Tab, TabGroup, TabsRemovedInfo, TabUpdateInfo} from './tab_search.mojom-webui.js'; import {TabSearchSection} from './tab_search.mojom-webui.js'; import type {TabSearchApiProxy} from './tab_search_api_proxy.js'; @@ -661,22 +661,12 @@ return ariaLabel(tabData); } - private getDisplayHostnameForUrl_(url: URL): string { - if (url.protocol === 'blob:') { - return loadTimeData.getString('blobUrlSource'); - } else if (url.protocol === 'file:') { - return loadTimeData.getString('fileUrlSource'); - } else { - return url.hostname; - } - } - private tabData_( tab: Tab|RecentlyClosedTab, inActiveWindow: boolean, type: TabItemType, tabGroupsMap: Map<string, TabGroup>): TabData { const tabData = new TabData( tab, type, - this.getDisplayHostnameForUrl_(new URL(normalizeURL(tab.url.url)))); + getDisplayHostnameForUrl(new URL(normalizeURL(tab.url.url)))); if (tab.groupId) { tabData.tabGroup = tabGroupsMap.get(tokenToString(tab.groupId));
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc index ff457271..ef64efc1 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.cc
@@ -266,6 +266,11 @@ content_analysis_request_.set_is_content_encrypted(is_content_encrypted); } +void BinaryUploadService::Request::set_is_content_too_large( + bool is_content_too_large) { + is_content_too_large_ = is_content_too_large; +} + void BinaryUploadService::Request::set_blocking(bool blocking) { content_analysis_request_.set_blocking(blocking); } @@ -382,6 +387,14 @@ image_paste_ = image_paste; } +bool BinaryUploadService::Request::is_content_too_large() const { + return is_content_too_large_; +} + +bool BinaryUploadService::Request::is_content_encrypted() const { + return content_analysis_request_.is_content_encrypted(); +} + void BinaryUploadService::Request::StartRequest() { if (!request_start_callback_.is_null()) { std::move(request_start_callback_).Run(*this);
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h index e660612..d436f79 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h +++ b/chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h
@@ -194,6 +194,7 @@ enterprise_connectors::ContentAnalysisRequest::Reason reason); void set_require_metadata_verdict(bool require_metadata_verdict); void set_is_content_encrypted(bool is_content_encrypted); + void set_is_content_too_large(bool is_content_too_large); void set_blocking(bool blocking); void add_local_ips(const std::string& ip_address); void set_referrer_chain(const google::protobuf::RepeatedPtrField< @@ -220,6 +221,8 @@ base::optional_ref<const std::string> password() const; enterprise_connectors::ContentAnalysisRequest::Reason reason() const; bool blocking() const; + bool is_content_encrypted() const; + bool is_content_too_large() const; // Called when beginning to try upload. void StartRequest(); @@ -259,6 +262,8 @@ std::string access_token_; bool image_paste_ = false; + + bool is_content_too_large_ = false; }; // A class to encapsulate the a request acknowledgement. This class will
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc index d26093f..f14f5b2 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service.cc
@@ -433,6 +433,9 @@ if (result == Result::FILE_ENCRYPTED) { request->set_is_content_encrypted(true); } + if (result == Result::FILE_TOO_LARGE) { + request->set_is_content_too_large(true); + } } if (!request->IsAuthRequest() && data.size == 0) { @@ -619,10 +622,17 @@ *response.add_results() = std::move(tag_and_result.second); } - // Set `result` to be unknown, if the request is terminated with incomplete + // Set `result` to be INCOMPLETE_RESPONSE, if the request is terminated with incomplete // response. - Result result = ResponseIsComplete(request_id) ? Result::SUCCESS - : Result::INCOMPLETE_RESPONSE; + Result result = Result::SUCCESS; + if (!ResponseIsComplete(request_id)) { + result = Result::INCOMPLETE_RESPONSE; + } else if (request->is_content_too_large()) { + result = Result::FILE_TOO_LARGE; + } else if (request->is_content_encrypted()) { + result = Result::FILE_ENCRYPTED; + } + FinishRequest(request, result, std::move(response)); }
diff --git a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc index b10d438..e5e7159 100644 --- a/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc +++ b/chrome/browser/safe_browsing/cloud_content_scanning/cloud_binary_upload_service_unittest.cc
@@ -288,6 +288,39 @@ base::test::ScopedFeatureList scoped_feature_list_; }; +TEST_F(CloudBinaryUploadServiceTest, PassesForLargeFile) { + BinaryUploadService::Result scanning_result; + enterprise_connectors::ContentAnalysisResponse scanning_response; + + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + + base::FilePath file_path = temp_dir.GetPath().AppendASCII("normal.doc"); + ASSERT_TRUE(base::WriteFile(file_path, "test")); + + ExpectNetworkResponse(/*should_succeed=*/true, + enterprise_connectors::ContentAnalysisResponse()); + + std::unique_ptr<MockRequest> request = MakeRequest( + &scanning_result, &scanning_response, /*is_advanced_protection*/ false); + request->set_analysis_connector( + enterprise_connectors::AnalysisConnector::FILE_ATTACHED); + ON_CALL(*request, GetRequestData(_)) + .WillByDefault( + [file_path](BinaryUploadService::Request::DataCallback callback) { + BinaryUploadService::Request::Data data; + data.path = file_path; + data.size = 4; // Must not be zero. + std::move(callback).Run(BinaryUploadService::Result::FILE_TOO_LARGE, + std::move(data)); + }); + UploadForDeepScanning(std::move(request)); + + content::RunAllTasksUntilIdle(); + + EXPECT_EQ(scanning_result, BinaryUploadService::Result::FILE_TOO_LARGE); +} + TEST_F(CloudBinaryUploadServiceTest, FailsForLargeFile) { BinaryUploadService::Result scanning_result; enterprise_connectors::ContentAnalysisResponse scanning_response; @@ -397,7 +430,7 @@ // instead. content::RunAllTasksUntilIdle(); - EXPECT_EQ(scanning_result, BinaryUploadService::Result::SUCCESS); + EXPECT_EQ(scanning_result, BinaryUploadService::Result::FILE_ENCRYPTED); } TEST_F(CloudBinaryUploadServiceTest, Succeeds) {
diff --git a/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc b/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc index ccf58c94..57f7983 100644 --- a/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc +++ b/chrome/browser/search_engine_choice/search_engine_choice_dialog_browsertest.cc
@@ -201,8 +201,10 @@ SessionRestoreTestHelper restore_observer; // Create a new window, which should trigger session restore. + ui_test_utils::BrowserCreatedObserver browser_created_observer; chrome::NewEmptyWindow(profile); tab_waiter.Wait(); + SetBrowser(browser_created_observer.Wait()); for (Browser* new_browser : *BrowserList::GetInstance()) { WaitForTabsToLoad(new_browser); @@ -211,7 +213,6 @@ restore_observer.Wait(); keep_alive.reset(); profile_keep_alive.reset(); - SelectFirstBrowser(); } void WaitForTabsToLoad(Browser* browser) {
diff --git a/chrome/browser/tab/BUILD.gn b/chrome/browser/tab/BUILD.gn index b89794c5..fafd647 100644 --- a/chrome/browser/tab/BUILD.gn +++ b/chrome/browser/tab/BUILD.gn
@@ -232,6 +232,7 @@ "tab_state_storage_database.cc", "tab_state_storage_service.cc", "tab_storage_package.cc", + "tab_storage_packager.cc", "tab_storage_util.cc", "web_contents_state.cc", ]
diff --git a/chrome/browser/tab/tab_state_storage_service.cc b/chrome/browser/tab/tab_state_storage_service.cc index 2a01bd7..869b6a87 100644 --- a/chrome/browser/tab/tab_state_storage_service.cc +++ b/chrome/browser/tab/tab_state_storage_service.cc
@@ -56,8 +56,7 @@ return; } - packager_->Package(tab); - std::unique_ptr<StoragePackage> package = packager_->ReleasePackage(); + std::unique_ptr<StoragePackage> package = packager_->Package(tab); DCHECK(package) << "Packager should return a package"; int storage_id = GetStorageId(tab); @@ -69,8 +68,8 @@ return; } - packager_->Package(collection, *this); - std::unique_ptr<StoragePackage> package = packager_->ReleasePackage(); + std::unique_ptr<StoragePackage> package = + packager_->Package(collection, *this); DCHECK(package) << "Packager should return a package"; int storage_id = GetStorageId(collection);
diff --git a/chrome/browser/tab/tab_storage_packager.cc b/chrome/browser/tab/tab_storage_packager.cc new file mode 100644 index 0000000..a76d28b --- /dev/null +++ b/chrome/browser/tab/tab_storage_packager.cc
@@ -0,0 +1,56 @@ +// 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/tab/tab_storage_packager.h" + +#include <memory> +#include <utility> + +#include "base/token.h" +#include "chrome/browser/tab/collection_storage_package.h" +#include "chrome/browser/tab/storage_id_mapping.h" +#include "chrome/browser/tab/storage_package.h" +#include "chrome/browser/tab/tab_storage_package.h" +#include "components/tabs/public/direct_child_walker.h" + +namespace tabs { + +// Crawls the direct children of a TabCollection and adds them to the list of +// children. +class ChildProcessor : public DirectChildWalker::Processor { + public: + ChildProcessor(tabs_pb::Children& children_proto, StorageIdMapping& mapping) + : children_proto_(children_proto), mapping_(mapping) {} + + void ProcessTab(const TabInterface* tab) override { + children_proto_->add_storage_id(mapping_->GetStorageId(tab)); + } + + void ProcessCollection(const TabCollection* collection) override { + children_proto_->add_storage_id(mapping_->GetStorageId(collection)); + } + + private: + raw_ref<tabs_pb::Children> children_proto_; + raw_ref<StorageIdMapping> mapping_; +}; + +TabStoragePackager::TabStoragePackager() = default; +TabStoragePackager::~TabStoragePackager() = default; + +std::unique_ptr<StoragePackage> TabStoragePackager::Package( + const TabCollection* collection, + StorageIdMapping& mapping) { + tabs_pb::Children children_proto; + + ChildProcessor processor(children_proto, mapping); + DirectChildWalker walker(collection, &processor); + walker.Walk(); + + // TODO(https://crbug.com/448875689): Fill this package with collection + // specific data. + return std::make_unique<CollectionStoragePackage>(std::move(children_proto)); +} + +} // namespace tabs
diff --git a/chrome/browser/tab/tab_storage_packager.h b/chrome/browser/tab/tab_storage_packager.h index 4552756..a77fceb 100644 --- a/chrome/browser/tab/tab_storage_packager.h +++ b/chrome/browser/tab/tab_storage_packager.h
@@ -17,28 +17,21 @@ // This class is used to package tab data for use in the background thread. class TabStoragePackager { public: - TabStoragePackager() = default; - virtual ~TabStoragePackager() = default; + TabStoragePackager(); + virtual ~TabStoragePackager(); TabStoragePackager(const TabStoragePackager&) = delete; TabStoragePackager& operator=(const TabStoragePackager&) = delete; - // Packages the tab's data for later use. After packaging a tab, its data - // is available via the #ReleasePackage() method. - virtual void Package(const TabInterface* tab) = 0; + // Packages the tab's data for later use. + virtual std::unique_ptr<StoragePackage> Package(const TabInterface* tab) = 0; - // Packages an aribtrtary tab collection's state for later use. Conceptually + // Packages an arbitrary tab collection's state for later use. Conceptually // just this collection is represented by the package, not parents or - // children's data. However the identity and order of children shold be - // captured in this package. After packaging, its is available via the - // #ReleasePackage() method. - virtual void Package(const TabCollection* collection, - StorageIdMapping& mapping) = 0; - - // Allows the unique ownership of the underlying StoragePackage to be - // transferred out of the packager. After this call, the stored package will - // be null. - virtual std::unique_ptr<StoragePackage> ReleasePackage() = 0; + // children's data. However the identity and order of children should be + // captured in this package. + std::unique_ptr<StoragePackage> Package(const TabCollection* collection, + StorageIdMapping& mapping); }; } // namespace tabs
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index 7ea9f0e..dba688925 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -1556,6 +1556,8 @@ "//chrome/browser/ui/webui/password_manager:mojo_bindings", "//chrome/browser/ui/webui/password_manager:password_manager_ui_handler", "//chrome/browser/ui/webui/privacy_sandbox", + "//chrome/browser/ui/webui/reload_button", + "//chrome/browser/ui/webui/reload_button:impl", "//chrome/browser/ui/webui/searchbox", "//chrome/browser/ui/webui/settings", "//chrome/browser/ui/webui/settings:impl", @@ -3829,6 +3831,8 @@ "views/frame/immersive_mode_controller_stub.h", "views/frame/main_container_view.cc", "views/frame/main_container_view.h", + "views/frame/main_region_view.cc", + "views/frame/main_region_view.h", "views/frame/multi_contents_background_view.cc", "views/frame/multi_contents_background_view.h", "views/frame/multi_contents_drop_target_view.cc", @@ -3964,6 +3968,8 @@ "views/omnibox/omnibox_popup_view_views.h", "views/omnibox/omnibox_popup_view_webui.cc", "views/omnibox/omnibox_popup_view_webui.h", + "views/omnibox/omnibox_popup_webui_content.cc", + "views/omnibox/omnibox_popup_webui_content.h", "views/omnibox/omnibox_result_view.cc", "views/omnibox/omnibox_result_view.h", "views/omnibox/omnibox_row_grouped_view.cc", @@ -4687,7 +4693,6 @@ # componentized: # c/b/ui/browser.h, browser_finder.h, browser_window.h. # c/b/ui/passwords/passwords_model_delegate.h, passwords_client_ui_delegate.h. - "//chrome/browser/ui/views/zoom", "//chrome/browser/ui/webauthn:impl", "//chrome/browser/ui/webui/app_service_internals", "//chrome/browser/ui/webui/autofill_ml_internals",
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java index dfbb5d0..016a8b1 100644 --- a/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java +++ b/chrome/browser/ui/android/edge_to_edge/internal/java/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerImpl.java
@@ -4,6 +4,9 @@ package org.chromium.chrome.browser.ui.edge_to_edge; +import static androidx.core.view.WindowInsetsCompat.Type.systemBars; +import static androidx.core.view.WindowInsetsCompat.Type.tappableElement; + import static org.chromium.build.NullUtil.assumeNonNull; import android.app.Activity; @@ -878,7 +881,7 @@ private static Insets getSystemInsets( WindowInsetsCompat windowInsets, boolean hasSeenNonZeroNavigationBarInsets) { - Insets systemBarInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); + Insets systemBarInsets = windowInsets.getInsets(systemBars() + tappableElement()); if (!EdgeToEdgeUtils.isUseBackupNavbarInsetsEnabled()) return systemBarInsets; @@ -891,8 +894,6 @@ windowInsets, BackupNavbarInsetsCallSite.EDGE_TO_EDGE_CONTROLLER, EdgeToEdgeFieldTrialImpl.getBackupNavbarInsetsOverrides(), - ChromeFeatureList.sEdgeToEdgeUseBackupNavbarInsetsUseTappable - .getValue(), ChromeFeatureList.sEdgeToEdgeUseBackupNavbarInsetsUseGestures .getValue()); // If applicable, apply backup navbar insets to the left, right, and bottom (not the
diff --git a/chrome/browser/ui/android/edge_to_edge/internal/junit/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java b/chrome/browser/ui/android/edge_to_edge/internal/junit/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java index 3e45238..475cec9c 100644 --- a/chrome/browser/ui/android/edge_to_edge/internal/junit/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java +++ b/chrome/browser/ui/android/edge_to_edge/internal/junit/src/org/chromium/chrome/browser/ui/edge_to_edge/EdgeToEdgeControllerTest.java
@@ -1127,21 +1127,19 @@ .expectNoRecords( "Android.EdgeToEdge.BackupNavbarInsets.EdgeToEdgeController") .build()) { - when(mInsetObserver.getLastRawWindowInsets()) - .thenReturn(SYSTEM_BARS_WITH_TAPPABLE_NAVBAR); - mEdgeToEdgeControllerImpl.handleWindowInsets( - mViewMock, SYSTEM_BARS_WITH_TAPPABLE_NAVBAR); + when(mInsetObserver.getLastRawWindowInsets()).thenReturn(SYSTEM_BARS_WINDOW_INSETS); + mEdgeToEdgeControllerImpl.handleWindowInsets(mViewMock, SYSTEM_BARS_WINDOW_INSETS); } - assertFalse(mEdgeToEdgeControllerImpl.isDrawingToEdge()); + assertTrue(mEdgeToEdgeControllerImpl.isDrawingToEdge()); assertEquals( "The controller should be using the system bar insets.", - Insets.of(0, TOP_INSET, 0, BOTTOM_INSET), + Insets.of(0, TOP_INSET, 0, 0), mEdgeToEdgeControllerImpl.getAppliedContentViewPaddingForTesting()); changeObserver.verify( - "The system bars are providing a bottom inset and the controller should be drawing" - + " toEdge.", + "The system bars are providing a bottom inset and the controller should be" + + " drawing toEdge.", BOTTOM_INSET, - /* isDrawingToEdge= */ false, + /* isDrawingToEdge= */ true, /* isPageOptInToEdge= */ false); try (var watcher = @@ -1150,9 +1148,9 @@ "Android.EdgeToEdge.BackupNavbarInsets.EdgeToEdgeController") .build()) { when(mInsetObserver.getLastRawWindowInsets()) - .thenReturn(SYSTEM_BARS_WITH_TAPPABLE_MISSING_NAVBAR); + .thenReturn(GESTURE_NAV_INSETS_MISSING_NAVBAR); mEdgeToEdgeControllerImpl.handleWindowInsets( - mViewMock, SYSTEM_BARS_WITH_TAPPABLE_MISSING_NAVBAR); + mViewMock, GESTURE_NAV_INSETS_MISSING_NAVBAR); } assertFalse(mEdgeToEdgeControllerImpl.isDrawingToEdge()); assertEquals( @@ -1169,10 +1167,7 @@ } @Test - @EnableFeatures({ - ChromeFeatureList.EDGE_TO_EDGE_USE_BACKUP_NAVBAR_INSETS, - ChromeFeatureList.EDGE_TO_EDGE_MONITOR_CONFIGURATIONS - }) + @EnableFeatures(ChromeFeatureList.EDGE_TO_EDGE_MONITOR_CONFIGURATIONS) public void handleWindowInsets_useTappableElementForBackupInsets() { TestChangeObserver changeObserver = new TestChangeObserver(); mEdgeToEdgeControllerImpl.registerObserver(changeObserver); @@ -1204,9 +1199,8 @@ try (var watcher = HistogramWatcher.newBuilder() - .expectIntRecord( - "Android.EdgeToEdge.BackupNavbarInsets.EdgeToEdgeController", - EdgeToEdgeManager.BackupNavbarInsetsSource.TAPPABLE_ELEMENT) + .expectNoRecords( + "Android.EdgeToEdge.BackupNavbarInsets.EdgeToEdgeController") .build()) { when(mInsetObserver.getLastRawWindowInsets()) .thenReturn(SYSTEM_BARS_WITH_TAPPABLE_MISSING_NAVBAR);
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings.grd b/chrome/browser/ui/android/strings/android_chrome_strings.grd index 7c40380..e8334edd 100644 --- a/chrome/browser/ui/android/strings/android_chrome_strings.grd +++ b/chrome/browser/ui/android/strings/android_chrome_strings.grd
@@ -2957,6 +2957,9 @@ <message name="IDS_CONTEXTMENU_UNPIN" desc="This string is shown in the context menu to remove an existing Custom Tile."> Unpin </message> + <message name="IDS_CONTEXTMENU_VIEW_PAGE_SOURCE" desc="This string is shown in the context menu to display non-editable HTML source code for the current page. [CHAR_LIMIT=30]"> + View page source + </message> <message name="IDS_CONTEXTMENU_INSPECT_ELEMENT" desc="This string is shown in the context menu to inspect an element in a web page using the developer tools. [CHAR_LIMIT=30]"> Inspect </message>
diff --git a/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_VIEW_PAGE_SOURCE.png.sha1 b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_VIEW_PAGE_SOURCE.png.sha1 new file mode 100644 index 0000000..c87050c7 --- /dev/null +++ b/chrome/browser/ui/android/strings/android_chrome_strings_grd/IDS_CONTEXTMENU_VIEW_PAGE_SOURCE.png.sha1
@@ -0,0 +1 @@ +2b40272d24724c59b42e353249a1f7761ad901db \ No newline at end of file
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionsMenuCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionsMenuCoordinator.java index 17be8c45..3dfa94c 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionsMenuCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/extensions/ExtensionsMenuCoordinator.java
@@ -147,7 +147,11 @@ } }); if (mShouldShowMenuOnInit) { - mExtensionsMenuButton.showMenu(); + if (mExtensionsMenuButton.getHost().isMenuShowing()) { + mExtensionsMenuButton.dismiss(); + } else { + mExtensionsMenuButton.showMenu(); + } mShouldShowMenuOnInit = false; } },
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressCoordinator.java index 822147b..0c8c0a33 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/load_progress/LoadProgressCoordinator.java
@@ -9,6 +9,8 @@ import org.chromium.base.supplier.ObservableSupplier; import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider.ControlsPosition; import org.chromium.chrome.browser.browser_controls.TopControlLayer; import org.chromium.chrome.browser.browser_controls.TopControlsStacker; import org.chromium.chrome.browser.browser_controls.TopControlsStacker.TopControlVisibility; @@ -25,17 +27,21 @@ private final ToolbarProgressBar mProgressBarView; private final LoadProgressViewBinder mLoadProgressViewBinder; private final TopControlsStacker mTopControlsStacker; + private final BrowserControlsStateProvider mBrowserControls; /** * @param tabSupplier An observable supplier of the current {@link Tab}. * @param progressBarView Toolbar progress bar view. * @param topControlsStacker TopControlsStacker to manage the view's y-offset. + * @param browserControlsStateProvider BrowserControlsStateProvider to provide control position. */ public LoadProgressCoordinator( ObservableSupplier<@Nullable Tab> tabSupplier, ToolbarProgressBar progressBarView, - TopControlsStacker topControlsStacker) { + TopControlsStacker topControlsStacker, + BrowserControlsStateProvider browserControlsStateProvider) { mProgressBarView = progressBarView; + mBrowserControls = browserControlsStateProvider; mModel = new PropertyModel(LoadProgressProperties.ALL_KEYS); mMediator = new LoadProgressMediator(tabSupplier, mModel); mLoadProgressViewBinder = new LoadProgressViewBinder(); @@ -85,6 +91,7 @@ public int getTopControlVisibility() { // TODO(crbug.com/417238089): Possibly add way to notify stacker of visibility changes. return mProgressBarView.getVisibility() == View.VISIBLE + && mBrowserControls.getControlsPosition() == ControlsPosition.TOP ? TopControlVisibility.VISIBLE : TopControlVisibility.HIDDEN; }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java index 7fccc25..414e21d 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainer.java
@@ -39,6 +39,8 @@ import org.chromium.build.annotations.Initializer; import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider.ControlsPosition; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.browser_controls.TopControlLayer; import org.chromium.chrome.browser.browser_controls.TopControlsStacker; @@ -105,8 +107,9 @@ private final Callback<Boolean> mOnXrSpaceModeChanged = this::onXrSpaceModeChanged; private @Nullable ObservableSupplier<Boolean> mXrSpaceModeObservableSupplier; private @Nullable ObservableSupplierImpl<Integer> mHeightChangedSupplier; - private @Nullable TopControlsStacker mTopControlsStacker; + private TopControlsStacker mTopControlsStacker; private ToolbarDataProvider mToolbarDataProvider; + private BrowserControlsStateProvider mBrowserControls; /** * Constructs a new control container. @@ -356,10 +359,12 @@ // When app header state available, set the state accordingly. if (appHeaderState != null && appHeaderState.isInDesktopWindow()) { + int topInset = + Math.max(0, appHeaderState.getAppHeaderHeight() - mToolbar.getTabStripHeight()); backgroundDrawable.setLayerInset( backgroundTabImageIndex, appHeaderState.getLeftPadding(), - 0, + topInset, appHeaderState.getRightPadding(), 0); } @@ -379,6 +384,7 @@ * @param layoutStateProviderSupplier Used to check the current layout type. * @param fullscreenManager Used to check whether in fullscreen. * @param topControlsStacker The TopControlsStacker for |this| to query layer states. + * @param browserControlsStateProvider BrowserControlsStateProvider to provide control position. */ @Initializer public void setPostInitializationDependencies( @@ -393,11 +399,13 @@ OneshotSupplier<LayoutStateProvider> layoutStateProviderSupplier, FullscreenManager fullscreenManager, TopControlsStacker topControlsStacker, - ToolbarDataProvider toolbarDataProvider) { + ToolbarDataProvider toolbarDataProvider, + BrowserControlsStateProvider browserControlsStateProvider) { mToolbar = toolbar; mIncognito = isIncognito; mTopControlsStacker = topControlsStacker; mToolbarDataProvider = toolbarDataProvider; + mBrowserControls = browserControlsStateProvider; mToolbarDataProvider.addToolbarDataProviderObserver(this); BooleanSupplier isVisible = () -> this.getVisibility() == View.VISIBLE; @@ -985,6 +993,7 @@ public int getTopControlVisibility() { // TODO(crbug.com/417238089): Possibly add way to notify stacker of visibility changes. return isToolbarContainerFullyVisible() + && mBrowserControls.getControlsPosition() == ControlsPosition.TOP ? TopControlVisibility.VISIBLE : TopControlVisibility.HIDDEN; }
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java index eca96d1..db31c41 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/ToolbarControlContainerTest.java
@@ -42,6 +42,7 @@ import org.chromium.base.test.util.HistogramWatcher; import org.chromium.cc.input.BrowserControlsState; import org.chromium.chrome.R; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.browser_controls.TopControlsStacker; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -115,6 +116,7 @@ @Mock private IncognitoStateProvider mIncognitoStateProvider; @Mock private NewTabPageDelegate mNewTabPageDelegate; @Mock private TopControlsStacker mTopControlsStacker; + @Mock private BrowserControlsStateProvider mBrowserControls; private final Supplier<Tab> mTabSupplier = () -> mTab; private final ObservableSupplierImpl<Boolean> mCompositorInMotionSupplier = @@ -480,10 +482,11 @@ // This is needed for the control container to read the height of the toolbar. controlContainer.setToolbarForTesting(mToolbar); - // Set app header with 10px padding on left, 20px on right, and 50px height. - doReturn(50).when(mToolbar).getTabStripHeight(); + // Set app header with 10px padding on left, 20px on right, and 100px height. Set tab strip + // height to 80px. Top inset should be 100 - 80 = 20. + doReturn(80).when(mToolbar).getTabStripHeight(); var appHeaderState = - new AppHeaderState(new Rect(0, 0, 100, 50), new Rect(10, 0, 80, 50), true); + new AppHeaderState(new Rect(0, 0, 100, 100), new Rect(10, 0, 80, 100), true); controlContainer.onAppHeaderStateChanged(appHeaderState); assertNotNull( "Control container background is null after app header state change.", @@ -499,6 +502,20 @@ "Right padding for tab drawable is wrong.", 20, background.getLayerInsetRight(tabDrawableIndex)); + assertEquals( + "Top inset for tab drawable is wrong.", + 20, + background.getLayerInsetTop(tabDrawableIndex)); + + // Set app header with 40px height, and tab strip with 50px height. + // Top inset should be max(0, 40 - 50) = 0. + appHeaderState = new AppHeaderState(new Rect(0, 0, 100, 40), new Rect(10, 0, 80, 40), true); + controlContainer.onAppHeaderStateChanged(appHeaderState); + background = (LayerDrawable) controlContainer.getBackground(); + assertEquals( + "Top inset for tab drawable should be 0.", + 0, + background.getLayerInsetTop(tabDrawableIndex)); controlContainer.onAppHeaderStateChanged(new AppHeaderState()); background = (LayerDrawable) controlContainer.getBackground(); @@ -510,6 +527,10 @@ "Right padding for tab drawable is wrong.", 0, background.getLayerInsetRight(tabDrawableIndex)); + assertEquals( + "Top inset for tab drawable should be 0.", + 0, + background.getLayerInsetTop(tabDrawableIndex)); } @Test @@ -578,7 +599,8 @@ mLayoutStateProviderSupplier, mFullscreenManager, mTopControlsStacker, - mToolbarDataProvider); + mToolbarDataProvider, + mBrowserControls); ToolbarPhone toolbarPhone = controlContainer.findViewById(R.id.toolbar); doReturn(mLocationBarCoordinatorPhone).when(mLocationBarCoordinator).getPhoneCoordinator(); @@ -649,7 +671,8 @@ mLayoutStateProviderSupplier, mFullscreenManager, mTopControlsStacker, - mToolbarDataProvider); + mToolbarDataProvider, + mBrowserControls); ToolbarControlContainer.ToolbarViewResourceCoordinatorLayout toolbarContainer = controlContainer.findViewById(R.id.toolbar_container); toolbarContainer.setVisibility(View.GONE);
diff --git a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java index 47c7589f..e0642b3f 100644 --- a/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java +++ b/chrome/browser/ui/android/toolbar/java/src/org/chromium/chrome/browser/toolbar/top/TopToolbarCoordinator.java
@@ -21,6 +21,7 @@ import org.chromium.base.supplier.OneshotSupplier; import org.chromium.build.annotations.NullMarked; import org.chromium.build.annotations.Nullable; +import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.browser_controls.BrowserControlsVisibilityManager; import org.chromium.chrome.browser.browser_controls.BrowserStateBrowserControlsVisibilityDelegate; import org.chromium.chrome.browser.browser_controls.TopControlsStacker; @@ -152,6 +153,7 @@ * @param homeButtonDisplay The {@link HomeButtonDisplay} to manage the display and behavior of * home button(s). Should be null on custom tabs. * @param topControlsStacker The TopControlsStacker for child objects to check state from. + * @param browserControlsStateProvider BrowserControlsStateProvider instance. */ public TopToolbarCoordinator( ToolbarControlContainer controlContainer, @@ -188,7 +190,8 @@ @Nullable ForwardButtonCoordinator forwardButtonCoordinator, @Nullable HomeButtonDisplay homeButtonDisplay, @Nullable ExtensionToolbarCoordinator extensionToolbarCoordinator, - TopControlsStacker topControlsStacker) { + TopControlsStacker topControlsStacker, + BrowserControlsStateProvider browserControlsStateProvider) { mToolbarLayout = toolbarLayout; mMenuButtonCoordinator = browsingModeMenuButtonCoordinator; mControlContainer = controlContainer; @@ -244,7 +247,8 @@ layoutStateProviderSupplier, fullscreenManager, topControlsStacker, - toolbarDataProvider); + toolbarDataProvider, + browserControlsStateProvider); mToolbarLayout.initialize( toolbarDataProvider, tabController,
diff --git a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc index a59039f0..08774b0a 100644 --- a/chrome/browser/ui/ash/desks/desks_client_browsertest.cc +++ b/chrome/browser/ui/ash/desks/desks_client_browsertest.cc
@@ -1870,6 +1870,7 @@ // Enter overview, head over to the desks templates grid and launch the // template. + ui_test_utils::BrowserCreatedObserver browser_created_observer; ash::ToggleOverview(); ash::WaitForOverviewEnterAnimation(); @@ -1878,10 +1879,11 @@ // Wait for the tabs to load. content::RunAllTasksUntilIdle(); + const BrowserWindowInterface* new_browser = browser_created_observer.Wait(); EXPECT_EQ(4u, BrowserList::GetInstance()->size()); aura::Window* new_browser_window = - BrowserList::GetInstance()->get(3)->window()->GetNativeWindow(); + new_browser->GetWindow()->GetNativeWindow(); // Tests that the stacking is correct while in overview. The parent has other // children for overview mode windows, but the first three app windows should
diff --git a/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc b/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc index 625a673a..f0eff59 100644 --- a/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc +++ b/chrome/browser/ui/ash/projector/projector_navigation_throttle_browsertest.cc
@@ -158,14 +158,14 @@ } browser_destroyed_observer.Wait(); - browser_created_observer.Wait(); + BrowserWindowInterface* const swa_browser = browser_created_observer.Wait(); // During the navigation, we closed the previous browser to prevent dangling // about:blank pages and opened a new app browser for the Projector SWA. // There is still only one browser available. EXPECT_EQ(BrowserList::GetInstance()->size(), 1u); - // Select the first available browser, which should be the SWA. - SelectFirstBrowser(); + // Set the default browser to the swa browser. + SetBrowser(swa_browser); Browser* app_browser = FindSystemWebAppBrowser(profile(), SystemWebAppType::PROJECTOR); // Projector SWA is now open. @@ -267,14 +267,14 @@ WindowOpenDisposition::CURRENT_TAB, ui_test_utils::BrowserTestWaitFlags::BROWSER_TEST_WAIT_FOR_BROWSER); browser_destroyed_observer.Wait(); - browser_created_observer.Wait(); + BrowserWindowInterface* const swa_browser = browser_created_observer.Wait(); // During the navigation, we closed the previous browser to prevent dangling // blank redirect pages and opened a new app browser for the Projector SWA. // There is still only one browser available. EXPECT_EQ(BrowserList::GetInstance()->size(), 1u); - // Select the first available browser, which should be the SWA. - SelectFirstBrowser(); + // Set the default browser to the swa browser. + SetBrowser(swa_browser); Browser* app_browser = FindSystemWebAppBrowser(profile(), SystemWebAppType::PROJECTOR);
diff --git a/chrome/browser/ui/ash/system/DEPS b/chrome/browser/ui/ash/system/DEPS index 4648560..58ff959 100644 --- a/chrome/browser/ui/ash/system/DEPS +++ b/chrome/browser/ui/ash/system/DEPS
@@ -30,6 +30,7 @@ "+chrome/browser/ui/ash/system_web_apps/system_web_app_ui_utils.h", "+chrome/browser/ui/browser.h", "+chrome/browser/ui/browser_navigator_params.h", + "+chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h", "+chrome/browser/ui/chrome_pages.h", "+chrome/browser/ui/managed_ui.h", "+chrome/browser/ui/scoped_tabbed_browser_displayer.h",
diff --git a/chrome/browser/ui/ash/system/system_tray_tray_cast_browsertest_media_router_chromeos.cc b/chrome/browser/ui/ash/system/system_tray_tray_cast_browsertest_media_router_chromeos.cc index 64a85c8e..93007ccb 100644 --- a/chrome/browser/ui/ash/system/system_tray_tray_cast_browsertest_media_router_chromeos.cc +++ b/chrome/browser/ui/ash/system/system_tray_tray_cast_browsertest_media_router_chromeos.cc
@@ -26,6 +26,7 @@ #include "chrome/browser/media/router/discovery/access_code/access_code_cast_feature.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/ash/cast_config/cast_config_controller_media_router.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/media_router/access_code_cast/access_code_cast_integration_browsertest.h" #include "chromeos/ash/components/login/auth/public/key.h" @@ -458,7 +459,7 @@ SetupUserProfile(account_id2_, /* allow_access_code */ true); // Show the first cast dialog from the browser. - SelectFirstBrowser(); + SetBrowser(GetLastActiveBrowserWindowInterfaceWithAnyProfile()); EnableAccessCodeCasting(); ASSERT_TRUE(ShowDialog());
diff --git a/chrome/browser/ui/browser_finder_chromeos_browsertest.cc b/chrome/browser/ui/browser_finder_chromeos_browsertest.cc index 3e301e2..9fdb4742 100644 --- a/chrome/browser/ui/browser_finder_chromeos_browsertest.cc +++ b/chrome/browser/ui/browser_finder_chromeos_browsertest.cc
@@ -33,7 +33,9 @@ desks_controller->NewDesk(ash::DesksCreationRemovalSource::kButton); } - void ActivateBrowser(Browser* browser) { browser->window()->Activate(); } + void ActivateBrowser(BrowserWindowInterface* browser) { + browser->GetWindow()->Activate(); + } Browser* CreateTestBrowser() { Browser* new_browser = CreateBrowser(browser()->profile()); @@ -52,10 +54,10 @@ auto* desk_2 = desks_controller->desks()[1].get(); auto* desk_3 = desks_controller->desks()[2].get(); - Browser* browser_1 = CreateTestBrowser(); + BrowserWindowInterface* const browser_1 = CreateTestBrowser(); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); - auto* window_1 = browser_1->window()->GetNativeWindow(); + SetBrowser(browser_1); + auto* window_1 = browser_1->GetWindow()->GetNativeWindow(); EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); EXPECT_TRUE(desk_1->is_active()); EXPECT_TRUE(desks_controller->BelongsToActiveDesk(window_1)); @@ -104,10 +106,10 @@ auto* desk_2 = desks_controller->desks()[1].get(); auto* desk_3 = desks_controller->desks()[2].get(); - Browser* browser_1 = CreateTestBrowser(); + BrowserWindowInterface* const browser_1 = CreateTestBrowser(); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); - auto* window_1 = browser_1->window()->GetNativeWindow(); + SetBrowser(browser_1); + auto* window_1 = browser_1->GetWindow()->GetNativeWindow(); EXPECT_EQ(1u, chrome::GetBrowserCount(browser()->profile())); EXPECT_TRUE(desk_1->is_active()); EXPECT_TRUE(desks_controller->BelongsToActiveDesk(window_1));
diff --git a/chrome/browser/ui/browser_list.h b/chrome/browser/ui/browser_list.h index 05853001..adc73d3 100644 --- a/chrome/browser/ui/browser_list.h +++ b/chrome/browser/ui/browser_list.h
@@ -56,8 +56,6 @@ bool empty() const { return browsers_.empty(); } size_t size() const { return browsers_.size(); } - Browser* get(size_t index) const { return browsers_[index]; } - // Enumerate the current browser and the new browser in-order. void ForEachCurrentAndNewBrowser( base::FunctionRef<void(Browser*)> on_browser);
diff --git a/chrome/browser/ui/browser_window/internal/BUILD.gn b/chrome/browser/ui/browser_window/internal/BUILD.gn index 30ef0d4c..02df6b9 100644 --- a/chrome/browser/ui/browser_window/internal/BUILD.gn +++ b/chrome/browser/ui/browser_window/internal/BUILD.gn
@@ -160,6 +160,7 @@ "android/java/src/org/chromium/chrome/browser/ui/browser_window/AndroidBrowserWindowEnumerator.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/BrowserWindowCreatorBridge.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/BrowserWindowInterfaceIteratorAndroid.java", + "android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraints.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImpl.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskTrackerFactory.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskTrackerImpl.java", @@ -203,6 +204,7 @@ sources = [ "android/java/src/org/chromium/chrome/browser/ui/browser_window/AndroidBrowserWindowCreateParamsImplUnitTest.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/BrowserWindowCreatorBridgeUnitTest.java", + "android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraintsUnitTest.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImplUnitTest.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskTrackerImplUnitTest.java", "android/java/src/org/chromium/chrome/browser/ui/browser_window/PendingActionManagerUnitTest.java",
diff --git a/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraints.java b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraints.java new file mode 100644 index 0000000..561b18f --- /dev/null +++ b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraints.java
@@ -0,0 +1,90 @@ +// 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. + +package org.chromium.chrome.browser.ui.browser_window; + +import android.graphics.Rect; +import android.os.Build; +import android.view.WindowInsets; +import android.view.WindowManager; + +import androidx.annotation.RequiresApi; + +import org.chromium.base.Log; +import org.chromium.build.annotations.NullMarked; +import org.chromium.ui.display.DisplayAndroid; +import org.chromium.ui.display.DisplayUtil; + +/** Contains logic for constraints on a {@link ChromeAndroidTask}'s bounds. */ +@NullMarked +final class ChromeAndroidTaskBoundsConstraints { + private static final String TAG = "CATBoundsConstraints"; + + /** + * The minimal size of a task, for both width and height. + * + * <p>The Android framework defines the minimal size for framework APIs [1], so the minimal size + * here must be no smaller than that. + * + * <p>Note: Apps don't have access to the Android framework's minimal size as it's not public. + * + * <p>[1] <a + * href="https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/res/res/values/dimens.xml;l=792;drc=37507ae292eef969c507d9438a4692539035f764">Link + * to Android framework's minimal size definition</a> + */ + static final int MINIMAL_TASK_SIZE_DP = 220; + + private ChromeAndroidTaskBoundsConstraints() {} + + /** + * Applies all constraints on {@code inputBoundsInPx} and returns the adjusted bounds. + * + * @param inputBoundsInPx The input bounds in pixels. + * @param displayAndroid The display the {@code inputBoundsInPx} is for. + * @param windowManager The {@link WindowManager} bound to the underlying display of the + * provided {@code displayAndroid}. + * @return The adjusted bounds in pixels. + */ + static Rect apply( + Rect inputBoundsInPx, DisplayAndroid displayAndroid, WindowManager windowManager) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) { + Log.w(TAG, "apply() requires Android R+; returning input bounds"); + return inputBoundsInPx; + } + + // 1. Get the max and min sizes. + Rect maxBoundsInPx = getMaxBoundsInPx(windowManager); + int minWidthAndHeightInPx = DisplayUtil.dpToPx(displayAndroid, MINIMAL_TASK_SIZE_DP); + + // 2. Clamp the input bounds so that it's fully within the max bounds. + Rect boundsWithinMaxBoundsInPx = DisplayUtil.clampRect(inputBoundsInPx, maxBoundsInPx); + int adjustedLeftInPx = boundsWithinMaxBoundsInPx.left; + int adjustedTopInPx = boundsWithinMaxBoundsInPx.top; + + // 3. Make sure the bounds are no smaller than the min size. + int adjustedWidthInPx = Math.max(boundsWithinMaxBoundsInPx.width(), minWidthAndHeightInPx); + int adjustedHeightInPx = + Math.max(boundsWithinMaxBoundsInPx.height(), minWidthAndHeightInPx); + + // 4. Return the adjusted bounds. + return new Rect( + adjustedLeftInPx, + adjustedTopInPx, + /* right= */ adjustedLeftInPx + adjustedWidthInPx, + /* bottom= */ adjustedTopInPx + adjustedHeightInPx); + } + + /** Returns the maximum bounds in pixels. */ + @RequiresApi(api = Build.VERSION_CODES.R) + static Rect getMaxBoundsInPx(WindowManager windowManager) { + var insets = + windowManager + .getMaximumWindowMetrics() + .getWindowInsets() + .getInsets(WindowInsets.Type.tappableElement()); + Rect fullscreenBounds = windowManager.getMaximumWindowMetrics().getBounds(); + return new Rect( + 0, insets.top, fullscreenBounds.right, fullscreenBounds.bottom - insets.bottom); + } +}
diff --git a/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraintsUnitTest.java b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraintsUnitTest.java new file mode 100644 index 0000000..5d6c9ee --- /dev/null +++ b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskBoundsConstraintsUnitTest.java
@@ -0,0 +1,107 @@ +// 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. + +package org.chromium.chrome.browser.ui.browser_window; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import static org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskUnitTestSupport.DEFAULT_FULL_SCREEN_BOUNDS_IN_PX; +import static org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskUnitTestSupport.DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX; +import static org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskUnitTestSupport.DEFAULT_MAX_TAPPABLE_INSETS_IN_PX; + +import android.annotation.SuppressLint; +import android.graphics.Rect; +import android.os.Build; +import android.view.WindowManager; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import org.robolectric.annotation.Config; + +import org.chromium.base.test.BaseRobolectricTestRunner; +import org.chromium.ui.display.DisplayAndroid; +import org.chromium.ui.display.DisplayUtil; + +@RunWith(BaseRobolectricTestRunner.class) +@Config(sdk = Build.VERSION_CODES.R) +@SuppressLint("NewApi" /* @Config already specifies the required SDK */) +public class ChromeAndroidTaskBoundsConstraintsUnitTest { + + private static final float TEST_DIP_SCALE = 2.0f; + + @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); + + @Mock private DisplayAndroid mMockDisplayAndroid; + @Mock private WindowManager mMockWindowManager; + + @Before + public void setUp() { + ChromeAndroidTaskUnitTestSupport.mockMaxWindowMetrics( + mMockWindowManager, + DEFAULT_FULL_SCREEN_BOUNDS_IN_PX, + DEFAULT_MAX_TAPPABLE_INSETS_IN_PX); + when(mMockDisplayAndroid.getDipScale()).thenReturn(TEST_DIP_SCALE); + } + + @Test + public void apply_clampsInputBoundsThatAreTooLarge() { + // Arrange: create a Rect that's larger than the maximized size. + Rect inputBoundsInPx = new Rect(DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX); + inputBoundsInPx.offset(/* dx= */ 0, /* dy= */ 10); + + // Act. + Rect adjustedBoundsInPx = + ChromeAndroidTaskBoundsConstraints.apply( + inputBoundsInPx, mMockDisplayAndroid, mMockWindowManager); + + // Assert. + assertEquals(DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX, adjustedBoundsInPx); + } + + @Test + public void apply_clampsInputBoundsThatAreTooSmall() { + // Arrange: create a Rect that's smaller than the smallest size. + int minSizeInPx = + DisplayUtil.dpToPx( + mMockDisplayAndroid, + ChromeAndroidTaskBoundsConstraints.MINIMAL_TASK_SIZE_DP); + int leftInPx = DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX.centerX(); + int topInPx = DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX.centerY(); + Rect inputBoundsInPx = + new Rect( + leftInPx, + topInPx, + /* right= */ leftInPx + minSizeInPx - 10, + /* bottom= */ topInPx + minSizeInPx - 10); + + // Act. + Rect adjustedBoundsInPx = + ChromeAndroidTaskBoundsConstraints.apply( + inputBoundsInPx, mMockDisplayAndroid, mMockWindowManager); + + // Assert. + Rect expectedBoundsInPx = + new Rect( + leftInPx, + topInPx, + /* right= */ leftInPx + minSizeInPx, + /* bottom= */ topInPx + minSizeInPx); + assertEquals(expectedBoundsInPx, adjustedBoundsInPx); + } + + @Test + public void getMaxBoundsInPx() { + // Act. + Rect maxBounds = ChromeAndroidTaskBoundsConstraints.getMaxBoundsInPx(mMockWindowManager); + + // Assert. + assertEquals(DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX, maxBounds); + } +}
diff --git a/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImpl.java b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImpl.java index 433b2182..bbbdf03 100644 --- a/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImpl.java +++ b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImpl.java
@@ -18,7 +18,6 @@ import android.view.Window; import android.view.WindowInsets; import android.view.WindowInsetsController; -import android.view.WindowManager; import androidx.annotation.GuardedBy; import androidx.annotation.RequiresApi; @@ -856,8 +855,10 @@ if (activity == null) return false; if (activity.isInMultiWindowMode()) { // Desktop windowing mode is also a multi-window mode. - return getCurrentBoundsInPxLocked(activityWindowAndroid) - .equals(getMaxBoundsInPx(activity.getWindowManager())); + Rect maxBoundsInPx = + ChromeAndroidTaskBoundsConstraints.getMaxBoundsInPx( + activity.getWindowManager()); + return getCurrentBoundsInPxLocked(activityWindowAndroid).equals(maxBoundsInPx); } else { // In non-multi-window mode, Chrome is maximized by default. return true; @@ -963,8 +964,9 @@ if (isRestoredInternalLocked(activityWindowAndroid)) { mRestoredBoundsInPx = getCurrentBoundsInPxLocked(activityWindowAndroid); } - Rect maximizedBounds = getMaxBoundsInPx(activity.getWindowManager()); - setBoundsInPxLocked(activity, activityWindowAndroid.getDisplay(), maximizedBounds); + Rect maxBoundsInPx = + ChromeAndroidTaskBoundsConstraints.getMaxBoundsInPx(activity.getWindowManager()); + setBoundsInPxLocked(activity, activityWindowAndroid.getDisplay(), maxBoundsInPx); } @GuardedBy("mActivityWindowAndroidLock") @@ -1001,19 +1003,12 @@ Rect boundsInPx = DisplayUtil.scaleToEnclosingRect( boundsInDp, activityWindowAndroid.getDisplay().getDipScale()); - setBoundsInPxLocked(activity, activityWindowAndroid.getDisplay(), boundsInPx); - } - - @RequiresApi(api = VERSION_CODES.R) - private static Rect getMaxBoundsInPx(WindowManager windowManager) { - var insets = - windowManager - .getMaximumWindowMetrics() - .getWindowInsets() - .getInsets(WindowInsets.Type.tappableElement()); - var fullscreenBounds = windowManager.getMaximumWindowMetrics().getBounds(); - return new Rect( - 0, insets.top, fullscreenBounds.right, fullscreenBounds.bottom - insets.bottom); + Rect adjustedBoundsInPx = + ChromeAndroidTaskBoundsConstraints.apply( + boundsInPx, + activityWindowAndroid.getDisplay(), + activity.getWindowManager()); + setBoundsInPxLocked(activity, activityWindowAndroid.getDisplay(), adjustedBoundsInPx); } @Nullable Rect getRestoredBoundsInPxForTesting() {
diff --git a/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImplUnitTest.java b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImplUnitTest.java index 8f63b97..e37fb46 100644 --- a/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImplUnitTest.java +++ b/chrome/browser/ui/browser_window/internal/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskImplUnitTest.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.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; @@ -21,22 +22,17 @@ import static org.mockito.Mockito.when; import static org.chromium.build.NullUtil.assertNonNull; +import static org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskUnitTestSupport.DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX; +import static org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskUnitTestSupport.DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX; import android.annotation.SuppressLint; import android.app.ActivityManager; import android.content.Context; import android.content.res.Configuration; -import android.graphics.Insets; import android.graphics.Rect; import android.os.Build; -import android.view.Window; -import android.view.WindowInsets; -import android.view.WindowInsetsController; -import android.view.WindowManager; import android.view.WindowMetrics; -import androidx.core.view.WindowInsetsControllerCompat; - import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; @@ -60,6 +56,8 @@ import org.chromium.chrome.browser.tab.TabLaunchType; import org.chromium.chrome.browser.tabmodel.TabModel; import org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskImpl.State; +import org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskUnitTestSupport.ActivityWindowAndroidMocks; +import org.chromium.chrome.browser.ui.browser_window.ChromeAndroidTaskUnitTestSupport.ChromeAndroidTaskWithMockDeps; import org.chromium.chrome.browser.ui.browser_window.PendingActionManager.PendingAction; import org.chromium.ui.display.DisplayUtil; import org.chromium.ui.mojom.WindowShowState; @@ -67,36 +65,57 @@ import java.util.Arrays; @RunWith(BaseRobolectricTestRunner.class) +@Config(sdk = Build.VERSION_CODES.R) public class ChromeAndroidTaskImplUnitTest { @Rule public FakeTimeTestRule mFakeTimeTestRule = new FakeTimeTestRule(); @Rule public MockitoRule mMockitoRule = MockitoJUnit.rule(); - private static ChromeAndroidTaskImpl createChromeAndroidTask() { - return createChromeAndroidTask(/* taskId= */ 1); + @SuppressLint("NewApi" /* @Config already specifies the required SDK */) + private static ChromeAndroidTaskWithMockDeps createChromeAndroidTaskWithMockDeps(int taskId) { + return createChromeAndroidTaskWithMockDeps(taskId, /* isPendingTask= */ false); } - private static ChromeAndroidTaskImpl createChromeAndroidTask(int taskId) { - var chromeAndroidTask = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps(taskId) - .mChromeAndroidTask; - assert chromeAndroidTask instanceof ChromeAndroidTaskImpl; - return (ChromeAndroidTaskImpl) chromeAndroidTask; + @SuppressLint("NewApi" /* @Config already specifies the required SDK */) + private static ChromeAndroidTaskWithMockDeps createChromeAndroidTaskWithMockDeps( + int taskId, boolean isPendingTask) { + var chromeAndroidTaskWithMockDeps = + ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( + taskId, /* mockNatives= */ true, isPendingTask); + var activityWindowAndroidMocks = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks; + mockDesktopWindowingMode(activityWindowAndroidMocks); + + return chromeAndroidTaskWithMockDeps; + } + + @SuppressLint("NewApi" /* @Config already specifies the required SDK */) + private static ActivityWindowAndroidMocks createActivityWindowAndroidMocks(int taskId) { + var activityWindowAndroidMocks = + ChromeAndroidTaskUnitTestSupport.createActivityWindowAndroidMocks(taskId); + mockDesktopWindowingMode(activityWindowAndroidMocks); + return activityWindowAndroidMocks; + } + + @SuppressLint("NewApi" /* @Config already specifies the required SDK */) + private static void mockDesktopWindowingMode( + ActivityWindowAndroidMocks activityWindowAndroidMocks) { + ChromeAndroidTaskUnitTestSupport.mockDesktopWindowingMode(activityWindowAndroidMocks); + + // Move mock Activity to the "resumed" state. + var mockActivity = activityWindowAndroidMocks.mMockActivity; + ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.CREATED); + ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.RESUMED); } @Test public void constructor_withActivity_setsActivityWindowAndroid() { // Arrange. + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var activityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(/* taskId= */ 1); - var profile = mock(Profile.class); - var tabModel = mock(TabModel.class); - when(tabModel.getProfile()).thenReturn(profile); - - // Act. - var chromeAndroidTask = - new ChromeAndroidTaskImpl( - BrowserWindowType.NORMAL, activityWindowAndroid, tabModel); + chromeAndroidTaskWithMockDeps + .mActivityWindowAndroidMocks + .mMockActivityWindowAndroid; // Assert. assertEquals(activityWindowAndroid, chromeAndroidTask.getActivityWindowAndroid()); @@ -105,9 +124,7 @@ @Test public void constructor_withActivity_registersActivityLifecycleObservers() { // Arrange & Act. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var mockActivityLifecycleDispatcher = chromeAndroidTaskWithMockDeps .mActivityWindowAndroidMocks @@ -123,9 +140,7 @@ @Test public void constructor_withActivity_setsTabModelRefAndRegistersTabModelObserver() { // Arrange & Act. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var mockTabModel = chromeAndroidTaskWithMockDeps.mMockTabModel; @@ -156,39 +171,31 @@ @Test public void getProfile_returnsInitialProfile() { // Arrange. - var profile = mock(Profile.class); - var tabModel = mock(TabModel.class); - when(tabModel.getProfile()).thenReturn(profile); - var chromeAndroidTask = - new ChromeAndroidTaskImpl( - BrowserWindowType.NORMAL, - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(1), - tabModel); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var initialProfile = chromeAndroidTaskWithMockDeps.mMockProfile; // Act & Assert. assertEquals( "The returned Profile should be the same as the one from the constructor.", - profile, + initialProfile, chromeAndroidTask.getProfile()); } @Test public void didAddTab_withDifferentProfile_throwsAssertionError() { // Arrange. - var initialProfile = mock(Profile.class, "InitialProfile"); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = + (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var initialProfile = chromeAndroidTaskWithMockDeps.mMockProfile; + var differentProfile = mock(Profile.class, "DifferentProfile"); var tabWithDifferentProfile = mock(Tab.class); when(tabWithDifferentProfile.getProfile()).thenReturn(differentProfile); - var tabModel = mock(TabModel.class); - when(tabModel.getProfile()).thenReturn(initialProfile); - - var chromeAndroidTask = - new ChromeAndroidTaskImpl( - BrowserWindowType.NORMAL, - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(1), - tabModel); // Act & Assert. + assertNotEquals(initialProfile, differentProfile); assertThrows( AssertionError.class, () -> @@ -203,7 +210,7 @@ public void getId_returnsTaskId() { // Arrange. int taskId = 1; - var chromeAndroidTask = createChromeAndroidTask(taskId); + var chromeAndroidTask = createChromeAndroidTaskWithMockDeps(taskId).mChromeAndroidTask; // Act & Assert. assertEquals(taskId, (int) chromeAndroidTask.getId()); @@ -212,9 +219,10 @@ @Test public void setActivityWindowAndroid_refAlreadyExists_throwsException() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + int taskId = 1; + var chromeAndroidTask = createChromeAndroidTaskWithMockDeps(taskId).mChromeAndroidTask; var newActivityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(/* taskId= */ 1); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; // Act & Assert. assertThrows( @@ -232,7 +240,7 @@ var task = new ChromeAndroidTaskImpl(/* pendingId= */ 1, mockParams); int taskId = 2; var activityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(taskId); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; // Act. task.setActivityWindowAndroid(activityWindowAndroid, mock(TabModel.class)); @@ -247,9 +255,9 @@ public void setActivityWindowAndroid_previousRefCleared_setsNewRef() { // Arrange. int taskId = 1; - var chromeAndroidTask = createChromeAndroidTask(taskId); + var chromeAndroidTask = createChromeAndroidTaskWithMockDeps(taskId).mChromeAndroidTask; var newActivityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(taskId); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; chromeAndroidTask.clearActivityWindowAndroid(); // Act. @@ -264,9 +272,8 @@ setActivityWindowAndroid_previousRefCleared_registersNewActivityLifecycleObservers() { // Arrange. int taskId = 1; - var chromeAndroidTask = createChromeAndroidTask(taskId); - var newActivityWindowAndroidMocks = - ChromeAndroidTaskUnitTestSupport.createActivityWindowAndroidMocks(taskId); + var chromeAndroidTask = createChromeAndroidTaskWithMockDeps(taskId).mChromeAndroidTask; + var newActivityWindowAndroidMocks = createActivityWindowAndroidMocks(taskId); chromeAndroidTask.clearActivityWindowAndroid(); // Act. @@ -285,14 +292,12 @@ setActivityWindowAndroid_previousRefCleared_setsNewTabModelRefAndRegistersTabModelObserver() { // Arrange. int taskId = 1; - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps(taskId); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(taskId); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var oldMockTabModel = chromeAndroidTaskWithMockDeps.mMockTabModel; - var newActivityWindowAndroidMocks = - ChromeAndroidTaskUnitTestSupport.createActivityWindowAndroidMocks(taskId); + var newActivityWindowAndroidMocks = createActivityWindowAndroidMocks(taskId); var newMockTabModel = mock(TabModel.class); // Act. @@ -313,9 +318,10 @@ public void setActivityWindowAndroid_previousRefCleared_newRefHasDifferentTaskId_throwsException() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; var newActivityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(/* taskId= */ 2); + createActivityWindowAndroidMocks(/* taskId= */ 2).mMockActivityWindowAndroid; chromeAndroidTask.clearActivityWindowAndroid(); // Act & Assert. @@ -330,12 +336,13 @@ public void setActivityWindowAndroid_calledAfterTaskDestroyed_throwsException() { // Arrange. int taskId = 1; - var chromeAndroidTask = createChromeAndroidTask(taskId); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; chromeAndroidTask.destroy(); // Act & Assert. var newActivityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(taskId); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; assertThrows( AssertionError.class, () -> @@ -346,21 +353,19 @@ @Test public void getActivityWindowAndroid_calledAfterTaskDestroyed_throwsException() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; chromeAndroidTask.destroy(); // Act & Assert. - assertThrows(AssertionError.class, () -> chromeAndroidTask.getActivityWindowAndroid()); + assertThrows(AssertionError.class, chromeAndroidTask::getActivityWindowAndroid); } @Test public void clearActivityWindowAndroid_unregistersActivityLifecycleObservers() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var mockActivityLifecycleDispatcher = chromeAndroidTaskWithMockDeps .mActivityWindowAndroidMocks @@ -379,9 +384,7 @@ @Test public void clearActivityWindowAndroid_unregistersTabModelObserverAndClearTabModelRef() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var mockTabModel = chromeAndroidTaskWithMockDeps.mMockTabModel; @@ -397,7 +400,8 @@ @Test public void addFeature_addsFeatureToInternalFeatureList() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; var mockFeature1 = mock(ChromeAndroidTaskFeature.class); var mockFeature2 = mock(ChromeAndroidTaskFeature.class); @@ -414,7 +418,8 @@ @Test public void addFeature_invokesOnAddedToTaskForFeature() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; var mockFeature = mock(ChromeAndroidTaskFeature.class); // Act. @@ -427,7 +432,8 @@ @Test public void addFeature_calledAfterTaskDestroyed_throwsException() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; chromeAndroidTask.destroy(); // Act & Assert. @@ -438,9 +444,7 @@ @Test public void getOrCreateNativeBrowserWindowPtr_returnsPtrValueForAliveTask() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; // Act. @@ -472,18 +476,20 @@ @Test public void getOrCreateNativeBrowserWindowPtr_calledAfterTaskDestroyed_throwsException() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; chromeAndroidTask.destroy(); // Act & Assert. - assertThrows( - AssertionError.class, () -> chromeAndroidTask.getOrCreateNativeBrowserWindowPtr()); + assertThrows(AssertionError.class, chromeAndroidTask::getOrCreateNativeBrowserWindowPtr); } @Test public void destroy_clearsActivityWindowAndroid() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + (ChromeAndroidTaskImpl) + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; // Act. chromeAndroidTask.destroy(); @@ -495,7 +501,8 @@ @Test public void destroy_destroysAllFeatures() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; var mockFeature1 = mock(ChromeAndroidTaskFeature.class); var mockFeature2 = mock(ChromeAndroidTaskFeature.class); chromeAndroidTask.addFeature(mockFeature1); @@ -513,9 +520,7 @@ @Test public void destroy_destroysAndroidBrowserWindow() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var mockAndroidBrowserWindowNatives = assertNonNull(chromeAndroidTaskWithMockDeps.mMockAndroidBrowserWindowNatives); @@ -531,7 +536,8 @@ @Test public void destroy_setsStateToDestroyed() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; assertFalse(chromeAndroidTask.isDestroyed()); // Act. @@ -553,7 +559,8 @@ // its onTaskRemoved() method. No feature should do this in production, but there is nothing // preventing this at compile time. Besides ChromeAndroidTask#addFeature(), the feature // could also call other ChromeAndroidTask APIs that require the Task state to be "ALIVE". - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; var mockFeature = mock(ChromeAndroidTaskFeature.class); doAnswer( invocation -> { @@ -565,17 +572,14 @@ chromeAndroidTask.addFeature(mockFeature); // Act & Assert. - assertThrows(AssertionError.class, () -> chromeAndroidTask.destroy()); + assertThrows(AssertionError.class, chromeAndroidTask::destroy); } @Test - @Config(sdk = Build.VERSION_CODES.R) @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void onConfigurationChanged_windowBoundsChanged_invokesOnTaskBoundsChangedForFeature() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; @@ -601,14 +605,11 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void onConfigurationChanged_windowBoundsDoesNotChangeInPxOrDp_doesNotInvokeOnTaskBoundsChangedForFeature() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; @@ -640,14 +641,11 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void onConfigurationChanged_windowBoundsChangesInPxButNotInDp_doesNotInvokeOnTaskBoundsChangedForFeature() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; @@ -685,9 +683,7 @@ @Test public void onTopResumedActivityChanged_activityIsTopResumed_updatesLastActivatedTime() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; long elapsedRealTime = TimeUtils.elapsedRealtimeMillis(); @@ -703,9 +699,7 @@ public void onTopResumedActivityChanged_activityIsNotTopResumed_doesNotUpdateLastActivatedTime() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; long elapsedRealTime1 = TimeUtils.elapsedRealtimeMillis(); @@ -723,7 +717,9 @@ @Test public void onTopResumedActivityChanged_invokesOnTaskFocusChangedForFeature() { // Arrange. - var chromeAndroidTask = createChromeAndroidTask(); + var chromeAndroidTask = + (ChromeAndroidTaskImpl) + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; var mockFeature = mock(ChromeAndroidTaskFeature.class); chromeAndroidTask.addFeature(mockFeature); @@ -739,24 +735,11 @@ @Test @Config(sdk = Build.VERSION_CODES.BAKLAVA) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void maximize_maximizeToMaximizedBounds() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; - var mockWindowManager = - chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockWindowManager; - var mockActivity = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockActivity; - - // Mock isInMultiWindowMode() to return true. - when(mockActivity.isInMultiWindowMode()).thenReturn(true); - - // Mock getMaximizedBounds(). - var maximizedBounds = mockMaximizedBounds(mockWindowManager); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; // Act. chromeAndroidTask.maximize(); @@ -766,50 +749,27 @@ verify(apiDelegate).moveTaskTo(any(), anyInt(), boundsCaptor.capture()); var capturedBounds = boundsCaptor.getValue(); - assertEquals("Not moving to target bound", maximizedBounds, capturedBounds); + assertEquals( + "Not moving to target bound", + DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX, + capturedBounds); } @Test - @Config(sdk = Build.VERSION_CODES.R) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void isMaximized_falseWhenNotMaximized() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; - var mockWindowManager = - chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockWindowManager; - - // Mock isInMultiWindowMode() to return true. - var mockWindowMetrics = mock(WindowMetrics.class); - when(chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockActivity - .isInMultiWindowMode()) - .thenReturn(true); - - // Mock getBounds() to return non-maximized bounds. - var currentBounds = new Rect(0, 0, 800, 600); - when(mockWindowManager.getCurrentWindowMetrics()).thenReturn(mockWindowMetrics); - when(mockWindowMetrics.getBounds()).thenReturn(currentBounds); - - // Mock getMaximizedBounds(). - mockMaximizedBounds(mockWindowManager); + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1).mChromeAndroidTask; // Act & Assert. assertFalse(chromeAndroidTask.isMaximized()); } @Test - @Config(sdk = Build.VERSION_CODES.R) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void getBoundsInDp_convertsBoundsInPxToDp() { // Arrange: ChromeAndroidTask - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; // Arrange: scaling factor float dipScale = 2.0f; @@ -817,72 +777,31 @@ chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockDisplayAndroid; when(mockDisplayAndroid.getDipScale()).thenReturn(dipScale); - // Arrange: bounds in pixels - Rect boundsInPx = new Rect(10, 20, 800, 600); - var mockWindowMetrics = mock(WindowMetrics.class); - when(mockWindowMetrics.getBounds()).thenReturn(boundsInPx); - var mockWindowManager = - chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockWindowManager; - when(mockWindowManager.getCurrentWindowMetrics()).thenReturn(mockWindowMetrics); - // Act Rect boundsInDp = chromeAndroidTask.getBoundsInDp(); // Assert - Rect expectedBoundsInDp = DisplayUtil.scaleToEnclosingRect(boundsInPx, 1.0f / dipScale); + Rect expectedBoundsInDp = + DisplayUtil.scaleToEnclosingRect( + DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX, 1.0f / dipScale); assertEquals(expectedBoundsInDp, boundsInDp); } @Test - @Config(sdk = Build.VERSION_CODES.R) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void getRestoredBoundsInDp_convertsBoundsInPxToDp() { // 1. Arrange: Create a ChromeAndroidTask with mock dependencies. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var mockDisplayAndroid = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockDisplayAndroid; - var mockWindowManager = - chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockWindowManager; - var mockActivity = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockActivity; // 2. Arrange: scaling factor float dipScale = 2.0f; when(mockDisplayAndroid.getDipScale()).thenReturn(dipScale); - // 3. Arrange: Mock isRestoredInternalLocked() to return true before maximize(). - // 3.1. Mock isMinimizedInternalLocked() to be false. (Assuming task is visible) - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.CREATED); - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.RESUMED); - assertFalse("Task is minimized", chromeAndroidTask.isMinimized()); - - // 3.2. Mock isMaximizedInternalLocked() to be false. - when(chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockActivity - .isInMultiWindowMode()) - .thenReturn(true); - - Rect currentBoundsInPx = new Rect(0, 0, 800, 600); - var mockCurrentWindowMetrics = mock(WindowMetrics.class); - when(mockCurrentWindowMetrics.getBounds()).thenReturn(currentBoundsInPx); - when(mockWindowManager.getCurrentWindowMetrics()).thenReturn(mockCurrentWindowMetrics); - - Rect maxBoundsInPx = new Rect(0, 0, 1920, 1080); - var mockMaxWindowMetrics = mock(WindowMetrics.class); - when(mockMaxWindowMetrics.getBounds()).thenReturn(maxBoundsInPx); - when(mockWindowManager.getMaximumWindowMetrics()).thenReturn(mockMaxWindowMetrics); - - var mockMaxWindowInsets = mock(WindowInsets.class); - when(mockMaxWindowMetrics.getWindowInsets()).thenReturn(mockMaxWindowInsets); - when(mockMaxWindowInsets.getInsets(WindowInsets.Type.tappableElement())) - .thenReturn(Insets.of(0, 0, 0, 0)); + // 3. Arrange: check the default test setup. + assertFalse("Task shouldn't be minimized", chromeAndroidTask.isMinimized()); assertFalse("Task shouldn't be maximized", chromeAndroidTask.isMaximized()); - - // 3.3. Mock isFullscreenInternalLocked() to be false. - when(mockActivity.getWindow()).thenReturn(mock(Window.class)); - when(mockMaxWindowInsets.isVisible(WindowInsets.Type.statusBars())).thenReturn(true); assertFalse("Task shouldn't be full-screen", chromeAndroidTask.isFullscreen()); // 4. Arrange: Call maximize(). This should set mRestoredBounds to the current bounds. @@ -893,7 +812,8 @@ // 6. Assert Rect expectedBoundsInDp = - DisplayUtil.scaleToEnclosingRect(currentBoundsInPx, 1.0f / dipScale); + DisplayUtil.scaleToEnclosingRect( + DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX, 1.0f / dipScale); assertEquals( "restored bounds should be the current bounds in dp", expectedBoundsInDp, @@ -902,14 +822,10 @@ @Test @Config(sdk = Build.VERSION_CODES.BAKLAVA) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void setBoundsInDp_setsNewBoundsInPx() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; var displayAndroid = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockDisplayAndroid; @@ -917,7 +833,10 @@ when(displayAndroid.getDipScale()).thenReturn(dipScale); // Act. - Rect newBoundsInDp = new Rect(10, 20, 800, 600); + Rect newBoundsInDp = + DisplayUtil.scaleToEnclosingRect( + DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX, 1.0f / dipScale); + newBoundsInDp.offset(/* dx= */ 10, /* dy= */ 10); chromeAndroidTask.setBoundsInDp(newBoundsInDp); // Assert. @@ -932,61 +851,98 @@ @Test @Config(sdk = Build.VERSION_CODES.BAKLAVA) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) + public void setBoundsInDp_clampsBoundsThatAreTooLarge() { + // Arrange + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; + var displayAndroid = + chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockDisplayAndroid; + float dipScale = 2.0f; + when(displayAndroid.getDipScale()).thenReturn(dipScale); + + // Act: set new bounds that are larger than the maximized bounds. + Rect newBoundsInDp = + DisplayUtil.scaleToEnclosingRect( + DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX, 1.0f / dipScale); + newBoundsInDp.offset(/* dx= */ 0, /* dy= */ 500); + chromeAndroidTask.setBoundsInDp(newBoundsInDp); + + // Assert + var boundsCaptor = ArgumentCaptor.forClass(Rect.class); + verify(apiDelegate).moveTaskTo(any(), anyInt(), boundsCaptor.capture()); + assertEquals( + "Bounds that are too large should be clamped to the maximized bounds", + DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX, + boundsCaptor.getValue()); + } + + @Test + @Config(sdk = Build.VERSION_CODES.BAKLAVA) + public void setBoundsInDp_clampsBoundsThatAreTooSmall() { + // Arrange + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; + var displayAndroid = + chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockDisplayAndroid; + float dipScale = 2.0f; + when(displayAndroid.getDipScale()).thenReturn(dipScale); + + // Act: set new bounds that are smaller than the minimum size. + Rect maxBoundsInDp = + DisplayUtil.scaleToEnclosingRect( + DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX, 1.0f / dipScale); + Rect newBoundsInDp = + new Rect( + maxBoundsInDp.centerX(), + maxBoundsInDp.centerY(), + /* right= */ maxBoundsInDp.centerX() + + ChromeAndroidTaskBoundsConstraints.MINIMAL_TASK_SIZE_DP + - 10, + /* bottom= */ maxBoundsInDp.centerY() + + ChromeAndroidTaskBoundsConstraints.MINIMAL_TASK_SIZE_DP + - 10); + chromeAndroidTask.setBoundsInDp(newBoundsInDp); + + // Assert + Rect expectedBoundsInDp = + new Rect( + maxBoundsInDp.centerX(), + maxBoundsInDp.centerY(), + /* right= */ maxBoundsInDp.centerX() + + ChromeAndroidTaskBoundsConstraints.MINIMAL_TASK_SIZE_DP, + /* bottom= */ maxBoundsInDp.centerY() + + ChromeAndroidTaskBoundsConstraints.MINIMAL_TASK_SIZE_DP); + Rect expectedBoundsInPx = DisplayUtil.scaleToEnclosingRect(expectedBoundsInDp, dipScale); + var boundsCaptor = ArgumentCaptor.forClass(Rect.class); + verify(apiDelegate).moveTaskTo(any(), anyInt(), boundsCaptor.capture()); + assertEquals( + "Bounds that are too small should be adjusted to the minimum size", + expectedBoundsInPx, + boundsCaptor.getValue()); + } + + @Test + @Config(sdk = Build.VERSION_CODES.BAKLAVA) public void restore_restoresToPreviousBounds() { // Arrange - int taskId = 1; - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps(taskId); + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; var chromeAndroidTask = (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; - var mockActivity = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockActivity; - var mockWindowManager = - chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockWindowManager; - var mockWindow = mock(Window.class); - when(mockActivity.getWindow()).thenReturn(mockWindow); - var mockWindowInsetsController = mock(WindowInsetsController.class); - when(mockWindow.getInsetsController()).thenReturn(mockWindowInsetsController); - when(mockWindowInsetsController.getSystemBarsBehavior()) - .thenReturn(WindowInsetsControllerCompat.BEHAVIOR_DEFAULT); - // Mock isRestoredInternalLocked() to return true before maximize(). - // 1. Mock isMinimizedInternalLocked() to be false. (Assuming task is visible) - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.CREATED); - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.RESUMED); - assertFalse("Task is minimized", chromeAndroidTask.isMinimized()); - - // 2. Mock isMaximizedInternalLocked() to be false. - // Mock isInMultiWindowMode() to return true. - var mockWindowMetrics = mock(WindowMetrics.class); - when(mockWindowManager.getCurrentWindowMetrics()).thenReturn(mockWindowMetrics); - when(chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockActivity - .isInMultiWindowMode()) - .thenReturn(true); - - var restoredBounds = new Rect(0, 0, 800, 600); - when(mockWindowMetrics.getBounds()).thenReturn(restoredBounds); - - var mockMaxWindowMetrics = mock(WindowMetrics.class); - var mockMaxWindowInsets = mock(WindowInsets.class); - when(mockWindowManager.getMaximumWindowMetrics()).thenReturn(mockMaxWindowMetrics); - when(mockMaxWindowMetrics.getWindowInsets()).thenReturn(mockMaxWindowInsets); - when(mockMaxWindowInsets.getInsets(WindowInsets.Type.tappableElement())) - .thenReturn(Insets.of(0, 0, 0, 0)); - when(mockMaxWindowMetrics.getBounds()).thenReturn(new Rect(0, 0, 1920, 1080)); - assertFalse("Task is maximized", chromeAndroidTask.isMaximized()); - - // 3. Mock isFullscreenInternalLocked() to be false. - when(mockMaxWindowInsets.isVisible(WindowInsets.Type.statusBars())).thenReturn(true); - assertFalse("Task is fullscreen", chromeAndroidTask.isFullscreen()); + // Check the default test setup. + assertFalse("Task shouldn't be minimized", chromeAndroidTask.isMinimized()); + assertFalse("Task shouldn't be maximized", chromeAndroidTask.isMaximized()); + assertFalse("Task shouldn't be fullscreen", chromeAndroidTask.isFullscreen()); // Call maximize(). This should set mRestoredBounds to the current bounds. chromeAndroidTask.maximize(); assertEquals( "restored bounds should be set to the current bounds", - restoredBounds, + DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX, chromeAndroidTask.getRestoredBoundsInPxForTesting()); // Act @@ -997,22 +953,19 @@ verify(apiDelegate, times(2)).moveTaskTo(any(), anyInt(), boundsCaptor.capture()); var capturedBounds = boundsCaptor.getValue(); - assertEquals("Not moving to target bound", restoredBounds, capturedBounds); + assertEquals( + "Not moving to target bound", DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX, capturedBounds); } @Test - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void minimize_alreadyMinimized_doesNotMinimizeAgain() { // Arrange. - var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1); - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var chromeAndroidTaskWithMockDeps = createChromeAndroidTaskWithMockDeps(/* taskId= */ 1); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; var activity = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockActivity; // Mock isMinimized() to return true. - ApplicationStatus.onStateChangeForTesting(activity, ActivityState.CREATED); + ApplicationStatus.onStateChangeForTesting(activity, ActivityState.PAUSED); ApplicationStatus.onStateChangeForTesting(activity, ActivityState.STOPPED); assertTrue("Task is minimized", chromeAndroidTask.isMinimized()); @@ -1105,7 +1058,6 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) public void maximize_whenPending_enqueuesPendingAction() { // Arrange. var mockParams = @@ -1122,7 +1074,6 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) public void minimize_whenPending_enqueuesPendingAction() { // Arrange. var mockParams = @@ -1226,7 +1177,6 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) public void isMaximized_whenPending_withPendingMaximize_returnsTrue() { // Arrange. var mockParams = @@ -1240,7 +1190,6 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) public void isMaximized_whenPending_withMaximizedStateInCreateParams_returnsTrue() { // Arrange. var mockParams = @@ -1253,7 +1202,6 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) public void isMaximized_whenPending_withDefaultStateInCreateParams_withoutPendingMaximize_returnsFalse() { // Arrange. @@ -1266,7 +1214,6 @@ } @Test - @Config(sdk = Build.VERSION_CODES.R) public void isMinimized_whenPending_withPendingMinimize_returnsTrue() { // Arrange. var mockParams = @@ -1461,12 +1408,10 @@ int taskId = 2; // Arrange: Setup WindowAndroid. var activityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(taskId); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; var mockActivity = activityWindowAndroid.getActivity().get(); var mockActivityManager = (ActivityManager) mockActivity.getSystemService(Context.ACTIVITY_SERVICE); - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.CREATED); - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.RESUMED); // Act. task.setActivityWindowAndroid(activityWindowAndroid, mock(TabModel.class)); @@ -1486,7 +1431,7 @@ int taskId = 2; // Arrange: Setup WindowAndroid. var activityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(taskId); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; var mockActivity = activityWindowAndroid.getActivity().get(); // Act. @@ -1507,7 +1452,7 @@ // Arrange: Setup WindowAndroid. int taskId = 2; var activityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(taskId); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; var mockActivity = activityWindowAndroid.getActivity().get(); var mockActivityManager = (ActivityManager) mockActivity.getSystemService(Context.ACTIVITY_SERVICE); @@ -1521,12 +1466,10 @@ @Test @Config(sdk = Build.VERSION_CODES.BAKLAVA) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void setActivityWindowAndroid_fromPendingState_dispatchesPendingMaximize() { // Arrange: Create pending task. var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1, /* mockNatives= */ true, /* isPendingTask= */ true); + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1, /* isPendingTask= */ true); var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; // Arrange: Request MAXIMIZE on a pending task. @@ -1536,13 +1479,6 @@ chromeAndroidTaskWithMockDeps .mActivityWindowAndroidMocks .mMockActivityWindowAndroid; - var mockActivity = activityWindowAndroid.getActivity().get(); - when(mockActivity.isInMultiWindowMode()).thenReturn(true); - var maximizedBounds = - mockMaximizedBounds( - chromeAndroidTaskWithMockDeps - .mActivityWindowAndroidMocks - .mMockWindowManager); // Act. chromeAndroidTask.setActivityWindowAndroid( @@ -1552,26 +1488,22 @@ var boundsCaptor = ArgumentCaptor.forClass(Rect.class); verify(apiDelegate).moveTaskTo(any(), anyInt(), boundsCaptor.capture()); var capturedBounds = boundsCaptor.getValue(); - assertEquals(maximizedBounds, capturedBounds); + assertEquals(DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX, capturedBounds); } @Test - @Config(sdk = Build.VERSION_CODES.R) public void setActivityWindowAndroid_fromPendingState_dispatchesPendingMinimize() { // Arrange: Create pending task. var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1, /* mockNatives= */ true, /* isPendingTask= */ true); + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1, /* isPendingTask= */ true); var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; // Arrange: Request MINIMIZE on a pending task. chromeAndroidTask.minimize(); // Arrange: Setup WindowAndroid. int taskId = 2; var activityWindowAndroid = - ChromeAndroidTaskUnitTestSupport.createMockActivityWindowAndroid(taskId); + createActivityWindowAndroidMocks(taskId).mMockActivityWindowAndroid; var mockActivity = activityWindowAndroid.getActivity().get(); - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.CREATED); - ApplicationStatus.onStateChangeForTesting(mockActivity, ActivityState.RESUMED); // Act. chromeAndroidTask.setActivityWindowAndroid( @@ -1583,16 +1515,13 @@ @Test @Config(sdk = Build.VERSION_CODES.BAKLAVA) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void setActivityWindowAndroid_fromPendingState_withNonEmptyPendingBounds_dispatchesPendingRestore() { // Arrange: Create pending task. var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1, /* mockNatives= */ true, /* isPendingTask= */ true); + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1, /* isPendingTask= */ true); var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; // Arrange: Setup display parameters. var displayAndroid = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockDisplayAndroid; @@ -1622,16 +1551,13 @@ @Test @Config(sdk = Build.VERSION_CODES.BAKLAVA) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void setActivityWindowAndroid_fromPendingState_withEmptyPendingBounds_ignoresPendingRestore() { // Arrange: Create pending task. var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1, /* mockNatives= */ true, /* isPendingTask= */ true); + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1, /* isPendingTask= */ true); var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; // Arrange: Request RESTORE on a pending task. chromeAndroidTask.restore(); // Arrange: Setup WindowAndroid. @@ -1650,28 +1576,29 @@ @Test @Config(sdk = Build.VERSION_CODES.BAKLAVA) - @SuppressLint("NewApi" /* @Config already specifies the required SDK */) public void setActivityWindowAndroid_fromPendingState_dispatchesPendingSetBounds() { // Arrange: Create pending task. var chromeAndroidTaskWithMockDeps = - ChromeAndroidTaskUnitTestSupport.createChromeAndroidTaskWithMockDeps( - /* taskId= */ 1, /* mockNatives= */ true, /* isPendingTask= */ true); + createChromeAndroidTaskWithMockDeps(/* taskId= */ 1, /* isPendingTask= */ true); + var chromeAndroidTask = chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + var activityWindowAndroid = + chromeAndroidTaskWithMockDeps + .mActivityWindowAndroidMocks + .mMockActivityWindowAndroid; var apiDelegate = chromeAndroidTaskWithMockDeps.mMockAconfigFlaggedApiDelegate; - var chromeAndroidTask = - (ChromeAndroidTaskImpl) chromeAndroidTaskWithMockDeps.mChromeAndroidTask; + // Arrange: Setup display parameters. var displayAndroid = chromeAndroidTaskWithMockDeps.mActivityWindowAndroidMocks.mMockDisplayAndroid; float dipScale = 2.0f; when(displayAndroid.getDipScale()).thenReturn(dipScale); + // Arrange: Request SET_BOUNDS on a pending task. - Rect pendingBoundsInDp = new Rect(10, 20, 800, 600); + Rect pendingBoundsInDp = + DisplayUtil.scaleToEnclosingRect( + DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX, 1.0f / dipScale); + pendingBoundsInDp.offset(/* dx= */ 10, /* dy= */ 10); chromeAndroidTask.setBoundsInDp(pendingBoundsInDp); - // Arrange: Setup WindowAndroid. - var activityWindowAndroid = - chromeAndroidTaskWithMockDeps - .mActivityWindowAndroidMocks - .mMockActivityWindowAndroid; // Act. chromeAndroidTask.setActivityWindowAndroid( @@ -1683,22 +1610,4 @@ verify(apiDelegate).moveTaskTo(any(), anyInt(), boundsCaptor.capture()); assertEquals(expectedBoundsInPx, boundsCaptor.getValue()); } - - /** - * This method sets up mock insets and window metrics to simulate and return maximized window - * bounds when {@link WindowManager#getMaximumWindowMetrics()} is invoked from {@code - * mockWindowManager}. - */ - private static Rect mockMaximizedBounds(WindowManager mockWindowManager) { - var mockMaxWindowMetrics = mock(WindowMetrics.class); - var mockMaxWindowInsets = mock(WindowInsets.class); - when(mockWindowManager.getMaximumWindowMetrics()).thenReturn(mockMaxWindowMetrics); - when(mockMaxWindowMetrics.getWindowInsets()).thenReturn(mockMaxWindowInsets); - var tappableInsets = Insets.of(0, 10, 0, 20); - when(mockMaxWindowInsets.getInsets(WindowInsets.Type.tappableElement())) - .thenReturn(tappableInsets); - var fullscreenBounds = new Rect(0, 0, 1920, 1080); - when(mockMaxWindowMetrics.getBounds()).thenReturn(fullscreenBounds); - return new Rect(0, 10, 1920, 1060); - } }
diff --git a/chrome/browser/ui/browser_window/internal/browser_window_features.cc b/chrome/browser/ui/browser_window/internal/browser_window_features.cc index 4b347e9..ef92de0 100644 --- a/chrome/browser/ui/browser_window/internal/browser_window_features.cc +++ b/chrome/browser/ui/browser_window/internal/browser_window_features.cc
@@ -87,7 +87,6 @@ #include "chrome/browser/ui/views/interaction/browser_elements_views_impl.h" #include "chrome/browser/ui/views/location_bar/cookie_controls/cookie_controls_bubble_coordinator.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/views/media_router/cast_browser_controller.h" #include "chrome/browser/ui/views/new_tab_footer/footer_controller.h" #include "chrome/browser/ui/views/profiles/profile_customization_bubble_sync_controller.h" @@ -762,10 +761,6 @@ std::make_unique<WindowsTaskbarIconUpdater>(*browser_view); #endif - zoom_bubble_coordinator_ = - GetUserDataFactory().CreateInstance<ZoomBubbleCoordinator>(*browser_, - *browser_view); - user_education_->Init(browser_view); find_bar_owner_ = std::make_unique<FindBarOwnerViews>(browser_view); @@ -805,8 +800,6 @@ } #endif - zoom_bubble_coordinator_.reset(); - comments_side_panel_coordinator_.reset(); history_clusters_side_panel_coordinator_.reset();
diff --git a/chrome/browser/ui/browser_window/public/browser_window_features.h b/chrome/browser/ui/browser_window/public/browser_window_features.h index 66cb990..faf0e6e 100644 --- a/chrome/browser/ui/browser_window/public/browser_window_features.h +++ b/chrome/browser/ui/browser_window/public/browser_window_features.h
@@ -82,7 +82,6 @@ class TranslateBubbleController; class UpgradeNotificationController; class WebUIBrowserSidePanelUI; -class ZoomBubbleCoordinator; #if BUILDFLAG(IS_WIN) class WindowsTaskbarIconUpdater; @@ -466,7 +465,6 @@ ImmersiveModeController* immersive_mode_controller() { return immersive_mode_controller_.get(); } - const ImmersiveModeController* immersive_mode_controller() const { return immersive_mode_controller_.get(); } @@ -600,8 +598,6 @@ std::unique_ptr<DownloadToolbarUIController> download_toolbar_ui_controller_; #endif - std::unique_ptr<ZoomBubbleCoordinator> zoom_bubble_coordinator_; - std::unique_ptr<ActorUiWindowController> actor_ui_window_controller_; std::unique_ptr<ActorBorderViewController> actor_border_view_controller_;
diff --git a/chrome/browser/ui/browser_window/test/BUILD.gn b/chrome/browser/ui/browser_window/test/BUILD.gn index a3f56ec..9596d379d 100644 --- a/chrome/browser/ui/browser_window/test/BUILD.gn +++ b/chrome/browser/ui/browser_window/test/BUILD.gn
@@ -22,6 +22,8 @@ "//chrome/browser/ui/browser_window/internal:java", "//chrome/browser/ui/browser_window/public/android:java", "//chrome/browser/util:java", + "//third_party/androidx:androidx_annotation_annotation_java", + "//third_party/androidx:androidx_core_core_java", "//third_party/mockito:mockito_java", "//ui/android:ui_no_recycler_view_java", "//ui/base/mojom:ui_base_types_java",
diff --git a/chrome/browser/ui/browser_window/test/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskUnitTestSupport.java b/chrome/browser/ui/browser_window/test/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskUnitTestSupport.java index 15b0f8c..934c5a30 100644 --- a/chrome/browser/ui/browser_window/test/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskUnitTestSupport.java +++ b/chrome/browser/ui/browser_window/test/android/java/src/org/chromium/chrome/browser/ui/browser_window/ChromeAndroidTaskUnitTestSupport.java
@@ -7,6 +7,7 @@ import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.mockingDetails; import static org.mockito.Mockito.when; import static org.mockito.Mockito.withSettings; @@ -14,8 +15,17 @@ import android.app.ActivityManager; import android.app.ActivityManager.AppTask; import android.content.Context; +import android.graphics.Insets; import android.graphics.Rect; +import android.os.Build.VERSION_CODES; +import android.view.Window; +import android.view.WindowInsets; +import android.view.WindowInsetsController; import android.view.WindowManager; +import android.view.WindowMetrics; + +import androidx.annotation.RequiresApi; +import androidx.core.view.WindowInsetsControllerCompat; import org.chromium.base.AconfigFlaggedApiDelegate; import org.chromium.build.annotations.NullMarked; @@ -40,8 +50,45 @@ public final class ChromeAndroidTaskUnitTestSupport { /** - * It's common for callers of {@link #createMockActivityWindowAndroid()} or {@link - * #createActivityWindowAndroidMocks()} to pass the resulting mocks into a {@link + * Default bounds (in pixels) intended for {@link WindowManager#getCurrentWindowMetrics()}. + * + * @see #mockDesktopWindowingMode + */ + public static final Rect DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX = new Rect(10, 20, 800, 600); + + /** + * Default bounds (in pixels) intended for {@link WindowManager#getMaximumWindowMetrics()}. + * + * @see #mockDesktopWindowingMode + */ + public static final Rect DEFAULT_FULL_SCREEN_BOUNDS_IN_PX = new Rect(0, 0, 1920, 1080); + + /** + * Default tappable {@link Insets} (in pixels) intended for max window metrics in {@link + * WindowManager}. + * + * @see #mockDesktopWindowingMode + */ + public static final Insets DEFAULT_MAX_TAPPABLE_INSETS_IN_PX = Insets.of(0, 10, 0, 20); + + /** + * Default maximized window bounds (in desktop-windowing mode) when {@link WindowManager} is + * configured using {@link #DEFAULT_FULL_SCREEN_BOUNDS_IN_PX} and {@link + * #DEFAULT_MAX_TAPPABLE_INSETS_IN_PX}. + * + * @see #mockDesktopWindowingMode + */ + public static final Rect DEFAULT_MAXIMIZED_WINDOW_BOUNDS_IN_PX = + new Rect( + 0, + DEFAULT_MAX_TAPPABLE_INSETS_IN_PX.top, + DEFAULT_FULL_SCREEN_BOUNDS_IN_PX.right, + DEFAULT_FULL_SCREEN_BOUNDS_IN_PX.bottom + - DEFAULT_MAX_TAPPABLE_INSETS_IN_PX.bottom); + + /** + * It's common for callers of {@link #createMockActivityWindowAndroid} or {@link + * #createActivityWindowAndroidMocks} to pass the resulting mocks into a {@link * ChromeAndroidTaskImpl}, which only holds it as a weak reference. Pinning the mocks here * ensures that they don't get garbage collected in the middle of a unit test. * @@ -276,4 +323,84 @@ return mockParams; } + + /** See {@link #mockDesktopWindowingMode(ActivityWindowAndroidMocks, Rect, Rect, Insets)}. */ + @RequiresApi(api = VERSION_CODES.R) + static void mockDesktopWindowingMode(ActivityWindowAndroidMocks activityWindowAndroidMocks) { + mockDesktopWindowingMode( + activityWindowAndroidMocks, + DEFAULT_CURRENT_WINDOW_BOUNDS_IN_PX, + DEFAULT_FULL_SCREEN_BOUNDS_IN_PX, + DEFAULT_MAX_TAPPABLE_INSETS_IN_PX); + } + + /** + * Configures the provided {@code ActivityWindowAndroidMocks} to meet the expectations of + * desktop windowing mode. + * + * <p>Only use this in Robolectric tests. Native unit tests run on an emulator, and Mockito will + * fail to mock "final" framework classes like {@link WindowMetrics}. + * + * @param activityWindowAndroidMocks The mocks to configure. + * @param currentWindowBoundsInPx Bounds (in pixels) intended for {@link + * WindowManager#getCurrentWindowMetrics()}. + * @param fullScreenWindowBoundsInPx Bounds (in pixels) intended for {@link + * WindowManager#getMaximumWindowMetrics()}. + * @param maxTappableInsetsInPx {@link Insets} (in pixels) intended for max window metrics in + * {@link WindowManager}. + */ + @RequiresApi(api = VERSION_CODES.R) + static void mockDesktopWindowingMode( + ActivityWindowAndroidMocks activityWindowAndroidMocks, + Rect currentWindowBoundsInPx, + Rect fullScreenWindowBoundsInPx, + Insets maxTappableInsetsInPx) { + var mockActivity = activityWindowAndroidMocks.mMockActivity; + var mockWindowManager = activityWindowAndroidMocks.mMockWindowManager; + + // Activity should be in multi-window mode. + // (Desktop windowing mode is a multi-window mode.) + when(mockActivity.isInMultiWindowMode()).thenReturn(true); + + // Config system bars behavior. + var mockWindow = mock(Window.class); + var mockWindowInsetsController = mock(WindowInsetsController.class); + when(mockWindowInsetsController.getSystemBarsBehavior()) + .thenReturn(WindowInsetsControllerCompat.BEHAVIOR_DEFAULT); + when(mockWindow.getInsetsController()).thenReturn(mockWindowInsetsController); + when(mockActivity.getWindow()).thenReturn(mockWindow); + + mockCurrentWindowMetrics(mockWindowManager, currentWindowBoundsInPx); + mockMaxWindowMetrics(mockWindowManager, fullScreenWindowBoundsInPx, maxTappableInsetsInPx); + + // Connect mock WindowManager to mock Activity. + when(mockActivity.getWindowManager()).thenReturn(mockWindowManager); + } + + @RequiresApi(api = VERSION_CODES.R) + static void mockCurrentWindowMetrics( + WindowManager mockWindowManager, Rect currentWindowBoundsInPx) { + assert mockingDetails(mockWindowManager).isMock(); + + var currentWindowMetrics = mock(WindowMetrics.class); + when(currentWindowMetrics.getBounds()).thenReturn(currentWindowBoundsInPx); + when(mockWindowManager.getCurrentWindowMetrics()).thenReturn(currentWindowMetrics); + } + + @RequiresApi(api = VERSION_CODES.R) + static void mockMaxWindowMetrics( + WindowManager mockWindowManager, + Rect fullScreenWindowBoundsInPx, + Insets maxTappableInsetsInPx) { + assert mockingDetails(mockWindowManager).isMock(); + + var maxWindowInsets = mock(WindowInsets.class); + when(maxWindowInsets.isVisible(WindowInsets.Type.statusBars())).thenReturn(true); + when(maxWindowInsets.getInsets(WindowInsets.Type.tappableElement())) + .thenReturn(maxTappableInsetsInPx); + var maxWindowMetrics = mock(WindowMetrics.class); + when(maxWindowMetrics.getBounds()).thenReturn(fullScreenWindowBoundsInPx); + when(maxWindowMetrics.getWindowInsets()).thenReturn(maxWindowInsets); + when(mockWindowManager.getMaximumWindowMetrics()).thenReturn(maxWindowMetrics); + } }
diff --git a/chrome/browser/ui/cocoa/tab_group_menu_bridge.h b/chrome/browser/ui/cocoa/tab_group_menu_bridge.h index 52552e0..8d8065f2 100644 --- a/chrome/browser/ui/cocoa/tab_group_menu_bridge.h +++ b/chrome/browser/ui/cocoa/tab_group_menu_bridge.h
@@ -12,7 +12,7 @@ #include "base/task/cancelable_task_tracker.h" #include "chrome/app/chrome_command_ids.h" #import "chrome/browser/ui/cocoa/main_menu_item.h" -#include "chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.h" #include "components/saved_tab_groups/public/tab_group_sync_service.h" using TabGroupMenuAction = tab_groups::TabGroupMenuAction;
diff --git a/chrome/browser/ui/cocoa/tab_group_menu_bridge.mm b/chrome/browser/ui/cocoa/tab_group_menu_bridge.mm index 7ead393..24e90dc45 100644 --- a/chrome/browser/ui/cocoa/tab_group_menu_bridge.mm +++ b/chrome/browser/ui/cocoa/tab_group_menu_bridge.mm
@@ -108,15 +108,24 @@ return; } + std::vector<base::Uuid> group_ids = + tab_groups::TabGroupMenuUtils::GetGroupsForDisplaySortedByCreationTime( + tab_group_service_); + if (group_ids.empty()) { + return; + } + [menu addItem:[NSMenuItem separatorItem]]; - for (const tab_groups::SavedTabGroup& group : - tab_group_service_->GetAllGroups()) { + for (const base::Uuid& uuid : group_ids) { + const std::optional<tab_groups::SavedTabGroup> group = + tab_group_service_->GetGroup(uuid); + if (!group) { + continue; + } + NSString* title = base::SysUTF16ToNSString( - group.title().empty() ? l10n_util::GetPluralStringFUTF16( - IDS_SAVED_TAB_GROUP_TABS_COUNT, - static_cast<int>(group.saved_tabs().size())) - : group.title()); + tab_groups::TabGroupMenuUtils::GetMenuTextForGroup(*group)); // Add menu item for each group. NSMenuItem* item = [[NSMenuItem alloc] initWithTitle:title @@ -125,28 +134,27 @@ // Set the icon of the group to the group color circle. const auto& color_provider = [AppController.sharedController lastActiveColorProvider]; - const ui::ColorId color_id = GetTabGroupContextMenuColorId(group.color()); + const ui::ColorId color_id = GetTabGroupContextMenuColorId(group->color()); gfx::ImageSkia group_icon = gfx::CreateVectorIcon( kTabGroupIcon, gfx::kFaviconSize, color_provider.GetColor(color_id)); item.image = NSImageFromImageSkia(group_icon); NSMenu* submenu = [[NSMenu alloc] init]; - base::Uuid uuid = group.saved_guid(); // Add static menu items for submenu. [submenu addItem:CreateStaticSubmenuItem( IDS_OPEN_GROUP_IN_BROWSER_MENU, TabGroupMenuAction::Type::OPEN_IN_BROWSER, uuid)]; [submenu addItem:CreateStaticSubmenuItem( - group.local_group_id().has_value() + group->local_group_id().has_value() ? IDS_TAB_GROUP_HEADER_CXMENU_MOVE_GROUP_TO_NEW_WINDOW : IDS_TAB_GROUP_HEADER_CXMENU_OPEN_GROUP_IN_NEW_WINDOW, TabGroupMenuAction::Type::OPEN_OR_MOVE_TO_NEW_WINDOW, uuid)]; [submenu addItem:CreateStaticSubmenuItem( - group.is_pinned() ? IDS_TAB_GROUP_HEADER_CXMENU_UNPIN_GROUP - : IDS_TAB_GROUP_HEADER_CXMENU_PIN_GROUP, + group->is_pinned() ? IDS_TAB_GROUP_HEADER_CXMENU_UNPIN_GROUP + : IDS_TAB_GROUP_HEADER_CXMENU_PIN_GROUP, TabGroupMenuAction::Type::PIN_OR_UNPIN_GROUP, uuid)]; bool is_owner = tab_groups::SavedTabGroupUtils::IsOwnerOfSharedTabGroup(profile_, uuid); @@ -159,15 +167,17 @@ [submenu addItem:[NSMenuItem separatorItem]]; // Add menu items for each tab in submenu. - for (const tab_groups::SavedTabGroupTab& tab : group.saved_tabs()) { + for (const tab_groups::SavedTabGroupTab& tab : group->saved_tabs()) { NSMenuItem* tab_menu_item = [[NSMenuItem alloc] - initWithTitle:base::SysUTF16ToNSString(tab.title()) + initWithTitle:base::SysUTF16ToNSString( + tab_groups::TabGroupMenuUtils::GetMenuTextForTab( + tab)) action:@selector(onMenuItem:) keyEquivalent:@""]; tab_menu_item.target = menu_listener_; const ui::ImageModel image = favicon::GetDefaultFaviconModel( - GetTabGroupBookmarkColorId(group.color())); + GetTabGroupBookmarkColorId(group->color())); tab_menu_item.image = NSImageFromImageSkia(image.Rasterize(&color_provider));
diff --git a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc index 9c097e28..513dc7621 100644 --- a/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc +++ b/chrome/browser/ui/startup/startup_browser_creator_browsertest.cc
@@ -2328,10 +2328,9 @@ content::RunAllTasksUntilIdle(); // Launching with an app opens the app window via a task, so the test - // might start before SelectFirstBrowser is called. + // might start before the first browser is created. if (!browser()) { - added_observer.Wait(); - SelectFirstBrowser(); + SetBrowser(added_observer.Wait()); } } ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile()));
diff --git a/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.cc b/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.cc index 48d5927..55502bdc 100644 --- a/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.cc +++ b/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.cc
@@ -31,13 +31,13 @@ } void TabSensitivityCache::OnPageContentAnnotated( - const GURL& url, + const page_content_annotations::HistoryVisit& visit, const page_content_annotations::PageContentAnnotationsResult& result) { CHECK(result.GetType() == page_content_annotations::AnnotationType::kContentVisibility); // Invert the visibility score to get a sensitivity score. - sensitivy_scores_[url] = 1.0 - result.GetContentVisibilityScore(); + sensitivy_scores_[visit.url] = 1.0 - result.GetContentVisibilityScore(); MaybeTrimCacheKeys(); }
diff --git a/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.h b/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.h index be80a56..eecc6d4 100644 --- a/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.h +++ b/chrome/browser/ui/tabs/organization/tab_sensitivity_cache.h
@@ -36,7 +36,7 @@ // ::PageContentAnnotationsService // ::PageContentAnnotationsObserver void OnPageContentAnnotated( - const GURL& url, + const page_content_annotations::HistoryVisit& visit, const page_content_annotations::PageContentAnnotationsResult& result) override;
diff --git a/chrome/browser/ui/tabs/organization/tab_sensitivity_cache_browsertest.cc b/chrome/browser/ui/tabs/organization/tab_sensitivity_cache_browsertest.cc index 5d6c0d5..6bcf05e 100644 --- a/chrome/browser/ui/tabs/organization/tab_sensitivity_cache_browsertest.cc +++ b/chrome/browser/ui/tabs/organization/tab_sensitivity_cache_browsertest.cc
@@ -11,6 +11,8 @@ #include "chrome/test/base/ui_test_utils.h" #include "content/public/test/browser_test.h" +using page_content_annotations::HistoryVisit; + class TabSensitivityCacheBrowserTest : public InProcessBrowserTest { public: TabSensitivityCacheBrowserTest() = default; @@ -57,8 +59,9 @@ const GURL url1 = embedded_test_server()->GetURL("a.com", "/title1.html"); AddTab(url1); cache()->OnPageContentAnnotated( - url1, page_content_annotations::PageContentAnnotationsResult:: - CreateContentVisibilityScoreResult(1.0f)); + HistoryVisit({}, url1), + page_content_annotations::PageContentAnnotationsResult:: + CreateContentVisibilityScoreResult(1.0f)); EXPECT_EQ(cache()->GetScore(url1), 0.0f); } @@ -75,29 +78,34 @@ content::WebContents* const tab2 = AddTab(url2); AddTab(url3); cache()->OnPageContentAnnotated( - url1, page_content_annotations::PageContentAnnotationsResult:: - CreateContentVisibilityScoreResult(1.0f)); + HistoryVisit({}, url1), + page_content_annotations::PageContentAnnotationsResult:: + CreateContentVisibilityScoreResult(1.0f)); cache()->OnPageContentAnnotated( - url2, page_content_annotations::PageContentAnnotationsResult:: - CreateContentVisibilityScoreResult(1.0f)); + HistoryVisit({}, url2), + page_content_annotations::PageContentAnnotationsResult:: + CreateContentVisibilityScoreResult(1.0f)); cache()->OnPageContentAnnotated( - url3, page_content_annotations::PageContentAnnotationsResult:: - CreateContentVisibilityScoreResult(1.0f)); + HistoryVisit({}, url3), + page_content_annotations::PageContentAnnotationsResult:: + CreateContentVisibilityScoreResult(1.0f)); RemoveTab(initial_tab); ASSERT_EQ(cache()->GetScore(url1), 0.0f); // Remove one tab. The cache does not trim yet as it would not shrink by 1/2. RemoveTab(tab1); cache()->OnPageContentAnnotated( - url3, page_content_annotations::PageContentAnnotationsResult:: - CreateContentVisibilityScoreResult(1.0f)); + HistoryVisit({}, url3), + page_content_annotations::PageContentAnnotationsResult:: + CreateContentVisibilityScoreResult(1.0f)); EXPECT_EQ(cache()->GetScore(url1), 0.0f); // Remove one more tab. The cache trims now as it can shrink by at least 1/2. RemoveTab(tab2); cache()->OnPageContentAnnotated( - url3, page_content_annotations::PageContentAnnotationsResult:: - CreateContentVisibilityScoreResult(1.0f)); + HistoryVisit({}, url3), + page_content_annotations::PageContentAnnotationsResult:: + CreateContentVisibilityScoreResult(1.0f)); EXPECT_EQ(cache()->GetScore(url1), std::nullopt); }
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/BUILD.gn b/chrome/browser/ui/tabs/saved_tab_groups/BUILD.gn index ac768aa..65445154 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/BUILD.gn +++ b/chrome/browser/ui/tabs/saved_tab_groups/BUILD.gn
@@ -24,7 +24,7 @@ "session_service_tab_group_sync_observer.h", "shared_tab_group_feedback_controller.h", "tab_group_action_context_desktop.h", - "tab_group_menu_action.h", + "tab_group_menu_utils.h", "tab_group_sync_delegate_desktop.h", ] public_deps = [ @@ -78,7 +78,7 @@ "session_service_tab_group_sync_observer.cc", "shared_tab_group_feedback_controller.cc", "tab_group_action_context_desktop.cc", - "tab_group_menu_action.cc", + "tab_group_menu_utils.cc", "tab_group_sync_delegate_desktop.cc", ] deps = [ @@ -159,6 +159,7 @@ "collaboration_messaging_page_action_controller_unittest.cc", "collaboration_messaging_tab_data_unittest.cc", "instant_message_queue_processor_unittest.cc", + "tab_group_menu_utils_unittest.cc", ] deps = [ ":saved_tab_groups",
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h index 6f4aa14..79ba7f8 100644 --- a/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h +++ b/chrome/browser/ui/tabs/saved_tab_groups/saved_tab_group_utils.h
@@ -10,7 +10,7 @@ #include "base/containers/span.h" #include "base/uuid.h" -#include "chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.h" #include "chrome/browser/ui/tabs/tab_group_deletion_dialog_controller.h" #include "components/data_sharing/public/group_data.h" #include "components/saved_tab_groups/public/saved_tab_group.h"
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.cc b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.cc deleted file mode 100644 index e0ddfdf0..0000000 --- a/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.cc +++ /dev/null
@@ -1,16 +0,0 @@ -// 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/ui/tabs/saved_tab_groups/tab_group_menu_action.h" - -namespace tab_groups { - -TabGroupMenuAction::TabGroupMenuAction(Type type, - std::variant<base::Uuid, GURL> element) - : type(type), element(element) {} -TabGroupMenuAction::TabGroupMenuAction(const TabGroupMenuAction& action) = - default; -TabGroupMenuAction::~TabGroupMenuAction() = default; - -} // namespace tab_groups
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.h b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.h deleted file mode 100644 index d1093b7..0000000 --- a/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.h +++ /dev/null
@@ -1,40 +0,0 @@ -// Copyright 2025 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_TAB_GROUP_MENU_ACTION_H_ -#define CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_TAB_GROUP_MENU_ACTION_H_ - -#include <variant> - -#include "base/uuid.h" -#include "url/gurl.h" - -namespace tab_groups { - -// The action users can perform on a saved tab group's submenu. -struct TabGroupMenuAction { - enum class Type { - DEFAULT = -1, - OPEN_IN_BROWSER, - OPEN_OR_MOVE_TO_NEW_WINDOW, - PIN_OR_UNPIN_GROUP, - DELETE_GROUP, - LEAVE_GROUP, - OPEN_URL, - }; - - TabGroupMenuAction(Type type, std::variant<base::Uuid, GURL> element); - TabGroupMenuAction(const TabGroupMenuAction&); - ~TabGroupMenuAction(); - - Type type = Type::DEFAULT; - - // The action needs either a UUID (e.g. Open group in new window) or a URL - // (e.g. Open tab) to perform. - std::variant<base::Uuid, GURL> element; -}; - -} // namespace tab_groups - -#endif // CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_TAB_GROUP_MENU_ACTION_H_
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.cc b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.cc new file mode 100644 index 0000000..d5758d6 --- /dev/null +++ b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.cc
@@ -0,0 +1,62 @@ +// 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/ui/tabs/saved_tab_groups/tab_group_menu_utils.h" + +#include "base/strings/utf_string_conversions.h" +#include "chrome/grit/generated_resources.h" +#include "ui/base/l10n/l10n_util.h" + +namespace tab_groups { + +TabGroupMenuAction::TabGroupMenuAction(Type type, + std::variant<base::Uuid, GURL> element) + : type(type), element(element) {} +TabGroupMenuAction::TabGroupMenuAction(const TabGroupMenuAction& action) = + default; +TabGroupMenuAction::~TabGroupMenuAction() = default; + +std::u16string TabGroupMenuUtils::GetMenuTextForGroup( + const tab_groups::SavedTabGroup& group) { + return group.title().empty() + ? l10n_util::GetPluralStringFUTF16( + IDS_SAVED_TAB_GROUP_TABS_COUNT, + static_cast<int>(group.saved_tabs().size())) + : group.title(); +} + +std::u16string TabGroupMenuUtils::GetMenuTextForTab( + const tab_groups::SavedTabGroupTab& tab) { + return tab.title().empty() ? base::UTF8ToUTF16(tab.url().spec()) + : tab.title(); +} + +std::vector<base::Uuid> +TabGroupMenuUtils::GetGroupsForDisplaySortedByCreationTime( + TabGroupSyncService* tab_group_service) { + CHECK(tab_group_service); + std::vector<const SavedTabGroup*> groups; + + std::vector<SavedTabGroup> all_groups = tab_group_service->GetAllGroups(); + for (const SavedTabGroup& group : all_groups) { + if (group.saved_tabs().empty()) { + continue; + } + groups.push_back(&group); + } + + std::sort(groups.begin(), groups.end(), + [](const SavedTabGroup* a, const SavedTabGroup* b) { + return a->creation_time() > b->creation_time(); + }); + + std::vector<base::Uuid> sorted_guids; + for (const SavedTabGroup* group : groups) { + sorted_guids.push_back(group->saved_guid()); + } + + return sorted_guids; +} + +} // namespace tab_groups
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.h b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.h new file mode 100644 index 0000000..10f2ef6 --- /dev/null +++ b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.h
@@ -0,0 +1,57 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_TAB_GROUP_MENU_UTILS_H_ +#define CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_TAB_GROUP_MENU_UTILS_H_ + +#include <variant> + +#include "base/uuid.h" +#include "components/saved_tab_groups/public/saved_tab_group.h" +#include "components/saved_tab_groups/public/saved_tab_group_tab.h" +#include "components/saved_tab_groups/public/tab_group_sync_service.h" +#include "url/gurl.h" + +namespace tab_groups { + +// The action users can perform on a saved tab group's submenu. +struct TabGroupMenuAction { + enum class Type { + DEFAULT = -1, + OPEN_IN_BROWSER, + OPEN_OR_MOVE_TO_NEW_WINDOW, + PIN_OR_UNPIN_GROUP, + DELETE_GROUP, + LEAVE_GROUP, + OPEN_URL, + }; + + TabGroupMenuAction(Type type, std::variant<base::Uuid, GURL> element); + TabGroupMenuAction(const TabGroupMenuAction&); + ~TabGroupMenuAction(); + + Type type = Type::DEFAULT; + + // The action needs either a UUID (e.g. Open group in new window) or a URL + // (e.g. Open tab) to perform. + std::variant<base::Uuid, GURL> element; +}; + +class TabGroupMenuUtils { + public: + static std::u16string GetMenuTextForGroup( + const tab_groups::SavedTabGroup& group); + + static std::u16string GetMenuTextForTab( + const tab_groups::SavedTabGroupTab& tab); + + // Returns sorted saved tab groups with the most recently created as the + // first, filtering out empty groups. + static std::vector<base::Uuid> GetGroupsForDisplaySortedByCreationTime( + TabGroupSyncService* wrapper_service); +}; + +} // namespace tab_groups + +#endif // CHROME_BROWSER_UI_TABS_SAVED_TAB_GROUPS_TAB_GROUP_MENU_UTILS_H_
diff --git a/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils_unittest.cc b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils_unittest.cc new file mode 100644 index 0000000..57c329a1 --- /dev/null +++ b/chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils_unittest.cc
@@ -0,0 +1,100 @@ +// 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/ui/tabs/saved_tab_groups/tab_group_menu_utils.h" + +#include "base/strings/utf_string_conversions.h" +#include "base/time/time.h" +#include "chrome/grit/generated_resources.h" +#include "components/saved_tab_groups/public/saved_tab_group.h" +#include "components/saved_tab_groups/public/saved_tab_group_tab.h" +#include "components/saved_tab_groups/public/tab_group_sync_service.h" +#include "components/saved_tab_groups/test_support/fake_tab_group_sync_service.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/base/l10n/l10n_util.h" +#include "url/gurl.h" + +namespace tab_groups { + +class TabGroupMenuUtilsTest : public testing::Test { + public: + TabGroupMenuUtilsTest() = default; + ~TabGroupMenuUtilsTest() override = default; + + protected: + const std::u16string kGroupTitle1 = u"Group 1"; + const std::u16string kTabTitle1 = u"Tab 1"; + const GURL kTabUrl1{"https://www.google.com/"}; +}; + +TEST_F(TabGroupMenuUtilsTest, GetMenuTextForGroup) { + SavedTabGroup group_with_title(kGroupTitle1, + tab_groups::TabGroupColorId::kGrey, {}); + EXPECT_EQ(kGroupTitle1, + TabGroupMenuUtils::GetMenuTextForGroup(group_with_title)); + + SavedTabGroup group_without_title(std::u16string(), + tab_groups::TabGroupColorId::kGrey, {}); + SavedTabGroupTab tab(kTabUrl1, kTabTitle1, group_without_title.saved_guid(), + /*position=*/0); + group_without_title.AddTabLocally(tab); + EXPECT_EQ(l10n_util::GetPluralStringFUTF16( + IDS_SAVED_TAB_GROUP_TABS_COUNT, + static_cast<int>(group_without_title.saved_tabs().size())), + TabGroupMenuUtils::GetMenuTextForGroup(group_without_title)); +} + +TEST_F(TabGroupMenuUtilsTest, GetMenuTextForTab) { + SavedTabGroupTab tab_with_title(kTabUrl1, kTabTitle1, {}, /*position=*/0); + EXPECT_EQ(kTabTitle1, TabGroupMenuUtils::GetMenuTextForTab(tab_with_title)); + + SavedTabGroupTab tab_without_title(kTabUrl1, std::u16string(), {}, + /*position=*/0); + EXPECT_EQ(base::UTF8ToUTF16(kTabUrl1.spec()), + TabGroupMenuUtils::GetMenuTextForTab(tab_without_title)); +} + +TEST_F(TabGroupMenuUtilsTest, GetGroupsForDisplaySortedByCreationTime) { + FakeTabGroupSyncService service; + + SavedTabGroup group1(u"Group 1", tab_groups::TabGroupColorId::kGrey, {}, + std::nullopt, std::nullopt, std::nullopt, std::nullopt, + std::nullopt, false, base::Time::Now()); + SavedTabGroupTab tab1(GURL("https://www.one.com/"), u"Tab 1", + group1.saved_guid(), 0); + group1.AddTabLocally(tab1); + service.AddGroup(group1); + + SavedTabGroup group2(u"Group 2", tab_groups::TabGroupColorId::kBlue, {}, + std::nullopt, std::nullopt, std::nullopt, std::nullopt, + std::nullopt, false, base::Time::Now() - base::Days(1)); + SavedTabGroupTab tab2(GURL("https://www.two.com/"), u"Tab 2", + group2.saved_guid(), 0); + group2.AddTabLocally(tab2); + service.AddGroup(group2); + + SavedTabGroup group3(u"Group 3", tab_groups::TabGroupColorId::kRed, {}, + std::nullopt, std::nullopt, std::nullopt, std::nullopt, + std::nullopt, false, base::Time::Now() + base::Days(1)); + SavedTabGroupTab tab3(GURL("https://www.three.com/"), u"Tab 3", + group3.saved_guid(), 0); + group3.AddTabLocally(tab3); + service.AddGroup(group3); + + SavedTabGroup empty_group(u"Empty Group", tab_groups::TabGroupColorId::kGreen, + {}, std::nullopt, std::nullopt, std::nullopt, + std::nullopt, std::nullopt, false, + base::Time::Now()); + service.AddGroup(empty_group); + + std::vector<base::Uuid> sorted_guids = + TabGroupMenuUtils::GetGroupsForDisplaySortedByCreationTime(&service); + + ASSERT_EQ(3u, sorted_guids.size()); + EXPECT_EQ(group3.saved_guid(), sorted_guids[0]); + EXPECT_EQ(group1.saved_guid(), sorted_guids[1]); + EXPECT_EQ(group2.saved_guid(), sorted_guids[2]); +} + +} // namespace tab_groups
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc index a8a0231d..3a4a6054 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.cc
@@ -124,37 +124,7 @@ return sorted_non_empty_tab_groups_.at(idx_in_sorted_tab_group); } -std::vector<base::Uuid> -STGEverythingMenu::GetGroupsForDisplaySortedByCreationTime( - TabGroupSyncService* tab_group_service) { - CHECK(tab_group_service); - std::vector<base::Uuid> sorted_tab_groups; - for (const SavedTabGroup& group : tab_group_service->GetAllGroups()) { - if (group.saved_tabs().empty()) { - continue; - } - sorted_tab_groups.push_back(group.saved_guid()); - } - auto compare_by_creation_time = [=](const base::Uuid& a, - const base::Uuid& b) { - const std::optional<SavedTabGroup> saved_tab_group_a = - tab_group_service->GetGroup(a); - const std::optional<SavedTabGroup> saved_tab_group_b = - tab_group_service->GetGroup(b); - - // If either gets deleted while creating the model, ignore the order. - if (!saved_tab_group_a.has_value() || !saved_tab_group_b.has_value()) { - return false; - } - - return saved_tab_group_a->creation_time() > - saved_tab_group_b->creation_time(); - }; - std::sort(sorted_tab_groups.begin(), sorted_tab_groups.end(), - compare_by_creation_time); - return sorted_tab_groups; -} std::unique_ptr<ui::SimpleMenuModel> STGEverythingMenu::CreateMenuModel( TabGroupSyncService* tab_group_service) { @@ -173,7 +143,8 @@ } sorted_non_empty_tab_groups_ = - GetGroupsForDisplaySortedByCreationTime(tab_group_service); + TabGroupMenuUtils::GetGroupsForDisplaySortedByCreationTime( + tab_group_service); const auto* const color_provider = browser_->window()->GetColorProvider(); for (size_t i = 0; i < sorted_non_empty_tab_groups_.size(); ++i) { @@ -186,12 +157,7 @@ const auto color_id = GetTabGroupDialogColorId(tab_group->color()); const auto group_icon = ui::ImageModel::FromVectorIcon( kTabGroupIcon, color_provider->GetColor(color_id), gfx::kFaviconSize); - auto title = tab_group->title(); - if (title.empty()) { - title = l10n_util::GetPluralStringFUTF16( - IDS_SAVED_TAB_GROUP_TABS_COUNT, - static_cast<int>(tab_group->saved_tabs().size())); - } + auto title = tab_groups::TabGroupMenuUtils::GetMenuTextForGroup(*tab_group); // For saved tab group items, use the indice in `sorted_tab_groups_` as the // command ids. const int command_id = GenerateTabGroupCommandID(i);
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h index 811245e..461ca1498 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_everything_menu.h
@@ -86,11 +86,6 @@ std::unique_ptr<ui::SimpleMenuModel> CreateMenuModel( TabGroupSyncService* tab_group_service); - // Returns sorted saved tab groups with the most recently created as the - // first, filtering out empty groups. - std::vector<base::Uuid> GetGroupsForDisplaySortedByCreationTime( - TabGroupSyncService* wrapper_service); - // Because all the menu items (i.e. tab group items in the Everything menu - // primary menu and their submenus - secondary menu) need to be recognized and // invoked from the 3-dot menu so they follow the same pattern to get their
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.cc b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.cc index 3af57a2..0dfafa3 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.cc +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.cc
@@ -155,8 +155,7 @@ for (size_t i = 0; i < tabs.size(); ++i) { const auto& tab = tabs.at(i); const std::u16string title = - tab.title().empty() ? base::UTF8ToUTF16(tab.url().spec()) : tab.title(); - + tab_groups::TabGroupMenuUtils::GetMenuTextForTab(tab); latest_command_id = get_next_command_id.Run(); const ui::ImageModel image = favicon::GetDefaultFaviconModel( GetTabGroupBookmarkColorId(saved_group.color()));
diff --git a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.h b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.h index e98685b..9cace16c 100644 --- a/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.h +++ b/chrome/browser/ui/views/bookmarks/saved_tab_groups/saved_tab_group_tabs_menu_model.h
@@ -13,7 +13,7 @@ #include "base/memory/weak_ptr.h" #include "base/task/cancelable_task_tracker.h" #include "base/uuid.h" -#include "chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_action.h" +#include "chrome/browser/ui/tabs/saved_tab_groups/tab_group_menu_utils.h" #include "components/saved_tab_groups/public/saved_tab_group.h" #include "ui/base/interaction/element_identifier.h" #include "ui/menus/simple_menu_model.h"
diff --git a/chrome/browser/ui/views/frame/browser_frame_view_chromeos_browsertest.cc b/chrome/browser/ui/views/frame/browser_frame_view_chromeos_browsertest.cc index f4a3123..d65b314 100644 --- a/chrome/browser/ui/views/frame/browser_frame_view_chromeos_browsertest.cc +++ b/chrome/browser/ui/views/frame/browser_frame_view_chromeos_browsertest.cc
@@ -50,8 +50,6 @@ #include "chrome/browser/ui/browser_navigator.h" #include "chrome/browser/ui/browser_navigator_params.h" #include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/browser/ui/page_action/page_action_icon_type.h" #include "chrome/browser/ui/passwords/passwords_client_ui_delegate.h" @@ -69,7 +67,6 @@ #include "chrome/browser/ui/views/location_bar/content_setting_image_view.h" #include "chrome/browser/ui/views/location_bar/custom_tab_bar_view.h" #include "chrome/browser/ui/views/location_bar/icon_label_bubble_view.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/page_action/page_action_view.h" @@ -731,16 +728,13 @@ zoom::ZoomController::FromWebContents(web_contents); IconLabelBubbleView* zoom_icon = GetPageActionView(kActionZoomNormal); - ZoomBubbleCoordinator* zoom_bubble_coordinator = - ZoomBubbleCoordinator::From(app_browser_); - EXPECT_TRUE(zoom_icon); EXPECT_FALSE(zoom_icon->GetVisible()); - EXPECT_FALSE(zoom_bubble_coordinator->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); zoom_controller->SetZoomLevel(blink::ZoomFactorToZoomLevel(1.5)); ASSERT_TRUE(WaitForVisible(true, zoom_icon)); - EXPECT_TRUE(zoom_bubble_coordinator->bubble()); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); } IN_PROC_BROWSER_TEST_P(WebAppFrameViewChromeOSTest, ShowFindIcon) {
diff --git a/chrome/browser/ui/views/frame/browser_view.cc b/chrome/browser/ui/views/frame/browser_view.cc index afcbe82..e1bba69 100644 --- a/chrome/browser/ui/views/frame/browser_view.cc +++ b/chrome/browser/ui/views/frame/browser_view.cc
@@ -134,6 +134,7 @@ #include "chrome/browser/ui/views/frame/contents_rounded_corner.h" #include "chrome/browser/ui/views/frame/contents_separator.h" #include "chrome/browser/ui/views/frame/main_container_view.h" +#include "chrome/browser/ui/views/frame/main_region_view.h" #include "chrome/browser/ui/views/frame/multi_contents_view.h" #include "chrome/browser/ui/views/frame/multi_contents_view_delegate.h" #include "chrome/browser/ui/views/frame/multi_contents_view_drop_target_controller.h" @@ -792,7 +793,7 @@ browser_->tab_strip_model()->AddObserver(this); - main_region_ = AddChildView(std::make_unique<views::View>()); + main_region_ = AddChildView(std::make_unique<MainRegionView>()); main_container_ = main_region_->AddChildView(std::make_unique<MainContainerView>());
diff --git a/chrome/browser/ui/views/frame/main_container_view.h b/chrome/browser/ui/views/frame/main_container_view.h index a1daffa..e91c3e2 100644 --- a/chrome/browser/ui/views/frame/main_container_view.h +++ b/chrome/browser/ui/views/frame/main_container_view.h
@@ -7,6 +7,16 @@ #include "ui/views/view.h" +// This view is responsible for holding the primary elements of the Browser UI +// other than the tab strip: +// - TopContainerView +// - ToolbarView +// - BookmarksBarView +// - ContentsSeparator +// - TopContainerLoadingBar +// - InfobarContainerView +// - ContentContainer +// - SidePanel class MainContainerView : public views::View { METADATA_HEADER(MainContainerView, views::View)
diff --git a/chrome/browser/ui/views/frame/main_region_view.cc b/chrome/browser/ui/views/frame/main_region_view.cc new file mode 100644 index 0000000..eece6aa --- /dev/null +++ b/chrome/browser/ui/views/frame/main_region_view.cc
@@ -0,0 +1,13 @@ +// 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/ui/views/frame/main_region_view.h" + +#include "ui/base/metadata/metadata_impl_macros.h" + +MainRegionView::MainRegionView() = default; +MainRegionView::~MainRegionView() = default; + +BEGIN_METADATA(MainRegionView) +END_METADATA
diff --git a/chrome/browser/ui/views/frame/main_region_view.h b/chrome/browser/ui/views/frame/main_region_view.h new file mode 100644 index 0000000..1c0e682 --- /dev/null +++ b/chrome/browser/ui/views/frame/main_region_view.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 CHROME_BROWSER_UI_VIEWS_FRAME_MAIN_REGION_VIEW_H_ +#define CHROME_BROWSER_UI_VIEWS_FRAME_MAIN_REGION_VIEW_H_ + +#include "ui/views/view.h" + +// This wrapper view primarily serves to hold the MainContainer and +// ToolbarHeightSidePanel. +class MainRegionView : public views::View { + METADATA_HEADER(MainRegionView, views::View) + + public: + MainRegionView(); + MainRegionView(const MainRegionView&) = delete; + MainRegionView& operator=(const MainRegionView&) = delete; + ~MainRegionView() override; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_FRAME_MAIN_REGION_VIEW_H_
diff --git a/chrome/browser/ui/views/frame/multi_contents_view_delegate.cc b/chrome/browser/ui/views/frame/multi_contents_view_delegate.cc index 9f72cc7..d0f4cc9 100644 --- a/chrome/browser/ui/views/frame/multi_contents_view_delegate.cc +++ b/chrome/browser/ui/views/frame/multi_contents_view_delegate.cc
@@ -126,9 +126,12 @@ const int new_tab_idx = tab_strip_model_->active_index() + (side == MultiContentsDropTargetView::DropSide::START ? 0 : 1); + + tabs::TabInterface* active_tab = tab_strip_model_->GetActiveTab(); const int inserted_tab_idx = tab_strip_model_->InsertDetachedTabAt( - new_tab_idx, std::move(detached_tab), AddTabTypes::ADD_NONE, - std::nullopt); + new_tab_idx, std::move(detached_tab), + active_tab->IsPinned() ? AddTabTypes::ADD_PINNED : AddTabTypes::ADD_NONE, + active_tab->GetGroup()); tab_strip_model_->AddToNewSplit( {inserted_tab_idx}, split_data, split_tabs::SplitTabCreatedSource::kDragAndDropTab);
diff --git a/chrome/browser/ui/views/location_bar/BUILD.gn b/chrome/browser/ui/views/location_bar/BUILD.gn index be015a9..eee4d9a 100644 --- a/chrome/browser/ui/views/location_bar/BUILD.gn +++ b/chrome/browser/ui/views/location_bar/BUILD.gn
@@ -29,7 +29,6 @@ "omnibox_chip_theme.h", "selected_keyword_view.h", "star_view.h", - "zoom_bubble_coordinator.h", "zoom_bubble_view.h", ] @@ -84,7 +83,6 @@ "omnibox_chip_button.cc", "selected_keyword_view.cc", "star_view.cc", - "zoom_bubble_coordinator.cc", "zoom_bubble_view.cc", ]
diff --git a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc index 6191344..eca44e2 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view_browsertest.cc
@@ -9,7 +9,6 @@ #include "base/feature_list.h" #include "base/files/file_path.h" #include "base/functional/bind.h" -#include "base/memory/raw_ptr.h" #include "base/path_service.h" #include "base/run_loop.h" #include "base/strings/string_util.h" @@ -21,14 +20,11 @@ #include "chrome/browser/ui/actions/chrome_action_id.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/page_action/page_action_icon_type.h" #include "chrome/browser/ui/tabs/public/tab_features.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" #include "chrome/browser/ui/views/page_action/page_action_container_view.h" @@ -78,20 +74,13 @@ } // namespace class LocationBarViewBrowserTest : public InProcessBrowserTest { - protected: + public: LocationBarViewBrowserTest() = default; LocationBarViewBrowserTest(const LocationBarViewBrowserTest&) = delete; LocationBarViewBrowserTest& operator=(const LocationBarViewBrowserTest&) = delete; - void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - zoom_bubble_coordinator_ = ZoomBubbleCoordinator::From(browser()); - } - - void TearDownOnMainThread() override { zoom_bubble_coordinator_ = nullptr; } - LocationBarView* GetLocationBarView() { BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser()); @@ -113,8 +102,6 @@ location_bar_view->GetContentSettingViewsForTest(), image_type, &ContentSettingImageView::GetType); } - - raw_ptr<ZoomBubbleCoordinator> zoom_bubble_coordinator_; }; // Ensure the location bar decoration is added when zooming, and is removed when @@ -128,38 +115,38 @@ ASSERT_TRUE(zoom_view); EXPECT_FALSE(zoom_view->GetVisible()); - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); // Altering zoom should display a bubble. Note ZoomBubbleView closes // asynchronously, so precede checks with a run loop flush. zoom_controller->SetZoomLevel(blink::ZoomFactorToZoomLevel(1.5)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(zoom_view->GetVisible()); - EXPECT_TRUE(zoom_bubble_coordinator_->bubble()); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); // Close the bubble at other than 100% zoom. Icon should remain visible. - zoom_bubble_coordinator_->Hide(); + ZoomBubbleView::CloseCurrentBubble(); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(zoom_view->GetVisible()); - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); // Show the bubble again. zoom_controller->SetZoomLevel(blink::ZoomFactorToZoomLevel(2.0)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(zoom_view->GetVisible()); - EXPECT_TRUE(zoom_bubble_coordinator_->bubble()); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); // Remains visible at 100% until the bubble is closed. zoom_controller->SetZoomLevel(blink::ZoomFactorToZoomLevel(1.0)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(zoom_view->GetVisible()); - EXPECT_TRUE(zoom_bubble_coordinator_->bubble()); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); // Closing at 100% hides the icon. - zoom_bubble_coordinator_->Hide(); + ZoomBubbleView::CloseCurrentBubble(); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(zoom_view->GetVisible()); - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); } // Ensure that location bar bubbles close when the webcontents hides. @@ -176,13 +163,13 @@ zoom_controller->SetZoomLevel(blink::ZoomFactorToZoomLevel(1.5)); base::RunLoop().RunUntilIdle(); EXPECT_TRUE(zoom_view->GetVisible()); - EXPECT_TRUE(zoom_bubble_coordinator_->bubble()); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); chrome::NewTab(browser()); chrome::SelectNextTab(browser()); base::RunLoop().RunUntilIdle(); - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); } // Check that the script blocked icon shows up when user disables javascript.
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.cc deleted file mode 100644 index 4154ca92..0000000 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.cc +++ /dev/null
@@ -1,251 +0,0 @@ -// 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/ui/views/location_bar/zoom_bubble_coordinator.h" - -#include <string> - -#include "base/check.h" -#include "base/types/to_address.h" -#include "chrome/browser/ui/actions/chrome_action_id.h" -#include "chrome/browser/ui/browser_actions.h" -#include "chrome/browser/ui/tabs/public/tab_features.h" -#include "chrome/browser/ui/views/frame/browser_view.h" -#include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" -#include "chrome/browser/ui/views/page_action/page_action_view.h" -#include "chrome/browser/ui/views/zoom/zoom_view_controller.h" -#include "components/zoom/zoom_controller.h" -#include "extensions/browser/extension_zoom_request_client.h" -#include "extensions/common/extension.h" -#include "ui/views/bubble/bubble_dialog_delegate_view.h" -#include "ui/views/controls/button/button.h" -#include "ui/views/widget/widget.h" - -#if BUILDFLAG(IS_MAC) -#include "chrome/browser/ui/fullscreen_util_mac.h" -#endif - -namespace { - -// Retrieves the anchor view for the zoom bubble. -views::View* GetAnchorView(BrowserView* browser_view) { - CHECK(browser_view); - -#if BUILDFLAG(IS_MAC) - if (fullscreen_utils::IsInContentFullscreen(browser_view->browser())) { - return nullptr; - } -#endif - - if (!browser_view->GetWidget()->IsFullscreen() || - browser_view->IsToolbarVisible() || - browser_view->immersive_mode_controller()->IsRevealed()) { - return browser_view->toolbar_button_provider()->GetAnchorView( - kActionZoomNormal); - } - return nullptr; -} - -// Find the extension that initiated the zoom change, if any. -const extensions::ExtensionZoomRequestClient* GetExtensionZoomRequestClient( - const content::WebContents* web_contents) { - auto* zoom_controller = - web_contents ? zoom::ZoomController::FromWebContents(web_contents) - : nullptr; - return zoom_controller - ? static_cast<const extensions::ExtensionZoomRequestClient*>( - zoom_controller->last_client()) - : nullptr; -} - -void UpdateBubbleVisibilityState(Browser* browser, bool is_bubble_visible) { - if (!browser) { - return; - } - - auto* action_item = actions::ActionManager::Get().FindAction( - kActionZoomNormal, browser->browser_actions()->root_action_item()); - CHECK(action_item); - action_item->SetIsShowingBubble(is_bubble_visible); -} - -} // namespace - -DEFINE_USER_DATA(ZoomBubbleCoordinator); - -ZoomBubbleCoordinator::ZoomBubbleCoordinator(BrowserView& browser_view) - : scoped_unowned_user_data_( - browser_view.browser()->GetUnownedUserDataHost(), - *this), - browser_view_(browser_view) { - immersive_mode_observation_.Observe( - browser_view_->immersive_mode_controller()); -} - -ZoomBubbleCoordinator::~ZoomBubbleCoordinator() { - Hide(); -} - -// static -ZoomBubbleCoordinator* ZoomBubbleCoordinator::From( - BrowserWindowInterface* browser) { - return browser ? Get(browser->GetUnownedUserDataHost()) : nullptr; -} - -void ZoomBubbleCoordinator::OnWidgetVisibilityChanged(views::Widget* widget, - bool visible) { - CHECK(widget_observation_.IsObservingSource(widget)); - UpdateZoomBubbleStateAndIconVisibility( - /*is_bubble_visible=*/visible); -} - -void ZoomBubbleCoordinator::OnWidgetDestroying(views::Widget* widget) { - CHECK(widget_observation_.IsObservingSource(widget)); - widget_observation_.Reset(); -} - -void ZoomBubbleCoordinator::Show( - content::WebContents* contents, - LocationBarBubbleDelegateView::DisplayReason reason) { - if (!browser_view_->browser()->GetActiveTabInterface()) { - return; - } - - if (RefreshIfShowing(contents)) { - return; - } - - Hide(); - - if (widget_observation_.IsObserving()) { - // Closing the widget is async, but IsClosed() will return true as soon as - // the Close() method has been invoked. - CHECK(widget_observation_.GetSource()->IsClosed()); - widget_observation_.Reset(); - } - - auto* anchor_view = GetAnchorView(base::to_address(browser_view_)); - auto bubble_view = std::make_unique<ZoomBubbleView>( - browser_view_->browser(), anchor_view, contents, reason); - - if (const auto* client = GetExtensionZoomRequestClient(contents)) { - bubble_view->SetExtensionInfo(client->extension()); - } - - views::Button* button = - browser_view_->toolbar_button_provider()->GetPageActionView( - kActionZoomNormal); - bubble_view->SetHighlightedButton(button); - - // If we don't anchor to anything the BrowserView is our parent. This happens - // in fullscreen cases. - bubble_view->set_parent_window( - bubble_view->anchor_widget() - ? gfx::NativeView() - : browser_view_->GetWidget()->GetNativeView()); - - ZoomBubbleView* bubble_raw = bubble_view.get(); - - auto* widget = - views::BubbleDialogDelegate::CreateBubble(std::move(bubble_view)); - - widget_observation_.Observe(widget); - - if (!anchor_view && browser_view_->browser()->window()->IsFullscreen()) { - bubble_raw->AdjustForFullscreen( - browser_view_->browser()->window()->GetBounds()); - } - - // Do not announce hotkey for refocusing inactive Zoom bubble as it - // disappears after a short timeout. - bubble_raw->ShowForReason(reason, /*allow_refocus_alert=*/false); -} - -void ZoomBubbleCoordinator::OnImmersiveRevealStarted() { - Hide(); -} - -void ZoomBubbleCoordinator::OnImmersiveModeControllerDestroyed() { - immersive_mode_observation_.Reset(); -} - -void ZoomBubbleCoordinator::Hide() { - if (!IsShowing()) { - return; - } - - widget_observation_.GetSource()->Close(); -} - -bool ZoomBubbleCoordinator::RefreshIfShowing(content::WebContents* contents) { - if (!CanRefresh(bubble(), contents)) { - return false; - } - - CHECK(bubble()); - bubble()->Refresh(); - return true; -} - -ZoomBubbleView* ZoomBubbleCoordinator::bubble() { - if (!IsShowing()) { - return nullptr; - } - - return static_cast<ZoomBubbleView*>( - widget_observation_.GetSource()->GetClientContentsView()); -} - -bool ZoomBubbleCoordinator::CanRefresh(ZoomBubbleView* current_bubble, - content::WebContents* web_contents) { - // Can't refresh when there's not already a bubble for this tab. - if (!current_bubble || (current_bubble->web_contents() != web_contents)) { - return false; - } - - // If the anchor view has changed, we must create a new bubble. - if (current_bubble->GetAnchorView() != - GetAnchorView(base::to_address(browser_view_))) { - return false; - } - - const extensions::ExtensionZoomRequestClient* client = - GetExtensionZoomRequestClient(web_contents); - - // Allow refreshes when the client won't create its own bubble. - if (client && client->ShouldSuppressBubble()) { - return true; - } - - // Allow refreshes only when the bubble has the same attribution. - const std::string current_extension_id = - client ? client->extension()->id() : std::string(); - return current_bubble->extension_id() == current_extension_id; -} - -void ZoomBubbleCoordinator::UpdateZoomBubbleStateAndIconVisibility( - bool is_bubble_visible) { - // This method can be called during browser destruction since the bubble close - // is async. - auto* tab_interface = browser_view_->browser()->GetActiveTabInterface(); - if (!tab_interface) { - return; - } - - if (!IsPageActionMigrated(PageActionIconType::kZoom)) { - browser_view_->browser()->window()->UpdatePageActionIcon( - PageActionIconType::kZoom); - return; - } - - // Update the bubble visibility state before we refresh the icon so that - // UpdateZoomIconVisibility() sees the correct value bubble state value. - UpdateBubbleVisibilityState(browser_view_->browser(), is_bubble_visible); - - auto* tab_feature = tab_interface->GetTabFeatures(); - CHECK(tab_feature); - tab_feature->zoom_view_controller()->UpdatePageActionIcon(is_bubble_visible); -}
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h b/chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h deleted file mode 100644 index ca93998..0000000 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h +++ /dev/null
@@ -1,95 +0,0 @@ -// Copyright 2025 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_COORDINATOR_H_ -#define CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_COORDINATOR_H_ - -#include "base/memory/raw_ref.h" -#include "base/scoped_observation.h" -#include "chrome/browser/ui/views/frame/immersive_mode_controller.h" -#include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h" -#include "ui/base/unowned_user_data/scoped_unowned_user_data.h" -#include "ui/views/widget/widget_observer.h" - -class ZoomBubbleView; -class BrowserWindowInterface; - -namespace content { -class WebContents; -} - -// Manages the zoom bubble, ensuring that only one is shown at a time and that -// it is properly cleared. This class is responsible for creating, showing, -// hiding, and refreshing the ZoomBubbleView. -class ZoomBubbleCoordinator : public views::WidgetObserver, - public ImmersiveModeController::Observer { - public: - DECLARE_USER_DATA(ZoomBubbleCoordinator); - - explicit ZoomBubbleCoordinator(BrowserView& browser_view); - ZoomBubbleCoordinator(const ZoomBubbleCoordinator&) = delete; - ZoomBubbleCoordinator& operator=(const ZoomBubbleCoordinator&) = delete; - ~ZoomBubbleCoordinator() override; - - // Retrieves from the a browser window interface, or null if none. - // Note: May return null in unit_tests, even for a valid `browser`. - static ZoomBubbleCoordinator* From(BrowserWindowInterface* browser); - - // views::WidgetObserver: - void OnWidgetVisibilityChanged(views::Widget* widget, bool visible) override; - void OnWidgetDestroying(views::Widget* widget) override; - - // Creates and shows a new zoom bubble for the given `contents`, hiding any - // existing bubble first. - void Show(content::WebContents* contents, - LocationBarBubbleDelegateView::DisplayReason reason); - - // Hides the currently showing zoom bubble, if one exists. - // NOTE: This is async, as a result, the hide is not immediate. Callers should - // ensure to wait to widget destruction. - void Hide(); - - // Refreshes the existing bubble if it's already showing for `contents`. - // Returns true if a bubble was successfully refreshed, false otherwise. - bool RefreshIfShowing(content::WebContents* contents); - - // Returns true if a zoom bubble is currently being shown. - [[nodiscard]] bool IsShowing() const { - return widget_observation_.IsObserving() && - widget_observation_.GetSource()->IsVisible(); - } - - // Returns a pointer to the currently showing bubble, or nullptr if none. - ZoomBubbleView* bubble(); - - private: - // ImmersiveModeController::Observer: - void OnImmersiveRevealStarted() override; - void OnImmersiveModeControllerDestroyed() override; - - // Determines if the existing zoom bubble can be refreshed for the given - // WebContents. - bool CanRefresh(ZoomBubbleView* current_bubble, - content::WebContents* web_contents); - - // Updates visibility of the zoom icon. - void UpdateZoomBubbleStateAndIconVisibility(bool is_bubble_visible); - - ui::ScopedUnownedUserData<ZoomBubbleCoordinator> scoped_unowned_user_data_; - - // Unowned reference to the browser view that whole this coordinator. - const raw_ref<BrowserView> browser_view_; - - // Observes the widget of the zoom bubble to be notified of its destruction. - base::ScopedObservation<views::Widget, views::WidgetObserver> - widget_observation_{this}; - - // The immersive mode controller observation for the BrowserView containing - // `web_contents_`. - base::ScopedObservation<ImmersiveModeController, - ImmersiveModeController::Observer> - immersive_mode_observation_{this}; -}; - -#endif // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_COORDINATOR_H_
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc index 82ce7f5..30daade 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.cc
@@ -8,7 +8,6 @@ #include <memory> #include "base/auto_reset.h" -#include "base/check.h" #include "base/i18n/number_formatting.h" #include "base/i18n/rtl.h" #include "base/strings/stringprintf.h" @@ -153,32 +152,222 @@ BEGIN_METADATA(ZoomValue) END_METADATA +bool IsBrowserFullscreen(Browser* browser) { + DCHECK(browser->window() && browser->GetFeatures() + .exclusive_access_manager() + ->fullscreen_controller()); + return browser->window()->IsFullscreen(); +} + +views::View* GetAnchorViewForBrowser(Browser* browser) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); +#if BUILDFLAG(IS_MAC) + if (fullscreen_utils::IsInContentFullscreen(browser)) { + return nullptr; + } +#endif + if (!IsBrowserFullscreen(browser) || browser_view->IsToolbarVisible() || + browser_view->immersive_mode_controller()->IsRevealed()) { + return browser_view->toolbar_button_provider()->GetAnchorView( + kActionZoomNormal); + } + return nullptr; +} + +ImmersiveModeController* GetImmersiveModeControllerForBrowser( + Browser* browser) { + BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser); + return browser_view->immersive_mode_controller(); +} + +void ParentToBrowser(Browser* browser, + ZoomBubbleView* zoom_bubble, + views::View* anchor_view, + content::WebContents* web_contents) { + BrowserView* const browser_view = + BrowserView::GetBrowserViewForBrowser(browser); + views::Button* button = + browser_view->toolbar_button_provider()->GetPageActionView( + kActionZoomNormal); + + zoom_bubble->SetHighlightedButton(button); + + // If we don't anchor to anything the BrowserView is our parent. This happens + // in fullscreen cases. + zoom_bubble->set_parent_window( + zoom_bubble->anchor_widget() + ? gfx::NativeView() + : browser_view->GetWidget()->GetNativeView()); + + views::BubbleDialogDelegateView::CreateBubble(zoom_bubble); +} + +// Find the extension that initiated the zoom change, if any. +const extensions::ExtensionZoomRequestClient* GetExtensionZoomRequestClient( + const content::WebContents* web_contents) { + const zoom::ZoomController* zoom_controller = + zoom::ZoomController::FromWebContents(web_contents); + const zoom::ZoomRequestClient* client = zoom_controller->last_client(); + return static_cast<const extensions::ExtensionZoomRequestClient*>(client); +} + +void UpdateBubbleVisibilityState(Browser* browser, bool is_bubble_visible) { + if (!browser) { + return; + } + + auto* action_item = actions::ActionManager::Get().FindAction( + kActionZoomNormal, browser->browser_actions()->root_action_item()); + CHECK(action_item); + action_item->SetIsShowingBubble(is_bubble_visible); +} + } // namespace +// static +ZoomBubbleView* ZoomBubbleView::zoom_bubble_ = nullptr; + +// static +void ZoomBubbleView::ShowBubble(content::WebContents* web_contents, + DisplayReason reason) { + Browser* browser = chrome::FindBrowserWithTab(web_contents); + // |web_contents| could have been unloaded if a tab gets closed and a mouse + // event arrives before the zoom icon gets hidden. + if (!browser) { + return; + } + + if (RefreshBubbleIfShowing(web_contents)) { + return; + } + + // If the bubble is already showing but in a different tab, the current + // bubble must be closed and a new one created. + CloseCurrentBubble(); + + views::View* anchor_view = GetAnchorViewForBrowser(browser); + ImmersiveModeController* immersive_mode_controller = + GetImmersiveModeControllerForBrowser(browser); + CHECK(immersive_mode_controller); + + zoom_bubble_ = new ZoomBubbleView(anchor_view, web_contents, reason, + *immersive_mode_controller); + + const extensions::ExtensionZoomRequestClient* client = + GetExtensionZoomRequestClient(web_contents); + + // If the zoom change was initiated by an extension, capture the relevent + // information from it. + if (client) { + zoom_bubble_->SetExtensionInfo(client->extension()); + } + + ParentToBrowser(browser, zoom_bubble_, anchor_view, web_contents); + + if (!anchor_view && IsBrowserFullscreen(browser)) { + zoom_bubble_->AdjustForFullscreen(browser->window()->GetBounds()); + } + + // Do not announce hotkey for refocusing inactive Zoom bubble as it + // disappears after a short timeout. + zoom_bubble_->ShowForReason(reason, /* allow_refocus_alert */ false); + + // This is a temporary fix (https://crbug.com/434615869). For some reason, + // `zoom_bubble_` become null after calling ShowForReason. A long term fix + // will be to have a clear and defined lifetime for the zoom bubble. + if (!zoom_bubble_) { + return; + } + + // Update the "bubble is showing" state before we refresh the icon so that + // UpdateZoomIconVisibility() sees the correct value bubble state value. + zoom_bubble_->UpdateZoomBubbleStateAndIconVisibility( + /*is_bubble_visible=*/true); +} + +// static +bool ZoomBubbleView::RefreshBubbleIfShowing( + const content::WebContents* web_contents) { + if (!CanRefresh(web_contents)) { + return false; + } + + DCHECK_EQ(web_contents, zoom_bubble_->web_contents()); + zoom_bubble_->Refresh(); + + return true; +} + +// static +bool ZoomBubbleView::CanRefresh(const content::WebContents* web_contents) { + // Can't refresh when there's not already a bubble for this tab. + if (!zoom_bubble_ || (zoom_bubble_->web_contents() != web_contents)) { + return false; + } + + Browser* browser = chrome::FindBrowserWithTab(web_contents); + if (!browser || + (zoom_bubble_->GetAnchorView() != GetAnchorViewForBrowser(browser))) { + return false; + } + + const extensions::ExtensionZoomRequestClient* client = + GetExtensionZoomRequestClient(web_contents); + + // Allow refreshes when the client won't create its own bubble; otherwise + // the existing bubble would show the wrong zoom value. + if (client && client->ShouldSuppressBubble()) { + return true; + } + + // Allow refreshes when the existing bubble has the same attribution for + // the zoom change, so only the label needs updating. + return zoom_bubble_->extension_info_.id == + (client ? client->extension()->id() : std::string()); +} + +// static +void ZoomBubbleView::CloseCurrentBubble() { + if (zoom_bubble_) { + zoom_bubble_->CloseBubble(); + } +} + +// static +ZoomBubbleView* ZoomBubbleView::GetZoomBubble() { + return zoom_bubble_; +} + void ZoomBubbleView::Refresh() { UpdateZoomPercent(); StartTimerIfNecessary(); } -ZoomBubbleView::ZoomBubbleView(Browser* browser, - views::View* anchor_view, - content::WebContents* web_contents, - DisplayReason reason) +ZoomBubbleView::ZoomBubbleView( + views::View* anchor_view, + content::WebContents* web_contents, + DisplayReason reason, + ImmersiveModeController& immersive_mode_controller) : LocationBarBubbleDelegateView(anchor_view, web_contents), - browser_(browser), auto_close_duration_(kBubbleCloseDelayDefault), - auto_close_(reason == AUTOMATIC) { + auto_close_(reason == AUTOMATIC), + session_id_(chrome::FindBrowserWithTab(web_contents)->session_id()) { SetButtons(static_cast<int>(ui::mojom::DialogButton::kNone)); SetNotifyEnterExitOnChild(true); + scoped_observation_.Observe(&immersive_mode_controller); UseCompactMargins(); } ZoomBubbleView::~ZoomBubbleView() = default; std::u16string ZoomBubbleView::GetAccessibleWindowTitle() const { + Browser* browser = GetBrowser(); + if (!browser) { + return {}; + } + ToolbarButtonProvider* provider = - BrowserView::GetBrowserViewForBrowser(browser_) - ->toolbar_button_provider(); + BrowserView::GetBrowserViewForBrowser(browser)->toolbar_button_provider(); return provider->GetPageActionView(kActionZoomNormal)->GetAccessibleName(); } @@ -200,7 +389,8 @@ } void ZoomBubbleView::OnGestureEvent(ui::GestureEvent* event) { - if (!auto_close_ || event->type() != ui::EventType::kGestureTap) { + if (!zoom_bubble_ || !zoom_bubble_->auto_close_ || + event->type() != ui::EventType::kGestureTap) { return; } @@ -210,7 +400,7 @@ } void ZoomBubbleView::OnKeyEvent(ui::KeyEvent* event) { - if (!auto_close_) { + if (!zoom_bubble_ || !zoom_bubble_->auto_close_) { return; } @@ -324,6 +514,40 @@ StartTimerIfNecessary(); } +void ZoomBubbleView::WindowClosing() { + // |zoom_bubble_| can be a new bubble by this point (as Close(); doesn't + // call this right away). Only set to nullptr when it's this bubble. + bool this_bubble = zoom_bubble_ == this; + if (this_bubble) { + zoom_bubble_ = nullptr; + } + + // Clear the "bubble is showing" state before we refresh the icon so that + // UpdateZoomIconVisibility() sees the correct value bubble state value. + UpdateZoomBubbleStateAndIconVisibility(/*is_bubble_visible=*/zoom_bubble_ != + nullptr); +} + +void ZoomBubbleView::CloseBubble() { + Browser* browser = GetBrowser(); + if (ignore_close_bubble_ && browser && + GetAnchorViewForBrowser(browser) == GetAnchorView()) { + return; + } + + // Widget's Close() is async, but we don't want to use zoom_bubble_ after + // this. Additionally web_contents() may have been destroyed. + zoom_bubble_ = nullptr; + LocationBarBubbleDelegateView::CloseBubble(); +} + +void ZoomBubbleView::OnImmersiveRevealStarted() { + CloseBubble(); +} + +void ZoomBubbleView::OnImmersiveModeControllerDestroyed() { + scoped_observation_.Reset(); +} void ZoomBubbleView::OnExtensionIconImageChanged( extensions::IconImage* /* image */) { @@ -388,20 +612,38 @@ !blink::ZoomValuesEqual(zoom_levels.back(), current_zoom_level)); } +void ZoomBubbleView::UpdateZoomBubbleStateAndIconVisibility( + bool is_bubble_visible) { + // Note that we can't rely on web_contents() here, as it may have been + // destroyed by the time we get this call. Also note parent_window() (if set) + // may also be destroyed: the call to WindowClosing() may be triggered by + // parent window destruction tearing down its child windows. + Browser* browser = chrome::FindBrowserWithID(session_id_); + if (!browser || !browser->window() || !browser->GetActiveTabInterface()) { + return; + } + + if (!IsPageActionMigrated(PageActionIconType::kZoom)) { + browser->window()->UpdatePageActionIcon(PageActionIconType::kZoom); + return; + } + + // Update the bubble visibility state before we refresh the icon so that + // UpdateZoomIconVisibility() sees the correct value bubble state value. + UpdateBubbleVisibilityState(browser, is_bubble_visible); + + auto* tab_feature = browser->GetActiveTabInterface()->GetTabFeatures(); + CHECK(tab_feature); + tab_feature->zoom_view_controller()->UpdatePageActionIcon(is_bubble_visible); +} + void ZoomBubbleView::StartTimerIfNecessary() { if (!auto_close_) { return; } - auto_close_timer_.Start( - FROM_HERE, auto_close_duration_, - base::BindOnce(&ZoomBubbleView::Close, base::Unretained(this))); -} - -void ZoomBubbleView::Close() { - if (GetWidget()) { - GetWidget()->Close(); - } + auto_close_timer_.Start(FROM_HERE, auto_close_duration_, this, + &ZoomBubbleView::CloseBubble); } void ZoomBubbleView::StopTimer() { @@ -422,30 +664,18 @@ void ZoomBubbleView::ImageButtonPressed() { DCHECK(extension_info_.icon_image) << "Invalid button press."; - chrome::AddSelectedTabWithURL( - browser_, - GURL(base::StringPrintf("chrome://extensions?id=%s", - extension_info_.id.c_str())), - ui::PAGE_TRANSITION_FROM_API); + Browser* browser = GetBrowser(); + if (browser) { + chrome::AddSelectedTabWithURL( + browser, + GURL(base::StringPrintf("chrome://extensions?id=%s", + extension_info_.id.c_str())), + ui::PAGE_TRANSITION_FROM_API); + } } -std::u16string_view ZoomBubbleView::GetLabelForTesting() const { - return label_->GetText(); -} - -base::OneShotTimer* ZoomBubbleView::GetAutoCloseTimerForTesting() { - return &auto_close_timer_; -} -views::Button* ZoomBubbleView::GetResetButtonForTesting() { - return reset_button_; -} - -views::Button* ZoomBubbleView::GetZoomInButtonForTesting() { - return zoom_in_button_; -} - -void ZoomBubbleView::OnKeyEventForTesting(ui::KeyEvent* event) { - OnKeyEvent(event); +Browser* ZoomBubbleView::GetBrowser() const { + return web_contents() ? chrome::FindBrowserWithTab(web_contents()) : nullptr; } ZoomBubbleView::ZoomBubbleExtensionInfo::ZoomBubbleExtensionInfo() = default;
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h index 440b916..1c2ced0 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view.h +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view.h
@@ -13,6 +13,7 @@ #include "base/scoped_observation.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "chrome/browser/ui/views/frame/immersive_mode_controller.h" #include "chrome/browser/ui/views/location_bar/location_bar_bubble_delegate_view.h" #include "components/sessions/core/session_id.h" #include "content/public/browser/web_contents_observer.h" @@ -32,44 +33,41 @@ // View used to display the zoom percentage when it has changed. class ZoomBubbleView : public LocationBarBubbleDelegateView, + public ImmersiveModeController::Observer, public extensions::IconImage::Observer { METADATA_HEADER(ZoomBubbleView, LocationBarBubbleDelegateView) public: - // Constructs ZoomBubbleView. Anchors the bubble to |anchor_view|, which must - // not be nullptr. The bubble will auto-close when |reason| is AUTOMATIC. If - // |immersive_mode_controller_| is present, the bubble will auto-close when - // the top-of-window views are revealed. - ZoomBubbleView(Browser* browser, - views::View* anchor_view, - content::WebContents* web_contents, - DisplayReason reason); - ~ZoomBubbleView() override; - ZoomBubbleView(const ZoomBubbleView&) = delete; ZoomBubbleView& operator=(const ZoomBubbleView&) = delete; + // Shows the bubble and automatically closes it after a short time period if + // |reason| is AUTOMATIC. + static void ShowBubble(content::WebContents* web_contents, + DisplayReason reason); + + // If the bubble is being shown for the given |web_contents|, refreshes it. + static bool RefreshBubbleIfShowing(const content::WebContents* web_contents); + + // Closes the showing bubble (if one exists). + static void CloseCurrentBubble(); + + // Returns the zoom bubble if the zoom bubble is showing. Returns NULL + // otherwise. + static ZoomBubbleView* GetZoomBubble(); + // Refreshes the bubble by changing the zoom percentage appropriately and // resetting the timer if necessary. void Refresh(); - // Sets information about the extension that initiated the zoom change. - // Calling this method asserts that the extension |extension| did initiate - // the zoom change. - void SetExtensionInfo(const extensions::Extension* extension); - - // Returns the ID of the extension that triggered the bubble, or an empty - // string if it was not triggered by an extension. - const std::string& extension_id() const { return extension_info_.id; } - - // Helpers for testing. - std::u16string_view GetLabelForTesting() const; - base::OneShotTimer* GetAutoCloseTimerForTesting(); - views::Button* GetResetButtonForTesting(); - views::Button* GetZoomInButtonForTesting(); - void OnKeyEventForTesting(ui::KeyEvent* event); - private: + FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest, ImmersiveFullscreen); + FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest, + BubbleSuppressingExtensionRefreshesExistingBubble); + FRIEND_TEST_ALL_PREFIXES(ZoomBubbleBrowserTest, FocusPreventsClose); + FRIEND_TEST_ALL_PREFIXES(ZoomBubbleImmersiveDisabledBrowserTest, + AnchorPositionsInFullscreen); + // Returns true if we can reuse the existing bubble for the given // |web_contents|. static bool CanRefresh(const content::WebContents* web_contents); @@ -93,6 +91,16 @@ std::unique_ptr<const extensions::IconImage> icon_image; }; + // Constructs ZoomBubbleView. Anchors the bubble to |anchor_view|, which must + // not be nullptr. The bubble will auto-close when |reason| is AUTOMATIC. If + // |immersive_mode_controller_| is present, the bubble will auto-close when + // the top-of-window views are revealed. + ZoomBubbleView(views::View* anchor_view, + content::WebContents* web_contents, + DisplayReason reason, + ImmersiveModeController& immersive_mode_controller); + ~ZoomBubbleView() override; + // LocationBarBubbleDelegateView: std::u16string GetAccessibleWindowTitle() const override; void OnFocus() override; @@ -102,16 +110,27 @@ void OnMouseEntered(const ui::MouseEvent& event) override; void OnMouseExited(const ui::MouseEvent& event) override; void Init() override; + void WindowClosing() override; + void CloseBubble() override; + + // ImmersiveModeController::Observer + void OnImmersiveRevealStarted() override; + void OnImmersiveModeControllerDestroyed() override; // extensions::IconImage::Observer void OnExtensionIconImageChanged(extensions::IconImage* /* image */) override; - // Closes the bubble's widget. - void Close(); + // Sets information about the extension that initiated the zoom change. + // Calling this method asserts that the extension |extension| did initiate + // the zoom change. + void SetExtensionInfo(const extensions::Extension* extension); // Updates |label_| with the up to date zoom. void UpdateZoomPercent(); + // Updates visibility of the zoom icon. + void UpdateZoomBubbleStateAndIconVisibility(bool is_bubble_visible); + // Starts a timer which will close the bubble if |auto_close_| is true. void StartTimerIfNecessary(); @@ -124,10 +143,16 @@ // Called by ButtonPressed() when |image_button_| is pressed. void ImageButtonPressed(); - raw_ptr<Browser> browser_; + // Gets the browser for `web_contents()`. May return null. + Browser* GetBrowser() const; ZoomBubbleExtensionInfo extension_info_; + // Singleton instance of the zoom bubble. The zoom bubble can only be shown on + // the active browser window, so there is no case in which it will be shown + // twice at the same time. + static ZoomBubbleView* zoom_bubble_; + // Timer used to auto close the bubble. base::OneShotTimer auto_close_timer_; @@ -154,6 +179,16 @@ // button presses, since pressing a button in the bubble should not trigger // closing. bool ignore_close_bubble_ = false; + + // The immersive mode controller observation for the BrowserView containing + // |web_contents_|. + base::ScopedObservation<ImmersiveModeController, + ImmersiveModeController::Observer> + scoped_observation_{this}; + + // The session of the Browser that triggered the bubble. This allows the zoom + // icon to be updated even if the WebContents is destroyed. + const SessionID session_id_; }; #endif // CHROME_BROWSER_UI_VIEWS_LOCATION_BAR_ZOOM_BUBBLE_VIEW_H_
diff --git a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc index 6b747a7..9767329 100644 --- a/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc +++ b/chrome/browser/ui/views/location_bar/zoom_bubble_view_browsertest.cc
@@ -7,14 +7,11 @@ #include "build/build_config.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/test/test_browser_dialog.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/immersive_mode_controller.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/common/chrome_features.h" #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" @@ -38,26 +35,18 @@ #include "ui/views/test/button_test_api.h" #endif +using ZoomBubbleBrowserTest = InProcessBrowserTest; + namespace { -class ZoomBubbleBrowserTest : public InProcessBrowserTest { - protected: - void SetUpOnMainThread() override { - InProcessBrowserTest::SetUpOnMainThread(); - zoom_bubble_coordinator_ = ZoomBubbleCoordinator::From(browser()); - } +void ShowInActiveTab(Browser* browser) { + content::WebContents* web_contents = + browser->tab_strip_model()->GetActiveWebContents(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::USER_GESTURE); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); +} - void TearDownOnMainThread() override { zoom_bubble_coordinator_ = nullptr; } - - void ShowInActiveTab(Browser* browser) { - content::WebContents* web_contents = - browser->tab_strip_model()->GetActiveWebContents(); - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::USER_GESTURE); - EXPECT_TRUE(zoom_bubble_coordinator_->bubble()); - } - - raw_ptr<ZoomBubbleCoordinator> zoom_bubble_coordinator_; -}; +} // namespace // Test whether the zoom bubble is anchored and whether it is visible when in // content fullscreen. @@ -70,37 +59,32 @@ content::WebContents* web_contents = browser_view->GetActiveWebContents(); // The zoom bubble should be anchored when not in fullscreen. - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); - ASSERT_TRUE(zoom_bubble_coordinator_->bubble()); - const ZoomBubbleView* zoom_bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); + ASSERT_TRUE(ZoomBubbleView::GetZoomBubble()); + const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble(); EXPECT_TRUE(zoom_bubble->GetAnchorView()); - views::test::WidgetDestroyedWaiter waiter( - const_cast<views::Widget*>(zoom_bubble->GetWidget())); - // Entering fullscreen should close the bubble. (We enter into tab fullscreen // here because tab fullscreen is non-immersive even on Chrome OS.) { // The fullscreen change notification is sent asynchronously. Wait for the // notification before testing the zoom bubble visibility. - ui_test_utils::FullscreenWaiter waiter_f(browser(), - {.tab_fullscreen = true}); + ui_test_utils::FullscreenWaiter waiter(browser(), {.tab_fullscreen = true}); static_cast<content::WebContentsDelegate*>(browser()) ->EnterFullscreenModeForTab(web_contents->GetPrimaryMainFrame(), {}); - waiter_f.Wait(); + waiter.Wait(); } #if !BUILDFLAG(IS_MAC) // The immersive mode controller is enabled in content fullscreen on Mac. ASSERT_FALSE(browser_view->immersive_mode_controller()->IsEnabled()); #endif - waiter.Wait(); - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); // The bubble should not be anchored when it is shown in non-immersive // fullscreen. - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); - ASSERT_TRUE(zoom_bubble_coordinator_->bubble()); - zoom_bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); + ASSERT_TRUE(ZoomBubbleView::GetZoomBubble()); + zoom_bubble = ZoomBubbleView::GetZoomBubble(); EXPECT_FALSE(zoom_bubble->GetAnchorView()); // Exit fullscreen before ending the test for the sake of sanity. @@ -138,24 +122,16 @@ BrowserView* browser_view = static_cast<BrowserView*>(browser()->window()); content::WebContents* web_contents = browser_view->GetActiveWebContents(); - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); - ASSERT_TRUE(zoom_bubble_coordinator_->bubble()); - ZoomBubbleView* zoom_bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); + ASSERT_TRUE(ZoomBubbleView::GetZoomBubble()); + ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble(); ASSERT_TRUE(zoom_bubble); // Record the anchor view when not in fullscreen. const views::View* org_anchor_view = zoom_bubble->GetAnchorView(); - // Set up a waiter to wait for the bubble to be destroyed when we enter - // fullscreen. - views::test::WidgetDestroyedWaiter close_waiter(zoom_bubble->GetWidget()); - // Enter into a browser fullscreen mode. This would close the zoom bubble. ui_test_utils::ToggleFullscreenModeAndWait(browser()); - - // Wait for the asynchronous widget destruction to complete. - close_waiter.Wait(); - - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); #if BUILDFLAG(IS_MAC) || BUILDFLAG(IS_CHROMEOS) const bool should_show_toolbar = true; @@ -166,8 +142,8 @@ // The zoom bubble should be anchored to the same anchor view if the toolbar // shows. - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); - zoom_bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); + zoom_bubble = ZoomBubbleView::GetZoomBubble(); ASSERT_TRUE(zoom_bubble); if (should_show_toolbar) { EXPECT_EQ(org_anchor_view, zoom_bubble->GetAnchorView()); @@ -176,7 +152,7 @@ // Hide toolbar. chrome::ToggleAlwaysShowToolbarInFullscreen(browser()); - zoom_bubble = zoom_bubble_coordinator_->bubble(); + zoom_bubble = ZoomBubbleView::GetZoomBubble(); EXPECT_EQ(org_zoom_bubble, zoom_bubble); EXPECT_EQ(org_anchor_view, zoom_bubble->GetAnchorView()); @@ -185,9 +161,8 @@ // position. const ui::MouseEvent event(ui::EventType::kMousePressed, gfx::Point(), gfx::Point(), ui::EventTimeForNow(), 0, 0); - views::test::ButtonTestApi(zoom_bubble->GetZoomInButtonForTesting()) - .NotifyClick(event); - zoom_bubble = zoom_bubble_coordinator_->bubble(); + views::test::ButtonTestApi(zoom_bubble->zoom_in_button_).NotifyClick(event); + zoom_bubble = ZoomBubbleView::GetZoomBubble(); EXPECT_NE(org_zoom_bubble, zoom_bubble); EXPECT_FALSE(zoom_bubble->GetAnchorView()); @@ -224,25 +199,22 @@ // The zoom bubble should not be anchored when it is shown in immersive // fullscreen and the top-of-window views are not revealed. - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); - ASSERT_TRUE(zoom_bubble_coordinator_->bubble()); - const ZoomBubbleView* zoom_bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); + ASSERT_TRUE(ZoomBubbleView::GetZoomBubble()); + const ZoomBubbleView* zoom_bubble = ZoomBubbleView::GetZoomBubble(); EXPECT_FALSE(zoom_bubble->GetAnchorView()); // An immersive reveal should hide the zoom bubble. - views::test::WidgetDestroyedWaiter waiter( - zoom_bubble_coordinator_->bubble()->GetWidget()); std::unique_ptr<ImmersiveRevealedLock> immersive_reveal_lock = immersive_controller->GetRevealedLock( ImmersiveModeController::ANIMATE_REVEAL_NO); ASSERT_TRUE(immersive_controller->IsRevealed()); - waiter.Wait(); - EXPECT_EQ(nullptr, zoom_bubble_coordinator_->bubble()); + EXPECT_EQ(nullptr, ZoomBubbleView::zoom_bubble_); // The zoom bubble should be anchored when it is shown in immersive fullscreen // and the top-of-window views are revealed. - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); - zoom_bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); + zoom_bubble = ZoomBubbleView::GetZoomBubble(); ASSERT_TRUE(zoom_bubble); EXPECT_TRUE(zoom_bubble->GetAnchorView()); @@ -251,7 +223,7 @@ // the zoom bubble was still visible.) immersive_reveal_lock.reset(); EXPECT_TRUE(immersive_controller->IsRevealed()); - zoom_bubble_coordinator_->Hide(); + ZoomBubbleView::CloseCurrentBubble(); // The zoom bubble is deleted on a task. content::RunAllPendingInMessageLoop(); EXPECT_FALSE(immersive_controller->IsRevealed()); @@ -266,11 +238,11 @@ content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); // Close the current tab and try opening the zoom bubble with stale // |web_contents|. chrome::CloseTab(browser()); - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); } // Ensure a tab switch closes the bubble. @@ -279,10 +251,10 @@ AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK)); ShowInActiveTab(browser()); views::test::WidgetDestroyedWaiter close_waiter( - zoom_bubble_coordinator_->bubble()->GetWidget()); + ZoomBubbleView::GetZoomBubble()->GetWidget()); chrome::SelectNextTab(browser()); close_waiter.Wait(); - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); } // Ensure the bubble is dismissed on tab closure and doesn't reference a @@ -292,19 +264,21 @@ AddTabAtIndex(0, GURL(url::kAboutBlankURL), ui::PAGE_TRANSITION_LINK)); ShowInActiveTab(browser()); - ZoomBubbleView* bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView* bubble = ZoomBubbleView::GetZoomBubble(); EXPECT_TRUE(bubble); views::test::TestWidgetObserver observer(bubble->GetWidget()); EXPECT_FALSE(bubble->GetWidget()->IsClosed()); - views::test::WidgetDestroyedWaiter waiter(bubble->GetWidget()); - chrome::CloseTab(browser()); - // Wait for the widget destruction to complete. - waiter.Wait(); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); - EXPECT_FALSE(zoom_bubble_coordinator_->bubble()); + // Widget::Close() completes asynchronously, so it's still safe to access + // |bubble| here, even though GetZoomBubble() returned null. + EXPECT_FALSE(observer.widget_closed()); + EXPECT_TRUE(bubble->GetWidget()->IsClosed()); + + base::RunLoop().RunUntilIdle(); EXPECT_TRUE(observer.widget_closed()); } @@ -343,11 +317,11 @@ zoom_controller->SetZoomMode(zoom::ZoomController::ZOOM_MODE_MANUAL); ShowInActiveTab(browser()); - const ZoomBubbleView* bubble = zoom_bubble_coordinator_->bubble(); + const ZoomBubbleView* bubble = ZoomBubbleView::GetZoomBubble(); ASSERT_TRUE(bubble); const double old_zoom_level = zoom_controller->GetZoomLevel(); - const std::u16string old_label(bubble->GetLabelForTesting()); + const std::u16string old_label(bubble->label_->GetText()); scoped_refptr<const extensions::Extension> extension = extensions::ExtensionBuilder("Test").Build(); @@ -356,8 +330,8 @@ const double new_zoom_level = old_zoom_level + 0.5; zoom_controller->SetZoomLevelByClient(new_zoom_level, client); - ASSERT_EQ(zoom_bubble_coordinator_->bubble(), bubble); - EXPECT_NE(bubble->GetLabelForTesting(), old_label); + ASSERT_EQ(ZoomBubbleView::GetZoomBubble(), bubble); + EXPECT_NE(bubble->label_->GetText(), old_label); } class ZoomBubbleReuseTest : public ZoomBubbleBrowserTest { @@ -382,10 +356,10 @@ const double zoom_level2 = zoom_level1 + 0.5; zoom_controller->SetZoomLevelByClient(zoom_level1, client1); - const ZoomBubbleView* bubble1 = zoom_bubble_coordinator_->bubble(); + const ZoomBubbleView* bubble1 = ZoomBubbleView::GetZoomBubble(); EXPECT_TRUE(bubble1); zoom_controller->SetZoomLevelByClient(zoom_level2, client2); - const ZoomBubbleView* bubble2 = zoom_bubble_coordinator_->bubble(); + const ZoomBubbleView* bubble2 = ZoomBubbleView::GetZoomBubble(); EXPECT_TRUE(bubble2); return bubble1 == bubble2; @@ -398,8 +372,6 @@ extension2_ = extensions::ExtensionBuilder("Test2").Build(); client2_ = base::MakeRefCounted<const TestZoomRequestClient>(extension2_, false); - - zoom_bubble_coordinator_ = ZoomBubbleCoordinator::From(browser()); } scoped_refptr<const extensions::Extension> extension1_; @@ -435,27 +407,8 @@ ZoomBubbleDialogTest(const ZoomBubbleDialogTest&) = delete; ZoomBubbleDialogTest& operator=(const ZoomBubbleDialogTest&) = delete; - void SetUpOnMainThread() override { - DialogBrowserTest::SetUpOnMainThread(); - zoom_bubble_coordinator_ = ZoomBubbleCoordinator::From(browser()); - } - - void TearDownOnMainThread() override { - zoom_bubble_coordinator_ = nullptr; - DialogBrowserTest::TearDownOnMainThread(); - } - - void ShowInActiveTab(Browser* browser) { - content::WebContents* web_contents = - browser->tab_strip_model()->GetActiveWebContents(); - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::USER_GESTURE); - EXPECT_TRUE(zoom_bubble_coordinator_->bubble()); - } - // DialogBrowserTest: void ShowUi(const std::string& name) override { ShowInActiveTab(browser()); } - - raw_ptr<ZoomBubbleCoordinator> zoom_bubble_coordinator_; }; // Test that calls ShowUi("default"). @@ -468,11 +421,11 @@ IN_PROC_BROWSER_TEST_F(ZoomBubbleBrowserTest, FocusPreventsClose) { content::WebContents* web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - zoom_bubble_coordinator_->Show(web_contents, ZoomBubbleView::AUTOMATIC); - ZoomBubbleView* bubble = zoom_bubble_coordinator_->bubble(); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); + ZoomBubbleView* bubble = ZoomBubbleView::GetZoomBubble(); ASSERT_TRUE(bubble); // |auto_close_timer_| is running so that the bubble is closed at the end. - EXPECT_TRUE(bubble->GetAutoCloseTimerForTesting()->IsRunning()); + EXPECT_TRUE(bubble->auto_close_timer_.IsRunning()); views::FocusManager* focus_manager = bubble->GetFocusManager(); // The bubble must have an associated Widget from which to get a FocusManager. @@ -480,11 +433,9 @@ // Focus is usually gained via a key combination like alt+shift+a. The test // simulates this by focusing the bubble and then sending an empty KeyEvent. - focus_manager->SetFocusedView(bubble->GetResetButtonForTesting()); - bubble->OnKeyEventForTesting(nullptr); + focus_manager->SetFocusedView(bubble->reset_button_); + bubble->OnKeyEvent(nullptr); // |auto_close_timer_| should not be running since focus should prevent the // bubble from closing. - EXPECT_FALSE(bubble->GetAutoCloseTimerForTesting()->IsRunning()); + EXPECT_FALSE(bubble->auto_close_timer_.IsRunning()); } - -} // namespace
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.cc index 5d03d1d..2dfdb66f 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.cc +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.cc
@@ -5,6 +5,8 @@ #include "chrome/browser/ui/views/omnibox/omnibox_popup_presenter.h" #include "base/feature_list.h" +#include "base/functional/bind.h" +#include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" #include "base/metrics/histogram_macros.h" #include "base/observer_list_types.h" @@ -13,6 +15,7 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/omnibox/omnibox_view.h" #include "chrome/browser/ui/views/location_bar/location_bar_view.h" +#include "chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.h" #include "chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h" #include "chrome/browser/ui/views/theme_copying_widget.h" #include "chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.h" @@ -21,39 +24,36 @@ #include "chrome/common/webui_url_constants.h" #include "components/omnibox/common/omnibox_features.h" #include "content/public/browser/render_widget_host_view.h" -#include "ui/base/metadata/metadata_impl_macros.h" +#include "omnibox_popup_webui_content.h" +#include "rounded_omnibox_results_frame.h" #include "ui/gfx/geometry/rounded_corners_f.h" +#include "ui/views/view_utils.h" OmniboxPopupPresenter::OmniboxPopupPresenter(LocationBarView* location_bar_view, OmniboxController* controller) - : views::WebView(location_bar_view->profile()), - location_bar_view_(location_bar_view), + : location_bar_view_(location_bar_view), + controller_(controller), include_location_bar_cutout_( !base::FeatureList::IsEnabled(omnibox::kWebUIOmniboxFullPopup)) { - set_owned_by_client(OwnedByClientPassKey()); - - // Make the OmniboxController available to the OmniboxPopupUI. - OmniboxPopupWebContentsHelper::CreateForWebContents(GetWebContents()); - OmniboxPopupWebContentsHelper::FromWebContents(GetWebContents()) - ->set_omnibox_controller(controller); - - LoadInitialURL(GURL(chrome::kChromeUIOmniboxPopupURL)); - + owned_omnibox_popup_webui_content_ = + std::make_unique<OmniboxPopupWebUIContent>( + this, location_bar_view_, controller_, include_location_bar_cutout_); location_bar_view_->AddObserver(this); } OmniboxPopupPresenter::~OmniboxPopupPresenter() { location_bar_view_->RemoveObserver(this); - ReleaseWidget(false); + ReleaseWidget(); } void OmniboxPopupPresenter::Show() { if (!widget_) { - widget_ = new ThemeCopyingWidget(location_bar_view_->GetWidget()); + widget_ = + std::make_unique<ThemeCopyingWidget>(location_bar_view_->GetWidget()); const views::Widget* parent_widget = location_bar_view_->GetWidget(); views::Widget::InitParams params( - views::Widget::InitParams::NATIVE_WIDGET_OWNS_WIDGET, + views::Widget::InitParams::CLIENT_OWNS_WIDGET, views::Widget::InitParams::TYPE_POPUP); #if BUILDFLAG(IS_WIN) // On Windows use the software compositor to ensure that we don't block @@ -64,36 +64,28 @@ params.parent = parent_widget->GetNativeView(); params.context = parent_widget->GetNativeWindow(); - RoundedOmniboxResultsFrame::OnBeforeWidgetInit(¶ms, widget_); + RoundedOmniboxResultsFrame::OnBeforeWidgetInit(¶ms, widget_.get()); + + widget_->MakeCloseSynchronous(base::BindOnce( + &OmniboxPopupPresenter::OnWidgetClosed, base::Unretained(this))); widget_->Init(std::move(params)); widget_->SetContentsView(std::make_unique<RoundedOmniboxResultsFrame>( - this, location_bar_view_, include_location_bar_cutout_)); - widget_->AddObserver(this); + owned_omnibox_popup_webui_content_.release(), location_bar_view_, + include_location_bar_cutout_)); + widget_->SetVisibilityChangedAnimationsEnabled(false); - // On ShowInactive(), the widget height can not be 0 or else the compositor - // thinks the webview is hidden and will not calculate its preferred size. + // On Show(), the widget height can not be 0 or else the compositor thinks + // the webview is hidden and will not calculate its preferred size. SetWidgetContentHeight(1); widget_->ShowInactive(); - - // Manually set zoom level, since any zooming is undesirable in the omnibox. - auto* zoom_controller = - zoom::ZoomController::FromWebContents(GetWebContents()); - if (!zoom_controller) { - // Create ZoomController manually, if not already exists, because it is - // not automatically created when the WebUI has not been opened in a tab. - zoom_controller = - zoom::ZoomController::CreateForWebContents(GetWebContents()); - } - zoom_controller->SetZoomMode(zoom::ZoomController::ZOOM_MODE_ISOLATED); - zoom_controller->SetZoomLevel(0); } } void OmniboxPopupPresenter::Hide() { // Only close if UI DevTools settings allow. if (widget_ && widget_->ShouldHandleNativeWidgetActivationChanged(false)) { - ReleaseWidget(true); + ReleaseWidget(); } } @@ -102,36 +94,10 @@ } WebuiOmniboxHandler* OmniboxPopupPresenter::GetHandler() { - const bool ready = IsHandlerReady(); - if (!requested_handler_) { - // Only log on first access. - requested_handler_ = true; - base::UmaHistogramBoolean("Omnibox.WebUI.HandlerReadyOnFirstAccess", ready); + if (auto* content = GetOmniboxPopupWebUIContent()) { + return content->GetHandler(); } - if (!ready) { - return nullptr; - } - OmniboxPopupUI* omnibox_popup_ui = static_cast<OmniboxPopupUI*>( - GetWebContents()->GetWebUI()->GetController()); - return omnibox_popup_ui->handler(); -} - -void OmniboxPopupPresenter::AddedToWidget() { - views::WebView::AddedToWidget(); - const float corner_radius = - views::LayoutProvider::Get()->GetCornerRadiusMetric( - views::ShapeContextTokens::kOmniboxExpandedRadius); - gfx::RoundedCornersF rounded_corner_radii = - gfx::RoundedCornersF(include_location_bar_cutout_ ? 0 : corner_radius, - include_location_bar_cutout_ ? 0 : corner_radius, - corner_radius, corner_radius); - holder()->SetCornerRadii(rounded_corner_radii); -} - -void OmniboxPopupPresenter::OnWidgetDestroyed(views::Widget* widget) { - if (widget == widget_) { - widget_ = nullptr; - } + return nullptr; } void OmniboxPopupPresenter::SetWidgetContentHeight(int content_height) { @@ -151,53 +117,49 @@ } } -void OmniboxPopupPresenter::ResizeDueToAutoResize(content::WebContents* source, - const gfx::Size& new_size) { - SetWidgetContentHeight(new_size.height()); +void OmniboxPopupPresenter::OnViewBoundsChanged(views::View* observed_view) { + CHECK(observed_view == location_bar_view_); + if (auto* content = GetOmniboxPopupWebUIContent()) { + const int width = + location_bar_view_->width() + + RoundedOmniboxResultsFrame::GetLocationBarAlignmentInsets().width(); + gfx::Size min_size(width, 1); + gfx::Size max_size(width, INT_MAX); + + content::RenderWidgetHostView* render_widget_host_view = + content->GetWebContents()->GetRenderWidgetHostView(); + if (render_widget_host_view) { + render_widget_host_view->EnableAutoResize(min_size, max_size); + } + } } -void OmniboxPopupPresenter::OnViewBoundsChanged(View* observed_view) { - CHECK(observed_view == location_bar_view_); - const int width = - location_bar_view_->width() + - RoundedOmniboxResultsFrame::GetLocationBarAlignmentInsets().width(); - gfx::Size min_size(width, 1); - gfx::Size max_size(width, INT_MAX); - - content::RenderWidgetHostView* render_widget_host_view = - GetWebContents()->GetRenderWidgetHostView(); - if (render_widget_host_view) { - render_widget_host_view->EnableAutoResize(min_size, max_size); - } +void OmniboxPopupPresenter::OnWidgetClosed( + views::Widget::ClosedReason closed_reason) { + owned_omnibox_popup_webui_content_ = AsViewClass<OmniboxPopupWebUIContent>( + AsViewClass<RoundedOmniboxResultsFrame>(widget_->GetContentsView()) + ->ExtractContents()); + widget_.reset(); } bool OmniboxPopupPresenter::IsHandlerReady() { - OmniboxPopupUI* omnibox_popup_ui = static_cast<OmniboxPopupUI*>( - GetWebContents()->GetWebUI()->GetController()); - return omnibox_popup_ui->handler() && - omnibox_popup_ui->handler()->IsRemoteBound(); + return GetOmniboxPopupWebUIContent()->IsHandlerReady(); } -void OmniboxPopupPresenter::ReleaseWidget(bool close) { +void OmniboxPopupPresenter::ReleaseWidget() { if (widget_) { - // Avoid possibility of dangling raw_ptr by nulling before cleanup. - views::Widget* widget = widget_; - widget_ = nullptr; - - widget->RemoveObserver(this); - if (close) { - // Ensure we close `widget_` synchronously. This is necessary as the - // `widget_`'s contents view has dependencies on the hosting widget's - // BrowserView (see `SetContentsView()` above). Since the popup widget is - // owned by its NativeWidget there is a risk of dangling pointers if it is - // not destroyed synchronously with its parent. - // TODO(crbug.com/40232479): Once this is migrated to CLIENT_OWNS_WIDGET - // this will no longer be necessary. - widget->CloseNow(); - } + widget_->CloseWithReason(views::Widget::ClosedReason::kUnspecified); } - CHECK(!views::WidgetObserver::IsInObserverList()); } -BEGIN_METADATA(OmniboxPopupPresenter) -END_METADATA +OmniboxPopupWebUIContent* OmniboxPopupPresenter::GetOmniboxPopupWebUIContent() { + if (widget_) { + return views::AsViewClass<OmniboxPopupWebUIContent>( + views::AsViewClass<RoundedOmniboxResultsFrame>( + widget_->GetContentsView())); + } + if (owned_omnibox_popup_webui_content_) { + return owned_omnibox_popup_webui_content_.get(); + } + return nullptr; +}
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.h b/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.h index 6da1b7f..776d285 100644 --- a/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.h +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_presenter.h
@@ -5,10 +5,11 @@ #ifndef CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_PRESENTER_H_ #define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_PRESENTER_H_ +#include <memory> + #include "base/memory/raw_ptr.h" #include "chrome/browser/ui/webui/searchbox/webui_omnibox_handler.h" #include "content/public/browser/render_frame_host.h" -#include "ui/base/metadata/metadata_header_macros.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" #include "ui/views/controls/webview/webview.h" @@ -18,6 +19,7 @@ class LocationBarView; class OmniboxController; +class OmniboxPopupWebUIContent; // An assistant class for OmniboxPopupViewWebUI, this manages a WebView and a // Widget to present WebUI suggestions. This class is an implementation detail @@ -25,11 +27,7 @@ // of this class is presentation only, i.e. Views and Widgets. For omnibox // logic concerns and communication between native omnibox code and the WebUI // code, work with OmniboxPopupViewWebUI directly. -class OmniboxPopupPresenter : public views::WebView, - public views::WidgetObserver, - public views::ViewObserver { - METADATA_HEADER(OmniboxPopupPresenter, views::WebView) - +class OmniboxPopupPresenter : public views::ViewObserver { public: OmniboxPopupPresenter(LocationBarView* location_bar_view, OmniboxController* controller); @@ -48,37 +46,39 @@ // Returns nullptr if handler is not ready. WebuiOmniboxHandler* GetHandler(); - // views::View: - void AddedToWidget() override; - - // views::WidgetObserver: - void OnWidgetDestroyed(views::Widget* widget) override; - // views::ViewObserver: - void OnViewBoundsChanged(View* observed_view) override; - - // content::WebContentsDelegate: - void ResizeDueToAutoResize(content::WebContents* source, - const gfx::Size& new_size) override; + void OnViewBoundsChanged(views::View* observed_view) override; void SetWidgetContentHeight(int content_height); private: friend class OmniboxPopupViewWebUITest; + void OnWidgetClosed(views::Widget::ClosedReason closed_reason); + // Tells whether the WebUI handler is loaded and ready to receive calls. bool IsHandlerReady(); // Remove observation and reset widget, optionally requesting it to close. - void ReleaseWidget(bool close); + void ReleaseWidget(); + + // Returns the webui content, either from the owned pointer or from the + // content of the widget_. + OmniboxPopupWebUIContent* GetOmniboxPopupWebUIContent(); // The location bar view that owns `this`. const raw_ptr<LocationBarView> location_bar_view_; + // The Omnibox WebUI popup contents. It is held here when the widget_ isn't + // being shown. + std::unique_ptr<OmniboxPopupWebUIContent> owned_omnibox_popup_webui_content_; + + // The controller for the Omnibox. + raw_ptr<OmniboxController> controller_ = nullptr; + // The popup widget that contains this WebView. Created and closed by `this`; // owned and destroyed by the OS. - // TODO(crbug.com/40232479): Migrate this to CLIENT_OWNS_WIDGET. - raw_ptr<views::Widget> widget_ = nullptr; + std::unique_ptr<views::Widget> widget_; // Whether any call to `GetHandler` has been made. bool requested_handler_ = false;
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.cc b/chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.cc new file mode 100644 index 0000000..61667b5 --- /dev/null +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.cc
@@ -0,0 +1,94 @@ +// 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/ui/views/omnibox/omnibox_popup_webui_content.h" + +#include "base/feature_list.h" +#include "base/metrics/histogram_functions.h" +#include "base/metrics/histogram_macros.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/views/location_bar/location_bar_view.h" +#include "chrome/browser/ui/views/omnibox/omnibox_popup_presenter.h" +#include "chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h" +#include "chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.h" +#include "chrome/browser/ui/webui/omnibox_popup/omnibox_popup_web_contents_helper.h" +#include "chrome/common/webui_url_constants.h" +#include "components/omnibox/common/omnibox_features.h" +#include "components/zoom/zoom_controller.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/gfx/geometry/rounded_corners_f.h" + +OmniboxPopupWebUIContent::OmniboxPopupWebUIContent( + OmniboxPopupPresenter* presenter, + LocationBarView* location_bar_view, + OmniboxController* controller, + bool include_location_bar_cutout) + : views::WebView(location_bar_view->profile()), + location_bar_view_(location_bar_view), + omnibox_popup_presenter_(presenter), + include_location_bar_cutout_(include_location_bar_cutout) { + // Make the OmniboxController available to the OmniboxPopupUI. + OmniboxPopupWebContentsHelper::CreateForWebContents(GetWebContents()); + OmniboxPopupWebContentsHelper::FromWebContents(GetWebContents()) + ->set_omnibox_controller(controller); + + LoadInitialURL(GURL(chrome::kChromeUIOmniboxPopupURL)); +} + +OmniboxPopupWebUIContent::~OmniboxPopupWebUIContent() = default; + +WebuiOmniboxHandler* OmniboxPopupWebUIContent::GetHandler() { + const bool ready = IsHandlerReady(); + if (!requested_handler_) { + // Only log on first access. + requested_handler_ = true; + base::UmaHistogramBoolean("Omnibox.WebUI.HandlerReadyOnFirstAccess", ready); + } + if (!ready) { + return nullptr; + } + OmniboxPopupUI* omnibox_popup_ui = static_cast<OmniboxPopupUI*>( + GetWebContents()->GetWebUI()->GetController()); + return omnibox_popup_ui->handler(); +} + +void OmniboxPopupWebUIContent::AddedToWidget() { + views::WebView::AddedToWidget(); + const float corner_radius = + views::LayoutProvider::Get()->GetCornerRadiusMetric( + views::ShapeContextTokens::kOmniboxExpandedRadius); + gfx::RoundedCornersF rounded_corner_radii = + gfx::RoundedCornersF(include_location_bar_cutout_ ? 0 : corner_radius, + include_location_bar_cutout_ ? 0 : corner_radius, + corner_radius, corner_radius); + holder()->SetCornerRadii(rounded_corner_radii); + + // Manually set zoom level, since any zooming is undesirable in the omnibox. + auto* zoom_controller = + zoom::ZoomController::FromWebContents(GetWebContents()); + if (!zoom_controller) { + // Create ZoomController manually, if not already exists, because it is + // not automatically created when the WebUI has not been opened in a tab. + zoom_controller = + zoom::ZoomController::CreateForWebContents(GetWebContents()); + } + zoom_controller->SetZoomMode(zoom::ZoomController::ZOOM_MODE_ISOLATED); + zoom_controller->SetZoomLevel(0); +} + +void OmniboxPopupWebUIContent::ResizeDueToAutoResize( + content::WebContents* source, + const gfx::Size& new_size) { + omnibox_popup_presenter_->SetWidgetContentHeight(new_size.height()); +} + +bool OmniboxPopupWebUIContent::IsHandlerReady() { + OmniboxPopupUI* omnibox_popup_ui = static_cast<OmniboxPopupUI*>( + GetWebContents()->GetWebUI()->GetController()); + return omnibox_popup_ui->handler() && + omnibox_popup_ui->handler()->IsRemoteBound(); +} + +BEGIN_METADATA(OmniboxPopupWebUIContent) +END_METADATA
diff --git a/chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.h b/chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.h new file mode 100644 index 0000000..cb9a219 --- /dev/null +++ b/chrome/browser/ui/views/omnibox/omnibox_popup_webui_content.h
@@ -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. + +#ifndef CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_WEBUI_CONTENT_H_ +#define CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_WEBUI_CONTENT_H_ + +#include "base/memory/raw_ptr.h" +#include "base/scoped_observation.h" +#include "chrome/browser/ui/webui/searchbox/webui_omnibox_handler.h" +#include "content/public/browser/render_frame_host.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" +#include "ui/views/controls/webview/webview.h" +#include "ui/views/view_observer.h" +#include "ui/views/widget/widget.h" + +class LocationBarView; +class OmniboxController; +class OmniboxPopupPresenter; + +// The content WebView for the popup of a WebUI Omnibox. +class OmniboxPopupWebUIContent : public views::WebView { + METADATA_HEADER(OmniboxPopupWebUIContent, views::WebView) + public: + OmniboxPopupWebUIContent() = delete; + OmniboxPopupWebUIContent(OmniboxPopupPresenter* presenter, + LocationBarView* location_bar_view, + OmniboxController* controller, + bool include_location_bar_cutout); + OmniboxPopupWebUIContent(const OmniboxPopupWebUIContent&) = delete; + OmniboxPopupWebUIContent& operator=(const OmniboxPopupWebUIContent&) = delete; + ~OmniboxPopupWebUIContent() override; + + // Get the handler for communicating with the WebUI interface. + // Returns nullptr if handler is not ready. + WebuiOmniboxHandler* GetHandler(); + + // Tells whether the WebUI handler is loaded and ready to receive calls. + bool IsHandlerReady(); + + // views::View: + void AddedToWidget() override; + + // content::WebContentsDelegate: + void ResizeDueToAutoResize(content::WebContents* source, + const gfx::Size& new_size) override; + + private: + raw_ptr<LocationBarView> location_bar_view_ = nullptr; + raw_ptr<OmniboxPopupPresenter> omnibox_popup_presenter_ = nullptr; + + // Whether any call to `GetHandler` has been made. + bool requested_handler_ = false; + + // Whether or not the WebUI popup includes the `location_bar_view` cutout. + bool include_location_bar_cutout_ = true; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_OMNIBOX_OMNIBOX_POPUP_WEBUI_CONTENT_H_
diff --git a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc index ee2ea7a..69d062e9 100644 --- a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc +++ b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.cc
@@ -4,6 +4,9 @@ #include "chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h" +#include <memory> +#include <utility> + #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/memory/raw_ptr.h" @@ -308,6 +311,15 @@ return views::BubbleBorder::GetBorderAndShadowInsets(kElevation); } +std::unique_ptr<views::View> RoundedOmniboxResultsFrame::ExtractContents() { + auto contents = std::exchange(contents_, nullptr); + return contents_host_->RemoveChildViewT<views::View>(contents); +} + +views::View* RoundedOmniboxResultsFrame::GetContents() { + return contents_; +} + void RoundedOmniboxResultsFrame::Layout(PassKey) { // This is called when the Widget resizes due to results changing. Resizing // the Widget is fast on ChromeOS, but slow on other platforms, and can't be
diff --git a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h index b2238d2..823cb66 100644 --- a/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h +++ b/chrome/browser/ui/views/omnibox/rounded_omnibox_results_frame.h
@@ -5,6 +5,8 @@ #ifndef CHROME_BROWSER_UI_VIEWS_OMNIBOX_ROUNDED_OMNIBOX_RESULTS_FRAME_H_ #define CHROME_BROWSER_UI_VIEWS_OMNIBOX_ROUNDED_OMNIBOX_RESULTS_FRAME_H_ +#include <memory> + #include "base/memory/raw_ptr.h" #include "ui/base/metadata/metadata_header_macros.h" #include "ui/gfx/geometry/insets.h" @@ -39,6 +41,12 @@ // Returns the blur region taken up by the Omnibox popup shadows. static gfx::Insets GetShadowInsets(); + // Removes the `contents_` view and returns ownership to the caller. + std::unique_ptr<views::View> ExtractContents(); + + // Returns the `contents_` view. + views::View* GetContents(); + // views::View: void Layout(PassKey) override; void AddedToWidget() override;
diff --git a/chrome/browser/ui/views/page_action/zoom_view.cc b/chrome/browser/ui/views/page_action/zoom_view.cc index 04aa706..c9e13f6 100644 --- a/chrome/browser/ui/views/page_action/zoom_view.cc +++ b/chrome/browser/ui/views/page_action/zoom_view.cc
@@ -6,14 +6,10 @@ #include "base/i18n/number_formatting.h" #include "chrome/app/vector_icons/vector_icons.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/view_ids.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #include "chrome/grit/generated_resources.h" #include "components/omnibox/browser/location_bar_model.h" -#include "components/tabs/public/tab_interface.h" #include "components/zoom/zoom_controller.h" #include "ui/accessibility/ax_node_data.h" #include "ui/base/l10n/l10n_util.h" @@ -22,23 +18,6 @@ #include "ui/gfx/geometry/size.h" #include "ui/views/accessibility/view_accessibility.h" -namespace { - -ZoomBubbleCoordinator* GetZoomBubbleCoordinator( - content::WebContents* web_contents) { - if (!web_contents) { - return nullptr; - } - - auto* tab_interface = tabs::TabInterface::GetFromContents(web_contents); - CHECK(tab_interface); - - auto* bwi = tab_interface->GetBrowserWindowInterface(); - return ZoomBubbleCoordinator::From(bwi); -} - -} // namespace - ZoomView::ZoomView(IconLabelBubbleView::Delegate* icon_label_bubble_delegate, PageActionIconView::Delegate* page_action_icon_delegate) : PageActionIconView(nullptr, @@ -97,9 +76,6 @@ return; } - auto* zoom_bubble_coordinator = GetZoomBubbleCoordinator(web_contents); - CHECK(zoom_bubble_coordinator); - if (ShouldBeVisible(can_show_bubble)) { zoom::ZoomController* zoom_controller = zoom::ZoomController::FromWebContents(web_contents); @@ -120,34 +96,26 @@ SetVisible(true); if (can_show_bubble) { - zoom_bubble_coordinator->Show(web_contents, ZoomBubbleView::AUTOMATIC); + ZoomBubbleView::ShowBubble(web_contents, ZoomBubbleView::AUTOMATIC); } else { - zoom_bubble_coordinator->RefreshIfShowing(web_contents); + ZoomBubbleView::RefreshBubbleIfShowing(web_contents); } } else { // Close the bubble first to ensure focus is not lost when SetVisible(false) // is called. See crbug.com/913829. if (HasAssociatedBubble()) { - zoom_bubble_coordinator->Hide(); + ZoomBubbleView::CloseCurrentBubble(); } SetVisible(false); } } void ZoomView::OnExecuting(PageActionIconView::ExecuteSource source) { - auto* zoom_bubble_coordinator = GetZoomBubbleCoordinator(GetWebContents()); - CHECK(zoom_bubble_coordinator); - - zoom_bubble_coordinator->Show(GetWebContents(), ZoomBubbleView::USER_GESTURE); + ZoomBubbleView::ShowBubble(GetWebContents(), ZoomBubbleView::USER_GESTURE); } views::BubbleDialogDelegate* ZoomView::GetBubble() const { - auto* zoom_bubble_coordinator = GetZoomBubbleCoordinator(GetWebContents()); - if (!zoom_bubble_coordinator) { - return nullptr; - } - - return zoom_bubble_coordinator->bubble(); + return ZoomBubbleView::GetZoomBubble(); } const gfx::VectorIcon& ZoomView::GetVectorIcon() const {
diff --git a/chrome/browser/ui/views/page_action/zoom_view_browsertest.cc b/chrome/browser/ui/views/page_action/zoom_view_browsertest.cc index 52e2351..9043f16 100644 --- a/chrome/browser/ui/views/page_action/zoom_view_browsertest.cc +++ b/chrome/browser/ui/views/page_action/zoom_view_browsertest.cc
@@ -5,17 +5,13 @@ #include "chrome/browser/ui/actions/chrome_action_id.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/page_action/page_action_view.h" #include "chrome/test/base/in_process_browser_test.h" #include "content/public/test/browser_test.h" -#include "ui/views/test/widget_test.h" using ZoomViewBrowserTest = InProcessBrowserTest; @@ -33,31 +29,25 @@ auto* zoom_icon = GetZoomView(browser()); auto* second_zoom_icon = GetZoomView(CreateBrowser(browser()->profile())); - ZoomBubbleCoordinator* zoom_bubble_coordinator = - ZoomBubbleCoordinator::From(browser()); - // Initially no icon. - EXPECT_FALSE(zoom_bubble_coordinator->bubble()); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); EXPECT_FALSE(zoom_icon->GetVisible()); EXPECT_FALSE(second_zoom_icon->GetVisible()); // Zooming in one browser should show the icon in all browsers on the same // URL. chrome::Zoom(browser(), content::PAGE_ZOOM_IN); - EXPECT_TRUE(zoom_bubble_coordinator->bubble()); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); EXPECT_TRUE(zoom_icon->GetVisible()); EXPECT_TRUE(second_zoom_icon->GetVisible()); - views::test::WidgetDestroyedWaiter waiter( - zoom_bubble_coordinator->bubble()->GetWidget()); - zoom_bubble_coordinator->Hide(); - waiter.Wait(); - EXPECT_FALSE(zoom_bubble_coordinator->bubble()); + ZoomBubbleView::CloseCurrentBubble(); + EXPECT_FALSE(ZoomBubbleView::GetZoomBubble()); // Clearing the zoom should clear the icon for all browsers on the URL except // the one where the interaction occurred because the bubble is showing there. chrome::Zoom(browser(), content::PAGE_ZOOM_RESET); - EXPECT_TRUE(zoom_bubble_coordinator->bubble()); + EXPECT_TRUE(ZoomBubbleView::GetZoomBubble()); EXPECT_TRUE(zoom_icon->GetVisible()); EXPECT_FALSE(second_zoom_icon->GetVisible()); }
diff --git a/chrome/browser/ui/views/profiles/profile_menu_view_ui_browsertest.cc b/chrome/browser/ui/views/profiles/profile_menu_view_ui_browsertest.cc index 7216c5a..b8e2f3e7 100644 --- a/chrome/browser/ui/views/profiles/profile_menu_view_ui_browsertest.cc +++ b/chrome/browser/ui/views/profiles/profile_menu_view_ui_browsertest.cc
@@ -502,7 +502,7 @@ if (new_browser) { ASSERT_NE(new_browser, browser()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(new_browser); ASSERT_EQ(new_browser, browser()); }
diff --git a/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_interactive_uitest.cc b/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_interactive_uitest.cc index c93bc07..c8208d1 100644 --- a/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_interactive_uitest.cc +++ b/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_interactive_uitest.cc
@@ -302,6 +302,25 @@ RunTestSequence(EnsureNotPresent(ConfirmInfoBar::kInfoBarElementId)); } +// Test that the session restore infobar is not shown on a new tab after the +// pref is changed. +IN_PROC_BROWSER_TEST_P(SessionRestoreInfobarInteractiveTest, + InfobarNotShownOnNewTabAfterPrefChange) { + CreateInfobar(browser(), false); + RunTestSequence(WaitForShow(ConfirmInfoBar::kInfoBarElementId), + // Change the pref to continue where you left off. + Do([this]() { + browser()->profile()->GetPrefs()->SetInteger( + prefs::kRestoreOnStartup, 1); + }), + // The infobar should be hidden after the pref change. + WaitForHide(ConfirmInfoBar::kInfoBarElementId), + // Open a new tab. + AddInstrumentedTab(kSecondTabContents, GURL("about:blank")), + // Ensure the infobar is not present on the new tab. + EnsureNotPresent(ConfirmInfoBar::kInfoBarElementId)); +} + INSTANTIATE_TEST_SUITE_P(All, SessionRestoreInfobarInteractiveTest, testing::Bool());
diff --git a/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.cc b/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.cc index 4b47738..e7a7249 100644 --- a/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.cc +++ b/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.cc
@@ -19,9 +19,12 @@ #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_delegate.h" +#include "chrome/common/pref_names.h" #include "components/infobars/content/content_infobar_manager.h" #include "components/infobars/core/confirm_infobar_delegate.h" #include "components/infobars/core/infobar.h" +#include "components/prefs/pref_change_registrar.h" +#include "components/prefs/pref_service.h" #include "content/public/browser/web_contents.h" namespace session_restore_infobar { @@ -43,6 +46,14 @@ profile_->AddObserver(this); message_type_ = message_type; + pref_change_registrar_ = std::make_unique<PrefChangeRegistrar>(); + pref_change_registrar_->Init(profile_->GetPrefs()); + pref_change_registrar_->Add( + prefs::kRestoreOnStartup, + base::BindRepeating( + &SessionRestoreInfoBarManager::OnSessionRestorePreferenceChanged, + base::Unretained(this))); + InitTabStripTracker(); } @@ -52,6 +63,7 @@ } browser_tab_strip_tracker_.reset(); + pref_change_registrar_.reset(); // Repeatedly remove the first infobar. OnInfoBarRemoved will be called, // which erases the infobar from the map. This continues until the map is @@ -157,4 +169,12 @@ CloseAllInfoBars(); } +void SessionRestoreInfoBarManager::OnSessionRestorePreferenceChanged() { + if (!profile_->GetPrefs() + ->FindPreference(prefs::kRestoreOnStartup) + ->IsDefaultValue()) { + CloseAllInfoBars(); + } +} + } // namespace session_restore_infobar
diff --git a/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.h b/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.h index 596481e..8a285b2 100644 --- a/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.h +++ b/chrome/browser/ui/views/session_restore_infobar/session_restore_infobar_manager.h
@@ -28,6 +28,8 @@ class InfoBar; } +class PrefChangeRegistrar; + namespace session_restore_infobar { // This class is responsible for managing the session restore infobar. It @@ -72,6 +74,9 @@ // ProfileObserver: void OnProfileWillBeDestroyed(Profile* profile) override; + // Callback for session restore preference changes. + void OnSessionRestorePreferenceChanged(); + // Helper methods void InitTabStripTracker(); void CreateInfoBarForWebContents(content::WebContents* web_contents); @@ -87,6 +92,8 @@ bool user_initiated_info_bar_close_pending_ = false; SessionRestoreInfoBarDelegate::InfobarMessageType message_type_ = SessionRestoreInfoBarDelegate::InfobarMessageType::kNone; + + std::unique_ptr<PrefChangeRegistrar> pref_change_registrar_; }; } // namespace session_restore_infobar
diff --git a/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.cc b/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.cc index 8c3b1b6..f787daf 100644 --- a/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.cc +++ b/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.cc
@@ -17,6 +17,7 @@ #include "chrome/browser/ui/browser_actions.h" #include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" +#include "chrome/browser/ui/views/side_panel/side_panel.h" #include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry.h" #include "chrome/browser/ui/views/side_panel/side_panel_entry_scope.h" @@ -48,10 +49,7 @@ : tab_(tab), side_panel_registry_(side_panel_registry), glic_action_(GetGlicActionItem( - tab->GetBrowserWindowInterface()->GetActions()->root_action_item())), - side_panel_coordinator_(tab->GetBrowserWindowInterface() - ->GetFeatures() - .side_panel_coordinator()) { + tab->GetBrowserWindowInterface()->GetActions()->root_action_item())) { CHECK(base::FeatureList::IsEnabled(features::kGlicMultiInstance)); auto* glic_service = GlicKeyedServiceFactory::GetGlicKeyedService( tab->GetBrowserWindowInterface()->GetProfile()); @@ -62,6 +60,9 @@ if (glic_service->enabling().IsAllowed()) { CreateAndRegisterEntry(); } + tab_deactivated_subscription_ = + tab_->RegisterWillDeactivate(base::BindRepeating( + &GlicSidePanelCoordinator::OnTabDeactivated, base::Unretained(this))); } GlicSidePanelCoordinator::~GlicSidePanelCoordinator() = default; @@ -81,19 +82,58 @@ entry->set_should_show_header(false); entry->set_should_show_ephemerally_in_toolbar(false); entry->AddObserver(this); + entry_ = entry->GetWeakPtr(); side_panel_registry_->Register(std::move(entry)); } +void GlicSidePanelCoordinator::Show() { + auto* window_side_panel_coordinator = GetWindowSidePanelCoordinator(); + if (!window_side_panel_coordinator || !entry_) { + return; + } + if (!tab_->IsActivated()) { + if (entry_) { + // The tab is in the background, so we just mark it for showing the glic + // side panel when it becomes the active tab. eg. This flow can be + // encountered when a background tab is bound via daisy chaining. + side_panel_registry_->SetActiveEntry(entry_.get()); + } + return; + } + window_side_panel_coordinator->Show(SidePanelEntry::Id::kGlic); +} + +void GlicSidePanelCoordinator::Close() { + auto* window_side_panel_coordinator = GetWindowSidePanelCoordinator(); + if (!window_side_panel_coordinator || !IsShowing()) { + return; + } + window_side_panel_coordinator->Close(); +} + +bool GlicSidePanelCoordinator::IsShowing() const { + return state_ == State::kShown; +} + void GlicSidePanelCoordinator::OnEntryWillHide( SidePanelEntry* entry, SidePanelEntryHideReason reason) { CHECK_EQ(entry->key().id(), SidePanelEntry::Id::kGlic); - visibility_changed_callbacks_.Notify(false); + state_ = State::kClosed; + NotifyStateChanged(); } void GlicSidePanelCoordinator::OnEntryShown(SidePanelEntry* entry) { CHECK_EQ(entry->key().id(), SidePanelEntry::Id::kGlic); - visibility_changed_callbacks_.Notify(true); + state_ = State::kShown; + NotifyStateChanged(); +} + +void GlicSidePanelCoordinator::OnTabDeactivated(tabs::TabInterface* tab) { + if (IsShowing()) { + state_ = State::kHidden; + NotifyStateChanged(); + } } void GlicSidePanelCoordinator::OnGlicEnabledChanged() { @@ -111,12 +151,13 @@ } else { SidePanelEntry::Key glic_key = SidePanelEntry::Key(SidePanelEntry::Id::kGlic); - if (side_panel_coordinator_->IsSidePanelEntryShowing(glic_key)) { - side_panel_coordinator_->Close(); + auto* window_side_panel_coordinator = GetWindowSidePanelCoordinator(); + if (window_side_panel_coordinator && + window_side_panel_coordinator->IsSidePanelEntryShowing(glic_key)) { + window_side_panel_coordinator->Close(); } - SidePanelEntry* glic_entry = side_panel_registry_->GetEntryForKey(glic_key); - if (glic_entry) { - glic_entry->RemoveObserver(this); + if (entry_) { + entry_->RemoveObserver(this); } side_panel_registry_->Deregister(glic_key); } @@ -142,9 +183,9 @@ return glic_container; } -base::CallbackListSubscription GlicSidePanelCoordinator::AddVisibilityCallback( - base::RepeatingCallback<void(bool isShowing)> callback) { - return visibility_changed_callbacks_.Add(std::move(callback)); +base::CallbackListSubscription GlicSidePanelCoordinator::AddStateCallback( + base::RepeatingCallback<void(State state)> callback) { + return state_changed_callbacks_.Add(std::move(callback)); } void GlicSidePanelCoordinator::SetContentsView( @@ -166,4 +207,16 @@ return features::kGlicSidePanelMinWidth.Get(); } +SidePanelCoordinator* GlicSidePanelCoordinator::GetWindowSidePanelCoordinator() + const { + if (auto* window = tab_->GetBrowserWindowInterface()) { + return window->GetFeatures().side_panel_coordinator(); + } + return nullptr; +} + +void GlicSidePanelCoordinator::NotifyStateChanged() { + state_changed_callbacks_.Notify(state_); +} + } // namespace glic
diff --git a/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.h b/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.h index a415ca9..148f8f33 100644 --- a/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.h +++ b/chrome/browser/ui/views/side_panel/glic/glic_side_panel_coordinator.h
@@ -41,13 +41,31 @@ // Create and register the Glic side panel entry. void CreateAndRegisterEntry(); - using VisibilityCallback = base::RepeatingCallback<void(bool isVisible)>; + // The current state of the Glic side panel. + enum class State { + // The side panel is showing in the foreground. + kShown, + // The side panel is in the background, but it will show if its tab becomes + // active. + kHidden, + // The side panel is closed and will only be shown if explicitly requested. + kClosed, + }; + + // Show the Glic side panel. + void Show(); + + // Close the Glic side panel. + void Close(); + + // Returns true if the Glic side panel is currently the active entry. + bool IsShowing() const; // Registers `callback` to be called when panel visibility is updated. - base::CallbackListSubscription AddVisibilityCallback( - VisibilityCallback callback); + base::CallbackListSubscription AddStateCallback( + base::RepeatingCallback<void(State state)> callback); - // Set the content to display in the Glic side panel. + // Sets the content view for the Glic side panel. void SetContentsView(std::unique_ptr<views::View> contents_view); // Returns preferred side panel width. Not guaranteed to be used if user @@ -59,24 +77,38 @@ protected: // Called when the Glic enabled status changes for `profile_`. void OnGlicEnabledChanged(); - // `SidePanelEntryObserver`: + + // SidePanelEntryObserver: void OnEntryWillHide(SidePanelEntry* entry, SidePanelEntryHideReason reason) override; void OnEntryShown(SidePanelEntry* entry) override; private: + void OnTabDeactivated(tabs::TabInterface* tab); + + // Returns the SidePanelCoordinator for the window associated with `tab_`. + SidePanelCoordinator* GetWindowSidePanelCoordinator() const; + // Gets the Glic WebView from the Glic service. std::unique_ptr<views::View> CreateView(SidePanelEntryScope& scope); + void NotifyStateChanged(); + raw_ptr<tabs::TabInterface> tab_ = nullptr; raw_ptr<SidePanelRegistry> side_panel_registry_ = nullptr; raw_ptr<actions::ActionItem> glic_action_ = nullptr; - raw_ptr<SidePanelCoordinator> side_panel_coordinator_ = nullptr; + base::WeakPtr<SidePanelEntry> entry_; base::CallbackListSubscription on_glic_enabled_changed_subscription_; - base::RepeatingCallbackList<void(bool isShowing)> - visibility_changed_callbacks_; - std::unique_ptr<views::View> contents_view_; + base::RepeatingCallbackList<void(State state)> state_changed_callbacks_; + base::CallbackListSubscription tab_deactivated_subscription_; + + State state_ = State::kHidden; + + // Tracks the glic container view. views::ViewTracker glic_container_tracker_; + + // Caches the contents view if it's set before the container is created. + std::unique_ptr<views::View> contents_view_; }; } // namespace glic
diff --git a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller_interactive_uitest.cc b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller_interactive_uitest.cc index d56f7b5..03735186 100644 --- a/chrome/browser/ui/views/tabs/dragging/tab_drag_controller_interactive_uitest.cc +++ b/chrome/browser/ui/views/tabs/dragging/tab_drag_controller_interactive_uitest.cc
@@ -3958,7 +3958,7 @@ HomeTabAddedToEveryWindow) { // Install tabbed web app. webapps::AppId app_id = InstallMockApp(/*add_home_tab=*/true); - Browser* app_browser = + BrowserWindowInterface* const app_browser = web_app::LaunchWebAppBrowser(browser()->profile(), app_id); ASSERT_EQ(2u, browser_list()->size()); @@ -3966,7 +3966,7 @@ CloseBrowserSynchronously(browser()); ASSERT_EQ(1u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser); ASSERT_EQ(app_browser, browser()); AddTabsAndResetBrowser(browser(), 1, GURL("https://www.example.com/newpage")); @@ -4015,7 +4015,7 @@ MAYBE_CantDragHomeTab) { // Install tabbed web app. webapps::AppId app_id = InstallMockApp(/*add_home_tab=*/true); - Browser* app_browser = + BrowserWindowInterface* const app_browser = web_app::LaunchWebAppBrowser(browser()->profile(), app_id); ASSERT_EQ(2u, browser_list()->size()); @@ -4023,7 +4023,7 @@ CloseBrowserSynchronously(browser()); ASSERT_EQ(1u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser); ASSERT_EQ(app_browser, browser()); AddTabsAndResetBrowser(browser(), 1, GURL("https://www.example.com/newpage")); @@ -4050,7 +4050,7 @@ NoHomeTab) { // Install tabbed web app. webapps::AppId app_id = InstallMockApp(/*add_home_tab=*/false); - Browser* app_browser = + BrowserWindowInterface* const app_browser = web_app::LaunchWebAppBrowser(browser()->profile(), app_id); ASSERT_EQ(2u, browser_list()->size()); @@ -4058,7 +4058,7 @@ CloseBrowserSynchronously(browser()); ASSERT_EQ(1u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser); ASSERT_EQ(app_browser, browser()); AddTabsAndResetBrowser(browser(), 1, GURL("https://www.example.com/newpage")); @@ -4865,7 +4865,7 @@ // Close normal browser since other code expects only 1 browser to start. CloseBrowserSynchronously(browser()); ASSERT_EQ(1u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser); ASSERT_EQ(app_browser, browser()); EXPECT_EQ(BrowserWindowInterface::Type::TYPE_APP, browser()->GetType()); AddTabsAndResetBrowser(browser(), 1, GetAppUrl()); @@ -4907,7 +4907,7 @@ // Close normal browser since other code expects only 1 browser to start. CloseBrowserSynchronously(browser()); ASSERT_EQ(2u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser1); ASSERT_EQ(app_browser1, browser()); AddTabsAndResetBrowser(browser(), 1, GetAppUrl()); @@ -5880,7 +5880,7 @@ // Close normal browser. CloseBrowserSynchronously(browser()); ASSERT_EQ(1u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser); ASSERT_EQ(app_browser, browser()); EXPECT_EQ(Browser::Type::TYPE_APP, browser()->GetType()); @@ -5914,7 +5914,7 @@ // Close normal browser. CloseBrowserSynchronously(browser()); ASSERT_EQ(1u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser); ASSERT_EQ(app_browser, browser()); EXPECT_EQ(Browser::Type::TYPE_APP, browser()->GetType()); @@ -5943,7 +5943,7 @@ // Close normal browser. CloseBrowserSynchronously(browser()); ASSERT_EQ(1u, browser_list()->size()); - SelectFirstBrowser(); + SetBrowser(app_browser); ASSERT_EQ(app_browser, browser()); EXPECT_EQ(Browser::Type::TYPE_APP, browser()->GetType());
diff --git a/chrome/browser/ui/views/tabs/glic_button.cc b/chrome/browser/ui/views/tabs/glic_button.cc index c48353e..2683bc7 100644 --- a/chrome/browser/ui/views/tabs/glic_button.cc +++ b/chrome/browser/ui/views/tabs/glic_button.cc
@@ -22,6 +22,7 @@ #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/color/chrome_color_id.h" #include "chrome/browser/ui/user_education/browser_user_education_interface.h" +#include "chrome/browser/ui/views/interaction/browser_elements_views.h" #include "chrome/browser/ui/views/tabs/tab_strip_control_button.h" #include "chrome/browser/ui/views/tabs/tab_strip_controller.h" #include "chrome/common/buildflags.h" @@ -205,6 +206,15 @@ GlicButton::~GlicButton() = default; +// Static +GlicButton* GlicButton::FromBrowser(BrowserWindowInterface* browser) { + if (!browser) { + return nullptr; + } + return BrowserElementsViews::From(browser)->GetViewAs<glic::GlicButton>( + kGlicButtonElementId); +} + void GlicButton::SetNudgeLabel(std::string label) { if (!EntrypointVariationsEnabled()) { initial_width_ = GetLayoutManager()->GetPreferredSize(this).width();
diff --git a/chrome/browser/ui/views/tabs/glic_button.h b/chrome/browser/ui/views/tabs/glic_button.h index 99ee85a..f81c39f 100644 --- a/chrome/browser/ui/views/tabs/glic_button.h +++ b/chrome/browser/ui/views/tabs/glic_button.h
@@ -18,6 +18,7 @@ #include "chrome/browser/glic/fre/glic_fre.mojom.h" #endif // BUILDFLAG(ENABLE_GLIC) +class BrowserWindowInterface; class PrefService; namespace glic { @@ -42,6 +43,8 @@ GlicButton& operator=(const GlicButton&) = delete; ~GlicButton() override; + static GlicButton* FromBrowser(BrowserWindowInterface* browser); + void SetNudgeLabel(std::string label); void RestoreDefaultLabel();
diff --git a/chrome/browser/ui/views/zoom/BUILD.gn b/chrome/browser/ui/views/zoom/BUILD.gn index 6d5cf3d..572c2716 100644 --- a/chrome/browser/ui/views/zoom/BUILD.gn +++ b/chrome/browser/ui/views/zoom/BUILD.gn
@@ -17,7 +17,6 @@ ":zoom", "//chrome/browser/ui", "//chrome/browser/ui:ui_features", - "//chrome/browser/ui/browser_window", "//chrome/browser/ui/views/frame:toolbar_button_provider", "//chrome/browser/ui/views/location_bar", "//chrome/browser/ui/views/page_action", @@ -35,7 +34,6 @@ deps = [ "//chrome/browser/ui", "//chrome/browser/ui:ui_features", - "//chrome/browser/ui/browser_window", "//chrome/browser/ui/views/frame:toolbar_button_provider", "//chrome/browser/ui/views/location_bar", "//chrome/browser/ui/views/page_action",
diff --git a/chrome/browser/ui/views/zoom/zoom_view_controller.cc b/chrome/browser/ui/views/zoom/zoom_view_controller.cc index 1a94dc8..556b356 100644 --- a/chrome/browser/ui/views/zoom/zoom_view_controller.cc +++ b/chrome/browser/ui/views/zoom/zoom_view_controller.cc
@@ -10,13 +10,10 @@ #include "chrome/app/vector_icons/vector_icons.h" #include "chrome/browser/ui/actions/chrome_action_id.h" #include "chrome/browser/ui/browser_actions.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/tabs/public/tab_features.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #include "chrome/browser/ui/views/page_action/page_action_controller.h" #include "chrome/browser/ui/views/page_action/page_action_view.h" @@ -101,15 +98,15 @@ CanBubbleBeVisible(prefer_to_show_bubble, is_at_default_zoom); if (can_bubble_be_visible) { if (prefer_to_show_bubble) { - GetBubbleCoordinator()->Show( + ZoomBubbleView::ShowBubble( GetWebContents(), from_user_gesture ? ZoomBubbleView::USER_GESTURE : ZoomBubbleView::AUTOMATIC); } else { - GetBubbleCoordinator()->RefreshIfShowing(GetWebContents()); + ZoomBubbleView::RefreshBubbleIfShowing(GetWebContents()); } } else { if (IsBubbleVisible()) { - GetBubbleCoordinator()->Hide(); + ZoomBubbleView::CloseCurrentBubble(); } } } @@ -139,9 +136,4 @@ return tab_interface_->GetContents(); } -ZoomBubbleCoordinator* ZoomViewController::GetBubbleCoordinator() { - return ZoomBubbleCoordinator::From( - tab_interface_->GetBrowserWindowInterface()); -} - } // namespace zoom
diff --git a/chrome/browser/ui/views/zoom/zoom_view_controller.h b/chrome/browser/ui/views/zoom/zoom_view_controller.h index 735016a..c418b23 100644 --- a/chrome/browser/ui/views/zoom/zoom_view_controller.h +++ b/chrome/browser/ui/views/zoom/zoom_view_controller.h
@@ -7,8 +7,6 @@ #include "components/tabs/public/tab_interface.h" -class ZoomBubbleCoordinator; - namespace content { class WebContents; } @@ -60,10 +58,6 @@ // Helper to retrieve the active WebContents from the tab. content::WebContents* GetWebContents() const; - // Returns the zoom bubble coordinator associated with the window owning this - // zoom page action. - ZoomBubbleCoordinator* GetBubbleCoordinator(); - // Because zoom settings are per-tab, we store the tab interface by reference. // The TabInterface is guaranteed valid for this object’s lifetime. const raw_ref<tabs::TabInterface> tab_interface_;
diff --git a/chrome/browser/ui/views/zoom/zoom_view_interactive_ui_tests.cc b/chrome/browser/ui/views/zoom/zoom_view_interactive_ui_tests.cc index 5f553d8..3b31f69f 100644 --- a/chrome/browser/ui/views/zoom/zoom_view_interactive_ui_tests.cc +++ b/chrome/browser/ui/views/zoom/zoom_view_interactive_ui_tests.cc
@@ -8,11 +8,9 @@ #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_commands.h" #include "chrome/browser/ui/browser_element_identifiers.h" -#include "chrome/browser/ui/browser_window/public/browser_window_features.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/frame/toolbar_button_provider.h" -#include "chrome/browser/ui/views/location_bar/zoom_bubble_coordinator.h" #include "chrome/browser/ui/views/location_bar/zoom_bubble_view.h" #include "chrome/browser/ui/views/page_action/page_action_icon_view.h" #include "chrome/browser/ui/views/page_action/page_action_view.h" @@ -82,16 +80,14 @@ DEFINE_LOCAL_STATE_IDENTIFIER_VALUE(ui::test::PollingStateObserver<bool>, kZoomBubbleVisible); - return Steps( - PollState(kZoomBubbleVisible, - [&, visible]() { - const bool is_visible = - ZoomBubbleCoordinator::From(browser())->bubble() != - nullptr; - return is_visible == visible; - }), - WaitForState(kZoomBubbleVisible, true), - StopObservingState(kZoomBubbleVisible)); + return Steps(PollState(kZoomBubbleVisible, + [&, visible]() { + bool is_visible = + ZoomBubbleView::GetZoomBubble() != nullptr; + return is_visible == visible; + }), + WaitForState(kZoomBubbleVisible, true), + StopObservingState(kZoomBubbleVisible)); } base::test::ScopedFeatureList scoped_feature_list_;
diff --git a/chrome/browser/ui/webui/BUILD.gn b/chrome/browser/ui/webui/BUILD.gn index d7ae711..bf36d6af 100644 --- a/chrome/browser/ui/webui/BUILD.gn +++ b/chrome/browser/ui/webui/BUILD.gn
@@ -65,6 +65,7 @@ "//chrome/browser/ui/webui/infobar_internals", "//chrome/browser/ui/webui/new_tab_footer", "//chrome/browser/ui/webui/privacy_sandbox", + "//chrome/browser/ui/webui/reload_button", "//chrome/browser/ui/webui_browser", ]
diff --git a/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc b/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc index 8472a678..e294e9c 100644 --- a/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc +++ b/chrome/browser/ui/webui/app_management/app_management_page_handler_unittest.cc
@@ -611,6 +611,56 @@ EXPECT_TRUE(overlapping_apps.empty()); } +TEST_P(AppManagementPageHandlerTestBase, GetSupportedLinksWithScopeExtensions) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + ::features::kPwaNavigationCapturingWithScopeExtensions); + auto web_app_info = web_app::WebAppInstallInfo::CreateWithStartUrlForTesting( + GURL("https://example.com/")); + web_app_info->title = u"app_name"; + web_app_info->scope_extensions = { + web_app::ScopeExtensionInfo::CreateForScope(GURL("https://sitea.com")), + web_app::ScopeExtensionInfo::CreateForScope( + GURL("https://app.siteb.com")), + web_app::ScopeExtensionInfo::CreateForScope(GURL("https://sitec.com"), + /*has_origin_wildcard=*/true), + web_app::ScopeExtensionInfo::CreateForScope( + GURL("https://sited.com/path")), + web_app::ScopeExtensionInfo::CreateForScope( + GURL("http://☃.net/")) /* Unicode */ + }; + web_app_info->validated_scope_extensions = web_app_info->scope_extensions; + web_app_info->scope_extensions.insert( + web_app::ScopeExtensionInfo::CreateForScope( + GURL("https://unvalidatedscope.com"))); + + web_app::WebAppInstallParams install_params; + // Skip origin association validation for testing. + install_params.skip_origin_association_validation = true; + + base::test::TestFuture<const webapps::AppId&, webapps::InstallResultCode> + future; + web_app::WebAppProvider* provider = + web_app::WebAppProvider::GetForTest(profile()); + provider->scheduler().InstallFromInfoWithParams( + std::move(web_app_info), /*overwrite_existing_manifest_fields=*/false, + webapps::WebappInstallSource::OMNIBOX_INSTALL_ICON, future.GetCallback(), + install_params); + + EXPECT_EQ(webapps::InstallResultCode::kSuccessNewInstall, + future.Get<webapps::InstallResultCode>()); + const webapps::AppId& app_id = future.Get<webapps::AppId>(); + + base::test::TestFuture<app_management::mojom::AppPtr> result; + handler()->GetApp(app_id, result.GetCallback()); + + EXPECT_THAT(result.Get()->supported_links, + testing::UnorderedElementsAre("sitea.com/*", "app.siteb.com/*", + "*.sitec.com/*", "sitec.com/*", + "sited.com/path*", "example.com/*", + "xn--n3h.net/*")); +} + #if !BUILDFLAG(IS_CHROMEOS) TEST_P(AppManagementPageHandlerTestBase, GetScopeExtensions) { auto web_app_info = web_app::WebAppInstallInfo::CreateWithStartUrlForTesting(
diff --git a/chrome/browser/ui/webui/app_management/web_app_settings_page_handler.cc b/chrome/browser/ui/webui/app_management/web_app_settings_page_handler.cc index 62e7c4d..0c70e63 100644 --- a/chrome/browser/ui/webui/app_management/web_app_settings_page_handler.cc +++ b/chrome/browser/ui/webui/app_management/web_app_settings_page_handler.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/web_applications/mojom/user_display_mode.mojom-shared.h" #include "chrome/browser/web_applications/web_app_command_scheduler.h" #include "chrome/browser/web_applications/web_app_provider.h" +#include "chrome/browser/web_applications/web_app_scope.h" #include "chrome/browser/web_applications/web_app_ui_manager.h" #include "chrome/browser/web_applications/web_app_utils.h" #include "chrome/common/chrome_features.h" @@ -33,24 +34,45 @@ namespace { +std::string FormatScope(const GURL& scope_url) { + std::string scope_str(scope_url.host()); + if (scope_url.has_port()) { + scope_str += ":"; + scope_str += scope_url.port(); + } + scope_str += scope_url.path().empty() ? "/" : scope_url.path(); + scope_str += "*"; + return scope_str; +} + std::vector<std::string> GetSupportedLinks(const std::string& app_id, web_app::WebAppProvider& provider) { - GURL app_scope = provider.registrar_unsafe().GetAppScope(app_id); - if (!web_app::IsValidScopeForLinkCapturing(app_scope)) { - return std::vector<std::string>(); + std::optional<web_app::WebAppScope> effective_scope = + provider.registrar_unsafe().GetEffectiveScope(app_id); + if (!effective_scope) { + return {}; } - std::string scope_str(app_scope.GetHost()); - if (app_scope.has_port()) { - scope_str += ":" + app_scope.GetPort(); + std::vector<std::string> supported_links; + if (base::FeatureList::IsEnabled( + features::kPwaNavigationCapturingWithScopeExtensions)) { + for (const auto& scope_extension : + effective_scope->validated_scope_extensions()) { + std::string formatted_scope = FormatScope(scope_extension.scope); + supported_links.push_back(formatted_scope); + if (scope_extension.has_origin_wildcard) { + supported_links.push_back("*." + formatted_scope); + } + } } - scope_str += app_scope.GetPath(); - if (scope_str.back() == '/') { - scope_str = scope_str + "*"; - } else { - scope_str = scope_str + "/*"; + + GURL app_scope = effective_scope->scope(); + if (!web_app::IsValidScopeForLinkCapturing(app_scope)) { + return supported_links; } - return {scope_str}; + + supported_links.push_back(FormatScope(app_scope)); + return supported_links; } std::string GetFormattedOrigin(const webapps::AppId& app_id,
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn b/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn index fa907e2..9d4bfa70 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn +++ b/chrome/browser/ui/webui/ash/settings/pages/device/BUILD.gn
@@ -82,7 +82,6 @@ sources = [ "device_keyboard_handler_unittest.cc", "device_section_unittest.cc", - "inputs_section_unittest.cc", ] deps = [
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc index ffdb12b..97f891f 100644 --- a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc +++ b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.cc
@@ -634,7 +634,7 @@ } bool InputsSection::ShouldShowEmojiSuggestionsSettings() const { - return pref_service_->GetBoolean(prefs::kEmojiSuggestionEnterpriseAllowed); + return false; } bool InputsSection::IsSpellCheckEnabled() const {
diff --git a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section_unittest.cc b/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section_unittest.cc deleted file mode 100644 index 5c731a4d..0000000 --- a/chrome/browser/ui/webui/ash/settings/pages/device/inputs_section_unittest.cc +++ /dev/null
@@ -1,101 +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. - -#include "chrome/browser/ui/webui/ash/settings/pages/device/inputs_section.h" - -#include "ash/constants/ash_features.h" -#include "ash/constants/ash_pref_names.h" -#include "base/command_line.h" -#include "base/memory/raw_ptr.h" -#include "base/test/scoped_feature_list.h" -#include "chrome/browser/ash/input_method/editor_geolocation_mock_provider.h" -#include "chrome/browser/ash/input_method/editor_geolocation_provider.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/ui/webui/ash/settings/search/search_tag_registry.h" -#include "chrome/grit/generated_resources.h" -#include "chrome/test/base/chrome_ash_test_base.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 "chromeos/components/magic_boost/test/fake_magic_boost_state.h" -#include "chromeos/constants/chromeos_features.h" -#include "chromeos/constants/chromeos_switches.h" -#include "components/prefs/testing_pref_service.h" -#include "components/spellcheck/browser/pref_names.h" -#include "components/sync_preferences/testing_pref_service_syncable.h" -#include "content/public/test/browser_task_environment.h" -#include "content/public/test/test_web_ui_data_source.h" - -namespace ash::settings { - -namespace { - -std::string GetSettingsSearchResultId(OsSettingsIdentifier id, int message_id) { - std::stringstream ss; - ss << id.setting << "," << message_id; - return ss.str(); -} - -} // namespace - -// Test for the inputs settings page. -class InputsSectionTest : public ChromeAshTestBase { - public: - InputsSectionTest() - : local_search_service_proxy_( - std::make_unique< - ash::local_search_service::LocalSearchServiceProxy>( - /*for_testing=*/true)), - search_tag_registry_(local_search_service_proxy_.get()) {} - - ~InputsSectionTest() override = default; - - TestingProfile* profile() { return &profile_; } - TestingPrefServiceSimple* pref_service() { return &pref_service_; } - ash::settings::SearchTagRegistry* search_tag_registry() { - return &search_tag_registry_; - } - - std::unique_ptr<InputsSection> inputs_section_; - - protected: - void SetUp() override { - pref_service()->registry()->RegisterBooleanPref( - prefs::kEmojiSuggestionEnterpriseAllowed, true); - pref_service()->registry()->RegisterBooleanPref( - spellcheck::prefs::kSpellCheckEnable, true); - - ChromeAshTestBase::SetUp(); - } - void TearDown() override { - inputs_section_.reset(); - ChromeAshTestBase::TearDown(); - } - - private: - std::unique_ptr<ash::local_search_service::LocalSearchServiceProxy> - local_search_service_proxy_; - ash::settings::SearchTagRegistry search_tag_registry_; - TestingPrefServiceSimple pref_service_; - TestingProfile profile_; -}; - -TEST_F(InputsSectionTest, SearchResultShouldIncludeEmojiSuggestion) { - auto mock_geolocation_provider = - std::make_unique<input_method::EditorGeolocationMockProvider>("us"); - input_method::EditorMediator editor_mediator( - profile(), std::move(mock_geolocation_provider)); - inputs_section_ = std::make_unique<InputsSection>( - profile(), search_tag_registry(), pref_service(), &editor_mediator); - OsSettingsIdentifier kEmojiSuggestionSettingId = { - .setting = chromeos::settings::mojom::Setting::kShowEmojiSuggestions}; - - std::string result_id = GetSettingsSearchResultId( - kEmojiSuggestionSettingId, - IDS_OS_SETTINGS_TAG_LANGUAGES_EMOJI_SUGGESTIONS); - - EXPECT_TRUE(search_tag_registry()->GetTagMetadata(result_id)); -} - -} // namespace ash::settings
diff --git a/chrome/browser/ui/webui/chrome_web_ui_configs.cc b/chrome/browser/ui/webui/chrome_web_ui_configs.cc index 746ec07..4bdba3f6 100644 --- a/chrome/browser/ui/webui/chrome_web_ui_configs.cc +++ b/chrome/browser/ui/webui/chrome_web_ui_configs.cc
@@ -42,6 +42,7 @@ #include "chrome/browser/ui/webui/policy/policy_ui.h" #include "chrome/browser/ui/webui/predictors/predictors_ui.h" #include "chrome/browser/ui/webui/privacy_sandbox/privacy_sandbox_internals_ui.h" +#include "chrome/browser/ui/webui/reload_button/reload_button_ui.h" #include "chrome/browser/ui/webui/saved_tab_groups_unsupported/saved_tab_groups_unsupported_ui.h" #include "chrome/browser/ui/webui/segmentation_internals/segmentation_internals_ui.h" #include "chrome/browser/ui/webui/signin_internals_ui.h" @@ -334,6 +335,7 @@ std::make_unique<commerce::ProductSpecificationsUIConfig>()); map.AddWebUIConfig(std::make_unique<ProfileInternalsUIConfig>()); map.AddWebUIConfig(std::make_unique<ReadingListUIConfig>()); + map.AddWebUIConfig(std::make_unique<ReloadButtonUIConfig>()); map.AddWebUIConfig(std::make_unique<SearchEngineChoiceUIConfig>()); map.AddWebUIConfig(std::make_unique<settings::SettingsUIConfig>()); map.AddWebUIConfig(std::make_unique<ShoppingInsightsSidePanelUIConfig>());
diff --git a/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc b/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc index 138a16b8..c5efd6f 100644 --- a/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc +++ b/chrome/browser/ui/webui/omnibox_popup/omnibox_popup_ui.cc
@@ -23,6 +23,7 @@ #include "chrome/grit/omnibox_popup_resources.h" #include "chrome/grit/omnibox_popup_resources_map.h" #include "components/favicon_base/favicon_url_parser.h" +#include "components/omnibox/common/omnibox_features.h" #include "content/public/browser/web_ui_data_source.h" #include "ui/webui/color_change_listener/color_change_handler.h" #include "ui/webui/webui_util.h" @@ -44,8 +45,11 @@ source->AddBoolean("isTopChromeSearchbox", true); - webui::SetupWebUIDataSource(source, kOmniboxPopupResources, - IDR_OMNIBOX_POPUP_OMNIBOX_POPUP_HTML); + webui::SetupWebUIDataSource( + source, kOmniboxPopupResources, + base::FeatureList::IsEnabled(omnibox::kWebUIOmniboxFullPopup) + ? IDR_OMNIBOX_POPUP_OMNIBOX_POPUP_FULL_HTML + : IDR_OMNIBOX_POPUP_OMNIBOX_POPUP_HTML); webui::EnableTrustedTypesCSP(source); content::URLDataSource::Add(profile_,
diff --git a/chrome/browser/ui/webui/profile_helper_browsertest.cc b/chrome/browser/ui/webui/profile_helper_browsertest.cc index b268907..3a46ddf 100644 --- a/chrome/browser/ui/webui/profile_helper_browsertest.cc +++ b/chrome/browser/ui/webui/profile_helper_browsertest.cc
@@ -200,10 +200,11 @@ webui::DeleteProfileAtPath(original_browser->profile()->GetPath(), ProfileMetrics::DELETE_PROFILE_SETTINGS); ui_test_utils::WaitForBrowserToClose(original_browser); - content::RunAllTasksUntilIdle(); EXPECT_EQ(1u, browser_list->size()); - EXPECT_EQ(additional_profile, browser_list->get(0)->profile()); + BrowserWindowInterface* const additional_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); + EXPECT_EQ(additional_profile, additional_browser->GetProfile()); EXPECT_EQ(1u, storage.GetNumberOfProfiles()); }
diff --git a/chrome/browser/ui/webui/reload_button/BUILD.gn b/chrome/browser/ui/webui/reload_button/BUILD.gn new file mode 100644 index 0000000..4a869c6 --- /dev/null +++ b/chrome/browser/ui/webui/reload_button/BUILD.gn
@@ -0,0 +1,24 @@ +# 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. + +assert(!is_android) + +source_set("reload_button") { + sources = [ "reload_button_ui.h" ] + public_deps = [ + "//chrome/browser/ui/webui/top_chrome", + "//chrome/common", + "//content/public/browser", + ] +} + +source_set("impl") { + sources = [ "reload_button_ui.cc" ] + deps = [ + ":reload_button", + "//chrome/common", + "//ui/webui", + ] + public_deps = [ "//chrome/browser:browser_public_dependencies" ] +}
diff --git a/chrome/browser/ui/webui/reload_button/OWNERS b/chrome/browser/ui/webui/reload_button/OWNERS new file mode 100644 index 0000000..1a22119a --- /dev/null +++ b/chrome/browser/ui/webui/reload_button/OWNERS
@@ -0,0 +1,7 @@ +fergal@chromium.org +leimy@chromium.org +mych@chromium.org +rakina@chromium.org + +per-file *.mojom=set noparent +per-file *.mojom=file://ipc/SECURITY_OWNERS
diff --git a/chrome/browser/ui/webui/reload_button/reload_button_ui.cc b/chrome/browser/ui/webui/reload_button/reload_button_ui.cc new file mode 100644 index 0000000..98446d3 --- /dev/null +++ b/chrome/browser/ui/webui/reload_button/reload_button_ui.cc
@@ -0,0 +1,25 @@ +// 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/ui/webui/reload_button/reload_button_ui.h" + +#include "base/feature_list.h" +#include "chrome/common/chrome_features.h" +#include "chrome/common/webui_url_constants.h" +#include "content/public/browser/web_contents.h" +#include "content/public/browser/web_ui.h" +#include "content/public/browser/web_ui_data_source.h" +#include "ui/webui/webui_util.h" + +// TODO(crbug.com/444358999): implement the reload button +ReloadButtonUI::ReloadButtonUI(content::WebUI* web_ui) + : TopChromeWebUIController(web_ui) {} + +ReloadButtonUI::~ReloadButtonUI() = default; + +bool ReloadButtonUIConfig::IsWebUIEnabled( + content::BrowserContext* browser_context) { + return base::FeatureList::IsEnabled(features::kInitialWebUI) && + base::FeatureList::IsEnabled(features::kWebUIReloadButton); +}
diff --git a/chrome/browser/ui/webui/reload_button/reload_button_ui.h b/chrome/browser/ui/webui/reload_button/reload_button_ui.h new file mode 100644 index 0000000..2c28bca --- /dev/null +++ b/chrome/browser/ui/webui/reload_button/reload_button_ui.h
@@ -0,0 +1,34 @@ +// Copyright 2025 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_WEBUI_RELOAD_BUTTON_RELOAD_BUTTON_UI_H_ +#define CHROME_BROWSER_UI_WEBUI_RELOAD_BUTTON_RELOAD_BUTTON_UI_H_ + +#include "chrome/browser/ui/webui/top_chrome/top_chrome_web_ui_controller.h" +#include "chrome/browser/ui/webui/top_chrome/top_chrome_webui_config.h" +#include "chrome/common/webui_url_constants.h" +#include "content/public/browser/web_ui_controller.h" +#include "content/public/browser/webui_config.h" +#include "content/public/common/url_constants.h" + +class ReloadButtonUI; + +class ReloadButtonUI : public TopChromeWebUIController { + public: + explicit ReloadButtonUI(content::WebUI* web_ui); + ~ReloadButtonUI() override; + static constexpr std::string_view GetWebUIName() { return "ReloadButtonUI"; } +}; + +class ReloadButtonUIConfig + : public DefaultTopChromeWebUIConfig<ReloadButtonUI> { + public: + ReloadButtonUIConfig() + : DefaultTopChromeWebUIConfig(content::kChromeUIScheme, + chrome::kChromeUIReloadButtonHost) {} + // DefaultTopChromeWebUIConfig overrides: + bool IsWebUIEnabled(content::BrowserContext* browser_context) override; +}; + +#endif // CHROME_BROWSER_UI_WEBUI_RELOAD_BUTTON_RELOAD_BUTTON_UI_H_
diff --git a/chrome/browser/ui/webui/search_engine_choice/search_engine_choice_ui_browsertest.cc b/chrome/browser/ui/webui/search_engine_choice/search_engine_choice_ui_browsertest.cc index 94eee3f..03c7238 100644 --- a/chrome/browser/ui/webui/search_engine_choice/search_engine_choice_ui_browsertest.cc +++ b/chrome/browser/ui/webui/search_engine_choice/search_engine_choice_ui_browsertest.cc
@@ -263,7 +263,7 @@ ASSERT_TRUE(new_browser->profile()->IsGuestSession()); CloseBrowserSynchronously(browser()); - SelectFirstBrowser(); + SetBrowser(new_browser); ASSERT_EQ(new_browser, browser()); } }
diff --git a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc index 36955759..e4580632 100644 --- a/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc +++ b/chrome/browser/ui/webui/tab_search/tab_search_page_handler.cc
@@ -1428,10 +1428,13 @@ // A visible URL is used when the a new tab is still loading. // If it is cancelled during loading the visible URL becomes empty. // We will display an empty URL as about:blank in Javascript. - tab_data->url = - !last_committed_url.is_valid() || last_committed_url.is_empty() - ? tab_renderer_data.visible_url - : last_committed_url; + if (!last_committed_url.is_valid() || last_committed_url.is_empty()) { + tab_data->url = tab_renderer_data.should_display_url + ? tab_renderer_data.visible_url + : GURL(url::kAboutBlankURL); + } else { + tab_data->url = last_committed_url; + } if (tab_renderer_data.favicon.IsEmpty()) { tab_data->is_default_favicon = true;
diff --git a/chrome/browser/ui/webui_browser/webui_browser_browsertest.cc b/chrome/browser/ui/webui_browser/webui_browser_browsertest.cc index 06c0d6a..497ee41 100644 --- a/chrome/browser/ui/webui_browser/webui_browser_browsertest.cc +++ b/chrome/browser/ui/webui_browser/webui_browser_browsertest.cc
@@ -36,6 +36,27 @@ InProcessBrowserTest::SetUpOnMainThread(); } + // Helper function to set up embedded web contents for tests. + // Returns the embedded web contents after it has been converted to a guest. + content::WebContents* SetUpEmbeddedWebContents() { + EXPECT_TRUE(browser()->window()); + + content::WebContents* web_contents = + browser()->tab_strip_model()->GetActiveWebContents(); + EXPECT_TRUE(web_contents); + EXPECT_TRUE(content::WaitForLoadStop(web_contents)); + + // Make sure that the web contents actually got converted to a guest before + // we navigate it again, so that WebContentsViewChildFrame gets involved. + EXPECT_TRUE(base::test::RunUntil( + [web_contents]() { return !!web_contents->GetOuterWebContents(); })); + + GURL url = embedded_https_test_server().GetURL("a.com", "/defaultresponse"); + EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); + + return web_contents; + } + private: base::test::ScopedFeatureList scoped_feature_list_; }; @@ -88,53 +109,79 @@ #if !BUILDFLAG(IS_CHROMEOS) // Begin security related tests. These tests validate the security // boundary between a GuestContents and the parent. + +// Test that parent history is not affected by embedded navigation. +// The history.length should be independent between inner and outer webcontents. IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, HistoryLengthIndependent) { - auto* window = browser()->window(); - ASSERT_TRUE(window); + content::WebContents* inner_webcontents = SetUpEmbeddedWebContents(); + EXPECT_EQ(2, EvalJs(inner_webcontents, "window.history.length")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(web_contents); - EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - - // Make sure that the web contents actually got converted to a guest before - // we navigate it again, so that WebContentsViewChildFrame gets involved. - EXPECT_TRUE(base::test::RunUntil([web_contents]() { - return web_contents->GetOuterWebContents() != nullptr; - })); - - GURL url = embedded_https_test_server().GetURL("a.com", "/defaultresponse"); - EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); - EXPECT_EQ(2, EvalJs(web_contents, "window.history.length")); - - content::WebContents* outer_webcontents = web_contents->GetOuterWebContents(); - EXPECT_TRUE(outer_webcontents->GetOuterWebContents() == nullptr); - EXPECT_NE(outer_webcontents, nullptr); + content::WebContents* outer_webcontents = + inner_webcontents->GetOuterWebContents(); + EXPECT_FALSE(outer_webcontents->GetOuterWebContents()); + EXPECT_TRUE(outer_webcontents); EXPECT_EQ(1, EvalJs(outer_webcontents, "window.history.length")); } +// Test that the frame tree isolation between inner and outer webcontents. +// Neither should include the other in their frames collection. IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, FramesIndependent) { - auto* window = browser()->window(); - ASSERT_TRUE(window); + content::WebContents* inner_webcontents = SetUpEmbeddedWebContents(); + EXPECT_EQ(0, EvalJs(inner_webcontents, "window.frames.length")); - content::WebContents* web_contents = - browser()->tab_strip_model()->GetActiveWebContents(); - ASSERT_TRUE(web_contents); - EXPECT_TRUE(content::WaitForLoadStop(web_contents)); - - // Make sure that the web contents actually got converted to a guest before - // we navigate it again, so that WebContentsViewChildFrame gets involved. - EXPECT_TRUE(base::test::RunUntil([web_contents]() { - return web_contents->GetOuterWebContents() != nullptr; - })); - - GURL url = embedded_https_test_server().GetURL("a.com", "/defaultresponse"); - EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), url)); - EXPECT_EQ(0, EvalJs(web_contents, "window.frames.length")); - - content::WebContents* outer_webcontents = web_contents->GetOuterWebContents(); - EXPECT_TRUE(outer_webcontents->GetOuterWebContents() == nullptr); - EXPECT_NE(outer_webcontents, nullptr); + content::WebContents* outer_webcontents = + inner_webcontents->GetOuterWebContents(); EXPECT_EQ(0, EvalJs(outer_webcontents, "window.frames.length")); } + +// Test that the parent window does not count the embedded content as a frame. +// The outer web contents should have window.length = 0 since the embedded +// content should not be counted in the parent's frame count. +IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, WindowLengthIndependent) { + content::WebContents* inner_webcontents = SetUpEmbeddedWebContents(); + + content::WebContents* outer_webcontents = + inner_webcontents->GetOuterWebContents(); + EXPECT_EQ(0, EvalJs(outer_webcontents, "window.length")); +} + +// Test that the embedded content acts as top level. +// window.top in the embedded content should equal window (itself), +// not the actual parent's top-level window. +IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, WindowTopIndependent) { + content::WebContents* inner_webcontents = SetUpEmbeddedWebContents(); + + EXPECT_TRUE(EvalJs(inner_webcontents, "window.top === window").ExtractBool()); +} + +// Test that the embedded content acts as top level. +// window.opener should be null since the embedded content should not +// have access to the parent that "opened" it. +IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, WindowOpenerIndependent) { + content::WebContents* inner_webcontents = SetUpEmbeddedWebContents(); + + EXPECT_TRUE( + EvalJs(inner_webcontents, "window.opener === null").ExtractBool()); +} + +// Test that the embedded content acts as top level. +// window.parent should equal window (itself) since there should be +// no accessible parent window from the embedded content's perspective. +IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, WindowParentIndependent) { + content::WebContents* inner_webcontents = SetUpEmbeddedWebContents(); + + EXPECT_TRUE( + EvalJs(inner_webcontents, "window.parent === window").ExtractBool()); +} + +// Test that the embedded content acts as top level. +// window.frameElement should be null since the embedded content should +// not appear to be contained within a frame element. +IN_PROC_BROWSER_TEST_F(WebUIBrowserTest, WindowFrameElementIndependent) { + content::WebContents* inner_webcontents = SetUpEmbeddedWebContents(); + + EXPECT_TRUE( + EvalJs(inner_webcontents, "window.frameElement === null").ExtractBool()); +} + #endif // !BUILDFLAG(IS_CHROMEOS)
diff --git a/chrome/browser/web_applications/BUILD.gn b/chrome/browser/web_applications/BUILD.gn index 290230ca..c9d85b2 100644 --- a/chrome/browser/web_applications/BUILD.gn +++ b/chrome/browser/web_applications/BUILD.gn
@@ -596,6 +596,8 @@ "preinstalled_web_apps/messages_dogfood.h", "preinstalled_web_apps/notebook_lm.cc", "preinstalled_web_apps/notebook_lm.h", + "preinstalled_web_apps/vids.cc", + "preinstalled_web_apps/vids.h", ] deps += [ "//extensions/common:common_constants" ] }
diff --git a/chrome/browser/web_applications/chromeos_web_app_experiments_browsertest.cc b/chrome/browser/web_applications/chromeos_web_app_experiments_browsertest.cc index a783b2b5..3c98fc5 100644 --- a/chrome/browser/web_applications/chromeos_web_app_experiments_browsertest.cc +++ b/chrome/browser/web_applications/chromeos_web_app_experiments_browsertest.cc
@@ -11,7 +11,6 @@ #include "base/run_loop.h" #include "base/strings/stringprintf.h" #include "base/test/scoped_feature_list.h" -#include "base/test/test_future.h" #include "build/build_config.h" #include "chrome/browser/apps/app_service/app_registry_cache_waiter.h" #include "chrome/browser/apps/app_service/app_service_proxy.h" @@ -20,8 +19,6 @@ #include "chrome/browser/apps/link_capturing/link_capturing_feature_test_support.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_list_observer.h" -#include "chrome/browser/ui/browser_window/public/browser_window_interface.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/web_applications/app_browser_controller.h" @@ -31,14 +28,12 @@ #include "chrome/test/base/in_process_browser_test.h" #include "chrome/test/base/ui_test_utils.h" #include "chromeos/constants/chromeos_features.h" -#include "content/public/browser/navigation_handle.h" #include "content/public/browser/web_contents.h" #include "content/public/common/content_features.h" #include "content/public/test/browser_test.h" #include "content/public/test/browser_test_utils.h" #include "content/public/test/test_navigation_observer.h" #include "content/public/test/theme_change_waiter.h" -#include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/input/web_input_event.h" #include "third_party/blink/public/common/manifest/manifest.h" #include "third_party/blink/public/mojom/input/input_event.mojom-shared.h" @@ -54,56 +49,6 @@ namespace web_app { -// A TestNavigationObserver that also waits for the browser window containing -// the navigation to become active. -class ActiveBrowserWindowNavigationObserver - : public content::TestNavigationObserver, - public BrowserListObserver { - public: - explicit ActiveBrowserWindowNavigationObserver(const GURL& target_url) - : content::TestNavigationObserver(target_url) { - WatchExistingWebContents(); - StartWatchingNewWebContents(); - } - - BrowserWindowInterface* WaitForActiveWindow() { - Wait(); - EXPECT_TRUE(navigated_contents_); - return active_browser_future_.Get(); - } - - protected: - void CheckNavigatedWindowActive(BrowserWindowInterface* active_browser) { - ASSERT_TRUE(navigated_contents_); - if (active_browser->GetTabStripModel()->GetActiveWebContents() == - navigated_contents_) { - active_browser_future_.SetValue(active_browser); - } - } - - // TestNavigationObserver: - void NavigationOfInterestDidFinish( - content::NavigationHandle* navigation_handle) override { - ASSERT_FALSE(navigated_contents_); - navigated_contents_ = navigation_handle->GetWebContents(); - - // Check if the navigated WebContents is already active. - CheckNavigatedWindowActive( - GetLastActiveBrowserWindowInterfaceWithAnyProfile()); - } - - // BrowserListObserver: - void OnBrowserSetLastActive(Browser* browser) override { - if (navigated_contents_) { - CheckNavigatedWindowActive(browser); - } - } - - private: - raw_ptr<content::WebContents> navigated_contents_ = nullptr; - base::test::TestFuture<BrowserWindowInterface*> active_browser_future_; -}; - class ChromeOsWebAppExperimentsBrowserTest : public WebAppNavigationBrowserTest, public testing::WithParamInterface< @@ -240,11 +185,6 @@ )", on_click_code.c_str()); ASSERT_TRUE(content::ExecJs(web_contents, script)); - - // Input events to a page may not work right after a page load. See - // browser_test_utils.h for details. - SimulateEndOfPaintHoldingOnPrimaryMainFrame(web_contents); - content::SimulateMouseClick(web_contents, blink::WebInputEvent::Modifiers::kNoModifiers, blink::WebMouseEvent::Button::kLeft); @@ -291,12 +231,13 @@ )", extended_scope_page_.spec().c_str()); - ActiveBrowserWindowNavigationObserver observer(extended_scope_page_); + auto observer = GetTestNavigationObserver(extended_scope_page_); AddAndClickLinkWithCode(app_web_contents, on_click_code); - BrowserWindowInterface* const active_browser = observer.WaitForActiveWindow(); + observer->Wait(); - // The web app handles the navigation without opening a new window. - EXPECT_EQ(active_browser, app_browser); + // The web app handles the navigation. + BrowserWindowInterface* const active_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); EXPECT_TRUE(AppBrowserController::IsForWebApp(active_browser, app_id_)); EXPECT_EQ(active_browser->GetTabStripModel() ->GetActiveWebContents() @@ -328,13 +269,13 @@ )", extended_scope_page_.spec().c_str()); - ActiveBrowserWindowNavigationObserver observer(extended_scope_page_); + auto observer = GetTestNavigationObserver(extended_scope_page_); AddAndClickLinkWithCode(app_web_contents, on_click_code); - BrowserWindowInterface* const active_browser = observer.WaitForActiveWindow(); + observer->Wait(); // The web app handles the navigation by opening a new app window. - ASSERT_TRUE(active_browser); - EXPECT_NE(active_browser, app_browser); + BrowserWindowInterface* const active_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); EXPECT_TRUE(AppBrowserController::IsForWebApp(active_browser, app_id_)); EXPECT_EQ(active_browser->GetTabStripModel() ->GetActiveWebContents() @@ -356,13 +297,13 @@ )", extended_scope_page_.spec().c_str()); - ActiveBrowserWindowNavigationObserver observer(extended_scope_page_); + auto observer = GetTestNavigationObserver(extended_scope_page_); AddAndClickLinkWithCode(app_web_contents, on_click_code); - BrowserWindowInterface* const active_browser = observer.WaitForActiveWindow(); + observer->Wait(); // The web app handles the navigation by opening a new app window. - ASSERT_TRUE(active_browser); - EXPECT_NE(active_browser, app_browser); + BrowserWindowInterface* const active_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); EXPECT_TRUE(AppBrowserController::IsForWebApp(active_browser, app_id_)); EXPECT_EQ(active_browser->GetTabStripModel() ->GetActiveWebContents() @@ -385,13 +326,13 @@ )", extended_scope_page_.spec().c_str()); - ActiveBrowserWindowNavigationObserver observer(extended_scope_page_); + auto observer = GetTestNavigationObserver(extended_scope_page_); AddAndClickLinkWithCode(app_web_contents, on_click_code); - BrowserWindowInterface* const active_browser = observer.WaitForActiveWindow(); + observer->Wait(); // The web app handles the navigation by opening a new app window. - ASSERT_TRUE(active_browser); - EXPECT_NE(active_browser, app_browser); + BrowserWindowInterface* const active_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); EXPECT_TRUE(AppBrowserController::IsForWebApp(active_browser, app_id_)); EXPECT_EQ(active_browser->GetTabStripModel() ->GetActiveWebContents() @@ -410,14 +351,14 @@ content::WebContents* page_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ActiveBrowserWindowNavigationObserver observer(extended_scope_page_); + auto observer = GetTestNavigationObserver(extended_scope_page_); AddAndClickLinkWithCode(page_web_contents, GetFormBasedRedirectorCode(extended_scope_page_)); - BrowserWindowInterface* const active_browser = observer.WaitForActiveWindow(); + observer->Wait(); // The web app handles the navigation by opening a new app window. - ASSERT_TRUE(active_browser); - EXPECT_NE(active_browser, browser()); + BrowserWindowInterface* const active_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); EXPECT_TRUE(AppBrowserController::IsForWebApp(active_browser, app_id_)); EXPECT_EQ(active_browser->GetTabStripModel() ->GetActiveWebContents() @@ -438,14 +379,14 @@ content::WebContents* page_web_contents = browser()->tab_strip_model()->GetActiveWebContents(); - ActiveBrowserWindowNavigationObserver observer(extended_scope_page_); + auto observer = GetTestNavigationObserver(extended_scope_page_); AddAndClickLinkWithCode(page_web_contents, GetFormBasedRedirectorCode(extended_scope_page_)); - BrowserWindowInterface* const active_browser = observer.WaitForActiveWindow(); + observer->Wait(); // The app window was not launched for the navigation. - ASSERT_TRUE(active_browser); - EXPECT_EQ(active_browser, browser()); + BrowserWindowInterface* const active_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); EXPECT_FALSE(AppBrowserController::IsForWebApp(active_browser, app_id_)); EXPECT_EQ(active_browser->GetTabStripModel() ->GetActiveWebContents() @@ -463,14 +404,14 @@ app_browser->tab_strip_model()->GetActiveWebContents(); const GURL target_url = https_server().GetURL("/empty.html"); - ActiveBrowserWindowNavigationObserver observer(target_url); + auto observer = GetTestNavigationObserver(target_url); ClickLink(app_web_contents, target_url, LinkTarget::BLANK, /*rel=*/"noreferrer noopener"); - BrowserWindowInterface* const active_browser = observer.WaitForActiveWindow(); + observer->Wait(); // A browser tab is opened for the target URL. - ASSERT_TRUE(active_browser); - EXPECT_NE(active_browser, app_browser); + BrowserWindowInterface* const active_browser = + GetLastActiveBrowserWindowInterfaceWithAnyProfile(); EXPECT_FALSE(AppBrowserController::IsForWebApp(active_browser, app_id_)); EXPECT_EQ(active_browser->GetTabStripModel() ->GetActiveWebContents()
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc index 8802e47..5ffd93c 100644 --- a/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc +++ b/chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_apps.cc
@@ -38,7 +38,9 @@ #include "chrome/browser/web_applications/preinstalled_web_apps/google_meet.h" #include "chrome/browser/web_applications/preinstalled_web_apps/messages_dogfood.h" #include "chrome/browser/web_applications/preinstalled_web_apps/notebook_lm.h" +#include "chrome/browser/web_applications/preinstalled_web_apps/vids.h" #include "chrome/common/extensions/extension_constants.h" +#include "chromeos/constants/chromeos_features.h" #include "extensions/common/constants.h" #include "google_apis/gaia/gaia_auth_util.h" #endif // BUILDFLAG(IS_CHROMEOS) @@ -105,6 +107,12 @@ #endif // BUILDFLAG(IS_CHROMEOS) }; +#if BUILDFLAG(IS_CHROMEOS) + if (base::FeatureList::IsEnabled(chromeos::features::kVidsAppPreinstall)) { + apps.push_back(GetConfigForVids()); + } +#endif // BUILDFLAG(IS_CHROMEOS) + #if !BUILDFLAG(IS_CHROMEOS) if (base::FeatureList::IsEnabled(kChatPreinstalledWebApp)) { apps.insert(apps.end(), GetConfigForGoogleChat(
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/vids.cc b/chrome/browser/web_applications/preinstalled_web_apps/vids.cc new file mode 100644 index 0000000..7d624cf --- /dev/null +++ b/chrome/browser/web_applications/preinstalled_web_apps/vids.cc
@@ -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. + +#include "chrome/browser/web_applications/preinstalled_web_apps/vids.h" + +#include "ash/constants/web_app_id_constants.h" +#include "base/functional/bind.h" +#include "base/strings/utf_string_conversions.h" +#include "build/build_config.h" +#include "chrome/browser/web_applications/mojom/user_display_mode.mojom.h" +#include "chrome/browser/web_applications/preinstalled_app_install_features.h" +#include "chrome/browser/web_applications/preinstalled_web_apps/preinstalled_web_app_definition_utils.h" +#include "chrome/browser/web_applications/web_app_helpers.h" +#include "chrome/browser/web_applications/web_app_install_info.h" +#include "chrome/grit/preinstalled_web_apps_resources.h" +#include "third_party/blink/public/common/manifest/manifest.h" +#include "third_party/blink/public/common/safe_url_pattern.h" +#include "third_party/liburlpattern/parse.h" +#include "third_party/liburlpattern/part.h" +#include "third_party/liburlpattern/pattern.h" + +namespace web_app { + +namespace { + +blink::Manifest::TabStrip HomeTabPathnames( + std::vector<std::string_view> pathnames) { + blink::Manifest::TabStrip tab_strip; + auto& home_tab = tab_strip.home_tab.emplace<blink::Manifest::HomeTabParams>(); + + for (const std::string_view pathname : pathnames) { + base::expected<liburlpattern::Pattern, absl::Status> parse_result = + liburlpattern::Parse(pathname, [](std::string_view input) { + return std::string(input); + }); + CHECK(parse_result.has_value()); + + blink::SafeUrlPattern url_pattern; + url_pattern.pathname = std::move(parse_result.value().PartList()); + for (const liburlpattern::Part& part : url_pattern.pathname) { + CHECK_NE(part.type, liburlpattern::PartType::kRegex); + } + home_tab.scope_patterns.push_back(std::move(url_pattern)); + } + + return tab_strip; +} + +} // namespace + +ExternalInstallOptions GetConfigForVids() { + ExternalInstallOptions options( + /*install_url=*/GURL( + "https://docs.google.com/videos/installwebapp?usp=chrome_default"), + /*user_display_mode=*/mojom::UserDisplayMode::kStandalone, + /*install_source=*/ExternalInstallSource::kExternalDefault); + + options.user_type_allowlist = {"unmanaged", "managed"}; + options.only_use_app_info_factory = true; + options.app_info_factory = base::BindRepeating([]() { + GURL start_url = + GURL("https://docs.google.com/videos/?usp=installed_webapp"); + webapps::ManifestId manifest_id = + GenerateManifestId("videos/?usp=installed_webapp", start_url); + auto info = std::make_unique<WebAppInstallInfo>(manifest_id, start_url); + info->title = u"Vids"; + info->scope = GURL("https://docs.google.com/videos/"); + info->display_mode = DisplayMode::kBrowser; + info->display_override = {DisplayMode::kTabbed}; + info->tab_strip = HomeTabPathnames({ + "/videos/", + "/videos/u/:index", + "/videos/u/:index/", + }); + info->icon_bitmaps.any = + LoadBundledIcons({IDR_PREINSTALLED_WEB_APPS_VIDS_ICON_144_PNG}); + return info; + }); + options.expected_app_id = ash::kVidsAppId; + + return options; +} + +} // namespace web_app
diff --git a/chrome/browser/web_applications/preinstalled_web_apps/vids.h b/chrome/browser/web_applications/preinstalled_web_apps/vids.h new file mode 100644 index 0000000..a98122f --- /dev/null +++ b/chrome/browser/web_applications/preinstalled_web_apps/vids.h
@@ -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. + +#ifndef CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_WEB_APPS_VIDS_H_ +#define CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_WEB_APPS_VIDS_H_ + +#include "chrome/browser/web_applications/external_install_options.h" + +namespace web_app { + +// Returns the config for preinstalling the Vids app. +ExternalInstallOptions GetConfigForVids(); + +} // namespace web_app + +#endif // CHROME_BROWSER_WEB_APPLICATIONS_PREINSTALLED_WEB_APPS_VIDS_H_
diff --git a/chrome/browser/web_applications/web_app_scope.h b/chrome/browser/web_applications/web_app_scope.h index e5866d7bb..6464400 100644 --- a/chrome/browser/web_applications/web_app_scope.h +++ b/chrome/browser/web_applications/web_app_scope.h
@@ -55,6 +55,12 @@ const GURL& url, WebAppScopeScoreOptions options = WebAppScopeScoreOptions()) const; + const GURL& scope() const { return scope_; } + + const base::flat_set<ScopeExtensionInfo>& validated_scope_extensions() const { + return validated_scope_extensions_; + } + bool operator==(const WebAppScope& other) const; private:
diff --git a/chrome/build/android-arm32.pgo.txt b/chrome/build/android-arm32.pgo.txt index 64cbb35..8d58ef12 100644 --- a/chrome/build/android-arm32.pgo.txt +++ b/chrome/build/android-arm32.pgo.txt
@@ -1 +1 @@ -chrome-android32-main-1759924488-e3da09e001217576724d139ef282c4b98dd4ac6b-586f74523e01f66517ccfb6beed4c7e943ec6ace.profdata +chrome-android32-main-1759967434-2cead1bccc6c8d34dfe60937761769f85ec8eaed-a448ecee062d789daa5fb70bed84846e08e816dd.profdata
diff --git a/chrome/build/android-arm64.pgo.txt b/chrome/build/android-arm64.pgo.txt index c7af90e..e0832381a0 100644 --- a/chrome/build/android-arm64.pgo.txt +++ b/chrome/build/android-arm64.pgo.txt
@@ -1 +1 @@ -chrome-android64-main-1759944655-32f1b77da7055b43f79e97220d24b9ad7ae3f858-47d808b4258c17b18046ba7114012884bd8563af.profdata +chrome-android64-main-1759989178-37857a53db7ec9d923b6fe163a4f9104018c11d9-8c3a5c2e5f5315e4998479543077add43819aa58.profdata
diff --git a/chrome/build/android-desktop-x64.pgo.txt b/chrome/build/android-desktop-x64.pgo.txt index cc94965..c37cb18 100644 --- a/chrome/build/android-desktop-x64.pgo.txt +++ b/chrome/build/android-desktop-x64.pgo.txt
@@ -1 +1 @@ -chrome-android-desktop-x64-main-1759946382-7610ff0f5500555794b0cab5067c92880d879be9-fee6c9da9c645ec4bcdd789ac89f894449410824.profdata +chrome-android-desktop-x64-main-1759989178-b99f9b6b695d97da54b5bcda127319fb2502e6b7-8c3a5c2e5f5315e4998479543077add43819aa58.profdata
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index 72f66ac..3b4c7f1 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1759946382-42308464b7771da9e521d7a327f8a1d134e1a35d-fee6c9da9c645ec4bcdd789ac89f894449410824.profdata +chrome-linux-main-1759989178-f057ea5cd62168c3d6b4f1395e07d1c00149b67d-8c3a5c2e5f5315e4998479543077add43819aa58.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index 922d805..38127472 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1759953581-4d6f48bfbc83aa6dc8329d3f56f722e51ba2a82e-87d37048d4660c3026788080099c508a0ea97b59.profdata +chrome-mac-arm-main-1759989178-3782005e18fb0077ed5244407eb5383ad0f2ba3c-8c3a5c2e5f5315e4998479543077add43819aa58.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index fb5d968..ef570b0 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1759935520-43d46a9afdca8c3fd328a3279439aeae3cae314b-75d5e8706cb696cba392ce9d51638c16c33132b2.profdata +chrome-win32-main-1759967434-02657514b65c5f0479fefa6f87a5dceeb5cbe786-a448ecee062d789daa5fb70bed84846e08e816dd.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index ce90533..41cc39ce 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1759935520-95b912030054417b6887c29e4d2edf95e4c51131-75d5e8706cb696cba392ce9d51638c16c33132b2.profdata +chrome-win64-main-1759967434-32098c0d35956aac4d3c7f58532f0f030474e5fa-a448ecee062d789daa5fb70bed84846e08e816dd.profdata
diff --git a/chrome/chrome_paks.gni b/chrome/chrome_paks.gni index 13aef8d..f0b5e19e 100644 --- a/chrome/chrome_paks.gni +++ b/chrome/chrome_paks.gni
@@ -222,6 +222,7 @@ "$root_gen_dir/chrome/password_manager_resources.pak", "$root_gen_dir/chrome/privacy_sandbox_resources.pak", "$root_gen_dir/chrome/profile_internals_resources.pak", + "$root_gen_dir/chrome/reload_button_resources.pak", "$root_gen_dir/chrome/search_engine_choice_resources.pak", "$root_gen_dir/chrome/settings_resources.pak", "$root_gen_dir/chrome/side_panel_bookmarks_resources.pak", @@ -256,6 +257,7 @@ "//chrome/browser/resources/data_sharing:resources", "//chrome/browser/resources/lens/overlay:resources", "//chrome/browser/resources/lens/shared:resources", + "//chrome/browser/resources/reload_button:resources", "//chrome/browser/resources/search_engine_choice:resources", "//chrome/browser/resources/side_panel/comments:resources", "//chrome/browser/resources/tab_group_home:resources",
diff --git a/chrome/common/chrome_features.cc b/chrome/common/chrome_features.cc index eec31a4..329fbea2 100644 --- a/chrome/common/chrome_features.cc +++ b/chrome/common/chrome_features.cc
@@ -436,6 +436,11 @@ // if user manually resizes. const base::FeatureParam<int> kGlicSidePanelMinWidth{ &kGlicMultiInstance, "glic-side-panel-min-width", 384}; +// Controls the width and height of the multi-instance floating panel. +const base::FeatureParam<int> kGlicMultiInstanceFloatyWidth{ + &kGlicMultiInstance, "glic-multi-instance-floaty-width", 400}; +const base::FeatureParam<int> kGlicMultiInstanceFloatyHeight{ + &kGlicMultiInstance, "glic-multi-instance-floaty-height", 400}; // Controls whether the Glic feature's z order changes based on the webclient // mode. @@ -1686,6 +1691,10 @@ // the WebUI implementation of top chrome. Individual features will be // additionally gated by this flag. BASE_FEATURE(kInitialWebUI, base::FEATURE_DISABLED_BY_DEFAULT); +// When enable, the reload button will be replaced with the a WebView, and +// chrome://reload-button.top-chrome will be loaded as the content. +// crbug.com/444358999 +BASE_FEATURE(kWebUIReloadButton, base::FEATURE_DISABLED_BY_DEFAULT); #endif // !BUILDFLAG(IS_ANDROID) // Enables the User-Agent override fix for SearchPrefetch. This will work only
diff --git a/chrome/common/chrome_features.h b/chrome/common/chrome_features.h index d7d6c136..b5d9624 100644 --- a/chrome/common/chrome_features.h +++ b/chrome/common/chrome_features.h
@@ -440,6 +440,10 @@ COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kGlicMultiInstance); COMPONENT_EXPORT(CHROME_FEATURES) extern const base::FeatureParam<int> kGlicSidePanelMinWidth; +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::FeatureParam<int> kGlicMultiInstanceFloatyWidth; +COMPONENT_EXPORT(CHROME_FEATURES) +extern const base::FeatureParam<int> kGlicMultiInstanceFloatyHeight; COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kGlicZOrderChanges); @@ -1251,6 +1255,11 @@ BASE_DECLARE_FEATURE(kWebium); COMPONENT_EXPORT(CHROME_FEATURES) BASE_DECLARE_FEATURE(kInitialWebUI); +// TODO(crbug.com/444358999): after the experiment to collect metrics, either +// remove this reload button web UI or extend it to include more top-chrome +// components. +COMPONENT_EXPORT(CHROME_FEATURES) +BASE_DECLARE_FEATURE(kWebUIReloadButton); #endif // !BUILDFLAG(IS_ANDROID) COMPONENT_EXPORT(CHROME_FEATURES)
diff --git a/chrome/common/webui_url_constants.cc b/chrome/common/webui_url_constants.cc index 85b06a4..b497a43 100644 --- a/chrome/common/webui_url_constants.cc +++ b/chrome/common/webui_url_constants.cc
@@ -121,6 +121,9 @@ kChromeUIPrefsInternalsHost, kChromeUIProfileInternalsHost, content::kChromeUIQuotaInternalsHost, +#if !BUILDFLAG(IS_ANDROID) + kChromeUIReloadButtonHost, +#endif kChromeUISignInInternalsHost, kChromeUISiteEngagementHost, #if !BUILDFLAG(IS_ANDROID)
diff --git a/chrome/common/webui_url_constants.h b/chrome/common/webui_url_constants.h index c98aa09..bc84e44 100644 --- a/chrome/common/webui_url_constants.h +++ b/chrome/common/webui_url_constants.h
@@ -300,6 +300,9 @@ inline constexpr char kChromeUITermsHost[] = "terms"; inline constexpr char kChromeUITermsURL[] = "chrome://terms/"; inline constexpr char kChromeUIThemeHost[] = "theme"; +inline constexpr char kChromeUIReloadButtonURL[] = + "chrome://reload-button.top-chrome"; +inline constexpr char kChromeUIReloadButtonHost[] = "reload-button.top-chrome"; inline constexpr char kChromeUIThemeURL[] = "chrome://theme/"; inline constexpr char kChromeUITopChromeDomain[] = "top-chrome"; inline constexpr char kChromeUITranslateInternalsHost[] = "translate-internals";
diff --git a/chrome/test/base/in_process_browser_test.cc b/chrome/test/base/in_process_browser_test.cc index 69190d7..e0a468f 100644 --- a/chrome/test/base/in_process_browser_test.cc +++ b/chrome/test/base/in_process_browser_test.cc
@@ -61,6 +61,7 @@ #include "chrome/browser/ui/browser_tabstrip.h" #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/browser_window/public/browser_window_interface.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/browser/ui/toolbar_controller_util.h" #include "chrome/common/chrome_constants.h" @@ -596,13 +597,7 @@ } void InProcessBrowserTest::SetBrowser(BrowserWindowInterface* browser) { - browser_ = browser->GetBrowserForMigrationOnly(); -} - -void InProcessBrowserTest::SelectFirstBrowser() { - const BrowserList* browser_list = BrowserList::GetInstance(); - if (!browser_list->empty()) - browser_ = browser_list->get(0); + browser_ = browser ? browser->GetBrowserForMigrationOnly() : nullptr; } void InProcessBrowserTest::RecordPropertyFromMap( @@ -838,7 +833,7 @@ // Pump startup related events. content::RunAllPendingInMessageLoop(); - SelectFirstBrowser(); + SetBrowser(GetLastActiveBrowserWindowInterfaceWithAnyProfile()); if (browser_ && !browser_->tab_strip_model()->empty()) { base::WeakPtr<content::WebContents> tab = browser_->tab_strip_model()->GetActiveWebContents()->GetWeakPtr();
diff --git a/chrome/test/base/in_process_browser_test.h b/chrome/test/base/in_process_browser_test.h index 612a8fd..92fc2be 100644 --- a/chrome/test/base/in_process_browser_test.h +++ b/chrome/test/base/in_process_browser_test.h
@@ -181,23 +181,14 @@ // and setup functions. static size_t GetTestPreCount(); - // Returns the browser created by BrowserMain(). - // If no browser is created in BrowserMain(), this will return nullptr unless - // another browser instance is created at a later time and - // `SelectFirstBrowser()` or `SetBrowser()` is called. + // Returns the browser created by BrowserMain(). If no browser is created in + // BrowserMain(), this will return nullptr unless another browser instance is + // created at a later time and `SetBrowser()` is called. Browser* browser() const { return browser_; } // Sets the default `browser_` instance for the fixture. void SetBrowser(BrowserWindowInterface* browser); - // Set |browser_| to the first browser on the browser list. - // Call this when your test subclass wants to access a non-null browser - // instance through browser() but browser creation is delayed until after - // PreRunTestOnMainThread(). - // DEPRECATED: Clients should not rely on ordering in the global BrowserList, - // use SetBrowser() instead. - void SelectFirstBrowser(); - // This function is used to record a set of properties for a test case in // gtest result and that will be used by resultDB. The map's key value pair // are defined by each test case. For use case check this bug: @@ -375,9 +366,8 @@ static SetUpBrowserFunction* global_browser_set_up_function_; // Usually references the browser created in BrowserMain(). - // If no browser is created in BrowserMain(), then |browser_| will remain - // nullptr unless SelectFirstBrowser() is called after the creation of the - // first browser instance at a later time. + // If no browser is created in BrowserMain(), then `browser_` will remain + // nullptr unless `SetBrowser()` is called at a later time. raw_ptr<Browser, AcrossTasksDanglingUntriaged> browser_ = nullptr; // Used to run the process until the BrowserProcess signals the test to quit.
diff --git a/chrome/test/data/webui/omnibox_popup/BUILD.gn b/chrome/test/data/webui/omnibox_popup/BUILD.gn index 3a76deab..9c85035 100644 --- a/chrome/test/data/webui/omnibox_popup/BUILD.gn +++ b/chrome/test/data/webui/omnibox_popup/BUILD.gn
@@ -7,7 +7,10 @@ assert(!is_android && !is_ios) build_webui_tests("build") { - files = [ "app_test.ts" ] + files = [ + "app_test.ts", + "full_app_test.ts", + ] ts_path_mappings = [ "chrome://omnibox-popup.top-chrome/omnibox_popup.js|" + rebase_path( "$root_gen_dir/chrome/browser/resources/omnibox_popup/tsc/omnibox_popup.d.ts",
diff --git a/chrome/test/data/webui/omnibox_popup/full_app_test.ts b/chrome/test/data/webui/omnibox_popup/full_app_test.ts new file mode 100644 index 0000000..f06543b5 --- /dev/null +++ b/chrome/test/data/webui/omnibox_popup/full_app_test.ts
@@ -0,0 +1,20 @@ +// 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 'chrome://omnibox-popup.top-chrome/omnibox_popup.js'; + +import {assertTrue} from 'chrome://webui-test/chai_assert.js'; +import {eventToPromise} from 'chrome://webui-test/test_util.js'; + +suite('FullAppTest', function() { + test('ContextMenuPrevented', async function() { + const app = document.createElement('omnibox-full-app'); + document.body.appendChild(app); + const whenFired = eventToPromise('contextmenu', document.documentElement); + document.documentElement.dispatchEvent( + new Event('contextmenu', {cancelable: true})); + const e = await whenFired; + assertTrue(e.defaultPrevented); + }); +});
diff --git a/chrome/test/data/webui/omnibox_popup/omnibox_popup_browsertest.cc b/chrome/test/data/webui/omnibox_popup/omnibox_popup_browsertest.cc index 1abf427b..c46df65 100644 --- a/chrome/test/data/webui/omnibox_popup/omnibox_popup_browsertest.cc +++ b/chrome/test/data/webui/omnibox_popup/omnibox_popup_browsertest.cc
@@ -3,23 +3,52 @@ // found in the LICENSE file. #include "base/test/scoped_feature_list.h" +#include "build/config/coverage/buildflags.h" #include "chrome/common/webui_url_constants.h" #include "chrome/test/base/web_ui_mocha_browser_test.h" #include "components/omnibox/common/omnibox_features.h" #include "content/public/test/browser_test.h" -class OmniboxPopupBrowserTest : public WebUIMochaBrowserTest { +class OmniboxPopupTest : public WebUIMochaBrowserTest { protected: - OmniboxPopupBrowserTest() { + OmniboxPopupTest() { set_test_loader_host(chrome::kChromeUIOmniboxPopupHost); + scoped_feature_list_.InitWithFeatures({omnibox::kWebUIOmniboxPopup}, + {omnibox::kWebUIOmniboxFullPopup}); } private: - base::test::ScopedFeatureList scoped_feature_list_{ - omnibox::kWebUIOmniboxPopup}; + base::test::ScopedFeatureList scoped_feature_list_; }; -typedef OmniboxPopupBrowserTest OmniboxPopupTest; -IN_PROC_BROWSER_TEST_F(OmniboxPopupTest, App) { +#if BUILDFLAG(USE_JAVASCRIPT_COVERAGE) +// TODO(crbug.com/40284073): Test fails with JS coverage turned on. +#define MAYBE_App DISABLED_App +#else +#define MAYBE_App App +#endif +IN_PROC_BROWSER_TEST_F(OmniboxPopupTest, MAYBE_App) { RunTest("omnibox_popup/app_test.js", "mocha.run();"); } + +class OmniboxPopupFullTest : public WebUIMochaBrowserTest { + protected: + OmniboxPopupFullTest() { + set_test_loader_host(chrome::kChromeUIOmniboxPopupHost); + scoped_feature_list_.InitWithFeatures( + {omnibox::kWebUIOmniboxPopup, omnibox::kWebUIOmniboxFullPopup}, {}); + } + + private: + base::test::ScopedFeatureList scoped_feature_list_; +}; + +#if BUILDFLAG(USE_JAVASCRIPT_COVERAGE) +// TODO(crbug.com/40284073): Test fails with JS coverage turned on. +#define MAYBE_App DISABLED_App +#else +#define MAYBE_App App +#endif +IN_PROC_BROWSER_TEST_F(OmniboxPopupFullTest, MAYBE_App) { + RunTest("omnibox_popup/full_app_test.js", "mocha.run();"); +}
diff --git a/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts b/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts index 505cd71f..bf64c17 100644 --- a/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts +++ b/chrome/test/data/webui/side_panel/read_anything/app_receives_toolbar_changes_test.ts
@@ -310,6 +310,15 @@ chrome.readingMode.keyboardShortcutStopSource, await metrics.whenCalled('recordSpeechStopSource')); }); + + test('other key presses do not play', async () => { + const fPress = new KeyboardEvent('keydown', {key: 'f'}); + app.$.appFlexParent.dispatchEvent(fPress); + await microtasksFinished(); + + assertFalse(speechController.isSpeechActive()); + assertEquals(0, metrics.getCallCount('recordSpeechStopSource')); + }); }); });
diff --git a/chrome/test/data/webui/tab_search/split_new_tab_page_test.ts b/chrome/test/data/webui/tab_search/split_new_tab_page_test.ts index 2de65aa8..2ccc569 100644 --- a/chrome/test/data/webui/tab_search/split_new_tab_page_test.ts +++ b/chrome/test/data/webui/tab_search/split_new_tab_page_test.ts
@@ -114,6 +114,49 @@ assertEquals(3, tabSearchItems.length); }); + test('Formats urls properly', async () => { + await splitNewTabPageSetup(); + + const windowData = createWindowData(); + windowData[0]!.tabs.push( + createTab({ + index: 6, + lastActiveTimeTicks: {internalValue: BigInt(10)}, + tabId: 8, + title: '', + url: {url: 'about:blank'}, + }), + createTab({ + index: 7, + lastActiveTimeTicks: {internalValue: BigInt(11)}, + tabId: 9, + title: 'file.jpg', + url: {url: 'file://file.jpg'}, + }), + createTab({ + index: 8, + lastActiveTimeTicks: {internalValue: BigInt(12)}, + tabId: 10, + title: 'Data', + url: {url: 'blob://data'}, + }), + ); + testApiProxy.getCallbackRouterRemote().tabsChanged(createProfileData({ + windows: windowData, + })); + await eventToPromise('viewport-filled', splitNewTabPage.$.splitTabsList); + + const tabSearchItems = + splitNewTabPage.shadowRoot.querySelectorAll('tab-search-item'); + assertEquals( + loadTimeData.getString('blobUrlSource'), + tabSearchItems[1]!.data.hostname); + assertEquals( + loadTimeData.getString('fileUrlSource'), + tabSearchItems[2]!.data.hostname); + assertEquals('about:blank', tabSearchItems[3]!.data.hostname); + }); + test('Sorts list', async () => { await splitNewTabPageSetup(); const tabSearchItems =
diff --git a/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc b/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc index 637cb94..2b493ad 100644 --- a/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc +++ b/chrome/test/fuzzing/kombucha_in_process_fuzzer.cc
@@ -10,6 +10,7 @@ #include "chrome/app/chrome_command_ids.h" #include "chrome/browser/ui/accelerator_utils.h" #include "chrome/browser/ui/browser_list.h" +#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h" #include "chrome/browser/ui/tabs/tab_group_model.h" #include "chrome/browser/ui/ui_features.h" #include "chrome/browser/ui/views/tabs/tab.h" @@ -175,7 +176,7 @@ for (Browser* browser : extra_browsers) { CloseBrowserSynchronously(browser); } - SelectFirstBrowser(); + SetBrowser(GetLastActiveBrowserWindowInterfaceWithAnyProfile()); } TabStripModel* tab_strip_model = browser()->tab_strip_model();
diff --git a/chrome/test/media_router/performance/openscreen_cast_performance_test.py b/chrome/test/media_router/performance/openscreen_cast_performance_test.py index a69e74e..eb78c12 100644 --- a/chrome/test/media_router/performance/openscreen_cast_performance_test.py +++ b/chrome/test/media_router/performance/openscreen_cast_performance_test.py
@@ -105,10 +105,9 @@ ] HOST_TUNNEL_CMD = [ - 'sshpass', - '-p', - PASSWORD, 'ssh', + '-i', + '~/.ssh/id_ed25519', '-L', f'{CHROMEDRIVER_PORT}:127.0.0.1:{CHROMEDRIVER_PORT}', f'{USERNAME}@{SENDER}', @@ -172,8 +171,14 @@ Returns: subprocess.CompletedProcess or subprocess.Popen: The process object. """ - ssh_command = ['sshpass', '-p', password, 'ssh', - f'{username}@{hostname}', command] + ssh_command = [ + 'ssh', + '-i', + '~/.ssh/id_ed25519', + f'{username}@{hostname}', + command + ] + if blocking: process = subprocess.run( ssh_command,
diff --git a/chrome/updater/app/server/win/com_classes_legacy.cc b/chrome/updater/app/server/win/com_classes_legacy.cc index 46fe251..39cdff3 100644 --- a/chrome/updater/app/server/win/com_classes_legacy.cc +++ b/chrome/updater/app/server/win/com_classes_legacy.cc
@@ -1255,7 +1255,7 @@ substitutions.push_back(substitution_string.value()); } - const HRESULT hr = app_command_runner_.value()->Run(substitutions, process_); + const HRESULT hr = app_command_runner_->Run(substitutions, process_); using LegacyAppCommandWebImplPtr = Microsoft::WRL::ComPtr<LegacyAppCommandWebImpl>; update_client::Callback callback = base::BindOnce(
diff --git a/chrome/updater/app/server/win/com_classes_legacy.h b/chrome/updater/app/server/win/com_classes_legacy.h index a26aa24..a839cc6 100644 --- a/chrome/updater/app/server/win/com_classes_legacy.h +++ b/chrome/updater/app/server/win/com_classes_legacy.h
@@ -320,7 +320,7 @@ ~LegacyAppCommandWebImpl() override; base::Process process_; - HResultOr<scoped_refptr<AppCommandRunner>> app_command_runner_; + HResultOr<AppCommandRunner> app_command_runner_; UpdaterScope scope_ = UpdaterScope::kSystem; std::string app_id_; std::string command_id_;
diff --git a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc index 8b5afdbb..0c970728 100644 --- a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc +++ b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
@@ -204,7 +204,7 @@ EXPECT_EQ(app_id, base::WideToUTF8(kAppId1)); EXPECT_EQ(command_id, base::WideToUTF8(kCmdId1)); EXPECT_EQ(error_params.error_code, - GOOPDATEINSTALL_E_INSTALLER_FAILED_START); + HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND)); EXPECT_EQ(error_params.extra_code1, kErrorAppCommandLaunchFailed); }), app_command_web));
diff --git a/chrome/updater/auto_run_on_os_upgrade_task.cc b/chrome/updater/auto_run_on_os_upgrade_task.cc index 942b9636..e07da97 100644 --- a/chrome/updater/auto_run_on_os_upgrade_task.cc +++ b/chrome/updater/auto_run_on_os_upgrade_task.cc
@@ -93,7 +93,7 @@ scope_, base::SysUTF8ToWide(app_id)), [&](const auto& app_command_runner) { base::Process process; - if (FAILED(app_command_runner->Run( + if (FAILED(app_command_runner.Run( {base::SysUTF8ToWide(os_upgrade_string_)}, process))) { return; }
diff --git a/chrome/updater/auto_run_on_os_upgrade_task_unittest.cc b/chrome/updater/auto_run_on_os_upgrade_task_unittest.cc index 87b3429..f1f09fe 100644 --- a/chrome/updater/auto_run_on_os_upgrade_task_unittest.cc +++ b/chrome/updater/auto_run_on_os_upgrade_task_unittest.cc
@@ -18,7 +18,6 @@ #include "base/strings/utf_string_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/test/bind.h" -#include "base/test/task_environment.h" #include "base/test/test_timeouts.h" #include "chrome/updater/activity.h" #include "chrome/updater/persisted_data.h" @@ -75,7 +74,6 @@ std::unique_ptr<TestingPrefServiceSimple> pref_service_; base::CommandLine cmd_exe_command_line_{base::CommandLine::NO_PROGRAM}; base::ScopedTempDir temp_programfiles_dir_; - base::test::TaskEnvironment environment_; }; TEST_F(AutoRunOnOsUpgradeTaskTest, RunOnOsUpgradeForApp) {
diff --git a/chrome/updater/win/app_command_runner.cc b/chrome/updater/win/app_command_runner.cc index ef8381f..12cca54 100644 --- a/chrome/updater/win/app_command_runner.cc +++ b/chrome/updater/win/app_command_runner.cc
@@ -8,7 +8,6 @@ #include <shellapi.h> -#include <functional> #include <optional> #include <string> #include <utility> @@ -18,25 +17,17 @@ #include "base/command_line.h" #include "base/containers/span.h" #include "base/files/file_path.h" -#include "base/functional/bind.h" -#include "base/functional/callback.h" #include "base/logging.h" -#include "base/memory/ref_counted.h" #include "base/numerics/safe_conversions.h" #include "base/path_service.h" -#include "base/process/kill.h" #include "base/process/launch.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/strings/string_util_impl_helpers.h" #include "base/strings/utf_string_conversions.h" -#include "base/synchronization/waitable_event.h" -#include "base/task/task_traits.h" -#include "base/task/thread_pool.h" #include "base/version.h" #include "base/win/registry.h" #include "base/win/scoped_localalloc.h" -#include "chrome/updater/constants.h" #include "chrome/updater/updater_branding.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/util/win_util.h" @@ -134,10 +125,13 @@ } // namespace AppCommandRunner::AppCommandRunner() = default; +AppCommandRunner::AppCommandRunner(const AppCommandRunner&) = default; +AppCommandRunner& AppCommandRunner::operator=(const AppCommandRunner&) = + default; AppCommandRunner::~AppCommandRunner() = default; // static -HResultOr<scoped_refptr<AppCommandRunner>> AppCommandRunner::LoadAppCommand( +HResultOr<AppCommandRunner> AppCommandRunner::LoadAppCommand( UpdaterScope scope, const std::wstring& app_id, const std::wstring& command_id) { @@ -152,11 +146,10 @@ } } - scoped_refptr<AppCommandRunner> app_command_runner = - base::MakeRefCounted<AppCommandRunner>(); + AppCommandRunner app_command_runner; hr = GetAppCommandFormatComponents(scope, command_format, - app_command_runner->executable_, - app_command_runner->parameters_); + app_command_runner.executable_, + app_command_runner.parameters_); if (FAILED(hr)) { return base::unexpected(hr); } @@ -165,14 +158,14 @@ } // static -std::vector<scoped_refptr<AppCommandRunner>> +std::vector<AppCommandRunner> AppCommandRunner::LoadAutoRunOnOsUpgradeAppCommands( UpdaterScope scope, const std::wstring& app_id) { const HKEY root = UpdaterScopeToHKeyRoot(scope); const std::wstring commands_key_name = GetAppCommandKey(app_id, L""); - std::vector<scoped_refptr<AppCommandRunner>> app_command_runners; + std::vector<AppCommandRunner> app_command_runners; for (base::win::RegistryKeyIterator it(root, commands_key_name.c_str(), KEY_WOW64_32KEY); it.Valid(); ++it) { @@ -190,7 +183,7 @@ continue; } - HResultOr<scoped_refptr<AppCommandRunner>> runner = + HResultOr<AppCommandRunner> runner = LoadAppCommand(scope, app_id, it.Name()); if (runner.has_value()) { app_command_runners.push_back(*std::move(runner)); @@ -201,102 +194,48 @@ } HRESULT AppCommandRunner::Run(base::span<const std::wstring> substitutions, - base::Process& process) { - if (executable_.empty()) { + base::Process& process) const { + if (executable_.empty() || process.IsValid()) { return E_UNEXPECTED; } - VLOG(2) << __func__ << ": " << executable_ << ": " - << base::JoinString(parameters_, L",") << " : " - << base::JoinString(substitutions, L","); + return ExecuteAppCommand(executable_, parameters_, substitutions, process); +} - const std::optional<std::wstring> command_line_parameters = - FormatAppCommandLine(parameters_, substitutions); - if (!command_line_parameters) { - LOG(ERROR) << __func__ << "!command_line_parameters"; +// static +HRESULT AppCommandRunner::StartProcess(const base::FilePath& executable, + const std::wstring& parameters, + base::Process& process) { + VLOG(2) << __func__ << ": " << executable << ": " << parameters; + + if (executable.empty() || process.IsValid()) { + return E_UNEXPECTED; + } + + // `executable` needs to be a full path to prevent `::CreateProcess` (which + // `base::LaunchProcess` uses internally) from using the search path for path + // resolution. + if (!executable.IsAbsolute()) { + LOG(ERROR) << __func__ << "!executable.IsAbsolute(): " << executable; return E_INVALIDARG; } - VLOG(2) << __func__ << ": " << executable_ << ": " - << *command_line_parameters; + base::LaunchOptions options = {}; + options.feedback_cursor_off = true; + options.start_hidden = true; - // `executable_` needs to be a full path to prevent `::CreateProcess` (which - // `AppCommandRunner::LaunchProcess` uses internally) from using the search - // path for path resolution. - if (!executable_.IsAbsolute()) { - LOG(ERROR) << __func__ << "!executable_.IsAbsolute(): " << executable_; - return E_INVALIDARG; - } - - base::WaitableEvent process_event; - base::ThreadPool::CreateSequencedTaskRunner( - {base::MayBlock(), base::WithBaseSyncPrimitives()}) - ->PostTask( - FROM_HERE, - base::BindOnce( - [](scoped_refptr<AppCommandRunner> obj, - const std::wstring& command_line_parameters, - base::WaitableEvent& event) { - base::LaunchOptions options = {}; - options.feedback_cursor_off = true; - options.start_hidden = true; - - base::TerminationStatus final_status = - base::TerminationStatus::TERMINATION_STATUS_MAX_ENUM; - - int exit_code = -1; - std::ignore = base::GetAppOutputWithExitCodeAndTimeout( - base::StrCat({base::CommandLine::QuoteForCommandLineToArgvW( - obj->executable_.value()), - L" ", command_line_parameters}), - /*include_stderr=*/true, nullptr, &exit_code, - kWaitForAppInstaller, options, - [&](const base::Process& process, - std::string_view partial_output) { - if (!obj->process_) { - obj->process_ = process.Duplicate(); - VLOG(1) << "AppCommand pid: " << obj->process_->Pid(); - event.Signal(); - } - - if (!partial_output.empty()) { - VLOG(1) << "AppCommand output: " << partial_output; - } - }, - &final_status); - - if (final_status == - base::TerminationStatus::TERMINATION_STATUS_LAUNCH_FAILED) { - VLOG(1) << "AppCommand failed to launch"; - return GOOPDATEINSTALL_E_INSTALLER_FAILED_START; - } - if (final_status == - base::TerminationStatus::TERMINATION_STATUS_STILL_RUNNING) { - VLOG(1) << "AppCommand timed out"; - return GOOPDATEINSTALL_E_INSTALLER_TIMED_OUT; - } - - return exit_code; - }, - base::WrapRefCounted(this), *command_line_parameters, - std::ref(process_event)) - .Then(base::BindOnce( - [](scoped_refptr<AppCommandRunner> obj, - base::WaitableEvent& event, HRESULT hr) { - obj->hr_ = hr; - event.Signal(); - }, - base::WrapRefCounted(this), std::ref(process_event)))); - - process_event.Wait(); - if (!process_) { - const HRESULT hr = hr_.value_or(E_UNEXPECTED); - LOG(ERROR) << __func__ << ": base::LaunchProcess failed: " << hr; + process = base::LaunchProcess( + base::StrCat( + {base::CommandLine::QuoteForCommandLineToArgvW(executable.value()), + L" ", parameters}), + options); + if (!process.IsValid()) { + const HRESULT hr = HRESULTFromLastError(); + LOG(ERROR) << __func__ << "base::LaunchProcess failed: " << hr; return hr; } - process = process_->Duplicate(); - VLOG(2) << __func__ << ": Started process with PID: " << process.Pid(); + VLOG(2) << __func__ << "Started process with PID: " << process.Pid(); return S_OK; } @@ -379,4 +318,24 @@ return formatted_command_line; } +// static +HRESULT AppCommandRunner::ExecuteAppCommand( + const base::FilePath& executable, + const std::vector<std::wstring>& parameters, + base::span<const std::wstring> substitutions, + base::Process& process) { + VLOG(2) << __func__ << ": " << executable << ": " + << base::JoinString(parameters, L",") << " : " + << base::JoinString(substitutions, L","); + + const std::optional<std::wstring> command_line_parameters = + FormatAppCommandLine(parameters, substitutions); + if (!command_line_parameters) { + LOG(ERROR) << __func__ << "!command_line_parameters"; + return E_INVALIDARG; + } + + return StartProcess(executable, command_line_parameters.value(), process); +} + } // namespace updater
diff --git a/chrome/updater/win/app_command_runner.h b/chrome/updater/win/app_command_runner.h index d4d5b65..5ea31e0 100644 --- a/chrome/updater/win/app_command_runner.h +++ b/chrome/updater/win/app_command_runner.h
@@ -14,7 +14,6 @@ #include "base/containers/span.h" #include "base/files/file_path.h" #include "base/gtest_prod_util.h" -#include "base/memory/ref_counted.h" #include "base/process/process.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/util/win_util.h" @@ -23,35 +22,38 @@ // AppCommandRunner loads and runs a pre-registered command line from the // registry. -class AppCommandRunner : public base::RefCountedThreadSafe<AppCommandRunner> { +class AppCommandRunner { public: AppCommandRunner(); + AppCommandRunner(const AppCommandRunner&); + AppCommandRunner& operator=(const AppCommandRunner&); + ~AppCommandRunner(); // Creates an instance of `AppCommandRunner` object corresponding to `app_id` // and `command_id`. - static HResultOr<scoped_refptr<AppCommandRunner>> LoadAppCommand( + static HResultOr<AppCommandRunner> LoadAppCommand( UpdaterScope scope, const std::wstring& app_id, const std::wstring& command_id); // Loads and returns a vector of `AppCommandRunner` objects corresponding to // "AutoRunOnOsUpgradeAppCommands" for `app_id`. - static std::vector<scoped_refptr<AppCommandRunner>> - LoadAutoRunOnOsUpgradeAppCommands(UpdaterScope scope, - const std::wstring& app_id); + static std::vector<AppCommandRunner> LoadAutoRunOnOsUpgradeAppCommands( + UpdaterScope scope, + const std::wstring& app_id); // Runs the AppCommand with the provided `substitutions` and populates // `process` if successful. HRESULT Run(base::span<const std::wstring> substitutions, - base::Process& process); - - std::string output(); - - protected: - friend class base::RefCountedThreadSafe<AppCommandRunner>; - virtual ~AppCommandRunner(); + base::Process& process) const; private: + // Starts a process with separate `executable` and `parameters` components. + // `executable` needs to be an absolute path. + static HRESULT StartProcess(const base::FilePath& executable, + const std::wstring& parameters, + base::Process& process); + // Separates a command line in `command_format` into an `executable` and // `parameters`. `executable` needs to be an absolute path, and additionally // needs to be under %programfiles% for System `scope`. Parameters on the @@ -90,12 +92,15 @@ const std::vector<std::wstring>& parameters, base::span<const std::wstring> substitutions); + // Helper method that calls `FormatAppCommandLine` and then `StartProcess`. + static HRESULT ExecuteAppCommand(const base::FilePath& executable, + const std::vector<std::wstring>& parameters, + base::span<const std::wstring> substitutions, + base::Process& process); + base::FilePath executable_; std::vector<std::wstring> parameters_; - std::optional<base::Process> process_; - std::optional<HRESULT> hr_; - friend class base::RefCountedThreadSafe<AppCommandRunner>; FRIEND_TEST_ALL_PREFIXES(AppCommandFormatComponentsInvalidPathsTest, TestCases); FRIEND_TEST_ALL_PREFIXES(AppCommandFormatComponentsProgramFilesPathsTest,
diff --git a/chrome/updater/win/app_command_runner_unittest.cc b/chrome/updater/win/app_command_runner_unittest.cc index 69d16d52..5ec59ea 100644 --- a/chrome/updater/win/app_command_runner_unittest.cc +++ b/chrome/updater/win/app_command_runner_unittest.cc
@@ -24,10 +24,7 @@ #include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "base/test/gmock_expected_support.h" -#include "base/test/task_environment.h" #include "base/test/test_timeouts.h" -#include "base/threading/platform_thread.h" -#include "base/time/time.h" #include "base/win/scoped_localalloc.h" #include "build/branding_buildflags.h" #include "chrome/updater/test/test_scope.h" @@ -68,7 +65,7 @@ test::DeleteAppClientKey(GetUpdaterScopeForTesting(), kAppId1); } - HResultOr<scoped_refptr<AppCommandRunner>> CreateAppCommandRunner( + HResultOr<AppCommandRunner> CreateAppCommandRunner( const std::wstring& app_id, const std::wstring& command_id, const std::wstring& command_line_format) { @@ -78,7 +75,7 @@ command_id); } - HResultOr<scoped_refptr<AppCommandRunner>> CreateProcessLauncherRunner( + HResultOr<AppCommandRunner> CreateProcessLauncherRunner( const std::wstring& app_id, const std::wstring& name, const std::wstring& pv, @@ -93,7 +90,6 @@ base::CommandLine cmd_exe_command_line_{base::CommandLine::NO_PROGRAM}; base::ScopedTempDir temp_programfiles_dir_; - base::test::TaskEnvironment environment_; }; class AppCommandRunnerTest : public AppCommandRunnerTestBase {}; @@ -368,8 +364,31 @@ const int expected_exit_code; }; +class AppCommandExecuteTest + : public ::testing::WithParamInterface<AppCommandTestCase>, + public AppCommandRunnerTestBase {}; + +INSTANTIATE_TEST_SUITE_P(AppCommandExecuteTestCases, + AppCommandExecuteTest, + ::testing::ValuesIn(std::vector<AppCommandTestCase>{ + {{L"/c", L"exit 7"}, {}, 7}, + {{L"/c", L"exit %1"}, {L"5420"}, 5420}, + })); + +TEST_P(AppCommandExecuteTest, TestCases) { + base::Process process; + ASSERT_HRESULT_SUCCEEDED(AppCommandRunner::ExecuteAppCommand( + cmd_exe_command_line_.GetProgram(), GetParam().input, + GetParam().substitutions, process)); + + int exit_code = 0; + EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), + &exit_code)); + EXPECT_EQ(exit_code, GetParam().expected_exit_code); +} + TEST_F(AppCommandRunnerTest, NoApp) { - HResultOr<scoped_refptr<AppCommandRunner>> app_command_runner = + HResultOr<AppCommandRunner> app_command_runner = AppCommandRunner::LoadAppCommand(GetUpdaterScopeForTesting(), kAppId1, kCmdId1); EXPECT_FALSE(app_command_runner.has_value()); @@ -378,7 +397,7 @@ TEST_F(AppCommandRunnerTest, NoCmd) { test::CreateAppCommandRegistry(GetUpdaterScopeForTesting(), kAppId1, kCmdId1, kCmdLineValid); - HResultOr<scoped_refptr<AppCommandRunner>> app_command_runner = + HResultOr<AppCommandRunner> app_command_runner = AppCommandRunner::LoadAppCommand(GetUpdaterScopeForTesting(), kAppId1, kCmdId2); EXPECT_FALSE(app_command_runner.has_value()); @@ -396,11 +415,10 @@ })); TEST_P(RunAppCommandFormatTest, TestCases) { - scoped_refptr<AppCommandRunner> app_command_runner = - base::MakeRefCounted<AppCommandRunner>(); + AppCommandRunner app_command_runner; base::Process process; - ASSERT_EQ(app_command_runner->Run(GetParam().substitutions, process), + ASSERT_EQ(app_command_runner.Run(GetParam().substitutions, process), E_UNEXPECTED); ASSERT_OK_AND_ASSIGN( @@ -410,7 +428,7 @@ base::StrCat({cmd_exe_command_line_.GetCommandLineString(), L" ", base::JoinString(GetParam().input, L" ")}))); ASSERT_HRESULT_SUCCEEDED( - app_command_runner->Run(GetParam().substitutions, process)); + app_command_runner.Run(GetParam().substitutions, process)); int exit_code = 0; EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), @@ -486,19 +504,20 @@ return; } + HResultOr<AppCommandRunner> app_command_runner; base::Process process; - HResultOr<scoped_refptr<AppCommandRunner>> app_command_runner = - CreateProcessLauncherRunner( - kAppId1, GetParam().app_name, GetParam().app_version, - GetParam().cmd_id, - base::StrCat({cmd_exe_command_line_.GetCommandLineString(), L" ", - base::JoinString(GetParam().input, L" ")})); + ASSERT_EQ(app_command_runner->Run({}, process), E_UNEXPECTED); + + app_command_runner = CreateProcessLauncherRunner( + kAppId1, GetParam().app_name, GetParam().app_version, GetParam().cmd_id, + base::StrCat({cmd_exe_command_line_.GetCommandLineString(), L" ", + base::JoinString(GetParam().input, L" ")})); ASSERT_EQ(app_command_runner.error_or(S_OK), GetParam().expected_hr); if (FAILED(GetParam().expected_hr)) { return; } - ASSERT_HRESULT_SUCCEEDED(app_command_runner.value()->Run({}, process)); + ASSERT_HRESULT_SUCCEEDED(app_command_runner->Run({}, process)); int exit_code = 0; EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), @@ -539,10 +558,9 @@ GTEST_SKIP(); } - scoped_refptr<AppCommandRunner> app_command_runner = - base::MakeRefCounted<AppCommandRunner>(); + AppCommandRunner app_command_runner; base::Process process; - ASSERT_EQ(app_command_runner->Run({}, process), E_UNEXPECTED); + ASSERT_EQ(app_command_runner.Run({}, process), E_UNEXPECTED); if (GetParam().cmd_id_appcommand) { test::CreateAppCommandRegistry( @@ -565,7 +583,7 @@ AppCommandRunner::LoadAppCommand(GetUpdaterScopeForTesting(), kAppId1, GetParam().cmd_id_to_execute)); - ASSERT_HRESULT_SUCCEEDED(app_command_runner->Run({}, process)); + ASSERT_HRESULT_SUCCEEDED(app_command_runner.Run({}, process)); int exit_code = 0; EXPECT_TRUE(process.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(), @@ -610,7 +628,7 @@ base::JoinString(app_command.input, L" ")})); }); - const std::vector<scoped_refptr<AppCommandRunner>> app_command_runners = + const std::vector<AppCommandRunner> app_command_runners = AppCommandRunner::LoadAutoRunOnOsUpgradeAppCommands( GetUpdaterScopeForTesting(), kAppId1); @@ -618,9 +636,8 @@ std::ranges::for_each( app_command_runners, [&](const auto& app_command_runner) { base::Process process; - EXPECT_HRESULT_SUCCEEDED(app_command_runner->Run({}, process)); + EXPECT_HRESULT_SUCCEEDED(app_command_runner.Run({}, process)); EXPECT_TRUE(process.WaitForExit(/*exit_code=*/nullptr)); - base::PlatformThread::Sleep(TestTimeouts::tiny_timeout()); }); }
diff --git a/chromeos/CHROMEOS_LKGM b/chromeos/CHROMEOS_LKGM index bfbcd6cd..9ee9ec0a 100644 --- a/chromeos/CHROMEOS_LKGM +++ b/chromeos/CHROMEOS_LKGM
@@ -1 +1 @@ -16442.0.0-1072259 \ No newline at end of file +16443.0.0-1072279 \ No newline at end of file
diff --git a/chromeos/ash/components/boca/boca_session_manager.cc b/chromeos/ash/components/boca/boca_session_manager.cc index 7740f52..add08d2 100644 --- a/chromeos/ash/components/boca/boca_session_manager.cc +++ b/chromeos/ash/components/boca/boca_session_manager.cc
@@ -7,6 +7,7 @@ #include <algorithm> #include <memory> #include <optional> +#include <utility> #include "ash/constants/ash_constants.h" #include "ash/constants/ash_features.h" @@ -424,9 +425,10 @@ std::move(frame_received_callback), std::move(crd_state_callback)); } -void BocaSessionManager::EndSpotlightSession() { +void BocaSessionManager::EndSpotlightSession( + base::OnceClosure on_stopped_callback) { CHECK(ash::features::IsBocaSpotlightRobotRequesterEnabled()); - remoting_client_manager_->StopCrdClient(base::DoNothing()); + remoting_client_manager_->StopCrdClient(std::move(on_stopped_callback)); } std::string BocaSessionManager::GetDeviceRobotEmail() {
diff --git a/chromeos/ash/components/boca/boca_session_manager.h b/chromeos/ash/components/boca/boca_session_manager.h index 640d5bf1..c8ee747 100644 --- a/chromeos/ash/components/boca/boca_session_manager.h +++ b/chromeos/ash/components/boca/boca_session_manager.h
@@ -246,7 +246,7 @@ // Calls the `SpotlightRemotingClientManager` to try and stop an existing // session and then free up any remaining resources. - void EndSpotlightSession(); + virtual void EndSpotlightSession(base::OnceClosure on_stopped_callback); virtual std::string GetDeviceRobotEmail();
diff --git a/chromeos/constants/chromeos_features.cc b/chromeos/constants/chromeos_features.cc index 11602a7..94956cd 100644 --- a/chromeos/constants/chromeos_features.cc +++ b/chromeos/constants/chromeos_features.cc
@@ -293,6 +293,9 @@ BASE_FEATURE(kWebAppManifestProtocolHandlerSupport, base::FEATURE_DISABLED_BY_DEFAULT); +// Controls whether Vids is preinstalled. +BASE_FEATURE(kVidsAppPreinstall, base::FEATURE_ENABLED_BY_DEFAULT); + bool IsBatteryBadgeIconEnabled() { return base::FeatureList::IsEnabled(kBatteryBadgeIcon); }
diff --git a/chromeos/constants/chromeos_features.h b/chromeos/constants/chromeos_features.h index 05a9790..021e4b9 100644 --- a/chromeos/constants/chromeos_features.h +++ b/chromeos/constants/chromeos_features.h
@@ -124,6 +124,8 @@ BASE_DECLARE_FEATURE(kNotebookLmAppShelfPinReset); COMPONENT_EXPORT(CHROMEOS_CONSTANTS) BASE_DECLARE_FEATURE(kWebAppManifestProtocolHandlerSupport); +COMPONENT_EXPORT(CHROMEOS_CONSTANTS) +BASE_DECLARE_FEATURE(kVidsAppPreinstall); // Keep alphabetized.
diff --git a/chromeos/crosapi/mojom/vpn_service.mojom b/chromeos/crosapi/mojom/vpn_service.mojom index 825f3bd..b44397f 100644 --- a/chromeos/crosapi/mojom/vpn_service.mojom +++ b/chromeos/crosapi/mojom/vpn_service.mojom
@@ -70,29 +70,11 @@ DestroyConfiguration@1(string configuration_name) => (VpnErrorResponse? error); - // Set |parameters| for the active VPN configuration after verifying that it - // belongs to the extension. - // See chrome.vpnProvider.setParameters(...) - // We use mojo_base.mojom.DictionaryValue as the type because: - // * The shill counterpart is stable and expects base::Value with type=dict. - // * Both the supplier and consumer of this information uses a type - // interchangeable with mojo_base.mojom.DictionaryValue. While we could add - // a translation layer to a strongly typed mojom struct, this adds an - // overhead and the potential for errors with no benefit. - SetParameters@2(mojo_base.mojom.DictionaryValue parameters) - => (VpnErrorResponse? error); + // SetParameters@2 was removed. - // Sends an IP packet contained in |data| to the active VPN configuration - // after verifying that it belongs to the extension. - // See chrome.vpnProvider.sendPacket(...) - SendPacket@3(array<uint8> data) - => (VpnErrorResponse? error); + // SendPacket@3 was removed. - // Notifies new connection state to the active VPN configuration after - // verifying that it belongs to the extension. - // See chrome.vpnProvider.notifyConnectionStateChanged(...) - NotifyConnectionStateChanged@4(bool connection_success) - => (VpnErrorResponse? error); + // NotifyConnectionStateChanged@4 was removed. // Binds |pepper_vpn_proxy_observer| to the active configuration if it belongs // to the extension and has name equal to
diff --git a/clank b/clank index e77b8ef..e1b431c 160000 --- a/clank +++ b/clank
@@ -1 +1 @@ -Subproject commit e77b8efbb4d973044f6b8d448e2c578c0900db51 +Subproject commit e1b431c9a8ec43eb47ae9e1bca1e1bfe86ee5445
diff --git a/components/autofill/core/browser/data_model/transliterator.cc b/components/autofill/core/browser/data_model/transliterator.cc index 6f08b6d..a6abfcab 100644 --- a/components/autofill/core/browser/data_model/transliterator.cc +++ b/components/autofill/core/browser/data_model/transliterator.cc
@@ -13,6 +13,7 @@ #include "base/i18n/unicodestring.h" #include "base/memory/ptr_util.h" #include "base/metrics/histogram_functions.h" +#include "base/strings/strcat.h" #include "base/strings/string_util.h" #include "components/autofill/core/browser/country_type.h" #include "components/autofill/core/browser/data_model/addresses/address.h" @@ -54,9 +55,29 @@ std::unique_ptr<base::i18n::Transliterator> CreateTransliterator( TransliterationId id) { - std::string transliteration_rules; std::unique_ptr<base::i18n::Transliterator> transliterator; + // Apply a simplified version of the "::de-ASCII" transliteration, which + // follows DIN 5007-2 ("ö" becomes "oe"). Here we map everything to lower case + // because that happens with "::Lower" anyway. + constexpr std::string_view kGermanRules = + "[ö {o \u0308} Ö {O \u0308}] → oe;" + "[ä {a \u0308} Ä {A \u0308}] → ae;" + "[ü {u \u0308} Ü {U \u0308}] → ue;"; + + // The following rules are happening in the following order: + // First there are `TransliterationId::kGerman` specific rules if they are + // present, then + // "::NFD;" performs a decomposition and normalization. (â becomes a and Ì‚) + // "::[:Nonspacing Mark:] Remove;" removes the " Ì‚" + // "::Lower;" converts the result to lower case + // "::NFC;" re-composes the decomposed characters + // "::Latin-ASCII;" converts various other Latin characters to an ASCII + // representation (e.g. "Å‚", which does not get decomposed, to "l"; "ß" + // to "ss"). + constexpr std::string_view kDefaultRules = + "::NFD; ::[:Nonspacing Mark:] Remove; ::Lower; ::NFC; ::Latin-ASCII;"; + switch (id) { case TransliterationId::kKatakanaToHiragana: transliterator = base::i18n::CreateTransliterator("Katakana-Hiragana"); @@ -65,30 +86,12 @@ transliterator = base::i18n::CreateTransliterator("Hiragana-Katakana"); break; case TransliterationId::kGerman: - // Apply a simplified version of the "::de-ASCII" transliteration, which - // follows DIN 5007-2 ("ö" becomes "oe"). Here we map everything to - // lower case because that happens with "::Lower" anyway. - transliteration_rules = - "[ö {o \u0308} Ö {O \u0308}] → oe;" - "[ä {a \u0308} Ä {A \u0308}] → ae;" - "[ü {u \u0308} Ü {U \u0308}] → ue;"; - [[fallthrough]]; - case TransliterationId::kDefault: - // These rules are happening in the following order: - // First there are `TransliterationId::kGerman` specific rules if they are - // present, then - // "::NFD;" performs a decomposition and normalization. - // (â becomes a and Ì‚) - // "::[:Nonspacing Mark:] Remove;" removes the " Ì‚" - // "::Lower;" converts the result to lower case - // "::NFC;" re-composes the decomposed characters - // "::Latin-ASCII;" converts various other Latin characters to an ASCII - // representation (e.g. "Å‚", which does not get decomposed, to "l"; "ß" - // to "ss"). - transliteration_rules += - "::NFD; ::[:Nonspacing Mark:] Remove; ::Lower; ::NFC; ::Latin-ASCII;"; transliterator = base::i18n::CreateTransliteratorFromRules( - "NormalizeForAddresses", transliteration_rules); + "DE_NormalizForAddress", base::StrCat({kGermanRules, kDefaultRules})); + break; + case TransliterationId::kDefault: + transliterator = base::i18n::CreateTransliteratorFromRules( + "NormalizeForAddress", kDefaultRules); break; }
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc index 2beb3ee..8fd9f6ea 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator.cc
@@ -1266,9 +1266,9 @@ switch (id) { case BnplIssuer::IssuerId::kBnplAffirm: return 4; - case BnplIssuer::IssuerId::kBnplZip: - return 3; case BnplIssuer::IssuerId::kBnplKlarna: + return 3; + case BnplIssuer::IssuerId::kBnplZip: return 2; case BnplIssuer::IssuerId::kBnplAfterpay: NOTREACHED();
diff --git a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc index 7dd34ce..c8a1478 100644 --- a/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc +++ b/components/autofill/core/browser/suggestions/payments/payments_suggestion_generator_unittest.cc
@@ -2194,10 +2194,10 @@ /*labels=*/ {{Suggestion::Text(l10n_util::GetStringFUTF16( IDS_AUTOFILL_BNPL_CREDIT_CARD_SUGGESTION_LABEL_THREE_ISSUERS, - // Affirm comes before Zip, and Zip comes before Klarna. + // Affirm comes before Klarna, and Klarna comes before Zip. bnpl_issuers[2].GetDisplayName(), - bnpl_issuers[1].GetDisplayName(), - bnpl_issuers[0].GetDisplayName()))}})); + bnpl_issuers[0].GetDisplayName(), + bnpl_issuers[1].GetDisplayName()))}})); } TEST_F(PaymentsSuggestionGeneratorTest, CreateBnplSuggestion_FlagDisabled) {
diff --git a/components/cast_receiver/renderer/public/content_renderer_client_mixins.h b/components/cast_receiver/renderer/public/content_renderer_client_mixins.h index 2d8d796..d08d440b 100644 --- a/components/cast_receiver/renderer/public/content_renderer_client_mixins.h +++ b/components/cast_receiver/renderer/public/content_renderer_client_mixins.h
@@ -9,10 +9,7 @@ #include <string_view> #include "base/functional/callback_forward.h" - -namespace blink { -class URLLoaderThrottleProvider; -} // namespace blink +#include "third_party/blink/public/platform/url_loader_throttle_provider.h" namespace content { class RenderFrame;
diff --git a/components/component_updater/android/loader_policies/tpcd_metadata_component_loader_policy.cc b/components/component_updater/android/loader_policies/tpcd_metadata_component_loader_policy.cc index 216245bb9..9a5929f 100644 --- a/components/component_updater/android/loader_policies/tpcd_metadata_component_loader_policy.cc +++ b/components/component_updater/android/loader_policies/tpcd_metadata_component_loader_policy.cc
@@ -31,7 +31,7 @@ &raw_tpcd_metadata)) { return raw_tpcd_metadata; } - return nullptr; + return std::nullopt; } } // namespace
diff --git a/components/cronet/android/cronet_bidirectional_stream_adapter.cc b/components/cronet/android/cronet_bidirectional_stream_adapter.cc index 41d95037..fb665d60 100644 --- a/components/cronet/android/cronet_bidirectional_stream_adapter.cc +++ b/components/cronet/android/cronet_bidirectional_stream_adapter.cc
@@ -67,7 +67,7 @@ } // namespace CronetMetrics::CronetMetrics() = default; -CronetMetrics::CronetMetrics(CronetMetrics& metrics) = default; +CronetMetrics::CronetMetrics(const CronetMetrics& metrics) = default; CronetMetrics::~CronetMetrics() = default; PendingWriteData::PendingWriteData(
diff --git a/components/cronet/android/cronet_bidirectional_stream_adapter.h b/components/cronet/android/cronet_bidirectional_stream_adapter.h index d8e50f3..04a43e8 100644 --- a/components/cronet/android/cronet_bidirectional_stream_adapter.h +++ b/components/cronet/android/cronet_bidirectional_stream_adapter.h
@@ -43,7 +43,7 @@ // not giving us a choice. // https://www.chromium.org/developers/coding-style/chromium-style-checker-errors/#constructordestructor-errors CronetMetrics(); - CronetMetrics(CronetMetrics& metrics); + CronetMetrics(const CronetMetrics& metrics); ~CronetMetrics(); };
diff --git a/components/cronet/native/engine.cc b/components/cronet/native/engine.cc index 8df83fd0..7efc1f67 100644 --- a/components/cronet/native/engine.cc +++ b/components/cronet/native/engine.cc
@@ -93,6 +93,132 @@ namespace cronet { +// The struct stream_engine for grpc support. +// Holds net::URLRequestContextGetter and app-specific annotation. +class Cronet_EngineImpl::StreamEngineImpl : public stream_engine { + public: + explicit StreamEngineImpl(net::URLRequestContextGetter* context_getter) { + context_getter_ = context_getter; + obj = context_getter_.get(); + annotation = nullptr; + } + + ~StreamEngineImpl() { + obj = nullptr; + annotation = nullptr; + } + + private: + scoped_refptr<net::URLRequestContextGetter> context_getter_; +}; + +// Callback is owned by CronetContext. It is invoked and deleted +// on the network thread. +class Cronet_EngineImpl::Callback : public CronetContext::Callback { + public: + explicit Callback(Cronet_EngineImpl* engine); + + Callback(const Callback&) = delete; + Callback& operator=(const Callback&) = delete; + + ~Callback() override; + + // CronetContext::Callback implementation: + void OnInitNetworkThread() override LOCKS_EXCLUDED(engine_->lock_); + void OnDestroyNetworkThread() override; + void OnEffectiveConnectionTypeChanged( + net::EffectiveConnectionType effective_connection_type) override; + void OnRTTOrThroughputEstimatesComputed( + int32_t http_rtt_ms, + int32_t transport_rtt_ms, + int32_t downstream_throughput_kbps) override; + void OnRTTObservation(int32_t rtt_ms, + int32_t timestamp_ms, + net::NetworkQualityObservationSource source) override; + void OnThroughputObservation( + int32_t throughput_kbps, + int32_t timestamp_ms, + net::NetworkQualityObservationSource source) override; + void OnStopNetLogCompleted() override LOCKS_EXCLUDED(engine_->lock_); + void OnBeforeTunnelRequest( + int chain_id, + net::ProxyDelegate::OnBeforeTunnelRequestCallback callback) override { + NOTREACHED(); + } + void OnTunnelHeadersReceived(int chain_id, + const net::HttpResponseHeaders& response_headers, + net::CompletionOnceCallback callback) override { + NOTREACHED(); + } + + private: + // The engine which owns context that owns |this| callback. + const raw_ptr<Cronet_EngineImpl> engine_; + + // All methods are invoked on the network thread. + THREAD_CHECKER(network_thread_checker_); +}; + +Cronet_EngineImpl::Callback::Callback(Cronet_EngineImpl* engine) + : engine_(engine) { + DETACH_FROM_THREAD(network_thread_checker_); +} + +Cronet_EngineImpl::Callback::~Callback() = default; + +void Cronet_EngineImpl::Callback::OnInitNetworkThread() { + DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); + // It is possible that engine_->context_ is reset from main thread while + // being intialized on network thread. + base::AutoLock lock(engine_->lock_); + if (engine_->context_) { + // Initialize bidirectional stream engine for grpc. + engine_->stream_engine_ = std::make_unique<StreamEngineImpl>( + engine_->context_->CreateURLRequestContextGetter()); + engine_->init_completed_.Signal(); + } +} + +void Cronet_EngineImpl::Callback::OnDestroyNetworkThread() { + DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); + DCHECK(!engine_->stream_engine_); +} + +void Cronet_EngineImpl::Callback::OnEffectiveConnectionTypeChanged( + net::EffectiveConnectionType effective_connection_type) { + NOTIMPLEMENTED(); +} + +void Cronet_EngineImpl::Callback::OnRTTOrThroughputEstimatesComputed( + int32_t http_rtt_ms, + int32_t transport_rtt_ms, + int32_t downstream_throughput_kbps) { + NOTIMPLEMENTED(); +} + +void Cronet_EngineImpl::Callback::OnRTTObservation( + int32_t rtt_ms, + int32_t timestamp_ms, + net::NetworkQualityObservationSource source) { + NOTIMPLEMENTED(); +} + +void Cronet_EngineImpl::Callback::OnThroughputObservation( + int32_t throughput_kbps, + int32_t timestamp_ms, + net::NetworkQualityObservationSource source) { + NOTIMPLEMENTED(); +} + +void Cronet_EngineImpl::Callback::OnStopNetLogCompleted() { + DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); + CHECK(engine_); + base::AutoLock lock(engine_->lock_); + DCHECK(engine_->is_logging_); + engine_->is_logging_ = false; + engine_->stop_netlog_completed_.Signal(); +} + Cronet_EngineImpl::Cronet_EngineImpl() : init_completed_(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::NOT_SIGNALED), @@ -351,132 +477,6 @@ return request_finished_registrations_.size() > 0; } -// The struct stream_engine for grpc support. -// Holds net::URLRequestContextGetter and app-specific annotation. -class Cronet_EngineImpl::StreamEngineImpl : public stream_engine { - public: - explicit StreamEngineImpl(net::URLRequestContextGetter* context_getter) { - context_getter_ = context_getter; - obj = context_getter_.get(); - annotation = nullptr; - } - - ~StreamEngineImpl() { - obj = nullptr; - annotation = nullptr; - } - - private: - scoped_refptr<net::URLRequestContextGetter> context_getter_; -}; - -// Callback is owned by CronetContext. It is invoked and deleted -// on the network thread. -class Cronet_EngineImpl::Callback : public CronetContext::Callback { - public: - explicit Callback(Cronet_EngineImpl* engine); - - Callback(const Callback&) = delete; - Callback& operator=(const Callback&) = delete; - - ~Callback() override; - - // CronetContext::Callback implementation: - void OnInitNetworkThread() override LOCKS_EXCLUDED(engine_->lock_); - void OnDestroyNetworkThread() override; - void OnEffectiveConnectionTypeChanged( - net::EffectiveConnectionType effective_connection_type) override; - void OnRTTOrThroughputEstimatesComputed( - int32_t http_rtt_ms, - int32_t transport_rtt_ms, - int32_t downstream_throughput_kbps) override; - void OnRTTObservation(int32_t rtt_ms, - int32_t timestamp_ms, - net::NetworkQualityObservationSource source) override; - void OnThroughputObservation( - int32_t throughput_kbps, - int32_t timestamp_ms, - net::NetworkQualityObservationSource source) override; - void OnStopNetLogCompleted() override LOCKS_EXCLUDED(engine_->lock_); - void OnBeforeTunnelRequest( - int chain_id, - net::ProxyDelegate::OnBeforeTunnelRequestCallback callback) override { - NOTREACHED(); - } - void OnTunnelHeadersReceived(int chain_id, - const net::HttpResponseHeaders& response_headers, - net::CompletionOnceCallback callback) override { - NOTREACHED(); - } - - private: - // The engine which owns context that owns |this| callback. - const raw_ptr<Cronet_EngineImpl> engine_; - - // All methods are invoked on the network thread. - THREAD_CHECKER(network_thread_checker_); -}; - -Cronet_EngineImpl::Callback::Callback(Cronet_EngineImpl* engine) - : engine_(engine) { - DETACH_FROM_THREAD(network_thread_checker_); -} - -Cronet_EngineImpl::Callback::~Callback() = default; - -void Cronet_EngineImpl::Callback::OnInitNetworkThread() { - DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); - // It is possible that engine_->context_ is reset from main thread while - // being intialized on network thread. - base::AutoLock lock(engine_->lock_); - if (engine_->context_) { - // Initialize bidirectional stream engine for grpc. - engine_->stream_engine_ = std::make_unique<StreamEngineImpl>( - engine_->context_->CreateURLRequestContextGetter()); - engine_->init_completed_.Signal(); - } -} - -void Cronet_EngineImpl::Callback::OnDestroyNetworkThread() { - DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); - DCHECK(!engine_->stream_engine_); -} - -void Cronet_EngineImpl::Callback::OnEffectiveConnectionTypeChanged( - net::EffectiveConnectionType effective_connection_type) { - NOTIMPLEMENTED(); -} - -void Cronet_EngineImpl::Callback::OnRTTOrThroughputEstimatesComputed( - int32_t http_rtt_ms, - int32_t transport_rtt_ms, - int32_t downstream_throughput_kbps) { - NOTIMPLEMENTED(); -} - -void Cronet_EngineImpl::Callback::OnRTTObservation( - int32_t rtt_ms, - int32_t timestamp_ms, - net::NetworkQualityObservationSource source) { - NOTIMPLEMENTED(); -} - -void Cronet_EngineImpl::Callback::OnThroughputObservation( - int32_t throughput_kbps, - int32_t timestamp_ms, - net::NetworkQualityObservationSource source) { - NOTIMPLEMENTED(); -} - -void Cronet_EngineImpl::Callback::OnStopNetLogCompleted() { - DCHECK_CALLED_ON_VALID_THREAD(network_thread_checker_); - CHECK(engine_); - base::AutoLock lock(engine_->lock_); - DCHECK(engine_->is_logging_); - engine_->is_logging_ = false; - engine_->stop_netlog_completed_.Signal(); -} - void Cronet_EngineImpl::SetMockCertVerifierForTesting( std::unique_ptr<net::CertVerifier> mock_cert_verifier) { CHECK(!context_);
diff --git a/components/data_sharing/BUILD.gn b/components/data_sharing/BUILD.gn index 7b83164..f9329a6c 100644 --- a/components/data_sharing/BUILD.gn +++ b/components/data_sharing/BUILD.gn
@@ -15,6 +15,7 @@ deps = [ "//components/data_sharing/internal:unit_tests", + "//components/data_sharing/migration/internal:unit_tests", "//components/data_sharing/public:unit_tests", ]
diff --git a/components/data_sharing/migration/internal/BUILD.gn b/components/data_sharing/migration/internal/BUILD.gn index 3d7aff7..0d35c064 100644 --- a/components/data_sharing/migration/internal/BUILD.gn +++ b/components/data_sharing/migration/internal/BUILD.gn
@@ -9,11 +9,31 @@ } source_set("internal") { + defines = [ "IS_DATA_SHARING_MIGRATION_IMPL=1" ] + sources = [ "base_migratable_sync_service.cc", "migratable_sync_service_coordinator_impl.cc", "migratable_sync_service_coordinator_impl.h", + "migration_state_database.h", + "migration_state_database_impl.cc", + "migration_state_database_impl.h", ] - deps = [ "//components/data_sharing/migration/public" ] + deps = [ + ":migration_state_proto", + "//base", + "//components/data_sharing/public", + ] +} + +source_set("unit_tests") { + testonly = true + sources = [ "migration_state_database_impl_unittest.cc" ] + deps = [ + ":internal", + "//base", + "//base/test:test_support", + "//testing/gtest", + ] }
diff --git a/components/data_sharing/migration/internal/migration_state_database.h b/components/data_sharing/migration/internal/migration_state_database.h new file mode 100644 index 0000000..5b2453c1 --- /dev/null +++ b/components/data_sharing/migration/internal/migration_state_database.h
@@ -0,0 +1,49 @@ +// 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_DATA_SHARING_MIGRATION_INTERNAL_MIGRATION_STATE_DATABASE_H_ +#define COMPONENTS_DATA_SHARING_MIGRATION_INTERNAL_MIGRATION_STATE_DATABASE_H_ + +#include <optional> + +#include "base/files/file_path.h" +#include "base/functional/callback_forward.h" +#include "components/data_sharing/migration/internal/protocol/migration_state.pb.h" +#include "components/data_sharing/migration/public/context_id.h" + +namespace data_sharing { + +// A SQLite database for storing data_sharing migration state. This database +// stores a proto for each sync entity, keyed by the context id. +class MigrationStateDatabase { + public: + // Callback for when the database has been initialized. The boolean argument + // indicates success or failure. + using InitCallback = base::OnceCallback<void(bool)>; + + virtual ~MigrationStateDatabase() = default; + + // Initializes the database at the given `db_path`. Must be called before any + // other methods. + virtual void Init(InitCallback callback) = 0; + + // Synchronously retrieves the migration state for a given `context_id`. + // Returns std::nullopt if the entry is not found. Must be called after Init() + // has completed successfully. + virtual std::optional<data_sharing_pb::MigrationState> GetMigrationState( + const ContextId& context_id) const = 0; + + // Synchronously adds or updates the migration state for a given + // `context_id`. The database will write to disk asynchronously after. + virtual void UpdateMigrationState( + const ContextId& context_id, + const data_sharing_pb::MigrationState& state) = 0; + + // Synchronously deletes the migration state for a given `context_id`. + virtual void DeleteMigrationState(const ContextId& context_id) = 0; +}; + +} // namespace data_sharing + +#endif // COMPONENTS_DATA_SHARING_MIGRATION_INTERNAL_MIGRATION_STATE_DATABASE_H_
diff --git a/components/data_sharing/migration/internal/migration_state_database_impl.cc b/components/data_sharing/migration/internal/migration_state_database_impl.cc new file mode 100644 index 0000000..70dc7f6 --- /dev/null +++ b/components/data_sharing/migration/internal/migration_state_database_impl.cc
@@ -0,0 +1,45 @@ +// 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/data_sharing/migration/internal/migration_state_database_impl.h" + +namespace data_sharing { + +MigrationStateDatabaseImpl::MigrationStateDatabaseImpl( + const base::FilePath& profile_dir) { + // TODO(haileywang): Implement this. +} + +MigrationStateDatabaseImpl::~MigrationStateDatabaseImpl() = default; + +void MigrationStateDatabaseImpl::Init(InitCallback callback) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // TODO(haileywang): Implement this. + is_initialized_ = true; + std::move(callback).Run(false); +} + +std::optional<data_sharing_pb::MigrationState> +MigrationStateDatabaseImpl::GetMigrationState( + const ContextId& context_id) const { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + CHECK(is_initialized_); + // TODO(haileywang): Implement this. + return std::nullopt; +} + +void MigrationStateDatabaseImpl::UpdateMigrationState( + const ContextId& context_id, + const data_sharing_pb::MigrationState& state) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // TODO(haileywang): Implement this. +} + +void MigrationStateDatabaseImpl::DeleteMigrationState( + const ContextId& context_id) { + DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); + // TODO(haileywang): Implement this. +} + +} // namespace data_sharing
diff --git a/components/data_sharing/migration/internal/migration_state_database_impl.h b/components/data_sharing/migration/internal/migration_state_database_impl.h new file mode 100644 index 0000000..1564046 --- /dev/null +++ b/components/data_sharing/migration/internal/migration_state_database_impl.h
@@ -0,0 +1,56 @@ +// 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_DATA_SHARING_MIGRATION_INTERNAL_MIGRATION_STATE_DATABASE_IMPL_H_ +#define COMPONENTS_DATA_SHARING_MIGRATION_INTERNAL_MIGRATION_STATE_DATABASE_IMPL_H_ + +#include <map> +#include <memory> +#include <string> + +#include "base/files/file_path.h" +#include "base/memory/weak_ptr.h" +#include "base/sequence_checker.h" +#include "base/task/sequenced_task_runner.h" +#include "components/data_sharing/migration/internal/migration_state_database.h" +#include "components/data_sharing/migration/internal/protocol/migration_state.pb.h" +#include "components/data_sharing/migration/public/context_id.h" + +namespace data_sharing { + +// A SQLite database for storing data_sharing migration state. This database +// stores a proto for each sync entity, keyed by the context id. The data is +// cached in memory for synchronous reads. +class MigrationStateDatabaseImpl : public MigrationStateDatabase { + public: + explicit MigrationStateDatabaseImpl(const base::FilePath& profile_dir); + ~MigrationStateDatabaseImpl() override; + MigrationStateDatabaseImpl(const MigrationStateDatabaseImpl&) = delete; + MigrationStateDatabaseImpl& operator=(const MigrationStateDatabaseImpl&) = + delete; + + // MigrationStateDatabase implementation. + void Init(InitCallback callback) override; + std::optional<data_sharing_pb::MigrationState> GetMigrationState( + const ContextId& context_id) const override; + void UpdateMigrationState( + const ContextId& context_id, + const data_sharing_pb::MigrationState& state) override; + void DeleteMigrationState(const ContextId& context_id) override; + + private: + // In-memory cache of the migration state. + std::map<ContextId, data_sharing_pb::MigrationState> cache_; + + // Whether database is initialized. + bool is_initialized_ = false; + + SEQUENCE_CHECKER(sequence_checker_); + + base::WeakPtrFactory<MigrationStateDatabaseImpl> weak_ptr_factory_{this}; +}; + +} // namespace data_sharing + +#endif // COMPONENTS_DATA_SHARING_MIGRATION_INTERNAL_MIGRATION_STATE_DATABASE_IMPL_H_
diff --git a/components/data_sharing/migration/internal/migration_state_database_impl_unittest.cc b/components/data_sharing/migration/internal/migration_state_database_impl_unittest.cc new file mode 100644 index 0000000..e1ff8c0 --- /dev/null +++ b/components/data_sharing/migration/internal/migration_state_database_impl_unittest.cc
@@ -0,0 +1,25 @@ +// 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/data_sharing/migration/internal/migration_state_database_impl.h" + +#include "base/test/task_environment.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace data_sharing { + +class MigrationStateDatabaseImplTest : public testing::Test { + public: + MigrationStateDatabaseImplTest() = default; + ~MigrationStateDatabaseImplTest() override = default; + + protected: + base::test::TaskEnvironment task_environment_; +}; + +TEST_F(MigrationStateDatabaseImplTest, ShouldDoNothing) { + // TODO(haileywang): Implement this. +} + +} // namespace data_sharing
diff --git a/components/exo/surface_tree_host_unittest.cc b/components/exo/surface_tree_host_unittest.cc index f40fbbb..0caab52 100644 --- a/components/exo/surface_tree_host_unittest.cc +++ b/components/exo/surface_tree_host_unittest.cc
@@ -334,10 +334,6 @@ return nullptr; } gpu::ContextSupport* ContextSupport() override { return nullptr; } - class GrDirectContext* GrContext() override { - ADD_FAILURE(); - return nullptr; - } gpu::SharedImageInterface* SharedImageInterface() override { ADD_FAILURE(); return nullptr;
diff --git a/components/os_crypt/async/browser/BUILD.gn b/components/os_crypt/async/browser/BUILD.gn index 45836a6..9c18006 100644 --- a/components/os_crypt/async/browser/BUILD.gn +++ b/components/os_crypt/async/browser/BUILD.gn
@@ -78,6 +78,20 @@ } } +if (is_posix && !is_apple) { + source_set("posix_key_provider") { + sources = [ + "posix_key_provider.cc", + "posix_key_provider.h", + ] + deps = [ + ":key_provider_interface", + "//base", + "//components/os_crypt/async/common", + ] + } +} + if (is_linux && use_dbus) { source_set("secret_portal_key_provider") { sources = [ @@ -99,14 +113,13 @@ source_set("freedesktop_secret_key_provider") { sources = [ - "fallback_linux_key_provider.cc", - "fallback_linux_key_provider.h", "freedesktop_secret_key_provider.cc", "freedesktop_secret_key_provider.h", ] deps = [ ":key_provider_interface", + ":posix_key_provider", "//base", "//components/dbus", "//components/os_crypt/async/common", @@ -182,6 +195,7 @@ ] deps += [ ":freedesktop_secret_key_provider", + ":posix_key_provider", ":secret_portal_key_provider", "//components/dbus", "//components/prefs:test_support",
diff --git a/components/os_crypt/async/browser/fallback_linux_key_provider.h b/components/os_crypt/async/browser/fallback_linux_key_provider.h deleted file mode 100644 index eed0cb59..0000000 --- a/components/os_crypt/async/browser/fallback_linux_key_provider.h +++ /dev/null
@@ -1,32 +0,0 @@ -// Copyright 2024 The Chromium Authors -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMPONENTS_OS_CRYPT_ASYNC_BROWSER_FALLBACK_LINUX_KEY_PROVIDER_H_ -#define COMPONENTS_OS_CRYPT_ASYNC_BROWSER_FALLBACK_LINUX_KEY_PROVIDER_H_ - -#include "components/os_crypt/async/browser/key_provider.h" - -namespace os_crypt_async { - -class FallbackLinuxKeyProvider : public KeyProvider { - public: - explicit FallbackLinuxKeyProvider(bool use_for_encryption); - - FallbackLinuxKeyProvider(const FallbackLinuxKeyProvider&) = delete; - FallbackLinuxKeyProvider& operator=(const FallbackLinuxKeyProvider&) = delete; - - ~FallbackLinuxKeyProvider() override; - - // KeyProvider: - void GetKey(KeyCallback callback) override; - bool UseForEncryption() override; - bool IsCompatibleWithOsCryptSync() override; - - private: - const bool use_for_encryption_; -}; - -} // namespace os_crypt_async - -#endif // COMPONENTS_OS_CRYPT_ASYNC_BROWSER_FALLBACK_LINUX_KEY_PROVIDER_H_
diff --git a/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc b/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc index 58a9065..3f287a5 100644 --- a/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc +++ b/components/os_crypt/async/browser/freedesktop_secret_key_provider.cc
@@ -275,7 +275,7 @@ default_collection_proxy_ = nullptr; if (password_store_ == "basic") { - // Use FallbackLinuxKeyProvider. + // Use PosixKeyProvider. FinalizeFailure(InitStatus::kDisabled, ErrorDetail::kNone); } else if (password_store_ == "gnome-libsecret") { InitializeFreedesktopSecretService();
diff --git a/components/os_crypt/async/browser/freedesktop_secret_key_provider_compat_unittest.cc b/components/os_crypt/async/browser/freedesktop_secret_key_provider_compat_unittest.cc index d21aeb3..8a865866 100644 --- a/components/os_crypt/async/browser/freedesktop_secret_key_provider_compat_unittest.cc +++ b/components/os_crypt/async/browser/freedesktop_secret_key_provider_compat_unittest.cc
@@ -13,9 +13,9 @@ #include "base/test/bind.h" #include "base/test/task_environment.h" #include "base/test/test_future.h" -#include "components/os_crypt/async/browser/fallback_linux_key_provider.h" #include "components/os_crypt/async/browser/freedesktop_secret_key_provider.h" #include "components/os_crypt/async/browser/os_crypt_async.h" +#include "components/os_crypt/async/browser/posix_key_provider.h" #include "components/os_crypt/sync/key_storage_linux.h" #include "components/os_crypt/sync/os_crypt.h" #include "testing/gtest/include/gtest/gtest.h" @@ -59,7 +59,7 @@ provider->secret_for_testing_ = kSecretKey; providers.emplace_back(0, std::move(provider)); } else { - providers.emplace_back(0, std::make_unique<FallbackLinuxKeyProvider>( + providers.emplace_back(0, std::make_unique<PosixKeyProvider>( /*use_for_encryption=*/true)); } OSCryptAsync factory(std::move(providers));
diff --git a/components/os_crypt/async/browser/fallback_linux_key_provider.cc b/components/os_crypt/async/browser/posix_key_provider.cc similarity index 66% rename from components/os_crypt/async/browser/fallback_linux_key_provider.cc rename to components/os_crypt/async/browser/posix_key_provider.cc index 5f7cda1..7c4eff9 100644 --- a/components/os_crypt/async/browser/fallback_linux_key_provider.cc +++ b/components/os_crypt/async/browser/posix_key_provider.cc
@@ -1,8 +1,8 @@ -// Copyright 2024 The Chromium Authors +// 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/os_crypt/async/browser/fallback_linux_key_provider.h" +#include "components/os_crypt/async/browser/posix_key_provider.h" #include <array> #include <utility> @@ -23,22 +23,26 @@ } // namespace -FallbackLinuxKeyProvider::FallbackLinuxKeyProvider(bool use_for_encryption) +PosixKeyProvider::PosixKeyProvider(bool use_for_encryption) : use_for_encryption_(use_for_encryption) {} -FallbackLinuxKeyProvider::~FallbackLinuxKeyProvider() = default; +PosixKeyProvider::~PosixKeyProvider() = default; -void FallbackLinuxKeyProvider::GetKey(KeyCallback callback) { +void PosixKeyProvider::GetKey(KeyCallback callback) { Encryptor::Key key(kV10Key, mojom::Algorithm::kAES128CBC); std::move(callback).Run(kEncryptionTag, std::move(key)); } -bool FallbackLinuxKeyProvider::UseForEncryption() { +bool PosixKeyProvider::UseForEncryption() { return use_for_encryption_; } -bool FallbackLinuxKeyProvider::IsCompatibleWithOsCryptSync() { +bool PosixKeyProvider::IsCompatibleWithOsCryptSync() { +#if BUILDFLAG(IS_LINUX) return false; +#else + return true; +#endif } } // namespace os_crypt_async
diff --git a/components/os_crypt/async/browser/posix_key_provider.h b/components/os_crypt/async/browser/posix_key_provider.h new file mode 100644 index 0000000..a35b10f --- /dev/null +++ b/components/os_crypt/async/browser/posix_key_provider.h
@@ -0,0 +1,32 @@ +// 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_OS_CRYPT_ASYNC_BROWSER_POSIX_KEY_PROVIDER_H_ +#define COMPONENTS_OS_CRYPT_ASYNC_BROWSER_POSIX_KEY_PROVIDER_H_ + +#include "components/os_crypt/async/browser/key_provider.h" + +namespace os_crypt_async { + +class PosixKeyProvider : public KeyProvider { + public: + explicit PosixKeyProvider(bool use_for_encryption); + + PosixKeyProvider(const PosixKeyProvider&) = delete; + PosixKeyProvider& operator=(const PosixKeyProvider&) = delete; + + ~PosixKeyProvider() override; + + // KeyProvider: + void GetKey(KeyCallback callback) override; + bool UseForEncryption() override; + bool IsCompatibleWithOsCryptSync() override; + + private: + const bool use_for_encryption_; +}; + +} // namespace os_crypt_async + +#endif // COMPONENTS_OS_CRYPT_ASYNC_BROWSER_POSIX_KEY_PROVIDER_H_
diff --git a/components/page_content_annotations/core/page_content_annotations_service.cc b/components/page_content_annotations/core/page_content_annotations_service.cc index 58dee3f8..f878db9 100644 --- a/components/page_content_annotations/core/page_content_annotations_service.cc +++ b/components/page_content_annotations/core/page_content_annotations_service.cc
@@ -519,7 +519,7 @@ MaybeRecordVisibilityUKM(visit, content_annotations); NotifyPageContentAnnotatedObservers( - AnnotationType::kContentVisibility, visit.url, + AnnotationType::kContentVisibility, visit, PageContentAnnotationsResult::CreateContentVisibilityScoreResult( content_annotations->visibility_score)); @@ -887,14 +887,14 @@ void PageContentAnnotationsService::NotifyPageContentAnnotatedObservers( AnnotationType annotation_type, - const GURL& url, + const HistoryVisit& visit, const PageContentAnnotationsResult& page_content_annotations_result) { if (page_content_annotations_observers_.find(annotation_type) == page_content_annotations_observers_.end()) { return; } for (auto& observer : page_content_annotations_observers_[annotation_type]) { - observer.OnPageContentAnnotated(url, page_content_annotations_result); + observer.OnPageContentAnnotated(visit, page_content_annotations_result); } }
diff --git a/components/page_content_annotations/core/page_content_annotations_service.h b/components/page_content_annotations/core/page_content_annotations_service.h index 58b6f05e..2cea359 100644 --- a/components/page_content_annotations/core/page_content_annotations_service.h +++ b/components/page_content_annotations/core/page_content_annotations_service.h
@@ -135,7 +135,7 @@ class PageContentAnnotationsObserver : public base::CheckedObserver { public: virtual void OnPageContentAnnotated( - const GURL& url, + const HistoryVisit& visit, const PageContentAnnotationsResult& result) = 0; }; @@ -333,7 +333,7 @@ // |annotation_type|. void NotifyPageContentAnnotatedObservers( AnnotationType annotation_type, - const GURL& url, + const page_content_annotations::HistoryVisit& visit, const PageContentAnnotationsResult& page_content_annotations_result); // Callback invoked when a response for |optimization_type| has been received
diff --git a/components/page_content_annotations/core/page_content_cache_handler.h b/components/page_content_annotations/core/page_content_cache_handler.h index fafc7832..9aaf2fb 100644 --- a/components/page_content_annotations/core/page_content_cache_handler.h +++ b/components/page_content_annotations/core/page_content_cache_handler.h
@@ -58,7 +58,7 @@ PageContentCache* page_content_cache() { return page_content_cache_.get(); } private: - std::unique_ptr<PageContentCache> page_content_cache_; + const std::unique_ptr<PageContentCache> page_content_cache_; }; } // namespace page_content_annotations
diff --git a/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.cc b/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.cc index 779035adc..9bd01bd 100644 --- a/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.cc +++ b/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.cc
@@ -27,6 +27,7 @@ const char kGwsHeadChunkEndMarkName[] = "SearchHeadEnd"; const char kGwsBodyChunkStartMarkName[] = "SearchBodyStart"; const char kGwsBodyChunkEndMarkName[] = "SearchBodyEnd"; +const char kGwsSGLMarkName[] = "SearchSGL"; } // namespace internal
diff --git a/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.h b/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.h index 5c351b1..bbec7ec 100644 --- a/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.h +++ b/components/page_load_metrics/google/browser/gws_abandoned_page_load_metrics_observer.h
@@ -20,6 +20,7 @@ extern const char kGwsHeadChunkEndMarkName[]; extern const char kGwsBodyChunkStartMarkName[]; extern const char kGwsBodyChunkEndMarkName[]; +extern const char kGwsSGLMarkName[]; } // namespace internal // Observes and records UMA for navigations to GWS which might or might get
diff --git a/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc b/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc index 02a8fca..7f7fc5b7 100644 --- a/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc +++ b/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.cc
@@ -81,6 +81,8 @@ HISTOGRAM_PREFIX "ConnectTiming.FinalRequestSslDelay"; const char kHistogramGWSAFTEnd[] = HISTOGRAM_PREFIX "PaintTiming.AFTEnd2"; +const char kHistogramGWSAFTEndWithPreNavigationLatency[] = + HISTOGRAM_PREFIX "PaintTiming.AFTEndWithPreNavigationLatency"; const char kHistogramGWSAFTStart[] = HISTOGRAM_PREFIX "PaintTiming.AFTStart2"; const char kHistogramGWSHeadChunkStart[] = HISTOGRAM_PREFIX "PaintTiming.HeadChunkStart"; @@ -110,6 +112,7 @@ const char kHistogramGWSHCT[] = HISTOGRAM_PREFIX "CSI.HCT"; const char kHistogramGWSSCT[] = HISTOGRAM_PREFIX "CSI.SCT"; const char kHistogramGWSSRT[] = HISTOGRAM_PREFIX "CSI.SRT"; +const char kHistogramGWSSGL[] = HISTOGRAM_PREFIX "CSI.SGL"; const char kHistogramGWSTimeBetweenHCTAndSCT[] = HISTOGRAM_PREFIX "CSI.TimeBetweenHCTAndSCT"; @@ -181,6 +184,12 @@ namespace { +BASE_FEATURE(kRecordPrenavigationLatency, base::FEATURE_ENABLED_BY_DEFAULT); + +bool IsPrenavigationLatencyEnabled() { + return base::FeatureList::IsEnabled(kRecordPrenavigationLatency); +} + bool IsNavigationFromNewTabPage( GWSPageLoadMetricsObserver::NavigationSourceType type) { switch (type) { @@ -529,6 +538,15 @@ body_chunk_start_time_ = mark->start_time; } else if (mark->mark_name == internal::kGwsBodyChunkEndMarkName) { record_histogram(internal::kHistogramGWSBodyChunkEnd, timing); + } else if (IsPrenavigationLatencyEnabled() && + mark->mark_name == internal::kGwsSGLMarkName) { + // Because this is a performance mark for previous navigation, we should + // not correct the timing for prerender activation, or else we would get + // inconsistent timing. + // So, we use `mark->start_time` directly here rather than using the + // pre-adjusted `timing`. + record_histogram(internal::kHistogramGWSSGL, mark->start_time); + sgl_time_ = mark->start_time; } } } @@ -579,6 +597,38 @@ return; } + if (IsPrenavigationLatencyEnabled() && aft_end_time_.has_value()) { + // There are multiple patterns to record the prenavigation latency events: + // - For non prerendering cases: If we have prenavigation latency, we should + // add them to the AFT performance mark to get the total latency. + // - For prerendering cases: + // - If the activation happens during this navigation, we should update + // the base time to start from the activation time. This means that any + // prenavigation event that happens before activation should be ignored + // and be set to 0. + // - If the activation happens before this navigation, the + // current navigation would start as a normal (non-prerendered + // navigation), since it should not start from `OnPrerenderStart`, and + // start from `OnStart`. Hence, we would not need to correct the base + // time, and the prenavigation latency should be recorded as it is to + // be consistent with what is recorded in the server side. + auto base_time = aft_end_time_.value(); + std::optional<base::TimeDelta> prenavigation_time = sgl_time_; + if (is_prerendered_) { + // If we are in prerendering, we need to correct the AFTEnd to start from + // the activation timing. + base_time = + page_load_metrics::CorrectEventAsNavigationOrActivationOrigined( + GetDelegate(), aft_end_time_.value()); + prenavigation_time = std::nullopt; + } + + // We record pre navigation time here as well. + PAGE_LOAD_HISTOGRAM( + internal::kHistogramGWSAFTEndWithPreNavigationLatency, + base_time + prenavigation_time.value_or(base::TimeDelta())); + } + if (!WasStartedInForegroundOptionalEventInForeground( all_frames_largest_contentful_paint.Time(), GetDelegate())) { return;
diff --git a/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.h b/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.h index 55508429..3b095ab 100644 --- a/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.h +++ b/components/page_load_metrics/google/browser/gws_page_load_metrics_observer.h
@@ -189,6 +189,7 @@ std::optional<base::TimeDelta> body_chunk_start_time_; std::optional<base::TimeDelta> head_chunk_start_time_; std::optional<base::TimeDelta> head_chunk_end_time_; + std::optional<base::TimeDelta> sgl_time_; int64_t navigation_id_; };
diff --git a/components/segmentation_platform/PRESUBMIT.py b/components/segmentation_platform/PRESUBMIT.py index 002277c..7f02276 100644 --- a/components/segmentation_platform/PRESUBMIT.py +++ b/components/segmentation_platform/PRESUBMIT.py
@@ -49,8 +49,8 @@ disabled_warnings=disabled_warnings) -def _CheckHistograms(input_api, output_api): - """Checks if the histograms.txt file is up to date.""" +def _CheckUmaMetrics(input_api, output_api): + """Checks if the UMA metric lists are up to date.""" # Path to the directory containing segmentation platform models. model_dir = input_api.os_path.join('components', 'segmentation_platform', 'embedder', 'default_model') @@ -73,22 +73,29 @@ old_sys_path = input_api.sys.path sys_path_to_add = input_api.os_path.join(cwd, 'tools') input_api.sys.path.insert(0, sys_path_to_add) - import check_histograms + import generate_histogram_list finally: input_api.sys.path = old_sys_path - expected_histograms = (check_histograms.GetExpectedHistogramsFileContent()) - actual_histograms = check_histograms.GetActualHistogramsFileContent() + warnings = [] + expected_histograms = ( + generate_histogram_list.GetExpectedHistogramsFileContent()) + actual_histograms = generate_histogram_list.GetActualHistogramsFileContent( + ) + expected_user_actions = ( + generate_histogram_list.GetExpectedUserActionsFileContent()) + actual_user_actions = ( + generate_histogram_list.GetActualUserActionsFileContent()) - if expected_histograms != actual_histograms: + if (expected_user_actions != actual_user_actions + or expected_histograms != actual_histograms): error_message = ( - 'The histograms.txt file is out of date.' - '\n\nPlease run:\n' - 'python3 components/segmentation_platform/tools/check_histograms.py' - ) - return [output_api.PresubmitPromptWarning(error_message, [])] + 'The Segmentation histogram list is out of date.\n\n' + 'Please run:\npython3 components/segmentation_platform' + '/tools/generate_histogram_list.py') + warnings.append(output_api.PresubmitPromptWarning(error_message, [])) - return [] + return warnings def _CommonChecks(input_api, output_api): @@ -104,7 +111,7 @@ 'The test launcher filter file does not match the ' + f'available tests.\n\nPlease run:\n{tool_help_path}', [])) - output.extend(_CheckHistograms(input_api, output_api)) + output.extend(_CheckUmaMetrics(input_api, output_api)) return output
diff --git a/components/segmentation_platform/internal/metadata/metadata_writer.h b/components/segmentation_platform/internal/metadata/metadata_writer.h index 47e72ea..e60ae38 100644 --- a/components/segmentation_platform/internal/metadata/metadata_writer.h +++ b/components/segmentation_platform/internal/metadata/metadata_writer.h
@@ -21,6 +21,7 @@ namespace segmentation_platform { +// LINT.IfChange namespace features { // Defines default values for a feature. @@ -254,6 +255,7 @@ } } // namespace features +// LINT.ThenChange(//components/segmentation_platform/tools/generate_histogram_list.py) template <typename EnumType> using FeaturePair = std::pair<EnumType, const features::Feature>;
diff --git a/components/segmentation_platform/tools/check_histograms.py b/components/segmentation_platform/tools/check_histograms.py deleted file mode 100755 index 721f709..0000000 --- a/components/segmentation_platform/tools/check_histograms.py +++ /dev/null
@@ -1,112 +0,0 @@ -#!/usr/bin/env python3 -# Copyright 2025 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. -"""This script provides functionality for automatically keeping a list of -histograms used by segmentation platform models up to date. - -By running this script as a binary, it automatically rewrites the golden file, -but it can also be used as a Python module for presubmit scripts. -""" - -import os -import re -import sys - -# The script needs to be run from the chromium src directory. -if __name__ == '__main__' and not os.path.exists('components'): - sys.exit('This script must be run from the chromium src directory.') - -# Path to the directory containing segmentation platform models. -MODEL_DIR = os.path.join('components', 'segmentation_platform', 'embedder', - 'default_model') - -# Name of the golden file. -OUTPUT_FILENAME = 'histograms.txt' - - -def _GetComponentDirectoryPath(): - """Returns the path to the current component.""" - return os.path.join('components', 'segmentation_platform') - - -def _GetHistogramsFilePath(): - """Returns the path to the golden file.""" - component_directory = _GetComponentDirectoryPath() - return os.path.join(component_directory, 'tools', OUTPUT_FILENAME) - - -def _FindHistograms(cwd): - """Finds all histograms used in the segmentation platform models.""" - # Regex to find histogram names in various macros and structs. - # The patterns handle multi-line macro invocations. - histogram_patterns = [ - re.compile(r'SEGMENTATION_UMA_ENUM\s*\(\s*"([^"]+)"', re.MULTILINE), - re.compile(r'From(?:Enum|Value)Histogram\s*\(\s*"([^"]+)"', - re.MULTILINE), - re.compile(r'FromUserAction\s*\(\s*"([^"]+)"', re.MULTILINE), - # This pattern is more specific to UMAFeature structs to avoid - # capturing names from other structs like CustomInput. - re.compile( - r'MetadataWriter::UMAFeature\s*\{[^}]*\.name\s*=\s*"([^"]+)"', - re.MULTILINE), - re.compile(r'features::UserAction\s*\(\s*"([^"]+)"', re.MULTILINE), - re.compile(r'features::UMA\w*\s*\(\s*"([^"]+)"', re.MULTILINE), - re.compile(r'features::LatestOrDefaultValue\s*\(\s*"([^"]+)"', - re.MULTILINE), - ] - - histograms = set() - for root, _, files in os.walk(cwd): - for filename in files: - if filename.endswith('.cc') and not filename.endswith( - ('_unittest.cc', '_test.cc')): - file_path = os.path.join(root, filename) - with open(file_path, 'r', encoding='utf-8') as f: - try: - file_contents = f.read() - for pattern in histogram_patterns: - for match in pattern.finditer(file_contents): - histograms.add(match.group(1)) - except Exception as e: - print(f"Error reading file {file_path}: {e}") - return sorted(list(histograms)) - - -def _CreateHistogramsFileContent(histograms): - """Creates the content for the golden file.""" - return '\n'.join(histograms) + '\n' - - -def GetActualHistogramsFileContent(): - """Reads the current content of the golden file.""" - file_path = _GetHistogramsFilePath() - if not os.path.exists(file_path): - return "" - with open(file_path, 'r', encoding='utf-8') as f: - return f.read() - - -def GetExpectedHistogramsFileContent(): - """Creates the expected content of the golden file.""" - histograms = _FindHistograms(MODEL_DIR) - return _CreateHistogramsFileContent(histograms) - - -def _WriteHistogramsFile(file_path, content): - """Writes the content to the given file path.""" - os.makedirs(os.path.dirname(file_path), exist_ok=True) - with open(file_path, 'w', encoding='utf-8') as f: - f.write(content) - - -def main(): - """Main function to update the golden file.""" - output_file_path = _GetHistogramsFilePath() - expected_content = GetExpectedHistogramsFileContent() - _WriteHistogramsFile(output_file_path, expected_content) - print(f"Updated {output_file_path}") - - -if __name__ == '__main__': - main()
diff --git a/components/segmentation_platform/tools/generate_histogram_list.py b/components/segmentation_platform/tools/generate_histogram_list.py new file mode 100755 index 0000000..8d1a8f3 --- /dev/null +++ b/components/segmentation_platform/tools/generate_histogram_list.py
@@ -0,0 +1,150 @@ +#!/usr/bin/env python3 +# Copyright 2025 The Chromium Authors +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +"""This script provides functionality for automatically keeping a list of +histograms and user actions used by segmentation platform models up to date. + +By running this script as a binary, it automatically rewrites the golden files, +but it can also be used as a Python module for presubmit scripts. +""" + +import os +import re +import sys + +# The script needs to be run from the chromium src directory. +if __name__ == '__main__' and not os.path.exists('components'): + sys.exit('This script must be run from the chromium src directory.') + +# Path to the directory containing segmentation platform models. +# TODO(haileywang): Also include home_modules/ folder. +MODEL_DIR = os.path.join('components', 'segmentation_platform', 'embedder', + 'default_model') + +# Name of the golden files. +# TODO(haileywang): Add ukm metrics. +HISTOGRAMS_FILENAME = 'histograms.txt' +USER_ACTIONS_FILENAME = 'user_actions.txt' + + +def _GetComponentDirectoryPath(): + """Returns the path to the current component.""" + return os.path.join('components', 'segmentation_platform') + + +def _GetHistogramsFilePath(): + """Returns the path to the histograms golden file.""" + component_directory = _GetComponentDirectoryPath() + return os.path.join(component_directory, 'tools', HISTOGRAMS_FILENAME) + + +def _GetUserActionsFilePath(): + """Returns the path to the user actions golden file.""" + component_directory = _GetComponentDirectoryPath() + return os.path.join(component_directory, 'tools', USER_ACTIONS_FILENAME) + + +def _FindMetrics(cwd, patterns): + """Finds all metrics matching the given patterns.""" + metrics = set() + for root, _, files in os.walk(cwd): + for filename in files: + if not filename.endswith('.cc') or filename.endswith( + ('_unittest.cc', '_test.cc')): + continue + + file_path = os.path.join(root, filename) + with open(file_path, 'r', encoding='utf-8') as f: + try: + file_contents = f.read() + for pattern in patterns: + for match in pattern.finditer(file_contents): + metrics.add(match.group(1)) + except Exception as e: + print(f"Error reading file {file_path}: {e}") + return sorted(list(metrics)) + + +def _FindHistograms(cwd): + """Finds all histograms used in the segmentation platform models.""" + histogram_patterns = [ + re.compile(r'From(?:Enum|Value)Histogram\s*\(\s*"([^"]+)"', + re.MULTILINE), + re.compile(r'FromLatestOrDefaultValue\s*\(\s*"([^"]+)"', re.MULTILINE), + re.compile( + r'MetadataWriter::UMAFeature\s*\{[^}]*\.name\s*=\s*"([^"]+)"', + re.MULTILINE), + re.compile(r'features::UMA\w*\s*\(\s*"([^"]+)"', re.MULTILINE), + re.compile(r'features::LatestOrDefaultValue\s*\(\s*"([^"]+)"', + re.MULTILINE), + ] + return _FindMetrics(cwd, histogram_patterns) + + +def _FindUserActions(cwd): + """Finds all user actions used in the segmentation platform models.""" + user_action_patterns = [ + re.compile(r'FromUserAction\s*\(\s*"([^"]+)"', re.MULTILINE), + re.compile(r'features::UserAction\s*\(\s*"([^"]+)"', re.MULTILINE), + ] + return _FindMetrics(cwd, user_action_patterns) + + +def _CreateFileContent(metrics): + """Creates the content for the golden file.""" + return '\n'.join(metrics) + '\n' + + +def GetActualHistogramsFileContent(): + """Reads the current content of the histograms golden file.""" + file_path = _GetHistogramsFilePath() + if not os.path.exists(file_path): + return "" + with open(file_path, 'r', encoding='utf-8') as f: + return f.read() + + +def GetExpectedHistogramsFileContent(): + """Creates the expected content of the histograms golden file.""" + histograms = _FindHistograms(MODEL_DIR) + return _CreateFileContent(histograms) + + +def GetActualUserActionsFileContent(): + """Reads the current content of the user actions golden file.""" + file_path = _GetUserActionsFilePath() + if not os.path.exists(file_path): + return "" + with open(file_path, 'r', encoding='utf-8') as f: + return f.read() + + +def GetExpectedUserActionsFileContent(): + """Creates the expected content of the user actions golden file.""" + user_actions = _FindUserActions(MODEL_DIR) + return _CreateFileContent(user_actions) + + +def _WriteFile(file_path, content): + """Writes the content to the given file path.""" + os.makedirs(os.path.dirname(file_path), exist_ok=True) + with open(file_path, 'w', encoding='utf-8') as f: + f.write(content) + + +def main(): + """Main function to update the golden files.""" + histograms_file_path = _GetHistogramsFilePath() + expected_histograms_content = GetExpectedHistogramsFileContent() + _WriteFile(histograms_file_path, expected_histograms_content) + print(f"Updated {histograms_file_path}") + + user_actions_file_path = _GetUserActionsFilePath() + expected_user_actions_content = GetExpectedUserActionsFileContent() + _WriteFile(user_actions_file_path, expected_user_actions_content) + print(f"Updated {user_actions_file_path}") + + +if __name__ == '__main__': + main()
diff --git a/components/segmentation_platform/tools/histograms.txt b/components/segmentation_platform/tools/histograms.txt index cff75b7e..c30fca82 100644 --- a/components/segmentation_platform/tools/histograms.txt +++ b/components/segmentation_platform/tools/histograms.txt
@@ -2,20 +2,14 @@ Android.AdaptiveToolbarButton.Clicked Android.AdaptiveToolbarButton.Variant.OnPageLoad Android.DragDrop.FromWebContent.TargetType -Android.HistoryPage.OpenItem Android.MultiInstance.NumActivities -Android.MultiWindowMode.MultiInstance.Enter Android.PhotoPicker.DialogAction Autofill.KeyMetrics.FillingAcceptance.Address Autofill.KeyMetrics.FillingAcceptance.CreditCard -Autofill.KeyMetrics.FillingAssistance.CreditCard -Autofill_PolledCreditCardSuggestions -Back Blink.FedCm.AccountsDialogShown Blink.FedCm.CancelReason Blink.FedCm.IsSignInUser Blink.FedCm.Status.RequestIdToken -Bookmarks.FolderAdded Commerce.PriceDrops.ActiveTabNavigationComplete.IsProductDetailPage ContentSettings.RegularProfile.DefaultRequestDesktopSiteSetting ContentSuggestions.Feed.EngagementType @@ -23,8 +17,6 @@ DataUse.TrafficSize.User.Upstream.Foreground.NotCellular Download.Start.PerProfileType FirstRun.Stage -Forward -Home IOS.CredentialExtension.IsEnabled.Startup IOS.Incognito.TimeSpent IOS.IncognitoInterstitial.Settings @@ -35,45 +27,11 @@ IOS.PageLoadCount.Counts IOS.ParcelTracking.Tracked.AutoTrack IOS.Start.Impression -IOSMagicStackSafetyCheckFreshSignal -IncognitoMode_Started MagicStack.Clank.NewTabPage.Module.Click MagicStack.Clank.NewTabPage.Module.TopImpressionV2 -Media.Controls.Cast -Media.Controls.CastOverlay Media.InputStreamDuration Media.OutputStreamDuration -MetadataWriter -MobileBookmarkManagerEntryOpened -MobileBookmarkManagerOpen -MobileMenuAddToBookmarks -MobileMenuAllBookmarks -MobileMenuDownloadManager -MobileMenuDownloadPage -MobileMenuHistory -MobileMenuRecentTabs -MobileMenuRequestDesktopSite -MobileMenuSettings -MobileMenuShare -MobileMenuTranslate -MobileNTPMostVisited -MobileNewTabOpened -MobileNewTabShown -MobileOmniboxLens -MobileOmniboxShortcutsOpenMostVisitedItem -MobileOmniboxShortcutsOpenReadingList -MobileOmniboxVoiceSearch -MobilePageLoadedWithKeyboard -MobileReadingListAdd -MobileReadingListOpen -MobileStackSwipeCancelled MobileStartup.LaunchCause -MobileTabGridEntered -MobileTabReturnedToCurrentTab -MobileTabSwitched -MobileToolbarForward -NewTabPage.MostVisited.Clicked -NewTabPage.SearchBox.Lens NewTabPage.TimeSpent Omnibox.SuggestionUsed.ClientSummarizedResultType Omnibox.SuggestionUsed.SearchVsUrl @@ -86,21 +44,15 @@ PasswordManager.ProfileStore.TotalAccountsHiRes3.WithScheme.Https PasswordManager.SaveUIDismissalReason PasswordManager.SavedPasswordIsGenerated -PasswordManager_Autofilled SafeBrowsing.Settings.UserAction.Default Session.TotalDuration Session.TotalDuration.WithAccount -SharingHubAndroid.SendTabToSelfSelected Signin.IOSNumberOfDeviceAccounts Startup.MobileSessionStartFromApps -Suggestions.Content.Opened Sync.DeviceCount2 Sync.DeviceCount2.Desktop Sync.DeviceCount2.Phone Sync.DeviceCount2.Tablet -TabGroup.Created.OpenInNewTab TabGroups.UserGroupCount -TasksSurface.FakeBox.Lens UMA.ProfileSignInStatusV2 UMA.ProfileSyncStatusV2 -UserActionName
diff --git a/components/segmentation_platform/tools/user_actions.txt b/components/segmentation_platform/tools/user_actions.txt new file mode 100644 index 0000000..6760318 --- /dev/null +++ b/components/segmentation_platform/tools/user_actions.txt
@@ -0,0 +1,48 @@ +Android.HistoryPage.OpenItem +Android.MultiWindowMode.MultiInstance.Enter +Autofill.KeyMetrics.FillingAssistance.CreditCard +Autofill_PolledCreditCardSuggestions +Back +Bookmarks.FolderAdded +Forward +Home +IOSMagicStackSafetyCheckFreshSignal +IncognitoMode_Started +Media.Controls.Cast +Media.Controls.CastOverlay +MetadataWriter +MobileBookmarkManagerEntryOpened +MobileBookmarkManagerOpen +MobileMenuAddToBookmarks +MobileMenuAllBookmarks +MobileMenuDownloadManager +MobileMenuDownloadPage +MobileMenuHistory +MobileMenuRecentTabs +MobileMenuRequestDesktopSite +MobileMenuSettings +MobileMenuShare +MobileMenuTranslate +MobileNTPMostVisited +MobileNewTabOpened +MobileNewTabShown +MobileOmniboxLens +MobileOmniboxShortcutsOpenMostVisitedItem +MobileOmniboxShortcutsOpenReadingList +MobileOmniboxVoiceSearch +MobilePageLoadedWithKeyboard +MobileReadingListAdd +MobileReadingListOpen +MobileStackSwipeCancelled +MobileTabGridEntered +MobileTabReturnedToCurrentTab +MobileTabSwitched +MobileToolbarForward +NewTabPage.MostVisited.Clicked +NewTabPage.SearchBox.Lens +PasswordManager_Autofilled +SharingHubAndroid.SendTabToSelfSelected +Suggestions.Content.Opened +TabGroup.Created.OpenInNewTab +TasksSurface.FakeBox.Lens +UserActionName
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.cc b/components/startup_metric_utils/browser/startup_metric_utils.cc index 22d0cec..2a0d7a8 100644 --- a/components/startup_metric_utils/browser/startup_metric_utils.cc +++ b/components/startup_metric_utils/browser/startup_metric_utils.cc
@@ -95,30 +95,8 @@ namespace { const char kProcessType[] = "type"; -// An enumeration of startup temperatures. This must be kept in sync with -// the UMA StartupType enumeration defined in histograms.xml. -enum StartupTemperature { - // The startup was a cold start: nearly all of the binaries and resources - // were - // brought into memory using hard faults. - COLD_STARTUP_TEMPERATURE = 0, - // The startup was a warm start: the binaries and resources were mostly - // already resident in memory and effectively no hard faults were - // observed. - WARM_STARTUP_TEMPERATURE = 1, - // The startup type couldn't quite be classified as warm or cold, but - // rather - // was somewhere in between. - LUKEWARM_STARTUP_TEMPERATURE = 2, - // Startup temperature wasn't yet determined, or could not be determined. - UNDETERMINED_STARTUP_TEMPERATURE = 3, - // This must be after all meaningful values. All new values should be - // added - // above this one. - STARTUP_TEMPERATURE_COUNT, -}; - -StartupTemperature g_startup_temperature = UNDETERMINED_STARTUP_TEMPERATURE; +startup_metric_utils::StartupTemperature g_startup_temperature = + startup_metric_utils::UNDETERMINED_STARTUP_TEMPERATURE; // Helper function for splitting out an UMA histogram based on startup // temperature. |histogram_function| is the histogram type, and corresponds to @@ -143,20 +121,20 @@ (*histogram_function)(histogram_basename, value); // Record to the cold/warm suffixed histogram as appropriate. switch (g_startup_temperature) { - case COLD_STARTUP_TEMPERATURE: + case startup_metric_utils::COLD_STARTUP_TEMPERATURE: (*histogram_function)(base::StrCat({histogram_basename, ".ColdStartup"}), value); break; - case WARM_STARTUP_TEMPERATURE: + case startup_metric_utils::WARM_STARTUP_TEMPERATURE: (*histogram_function)(base::StrCat({histogram_basename, ".WarmStartup"}), value); break; - case LUKEWARM_STARTUP_TEMPERATURE: + case startup_metric_utils::LUKEWARM_STARTUP_TEMPERATURE: // No suffix emitted for lukewarm startups. break; - case UNDETERMINED_STARTUP_TEMPERATURE: + case startup_metric_utils::UNDETERMINED_STARTUP_TEMPERATURE: break; - case STARTUP_TEMPERATURE_COUNT: + case startup_metric_utils::STARTUP_TEMPERATURE_COUNT: NOTREACHED(); } } @@ -477,26 +455,10 @@ return; } - base::TimeTicks latency_origin; -#if BUILDFLAG(IS_CHROMEOS) - // `application_start_ticks_` is inappropriate since the device often boots - // to a login screen, and an indefinite amount of time can elapse before a - // browser window is opened. Even when restoring a session after a crash - // (which has no login screen), the session is not restored automatically. - // The user must click a notification first before browser windows are - // created and restored, so using `application_start_ticks_` would have the - // same issue. - // - // If `web_contents_start_ticks_` is not set here, that could be intentional - // as this metric should not be recorded in certain cases (ex: a manually - // opened browser window). - if (web_contents_start_ticks_.is_null()) { + base::TimeTicks latency_origin = GetApplicationStartTicksForStartup(); + if (latency_origin.is_null()) { return; } - latency_origin = web_contents_start_ticks_; -#else - latency_origin = GetCommon().application_start_ticks_; -#endif // BUILDFLAG(IS_CHROMEOS) DCHECK(!latency_origin.is_null()); EmitHistogramWithTemperatureAndTraceEvent(&base::UmaHistogramLongTimes100, @@ -552,6 +514,33 @@ return !WasMainWindowStartupInterrupted(); } +StartupTemperature BrowserStartupMetricRecorder::GetStartupTemperature() const { + return g_startup_temperature; +} + +base::TimeTicks +BrowserStartupMetricRecorder::GetApplicationStartTicksForStartup() const { +#if BUILDFLAG(IS_CHROMEOS) + // `application_start_ticks_` is inappropriate since the device often boots + // to a login screen, and an indefinite amount of time can elapse before a + // browser window is opened. Even when restoring a session after a crash + // (which has no login screen), the session is not restored automatically. + // The user must click a notification first before browser windows are + // created and restored, so using `application_start_ticks_` would have the + // same issue. + // + // If `web_contents_start_ticks_` is not set here, that could be intentional + // as this metric should not be recorded in certain cases (ex: a manually + // opened browser window). + if (web_contents_start_ticks_.is_null()) { + return base::TimeTicks(); + } + return web_contents_start_ticks_; +#else + return GetCommon().application_start_ticks_; +#endif // BUILDFLAG(IS_CHROMEOS) +} + #if BUILDFLAG(IS_CHROMEOS) void BrowserStartupMetricRecorder::RecordWebContentsStartTime( base::TimeTicks ticks) {
diff --git a/components/startup_metric_utils/browser/startup_metric_utils.h b/components/startup_metric_utils/browser/startup_metric_utils.h index 3600976..b131878 100644 --- a/components/startup_metric_utils/browser/startup_metric_utils.h +++ b/components/startup_metric_utils/browser/startup_metric_utils.h
@@ -34,6 +34,27 @@ kMaxValue = kFileSystemError, }; +// An enumeration of startup temperatures. This must be kept in sync with +// the UMA StartupType enumeration defined in histograms.xml. +// LINT.IfChange(StartupTemperature) +enum StartupTemperature { + // The startup was a cold start: nearly all of the binaries and resources were + // brought into memory using hard faults. + COLD_STARTUP_TEMPERATURE = 0, + // The startup was a warm start: the binaries and resources were mostly + // already resident in memory and effectively no hard faults were observed. + WARM_STARTUP_TEMPERATURE = 1, + // The startup type couldn't quite be classified as warm or cold, but rather + // was somewhere in between. + LUKEWARM_STARTUP_TEMPERATURE = 2, + // Startup temperature wasn't yet determined, or could not be determined. + UNDETERMINED_STARTUP_TEMPERATURE = 3, + // This must be after all meaningful values. All new values should be added + // above this one. + STARTUP_TEMPERATURE_COUNT, +}; +// LINT.ThenChange(//tools/metrics/histograms/metadata/startup/enums.xml:StartupTemperature) + class COMPONENT_EXPORT(STARTUP_METRIC_UTILS) BrowserStartupMetricRecorder final { public: @@ -132,6 +153,13 @@ bool ShouldLogStartupHistogram() const; + // Returns the startup temperature if available. + StartupTemperature GetStartupTemperature() const; + + // Returns the appropriate application start ticks for use in startup metrics. + // Returns a null TimeTicks if a value has not been recorded yet. + base::TimeTicks GetApplicationStartTicksForStartup() const; + #if BUILDFLAG(IS_CHROMEOS) // On ChromeOS, the time at which the first browser window is opened may not // match the application start time mainly because the login screen is often
diff --git a/components/supervised_user/core/browser/supervised_user_test_environment.h b/components/supervised_user/core/browser/supervised_user_test_environment.h index b12e074..88d82876 100644 --- a/components/supervised_user/core/browser/supervised_user_test_environment.h +++ b/components/supervised_user/core/browser/supervised_user_test_environment.h
@@ -10,6 +10,7 @@ #include <string_view> #include "base/memory/ref_counted.h" +#include "components/prefs/pref_notifier_impl.h" #include "components/prefs/pref_service.h" #include "components/prefs/testing_pref_store.h" #include "components/safe_search_api/fake_url_checker_client.h"
diff --git a/components/sync/model/client_tag_based_remote_update_handler.cc b/components/sync/model/client_tag_based_remote_update_handler.cc index 8157aa4..0fdc8d7 100644 --- a/components/sync/model/client_tag_based_remote_update_handler.cc +++ b/components/sync/model/client_tag_based_remote_update_handler.cc
@@ -24,6 +24,7 @@ #include "components/sync/protocol/data_type_state_helper.h" #include "components/sync/protocol/entity_specifics.pb.h" #include "components/sync/protocol/unique_position.pb.h" +#include "third_party/abseil-cpp/absl/container/flat_hash_set.h" namespace syncer { @@ -68,7 +69,7 @@ // If new encryption requirements come from the server, the entities that are // in `updates` will be recorded here so they can be ignored during the // re-encryption phase at the end. - std::unordered_set<std::string> already_updated; + absl::flat_hash_set<std::string> already_updated; for (syncer::UpdateResponseData& update : updates) { std::string storage_key_to_clear;
diff --git a/components/sync/model/processor_entity_tracker.cc b/components/sync/model/processor_entity_tracker.cc index 3c063cd..d021cea 100644 --- a/components/sync/model/processor_entity_tracker.cc +++ b/components/sync/model/processor_entity_tracker.cc
@@ -278,12 +278,11 @@ std::vector<const ProcessorEntity*> ProcessorEntityTracker::IncrementSequenceNumberForAllExcept( - const std::unordered_set<std::string>& already_updated_storage_keys) { + const absl::flat_hash_set<std::string>& already_updated_storage_keys) { std::vector<const ProcessorEntity*> affected_entities; for (const auto& [client_tag_hash, entity] : entities_) { if (entity->storage_key().empty() || - (already_updated_storage_keys.find(entity->storage_key()) != - already_updated_storage_keys.end())) { + already_updated_storage_keys.contains(entity->storage_key())) { // Entities with empty storage key were already processed. ProcessUpdate() // incremented their sequence numbers and cached commit data. Their // metadata will be persisted in UpdateStorageKey().
diff --git a/components/sync/model/processor_entity_tracker.h b/components/sync/model/processor_entity_tracker.h index b84b994..3a21c28 100644 --- a/components/sync/model/processor_entity_tracker.h +++ b/components/sync/model/processor_entity_tracker.h
@@ -8,7 +8,6 @@ #include <memory> #include <optional> #include <string> -#include <unordered_set> #include <vector> #include "base/containers/flat_set.h" @@ -16,6 +15,7 @@ #include "components/sync/engine/commit_and_get_updates_types.h" #include "components/sync/protocol/data_type_state.pb.h" #include "third_party/abseil-cpp/absl/container/flat_hash_map.h" +#include "third_party/abseil-cpp/absl/container/flat_hash_set.h" namespace sync_pb { class EntityMetadata; @@ -129,7 +129,7 @@ // Increments sequence number for all entities except those in // `already_updated_storage_keys`. Returns affected list of entities. std::vector<const ProcessorEntity*> IncrementSequenceNumberForAllExcept( - const std::unordered_set<std::string>& already_updated_storage_keys); + const absl::flat_hash_set<std::string>& already_updated_storage_keys); // Assigns a new storage key to the entity for the given `client_tag_hash`. // Clears previous storage key if entity already has one (the metadata of the
diff --git a/components/user_manager/scoped_user_manager.h b/components/user_manager/scoped_user_manager.h index 0c6c2e9a..2406c54 100644 --- a/components/user_manager/scoped_user_manager.h +++ b/components/user_manager/scoped_user_manager.h
@@ -9,6 +9,7 @@ #include <utility> #include "base/memory/raw_ptr.h" +#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager_export.h" namespace user_manager {
diff --git a/components/viz/common/gpu/context_provider.h b/components/viz/common/gpu/context_provider.h index c39a52a..c5418c71 100644 --- a/components/viz/common/gpu/context_provider.h +++ b/components/viz/common/gpu/context_provider.h
@@ -21,8 +21,6 @@ #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/context_result.h" -class GrDirectContext; - namespace base { class Lock; } @@ -94,11 +92,6 @@ // must have been successfully bound to a thread before calling this. virtual gpu::ContextSupport* ContextSupport() = 0; - // Get a Skia GPU raster interface to the 3d context. The context provider - // must have been successfully bound to a thread before calling this. Returns - // nullptr if a GrContext fails to initialize on this context. - virtual class GrDirectContext* GrContext() = 0; - virtual gpu::SharedImageInterface* SharedImageInterface() = 0; // Returns the capabilities of the currently bound 3d context. The context
diff --git a/components/viz/common/gpu/raster_context_provider.h b/components/viz/common/gpu/raster_context_provider.h index e3bce53..5188f0c 100644 --- a/components/viz/common/gpu/raster_context_provider.h +++ b/components/viz/common/gpu/raster_context_provider.h
@@ -21,8 +21,6 @@ #include "gpu/command_buffer/common/capabilities.h" #include "gpu/command_buffer/common/context_result.h" -class GrDirectContext; - namespace base { class Lock; } @@ -96,11 +94,6 @@ // must have been successfully bound to a thread before calling this. virtual gpu::ContextSupport* ContextSupport() = 0; - // Get a Skia GPU raster interface to the 3d context. The context provider - // must have been successfully bound to a thread before calling this. Returns - // nullptr if a GrContext fails to initialize on this context. - virtual class GrDirectContext* GrContext() = 0; - virtual gpu::SharedImageInterface* SharedImageInterface() = 0; // Returns the capabilities of the currently bound 3d context. The context
diff --git a/components/viz/service/display/direct_renderer.cc b/components/viz/service/display/direct_renderer.cc index b97af79..382d6f0 100644 --- a/components/viz/service/display/direct_renderer.cc +++ b/components/viz/service/display/direct_renderer.cc
@@ -252,10 +252,10 @@ gfx::ColorSpace frame_color_space = RenderPassColorSpace(current_frame()->root_render_pass); - SharedImageFormat frame_si_format = GetSharedImageFormat( - current_frame()->display_color_spaces.GetOutputBufferFormat( + SharedImageFormat frame_si_format = + current_frame()->display_color_spaces.GetOutputFormat( current_frame()->root_render_pass->content_color_usage, - current_frame()->root_render_pass->has_transparent_background)); + current_frame()->root_render_pass->has_transparent_background); gfx::Size surface_resource_size = CalculateSizeForOutputSurface(device_viewport_size); #if BUILDFLAG(IS_WIN)
diff --git a/components/viz/service/gl/gpu_service_impl.cc b/components/viz/service/gl/gpu_service_impl.cc index 39e017d..32889fd 100644 --- a/components/viz/service/gl/gpu_service_impl.cc +++ b/components/viz/service/gl/gpu_service_impl.cc
@@ -242,10 +242,11 @@ if (dawn_context_provider_) { // GpuServiceImpl holds the instance of DawnContextProvider, so it // outlives the DawnContextProvider. - std::unique_ptr<dawn::platform::CachingInterface> caching_interface; + std::unique_ptr<gpu::webgpu::DawnCachingInterface> caching_interface; if (features::kSkiaGraphiteDawnUsePersistentCache.Get()) { - caching_interface = - std::make_unique<gpu::GpuPersistentCache>("GraphiteDawn"); + caching_interface = dawn_caching_interface_factory_->CreateInstance( + gpu::kGraphiteDawnGpuDiskCacheHandle, + std::make_unique<gpu::GpuPersistentCache>("GraphiteDawn")); } else { auto cache_blob_callback = base::BindRepeating( [](GpuServiceImpl* self, const std::string& key, @@ -948,10 +949,9 @@ return; } - auto* persistent_cache = static_cast<gpu::GpuPersistentCache*>( - dawn_context_provider_->GetCachingInterface()); - CHECK(persistent_cache); - persistent_cache->InitializeCache(std::move(backend_params)); + auto* cache = dawn_context_provider_->GetCachingInterface(); + CHECK(cache); + cache->InitializePersistentCache(std::move(backend_params)); #endif }
diff --git a/components/viz/service/surfaces/surface_saved_frame.cc b/components/viz/service/surfaces/surface_saved_frame.cc index bf33895..911ad5a 100644 --- a/components/viz/service/surfaces/surface_saved_frame.cc +++ b/components/viz/service/surfaces/surface_saved_frame.cc
@@ -208,9 +208,8 @@ const auto& display_color_spaces = directive_.display_color_spaces(); bool has_transparent_background = render_pass.has_transparent_background; - auto image_format = - GetSharedImageFormat(display_color_spaces.GetOutputBufferFormat( - content_color_usage, has_transparent_background)); + auto image_format = display_color_spaces.GetOutputFormat( + content_color_usage, has_transparent_background); auto color_space = display_color_spaces.GetRasterAndCompositeColorSpace(content_color_usage);
diff --git a/components/viz/test/test_context_provider.h b/components/viz/test/test_context_provider.h index cd0a9dd..f7071ff 100644 --- a/components/viz/test/test_context_provider.h +++ b/components/viz/test/test_context_provider.h
@@ -80,7 +80,6 @@ gpu::gles2::GLES2Interface* ContextGL() override; gpu::raster::RasterInterface* RasterInterface() override; gpu::ContextSupport* ContextSupport() override; - class GrDirectContext* GrContext() override; gpu::TestSharedImageInterface* SharedImageInterface() override; ContextCacheController* CacheController() override; base::Lock* GetLock() override; @@ -88,6 +87,8 @@ void RemoveObserver(ContextLostObserver* obs) override; unsigned int GetGrGLTextureFormat(SharedImageFormat format) const override; + class GrDirectContext* GrContext(); + TestGLES2Interface* TestContextGL(); TestRasterInterface* GetTestRasterInterface();
diff --git a/components/viz/test/test_in_process_context_provider.cc b/components/viz/test/test_in_process_context_provider.cc index d7f357a5..f7fc5d6 100644 --- a/components/viz/test/test_in_process_context_provider.cc +++ b/components/viz/test/test_in_process_context_provider.cc
@@ -21,8 +21,6 @@ #include "gpu/config/skia_limits.h" #include "gpu/ipc/gl_in_process_context.h" #include "gpu/ipc/raster_in_process_context.h" -#include "gpu/skia_bindings/grcontext_for_gles2_interface.h" -#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" namespace viz { @@ -107,10 +105,6 @@ : raster_context_->GetContextSupport(); } -class GrDirectContext* TestInProcessContextProvider::GrContext() { - return nullptr; -} - gpu::SharedImageInterface* TestInProcessContextProvider::SharedImageInterface() { return gles2_context_ ? gles2_context_->GetSharedImageInterface()
diff --git a/components/viz/test/test_in_process_context_provider.h b/components/viz/test/test_in_process_context_provider.h index aac1d12..7f9ad23 100644 --- a/components/viz/test/test_in_process_context_provider.h +++ b/components/viz/test/test_in_process_context_provider.h
@@ -18,8 +18,6 @@ #include "components/viz/common/gpu/raster_context_provider.h" #include "gpu/config/gpu_feature_info.h" -class GrDirectContext; - namespace gpu { class GLInProcessContext; class GpuProcessShmCount; @@ -57,7 +55,6 @@ gpu::gles2::GLES2Interface* ContextGL() override; gpu::raster::RasterInterface* RasterInterface() override; gpu::ContextSupport* ContextSupport() override; - class GrDirectContext* GrContext() override; gpu::SharedImageInterface* SharedImageInterface() override; ContextCacheController* CacheController() override; base::Lock* GetLock() override;
diff --git a/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc b/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc index 6dd9a24..572bf2e6 100644 --- a/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc +++ b/content/browser/file_system_access/file_system_access_directory_handle_impl_unittest.cc
@@ -477,11 +477,14 @@ public: FileSystemAccessDirectoryHandleImplRemoveTest() { if (GetParam().is_feature_enabled) { - scoped_feature_list_.InitAndEnableFeature( - blink::features::kFileSystemAccessWriteMode); + scoped_feature_list_.InitWithFeatures( + {blink::features::kFileSystemAccessWriteMode, + blink::features::kFileSystemAccessRevokeReadOnRemove}, + {}); } else { - scoped_feature_list_.InitAndDisableFeature( - blink::features::kFileSystemAccessWriteMode); + scoped_feature_list_.InitWithFeatures( + {}, {blink::features::kFileSystemAccessWriteMode, + blink::features::kFileSystemAccessRevokeReadOnRemove}); } } @@ -511,6 +514,10 @@ base::FilePath dir = dir_.GetPath().AppendASCII("dirname"); ASSERT_TRUE(base::CreateDirectory(dir)); + if (GetParam().is_feature_enabled) { + EXPECT_CALL(permission_context_, NotifyEntryRemoved(_, _)).Times(1); + } + auto handle = GetHandleWithPermissions(dir, /*read=*/true, /*write=*/true); base::test::TestFuture<blink::mojom::FileSystemAccessErrorPtr> future; @@ -527,6 +534,9 @@ ASSERT_TRUE(base::CreateDirectory(dir)); base::FilePath file = dir.AppendASCII("test_file.txt"); ASSERT_TRUE(base::WriteFile(file, "test data")); + if (GetParam().is_feature_enabled) { + EXPECT_CALL(permission_context_, NotifyEntryRemoved(_, _)).Times(1); + } auto handle = GetHandleWithPermissions(dir, /*read=*/true, /*write=*/true); @@ -576,7 +586,9 @@ auto handle = CreateHandle(); auto test_dir_path = dir_.GetPath().AppendASCII("test_dir"); - if (!GetParam().is_feature_enabled) { + if (GetParam().is_feature_enabled) { + EXPECT_CALL(permission_context_, NotifyEntryRemoved(_, _)).Times(1); + } else { SetUpGrantExpectations(*mock_read_grant_, PermissionStatus::GRANTED, FileSystemAccessPermissionGrant:: PermissionRequestOutcome::kUserGranted); @@ -609,11 +621,14 @@ public: FileSystemAccessDirectoryHandleImplRemoveEntryTest() { if (GetParam().is_feature_enabled) { - scoped_feature_list_.InitAndEnableFeature( - blink::features::kFileSystemAccessWriteMode); + scoped_feature_list_.InitWithFeatures( + {blink::features::kFileSystemAccessWriteMode, + blink::features::kFileSystemAccessRevokeReadOnRemove}, + {}); } else { - scoped_feature_list_.InitAndDisableFeature( - blink::features::kFileSystemAccessWriteMode); + scoped_feature_list_.InitWithFeatures( + {}, {blink::features::kFileSystemAccessWriteMode, + blink::features::kFileSystemAccessRevokeReadOnRemove}); } } @@ -636,6 +651,10 @@ LockType exclusive_lock_type = manager_->GetExclusiveLockType(); LockType wfs_siloed_lock_type = manager_->GetWFSSiloedLockType(); + if (GetParam().is_feature_enabled) { + EXPECT_CALL(permission_context_, NotifyEntryRemoved(_, _)).Times(1); + } + // Calling removeEntry() on an unlocked file should succeed. { base::CreateTemporaryFileInDir(dir, &file); @@ -736,6 +755,9 @@ ASSERT_TRUE(base::CreateDirectory(subdir_path)); base::FilePath file_path = subdir_path.AppendASCII("test_file.txt"); ASSERT_TRUE(base::WriteFile(file_path, "test data")); + if (GetParam().is_feature_enabled) { + EXPECT_CALL(permission_context_, NotifyEntryRemoved(_, _)).Times(1); + } base::test::TestFuture<blink::mojom::FileSystemAccessErrorPtr> future; handle_->RemoveEntry("subdir", /*recurse=*/true, future.GetCallback()); @@ -772,7 +794,9 @@ base::FilePath file_path = test_dir.AppendASCII("test_file.txt"); ASSERT_TRUE(base::WriteFile(file_path, "test data")); - if (!GetParam().is_feature_enabled) { + if (GetParam().is_feature_enabled) { + EXPECT_CALL(permission_context_, NotifyEntryRemoved(_, _)).Times(1); + } else { SetUpGrantExpectations(*mock_read_grant_, PermissionStatus::GRANTED, FileSystemAccessPermissionGrant:: PermissionRequestOutcome::kUserGranted);
diff --git a/content/browser/file_system_access/file_system_access_file_writer_impl_unittest.cc b/content/browser/file_system_access/file_system_access_file_writer_impl_unittest.cc index df50e9b..20e96b97 100644 --- a/content/browser/file_system_access/file_system_access_file_writer_impl_unittest.cc +++ b/content/browser/file_system_access/file_system_access_file_writer_impl_unittest.cc
@@ -649,6 +649,7 @@ kFrameId, _)) .WillOnce(base::test::RunOnceCallback<2>( FileSystemAccessPermissionContext::AfterWriteCheckResult::kAllow)); + EXPECT_CALL(permission_context_, NotifyEntryModified(_, _)).Times(1); result = CloseSync(); EXPECT_EQ(result, FileSystemAccessStatus::kOk); @@ -699,6 +700,7 @@ sb_callback = std::move(callback); loop.Quit(); }); + EXPECT_CALL(permission_context_, NotifyEntryModified(_, _)).Times(1); handle_->Close(base::DoNothing()); loop.Run(); @@ -849,11 +851,14 @@ public: FileSystemAccessFileWriterImplPermissionTest() { if (GetParam().is_feature_enabled) { - scoped_feature_list_.InitAndEnableFeature( - blink::features::kFileSystemAccessWriteMode); + scoped_feature_list_.InitWithFeatures( + {blink::features::kFileSystemAccessWriteMode, + blink::features::kFileSystemAccessRevokeReadOnRemove}, + {}); } else { - scoped_feature_list_.InitAndDisableFeature( - blink::features::kFileSystemAccessWriteMode); + scoped_feature_list_.InitWithFeatures( + {}, {blink::features::kFileSystemAccessWriteMode, + blink::features::kFileSystemAccessRevokeReadOnRemove}); } }
diff --git a/content/browser/gpu/gpu_internals_ui.cc b/content/browser/gpu/gpu_internals_ui.cc index 5d8535c..8482380 100644 --- a/content/browser/gpu/gpu_internals_ui.cc +++ b/content/browser/gpu/gpu_internals_ui.cc
@@ -382,8 +382,8 @@ { std::vector<std::string> names; std::vector<gfx::ColorSpace> color_spaces; - std::vector<gfx::BufferFormat> buffer_formats; - display_color_spaces.ToStrings(&names, &color_spaces, &buffer_formats); + std::vector<viz::SharedImageFormat> formats; + display_color_spaces.ToStrings(&names, &color_spaces, &formats); for (size_t i = 0; i < names.size(); ++i) { display_info.Append(display::BuildGpuInfoEntry( base::StringPrintf("Color space (%s)", names[i].c_str()), @@ -393,7 +393,7 @@ .ToString())); display_info.Append(display::BuildGpuInfoEntry( base::StringPrintf("Buffer format (%s)", names[i].c_str()), - gfx::BufferFormatToString(buffer_formats[i]))); + formats[i].ToString())); } } display_info.Append(display::BuildGpuInfoEntry(
diff --git a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt index 1a410b0..e1ed28a 100644 --- a/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/context_lost_expectations.txt
@@ -237,6 +237,9 @@ crbug.com/338574390 [ angle-metal asan graphite-disabled intel-0x3e9b mac ] GpuNormalTermination_NewWebGLNotBlocked [ RetryOnFailure ] crbug.com/338574390 [ angle-metal graphite-enabled amd-0x7340 mac ] ContextLost_WebGPUBlockedAfterJSNavigation [ Slow ] +# Win11 / NVIDIA RTX 4070 Super +crbug.com/450323460 [ win11 nvidia-0x2783 ] ContextLost_WebGPUStressRequestDeviceAndRemoveLoop [ RetryOnFailure ] + ############################### # Permanent Slow Expectations # ###############################
diff --git a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt index a32c4bb..298ab5b4 100644 --- a/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/pixel_expectations.txt
@@ -565,6 +565,27 @@ crbug.com/446861923 [ android android-pixel-10 android-chromium ] Pixel_Video_MP4_Rounded_Corner [ Failure ] crbug.com/446861923 [ android android-pixel-10 android-chromium ] Pixel_Video_VP9 [ Failure ] +# Win11/RTX 4070 Super failures +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_Canvas2DRedBox [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_Canvas2DRedBoxScrgbLinear [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_CanvasDisplaySRGBAccelerated2D [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_GpuRasterization_ConcavePaths [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasAccelerated2DWorker [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasIBRCWorker [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasTransferBeforeStyleResize [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasTransferToImageBitmap [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_PaintWorkletTransform [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_ScissorTestWithPreserveDrawingBuffer [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_WebGLGreenTriangle_NoAA_NoAlpha [ RetryOnFailure ] +crbug.com/450326412 [ win11 nvidia-0x2783 ] Pixel_WebglResizedCanvas [ RetryOnFailure ] +crbug.com/450326413 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasWebGLPaintAfterResize [ RetryOnFailure ] +crbug.com/450326413 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasWebglResizeOnWorker [ RetryOnFailure ] +crbug.com/450326413 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasWebGLSoftwareCompositing [ RetryOnFailure ] +crbug.com/450325666 [ win11 nvidia-0x2783 ] Pixel_DirectComposition_Video_VP9_Fullsize [ RetryOnFailure ] +crbug.com/450325666 [ win11 nvidia-0x2783 ] Pixel_OffscreenCanvasUnaccelerated2DGPUCompositing [ RetryOnFailure ] +crbug.com/450325666 [ win11 nvidia-0x2783 ] Pixel_WebGLTextureFromWebGLReadback [ RetryOnFailure ] +crbug.com/450325666 [ win11 nvidia-0x2783 ] Pixel_WebGPUImportVideoFrame [ RetryOnFailure ] + ####################################################################### # Automated Entries After This Point - Do Not Manually Add Below Here # #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt index 5232a450..3d71b1fc 100644 --- a/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/screenshot_sync_expectations.txt
@@ -120,6 +120,10 @@ # Gardener 2024-04-30 - timeouts crbug.com/324934210 [ mac angle-metal intel-0x3e9b passthrough asan ] ScreenshotSync_SWRasterWithCanvas [ Failure ] +# Win11 / NVIDIA RTX 4070 Super +crbug.com/450325666 [ win11 nvidia-0x2783 ] ScreenshotSync_GPURasterWithCanvas [ RetryOnFailure ] +crbug.com/450325666 [ win11 nvidia-0x2783 ] ScreenshotSync_GPURasterWithDivs [ RetryOnFailure ] + ####################################################################### # Automated Entries After This Point - Do Not Manually Add Below Here # #######################################################################
diff --git a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt index b5e1a3c1..8da0235 100644 --- a/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/trace_test_expectations.txt
@@ -260,6 +260,9 @@ # Win11/RTX 4070 Super failures after upgrading to driver 580.88 crbug.com/438512194 [ win11 nvidia-0x2783 ] OverlayModeTraceTest_DirectComposition_Underlay [ RetryOnFailure ] +crbug.com/450323461 [ win11 nvidia-0x2783 ] OverlayModeTraceTest_DirectComposition_Video_VP9_YUY2 [ RetryOnFailure ] +crbug.com/450323461 [ win11 nvidia-0x2783 ] VideoPathTraceTest_DirectComposition_Video_MP4 [ RetryOnFailure ] +crbug.com/450323461 [ win11 nvidia-0x2783 ] VideoPathTraceTest_DirectComposition_Video_SW_Decode [ RetryOnFailure ] ############################### # Permanent Slow Expectations #
diff --git a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt index a693991c..05178135 100644 --- a/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt +++ b/content/test/gpu/gpu_tests/test_expectations/webgl_conformance_expectations.txt
@@ -486,6 +486,9 @@ crbug.com/443182226 [ win nvidia angle-vulkan passthrough ] conformance/misc/shader-precision-format.html [ Failure ] crbug.com/443182226 [ win nvidia angle-vulkan passthrough ] conformance/uniforms/no-over-optimization-on-uniform-array-* [ Failure ] +# Win11 / NVIDIA RTX 4070 Super +crbug.com/450326413 [ win11 nvidia-0x2783 ] conformance/textures/image_bitmap_from_canvas/tex-2d-rgb-rgb-unsigned_short_5_6_5.html [ RetryOnFailure ] + #################### # Mac failures # ####################
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/extensions/browser/api/declarative_net_request/ruleset_manager.cc index cdf8ae2..2b36ce05 100644 --- a/extensions/browser/api/declarative_net_request/ruleset_manager.cc +++ b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -187,7 +187,19 @@ const net::HttpResponseHeaders* response_headers, bool is_incognito_context) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); - CHECK(response_headers); + + if (!response_headers) { + // NOTE: This can happen for auth challenges from CORS preflight requests + // that get routed to the respective main request's handler (since they + // share the same `request_id`), which happens when `extraHeaders` is + // enabled. + // + // At this point, the main request is paused waiting for the preflight, and + // has not received its own headers, so `response_headers` is null. We must + // return early. See https://crbug.com/444248440. + return {}; + } + return EvaluateRequestInternal(request, response_headers, is_incognito_context); }
diff --git a/extensions/common/api/_permission_features.json b/extensions/common/api/_permission_features.json index a72e301..afce21c 100644 --- a/extensions/common/api/_permission_features.json +++ b/extensions/common/api/_permission_features.json
@@ -479,12 +479,6 @@ "A4CC6F00ACF41015AF38F1D5C98E97C2B8B3B320", // http://crbug.com/1483151 "4E09F1C1EEC4D27F1F7DF18BA3643307107A7C41" // http://crbug.com/1483151 ] - }, - { - "channel": "dev", - "extension_types": ["extension"], - "platforms": ["chromeos"], - "session_types": ["kiosk"] }], "networkingPrivate": { "channel": "stable", @@ -722,20 +716,12 @@ "extension", "legacy_packaged_app", "hosted_app", "platform_app" ] }, - "usb": [ - { - "channel": "stable", - "extension_types": ["platform_app"], - // "desktop_android" is not supported. - "platforms": ["chromeos", "linux", "mac", "win"] - }, - { - "channel": "dev", - "extension_types": ["extension"], - "platforms": ["chromeos"], - "session_types": ["kiosk"] - } - ], + "usb": { + "channel": "stable", + "extension_types": ["platform_app"], + // "desktop_android" is not supported. + "platforms": ["chromeos", "linux", "mac", "win"] + }, "usbDevices": [ { "channel": "stable", @@ -750,12 +736,6 @@ "4839A26B29CD1BD021B2E126EF6D28C9CB84018B", // http://crbug.com/710541 "8F44FBB4474CCDF23450B166C9E83E85BD03AE24" // http://crbug.com/710541 ] - }, - { - "channel": "dev", - "extension_types": ["extension"], - "platforms": ["chromeos"], - "session_types": ["kiosk"] } ], "videoCapture": [ @@ -772,17 +752,12 @@ ] } ], - "virtualKeyboard": [{ + "virtualKeyboard": { "channel": "stable", "extension_types": ["platform_app"], "platforms": ["chromeos"], "session_types": ["kiosk"] - }, { - "channel": "dev", - "extension_types": ["extension"], - "platforms": ["chromeos"], - "session_types": ["kiosk"] - }], + }, "virtualKeyboardPrivate": { "channel": "stable", "extension_types": ["extension", "platform_app"],
diff --git a/gpu/command_buffer/service/dawn_caching_interface.cc b/gpu/command_buffer/service/dawn_caching_interface.cc index 8384784c..49d5202e 100644 --- a/gpu/command_buffer/service/dawn_caching_interface.cc +++ b/gpu/command_buffer/service/dawn_caching_interface.cc
@@ -14,6 +14,8 @@ #include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_request_args.h" #include "base/trace_event/trace_event.h" +#include "components/persistent_cache/entry.h" +#include "gpu/command_buffer/service/gpu_persistent_cache.h" #include "gpu/command_buffer/service/service_utils.h" #include "gpu/config/gpu_preferences.h" #include "net/base/io_buffer.h" @@ -26,28 +28,83 @@ : memory_cache_backend_(std::move(backend)), cache_blob_callback_(std::move(callback)) {} +DawnCachingInterface::DawnCachingInterface( + scoped_refptr<detail::DawnMemoryCache> backend, + std::unique_ptr<GpuPersistentCache> persistent_cache) + : memory_cache_backend_(std::move(backend)), + persistent_cache_(std::move(persistent_cache)) {} + DawnCachingInterface::~DawnCachingInterface() = default; +void DawnCachingInterface::InitializePersistentCache( + persistent_cache::BackendParams backend_params) { + CHECK(persistent_cache_); + // TODO(crbug.com/399642827): PersistentCache's sqlite backend has default + // in-memory page cache of 2 MB. + // See https://www.sqlite.org/pragma.html#pragma_cache_size + // Since we have our own memory cache here, we might want to disable the + // page cache or at least reduce its max size. + persistent_cache_->InitializeCache(std::move(backend_params)); +} + size_t DawnCachingInterface::LoadData(const void* key, size_t key_size, void* value_out, size_t value_size) { - if (memory_cache() == nullptr) { + std::string key_str(static_cast<const char*>(key), key_size); + if (memory_cache() != nullptr) { + size_t bytes_read = + memory_cache()->LoadData(key_str, value_out, value_size); + if (bytes_read > 0) { + return bytes_read; + } + } + + if (!persistent_cache_) { return 0u; } - std::string key_str(static_cast<const char*>(key), key_size); - return memory_cache()->LoadData(key_str, value_out, value_size); + + std::unique_ptr<persistent_cache::Entry> entry = + persistent_cache_->LoadEntry(key_str); + if (!entry) { + return 0u; + } + + size_t bytes_copied = 0; + if (value_size > 0) { + bytes_copied = entry->CopyContentTo( + UNSAFE_TODO(base::span(static_cast<uint8_t*>(value_out), value_size))); + } + + if (memory_cache()) { + memory_cache()->StoreData(key_str, entry->GetContentSpan().data(), + entry->GetContentSize()); + } + + if (bytes_copied > 0) { + return bytes_copied; + } + + return entry->GetContentSize(); } void DawnCachingInterface::StoreData(const void* key, size_t key_size, const void* value, size_t value_size) { - if (memory_cache() == nullptr || value == nullptr || value_size <= 0) { + if (value == nullptr || value_size <= 0) { return; } + std::string key_str(static_cast<const char*>(key), key_size); - memory_cache()->StoreData(key_str, value, value_size); + if (memory_cache() != nullptr) { + memory_cache()->StoreData(key_str, value, value_size); + } + + if (persistent_cache_) { + persistent_cache_->StoreData(key_str.data(), key_str.size(), value, + value_size); + } // Send the cache entry to be stored on the host-side if applicable. if (cache_blob_callback_) { @@ -77,25 +134,39 @@ DawnCachingInterfaceFactory::CreateInstance( const gpu::GpuDiskCacheHandle& handle, DawnCachingInterface::CacheBlobCallback callback) { + return base::WrapUnique(new DawnCachingInterface( + GetOrCreateMemoryCache(handle), std::move(callback))); +} + +std::unique_ptr<DawnCachingInterface> +DawnCachingInterfaceFactory::CreateInstance( + const gpu::GpuDiskCacheHandle& handle, + std::unique_ptr<GpuPersistentCache> persistent_cache) { + return base::WrapUnique(new DawnCachingInterface( + GetOrCreateMemoryCache(handle), std::move(persistent_cache))); +} + +std::unique_ptr<DawnCachingInterface> +DawnCachingInterfaceFactory::CreateInstance() { + return base::WrapUnique(new DawnCachingInterface(backend_factory_.Run())); +} + +scoped_refptr<detail::DawnMemoryCache> +DawnCachingInterfaceFactory::GetOrCreateMemoryCache( + const gpu::GpuDiskCacheHandle& handle) { DCHECK(gpu::GetHandleType(handle) == gpu::GpuDiskCacheType::kDawnWebGPU || gpu::GetHandleType(handle) == gpu::GpuDiskCacheType::kDawnGraphite); if (const auto it = backends_.find(handle); it != backends_.end()) { - return base::WrapUnique( - new DawnCachingInterface(it->second, std::move(callback))); + return it->second; } scoped_refptr<detail::DawnMemoryCache> backend = backend_factory_.Run(); if (backend != nullptr) { backends_[handle] = backend; } - return base::WrapUnique( - new DawnCachingInterface(std::move(backend), std::move(callback))); -} -std::unique_ptr<DawnCachingInterface> -DawnCachingInterfaceFactory::CreateInstance() { - return base::WrapUnique(new DawnCachingInterface(backend_factory_.Run())); + return backend; } void DawnCachingInterfaceFactory::ReleaseHandle(
diff --git a/gpu/command_buffer/service/dawn_caching_interface.h b/gpu/command_buffer/service/dawn_caching_interface.h index 8671f23..4d0ff048 100644 --- a/gpu/command_buffer/service/dawn_caching_interface.h +++ b/gpu/command_buffer/service/dawn_caching_interface.h
@@ -19,10 +19,14 @@ #include "base/synchronization/lock.h" #include "base/thread_annotations.h" #include "base/trace_event/memory_dump_provider.h" +#include "components/persistent_cache/persistent_cache.h" #include "gpu/gpu_gles2_export.h" #include "gpu/ipc/common/gpu_disk_cache_type.h" namespace gpu { + +class GpuPersistentCache; + namespace webgpu { class DawnCachingInterfaceFactory; @@ -88,15 +92,9 @@ } // namespace detail -// Provides a wrapper class around an in-memory DawnMemoryCache. This class was -// originally designed to handle both disk and in-memory cache backends, but -// because it lives on the GPU process and does not have permissions (due to -// sandbox restrictions) to disk, the disk functionality was removed. Should it -// become necessary to provide interfaces over a disk level disk_cache::Backend, -// please refer to the file history for reference. Note that the big difference -// between in-memory and disk backends are the sync vs async nature of the two -// respectively. Because we are only handling in-memory backends now, the logic -// can be simplified to handle everything synchronously. +// Provides a wrapper class around an in-memory DawnMemoryCache and a disk +// cache. The disk cache controller can be provided either via a +// CacheBlobCallback or a GpuPersistentCache pointer. class GPU_GLES2_EXPORT DawnCachingInterface : public dawn::platform::CachingInterface { public: @@ -106,11 +104,13 @@ ~DawnCachingInterface() override; + void InitializePersistentCache( + persistent_cache::BackendParams backend_params); + size_t LoadData(const void* key, size_t key_size, void* value_out, size_t value_size) override; - void StoreData(const void* key, size_t key_size, const void* value, @@ -128,12 +128,21 @@ // the factory. explicit DawnCachingInterface(scoped_refptr<detail::DawnMemoryCache> backend, CacheBlobCallback callback = {}); + explicit DawnCachingInterface( + scoped_refptr<detail::DawnMemoryCache> backend, + std::unique_ptr<GpuPersistentCache> persistent_cache); // Caching interface owns a reference to the backend. scoped_refptr<detail::DawnMemoryCache> memory_cache_backend_ = nullptr; // The callback provides ability to store cache entries to persistent disk. CacheBlobCallback cache_blob_callback_; + + // The interface that allows storing and loading cache entries directly + // to/from disk. + // TODO(crbug.com/399642827): Remove the above callback once we migrate + // everything to use GpuPersistentCache API. + std::unique_ptr<GpuPersistentCache> persistent_cache_; }; // Factory class for producing and managing DawnCachingInterfaces. @@ -158,6 +167,10 @@ const gpu::GpuDiskCacheHandle& handle, DawnCachingInterface::CacheBlobCallback callback = {}); + std::unique_ptr<DawnCachingInterface> CreateInstance( + const gpu::GpuDiskCacheHandle& handle, + std::unique_ptr<GpuPersistentCache> persistent_cache); + // Returns a pointer to a DawnCachingInterface that owns the in memory // backend. This is used for incognito cases where the cache should not be // persisted to disk. @@ -182,6 +195,9 @@ base::trace_event::ProcessMemoryDump* pmd) override; private: + scoped_refptr<detail::DawnMemoryCache> GetOrCreateMemoryCache( + const gpu::GpuDiskCacheHandle& handle); + // Creates a default backend for assignment. static scoped_refptr<detail::DawnMemoryCache> CreateDefaultInMemoryBackend();
diff --git a/gpu/command_buffer/service/dawn_caching_interface_unittest.cc b/gpu/command_buffer/service/dawn_caching_interface_unittest.cc index 9041d2c..28b22ce 100644 --- a/gpu/command_buffer/service/dawn_caching_interface_unittest.cc +++ b/gpu/command_buffer/service/dawn_caching_interface_unittest.cc
@@ -12,7 +12,12 @@ #include <string> #include <string_view> +#include "base/files/file_util.h" +#include "base/files/scoped_temp_dir.h" #include "base/test/scoped_feature_list.h" +#include "components/persistent_cache/backend_params.h" +#include "components/persistent_cache/sqlite/vfs/sandboxed_file.h" +#include "gpu/command_buffer/service/gpu_persistent_cache.h" #include "gpu/command_buffer/service/mocks.h" #include "gpu/config/gpu_finch_features.h" #include "testing/gmock/include/gmock/gmock.h" @@ -292,5 +297,80 @@ } } +// Verifies that data stored in a persistent cache can be loaded back. +TEST_F(DawnCachingInterfaceTest, StoreAndLoadWithPersistentCache) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + auto shared_lock = base::UnsafeSharedMemoryRegion::Create( + sizeof(persistent_cache::LockState)); + ASSERT_TRUE(shared_lock.IsValid()); + auto OpenPersistentCache = + [&temp_dir, &shared_lock]() -> std::unique_ptr<GpuPersistentCache> { + auto db_path = temp_dir.GetPath().AppendASCII("test.db"); + auto journal_path = temp_dir.GetPath().AppendASCII("test.journal"); + + persistent_cache::BackendParams params; + params.type = persistent_cache::BackendType::kSqlite; + params.db_file = + base::File(db_path, base::File::FLAG_OPEN_ALWAYS | + base::File::FLAG_READ | base::File::FLAG_WRITE); + params.journal_file = base::File( + journal_path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ | + base::File::FLAG_WRITE); + params.shared_lock = shared_lock.Duplicate(); + CHECK(params.db_file.IsValid()); + CHECK(params.journal_file.IsValid()); + + auto persistent_cache = std::make_unique<GpuPersistentCache>("Test"); + persistent_cache->InitializeCache(std::move(params)); + return persistent_cache; + }; + + // Store data to the persistent cache via store interface. + { + scoped_refptr<detail::DawnMemoryCache> memory_cache = + base::MakeRefCounted<detail::DawnMemoryCache>(1024); + DawnCachingInterfaceFactory store_factory(base::BindRepeating( + [](scoped_refptr<detail::DawnMemoryCache> cache) { return cache; }, + memory_cache)); + auto store_interface = + store_factory.CreateInstance(handle_, OpenPersistentCache()); + store_interface->StoreData(kKey.data(), kKeySize, kData.data(), kDataSize); + + // Check that the entry exists in the memory cache. + char buffer[kDataSize]; + EXPECT_EQ(kDataSize, memory_cache->LoadData(std::string(kKey), nullptr, 0)); + EXPECT_EQ(kDataSize, + memory_cache->LoadData(std::string(kKey), buffer, kDataSize)); + EXPECT_EQ(0, memcmp(buffer, kData.data(), kDataSize)); + } + + // Use the same persistent cache but with different memory cache. + { + scoped_refptr<detail::DawnMemoryCache> memory_cache2 = + base::MakeRefCounted<detail::DawnMemoryCache>(1024); + DawnCachingInterfaceFactory load_factory(base::BindRepeating( + [](scoped_refptr<detail::DawnMemoryCache> cache) { return cache; }, + memory_cache2)); + auto load_interface = + load_factory.CreateInstance(handle_, OpenPersistentCache()); + + EXPECT_EQ(0u, memory_cache2->LoadData(std::string(kKey), nullptr, 0)); + + // Verify that we can query the existing entry. + char buffer[kDataSize]; + EXPECT_EQ(kDataSize, + load_interface->LoadData(kKey.data(), kKeySize, nullptr, 0)); + EXPECT_EQ(kDataSize, load_interface->LoadData(kKey.data(), kKeySize, buffer, + kDataSize)); + EXPECT_EQ(0, memcmp(buffer, kData.data(), kDataSize)); + + // Check that the memory cache now contains the same entry after the + // LoadData() call above + EXPECT_EQ(kDataSize, + memory_cache2->LoadData(std::string(kKey), nullptr, 0)); + } +} + } // namespace } // namespace gpu::webgpu
diff --git a/gpu/command_buffer/service/dawn_context_provider.cc b/gpu/command_buffer/service/dawn_context_provider.cc index a0f6ae6..1ce5b762 100644 --- a/gpu/command_buffer/service/dawn_context_provider.cc +++ b/gpu/command_buffer/service/dawn_context_provider.cc
@@ -444,7 +444,7 @@ const GpuDriverBugWorkarounds& workarounds, DawnContextProvider::ValidateAdapterFn validate_adapter_fn); void SetCachingInterface( - std::unique_ptr<dawn::platform::CachingInterface> caching_interface); + std::unique_ptr<webgpu::DawnCachingInterface> caching_interface); wgpu::Device GetDevice() const { return device_; } wgpu::BackendType backend_type() const { return backend_type_; } @@ -456,7 +456,7 @@ webgpu::DawnPlatform* GetDawnPlatform() { return &platform_; } - dawn::platform::CachingInterface* GetCachingInterface() { + webgpu::DawnCachingInterface* GetCachingInterface() { return caching_interface_.get(); } @@ -670,7 +670,7 @@ bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) override; - std::unique_ptr<dawn::platform::CachingInterface> caching_interface_; + std::unique_ptr<webgpu::DawnCachingInterface> caching_interface_; Platform platform_; std::unique_ptr<webgpu::DawnInstance> instance_; @@ -982,7 +982,7 @@ } void DawnSharedContext::SetCachingInterface( - std::unique_ptr<dawn::platform::CachingInterface> caching_interface) { + std::unique_ptr<webgpu::DawnCachingInterface> caching_interface) { CHECK(!caching_interface_); caching_interface_ = std::move(caching_interface); } @@ -1239,14 +1239,13 @@ } void DawnContextProvider::SetCachingInterface( - std::unique_ptr<dawn::platform::CachingInterface> caching_interface) { + std::unique_ptr<webgpu::DawnCachingInterface> caching_interface) { CHECK(dawn_shared_context_->HasOneRef()); CHECK(!graphite_shared_context_); dawn_shared_context_->SetCachingInterface(std::move(caching_interface)); } -dawn::platform::CachingInterface* DawnContextProvider::GetCachingInterface() - const { +webgpu::DawnCachingInterface* DawnContextProvider::GetCachingInterface() const { return dawn_shared_context_->GetCachingInterface(); }
diff --git a/gpu/command_buffer/service/dawn_context_provider.h b/gpu/command_buffer/service/dawn_context_provider.h index 013449e..6a8adfe 100644 --- a/gpu/command_buffer/service/dawn_context_provider.h +++ b/gpu/command_buffer/service/dawn_context_provider.h
@@ -86,9 +86,9 @@ // Sets the caching interface. This must be called before graphite context // is created and before device is shared with any other threads. void SetCachingInterface( - std::unique_ptr<dawn::platform::CachingInterface> caching_interface); + std::unique_ptr<webgpu::DawnCachingInterface> caching_interface); - dawn::platform::CachingInterface* GetCachingInterface() const; + webgpu::DawnCachingInterface* GetCachingInterface() const; bool use_thread_safe_shared_context() const;
diff --git a/gpu/command_buffer/service/gpu_persistent_cache.cc b/gpu/command_buffer/service/gpu_persistent_cache.cc index dbff0c2..2957d7d 100644 --- a/gpu/command_buffer/service/gpu_persistent_cache.cc +++ b/gpu/command_buffer/service/gpu_persistent_cache.cc
@@ -71,9 +71,25 @@ size_t key_size, void* value, size_t value_size) { + std::string_view key_str(static_cast<const char*>(key), key_size); + std::unique_ptr<persistent_cache::Entry> entry = LoadEntry(key_str); + if (!entry) { + return 0; + } + + if (value_size > 0) { + return entry->CopyContentTo( + UNSAFE_TODO(base::span(static_cast<uint8_t*>(value), value_size))); + } + + return entry->GetContentSize(); +} + +std::unique_ptr<persistent_cache::Entry> GpuPersistentCache::LoadEntry( + std::string_view key) { ScopedHistogramTimer timer(GetHistogramName("Load")); SCOPED_LOCK(lock_); - TRACE_EVENT1("gpu", "GpuPersistentCache::LoadData", "persistent_cache_", + TRACE_EVENT1("gpu", "GpuPersistentCache::LoadEntry", "persistent_cache_", !!persistent_cache_); // Track cache available for the 1st kMaxLoadStoreForTrackingCacheAvailable @@ -85,23 +101,11 @@ if (!persistent_cache_) { timer.SetEnabled(false); - return 0; + return nullptr; } - std::string_view key_str(static_cast<const char*>(key), key_size); - std::unique_ptr<persistent_cache::Entry> entry = - persistent_cache_->Find(key_str); + return persistent_cache_->Find(key); - if (!entry) { - return 0; - } - - if (value_size > 0) { - return entry->CopyContentTo( - UNSAFE_TODO(base::span(static_cast<uint8_t*>(value), value_size))); - } - - return entry->GetContentSize(); } void GpuPersistentCache::StoreData(const void* key,
diff --git a/gpu/command_buffer/service/gpu_persistent_cache.h b/gpu/command_buffer/service/gpu_persistent_cache.h index d066973..4100aa1 100644 --- a/gpu/command_buffer/service/gpu_persistent_cache.h +++ b/gpu/command_buffer/service/gpu_persistent_cache.h
@@ -18,7 +18,8 @@ namespace persistent_cache { class PersistentCache; -} +class Entry; +} // namespace persistent_cache namespace gpu { @@ -44,6 +45,8 @@ const void* value, size_t value_size) override; + std::unique_ptr<persistent_cache::Entry> LoadEntry(std::string_view key); + private: std::string GetHistogramName(std::string_view metric) const;
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc index cc818010..dd81502 100644 --- a/gpu/command_buffer/service/shared_image/d3d_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/d3d_image_backing.cc
@@ -1006,7 +1006,7 @@ SharedImageManager* manager, MemoryTypeTracker* tracker, VideoDevice device) { - if (texture_d3d11_device_ != device && !dxgi_shared_handle_state_) { + if (texture_d3d11_device_ != device) { // Readback is the only option for a caller cannot create a representation // for this shared image. When the caller cannot use a shared device // (GL/Ganesh) create a copy since this is much more efficient than forcing
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc index 0aa7f21..08f3da2 100644 --- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc +++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.cc
@@ -12,7 +12,10 @@ #include "base/memory/shared_memory_mapping.h" #include "base/strings/string_number_conversions.h" +#include "base/synchronization/waitable_event.h" +#include "base/trace_event/trace_event.h" #include "base/win/scoped_handle.h" +#include "components/viz/common/resources/shared_image_format_utils.h" #include "gpu/command_buffer/common/shared_image_usage.h" #include "gpu/command_buffer/service/dxgi_shared_handle_manager.h" #include "gpu/command_buffer/service/shared_image/d3d_image_backing.h" @@ -20,8 +23,10 @@ #include "gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.h" #include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h" #include "gpu/config/gpu_finch_features.h" +#include "gpu/ipc/common/dxgi_helpers.h" #include "ui/gfx/buffer_format_util.h" #include "ui/gfx/buffer_types.h" +#include "ui/gfx/buffer_usage_util.h" #include "ui/gfx/color_space_win.h" #include "ui/gl/direct_composition_support.h" #include "ui/gl/gl_angle_util_win.h" @@ -225,13 +230,107 @@ D3DImageBackingFactory::SwapChainBackings&&) = default; // static +gfx::GpuMemoryBufferHandle +D3DImageBackingFactory::CreateGpuMemoryBufferHandleOnIO( + scoped_refptr<base::SingleThreadTaskRunner> io_runner, + const gfx::Size& size, + viz::SharedImageFormat format, + gfx::BufferUsage usage) { + gfx::GpuMemoryBufferHandle result; + base::WaitableEvent event; + + io_runner->PostTask( + FROM_HERE, base::BindOnce( + [](gfx::GpuMemoryBufferHandle* out_gmb_handle, + base::WaitableEvent* waitable_event, + scoped_refptr<base::SingleThreadTaskRunner> io_runner, + const gfx::Size& size, viz::SharedImageFormat format, + gfx::BufferUsage usage) { + *out_gmb_handle = + D3DImageBackingFactory::CreateGpuMemoryBufferHandle( + io_runner, size, format, usage); + + waitable_event->Signal(); + }, + &result, &event, io_runner, size, format, usage)); + + event.Wait(); + + return result; +} + +// static gfx::GpuMemoryBufferHandle D3DImageBackingFactory::CreateGpuMemoryBufferHandle( scoped_refptr<base::SingleThreadTaskRunner> io_runner, const gfx::Size& size, viz::SharedImageFormat format, gfx::BufferUsage usage) { - return GetGpuMemoryBufferFactoryDXGI(io_runner)->CreateNativeGmbHandle( - size, format, usage); + if (io_runner && !io_runner->BelongsToCurrentThread()) { + // Thread-hop is required! + return CreateGpuMemoryBufferHandleOnIO(io_runner, size, format, usage); + } + + TRACE_EVENT0("gpu", "D3DImageBackingFactory::CrceateGpuMemoryBufferHandle"); + + gfx::GpuMemoryBufferHandle handle; + auto d3d11_device = + GetGpuMemoryBufferFactoryDXGI(io_runner)->GetOrCreateD3D11Device(); + if (!d3d11_device) { + return handle; + } + + DXGI_FORMAT dxgi_format = gpu::ToDXGIFormat(format); + if (dxgi_format == DXGI_FORMAT_UNKNOWN) { + return handle; + } + + auto buffer_size = viz::SharedMemorySizeForSharedImageFormat(format, size); + if (!buffer_size) { + return handle; + } + + // We are binding as a shader resource and render target regardless of usage, + // so make sure that the usage is one that we support. + DCHECK(usage == gfx::BufferUsage::GPU_READ || + usage == gfx::BufferUsage::SCANOUT || + usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE) + << "Incorrect usage, usage=" << gfx::BufferUsageToString(usage); + + D3D11_TEXTURE2D_DESC desc = { + static_cast<UINT>(size.width()), + static_cast<UINT>(size.height()), + 1, + 1, + dxgi_format, + {1, 0}, + D3D11_USAGE_DEFAULT, + D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, + 0, + D3D11_RESOURCE_MISC_SHARED_NTHANDLE | + D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX}; + + Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture; + + if (FAILED(d3d11_device->CreateTexture2D(&desc, nullptr, &d3d11_texture))) { + return handle; + } + + Microsoft::WRL::ComPtr<IDXGIResource1> dxgi_resource; + if (FAILED(d3d11_texture.As(&dxgi_resource))) { + return handle; + } + + HANDLE texture_handle; + if (FAILED(dxgi_resource->CreateSharedHandle( + nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, + nullptr, &texture_handle))) { + return handle; + } + + handle = gfx::GpuMemoryBufferHandle( + gfx::DXGIHandle(base::win::ScopedHandle(texture_handle))); + + return handle; } // static @@ -239,9 +338,23 @@ scoped_refptr<base::SingleThreadTaskRunner> io_runner, gfx::GpuMemoryBufferHandle buffer_handle, base::UnsafeSharedMemoryRegion shared_memory) { - return GetGpuMemoryBufferFactoryDXGI(io_runner) - ->FillSharedMemoryRegionWithBufferContents(std::move(buffer_handle), - std::move(shared_memory)); + DCHECK_EQ(buffer_handle.type, gfx::GpuMemoryBufferType::DXGI_SHARED_HANDLE); + auto* gmb_factory = GetGpuMemoryBufferFactoryDXGI(io_runner); + + auto d3d11_device = gmb_factory->GetOrCreateD3D11Device(); + if (!d3d11_device) { + return false; + } + + base::WritableSharedMemoryMapping mapping = shared_memory.Map(); + if (!mapping.IsValid()) { + return false; + } + + return CopyDXGIBufferToShMem(buffer_handle.dxgi_handle().buffer_handle(), + mapping.GetMemoryAsSpan<uint8_t>(), + d3d11_device.Get(), + &gmb_factory->staging_texture()); } // static
diff --git a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h index a320320..686e1b74 100644 --- a/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h +++ b/gpu/command_buffer/service/shared_image/d3d_image_backing_factory.h
@@ -148,6 +148,12 @@ } private: + static gfx::GpuMemoryBufferHandle CreateGpuMemoryBufferHandleOnIO( + scoped_refptr<base::SingleThreadTaskRunner> io_runner, + const gfx::Size& size, + viz::SharedImageFormat format, + gfx::BufferUsage usage); + std::unique_ptr<SharedImageBacking> CreateSharedBufferD3D12( const Mailbox& mailbox, const gfx::Size& size,
diff --git a/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.cc b/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.cc index e0b9491..1820025 100644 --- a/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.cc +++ b/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.cc
@@ -4,20 +4,8 @@ #include "gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.h" -#include <vector> - -#include "base/memory/unsafe_shared_memory_region.h" -#include "base/synchronization/waitable_event.h" #include "base/task/single_thread_task_runner.h" -#include "base/trace_event/trace_event.h" -#include "components/viz/common/resources/shared_image_format_utils.h" -#include "gpu/command_buffer/service/shared_image/shared_image_format_service_utils.h" -#include "gpu/ipc/common/dxgi_helpers.h" -#include "ui/gfx/buffer_format_util.h" -#include "ui/gfx/buffer_types.h" -#include "ui/gfx/buffer_usage_util.h" #include "ui/gl/gl_angle_util_win.h" -#include "ui/gl/gl_bindings.h" namespace gpu { @@ -110,124 +98,4 @@ return d3d11_device_; } -gfx::GpuMemoryBufferHandle -GpuMemoryBufferFactoryDXGI::CreateNativeGmbHandleOnIO( - const gfx::Size& size, - viz::SharedImageFormat format, - gfx::BufferUsage usage) { - DCHECK(io_runner_); - - gfx::GpuMemoryBufferHandle result; - base::WaitableEvent event; - - io_runner_->PostTask( - FROM_HERE, - base::BindOnce( - [](gfx::GpuMemoryBufferHandle* out_gmb_handle, - base::WaitableEvent* waitable_event, - GpuMemoryBufferFactoryDXGI* factory, const gfx::Size& size, - viz::SharedImageFormat format, gfx::BufferUsage usage) { - *out_gmb_handle = - factory->CreateNativeGmbHandle(size, format, usage); - - waitable_event->Signal(); - }, - &result, &event, this, size, format, usage)); - - event.Wait(); - - return result; -} - -gfx::GpuMemoryBufferHandle GpuMemoryBufferFactoryDXGI::CreateNativeGmbHandle( - const gfx::Size& size, - viz::SharedImageFormat format, - gfx::BufferUsage usage) { - if (io_runner_ && !io_runner_->BelongsToCurrentThread()) { - // Thread-hop is required! - return CreateNativeGmbHandleOnIO(size, format, usage); - } - - TRACE_EVENT0("gpu", "GpuMemoryBufferFactoryDXGI::CreateNativeGmbHandle"); - - gfx::GpuMemoryBufferHandle handle; - auto d3d11_device = GetOrCreateD3D11Device(); - if (!d3d11_device) { - return handle; - } - - DXGI_FORMAT dxgi_format = gpu::ToDXGIFormat(format); - if (dxgi_format == DXGI_FORMAT_UNKNOWN) { - return handle; - } - - auto buffer_size = viz::SharedMemorySizeForSharedImageFormat(format, size); - if (!buffer_size) { - return handle; - } - - // We are binding as a shader resource and render target regardless of usage, - // so make sure that the usage is one that we support. - DCHECK(usage == gfx::BufferUsage::GPU_READ || - usage == gfx::BufferUsage::SCANOUT || - usage == gfx::BufferUsage::SCANOUT_CPU_READ_WRITE) - << "Incorrect usage, usage=" << gfx::BufferUsageToString(usage); - - D3D11_TEXTURE2D_DESC desc = { - static_cast<UINT>(size.width()), - static_cast<UINT>(size.height()), - 1, - 1, - dxgi_format, - {1, 0}, - D3D11_USAGE_DEFAULT, - D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET, - 0, - D3D11_RESOURCE_MISC_SHARED_NTHANDLE | - D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX}; - - Microsoft::WRL::ComPtr<ID3D11Texture2D> d3d11_texture; - - if (FAILED(d3d11_device->CreateTexture2D(&desc, nullptr, &d3d11_texture))) { - return handle; - } - - Microsoft::WRL::ComPtr<IDXGIResource1> dxgi_resource; - if (FAILED(d3d11_texture.As(&dxgi_resource))) { - return handle; - } - - HANDLE texture_handle; - if (FAILED(dxgi_resource->CreateSharedHandle( - nullptr, DXGI_SHARED_RESOURCE_READ | DXGI_SHARED_RESOURCE_WRITE, - nullptr, &texture_handle))) { - return handle; - } - - handle = gfx::GpuMemoryBufferHandle( - gfx::DXGIHandle(base::win::ScopedHandle(texture_handle))); - - return handle; -} - -bool GpuMemoryBufferFactoryDXGI::FillSharedMemoryRegionWithBufferContents( - gfx::GpuMemoryBufferHandle buffer_handle, - base::UnsafeSharedMemoryRegion shared_memory) { - DCHECK_EQ(buffer_handle.type, gfx::GpuMemoryBufferType::DXGI_SHARED_HANDLE); - - auto d3d11_device = GetOrCreateD3D11Device(); - if (!d3d11_device) { - return false; - } - - base::WritableSharedMemoryMapping mapping = shared_memory.Map(); - if (!mapping.IsValid()) { - return false; - } - - return CopyDXGIBufferToShMem(buffer_handle.dxgi_handle().buffer_handle(), - mapping.GetMemoryAsSpan<uint8_t>(), - d3d11_device.Get(), &staging_texture_); -} - } // namespace gpu
diff --git a/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.h b/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.h index 8891eb2..2db15b8 100644 --- a/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.h +++ b/gpu/command_buffer/service/shared_image/gpu_memory_buffer_factory_dxgi.h
@@ -36,22 +36,12 @@ GpuMemoryBufferFactoryDXGI& operator=(const GpuMemoryBufferFactoryDXGI&) = delete; - gfx::GpuMemoryBufferHandle CreateNativeGmbHandle( - const gfx::Size& size, - viz::SharedImageFormat format, - gfx::BufferUsage usage); - bool FillSharedMemoryRegionWithBufferContents( - gfx::GpuMemoryBufferHandle buffer_handle, - base::UnsafeSharedMemoryRegion shared_memory); + Microsoft::WRL::ComPtr<ID3D11Device> GetOrCreateD3D11Device(); + Microsoft::WRL::ComPtr<ID3D11Texture2D> staging_texture() { + return staging_texture_; + } private: - Microsoft::WRL::ComPtr<ID3D11Device> GetOrCreateD3D11Device(); - - gfx::GpuMemoryBufferHandle CreateNativeGmbHandleOnIO( - const gfx::Size& size, - viz::SharedImageFormat format, - gfx::BufferUsage usage); - Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_ GUARDED_BY_CONTEXT(thread_checker_);
diff --git a/gpu/config/gpu_info_collector.cc b/gpu/config/gpu_info_collector.cc index 841443d7..e057ed5 100644 --- a/gpu/config/gpu_info_collector.cc +++ b/gpu/config/gpu_info_collector.cc
@@ -91,7 +91,6 @@ scoped_refptr<gl::GLContext> InitializeGLContext(gl::GLSurface* surface) { TRACE_EVENT("gpu,startup", "gpu_info_collector::InitializeGLContext"); gl::GLContextAttribs attribs; - attribs.client_major_es_version = 2; scoped_refptr<gl::GLContext> context( gl::init::CreateGLContext(nullptr, surface, attribs)); if (!context.get()) {
diff --git a/internal b/internal index a60d46c..796b60e 160000 --- a/internal +++ b/internal
@@ -1 +1 @@ -Subproject commit a60d46ccb6f87592fb259207f7a7dc29797258fe +Subproject commit 796b60e971aab3ab6e82cb1514b01b17a06c62dc
diff --git a/ios/chrome/app/strings/ios_strings.grd b/ios/chrome/app/strings/ios_strings.grd index 86587e0..1ee56132 100644 --- a/ios/chrome/app/strings/ios_strings.grd +++ b/ios/chrome/app/strings/ios_strings.grd
@@ -297,6 +297,12 @@ <message name="IDS_IOS_AI_HUB_POPUP_BLOCKER_LABEL" desc="The button label for the Pop-up blocker feature of the AI hub."> Pop-ups blocked </message> + <message name="IDS_IOS_AI_HUB_PRICE_TRACKING_BUTTON_LABEL" desc="The button label for tracking prices in the Price tracking feature of the AI hub."> + Tracking + </message> + <message name="IDS_IOS_AI_HUB_PRICE_TRACKING_LABEL" desc="The label for the Price tracking feature of the AI hub."> + Price history + </message> <message name="IDS_IOS_AI_HUB_READER_MODE_LABEL" desc="The button label for the Reader mode entry point of the AI hub."> Reading Mode </message>
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AI_HUB_PRICE_TRACKING_BUTTON_LABEL.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AI_HUB_PRICE_TRACKING_BUTTON_LABEL.png.sha1 new file mode 100644 index 0000000..407bfa1 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AI_HUB_PRICE_TRACKING_BUTTON_LABEL.png.sha1
@@ -0,0 +1 @@ +0841787bbbfcecc18f82e5c0efbde2176d07340d \ No newline at end of file
diff --git a/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AI_HUB_PRICE_TRACKING_LABEL.png.sha1 b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AI_HUB_PRICE_TRACKING_LABEL.png.sha1 new file mode 100644 index 0000000..407bfa1 --- /dev/null +++ b/ios/chrome/app/strings/ios_strings_grd/IDS_IOS_AI_HUB_PRICE_TRACKING_LABEL.png.sha1
@@ -0,0 +1 @@ +0841787bbbfcecc18f82e5c0efbde2176d07340d \ No newline at end of file
diff --git a/ios/chrome/browser/fullscreen/ui_bundled/test/test_fullscreen_controller.h b/ios/chrome/browser/fullscreen/ui_bundled/test/test_fullscreen_controller.h index 9af4c2b2..ef64c36 100644 --- a/ios/chrome/browser/fullscreen/ui_bundled/test/test_fullscreen_controller.h +++ b/ios/chrome/browser/fullscreen/ui_bundled/test/test_fullscreen_controller.h
@@ -72,7 +72,7 @@ private: // The model. - std::unique_ptr<FullscreenModel> model_ = std::make_unique<FullscreenModel>(); + std::unique_ptr<FullscreenModel> model_; // The broadcaster. ChromeBroadcaster* broadcaster_ = nil; // The observers.
diff --git a/ios/chrome/browser/intelligence/page_action_menu/coordinator/BUILD.gn b/ios/chrome/browser/intelligence/page_action_menu/coordinator/BUILD.gn index cc02c31..6562954 100644 --- a/ios/chrome/browser/intelligence/page_action_menu/coordinator/BUILD.gn +++ b/ios/chrome/browser/intelligence/page_action_menu/coordinator/BUILD.gn
@@ -10,11 +10,13 @@ "page_action_menu_mediator.mm", ] deps = [ + "//components/content_settings/core/browser", "//components/prefs", "//components/search", "//components/search_engines", "//components/signin/public/identity_manager", "//ios/chrome/app/strings", + "//ios/chrome/browser/content_settings/model", "//ios/chrome/browser/dom_distiller/model", "//ios/chrome/browser/intelligence/bwg/coordinator", "//ios/chrome/browser/intelligence/bwg/model",
diff --git a/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_coordinator.mm b/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_coordinator.mm index 09d3e7f..33405b0c 100644 --- a/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_coordinator.mm +++ b/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_coordinator.mm
@@ -4,6 +4,7 @@ #import "ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_coordinator.h" +#import "ios/chrome/browser/content_settings/model/host_content_settings_map_factory.h" #import "ios/chrome/browser/dom_distiller/model/distiller_service_factory.h" #import "ios/chrome/browser/intelligence/bwg/model/bwg_service_factory.h" #import "ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.h" @@ -52,13 +53,17 @@ ReaderModeTabHelper* readerModeTabHelper = ReaderModeTabHelper::FromWebState(activeWebState); + + HostContentSettingsMap* hostContentSettingsMap = + ios::HostContentSettingsMapFactory::GetForProfile(self.profile); _mediator = [[PageActionMenuMediator alloc] - initWithWebState:activeWebState - profilePrefService:self.profile->GetPrefs() - templateURLService:ios::TemplateURLServiceFactory::GetForProfile( - self.profile) - BWGService:BwgServiceFactory::GetForProfile(self.profile) - readerModeTabHelper:readerModeTabHelper]; + initWithWebState:activeWebState + profilePrefService:self.profile->GetPrefs() + templateURLService:ios::TemplateURLServiceFactory::GetForProfile( + self.profile) + BWGService:BwgServiceFactory::GetForProfile(self.profile) + readerModeTabHelper:readerModeTabHelper + hostContentSettingsMap:hostContentSettingsMap]; id<PageActionMenuCommands> pageActionMenuHandler = HandlerForProtocol( self.browser->GetCommandDispatcher(), PageActionMenuCommands);
diff --git a/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.h b/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.h index 419912c2..a7f4113 100644 --- a/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.h +++ b/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.h
@@ -14,6 +14,7 @@ class PrefService; class ReaderModeTabHelper; class TemplateURLService; +class HostContentSettingsMap; @protocol PageActionMenuCommands; @@ -30,6 +31,7 @@ templateURLService:(TemplateURLService*)templateURLService BWGService:(BwgService*)BWGService readerModeTabHelper:(ReaderModeTabHelper*)readerModeTabHelper + hostContentSettingsMap:(HostContentSettingsMap*)hostContentSettingsMap NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE;
diff --git a/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.mm b/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.mm index af63d2ce..149198e 100644 --- a/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.mm +++ b/ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.mm
@@ -5,6 +5,7 @@ #import "ios/chrome/browser/intelligence/page_action_menu/coordinator/page_action_menu_mediator.h" #import "base/strings/sys_string_conversions.h" +#import "components/content_settings/core/browser/host_content_settings_map.h" #import "components/prefs/pref_service.h" #import "components/search/search.h" #import "components/search_engines/template_url_service.h" @@ -55,13 +56,18 @@ // The tab helper for Reader mode. raw_ptr<ReaderModeTabHelper> _readerModeTabHelper; + + // The host content settings map for managing site permissions. + raw_ptr<HostContentSettingsMap> _hostContentSettingsMap; } - (instancetype)initWithWebState:(web::WebState*)webState profilePrefService:(PrefService*)profilePrefs templateURLService:(TemplateURLService*)templateURLService BWGService:(BwgService*)BWGService - readerModeTabHelper:(ReaderModeTabHelper*)readerModeTabHelper { + readerModeTabHelper:(ReaderModeTabHelper*)readerModeTabHelper + hostContentSettingsMap: + (HostContentSettingsMap*)hostContentSettingsMap { self = [super init]; if (self) { _webState = webState; @@ -69,6 +75,7 @@ _templateURLService = templateURLService; _BWGService = BWGService; _readerModeTabHelper = readerModeTabHelper; + _hostContentSettingsMap = hostContentSettingsMap; _webStateObserver = std::make_unique<web::WebStateObserverBridge>(self); _webState->AddObserver(_webStateObserver.get()); } @@ -144,9 +151,23 @@ return state == web::PermissionStateAllowed; } case PageActionMenuPopupBlocker: { + if (!_hostContentSettingsMap) { + return NO; + } + GURL url = _webState->GetLastCommittedURL(); + ContentSetting setting = _hostContentSettingsMap->GetContentSetting( + url, url, ContentSettingsType::POPUPS); + + // Show row only if blocking is active AND there are blocked popups. BlockedPopupTabHelper* helper = BlockedPopupTabHelper::GetOrCreateForWebState(_webState); - return helper && helper->GetBlockedPopupCount() > 0; + bool hasBlockedPopups = helper && helper->GetBlockedPopupCount() > 0; + + return setting == CONTENT_SETTING_BLOCK && hasBlockedPopups; + } + case PageActionMenuPriceTracking: { + // TODO(crbug.com/447143165): Add price tracking detection. + return NO; } } } @@ -203,6 +224,7 @@ break; case PageActionMenuTranslate: case PageActionMenuPopupBlocker: + case PageActionMenuPriceTracking: CHECK(false) << "revokePermission called with non-permission feature type: " << featureType; @@ -283,10 +305,56 @@ micFeature.toggleState = YES; [features addObject:micFeature]; } + // Price tracking feature. + if ([self isFeatureAvailable:PageActionMenuPriceTracking]) { + PageActionMenuFeature* priceTrackingFeature = [[PageActionMenuFeature alloc] + initWithFeatureType:PageActionMenuPriceTracking + title:l10n_util::GetNSString( + IDS_IOS_AI_HUB_PRICE_TRACKING_LABEL) + icon:CustomSymbolWithPointSize(kDownTrendSymbol, + kFeatureRowIconSize) + actionType:PageActionMenuButtonAction]; + priceTrackingFeature.actionText = + l10n_util::GetNSString(IDS_IOS_AI_HUB_PRICE_TRACKING_BUTTON_LABEL); + [features addObject:priceTrackingFeature]; + } return features; } +- (void)allowBlockedPopups { + if (!_webState || !_hostContentSettingsMap) { + return; + } + + BlockedPopupTabHelper* helper = + BlockedPopupTabHelper::GetOrCreateForWebState(_webState); + if (!helper) { + return; + } + + // Get the blocked popups. + std::vector<BlockedPopupTabHelper::Popup> popups = helper->GetBlockedPopups(); + + GURL currentUrl = _webState->GetLastCommittedURL(); + + // Open each blocked popup and allow future popups from this site. + for (const auto& popup : popups) { + web::WebState::OpenURLParams params(popup.popup_url, popup.referrer, + WindowOpenDisposition::NEW_POPUP, + ui::PAGE_TRANSITION_LINK, true); + _webState->OpenURL(params); + + // Set popup permission to ALLOW for the referrer site. + _hostContentSettingsMap->SetContentSettingCustomScope( + ContentSettingsPattern::FromURL(popup.referrer.url), + ContentSettingsPattern::Wildcard(), ContentSettingsType::POPUPS, + CONTENT_SETTING_ALLOW); + } + + [self.consumer updateFeatureRowsAvailability]; +} + #pragma mark - CRWWebStateObserver - (void)webStateDidStartLoading:(web::WebState*)webState { @@ -345,4 +413,10 @@ ->current_language(); } +// Returns true if price tracking is currently active for the page. +- (BOOL)isPriceTrackingAvailable { + // TODO(crbug.com/447143165): Implement price tracking detection. + return NO; +} + @end
diff --git a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_feature.h b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_feature.h index 8524e7b..4a9bc24 100644 --- a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_feature.h +++ b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_feature.h
@@ -13,6 +13,7 @@ PageActionMenuPopupBlocker, PageActionMenuCameraPermission, PageActionMenuMicrophonePermission, + PageActionMenuPriceTracking, }; // Types of actions a feature perform.
diff --git a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_mutator.h b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_mutator.h index b2370d6..a8b0c48 100644 --- a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_mutator.h +++ b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_mutator.h
@@ -45,6 +45,12 @@ // Returns array of currently active features to display. - (NSArray<PageActionMenuFeature*>*)activeFeatures; +// Allows all blocked popups for the current site. +- (void)allowBlockedPopups; + +// Returns whether price tracking is available for the current page. +- (BOOL)isPriceTrackingAvailable; + @end #endif // IOS_CHROME_BROWSER_INTELLIGENCE_PAGE_ACTION_MENU_UI_PAGE_ACTION_MENU_MUTATOR_H_
diff --git a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm index e827933..f666b76c 100644 --- a/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm +++ b/ios/chrome/browser/intelligence/page_action_menu/ui/page_action_menu_view_controller.mm
@@ -961,7 +961,10 @@ // TODO(crbug.com/447649727): Handle translate "Show original" action. break; case PageActionMenuPopupBlocker: - // TODO(crbug.com/447649727): Handle popup "Always show" action. + [self.mutator allowBlockedPopups]; + break; + case PageActionMenuPriceTracking: + // TODO(crbug.com/447143165): Handle price tracking action. break; default: break;
diff --git a/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest.mm b/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest.mm index 3675e889..1df1e44 100644 --- a/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest.mm +++ b/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest.mm
@@ -112,8 +112,9 @@ // Scroll to the top of the Reading List. void ScrollToTop() { - [[EarlGrey selectElementWithMatcher:grey_accessibilityID(kReadingListViewID)] - performAction:[ChromeActionsAppInterface scrollToTop]]; + XCUIApplication* springboardApplication = [[XCUIApplication alloc] + initWithBundleIdentifier:@"com.apple.springboard"]; + [springboardApplication.statusBars.firstMatch tap]; } // Asserts that the "mark" toolbar button is visible and has the a11y label of @@ -170,7 +171,7 @@ void PerformActionOnEntry(NSString* entryTitle, id<GREYAction> action) { ScrollToTop(); [[[EarlGrey selectElementWithMatcher:VisibleReadingListItem(entryTitle)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 100) + usingSearchAction:grey_swipeSlowInDirection(kGREYDirectionUp) onElementWithMatcher:grey_accessibilityID(kReadingListViewID)] performAction:action]; } @@ -190,7 +191,7 @@ void AssertEntryVisible(NSString* entryTitle) { ScrollToTop(); [[[EarlGrey selectElementWithMatcher:VisibleReadingListItem(entryTitle)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 100) + usingSearchAction:grey_swipeSlowInDirection(kGREYDirectionUp) onElementWithMatcher:grey_accessibilityID(kReadingListViewID)] assertWithMatcher:grey_notNil()]; } @@ -207,6 +208,7 @@ @"The number of entries have changed"); GREYAssertEqual((size_t)2, kNumberUnreadEntries, @"The number of entries have changed"); + ScrollToTop(); } // Asserts that the entry `title` is not visible. @@ -216,7 +218,7 @@ NSError* error; [[[EarlGrey selectElementWithMatcher:VisibleReadingListItem(title)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 100) + usingSearchAction:grey_swipeSlowInDirection(kGREYDirectionUp) onElementWithMatcher:grey_accessibilityID(kReadingListViewID)] assertWithMatcher:grey_notNil() error:&error]; @@ -824,7 +826,7 @@ AddEntriesAndOpenReadingList(); [[[EarlGrey selectElementWithMatcher:VisibleReadingListItem(kReadTitle)] - usingSearchAction:grey_scrollInDirection(kGREYDirectionDown, 100) + usingSearchAction:grey_swipeSlowInDirection(kGREYDirectionUp) onElementWithMatcher:grey_accessibilityID(kReadingListViewID)] performAction:grey_swipeFastInDirection(kGREYDirectionLeft)]; @@ -1250,9 +1252,8 @@ verifyOpenInIncognitoActionWithURL:distillablePageURL.GetContent()]; } -// TODO(crbug.com/446871565): This test is flaky. // Tests the Mark as Read/Unread context menu action for a reading list entry. -- (void)FLAKY_testContextMenuMarkAsReadAndBack { +- (void)testContextMenuMarkAsReadAndBack { #if TARGET_IPHONE_SIMULATOR // TODO(crbug.com/433982582): Flaky on an iPhone simulator. if ([ChromeEarlGrey isIPhoneIdiom]) { @@ -1271,6 +1272,9 @@ [ReadingListAppInterface unreadEntriesCount], @"Wrong number of unread entry."); + // TODO(crbug.com/446889046): Investigate if there is a better solution to fix + // flakiness on iOS26. + base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(1)); // Mark an unread entry as read. LongPressEntry(kUnreadTitle); @@ -1285,6 +1289,9 @@ [ReadingListAppInterface unreadEntriesCount], @"Wrong number of unread entry after marking read."); + // TODO(crbug.com/446889046): Investigate if there is a better solution to fix + // flakiness on iOS26. + base::test::ios::SpinRunLoopWithMinDelay(base::Seconds(1)); // Now mark it back as unread. LongPressEntry(kUnreadTitle);
diff --git a/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest_utils.mm b/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest_utils.mm index 8913c2f..d84437fc 100644 --- a/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest_utils.mm +++ b/ios/chrome/browser/reading_list/ui_bundled/reading_list_egtest_utils.mm
@@ -33,13 +33,13 @@ id<GREYMatcher> VisibleReadingListItem(NSString* entryTitle) { return grey_allOf(grey_accessibilityID(entryTitle), grey_kindOfClassName(@"TableViewURLCell"), - grey_sufficientlyVisible(), nil); + grey_minimumVisiblePercent(0.95), nil); } id<GREYMatcher> VisibleLocalItemIcon(NSString* title) { return grey_allOf(grey_ancestor(ReadingListItem(title)), grey_accessibilityID(kTableViewURLCellMetadataImageID), - grey_sufficientlyVisible(), nil); + grey_minimumVisiblePercent(0.95), nil); } // Opens the reading list menu.
diff --git a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_export_coordinator.mm b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_export_coordinator.mm index 9394444..d401adc 100644 --- a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_export_coordinator.mm +++ b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_export_coordinator.mm
@@ -58,9 +58,11 @@ } - (void)confirmationAlertSecondaryAction { + if (_importCoordinator) { + return; + } RecordActionOnSafariExportEducationScreen( SafariDataImportExportEducationAction::kContinue); - CHECK(!_importCoordinator); _importCoordinator = [[SafariDataImportImportCoordinator alloc] initWithBaseNavigationController:_navigationController browser:self.browser]; @@ -80,8 +82,10 @@ didShowViewController:(UIViewController*)viewController animated:(BOOL)animated { CHECK_EQ(navigationController, _navigationController); - if (viewController == _navigationController.viewControllers[0]) { + if (_importCoordinator && + viewController == _navigationController.viewControllers[0]) { /// Handle user going back from import stage. + RecordSafariDataImportTapsBackAtImportStage(_importCoordinator.importStage); [_importCoordinator stop]; _importCoordinator = nil; }
diff --git a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.h b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.h index fe11923e..40e461f 100644 --- a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.h +++ b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.h
@@ -8,6 +8,7 @@ #import "ios/chrome/browser/shared/coordinator/chrome_coordinator/chrome_coordinator.h" @protocol SafariDataImportChildCoordinatorDelegate; +enum class SafariDataImportStage; /// Coordinator for the safari data import screen. @interface SafariDataImportImportCoordinator : ChromeCoordinator @@ -16,6 +17,9 @@ @property(nonatomic, weak) id<SafariDataImportChildCoordinatorDelegate> delegate; +/// The current stage of import. +@property(nonatomic, readonly) SafariDataImportStage importStage; + /// Coordinator should be initialized with a base navigation view controller. - (instancetype)initWithBaseNavigationController: (UINavigationController*)navigationController
diff --git a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.mm b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.mm index 67e1dc11..7596ef5 100644 --- a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.mm +++ b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_import_coordinator.mm
@@ -110,6 +110,10 @@ #pragma mark - Accessors +- (SafariDataImportStage)importStage { + return _containerViewController.importStage; +} + - (SafariDataImportImportMediator*)mediator { if (!_mediator) { /// Use original profile as the user has explicitly requested this operation @@ -216,7 +220,7 @@ #pragma mark - PromoStyleViewControllerDelegate - (void)didTapPrimaryActionButton { - switch (_containerViewController.importStage) { + switch (self.importStage) { case SafariDataImportStage::kNotStarted: if ([self showFilePicker]) { [self transitionToNextImportStage]; @@ -244,18 +248,16 @@ #pragma mark - SafariDataImportImportStageTransitionHandler - (void)transitionToNextImportStage { - CHECK_NE(_containerViewController.importStage, - SafariDataImportStage::kImported) + CHECK_NE(self.importStage, SafariDataImportStage::kImported) << "No next import stage."; - int nextImportStageInt = - static_cast<int>(_containerViewController.importStage) + 1; + int nextImportStageInt = static_cast<int>(self.importStage) + 1; _containerViewController.email = self.mediator.email; _containerViewController.importStage = static_cast<SafariDataImportStage>(nextImportStageInt); } - (void)resetToInitialImportStage:(BOOL)userInitiated { - SafariDataImportStage currentStage = _containerViewController.importStage; + SafariDataImportStage currentStage = self.importStage; CHECK_EQ(currentStage, SafariDataImportStage::kFileLoading) << "Not supported for stage: " << static_cast<int>(currentStage); /// If the user has not explicitly canceled the import, alert the user that @@ -374,7 +376,7 @@ /// Dismisses Safari import workflow. - (void)dismissWorkflow { - RecordSafariDataImportEndsAtImportStage(_containerViewController.importStage); + RecordSafariDataImportEndsAtImportStage(self.importStage); [self.delegate safariDataImportCoordinatorWillDismissWorkflow:self]; }
diff --git a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_main_coordinator.mm b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_main_coordinator.mm index 4161012c..64e952b 100644 --- a/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_main_coordinator.mm +++ b/ios/chrome/browser/safari_data_import/coordinator/safari_data_import_main_coordinator.mm
@@ -97,9 +97,11 @@ #pragma mark - ConfirmationAlertActionHandler - (void)confirmationAlertPrimaryAction { + if (_exportCoordinator) { + return; + } RecordSafariImportActionOnEntryPoint( SafariDataImportEntryPointAction::kImport, _entryPoint); - CHECK(!_exportCoordinator); [_mediator notifyUsedOrDismissed]; _exportCoordinator = [[SafariDataImportExportCoordinator alloc] initWithBaseViewController:_viewController
diff --git a/ios/chrome/browser/safari_data_import/public/metrics.h b/ios/chrome/browser/safari_data_import/public/metrics.h index 4930397b..b451dbb6 100644 --- a/ios/chrome/browser/safari_data_import/public/metrics.h +++ b/ios/chrome/browser/safari_data_import/public/metrics.h
@@ -64,6 +64,10 @@ // successfully displayed. void RecordSafariDataImportFailure(bool alert_displayed); +// Records the current stage of import when the user taps the "back" button. +// Only applicable for users who reach the import screen. +void RecordSafariDataImportTapsBackAtImportStage(SafariDataImportStage stage); + // Records the current stage of import when the user exits the workflow. Only // applicable for users who reach the import screen. void RecordSafariDataImportEndsAtImportStage(SafariDataImportStage stage);
diff --git a/ios/chrome/browser/safari_data_import/public/metrics.mm b/ios/chrome/browser/safari_data_import/public/metrics.mm index 4acba77..83bd572 100644 --- a/ios/chrome/browser/safari_data_import/public/metrics.mm +++ b/ios/chrome/browser/safari_data_import/public/metrics.mm
@@ -34,6 +34,11 @@ action); } +void RecordSafariDataImportTapsBackAtImportStage(SafariDataImportStage stage) { + base::UmaHistogramEnumeration("IOS.SafariImport.Import.TapBackOnStage", + stage); +} + void RecordSafariDataImportEndsAtImportStage(SafariDataImportStage stage) { base::UmaHistogramEnumeration("IOS.SafariImport.Import.ExitOnStage", stage); }
diff --git a/ios/chrome/browser/web/model/blocked_popup_tab_helper.h b/ios/chrome/browser/web/model/blocked_popup_tab_helper.h index cc8a798..c1bdb66 100644 --- a/ios/chrome/browser/web/model/blocked_popup_tab_helper.h +++ b/ios/chrome/browser/web/model/blocked_popup_tab_helper.h
@@ -63,6 +63,9 @@ const web::Referrer referrer; }; + // Returns a copy of the currently blocked popups. + std::vector<Popup> GetBlockedPopups() const { return popups_; } + private: friend class web::LazyWebStateUserData<BlockedPopupTabHelper>;
diff --git a/ios_internal b/ios_internal index deec601..f34aa19 160000 --- a/ios_internal +++ b/ios_internal
@@ -1 +1 @@ -Subproject commit deec601008dc93b675f5a8d94df26732d38a3d59 +Subproject commit f34aa19784ed9d36ae10f877a4347e2e23aab6cb
diff --git a/media/audio/BUILD.gn b/media/audio/BUILD.gn index cbda18b..9388ffac 100644 --- a/media/audio/BUILD.gn +++ b/media/audio/BUILD.gn
@@ -457,6 +457,7 @@ "power_observer_helper_unittest.cc", "reconfigurable_audio_bus_pool_unittest.cc", "simple_sources_unittest.cc", + "wav_audio_handler_unittest.cc", ] deps = [ @@ -511,7 +512,6 @@ sources += [ "flac_audio_handler_unittest.cc", "test_data.h", - "wav_audio_handler_unittest.cc", ] }
diff --git a/media/audio/wav_audio_handler.cc b/media/audio/wav_audio_handler.cc index 1d71c7f..d43e3f9 100644 --- a/media/audio/wav_audio_handler.cc +++ b/media/audio/wav_audio_handler.cc
@@ -5,7 +5,9 @@ #include "media/audio/wav_audio_handler.h" #include <algorithm> +#include <array> #include <cstring> +#include <optional> #include "base/check.h" #include "base/check_op.h" @@ -25,136 +27,175 @@ namespace media { namespace { -const uint8_t kChunkId[] = {'R', 'I', 'F', 'F'}; -const uint8_t kFormat[] = {'W', 'A', 'V', 'E'}; -const uint8_t kFmtSubchunkId[] = {'f', 'm', 't', ' '}; -const uint8_t kDataSubchunkId[] = {'d', 'a', 't', 'a'}; +constexpr auto kChunkId = std::to_array<uint8_t>({'R', 'I', 'F', 'F'}); +constexpr auto kFormat = std::to_array<uint8_t>({'W', 'A', 'V', 'E'}); +constexpr auto kFmtSubchunkId = std::to_array<uint8_t>({'f', 'm', 't', ' '}); +constexpr auto kDataSubchunkId = std::to_array<uint8_t>({'d', 'a', 't', 'a'}); // The size of a chunk header in wav file format. A chunk header consists of a // tag ('fmt ' or 'data') and 4 bytes of chunk length. -const size_t kChunkHeaderSize = 8; +constexpr size_t kChunkHeaderSize = 8; // The minimum size of 'fmt' chunk. -const size_t kFmtChunkMinimumSize = 16; -const size_t kFmtChunkExtensibleMinimumSize = 40; +constexpr size_t kFmtChunkMinimumSize = 16; +constexpr size_t kFmtChunkExtensibleMinimumSize = 40; // The offsets of 'fmt' fields. -const size_t kAudioFormatOffset = 0; -const size_t kChannelOffset = 2; -const size_t kSampleRateOffset = 4; -const size_t kBitsPerSampleOffset = 14; -const size_t kValidBitsPerSampleOffset = 18; -const size_t kSubFormatOffset = 24; +constexpr size_t kAudioFormatOffset = 0; +constexpr size_t kChannelOffset = 2; +constexpr size_t kSampleRateOffset = 4; +constexpr size_t kBitsPerSampleOffset = 14; +constexpr size_t kValidBitsPerSampleOffset = 18; +constexpr size_t kSubFormatOffset = 24; -// A convenience struct for passing WAV parameters around. AudioParameters is +// A convenience class for passing WAV parameters around. AudioParameters is // too heavyweight for this. Keep this class internal to this implementation. -struct WavAudioParameters { - // TODO(crbug.com/340824112): note that zero-initializing this field does not - // correspond to any enumerator value defined in the `AudioFormat` enum. - // However, not initializing is also problematic: `ParseFmtChunk()` simply - // early-returns on failure, leaving random fields uninitialized and causing - // MSan errors elsewhere. A better long-term solution would be for - // `ParseFmtChunk` to return a `std::optional<WavAudioParameters>`. For now, - // zero-initializing this field has a (small) benefit that it won't - // correspond to any valid format and is guaranteed to fail the - // `ParamsAreValid()` check. - WavAudioHandler::AudioFormat audio_format = {}; - uint16_t num_channels = 0; - uint32_t sample_rate = 0; - uint16_t bits_per_sample = 0; - uint16_t valid_bits_per_sample = 0; - bool is_extensible = false; +class WavAudioParameters { + public: + WavAudioParameters() = default; + + WavAudioParameters(WavAudioHandler::AudioFormat audio_format, + uint16_t num_channels, + uint32_t sample_rate, + uint16_t bits_per_sample, + uint16_t valid_bits_per_sample = 0, + bool is_extensible = false) + : audio_format_(audio_format), + num_channels_(num_channels), + sample_rate_(sample_rate), + bits_per_sample_(bits_per_sample), + valid_bits_per_sample_(valid_bits_per_sample), + is_extensible_(is_extensible) {} + + WavAudioHandler::AudioFormat audio_format() const { return audio_format_; } + uint16_t num_channels() const { return num_channels_; } + uint32_t sample_rate() const { return sample_rate_; } + uint16_t bits_per_sample() const { return bits_per_sample_; } + uint16_t valid_bits_per_sample() const { return valid_bits_per_sample_; } + bool is_extensible() const { return is_extensible_; } + + bool IsValid() const { + return + // Check number of channels + num_channels_ != 0u && + num_channels_ <= static_cast<uint16_t>(limits::kMaxChannels) && + // Check sample rate + sample_rate_ != 0u && + ( + // Check bits per second for PCM data + (audio_format_ == WavAudioHandler::AudioFormat::kAudioFormatPCM && + (bits_per_sample_ == 8u || bits_per_sample_ == 16u || + bits_per_sample_ == 32u)) || + // Check bits per second for float data + (audio_format_ == WavAudioHandler::AudioFormat::kAudioFormatFloat && + (bits_per_sample_ == 32u || bits_per_sample_ == 64u))) && + // Check extensible format bps + (!is_extensible_ || valid_bits_per_sample_ == bits_per_sample_); + } + + private: + WavAudioHandler::AudioFormat audio_format_ = + WavAudioHandler::AudioFormat::kAudioFormatPCM; + uint16_t num_channels_ = 0; + uint32_t sample_rate_ = 0; + uint16_t bits_per_sample_ = 0; + uint16_t valid_bits_per_sample_ = 0; + bool is_extensible_ = false; }; -bool ParamsAreValid(const WavAudioParameters& params) { - return ( - // Check number of channels - params.num_channels != 0u && - params.num_channels <= static_cast<uint16_t>(limits::kMaxChannels) && - // Check sample rate - params.sample_rate != 0u && - ( - // Check bits per second for PCM data - (params.audio_format == - WavAudioHandler::AudioFormat::kAudioFormatPCM && - (params.bits_per_sample == 8u || params.bits_per_sample == 16u || - params.bits_per_sample == 32u)) || - // Check bits per second for float data - (params.audio_format == - WavAudioHandler::AudioFormat::kAudioFormatFloat && - (params.bits_per_sample == 32u || params.bits_per_sample == 64u))) && - // Check extensible format bps - (!params.is_extensible || - params.valid_bits_per_sample == params.bits_per_sample)); -} +// Result struct containing both audio data and parameters from ParseWavData. +struct ParseWavResult { + base::raw_span<const uint8_t> audio_data; + WavAudioParameters params; +}; // Parse a "fmt " chunk from wav data into its parameters. The `data` is in // little endian encoding. -bool ParseFmtChunk(base::span<const uint8_t> data, WavAudioParameters& params) { - // If the chunk is too small, return false. +std::optional<WavAudioParameters> ParseFmtChunk( + base::span<const uint8_t> data) { + // If the chunk is too small, return nullopt. if (data.size() < kFmtChunkMinimumSize) { - LOG(ERROR) << "Data size " << data.size() << " is too short."; - return false; + DVLOG(1) << "Data size " << data.size() << " is too short."; + return std::nullopt; } // Read in serialized parameters. - params.audio_format = + WavAudioHandler::AudioFormat audio_format = static_cast<WavAudioHandler::AudioFormat>(base::U16FromLittleEndian( data.subspan<kAudioFormatOffset, sizeof(WavAudioHandler::AudioFormat)>())); - params.num_channels = + uint16_t num_channels = base::U16FromLittleEndian(data.subspan<kChannelOffset, 2u>()); - params.sample_rate = + uint32_t sample_rate = base::U32FromLittleEndian(data.subspan<kSampleRateOffset, 4u>()); - params.bits_per_sample = + uint16_t bits_per_sample = base::U16FromLittleEndian(data.subspan<kBitsPerSampleOffset, 2u>()); - if (params.audio_format == - WavAudioHandler::AudioFormat::kAudioFormatExtensible) { + WavAudioParameters params; + + if (audio_format == WavAudioHandler::AudioFormat::kAudioFormatExtensible) { if (data.size() < kFmtChunkExtensibleMinimumSize) { - LOG(ERROR) << "Data size " << data.size() << " is too short."; - return false; + DVLOG(1) << "Data size " << data.size() << " is too short."; + return std::nullopt; } - params.is_extensible = true; - params.audio_format = + WavAudioHandler::AudioFormat actual_format = static_cast<WavAudioHandler::AudioFormat>(base::U16FromLittleEndian( data.subspan<kSubFormatOffset, sizeof(WavAudioHandler::AudioFormat)>())); - params.valid_bits_per_sample = base::U16FromLittleEndian( + uint16_t valid_bits_per_sample = base::U16FromLittleEndian( data.subspan<kValidBitsPerSampleOffset, 2u>()); + + params = WavAudioParameters(actual_format, num_channels, sample_rate, + bits_per_sample, valid_bits_per_sample, true); } else { - params.is_extensible = false; + params = WavAudioParameters(audio_format, num_channels, sample_rate, + bits_per_sample); } - return true; + + // Validate the parameters before returning to ensure we only return + // completely valid WavAudioParameters, never partially-valid results. + if (!params.IsValid()) { + DVLOG(1) << "Format chunk contains invalid parameters. " + << "num_channels: " << params.num_channels() << " " + << "sample_rate: " << params.sample_rate() << " " + << "bits_per_sample: " << params.bits_per_sample() << " " + << "valid_bits_per_sample: " << params.valid_bits_per_sample() + << " " + << "is_extensible: " << params.is_extensible(); + return std::nullopt; + } + + return params; } -// The `wav_data` is encoded in little endian, as will be `audio_data_out`. -bool ParseWavData(base::span<const uint8_t> wav_data, - base::span<const uint8_t>& audio_data_out, - WavAudioParameters& params_out) { +// The `wav_data` is encoded in little endian, as will be the returned audio +// data. +std::optional<ParseWavResult> ParseWavData(base::span<const uint8_t> wav_data) { // The header should look like: |R|I|F|F|1|2|3|4|W|A|V|E| auto buf = base::SpanReader(wav_data); // Read the chunk ID and compare to "RIFF". std::optional<base::span<const uint8_t, 4u>> chunk_id = buf.Read<4u>(); if (chunk_id != kChunkId) { - DLOG(ERROR) << "missing or incorrect chunk ID in wav header"; - return false; + DVLOG(1) << "missing or incorrect chunk ID in wav header"; + return std::nullopt; } // The RIFF chunk length comes next, but we don't actually care what it says. if (!buf.Skip(sizeof(uint32_t))) { - DLOG(ERROR) << "missing length in wav header"; - return false; + DVLOG(1) << "missing length in wav header"; + return std::nullopt; } // Read format and compare to "WAVE". std::optional<base::span<const uint8_t, 4u>> format = buf.Read<4u>(); if (format != kFormat) { - DLOG(ERROR) << "missing or incorrect format ID in wav header"; - return false; + DVLOG(1) << "missing or incorrect format ID in wav header"; + return std::nullopt; } + ParseWavResult result; bool got_format = false; + // If the number of remaining bytes is smaller than |kChunkHeaderSize|, it's // just junk at the end. while (buf.remaining() >= kChunkHeaderSize) { @@ -172,31 +213,26 @@ // chunk. Skip it otherwise. if (chunk_fmt == kFmtSubchunkId) { got_format = true; - if (!ParseFmtChunk(chunk_payload, params_out)) - return false; + std::optional<WavAudioParameters> params = ParseFmtChunk(chunk_payload); + if (!params) { + return std::nullopt; + } + result.params = std::move(*params); } else if (chunk_fmt == kDataSubchunkId) { - audio_data_out = chunk_payload; + result.audio_data = chunk_payload; } else { DVLOG(1) << "Skipping unknown data chunk: " << base::as_string_view(chunk_fmt) << "."; } } - // Check that data format has been read in and is valid. + // Check that data format has been read in. if (!got_format) { - LOG(ERROR) << "Invalid: No \"" << kFmtSubchunkId << "\" header found!"; - return false; - } else if (!ParamsAreValid(params_out)) { - LOG(ERROR) << "Format is invalid. " - << "num_channels: " << params_out.num_channels << " " - << "sample_rate: " << params_out.sample_rate << " " - << "bits_per_sample: " << params_out.bits_per_sample << " " - << "valid_bits_per_sample: " << params_out.valid_bits_per_sample - << " " - << "is_extensible: " << params_out.is_extensible; - return false; + DVLOG(1) << "Invalid: No \"" << base::as_string_view(kFmtSubchunkId) + << "\" header found!"; + return std::nullopt; } - return true; + return result; } } // namespace @@ -221,17 +257,16 @@ // static std::unique_ptr<WavAudioHandler> WavAudioHandler::Create( base::span<const uint8_t> wav_data) { - WavAudioParameters params; - base::span<const uint8_t> audio_data; - // Attempt to parse the WAV data. - if (!ParseWavData(wav_data, audio_data, params)) { + std::optional<ParseWavResult> result = ParseWavData(wav_data); + if (!result) { return nullptr; } - return base::WrapUnique( - new WavAudioHandler(audio_data, params.num_channels, params.sample_rate, - params.bits_per_sample, params.audio_format)); + return base::WrapUnique(new WavAudioHandler( + result->audio_data, result->params.num_channels(), + result->params.sample_rate(), result->params.bits_per_sample(), + result->params.audio_format())); } bool WavAudioHandler::Initialize() { @@ -256,6 +291,7 @@ if (AtEnd()) { bus->Zero(); + *frames_written = 0; return true; } const int bytes_per_frame = num_channels_ * bits_per_sample_ / 8;
diff --git a/media/audio/wav_audio_handler_fuzzer.cc b/media/audio/wav_audio_handler_fuzzer.cc index 4ae7f805..4db4120 100644 --- a/media/audio/wav_audio_handler_fuzzer.cc +++ b/media/audio/wav_audio_handler_fuzzer.cc
@@ -8,7 +8,6 @@ #include <stdint.h> #include <memory> -#include <string_view> #include "base/containers/span.h" #include "base/logging.h" @@ -18,11 +17,10 @@ Environment() { logging::SetMinLogLevel(logging::LOGGING_FATAL); } }; -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(base::span<const uint8_t> data_span) { static Environment env; - std::string_view wav_data(reinterpret_cast<const char*>(data), size); std::unique_ptr<media::WavAudioHandler> handler = - media::WavAudioHandler::Create(base::as_byte_span(wav_data)); + media::WavAudioHandler::Create(data_span); // Abort early to avoid crashing inside AudioBus's ValidateConfig() function. if (!handler || !handler->Initialize() ||
diff --git a/media/audio/wav_audio_handler_unittest.cc b/media/audio/wav_audio_handler_unittest.cc index 40e8e3a..520679e 100644 --- a/media/audio/wav_audio_handler_unittest.cc +++ b/media/audio/wav_audio_handler_unittest.cc
@@ -6,6 +6,7 @@ #include <stddef.h> +#include <array> #include <memory> #include <string> #include <string_view> @@ -18,19 +19,19 @@ namespace media { namespace { // WAV header comes first in the test data. -const size_t kWavHeaderSize = 12; -const size_t kWavDataSizeIndex = 4; +constexpr size_t kWavHeaderSize = 12; +constexpr size_t kWavDataSizeIndex = 4; // "fmt " header comes next. -const size_t kFormatHeaderIndex = kWavHeaderSize; -const size_t kFormatHeaderSize = 8; -const size_t kFormatPayloadSize = 16; -const size_t kChannelIndex = kWavHeaderSize + kFormatHeaderSize + 2; -const size_t kBitsPerSampleIndex = kWavHeaderSize + kFormatHeaderSize + 14; -const size_t kSampleRateIndex = kWavHeaderSize + kFormatHeaderSize + 4; +constexpr size_t kFormatHeaderIndex = kWavHeaderSize; +constexpr size_t kFormatHeaderSize = 8; +constexpr size_t kFormatPayloadSize = 16; +constexpr size_t kChannelIndex = kWavHeaderSize + kFormatHeaderSize + 2; +constexpr size_t kBitsPerSampleIndex = kWavHeaderSize + kFormatHeaderSize + 14; +constexpr size_t kSampleRateIndex = kWavHeaderSize + kFormatHeaderSize + 4; // "data" header comes last. -const size_t kDataHeaderIndex = +constexpr size_t kDataHeaderIndex = kWavHeaderSize + kFormatHeaderSize + kFormatPayloadSize; } // namespace @@ -201,24 +202,6 @@ EXPECT_FALSE(handler); } -TEST(WavAudioHandlerTest, TestOtherSectionTypesIsOkay) { - // Append some other subsection header "abcd", the class should just consume - // and keep going. - std::string data(kTestAudioData, kTestAudioDataSize); - data.append("abcd\x04\x00\x00\x00\x01\x02\x03\x04"); - data[kWavDataSizeIndex] += 12; // This should not overflow. - - auto handler = WavAudioHandler::Create(base::as_byte_span(data)); - EXPECT_TRUE(handler); - EXPECT_TRUE(handler->Initialize()); - ASSERT_EQ(2, handler->GetNumChannels()); - ASSERT_EQ(16, handler->bits_per_sample_for_testing()); - ASSERT_EQ(48000, handler->GetSampleRate()); - ASSERT_EQ(1, handler->total_frames_for_testing()); - ASSERT_EQ(20u, handler->GetDuration().InMicroseconds()); - ASSERT_EQ(4u, handler->data().size()); -} - TEST(WavAudioHandlerTest, TestNoFmtSectionIsNotValid) { // Write over the "fmt " header. No valid handler should be returned. std::string data(kTestAudioData, kTestAudioDataSize); @@ -250,4 +233,470 @@ ASSERT_EQ(0u, handler->data().size()); } +// Test extensible format with insufficient data size. +TEST(WavAudioHandlerTest, ExtensibleFormatTooShort) { + // clang-format off + constexpr auto kInvalidExtensibleWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x1C, 0x00, 0x00, 0x00, // chunk size (28 bytes = 8 + 20 for fmt chunk only). + 'W', 'A', 'V', 'E', + // fmt chunk with extensible format but insufficient size. + 'f', 'm', 't', ' ', + 0x14, 0x00, 0x00, 0x00, // chunk size (20 bytes, less than required 40). + 0xFE, 0xFF, // WAVE_FORMAT_EXTENSIBLE. + 0x02, 0x00, // 2 channels. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x10, 0xB1, 0x02, 0x00, // byte rate (44100 * 2 * 2 = 176400). + 0x04, 0x00, // block align (2 channels * 2 bytes). + 0x10, 0x00, // 16 bits per sample. + 0x10, 0x00, // valid bits per sample. + 0x00, 0x00, 0x00, 0x00, // channel mask. + // Missing subformat GUID (should be 16 more bytes for extensible format). + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kInvalidExtensibleWav)); + EXPECT_FALSE(handler); +} + +// Test invalid parameters validation. +TEST(WavAudioHandlerTest, InvalidParametersValidation) { + // Test unsupported PCM bit depth. + // clang-format off + constexpr auto kUnsupportedPcmBitsWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x28, 0x00, 0x00, 0x00, // chunk size (40 bytes = 8 + 16 + 8 + 8). + 'W', 'A', 'V', 'E', + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x01, 0x00, // PCM format. + 0x02, 0x00, // 2 channels. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x38, 0x09, 0x04, 0x00, // byte rate (44100 * 2 * 3 = 264600). + 0x06, 0x00, // block align (2 channels * 3 bytes). + 0x18, 0x00, // 24 bits per sample (not supported for PCM). + // data chunk. + 'd', 'a', 't', 'a', + 0x08, 0x00, 0x00, 0x00, // data size (8 bytes). + 0x00, 0x00, 0x00, 0x00, // sample data (padding to match 24-bit format). + 0x00, 0x00, 0x00, 0x00 + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kUnsupportedPcmBitsWav)); + EXPECT_FALSE(handler); + + // Test unsupported float bit depth. + // clang-format off + constexpr auto kUnsupportedFloatBitsWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x28, 0x00, 0x00, 0x00, // chunk size (40 bytes = 8 + 16 + 8 + 8). + 'W', 'A', 'V', 'E', + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x03, 0x00, // IEEE float format. + 0x02, 0x00, // 2 channels. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x38, 0x09, 0x04, 0x00, // byte rate (44100 * 2 * 3 = 264600). + 0x06, 0x00, // block align (2 channels * 3 bytes). + 0x18, 0x00, // 24 bits per sample (not supported for float). + // data chunk. + 'd', 'a', 't', 'a', + 0x08, 0x00, 0x00, 0x00, // data size (8 bytes). + 0x00, 0x00, 0x00, 0x00, // sample data (padding to match 24-bit format). + 0x00, 0x00, 0x00, 0x00 + }); + // clang-format on + + auto handler2 = WavAudioHandler::Create(base::span(kUnsupportedFloatBitsWav)); + EXPECT_FALSE(handler2); +} + +// Test invalid RIFF chunk ID. +TEST(WavAudioHandlerTest, InvalidRiffChunkId) { + // clang-format off + constexpr auto kInvalidRiffWav = std::to_array<uint8_t>({ + // Invalid RIFF header. + 'X', 'I', 'F', 'F', // Wrong chunk ID (should be "RIFF"). + 0x24, 0x00, 0x00, 0x00, // chunk size (36 bytes = 8 + 16 + 8 + 4). + 'W', 'A', 'V', 'E', // format. + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x01, 0x00, // PCM format. + 0x02, 0x00, // 2 channels. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x10, 0xB1, 0x02, 0x00, // byte rate (44100 * 2 * 2 = 176400). + 0x04, 0x00, // block align (2 channels * 2 bytes). + 0x10, 0x00, // 16 bits per sample. + // data chunk. + 'd', 'a', 't', 'a', + 0x04, 0x00, 0x00, 0x00, // data size (4 bytes). + 0x00, 0x00, 0x00, 0x00 // sample data. + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kInvalidRiffWav)); + EXPECT_FALSE(handler); +} + +// Test missing length field. +TEST(WavAudioHandlerTest, MissingLengthField) { + // clang-format off + constexpr auto kTruncatedWav = std::to_array<uint8_t>({ + // RIFF header without length. + 'R', 'I', 'F', 'F' + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kTruncatedWav)); + EXPECT_FALSE(handler); +} + +// Test invalid format ID. +TEST(WavAudioHandlerTest, InvalidFormatId) { + // clang-format off + constexpr auto kInvalidFormatWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x24, 0x00, 0x00, 0x00, // chunk size (36 bytes = 8 + 16 + 8 + 4). + 'X', 'A', 'V', 'E', // Wrong format ID (should be "WAVE"). + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x01, 0x00, // PCM format. + 0x02, 0x00, // 2 channels. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x10, 0xB1, 0x02, 0x00, // byte rate (44100 * 2 * 2 = 176400). + 0x04, 0x00, // block align (2 channels * 2 bytes). + 0x10, 0x00, // 16 bits per sample. + // data chunk. + 'd', 'a', 't', 'a', + 0x04, 0x00, 0x00, 0x00, // data size (4 bytes). + 0x00, 0x00, 0x00, 0x00 // sample data. + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kInvalidFormatWav)); + EXPECT_FALSE(handler); +} + +// Test missing format chunk. +TEST(WavAudioHandlerTest, MissingFormatChunk) { + // clang-format off + constexpr auto kNoFormatWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x0C, 0x00, 0x00, 0x00, // chunk size (12 bytes = 8 + 4 for data chunk). + 'W', 'A', 'V', 'E', + // Only data chunk, no fmt chunk. + 'd', 'a', 't', 'a', + 0x04, 0x00, 0x00, 0x00, // data size (4 bytes). + 0x00, 0x00, 0x00, 0x00 // sample data. + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kNoFormatWav)); + EXPECT_FALSE(handler); +} + +// Test accessor methods and basic functionality. +TEST(WavAudioHandlerTest, AccessorMethodsAndBasicFunctionality) { + // clang-format off + constexpr auto kValidWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x24, 0x00, 0x00, 0x00, // chunk size (36 bytes = 8 + 16 + 8 + 8). + 'W', 'A', 'V', 'E', + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x01, 0x00, // PCM format. + 0x02, 0x00, // 2 channels. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x10, 0xB1, 0x02, 0x00, // byte rate (44100 * 2 * 2 = 176400). + 0x04, 0x00, // block align (2 channels * 2 bytes). + 0x10, 0x00, // 16 bits per sample. + // data chunk. + 'd', 'a', 't', 'a', + 0x08, 0x00, 0x00, 0x00, // data size (8 bytes). + 0x00, 0x00, 0x01, 0x00, // sample data (2 frames * 2 channels * 2 bytes). + 0x00, 0x00, 0x01, 0x00 + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kValidWav)); + ASSERT_TRUE(handler); + + // Test accessor methods. + EXPECT_EQ(2, handler->GetNumChannels()); + EXPECT_EQ(44100, handler->GetSampleRate()); + + // Test GetDuration. + EXPECT_GT(handler->GetDuration().InMicroseconds(), 0); + + // Test CopyTo functionality. + auto bus = AudioBus::Create(2, 2); + size_t frames_written = 0; + EXPECT_TRUE(handler->CopyTo(bus.get(), &frames_written)); + EXPECT_EQ(2u, frames_written); + + // Test Reset functionality. + handler->Reset(); + EXPECT_FALSE(handler->AtEnd()); +} + +// Test 64-bit float format support. +TEST(WavAudioHandlerTest, Float64FormatSupport) { + // clang-format off + // Use WAVE_FORMAT_EXTENSIBLE with padding chunk to ensure data is 8-byte aligned. + // Structure: 12 (RIFF) + 48 (fmt) + 12 (pad with 4 bytes data) + 8 (data header) = 80 + // Data starts at offset 80, which is 8-byte aligned (80 % 8 == 0). + alignas(8) constexpr auto kFloat64Wav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x68, 0x00, 0x00, 0x00, // chunk size (104 bytes = 4 + 48 + 12 + 8 + 32). + 'W', 'A', 'V', 'E', + // fmt chunk with WAVE_FORMAT_EXTENSIBLE (40 bytes data). + 'f', 'm', 't', ' ', + 0x28, 0x00, 0x00, 0x00, // chunk size (40 bytes for extensible format). + 0xFE, 0xFF, // WAVE_FORMAT_EXTENSIBLE. + 0x02, 0x00, // 2 channels. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x40, 0xC4, 0x0A, 0x00, // byte rate (44100 * 2 * 8 = 705600). + 0x10, 0x00, // block align (2 channels * 8 bytes). + 0x40, 0x00, // 64 bits per sample. + 0x16, 0x00, // extension size (22 bytes). + 0x40, 0x00, // valid bits per sample (64). + 0x03, 0x00, 0x00, 0x00, // channel mask (3 = front left | front right). + // Subformat GUID for IEEE float: 00000003-0000-0010-8000-00aa00389b71. + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, + // Padding chunk to align data section (12 bytes total: 4 ID + 4 size + 4 data). + 'P', 'A', 'D', ' ', + 0x04, 0x00, 0x00, 0x00, // chunk size (4 bytes). + 0x00, 0x00, 0x00, 0x00, // padding data (4 bytes). + // data chunk (now starts at offset 72, and data at 80, which is 8-byte aligned). + 'd', 'a', 't', 'a', + 0x20, 0x00, 0x00, 0x00, // data size (32 bytes = 2 frames * 2 channels * 8 bytes). + // Sample data: 2 frames of 64-bit float data (starts at offset 80). + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // frame 1, channel 1 (0.0). + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // frame 1, channel 2 (0.0). + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // frame 2, channel 1 (0.0). + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // frame 2, channel 2 (0.0). + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kFloat64Wav)); + ASSERT_TRUE(handler); + EXPECT_EQ(64, handler->bits_per_sample_for_testing()); + + auto bus = AudioBus::Create(2, 2); + size_t frames_written = 0; + EXPECT_TRUE(handler->CopyTo(bus.get(), &frames_written)); + EXPECT_EQ(2u, frames_written); +} + +// Test 8-bit and 32-bit PCM format support. +TEST(WavAudioHandlerTest, PcmFormatVariations) { + // Test 8-bit PCM. + // clang-format off + alignas(8) constexpr auto k8BitPcmWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x24, 0x00, 0x00, 0x00, // chunk size (36 bytes = 8 + 16 + 8 + 4). + 'W', 'A', 'V', 'E', + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x01, 0x00, // PCM format. + 0x01, 0x00, // 1 channel. + 0x40, 0x1F, 0x00, 0x00, // 8000 Hz sample rate. + 0x40, 0x1F, 0x00, 0x00, // byte rate (8000 * 1 * 1 = 8000). + 0x01, 0x00, // block align (1 channel * 1 byte). + 0x08, 0x00, // 8 bits per sample. + // data chunk. + 'd', 'a', 't', 'a', + 0x04, 0x00, 0x00, 0x00, // data size (4 bytes). + 0x80, 0x90, 0xA0, 0xB0 // 8-bit samples (4 samples). + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(k8BitPcmWav)); + ASSERT_TRUE(handler); + EXPECT_EQ(8, handler->bits_per_sample_for_testing()); + + auto bus = AudioBus::Create(1, 4); + size_t frames_written = 0; + EXPECT_TRUE(handler->CopyTo(bus.get(), &frames_written)); + EXPECT_EQ(4u, frames_written); + + // Test 32-bit PCM. + // clang-format off + // Use WAVE_FORMAT_EXTENSIBLE with padding chunk to ensure data is 8-byte aligned. + // Structure: 12 (RIFF) + 48 (fmt) + 12 (pad with 4 bytes data) + 8 (data header) = 80 + // Data starts at offset 80, which is 8-byte aligned (80 % 8 == 0). + alignas(8) constexpr auto k32BitPcmWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x50, 0x00, 0x00, 0x00, // chunk size (80 bytes = 4 + 48 + 12 + 8 + 8). + 'W', 'A', 'V', 'E', + // fmt chunk with WAVE_FORMAT_EXTENSIBLE (40 bytes data). + 'f', 'm', 't', ' ', + 0x28, 0x00, 0x00, 0x00, // chunk size (40 bytes for extensible format). + 0xFE, 0xFF, // WAVE_FORMAT_EXTENSIBLE. + 0x01, 0x00, // 1 channel. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x10, 0xB1, 0x02, 0x00, // byte rate (44100 * 1 * 4 = 176400). + 0x04, 0x00, // block align (1 channel * 4 bytes). + 0x20, 0x00, // 32 bits per sample. + 0x16, 0x00, // extension size (22 bytes). + 0x20, 0x00, // valid bits per sample (32). + 0x04, 0x00, 0x00, 0x00, // channel mask (4 = front center). + // Subformat GUID for PCM: 00000001-0000-0010-8000-00aa00389b71. + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, + // Padding chunk to align data section (12 bytes total: 4 ID + 4 size + 4 data). + 'P', 'A', 'D', ' ', + 0x04, 0x00, 0x00, 0x00, // chunk size (4 bytes). + 0x00, 0x00, 0x00, 0x00, // padding data (4 bytes). + // data chunk (now starts at offset 72, and data at 80, which is 8-byte aligned). + 'd', 'a', 't', 'a', + 0x08, 0x00, 0x00, 0x00, // data size (8 bytes). + // Sample data (starts at offset 80, which is 8-byte aligned). + 0x00, 0x00, 0x01, 0x00, // 32-bit sample 1 (little-endian: 65536). + 0x00, 0x00, 0x02, 0x00 // 32-bit sample 2 (little-endian: 131072). + }); + // clang-format on + + auto handler2 = WavAudioHandler::Create(base::span(k32BitPcmWav)); + ASSERT_TRUE(handler2); + EXPECT_EQ(32, handler2->bits_per_sample_for_testing()); + + auto bus2 = AudioBus::Create(1, 2); + size_t frames_written2 = 0; + EXPECT_TRUE(handler2->CopyTo(bus2.get(), &frames_written2)); + EXPECT_EQ(2u, frames_written2); +} + +// Test AtEnd() boundary condition and CopyTo at end of data. +TEST(WavAudioHandlerTest, AtEndBoundaryCondition) { + // clang-format off + constexpr auto kSmallWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x24, 0x00, 0x00, 0x00, // chunk size (36 bytes = 4 + 24 + 8). + 'W', 'A', 'V', 'E', + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x01, 0x00, // PCM format. + 0x01, 0x00, // 1 channel. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0xAC, 0x44, 0x00, 0x00, // byte rate (44100 * 1 * 1 = 44100). + 0x01, 0x00, // block align (1 channel * 1 byte). + 0x08, 0x00, // 8 bits per sample. + // data chunk with zero length. + 'd', 'a', 't', 'a', + 0x00, 0x00, 0x00, 0x00 // data size (0 bytes). + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kSmallWav)); + ASSERT_TRUE(handler); + + // Initially should not be at end since we haven't read any data. + EXPECT_TRUE(handler->AtEnd()); + + auto bus = AudioBus::Create(1, 4); + auto channel_data = bus->channel_span(0); + for (int i = 0; i < bus->frames(); ++i) { + channel_data[i] = 1.0f; + } + + size_t frames_written = 0; + EXPECT_TRUE(handler->CopyTo(bus.get(), &frames_written)); + EXPECT_EQ(0u, frames_written); + + // Verify bus was zeroed. + for (int i = 0; i < bus->frames(); ++i) { + EXPECT_EQ(0.0f, channel_data[i]); + } +} + +// Test skipping unknown chunks to cover DVLOG path. +TEST(WavAudioHandlerTest, SkipUnknownChunks) { + // clang-format off + constexpr auto kWavWithUnknownChunk = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x34, 0x00, 0x00, 0x00, // chunk size (52 bytes = 4 + 24 + 12 + 12). + 'W', 'A', 'V', 'E', + // fmt chunk. + 'f', 'm', 't', ' ', + 0x10, 0x00, 0x00, 0x00, // chunk size (16 bytes). + 0x01, 0x00, // PCM format. + 0x01, 0x00, // 1 channel. + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0xAC, 0x44, 0x00, 0x00, // byte rate (44100 * 1 * 1 = 44100). + 0x01, 0x00, // block align (1 channel * 1 byte). + 0x08, 0x00, // 8 bits per sample. + // Unknown chunk "LIST". + 'L', 'I', 'S', 'T', + 0x04, 0x00, 0x00, 0x00, // chunk size (4 bytes). + 0x00, 0x00, 0x00, 0x00, // dummy data. + // data chunk. + 'd', 'a', 't', 'a', + 0x04, 0x00, 0x00, 0x00, // data size (4 bytes). + 0x80, 0x90, 0xA0, 0xB0 // sample data. + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kWavWithUnknownChunk)); + ASSERT_TRUE(handler); + EXPECT_EQ(1, handler->GetNumChannels()); + EXPECT_EQ(8, handler->bits_per_sample_for_testing()); + EXPECT_EQ(4u, handler->data().size()); +} + +// Test to specifically trigger the DVLOG path that calls +// valid_bits_per_sample() and is_extensible() accessor methods. +TEST(WavAudioHandlerTest, TriggerAccessorMethodsInDVLOG) { + // clang-format off + constexpr auto kInvalidExtensibleWav = std::to_array<uint8_t>({ + // RIFF header. + 'R', 'I', 'F', 'F', + 0x40, 0x00, 0x00, 0x00, // chunk size (64 bytes = 4 + 48 + 12). + 'W', 'A', 'V', 'E', + // fmt chunk - extensible format. + 'f', 'm', 't', ' ', + 0x28, 0x00, 0x00, 0x00, // chunk size (40 bytes for extensible). + 0xFE, 0xFF, // WAVE_FORMAT_EXTENSIBLE. + 0x00, 0x00, // 0 channels (invalid - will trigger DVLOG). + 0x44, 0xAC, 0x00, 0x00, // 44100 Hz sample rate. + 0x00, 0x00, 0x00, 0x00, // byte rate (0 due to invalid channels). + 0x00, 0x00, // block align (0 due to invalid channels). + 0x10, 0x00, // 16 bits per sample. + 0x16, 0x00, // extension size (22 bytes). + 0x10, 0x00, // valid bits per sample. + 0x04, 0x00, 0x00, 0x00, // channel mask. + // Subformat GUID for PCM. + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71, + // data chunk. + 'd', 'a', 't', 'a', + 0x04, 0x00, 0x00, 0x00, // data size (4 bytes). + 0x00, 0x00, 0x00, 0x00 // sample data. + }); + // clang-format on + + auto handler = WavAudioHandler::Create(base::span(kInvalidExtensibleWav)); + EXPECT_FALSE(handler); +} + } // namespace media
diff --git a/media/base/supported_types_unittest.cc b/media/base/supported_types_unittest.cc index 6dc84db..431cee8 100644 --- a/media/base/supported_types_unittest.cc +++ b/media/base/supported_types_unittest.cc
@@ -32,8 +32,9 @@ // Expect support for baseline configuration of known codecs. EXPECT_TRUE(IsDecoderSupportedVideoType( {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, kColorSpace})); - EXPECT_TRUE(IsDecoderSupportedVideoType( - {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, kColorSpace})); + EXPECT_EQ(IsDecoderSupportedVideoType({VideoCodec::kVP9, VP9PROFILE_PROFILE0, + kUnspecifiedLevel, kColorSpace}), + BUILDFLAG(ENABLE_LIBVPX)); EXPECT_FALSE(IsDecoderSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, kColorSpace})); @@ -69,6 +70,7 @@ #endif } +#if defined(ENABLE_LIBVPX) TEST(SupportedTypesTest, IsDecoderSupportedVideoType_VP9TransferFunctions) { size_t num_found = 0; // TODO(hubbe): Verify support for HDR codecs when color management enabled. @@ -190,6 +192,7 @@ {VideoCodec::kVP9, VP9PROFILE_PROFILE2, kUnspecifiedLevel, kColorSpace})); #endif } +#endif // defined(ENABLE_LIBVPX) TEST(SupportedTypesTest, IsDecoderSupportedAudioTypeWithSpatialRenderingBasics) { @@ -284,8 +287,10 @@ // Expect support for baseline configuration of known codecs. EXPECT_TRUE(IsDecoderSupportedVideoType( {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space})); +#if defined(ENABLE_LIBVPX) EXPECT_TRUE(IsDecoderSupportedVideoType( {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space})); +#endif EXPECT_FALSE(IsDecoderSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, color_space})); @@ -301,8 +306,10 @@ color_space.transfer = VideoColorSpace::TransferID::SMPTEST2084; EXPECT_TRUE(IsDecoderSupportedVideoType( {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space})); +#if defined(ENABLE_LIBVPX) EXPECT_TRUE(IsDecoderSupportedVideoType( {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space})); +#endif EXPECT_FALSE(IsDecoderSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, color_space})); @@ -314,8 +321,10 @@ color_space.transfer = VideoColorSpace::TransferID::ARIB_STD_B67; EXPECT_TRUE(IsDecoderSupportedVideoType( {VideoCodec::kVP8, VP8PROFILE_ANY, kUnspecifiedLevel, color_space})); +#if defined(ENABLE_LIBVPX) EXPECT_TRUE(IsDecoderSupportedVideoType( {VideoCodec::kVP9, VP9PROFILE_PROFILE0, kUnspecifiedLevel, color_space})); +#endif EXPECT_FALSE(IsDecoderSupportedVideoType({VideoCodec::kTheora, VIDEO_CODEC_PROFILE_UNKNOWN, kUnspecifiedLevel, color_space}));
diff --git a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc index 73eb1fe..e0050297 100644 --- a/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc +++ b/media/cdm/library_cdm/clear_key_cdm/cdm_video_decoder.cc
@@ -31,6 +31,8 @@ #include "media/base/decoder_status.h" #include "media/base/media_switches.h" #include "media/base/media_util.h" +#include "media/base/video_decoder.h" +#include "media/base/video_frame.h" #include "media/cdm/cdm_type_conversion.h" #include "media/cdm/library_cdm/cdm_host_proxy.h" #include "media/media_buildflags.h"
diff --git a/media/fuchsia/video/fuchsia_video_decoder_unittest.cc b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc index 99a6274..5b078f00 100644 --- a/media/fuchsia/video/fuchsia_video_decoder_unittest.cc +++ b/media/fuchsia/video/fuchsia_video_decoder_unittest.cc
@@ -91,10 +91,6 @@ gpu::ContextSupport* ContextSupport() override { return &gpu_context_support_; } - class GrDirectContext* GrContext() override { - ADD_FAILURE(); - return nullptr; - } gpu::SharedImageInterface* SharedImageInterface() override { return shared_image_interface_.get(); }
diff --git a/media/gpu/test/video_encoder/video_encoder.h b/media/gpu/test/video_encoder/video_encoder.h index 2cdade0..52def0c6 100644 --- a/media/gpu/test/video_encoder/video_encoder.h +++ b/media/gpu/test/video_encoder/video_encoder.h
@@ -20,13 +20,13 @@ #include "base/synchronization/lock.h" #include "base/thread_annotations.h" #include "base/time/time.h" +#include "media/gpu/test/bitstream_helpers.h" namespace media { class VideoBitrateAllocation; namespace test { -class BitstreamProcessor; class RawVideo; class VideoEncoderClient; struct VideoEncoderClientConfig;
diff --git a/media/mojo/clients/mojo_gpu_video_accelerator_factories_unittest.cc b/media/mojo/clients/mojo_gpu_video_accelerator_factories_unittest.cc index 11d6a7d..a829529 100644 --- a/media/mojo/clients/mojo_gpu_video_accelerator_factories_unittest.cc +++ b/media/mojo/clients/mojo_gpu_video_accelerator_factories_unittest.cc
@@ -159,7 +159,6 @@ MOCK_METHOD(gpu::gles2::GLES2Interface*, ContextGL, (), (override)); MOCK_METHOD(gpu::raster::RasterInterface*, RasterInterface, (), (override)); MOCK_METHOD(gpu::ContextSupport*, ContextSupport, (), (override)); - MOCK_METHOD(class GrDirectContext*, GrContext, (), (override)); MOCK_METHOD(gpu::SharedImageInterface*, SharedImageInterface, (), (override)); MOCK_METHOD(viz::ContextCacheController*, CacheController, (), (override)); MOCK_METHOD(base::Lock*, GetLock, (), (override));
diff --git a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc index 575b5c8..2e03259 100644 --- a/mojo/public/cpp/bindings/tests/sync_method_unittest.cc +++ b/mojo/public/cpp/bindings/tests/sync_method_unittest.cc
@@ -1728,12 +1728,10 @@ class NoSyncImpl : public mojom::NoSync { public: - explicit NoSyncImpl(PendingReceiver<mojom::NoSync> receiver) - : receiver_(this, std::move(receiver)) {} + explicit NoSyncImpl(PendingReceiver<mojom::NoSync> receiver); explicit NoSyncImpl( - PendingAssociatedReceiver<mojom::NoSync> associated_receiver) - : associated_receiver_(this, std::move(associated_receiver)) {} + PendingAssociatedReceiver<mojom::NoSync> associated_receiver); // mojom::NoSync implementation: void Method(MethodCallback callback) override; @@ -1771,6 +1769,13 @@ std::unique_ptr<OneSyncImpl> associated_one_sync_; }; +NoSyncImpl::NoSyncImpl(PendingReceiver<mojom::NoSync> receiver) + : receiver_(this, std::move(receiver)) {} + +NoSyncImpl::NoSyncImpl( + PendingAssociatedReceiver<mojom::NoSync> associated_receiver) + : associated_receiver_(this, std::move(associated_receiver)) {} + void NoSyncImpl::Method(MethodCallback callback) { EXPECT_TRUE(false); std::move(callback).Run();
diff --git a/net/disk_cache/sql/cache_entry_key.cc b/net/disk_cache/sql/cache_entry_key.cc index def33777..398f3ff 100644 --- a/net/disk_cache/sql/cache_entry_key.cc +++ b/net/disk_cache/sql/cache_entry_key.cc
@@ -5,13 +5,13 @@ #include "net/disk_cache/sql/cache_entry_key.h" #include "base/check.h" -#include "net/disk_cache/simple/simple_util.h" +#include "base/hash/hash.h" namespace disk_cache { CacheEntryKey::CacheEntryKey(std::string str) : data_(base::MakeRefCounted<base::RefCountedString>(std::move(str))), - hash_(static_cast<int64_t>(simple_util::GetEntryHashKey(string()))) {} + hash_(static_cast<int32_t>(base::PersistentHash(string()))) {} CacheEntryKey::~CacheEntryKey() = default; @@ -25,7 +25,8 @@ } bool CacheEntryKey::operator==(const CacheEntryKey& other) const { - return data_ == other.data_ || string() == other.string(); + return data_ == other.data_ || + (hash() == other.hash() && string() == other.string()); } const std::string& CacheEntryKey::string() const {
diff --git a/net/disk_cache/sql/cache_entry_key.h b/net/disk_cache/sql/cache_entry_key.h index 35ad60a7..d895ea9 100644 --- a/net/disk_cache/sql/cache_entry_key.h +++ b/net/disk_cache/sql/cache_entry_key.h
@@ -37,7 +37,7 @@ // the main cache key string. class NET_EXPORT_PRIVATE CacheEntryKey { public: - using Hash = base::StrongAlias<class HashTag, int64_t>; + using Hash = base::StrongAlias<class HashTag, int32_t>; explicit CacheEntryKey(std::string str = ""); ~CacheEntryKey();
diff --git a/net/disk_cache/sql/sql_backend_constants.h b/net/disk_cache/sql/sql_backend_constants.h index 2644e4a0..e455e44 100644 --- a/net/disk_cache/sql/sql_backend_constants.h +++ b/net/disk_cache/sql/sql_backend_constants.h
@@ -58,21 +58,24 @@ // cleaned up. Instead of a delayed task, cleanup is now triggered // during browser idle periods. Also, the index on `res_id` for // doomed entries was removed as it's no longer needed. +// Version 6: https://crrev.com/c/7006231 changed the hash function for cache +// keys to base::PersistentHash, which uses a 32-bit hash. This is a +// breaking change as the previous version used a 64-bit hash. // ---------------------------------------------------------------------------- // The oldest database schema version that the current code can read. // A database with a version older than this will be razed as it's considered // obsolete and the code no longer supports migrating from it. -inline constexpr int kSqlBackendLowestSupportedDatabaseVersion = 5; +inline constexpr int kSqlBackendLowestSupportedDatabaseVersion = 6; // The current version of the database schema. This should be incremented for // any schema change. -inline constexpr int kSqlBackendCurrentDatabaseVersion = 5; +inline constexpr int kSqlBackendCurrentDatabaseVersion = 6; // The oldest application version that can use a database with the current // schema. If a schema change is not backward-compatible, this must be set to // the same value as `kSqlBackendCurrentDatabaseVersion`. -inline constexpr int kSqlBackendCompatibleDatabaseVersion = 5; +inline constexpr int kSqlBackendCompatibleDatabaseVersion = 6; // Estimated static size overhead for a resource entry in the database, // excluding the key and any blob data. This is a conservative estimate based on
diff --git a/net/disk_cache/sql/sql_persistent_store.cc b/net/disk_cache/sql/sql_persistent_store.cc index 44fb843b..b4979437 100644 --- a/net/disk_cache/sql/sql_persistent_store.cc +++ b/net/disk_cache/sql/sql_persistent_store.cc
@@ -666,7 +666,7 @@ Query::kGetCacheKeyHashes_SelectCacheKeyHashFromLiveResources))); while (statement.Step()) { const auto res_id = ResId(statement.ColumnInt64(0)); - const auto key_hash = CacheEntryKey::Hash(statement.ColumnInt64(1)); + const auto key_hash = CacheEntryKey::Hash(statement.ColumnInt(1)); const bool doomed = statement.ColumnBool(2); if (doomed) { doomed_entry_res_ids.emplace_back(res_id); @@ -796,7 +796,7 @@ sql::Statement statement(db_.GetCachedStatement( SQL_FROM_HERE, GetQuery(Query::kOpenEntry_SelectLiveResources))); - statement.BindInt64(0, key.hash().value()); + statement.BindInt(0, key.hash().value()); statement.BindString(1, key.string()); if (!statement.Step()) { // `Step()` returned false, which means either the query completed with no @@ -890,7 +890,7 @@ statement.BindTime(0, entry_info.last_used); statement.BindInt64(1, entry_info.body_end); statement.BindInt64(2, bytes_usage); - statement.BindInt64(3, key.hash().value()); + statement.BindInt(3, key.hash().value()); statement.BindString(4, key.string()); if (!statement.Step()) { return base::unexpected(Error::kFailedToExecute); @@ -1150,7 +1150,7 @@ { sql::Statement statement(db_.GetCachedStatement( SQL_FROM_HERE, GetQuery(Query::kDeleteLiveEntry_DeleteFromResources))); - statement.BindInt64(0, key.hash().value()); + statement.BindInt(0, key.hash().value()); statement.BindString(1, key.string()); while (statement.Step()) { const auto res_id = ResId(statement.ColumnInt64(0)); @@ -1394,7 +1394,7 @@ SQL_FROM_HERE, GetQuery(Query::kUpdateEntryLastUsedByKey_UpdateResourceLastUsed))); statement.BindTime(0, last_used); - statement.BindInt64(1, key.hash().value()); + statement.BindInt(1, key.hash().value()); statement.BindString(2, key.string()); if (!statement.Run()) { return Error::kFailedToExecute;
diff --git a/services/network/cookie_access_delegate_impl_unittest.cc b/services/network/cookie_access_delegate_impl_unittest.cc index b139f69..ccfc7c1 100644 --- a/services/network/cookie_access_delegate_impl_unittest.cc +++ b/services/network/cookie_access_delegate_impl_unittest.cc
@@ -55,7 +55,7 @@ base::BindOnce( [](net::FirstPartySetMetadata, net::FirstPartySetsCacheFilter::MatchInfo) { FAIL(); })), - Optional(std::make_pair(std::ref(expected_metadata), + Optional(std::make_pair(std::cref(expected_metadata), net::FirstPartySetsCacheFilter::MatchInfo()))); EXPECT_THAT(
diff --git a/services/network/shared_dictionary/shared_dictionary_manager.cc b/services/network/shared_dictionary/shared_dictionary_manager.cc index e7507ba..a8625c8 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager.cc +++ b/services/network/shared_dictionary/shared_dictionary_manager.cc
@@ -158,6 +158,8 @@ cached_storages_.Clear(); preloaded_dictionaries_set_.clear(); } + + HandleMemoryPressure(level); } size_t SharedDictionaryManager::GetStorageCountForTesting() {
diff --git a/services/network/shared_dictionary/shared_dictionary_manager.h b/services/network/shared_dictionary/shared_dictionary_manager.h index 5efc3ed..57f6c9634a 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager.h +++ b/services/network/shared_dictionary/shared_dictionary_manager.h
@@ -97,6 +97,8 @@ base::Time start_time, base::Time end_time, base::OnceCallback<void(const std::vector<url::Origin>&)> callback) = 0; + virtual void HandleMemoryPressure( + base::MemoryPressureLevel memory_pressure_level) = 0; net::SharedDictionaryGetter MaybeCreateSharedDictionaryGetter( int request_load_flags,
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_in_memory.h b/services/network/shared_dictionary/shared_dictionary_manager_in_memory.h index 88dbabf1..1de039b5 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager_in_memory.h +++ b/services/network/shared_dictionary/shared_dictionary_manager_in_memory.h
@@ -52,6 +52,8 @@ base::Time end_time, base::OnceCallback<void(const std::vector<url::Origin>&)> callback) override; + void HandleMemoryPressure( + base::MemoryPressureLevel memory_pressure_level) override {} void MaybeRunCacheEvictionPerSite(const net::SchemefulSite& top_frame_site); void MaybeRunCacheEviction();
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc index b0388af..1b90b7c 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc +++ b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.cc
@@ -493,12 +493,6 @@ base::CommandLine::ForCurrentProcess()->HasSwitch( switches::kDisableSharedDictionaryStorageCleanupForTesting)) { dictionary_cache_ = base::MakeRefCounted<SharedDictionaryCache>(); - memory_pressure_listener_registration_ = - std::make_unique<base::AsyncMemoryPressureListenerRegistration>( - FROM_HERE, - base::MemoryPressureListenerTag::kSharedDictionaryManagerOnDisk, - base::BindRepeating(&SharedDictionaryManagerOnDisk::OnMemoryPressure, - weak_factory_.GetWeakPtr())); disk_cache_.Initialize(cache_directory_path, #if BUILDFLAG(IS_ANDROID) app_status_listener_getter, @@ -593,6 +587,13 @@ std::move(callback))); } +void SharedDictionaryManagerOnDisk::HandleMemoryPressure( + base::MemoryPressureLevel level) { + if (level != base::MEMORY_PRESSURE_LEVEL_NONE) { + dictionary_cache_->Clear(); + } +} + scoped_refptr<SharedDictionaryWriter> SharedDictionaryManagerOnDisk::CreateWriter( const net::SharedDictionaryIsolationKey& isolation_key, @@ -833,11 +834,4 @@ weak_factory_.GetWeakPtr()))); } -void SharedDictionaryManagerOnDisk::OnMemoryPressure( - base::MemoryPressureLevel level) { - if (level != base::MEMORY_PRESSURE_LEVEL_NONE) { - dictionary_cache_->Clear(); - } -} - } // namespace network
diff --git a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h index 1b71861b5..cb92d2d 100644 --- a/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h +++ b/services/network/shared_dictionary/shared_dictionary_manager_on_disk.h
@@ -83,6 +83,8 @@ base::Time end_time, base::OnceCallback<void(const std::vector<url::Origin>&)> callback) override; + void HandleMemoryPressure( + base::MemoryPressureLevel memory_pressure_level) override; SharedDictionaryDiskCache& disk_cache() { return disk_cache_; } net::SQLitePersistentSharedDictionaryStore& metadata_store() { @@ -174,8 +176,6 @@ return writing_disk_cache_key_tokens_; } - void OnMemoryPressure(base::MemoryPressureLevel level); - uint64_t cache_max_size() const { return cache_max_size_; } uint64_t cache_max_count() const { return cache_max_count_; } @@ -195,8 +195,6 @@ bool expired_entry_deletion_task_queued_ = false; bool cleanup_task_disabled_for_testing_ = false; - std::unique_ptr<base::AsyncMemoryPressureListenerRegistration> - memory_pressure_listener_registration_; base::WeakPtrFactory<SharedDictionaryManagerOnDisk> weak_factory_{this}; };
diff --git a/services/network/slop_bucket.cc b/services/network/slop_bucket.cc index 981cfe2..1c927b4 100644 --- a/services/network/slop_bucket.cc +++ b/services/network/slop_bucket.cc
@@ -116,6 +116,10 @@ base::MEMORY_PRESSURE_LEVEL_MODERATE, &kMemoryPressureLevelOptions); +// "enabled_for_cache_response" parameter. +constexpr base::FeatureParam<bool> + kEnabledForCacheresponse(&kSlopBucket, "enabled_for_cache_response", true); + } // namespace // This class encapsulates the runtime configuration of SlopBucket. When @@ -135,6 +139,9 @@ base::MemoryPressureLevel memory_pressure_disable_level() const { return memory_pressure_disable_level_; } + bool enabled_for_cache_response() const { + return enabled_for_cache_response_; + } private: friend std::ostream& operator<<(std::ostream& os, @@ -187,6 +194,8 @@ "max_chunks_total is less than max_chunks_per_request"); } memory_pressure_disable_level_ = kMemoryPressureDisableLevelParam.Get(); + + enabled_for_cache_response_ = kEnabledForCacheresponse.Get(); } void DisableWithWarning(const char* warning) { @@ -209,6 +218,8 @@ base::MemoryPressureLevel memory_pressure_disable_level_ = kDefaultMemoryPressureDisableLevel; + + bool enabled_for_cache_response_ = true; }; // SlopBucketManager tracks global state for SlopBuckets. It is thread-hostile. @@ -268,6 +279,10 @@ size_t chunk_size() const { return configuration_.chunk_size(); } size_t min_buffer_size() const { return configuration_.min_buffer_size(); } + bool enabled_for_cache_response() const { + return configuration_.enabled_for_cache_response(); + } + scoped_refptr<ChunkIOBuffer> RequestChunk(size_t existing_chunks) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); if (disabled()) { @@ -514,6 +529,16 @@ return nullptr; } + using CacheEntryStatus = net::HttpResponseInfo::CacheEntryStatus; + const CacheEntryStatus& cache_entry_status = + for_request->response_info().cache_entry_status; + const bool is_response_from_cache = + cache_entry_status == CacheEntryStatus::ENTRY_USED || + cache_entry_status == CacheEntryStatus::ENTRY_VALIDATED; + if (is_response_from_cache && !manager.enabled_for_cache_response()) { + return nullptr; + } + return std::make_unique<SlopBucket>(PassKey(), for_request); }
diff --git a/services/network/url_loader.cc b/services/network/url_loader.cc index 7834c23..622190e 100644 --- a/services/network/url_loader.cc +++ b/services/network/url_loader.cc
@@ -1533,6 +1533,7 @@ bool should_wait = true; if (base::FeatureList::IsEnabled(kSlopBucket) && !slop_bucket_) { slop_bucket_ = SlopBucket::RequestSlopBucket(url_request_.get()); + was_slop_bucket_enabled_ = true; } if (slop_bucket_ && !slop_bucket_->read_in_progress() && !slop_bucket_->IsComplete()) { @@ -1948,10 +1949,25 @@ total_received, 50, 10 * 1000 * 1000, 50); mojo_begin_write_count_for_uma_ = std::max(mojo_begin_write_count_for_uma_, 1); + const int proportion = mojo_blocked_write_count_for_uma_ * 100 / + mojo_begin_write_count_for_uma_; base::UmaHistogramPercentage( - "Net.URLLoader.ProportionOfWritesBlockedByMojo", - mojo_blocked_write_count_for_uma_ * 100 / - mojo_begin_write_count_for_uma_); + "Net.URLLoader.ProportionOfWritesBlockedByMojo", proportion); + if (was_slop_bucket_enabled_) { + base::UmaHistogramPercentage( + "Net.URLLoader.SlopBucket.ProportionOfWritesBlockedByMojo.All", + proportion); + + using CacheEntryStatus = net::HttpResponseInfo::CacheEntryStatus; + const CacheEntryStatus& cache_entry_status = + url_request_->response_info().cache_entry_status; + if (cache_entry_status != CacheEntryStatus::ENTRY_USED && + cache_entry_status != CacheEntryStatus::ENTRY_VALIDATED) { + base::UmaHistogramPercentage( + "Net.URLLoader.SlopBucket.ProportionOfWritesBlockedByMojo.NoCache", + proportion); + } + } } if (total_sent > 0) {
diff --git a/services/network/url_loader.h b/services/network/url_loader.h index 21dc5e84807..09c035a 100644 --- a/services/network/url_loader.h +++ b/services/network/url_loader.h
@@ -762,6 +762,7 @@ // Internal counters to record UMA for SlopBucket. int mojo_begin_write_count_for_uma_ = 0; int mojo_blocked_write_count_for_uma_ = 0; + bool was_slop_bucket_enabled_ = false; // For decoding a small part of the response body to check its type (for ORB // and MIME sniffing) when the response might be compressed and client-side
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc index cb104393b..747e05d8 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.cc +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
@@ -47,7 +47,6 @@ #include "services/viz/public/cpp/gpu/command_buffer_metrics.h" #include "skia/buildflags.h" #include "third_party/skia/include/core/SkTraceMemoryDump.h" -#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h" #include "ui/gl/trace_util.h" class SkDiscardableMemory; @@ -472,12 +471,6 @@ return impl_; } -class GrDirectContext* ContextProviderCommandBuffer::GrContext() { - DCHECK(bind_tried_); - DCHECK_EQ(bind_result_, gpu::ContextResult::kSuccess); - return nullptr; -} - gpu::SharedImageInterface* ContextProviderCommandBuffer::SharedImageInterface() { return shared_image_interface_.get();
diff --git a/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/services/viz/public/cpp/gpu/context_provider_command_buffer.h index 41c575a..2dbecfb 100644 --- a/services/viz/public/cpp/gpu/context_provider_command_buffer.h +++ b/services/viz/public/cpp/gpu/context_provider_command_buffer.h
@@ -126,7 +126,6 @@ gpu::gles2::GLES2Interface* ContextGL() override; gpu::raster::RasterInterface* RasterInterface() override; gpu::ContextSupport* ContextSupport() override; - class GrDirectContext* GrContext() override; gpu::SharedImageInterface* SharedImageInterface() override; ContextCacheController* CacheController() override; base::Lock* GetLock() override;
diff --git a/services/webnn/ort/context_impl_ort.cc b/services/webnn/ort/context_impl_ort.cc index d5150c2..054ab05c 100644 --- a/services/webnn/ort/context_impl_ort.cc +++ b/services/webnn/ort/context_impl_ort.cc
@@ -252,7 +252,7 @@ {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(1)}, /*matmul_input=*/{DataTypeConstraint::kFloat16To32Ints32To64, kMaxRank}, /*pad_input=*/ - {DataTypeConstraint::kAllDataTypesAtLeast8bits, kMaxNonScalarRank}, + {DataTypeConstraint::kAllDataTypesAtLeast8bits, kMaxRank}, /*average_pool2d_input=*/{DataTypeConstraint::kFloat16To32, {3, 8}}, /*l2_pool2d_input=*/{DataTypeConstraint::kFloat16To32, {3, 8}}, /*max_pool2d_input=*/{kInts8Float16To32, {3, 8}}, @@ -303,7 +303,7 @@ /*sigmoid_input=*/{DataTypeConstraint::kFloat16To32, kMaxRank}, /*slice_input=*/ {DataTypeConstraint::kAllDataTypesAtLeast8bits, kMaxRank}, - /*softmax_input=*/{DataTypeConstraint::kFloat16To32, kMaxRank}, + /*softmax_input=*/{DataTypeConstraint::kFloat16To32, kMaxNonScalarRank}, /*softplus_input=*/{DataTypeConstraint::kFloat16To32, kMaxRank}, /*softsign_input=*/{DataTypeConstraint::kFloat16To32, kMaxRank}, /*split_input=*/
diff --git a/services/webnn/tflite/graph_builder_tflite.cc b/services/webnn/tflite/graph_builder_tflite.cc index 889d951..7e72d6b 100644 --- a/services/webnn/tflite/graph_builder_tflite.cc +++ b/services/webnn/tflite/graph_builder_tflite.cc
@@ -502,9 +502,12 @@ /*arg_min_max_output=*/ {DataTypeConstraint::kInt32To64, SupportedRanks::UpTo(8)}, // BatchNormalization is emulated by sub, mul, add and div ops that only - // support max rank up to 5. + // support max rank up to 5. Because `SerializeBatchNormalization()` + // emulation code accesses input size along axis, input cannot be a + // scalar: + // https://source.chromium.org/chromium/chromium/src/+/main:services/webnn/tflite/graph_builder_tflite.cc;l=3556;drc=7b1dd7749fbb05ea8469492fe5c03c27fef75e38 /*batch_normalization_input=*/ - {DataTypeConstraint::kFloat16To32, SupportedRanks::UpTo(5)}, + {DataTypeConstraint::kFloat16To32, SupportedRanks::NonScalarUpTo(5)}, /*batch_normalization_mean=*/ {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(1)}, /*cast_input=*/ @@ -512,7 +515,10 @@ // Polyfilled using MIN and MAX. /*clamp_input=*/ {DataTypeConstraint::kFloat16To32, SupportedRanks::UpTo(5)}, - /*concat_inputs=*/{kAllDataTypesExceptUint4, SupportedRanks::UpTo(8)}, + // Scalar is not supported: + // https://source.chromium.org/chromium/chromium/src/+/main:third_party/tflite/src/tensorflow/lite/kernels/internal/reference/concatenation.h;l=38;drc=31b46e86a93151ca1192009863818d4eaf5df831 + /*concat_inputs=*/ + {kAllDataTypesExceptUint4, SupportedRanks::NonScalarUpTo(8)}, // https://source.chromium.org/chromium/chromium/src/+/main:third_party/tflite/src/tensorflow/lite/kernels/conv.cc /*conv2d_input=*/ {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(4)}, @@ -620,8 +626,10 @@ /*elu_input=*/{kFloat16To32AndInt8, SupportedRanks::UpTo(5)}, /*expand_input=*/ {kFloat16To32AndInts8To32AndInt64, SupportedRanks::UpTo(8)}, + // Scalar is not supported: + // https://source.chromium.org/chromium/chromium/src/+/main:third_party/tflite/src/tensorflow/lite/kernels/internal/reference/gather.h;l=43;drc=49db932a0bdfca060c3e8b0d063a7e8c9f5d2fa5 /*gather_input=*/ - {kFloat16To32AndInt8To64AndUint8, SupportedRanks::UpTo(8)}, + {kFloat16To32AndInt8To64AndUint8, SupportedRanks::NonScalarUpTo(8)}, /*gather_indices=*/ {DataTypeConstraint::kGatherScatterIndicesSupportedDataTypes, SupportedRanks::UpTo(8)},
diff --git a/services/webnn/webnn_context_impl.cc b/services/webnn/webnn_context_impl.cc index 1f5d8f5..dad6d57 100644 --- a/services/webnn/webnn_context_impl.cc +++ b/services/webnn/webnn_context_impl.cc
@@ -392,23 +392,41 @@ // A specific maximum rank is still under discussion, but 8 is the highest // supported by any backend. constexpr SupportedRanks kNonScalarMaxRank = SupportedRanks::NonScalarUpTo(8); + constexpr SupportedRanks kAtLeast2D{2, 8}; // Only intersects for ones that have limits defined in the specification. // For ones that has no limit, no need to intersect with // `SupportedDataTypes::All()`. + backend_context_properties.data_type_limits.arg_min_max_input.ranks + .IntersectWith(kNonScalarMaxRank); + backend_context_properties.data_type_limits.arg_min_max_output.data_types + .RetainAll(DataTypeConstraint::kInt32To64); backend_context_properties.data_type_limits.batch_normalization_input - .data_types.RetainAll(DataTypeConstraint::kFloat16To32); + .IntersectWith({DataTypeConstraint::kFloat16To32, kNonScalarMaxRank}); backend_context_properties.data_type_limits.batch_normalization_mean .IntersectWith( {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(1)}); - backend_context_properties.data_type_limits.conv2d_input.ranks.IntersectWith( - SupportedRanks::Exactly(4)); - backend_context_properties.data_type_limits.conv2d_bias.ranks.IntersectWith( - SupportedRanks::Exactly(1)); - backend_context_properties.data_type_limits.conv_transpose2d_input.ranks - .IntersectWith(SupportedRanks::Exactly(4)); - backend_context_properties.data_type_limits.conv_transpose2d_bias.ranks - .IntersectWith(SupportedRanks::Exactly(1)); + backend_context_properties.data_type_limits.concat_inputs.ranks.IntersectWith( + kNonScalarMaxRank); + backend_context_properties.data_type_limits.conv2d_input.IntersectWith( + {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(4)}); + backend_context_properties.data_type_limits.conv2d_bias.IntersectWith( + {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(1)}); + backend_context_properties.data_type_limits.conv_transpose2d_input + .IntersectWith( + {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(4)}); + backend_context_properties.data_type_limits.conv_transpose2d_bias + .IntersectWith( + {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(1)}); + backend_context_properties.data_type_limits.cumulative_sum_input + .IntersectWith( + {DataTypeConstraint::kFloat16To32Ints32To64, kNonScalarMaxRank}); + backend_context_properties.data_type_limits.dequantize_linear_input.data_types + .RetainAll(DataTypeConstraint::kInts4Ints8Ints32); + backend_context_properties.data_type_limits.dequantize_linear_scale.data_types + .RetainAll(DataTypeConstraint::kFloat16To32); + backend_context_properties.data_type_limits.dequantize_linear_zero_point + .data_types.RetainAll(DataTypeConstraint::kInts4Ints8Ints32); backend_context_properties.data_type_limits.logical_and_input.data_types .RetainAll(DataTypeConstraint::kUint8); backend_context_properties.data_type_limits.logical_or_input.data_types @@ -429,15 +447,6 @@ DataTypeConstraint::kFloat16To32); backend_context_properties.data_type_limits.cos_input.data_types.RetainAll( DataTypeConstraint::kFloat16To32); - backend_context_properties.data_type_limits.cumulative_sum_input - .IntersectWith( - {DataTypeConstraint::kFloat16To32Ints32To64, kNonScalarMaxRank}); - backend_context_properties.data_type_limits.dequantize_linear_input.data_types - .RetainAll(DataTypeConstraint::kInts4Ints8Ints32); - backend_context_properties.data_type_limits.dequantize_linear_scale.data_types - .RetainAll(DataTypeConstraint::kFloat16To32); - backend_context_properties.data_type_limits.dequantize_linear_zero_point - .data_types.RetainAll(DataTypeConstraint::kInts4Ints8Ints32); backend_context_properties.data_type_limits.erf_input.data_types.RetainAll( DataTypeConstraint::kFloat16To32); backend_context_properties.data_type_limits.exp_input.data_types.RetainAll( @@ -463,20 +472,20 @@ backend_context_properties.data_type_limits.elu_input.data_types.RetainAll( DataTypeConstraint::kFloat16To32); backend_context_properties.data_type_limits.gather_input.ranks.IntersectWith( - SupportedRanks::NonScalarUpTo(8)); + kNonScalarMaxRank); backend_context_properties.data_type_limits.gather_indices.data_types .RetainAll(DataTypeConstraint::kGatherScatterIndicesSupportedDataTypes); backend_context_properties.data_type_limits.gather_elements_input.ranks - .IntersectWith(SupportedRanks::NonScalarUpTo(8)); + .IntersectWith(kNonScalarMaxRank); backend_context_properties.data_type_limits.gather_elements_indices .IntersectWith( {DataTypeConstraint::kGatherScatterIndicesSupportedDataTypes, - SupportedRanks::NonScalarUpTo(8)}); + kNonScalarMaxRank}); backend_context_properties.data_type_limits.gather_nd_input.ranks - .IntersectWith(SupportedRanks::NonScalarUpTo(8)); + .IntersectWith(kNonScalarMaxRank); backend_context_properties.data_type_limits.gather_nd_indices.IntersectWith( {DataTypeConstraint::kGatherScatterIndicesSupportedDataTypes, - SupportedRanks::NonScalarUpTo(8)}); + kNonScalarMaxRank}); backend_context_properties.data_type_limits.gelu_input.data_types.RetainAll( DataTypeConstraint::kFloat16To32); backend_context_properties.data_type_limits.gemm_a.IntersectWith( @@ -521,16 +530,14 @@ backend_context_properties.data_type_limits.lstm_cell_bias.IntersectWith( {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(1)}); backend_context_properties.data_type_limits.matmul_input.IntersectWith( - {DataTypeConstraint::kFloat16To32, {2, 8}}); - backend_context_properties.data_type_limits.pad_input.IntersectWith( - {SupportedDataTypes::All(), kNonScalarMaxRank}); + {DataTypeConstraint::kFloat16To32, kAtLeast2D}); backend_context_properties.data_type_limits.average_pool2d_input .IntersectWith( {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(4)}); backend_context_properties.data_type_limits.l2_pool2d_input.IntersectWith( {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(4)}); - backend_context_properties.data_type_limits.max_pool2d_input.IntersectWith( - {SupportedDataTypes::All(), SupportedRanks::Exactly(4)}); + backend_context_properties.data_type_limits.max_pool2d_input.ranks + .IntersectWith(SupportedRanks::Exactly(4)); backend_context_properties.data_type_limits.prelu_input.data_types.RetainAll( DataTypeConstraint::kFloat16To32Int8To64); backend_context_properties.data_type_limits.quantize_linear_input.data_types @@ -558,29 +565,29 @@ backend_context_properties.data_type_limits.resample2d_input.IntersectWith( {DataTypeConstraint::kFloat16To32, SupportedRanks::Exactly(4)}); backend_context_properties.data_type_limits.scatter_elements_input.ranks - .IntersectWith(SupportedRanks::NonScalarUpTo(8)); + .IntersectWith(kNonScalarMaxRank); backend_context_properties.data_type_limits.scatter_elements_indices .data_types.RetainAll( DataTypeConstraint::kGatherScatterIndicesSupportedDataTypes); backend_context_properties.data_type_limits.scatter_nd_input.ranks - .IntersectWith(SupportedRanks::NonScalarUpTo(8)); + .IntersectWith(kNonScalarMaxRank); backend_context_properties.data_type_limits.scatter_nd_indices.IntersectWith( {DataTypeConstraint::kGatherScatterIndicesSupportedDataTypes, - SupportedRanks::NonScalarUpTo(8)}); + kNonScalarMaxRank}); backend_context_properties.data_type_limits.sigmoid_input.data_types .RetainAll(DataTypeConstraint::kFloat16To32); - backend_context_properties.data_type_limits.slice_input.IntersectWith( - {SupportedDataTypes::All(), kNonScalarMaxRank}); - backend_context_properties.data_type_limits.softmax_input.data_types - .RetainAll(DataTypeConstraint::kFloat16To32); + backend_context_properties.data_type_limits.softmax_input.IntersectWith( + {DataTypeConstraint::kFloat16To32, kNonScalarMaxRank}); backend_context_properties.data_type_limits.softplus_input.data_types .RetainAll(DataTypeConstraint::kFloat16To32); backend_context_properties.data_type_limits.softsign_input.data_types .RetainAll(DataTypeConstraint::kFloat16To32); + backend_context_properties.data_type_limits.split_input.ranks.IntersectWith( + kNonScalarMaxRank); backend_context_properties.data_type_limits.tanh_input.data_types.RetainAll( DataTypeConstraint::kFloat16To32); - backend_context_properties.data_type_limits.triangular_input.IntersectWith( - {SupportedDataTypes::All(), {2, 8}}); + backend_context_properties.data_type_limits.triangular_input.ranks + .IntersectWith(kAtLeast2D); backend_context_properties.data_type_limits.where_condition.data_types .RetainAll(DataTypeConstraint::kUint8); return backend_context_properties;
diff --git a/testing/perf/cbb_ref_info/edge/dev/windows.json b/testing/perf/cbb_ref_info/edge/dev/windows.json index 00bb32bf..deb6d4aa 100644 --- a/testing/perf/cbb_ref_info/edge/dev/windows.json +++ b/testing/perf/cbb_ref_info/edge/dev/windows.json
@@ -2,5 +2,5 @@ "browser": "edge", "channel": "dev", "platform": "windows", - "version": "142.0.3581.0" + "version": "142.0.3595.7" } \ No newline at end of file
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index 05e4ba7..8e8bb34 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -12799,6 +12799,28 @@ ] } ] + }, + { + "platforms": [ + "chromeos", + "linux", + "mac", + "windows" + ], + "experiments": [ + { + "name": "Enabled_NVS_HttpCache_Only_WithNewAreEquivalent_DevCanary_1008_Desktop", + "enable_features": [ + "HttpCacheNoVarySearch", + "HttpNoVarySearchDataUseNewAreEquivalent" + ], + "disable_features": [ + "DsePreload2", + "PrefetchPrerenderIntegration", + "SearchPrefetchWithNoVarySearchDiskCache" + ] + } + ] } ], "HttpDiskCachePrewarming": [ @@ -23983,6 +24005,15 @@ "experiments": [ { "name": "Enabled", + "params": { + "chunk_size": "524288", + "enabled_for_cache_response": "true", + "max_chunks_per_request": "8", + "max_chunks_total": "32", + "memory_pressure_disable_level": "MODERATE", + "min_buffer_size": "32768", + "require_priority": "MEDIUM" + }, "enable_features": [ "SlopBucket" ]
diff --git a/third_party/androidx/build.gradle b/third_party/androidx/build.gradle index 5c676d1..25b940f 100644 --- a/third_party/androidx/build.gradle +++ b/third_party/androidx/build.gradle
@@ -314,7 +314,7 @@ google() maven { // This URL is generated by the fetch_all_androidx.py script. - url 'https://androidx.dev/snapshots/builds/14233173/artifacts/repository' + url 'https://androidx.dev/snapshots/builds/14236064/artifacts/repository' } mavenCentral() }
diff --git a/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium b/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium index b498c3a..968532e 100644 --- a/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium +++ b/third_party/androidx/committed/libs/androidx_activity_activity/README.chromium
@@ -1,6 +1,6 @@ Name: Activity Short Name: activity -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/activity/activity/1.12.0-SNAPSHOT/activity-1.12.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/activity/activity/1.12.0-SNAPSHOT/activity-1.12.0-20251008.211458-1.aar Version: 1.12.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium b/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium index 79e202a3..50dcf94 100644 --- a/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium +++ b/third_party/androidx/committed/libs/androidx_activity_activity_compose/README.chromium
@@ -1,6 +1,6 @@ Name: Activity Compose Short Name: activity-compose -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/activity/activity-compose/1.12.0-SNAPSHOT/activity-compose-1.12.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/activity/activity-compose/1.12.0-SNAPSHOT/activity-compose-1.12.0-20251008.211458-1.aar Version: 1.12.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium index 27fcb1ce..d02bda0cc 100644 --- a/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_activity_activity_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Activity Kotlin Extensions Short Name: activity-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/activity/activity-ktx/1.12.0-SNAPSHOT/activity-ktx-1.12.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/activity/activity-ktx/1.12.0-SNAPSHOT/activity-ktx-1.12.0-20251008.211458-1.aar Version: 1.12.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium b/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium index 21c9f7d0..9f74009f 100644 --- a/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium +++ b/third_party/androidx/committed/libs/androidx_annotation_annotation_experimental/README.chromium
@@ -1,6 +1,6 @@ Name: Experimental annotation Short Name: annotation-experimental -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/annotation/annotation-experimental/1.6.0-SNAPSHOT/annotation-experimental-1.6.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/annotation/annotation-experimental/1.6.0-SNAPSHOT/annotation-experimental-1.6.0-20251008.211458-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium index dc055a1..69c636d 100644 --- a/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_annotation_annotation_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: Annotation Short Name: annotation-jvm -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/annotation/annotation-jvm/1.10.0-SNAPSHOT/annotation-jvm-1.10.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/annotation/annotation-jvm/1.10.0-SNAPSHOT/annotation-jvm-1.10.0-20251008.211458-1.jar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium b/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium index d9b02f0..26d2f81 100644 --- a/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appcompat_appcompat/README.chromium
@@ -1,6 +1,6 @@ Name: AppCompat Short Name: appcompat -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/appcompat/appcompat/1.8.0-SNAPSHOT/appcompat-1.8.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/appcompat/appcompat/1.8.0-SNAPSHOT/appcompat-1.8.0-20251008.211458-1.aar Version: 1.8.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium b/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium index b2ca89e2c..18a5617 100644 --- a/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appcompat_appcompat_resources/README.chromium
@@ -1,6 +1,6 @@ Name: AppCompat Resources Short Name: appcompat-resources -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/appcompat/appcompat-resources/1.8.0-SNAPSHOT/appcompat-resources-1.8.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/appcompat/appcompat-resources/1.8.0-SNAPSHOT/appcompat-resources-1.8.0-20251008.211458-1.aar Version: 1.8.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium b/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium index f5b2144f..bdaba6d 100644 --- a/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appsearch_appsearch/README.chromium
@@ -1,6 +1,6 @@ Name: AppSearch Short Name: appsearch -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/appsearch/appsearch/1.2.0-SNAPSHOT/appsearch-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/appsearch/appsearch/1.2.0-SNAPSHOT/appsearch-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium index 2496ce9f..ba1a9128 100644 --- a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_builtin_types/README.chromium
@@ -1,6 +1,6 @@ Name: AppSearch Builtin Types Short Name: appsearch-builtin-types -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/appsearch/appsearch-builtin-types/1.2.0-SNAPSHOT/appsearch-builtin-types-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/appsearch/appsearch-builtin-types/1.2.0-SNAPSHOT/appsearch-builtin-types-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium index 77fb61e..f8c87bd 100644 --- a/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium +++ b/third_party/androidx/committed/libs/androidx_appsearch_appsearch_platform_storage/README.chromium
@@ -1,6 +1,6 @@ Name: AppSearch Platform Storage Short Name: appsearch-platform-storage -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/appsearch/appsearch-platform-storage/1.2.0-SNAPSHOT/appsearch-platform-storage-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/appsearch/appsearch-platform-storage/1.2.0-SNAPSHOT/appsearch-platform-storage-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium b/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium index 12dec2be..44a3b8eb 100644 --- a/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium +++ b/third_party/androidx/committed/libs/androidx_arch_core_core_common/README.chromium
@@ -1,6 +1,6 @@ Name: Arch-Common Short Name: core-common -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/arch/core/core-common/2.3.0-SNAPSHOT/core-common-2.3.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/arch/core/core-common/2.3.0-SNAPSHOT/core-common-2.3.0-20251008.211458-1.jar Version: 2.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium b/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium index d5fc6b4..2431d22e 100644 --- a/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium +++ b/third_party/androidx/committed/libs/androidx_arch_core_core_runtime/README.chromium
@@ -1,6 +1,6 @@ Name: Arch-Runtime Short Name: core-runtime -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/arch/core/core-runtime/2.3.0-SNAPSHOT/core-runtime-2.3.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/arch/core/core-runtime/2.3.0-SNAPSHOT/core-runtime-2.3.0-20251008.211458-1.aar Version: 2.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium b/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium index 2046b975..47819673 100644 --- a/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium +++ b/third_party/androidx/committed/libs/androidx_autofill_autofill/README.chromium
@@ -1,6 +1,6 @@ Name: Autofill Short Name: autofill -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/autofill/autofill/1.4.0-SNAPSHOT/autofill-1.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/autofill/autofill/1.4.0-SNAPSHOT/autofill-1.4.0-20251008.211458-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium index 9a78b1f..fad3193 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_common/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - Common Short Name: benchmark-common -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/benchmark/benchmark-common/1.5.0-SNAPSHOT/benchmark-common-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/benchmark/benchmark-common/1.5.0-SNAPSHOT/benchmark-common-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium index 7949d37e..dc91cac 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_junit4/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - JUnit4 Short Name: benchmark-junit4 -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/benchmark/benchmark-junit4/1.5.0-SNAPSHOT/benchmark-junit4-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/benchmark/benchmark-junit4/1.5.0-SNAPSHOT/benchmark-junit4-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium index 70c17da..00b73d82 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - Macrobenchmark Short Name: benchmark-macro -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/benchmark/benchmark-macro/1.5.0-SNAPSHOT/benchmark-macro-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/benchmark/benchmark-macro/1.5.0-SNAPSHOT/benchmark-macro-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium index 805aaf4f..4c5a352 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_macro_junit4/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark - Macrobenchmark JUnit4 Short Name: benchmark-macro-junit4 -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/benchmark/benchmark-macro-junit4/1.5.0-SNAPSHOT/benchmark-macro-junit4-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/benchmark/benchmark-macro-junit4/1.5.0-SNAPSHOT/benchmark-macro-junit4-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium index d4288a6..9432d8a 100644 --- a/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_benchmark_benchmark_traceprocessor_android/README.chromium
@@ -1,6 +1,6 @@ Name: Benchmark TraceProcessor Short Name: benchmark-traceprocessor-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/benchmark/benchmark-traceprocessor-android/1.5.0-SNAPSHOT/benchmark-traceprocessor-android-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/benchmark/benchmark-traceprocessor-android/1.5.0-SNAPSHOT/benchmark-traceprocessor-android-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium b/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium index 3d848c6..d4af0f76 100644 --- a/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium +++ b/third_party/androidx/committed/libs/androidx_biometric_biometric/README.chromium
@@ -1,6 +1,6 @@ Name: Biometric Short Name: biometric -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/biometric/biometric/1.4.0-SNAPSHOT/biometric-1.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/biometric/biometric/1.4.0-SNAPSHOT/biometric-1.4.0-20251008.211458-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium b/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium index 12e0204..ad748f4 100644 --- a/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium +++ b/third_party/androidx/committed/libs/androidx_browser_browser/README.chromium
@@ -1,6 +1,6 @@ Name: Browser Short Name: browser -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/browser/browser/1.10.0-SNAPSHOT/browser-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/browser/browser/1.10.0-SNAPSHOT/browser-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium b/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium index df88f6d..22ac539 100644 --- a/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium +++ b/third_party/androidx/committed/libs/androidx_cardview_cardview/README.chromium
@@ -1,6 +1,6 @@ Name: CardView Short Name: cardview -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/cardview/cardview/1.1.0-SNAPSHOT/cardview-1.1.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/cardview/cardview/1.1.0-SNAPSHOT/cardview-1.1.0-20251008.211458-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium index 59fb5a6..5d69450 100644 --- a/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_collection_collection_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: collections Short Name: collection-jvm -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/collection/collection-jvm/1.6.0-SNAPSHOT/collection-jvm-1.6.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/collection/collection-jvm/1.6.0-SNAPSHOT/collection-jvm-1.6.0-20251008.211458-1.jar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium index 8443ee3..4bf1614 100644 --- a/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_collection_collection_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Collections Kotlin Extensions Short Name: collection-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/collection/collection-ktx/1.6.0-SNAPSHOT/collection-ktx-1.6.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/collection/collection-ktx/1.6.0-SNAPSHOT/collection-ktx-1.6.0-20251008.211458-1.jar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium index 5f330696..d8e5aad 100644 --- a/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_animation_animation_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Animation Short Name: animation-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/animation/animation-android/1.10.0-SNAPSHOT/animation-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/animation/animation-android/1.10.0-SNAPSHOT/animation-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium index 0e50be01..7565c04 100644 --- a/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_animation_animation_core_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Animation Core Short Name: animation-core-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/animation/animation-core-android/1.10.0-SNAPSHOT/animation-core-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/animation/animation-core-android/1.10.0-SNAPSHOT/animation-core-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium index 124fc967..9c2f629dc 100644 --- a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Foundation Short Name: foundation-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/foundation/foundation-android/1.10.0-SNAPSHOT/foundation-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/foundation/foundation-android/1.10.0-SNAPSHOT/foundation-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium index e4d66bf..5a6d2ef 100644 --- a/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_foundation_foundation_layout_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Layouts Short Name: foundation-layout-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/foundation/foundation-layout-android/1.10.0-SNAPSHOT/foundation-layout-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/foundation/foundation-layout-android/1.10.0-SNAPSHOT/foundation-layout-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium index c585fa2..a334ff3 100644 --- a/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_material3_material3_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Material3 Components Short Name: material3-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/material3/material3-android/1.5.0-SNAPSHOT/material3-android-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/material3/material3-android/1.5.0-SNAPSHOT/material3-android-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium index ee6a3f9..c427a40 100644 --- a/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_material_material_ripple_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Material Ripple Short Name: material-ripple-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/material/material-ripple-android/1.10.0-SNAPSHOT/material-ripple-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/material/material-ripple-android/1.10.0-SNAPSHOT/material-ripple-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium index cf1f734..efbc5e8 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Runtime Short Name: runtime-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/runtime/runtime-android/1.10.0-SNAPSHOT/runtime-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/runtime/runtime-android/1.10.0-SNAPSHOT/runtime-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium index dd4a549d..e36aeec 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_annotation_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Runtime Annotation Short Name: runtime-annotation-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/runtime/runtime-annotation-android/1.10.0-SNAPSHOT/runtime-annotation-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/runtime/runtime-annotation-android/1.10.0-SNAPSHOT/runtime-annotation-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium index aa34576..cf6d633b 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_retain_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Runtime Retain Short Name: runtime-retain-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/runtime/runtime-retain-android/1.10.0-SNAPSHOT/runtime-retain-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/runtime/runtime-retain-android/1.10.0-SNAPSHOT/runtime-retain-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium index e2a3f35..472670f 100644 --- a/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_runtime_runtime_saveable_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Saveable Short Name: runtime-saveable-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/runtime/runtime-saveable-android/1.10.0-SNAPSHOT/runtime-saveable-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/runtime/runtime-saveable-android/1.10.0-SNAPSHOT/runtime-saveable-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium index 6c5114fb..793357d 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose UI Short Name: ui-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-android/1.10.0-SNAPSHOT/ui-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-android/1.10.0-SNAPSHOT/ui-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium index f345649..408840bb 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_geometry_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Geometry Short Name: ui-geometry-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-geometry-android/1.10.0-SNAPSHOT/ui-geometry-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-geometry-android/1.10.0-SNAPSHOT/ui-geometry-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium index 7b78771..7fe42711 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_graphics_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Graphics Short Name: ui-graphics-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-graphics-android/1.10.0-SNAPSHOT/ui-graphics-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-graphics-android/1.10.0-SNAPSHOT/ui-graphics-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium index e5adac2..28174fbd 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Testing Short Name: ui-test-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-test-android/1.10.0-SNAPSHOT/ui-test-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-test-android/1.10.0-SNAPSHOT/ui-test-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium index 297d247..0cd65c9 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_junit4_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Testing for JUnit4 Short Name: ui-test-junit4-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-test-junit4-android/1.10.0-SNAPSHOT/ui-test-junit4-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-test-junit4-android/1.10.0-SNAPSHOT/ui-test-junit4-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium index eab6256..76565ed 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_test_manifest/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Testing manifest dependency Short Name: ui-test-manifest -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-test-manifest/1.10.0-SNAPSHOT/ui-test-manifest-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-test-manifest/1.10.0-SNAPSHOT/ui-test-manifest-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium index 0eef630..9bee968c 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose UI Text Short Name: ui-text-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-text-android/1.10.0-SNAPSHOT/ui-text-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-text-android/1.10.0-SNAPSHOT/ui-text-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium index 7f36433..830dd20 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_text_google_fonts/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Google Fonts integration Short Name: ui-text-google-fonts -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-text-google-fonts/1.10.0-SNAPSHOT/ui-text-google-fonts-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-text-google-fonts/1.10.0-SNAPSHOT/ui-text-google-fonts-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium index 7680cc5..d4d496f 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_unit_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Unit Short Name: ui-unit-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-unit-android/1.10.0-SNAPSHOT/ui-unit-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-unit-android/1.10.0-SNAPSHOT/ui-unit-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium b/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium index 04a5cf1..9f21cfb 100644 --- a/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_compose_ui_ui_util_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Util Short Name: ui-util-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/compose/ui/ui-util-android/1.10.0-SNAPSHOT/ui-util-android-1.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/compose/ui/ui-util-android/1.10.0-SNAPSHOT/ui-util-android-1.10.0-20251008.211458-1.aar Version: 1.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium index d9167312..72c2fb5 100644 --- a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout/README.chromium
@@ -1,6 +1,6 @@ Name: ConstraintLayout Short Name: constraintlayout -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/constraintlayout/constraintlayout/2.3.0-SNAPSHOT/constraintlayout-2.3.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/constraintlayout/constraintlayout/2.3.0-SNAPSHOT/constraintlayout-2.3.0-20251008.211458-1.aar Version: 2.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium index c38dace..c74aebb 100644 --- a/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium +++ b/third_party/androidx/committed/libs/androidx_constraintlayout_constraintlayout_core/README.chromium
@@ -1,6 +1,6 @@ Name: ConstraintLayout Core Short Name: constraintlayout-core -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/constraintlayout/constraintlayout-core/1.2.0-SNAPSHOT/constraintlayout-core-1.2.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/constraintlayout/constraintlayout-core/1.2.0-SNAPSHOT/constraintlayout-core-1.2.0-20251008.211458-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_core_core/README.chromium b/third_party/androidx/committed/libs/androidx_core_core/README.chromium index 0039a393..99a8907 100644 --- a/third_party/androidx/committed/libs/androidx_core_core/README.chromium +++ b/third_party/androidx/committed/libs/androidx_core_core/README.chromium
@@ -1,6 +1,6 @@ Name: Core Short Name: core -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/core/core/1.18.0-SNAPSHOT/core-1.18.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/core/core/1.18.0-SNAPSHOT/core-1.18.0-20251008.211458-1.aar Version: 1.18.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium index d222d2b..91d6eb71 100644 --- a/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_core_core_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Core Kotlin Extensions Short Name: core-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/core/core-ktx/1.18.0-SNAPSHOT/core-ktx-1.18.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/core/core-ktx/1.18.0-SNAPSHOT/core-ktx-1.18.0-20251008.211458-1.aar Version: 1.18.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium b/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium index 9631802..a255ae38 100644 --- a/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium +++ b/third_party/androidx/committed/libs/androidx_core_core_viewtree/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.core:core-viewtree Short Name: core-viewtree -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/core/core-viewtree/1.1.0-SNAPSHOT/core-viewtree-1.1.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/core/core-viewtree/1.1.0-SNAPSHOT/core-viewtree-1.1.0-20251008.211458-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium index 2a67cda..0ac7878b 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_credentials/README.chromium
@@ -1,6 +1,6 @@ Name: Credentials Short Name: credentials -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/credentials/credentials/1.6.0-SNAPSHOT/credentials-1.6.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/credentials/credentials/1.6.0-SNAPSHOT/credentials-1.6.0-20251008.211458-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium index 2f3069e..b865d47 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_credentials_play_services_auth/README.chromium
@@ -1,6 +1,6 @@ Name: Credentials Play Services Auth Short Name: credentials-play-services-auth -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/credentials/credentials-play-services-auth/1.6.0-SNAPSHOT/credentials-play-services-auth-1.6.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/credentials/credentials-play-services-auth/1.6.0-SNAPSHOT/credentials-play-services-auth-1.6.0-20251008.211458-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium index a0ab7a1..2eb575a1 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.credentials.registry:registry-provider Short Name: registry-provider -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/credentials/registry/registry-provider/1.0.0-SNAPSHOT/registry-provider-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/credentials/registry/registry-provider/1.0.0-SNAPSHOT/registry-provider-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium index cd6466d..530c381 100644 --- a/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium +++ b/third_party/androidx/committed/libs/androidx_credentials_registry_registry_provider_play_services/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.credentials.registry:registry-provider-play-services Short Name: registry-provider-play-services -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/credentials/registry/registry-provider-play-services/1.0.0-SNAPSHOT/registry-provider-play-services-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/credentials/registry/registry-provider-play-services/1.0.0-SNAPSHOT/registry-provider-play-services-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium b/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium index 6eedf43..3f16e35 100644 --- a/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium +++ b/third_party/androidx/committed/libs/androidx_cursoradapter_cursoradapter/README.chromium
@@ -1,6 +1,6 @@ Name: Cursor Adapter Short Name: cursoradapter -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/cursoradapter/cursoradapter/1.1.0-SNAPSHOT/cursoradapter-1.1.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/cursoradapter/cursoradapter/1.1.0-SNAPSHOT/cursoradapter-1.1.0-20251008.211458-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium index b980b38..1fe4863 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_android/README.chromium
@@ -1,6 +1,6 @@ Name: DataStore Short Name: datastore-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/datastore/datastore-android/1.2.0-SNAPSHOT/datastore-android-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/datastore/datastore-android/1.2.0-SNAPSHOT/datastore-android-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium index 113e571..696fb15 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_android/README.chromium
@@ -1,6 +1,6 @@ Name: DataStore Core Short Name: datastore-core-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/datastore/datastore-core-android/1.2.0-SNAPSHOT/datastore-core-android-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/datastore/datastore-core-android/1.2.0-SNAPSHOT/datastore-core-android-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium index ebb3e556..442512a5 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_core_okio_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: DataStore Core Okio Short Name: datastore-core-okio-jvm -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/datastore/datastore-core-okio-jvm/1.2.0-SNAPSHOT/datastore-core-okio-jvm-1.2.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/datastore/datastore-core-okio-jvm/1.2.0-SNAPSHOT/datastore-core-okio-jvm-1.2.0-20251008.211458-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium index 8ddb5a14..000cc743 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_android/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences DataStore Short Name: datastore-preferences-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/datastore/datastore-preferences-android/1.2.0-SNAPSHOT/datastore-preferences-android-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/datastore/datastore-preferences-android/1.2.0-SNAPSHOT/datastore-preferences-android-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium index 1cb6369..8ef8b4bd 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_core_android/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences DataStore Core Short Name: datastore-preferences-core-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/datastore/datastore-preferences-core-android/1.2.0-SNAPSHOT/datastore-preferences-core-android-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/datastore/datastore-preferences-core-android/1.2.0-SNAPSHOT/datastore-preferences-core-android-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium index bccbce8..eaf4dbbc 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_external_protobuf/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences External Protobuf Short Name: datastore-preferences-external-protobuf -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/datastore/datastore-preferences-external-protobuf/1.2.0-SNAPSHOT/datastore-preferences-external-protobuf-1.2.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/datastore/datastore-preferences-external-protobuf/1.2.0-SNAPSHOT/datastore-preferences-external-protobuf-1.2.0-20251008.211458-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: BSD-3-Clause
diff --git a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium index 779aa3f..79158c1 100644 --- a/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium +++ b/third_party/androidx/committed/libs/androidx_datastore_datastore_preferences_proto/README.chromium
@@ -1,6 +1,6 @@ Name: Preferences DataStore Proto Short Name: datastore-preferences-proto -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/datastore/datastore-preferences-proto/1.2.0-SNAPSHOT/datastore-preferences-proto-1.2.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/datastore/datastore-preferences-proto/1.2.0-SNAPSHOT/datastore-preferences-proto-1.2.0-20251008.211458-1.jar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium b/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium index 8c35e63..2c643479 100644 --- a/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_drawerlayout_drawerlayout/README.chromium
@@ -1,6 +1,6 @@ Name: Drawer Layout Short Name: drawerlayout -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/drawerlayout/drawerlayout/1.3.0-SNAPSHOT/drawerlayout-1.3.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/drawerlayout/drawerlayout/1.3.0-SNAPSHOT/drawerlayout-1.3.0-20251008.211458-1.aar Version: 1.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium b/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium index bdd49597..ac55d6d 100644 --- a/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium +++ b/third_party/androidx/committed/libs/androidx_emoji_emoji/README.chromium
@@ -1,6 +1,6 @@ Name: Emoji Short Name: emoji -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/emoji/emoji/1.2.0-SNAPSHOT/emoji-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/emoji/emoji/1.2.0-SNAPSHOT/emoji-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0, SIL Open Font License, Version 1.1, Unicode, Inc. License
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium index a2c8072..e68978d 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment/README.chromium
@@ -1,6 +1,6 @@ Name: fragment Short Name: fragment -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/fragment/fragment/1.9.0-SNAPSHOT/fragment-1.9.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/fragment/fragment/1.9.0-SNAPSHOT/fragment-1.9.0-20251008.211458-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium index eeb64e4..83e1270 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_compose/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Compose Short Name: fragment-compose -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/fragment/fragment-compose/1.9.0-SNAPSHOT/fragment-compose-1.9.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/fragment/fragment-compose/1.9.0-SNAPSHOT/fragment-compose-1.9.0-20251008.211458-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium index 080dfd8..eef422e 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Kotlin Extensions Short Name: fragment-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/fragment/fragment-ktx/1.9.0-SNAPSHOT/fragment-ktx-1.9.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/fragment/fragment-ktx/1.9.0-SNAPSHOT/fragment-ktx-1.9.0-20251008.211458-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium index 09843027..270f065 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Testing Extensions Short Name: fragment-testing -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/fragment/fragment-testing/1.9.0-SNAPSHOT/fragment-testing-1.9.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/fragment/fragment-testing/1.9.0-SNAPSHOT/fragment-testing-1.9.0-20251008.211458-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium index 53403331..f5377e3d 100644 --- a/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium +++ b/third_party/androidx/committed/libs/androidx_fragment_fragment_testing_manifest/README.chromium
@@ -1,6 +1,6 @@ Name: Fragment Testing Manifest dependency Short Name: fragment-testing-manifest -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/fragment/fragment-testing-manifest/1.9.0-SNAPSHOT/fragment-testing-manifest-1.9.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/fragment/fragment-testing-manifest/1.9.0-SNAPSHOT/fragment-testing-manifest-1.9.0-20251008.211458-1.aar Version: 1.9.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium b/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium index 5c4dc5a7..d9aa95a 100644 --- a/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium +++ b/third_party/androidx/committed/libs/androidx_graphics_graphics_path/README.chromium
@@ -1,6 +1,6 @@ Name: Android Graphics Path Short Name: graphics-path -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/graphics/graphics-path/1.1.0-SNAPSHOT/graphics-path-1.1.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/graphics/graphics-path/1.1.0-SNAPSHOT/graphics-path-1.1.0-20251008.211458-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium b/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium index 4e0a0a5..aff0597c 100644 --- a/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_graphics_graphics_shapes_android/README.chromium
@@ -1,6 +1,6 @@ Name: Graphics Shapes Short Name: graphics-shapes-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/graphics/graphics-shapes-android/1.1.0-SNAPSHOT/graphics-shapes-android-1.1.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/graphics/graphics-shapes-android/1.1.0-SNAPSHOT/graphics-shapes-android-1.1.0-20251008.211458-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium b/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium index 84cb1d8..9d8fa83 100644 --- a/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium +++ b/third_party/androidx/committed/libs/androidx_interpolator_interpolator/README.chromium
@@ -1,6 +1,6 @@ Name: Interpolators Short Name: interpolator -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/interpolator/interpolator/1.1.0-SNAPSHOT/interpolator-1.1.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/interpolator/interpolator/1.1.0-SNAPSHOT/interpolator-1.1.0-20251008.211458-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium index a56b2d9..c48744e2 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_java8/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle-Common for Java 8 Short Name: lifecycle-common-java8 -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-common-java8/2.10.0-SNAPSHOT/lifecycle-common-java8-2.10.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-common-java8/2.10.0-SNAPSHOT/lifecycle-common-java8-2.10.0-20251008.211458-1.jar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium index de87ad40..c77fcfda 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_common_jvm/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle-Common Short Name: lifecycle-common-jvm -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-common-jvm/2.10.0-SNAPSHOT/lifecycle-common-jvm-2.10.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-common-jvm/2.10.0-SNAPSHOT/lifecycle-common-jvm-2.10.0-20251008.211458-1.jar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium index 444d678..0a351ed 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle LiveData Short Name: lifecycle-livedata -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-livedata/2.10.0-SNAPSHOT/lifecycle-livedata-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-livedata/2.10.0-SNAPSHOT/lifecycle-livedata-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium index eef16ef..fc5291c 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle LiveData Core Short Name: lifecycle-livedata-core -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core/2.10.0-SNAPSHOT/lifecycle-livedata-core-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core/2.10.0-SNAPSHOT/lifecycle-livedata-core-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium index 26a4ee8d..7282701 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_core_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: LiveData Core Kotlin Extensions Short Name: lifecycle-livedata-core-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-core-ktx-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-livedata-core-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-core-ktx-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium index bd3b37ad..54664b89 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_livedata_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: LiveData Kotlin Extensions Short Name: lifecycle-livedata-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-livedata-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-ktx-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-livedata-ktx/2.10.0-SNAPSHOT/lifecycle-livedata-ktx-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium index b0f65672..3e2a98ef 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_process/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Process Short Name: lifecycle-process -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-process/2.10.0-SNAPSHOT/lifecycle-process-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-process/2.10.0-SNAPSHOT/lifecycle-process-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium index 70b2657..0027be6a 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Runtime Short Name: lifecycle-runtime-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-runtime-android/2.10.0-SNAPSHOT/lifecycle-runtime-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-runtime-android/2.10.0-SNAPSHOT/lifecycle-runtime-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium index 15e5bdc..6e9131a 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Runtime Compose Short Name: lifecycle-runtime-compose-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-runtime-compose-android/2.10.0-SNAPSHOT/lifecycle-runtime-compose-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-runtime-compose-android/2.10.0-SNAPSHOT/lifecycle-runtime-compose-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium index 09afe7ba..2bd9ebd7 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_runtime_ktx_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Kotlin Extensions Short Name: lifecycle-runtime-ktx-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-runtime-ktx-android/2.10.0-SNAPSHOT/lifecycle-runtime-ktx-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-runtime-ktx-android/2.10.0-SNAPSHOT/lifecycle-runtime-ktx-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium index 1cdae34c..b455b3e 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_service/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle Service Short Name: lifecycle-service -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-service/2.10.0-SNAPSHOT/lifecycle-service-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-service/2.10.0-SNAPSHOT/lifecycle-service-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium index 0bb56fb1..6d778f57 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel Short Name: lifecycle-viewmodel-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium index 2d6c49d9..d43f9b1 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel Compose Short Name: lifecycle-viewmodel-compose-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-compose-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-compose-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-compose-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-compose-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium index 849b8812..846894c8 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel Kotlin Extensions Short Name: lifecycle-viewmodel-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-ktx/2.10.0-SNAPSHOT/lifecycle-viewmodel-ktx-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-ktx/2.10.0-SNAPSHOT/lifecycle-viewmodel-ktx-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium index 60c619a..9a6cc99d 100644 --- a/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_lifecycle_lifecycle_viewmodel_savedstate_android/README.chromium
@@ -1,6 +1,6 @@ Name: Lifecycle ViewModel with SavedState Short Name: lifecycle-viewmodel-savedstate-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-savedstate-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-savedstate-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/lifecycle/lifecycle-viewmodel-savedstate-android/2.10.0-SNAPSHOT/lifecycle-viewmodel-savedstate-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium b/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium index 7d0f1db6..2cc9dafd 100644 --- a/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium +++ b/third_party/androidx/committed/libs/androidx_loader_loader/README.chromium
@@ -1,6 +1,6 @@ Name: loader Short Name: loader -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/loader/loader/1.2.0-SNAPSHOT/loader-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/loader/loader/1.2.0-SNAPSHOT/loader-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_media_media/README.chromium b/third_party/androidx/committed/libs/androidx_media_media/README.chromium index 1c6ce43..acfe350 100644 --- a/third_party/androidx/committed/libs/androidx_media_media/README.chromium +++ b/third_party/androidx/committed/libs/androidx_media_media/README.chromium
@@ -1,6 +1,6 @@ Name: Media Short Name: media -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/media/media/1.8.0-SNAPSHOT/media-1.8.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/media/media/1.8.0-SNAPSHOT/media-1.8.0-20251008.211458-1.aar Version: 1.8.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium index e987524..f7699eae 100644 --- a/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigation_navigation_common_android/README.chromium
@@ -1,6 +1,6 @@ Name: Navigation Common Short Name: navigation-common-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/navigation/navigation-common-android/2.10.0-SNAPSHOT/navigation-common-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/navigation/navigation-common-android/2.10.0-SNAPSHOT/navigation-common-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium index 148d2fd..07ad84d 100644 --- a/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigation_navigation_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Compose Navigation Short Name: navigation-compose-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/navigation/navigation-compose-android/2.10.0-SNAPSHOT/navigation-compose-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/navigation/navigation-compose-android/2.10.0-SNAPSHOT/navigation-compose-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium index aadf2d6..50dd40d 100644 --- a/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigation_navigation_runtime_android/README.chromium
@@ -1,6 +1,6 @@ Name: Navigation Runtime Short Name: navigation-runtime-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/navigation/navigation-runtime-android/2.10.0-SNAPSHOT/navigation-runtime-android-2.10.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/navigation/navigation-runtime-android/2.10.0-SNAPSHOT/navigation-runtime-android-2.10.0-20251008.211458-1.aar Version: 2.10.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium index 16d7575..98f572e 100644 --- a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_android/README.chromium
@@ -1,6 +1,6 @@ Name: Navigation Event Short Name: navigationevent-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/navigationevent/navigationevent-android/1.0.0-SNAPSHOT/navigationevent-android-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/navigationevent/navigationevent-android/1.0.0-SNAPSHOT/navigationevent-android-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium index e0a522e..e7fbdccb 100644 --- a/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_navigationevent_navigationevent_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: NavigationEvent Compose Short Name: navigationevent-compose-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/navigationevent/navigationevent-compose-android/1.0.0-SNAPSHOT/navigationevent-compose-android-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/navigationevent/navigationevent-compose-android/1.0.0-SNAPSHOT/navigationevent-compose-android-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium index 2680f04e..cd7d1c1 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_common_android/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Common Short Name: paging-common-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/paging/paging-common-android/3.4.0-SNAPSHOT/paging-common-android-3.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/paging/paging-common-android/3.4.0-SNAPSHOT/paging-common-android-3.4.0-20251008.211458-1.aar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium index afa9dd26..d1ed6ca 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_common_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Common Kotlin Extensions Short Name: paging-common-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/paging/paging-common-ktx/3.4.0-SNAPSHOT/paging-common-ktx-3.4.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/paging/paging-common-ktx/3.4.0-SNAPSHOT/paging-common-ktx-3.4.0-20251008.211458-1.jar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium index 72f6f0e..fea8e7ba 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Compose Short Name: paging-compose-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/paging/paging-compose-android/3.4.0-SNAPSHOT/paging-compose-android-3.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/paging/paging-compose-android/3.4.0-SNAPSHOT/paging-compose-android-3.4.0-20251008.211458-1.aar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium b/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium index a79487f..ff418f76a 100644 --- a/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium +++ b/third_party/androidx/committed/libs/androidx_paging_paging_runtime/README.chromium
@@ -1,6 +1,6 @@ Name: Paging-Runtime Short Name: paging-runtime -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/paging/paging-runtime/3.4.0-SNAPSHOT/paging-runtime-3.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/paging/paging-runtime/3.4.0-SNAPSHOT/paging-runtime-3.4.0-20251008.211458-1.aar Version: 3.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium b/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium index 4bf39410..f3d64fc 100644 --- a/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium +++ b/third_party/androidx/committed/libs/androidx_palette_palette/README.chromium
@@ -1,6 +1,6 @@ Name: Palette Short Name: palette -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/palette/palette/1.1.0-SNAPSHOT/palette-1.1.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/palette/palette/1.1.0-SNAPSHOT/palette-1.1.0-20251008.211458-1.aar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_pdf_pdf_document_service/README.chromium b/third_party/androidx/committed/libs/androidx_pdf_pdf_document_service/README.chromium index dc0d0e6..cb4fea3f 100644 --- a/third_party/androidx/committed/libs/androidx_pdf_pdf_document_service/README.chromium +++ b/third_party/androidx/committed/libs/androidx_pdf_pdf_document_service/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.pdf:pdf-document-service Short Name: pdf-document-service -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/pdf/pdf-document-service/1.0.0-SNAPSHOT/pdf-document-service-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/pdf/pdf-document-service/1.0.0-SNAPSHOT/pdf-document-service-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer/README.chromium b/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer/README.chromium index 56dbee32..815d102 100644 --- a/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer/README.chromium +++ b/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.pdf:pdf-viewer Short Name: pdf-viewer -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/pdf/pdf-viewer/1.0.0-SNAPSHOT/pdf-viewer-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/pdf/pdf-viewer/1.0.0-SNAPSHOT/pdf-viewer-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer_fragment/README.chromium b/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer_fragment/README.chromium index 86926de..566ed23b 100644 --- a/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer_fragment/README.chromium +++ b/third_party/androidx/committed/libs/androidx_pdf_pdf_viewer_fragment/README.chromium
@@ -1,6 +1,6 @@ Name: androidx.pdf:pdf-viewer-fragment Short Name: pdf-viewer-fragment -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/pdf/pdf-viewer-fragment/1.0.0-SNAPSHOT/pdf-viewer-fragment-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/pdf/pdf-viewer-fragment/1.0.0-SNAPSHOT/pdf-viewer-fragment-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium b/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium index f1c0a526..9ad6ce36 100644 --- a/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium +++ b/third_party/androidx/committed/libs/androidx_preference_preference/README.chromium
@@ -1,6 +1,6 @@ Name: Preference Short Name: preference -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/preference/preference/1.3.0-SNAPSHOT/preference-1.3.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/preference/preference/1.3.0-SNAPSHOT/preference-1.3.0-20251008.211458-1.aar Version: 1.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium b/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium index 44685668..87a33df 100644 --- a/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium +++ b/third_party/androidx/committed/libs/androidx_profileinstaller_profileinstaller/README.chromium
@@ -1,6 +1,6 @@ Name: Profile Installer Short Name: profileinstaller -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/profileinstaller/profileinstaller/1.5.0-SNAPSHOT/profileinstaller-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/profileinstaller/profileinstaller/1.5.0-SNAPSHOT/profileinstaller-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium b/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium index 18dd623..f22f975 100644 --- a/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium +++ b/third_party/androidx/committed/libs/androidx_recyclerview_recyclerview/README.chromium
@@ -1,6 +1,6 @@ Name: RecyclerView Short Name: recyclerview -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/recyclerview/recyclerview/1.5.0-SNAPSHOT/recyclerview-1.5.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/recyclerview/recyclerview/1.5.0-SNAPSHOT/recyclerview-1.5.0-20251008.211458-1.aar Version: 1.5.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium b/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium index 3bd95fa..250a229 100644 --- a/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium +++ b/third_party/androidx/committed/libs/androidx_resourceinspection_resourceinspection_annotation/README.chromium
@@ -1,6 +1,6 @@ Name: Resource Inspection - Annotations Short Name: resourceinspection-annotation -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/resourceinspection/resourceinspection-annotation/1.1.0-SNAPSHOT/resourceinspection-annotation-1.1.0-20251008.132034-1.jar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/resourceinspection/resourceinspection-annotation/1.1.0-SNAPSHOT/resourceinspection-annotation-1.1.0-20251008.211458-1.jar Version: 1.1.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium index 9c98b961..6849319 100644 --- a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_android/README.chromium
@@ -1,6 +1,6 @@ Name: Saved State Short Name: savedstate-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/savedstate/savedstate-android/1.4.0-SNAPSHOT/savedstate-android-1.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/savedstate/savedstate-android/1.4.0-SNAPSHOT/savedstate-android-1.4.0-20251008.211458-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium index 97019c8e..e6a8b46 100644 --- a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_compose_android/README.chromium
@@ -1,6 +1,6 @@ Name: Saved State Compose Short Name: savedstate-compose-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/savedstate/savedstate-compose-android/1.4.0-SNAPSHOT/savedstate-compose-android-1.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/savedstate/savedstate-compose-android/1.4.0-SNAPSHOT/savedstate-compose-android-1.4.0-20251008.211458-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium index 56b821f..b62779b 100644 --- a/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium +++ b/third_party/androidx/committed/libs/androidx_savedstate_savedstate_ktx/README.chromium
@@ -1,6 +1,6 @@ Name: SavedState Kotlin Extensions Short Name: savedstate-ktx -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/savedstate/savedstate-ktx/1.4.0-SNAPSHOT/savedstate-ktx-1.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/savedstate/savedstate-ktx/1.4.0-SNAPSHOT/savedstate-ktx-1.4.0-20251008.211458-1.aar Version: 1.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium b/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium index af5800c..07d3fcf 100644 --- a/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_slidingpanelayout_slidingpanelayout/README.chromium
@@ -1,6 +1,6 @@ Name: Sliding Pane Layout Short Name: slidingpanelayout -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/slidingpanelayout/slidingpanelayout/1.3.0-SNAPSHOT/slidingpanelayout-1.3.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/slidingpanelayout/slidingpanelayout/1.3.0-SNAPSHOT/slidingpanelayout-1.3.0-20251008.211458-1.aar Version: 1.3.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium b/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium index d5a545a..0a4ac0f 100644 --- a/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium +++ b/third_party/androidx/committed/libs/androidx_swiperefreshlayout_swiperefreshlayout/README.chromium
@@ -1,6 +1,6 @@ Name: Swipe Refresh Layout Short Name: swiperefreshlayout -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/swiperefreshlayout/swiperefreshlayout/1.2.0-SNAPSHOT/swiperefreshlayout-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/swiperefreshlayout/swiperefreshlayout/1.2.0-SNAPSHOT/swiperefreshlayout-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium b/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium index e9ff841..8f2add0 100644 --- a/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium +++ b/third_party/androidx/committed/libs/androidx_test_uiautomator_uiautomator/README.chromium
@@ -1,6 +1,6 @@ Name: UIAutomator Short Name: uiautomator -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/test/uiautomator/uiautomator/2.4.0-SNAPSHOT/uiautomator-2.4.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/test/uiautomator/uiautomator/2.4.0-SNAPSHOT/uiautomator-2.4.0-20251008.211458-1.aar Version: 2.4.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium b/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium index c6bbe96f..a263ce90 100644 --- a/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium +++ b/third_party/androidx/committed/libs/androidx_transition_transition/README.chromium
@@ -1,6 +1,6 @@ Name: Transition Short Name: transition -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/transition/transition/1.7.0-SNAPSHOT/transition-1.7.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/transition/transition/1.7.0-SNAPSHOT/transition-1.7.0-20251008.211458-1.aar Version: 1.7.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium b/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium index 7576b72..d9dd4af 100644 --- a/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium +++ b/third_party/androidx/committed/libs/androidx_viewpager2_viewpager2/README.chromium
@@ -1,6 +1,6 @@ Name: ViewPager2 Short Name: viewpager2 -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/viewpager2/viewpager2/1.2.0-SNAPSHOT/viewpager2-1.2.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/viewpager2/viewpager2/1.2.0-SNAPSHOT/viewpager2-1.2.0-20251008.211458-1.aar Version: 1.2.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium b/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium index 65b5cd5f..168423f 100644 --- a/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium +++ b/third_party/androidx/committed/libs/androidx_webkit_webkit/README.chromium
@@ -1,6 +1,6 @@ Name: Webkit Short Name: webkit -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/webkit/webkit/1.15.0-SNAPSHOT/webkit-1.15.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/webkit/webkit/1.15.0-SNAPSHOT/webkit-1.15.0-20251008.211458-1.aar Version: 1.15.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium b/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium index 5d1cee4c..324dc47a 100644 --- a/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium +++ b/third_party/androidx/committed/libs/androidx_window_sidecar_sidecar/README.chromium
@@ -1,6 +1,6 @@ Name: WindowManager Sidecar Short Name: sidecar -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/window/sidecar/sidecar/1.0.0-SNAPSHOT/sidecar-1.0.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/window/sidecar/sidecar/1.0.0-SNAPSHOT/sidecar-1.0.0-20251008.211458-1.aar Version: 1.0.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_window_window/README.chromium b/third_party/androidx/committed/libs/androidx_window_window/README.chromium index ed59070..2b610e69 100644 --- a/third_party/androidx/committed/libs/androidx_window_window/README.chromium +++ b/third_party/androidx/committed/libs/androidx_window_window/README.chromium
@@ -1,6 +1,6 @@ Name: WindowManager Short Name: window -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/window/window/1.6.0-SNAPSHOT/window-1.6.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/window/window/1.6.0-SNAPSHOT/window-1.6.0-20251008.211458-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/androidx/committed/libs/androidx_window_window_core_android/README.chromium b/third_party/androidx/committed/libs/androidx_window_window_core_android/README.chromium index f5da02e7..ca4f6810 100644 --- a/third_party/androidx/committed/libs/androidx_window_window_core_android/README.chromium +++ b/third_party/androidx/committed/libs/androidx_window_window_core_android/README.chromium
@@ -1,6 +1,6 @@ Name: WindowManager Core Short Name: window-core-android -URL: https://androidx.dev/snapshots/builds/14233173/artifacts/repository/androidx/window/window-core-android/1.6.0-SNAPSHOT/window-core-android-1.6.0-20251008.132034-1.aar +URL: https://androidx.dev/snapshots/builds/14236064/artifacts/repository/androidx/window/window-core-android/1.6.0-SNAPSHOT/window-core-android-1.6.0-20251008.211458-1.aar Version: 1.6.0-SNAPSHOT Update Mechanism: Autoroll License: Apache-2.0
diff --git a/third_party/angle b/third_party/angle index f9685fd..17977bb 160000 --- a/third_party/angle +++ b/third_party/angle
@@ -1 +1 @@ -Subproject commit f9685fdb79805ace8376705bafb024a1bd64c05a +Subproject commit 17977bb088acae8e114bae7f1ae92326b5fe8d1d
diff --git a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc index 4b582288..ec9d788 100644 --- a/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc +++ b/third_party/blink/renderer/core/css/properties/longhands/longhands_custom.cc
@@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "base/memory/values_equivalent.h" #include "base/numerics/clamped_math.h" #include "third_party/blink/public/strings/grit/blink_strings.h" #include "third_party/blink/renderer/core/css/basic_shape_functions.h" @@ -64,6 +65,7 @@ #include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_object.h" #include "third_party/blink/renderer/core/style/computed_style.h" +#include "third_party/blink/renderer/core/style/computed_style_constants.h" #include "third_party/blink/renderer/core/style/coord_box_offset_path_operation.h" #include "third_party/blink/renderer/core/style/geometry_box_clip_path_operation.h" #include "third_party/blink/renderer/core/style/grid_area.h" @@ -1966,6 +1968,24 @@ return ZoomAdjustedPixelValue(width, style); } +namespace { + +const CSSValue* ConsumeBasicShapeAndCoordBox(CSSParserTokenStream& stream, + const CSSParserContext& context) { + CSSValue* shape = css_parsing_utils::ConsumeBasicShape(stream, context); + if (!shape) { + return nullptr; + } + CSSValue* coord_box = css_parsing_utils::ConsumeCoordBox(stream); + if (coord_box) { + return MakeGarbageCollected<CSSValuePair>( + shape, coord_box, CSSValuePair::kKeepIdenticalValues); + } + return shape; +} + +} // namespace + const CSSValue* BorderShape::ParseSingleValue( CSSParserTokenStream& stream, const CSSParserContext& context, @@ -1975,17 +1995,20 @@ return css_parsing_utils::ConsumeIdent(stream); } - // TODO(nrosenthal) parse the <<geometry-box>>. - CSSValue* outer_shape = css_parsing_utils::ConsumeBasicShape(stream, context); - if (!outer_shape) { + const CSSValue* outer = ConsumeBasicShapeAndCoordBox(stream, context); + if (!outer) { return nullptr; } - CSSValue* inner_shape = css_parsing_utils::ConsumeBasicShape(stream, context); - return inner_shape - ? MakeGarbageCollected<CSSValuePair>( - outer_shape, inner_shape, CSSValuePair::kDropIdenticalValues) - : outer_shape; + const CSSValue* inner = ConsumeBasicShapeAndCoordBox(stream, context); + if (!inner || base::ValuesEquivalent(inner, outer)) { + return outer; + } + + CSSValueList* list = CSSValueList::CreateSpaceSeparated(); + list->Append(*outer); + list->Append(*inner); + return list; } const CSSValue* BorderShape::CSSValueFromComputedStyleInternal( @@ -1997,15 +2020,25 @@ return CSSIdentifierValue::Create(CSSValueID::kNone); } const StyleBorderShape& border_shape = *style.BorderShape(); + CSSValueList* list = CSSValueList::CreateSpaceSeparated(); const CSSValue* outer_shape = ValueForBasicShape(style, &border_shape.OuterShape()); - if (!border_shape.HasSeparateInnerShape()) { - return outer_shape; + list->Append(*outer_shape); + CoordBox coord_box = border_shape.OuterCoordBox(); + if (coord_box != CoordBox::kBorderBox) { + list->Append(*CSSIdentifierValue::Create(coord_box)); } - - return MakeGarbageCollected<CSSValuePair>( - outer_shape, ValueForBasicShape(style, &border_shape.InnerShape()), - CSSValuePair::kDropIdenticalValues); + if (!border_shape.HasSeparateInnerShape()) { + return list; + } + const CSSValue* inner_shape = + ValueForBasicShape(style, &border_shape.InnerShape()); + list->Append(*inner_shape); + coord_box = border_shape.InnerCoordBox(); + if (coord_box != CoordBox::kBorderBox) { + list->Append(*CSSIdentifierValue::Create(coord_box)); + } + return list; } const CSSValue* Bottom::ParseSingleValue(
diff --git a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc index aaf3b23..18195a2 100644 --- a/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc +++ b/third_party/blink/renderer/core/css/resolver/style_builder_converter.cc
@@ -275,22 +275,58 @@ url_value.ValueForSerialization()); } +namespace { + +struct BasicShapeAndCoordBox { + STACK_ALLOCATED(); + + public: + BasicShape* shape; + CoordBox coord_box; +}; + +BasicShapeAndCoordBox BasicShapeAndCoordBoxForValue(StyleResolverState& state, + const CSSValue& value) { + BasicShape* shape = nullptr; + CoordBox coord_box = CoordBox::kBorderBox; + if (const auto* pair = DynamicTo<CSSValuePair>(value)) { + shape = BasicShapeForValue(state, pair->First()); + coord_box = To<CSSIdentifierValue>(pair->Second()).ConvertTo<CoordBox>(); + } else { + shape = BasicShapeForValue(state, value); + } + return {shape, coord_box}; +} + +} // namespace + StyleBorderShape* StyleBuilderConverter::ConvertBorderShape( StyleResolverState& state, const CSSValue& value) { + // Either: + // - none; + // - a single shape (meaning default coord box is border-box); + // - a pair of shape + coord_box; + // - list of either: two pairs of shape + coord_box or two shapes. if (value.IsIdentifierValue()) { CHECK_EQ(To<CSSIdentifierValue>(value).GetValueID(), CSSValueID::kNone); return nullptr; } - if (const auto* pair = DynamicTo<CSSValuePair>(value)) { + if (const auto* list = DynamicTo<CSSValueList>(value)) { + DCHECK_EQ(list->length(), 2u); + auto [outer_shape, outer_coord_box] = + BasicShapeAndCoordBoxForValue(state, list->First()); + auto [inner_shape, inner_coord_box] = + BasicShapeAndCoordBoxForValue(state, list->Last()); return MakeGarbageCollected<StyleBorderShape>( - *BasicShapeForValue(state, pair->First()), - BasicShapeForValue(state, pair->Second())); + *outer_shape, inner_shape, outer_coord_box, inner_coord_box); } + auto [outer_shape, outer_coord_box] = + BasicShapeAndCoordBoxForValue(state, value); return MakeGarbageCollected<StyleBorderShape>( - *BasicShapeForValue(state, value)); + *outer_shape, outer_shape, outer_coord_box, outer_coord_box); } LengthBox StyleBuilderConverter::ConvertClip(StyleResolverState& state,
diff --git a/third_party/blink/renderer/core/dom/document.cc b/third_party/blink/renderer/core/dom/document.cc index 79daed3..80d39d5 100644 --- a/third_party/blink/renderer/core/dom/document.cc +++ b/third_party/blink/renderer/core/dom/document.cc
@@ -3676,6 +3676,10 @@ documentElement()->SetNeedsStyleRecalc( kLocalStyleChange, StyleChangeReasonForTracing::Create(style_change_reason::kFrame)); + if (GetLayoutView() && GetFrame()->Owner() && + !GetFrame()->Owner()->IsDisplayNone()) { + GetLayoutView()->CacheScrollDimensions(); + } } bool Document::WillPrintSoon() {
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 61c41eae..255582b 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
@@ -234,7 +234,7 @@ uses_menu_list_ = FastHasAttribute(html_names::kSizeAttr) ? size_ == 1 : false; } else { - uses_menu_list_ = size_ == 1; + uses_menu_list_ = size_ <= 1; } return; } @@ -1604,6 +1604,7 @@ if (UsesMenuList() != old_uses_menu_list) { select_type_->WillBeDestroyed(); select_type_ = SelectType::Create(*this); + PseudoStateChanged(CSSSelector::kPseudoListBox); } if (!InActiveDocument()) return;
diff --git a/third_party/blink/renderer/core/html/media/html_media_test_helper.h b/third_party/blink/renderer/core/html/media/html_media_test_helper.h index ee8086a6..74f1658 100644 --- a/third_party/blink/renderer/core/html/media/html_media_test_helper.h +++ b/third_party/blink/renderer/core/html/media/html_media_test_helper.h
@@ -5,6 +5,7 @@ #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_TEST_HELPER_H_ #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_MEDIA_HTML_MEDIA_TEST_HELPER_H_ +#include "third_party/blink/public/platform/web_media_player.h" #include "third_party/blink/renderer/core/loader/empty_clients.h" namespace blink {
diff --git a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc index 5a2e15c5..5c0cdb3 100644 --- a/third_party/blink/renderer/core/inspector/inspector_css_agent.cc +++ b/third_party/blink/renderer/core/inspector/inspector_css_agent.cc
@@ -154,7 +154,6 @@ #include "third_party/blink/renderer/platform/fonts/font.h" #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_custom_platform_data.h" -#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h" #include "third_party/blink/renderer/platform/geometry/layout_unit.h" #include "third_party/blink/renderer/platform/heap/collection_support/clear_collection_scope.h"
diff --git a/third_party/blink/renderer/core/layout/layout_view.cc b/third_party/blink/renderer/core/layout/layout_view.cc index 18786d2..7931113 100644 --- a/third_party/blink/renderer/core/layout/layout_view.cc +++ b/third_party/blink/renderer/core/layout/layout_view.cc
@@ -918,6 +918,34 @@ SetHasBoxDecorationBackground(true); } +void LayoutView::UpdateAfterLayout() { + NOT_DESTROYED(); + LayoutBlockFlow::UpdateAfterLayout(); + if (cached_scroll_dimensions_.has_value() && GetFrame()->Owner() && + !GetFrame()->Owner()->IsDisplayNone() && !GetDocument().Printing()) { + auto* scrollable_area = GetScrollableArea(); + CHECK(scrollable_area); + // Only restore scroll offset if the scroll dimensions match + if (scrollable_area->ScrollWidth() == cached_scroll_dimensions_->width && + scrollable_area->ScrollHeight() == cached_scroll_dimensions_->height && + scrollable_area->ScrollOrigin() == cached_scroll_dimensions_->origin) { + scrollable_area->SetScrollOffset(cached_scroll_dimensions_->offset, + mojom::blink::ScrollType::kProgrammatic, + cc::ScrollSourceType::kAbsoluteScroll); + } + cached_scroll_dimensions_.reset(); + } +} + +void LayoutView::CacheScrollDimensions() { + NOT_DESTROYED(); + auto* scrollable_area = GetScrollableArea(); + CHECK(scrollable_area); + cached_scroll_dimensions_.emplace(CachedScrollDimensions{ + scrollable_area->ScrollWidth(), scrollable_area->ScrollHeight(), + scrollable_area->ScrollOrigin(), scrollable_area->GetScrollOffset()}); +} + void LayoutView::StyleDidChange( StyleDifference diff, const ComputedStyle* old_style,
diff --git a/third_party/blink/renderer/core/layout/layout_view.h b/third_party/blink/renderer/core/layout/layout_view.h index 711dac9..cc8971f 100644 --- a/third_party/blink/renderer/core/layout/layout_view.h +++ b/third_party/blink/renderer/core/layout/layout_view.h
@@ -27,6 +27,7 @@ #include "third_party/blink/public/mojom/scroll/scrollbar_mode.mojom-blink.h" #include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/layout/layout_block_flow.h" +#include "third_party/blink/renderer/core/scroll/scroll_types.h" #include "third_party/blink/renderer/core/scroll/scrollable_area.h" #include "third_party/blink/renderer/platform/graphics/overlay_scrollbar_clip_behavior.h" #include "third_party/blink/renderer/platform/heap/collection_support/heap_hash_set.h" @@ -336,6 +337,8 @@ LayoutViewTransitionRoot* GetViewTransitionRoot() const; + void CacheScrollDimensions(); + private: void StyleDidChange(StyleDifference, const ComputedStyle* old_style, @@ -356,6 +359,7 @@ bool CanHaveChildren() const override; void UpdateFromStyle() override; + void UpdateAfterLayout() override; // The CompositeBackgroundAttachmentFixed optimization doesn't apply to // LayoutView which paints background specially. @@ -403,6 +407,17 @@ mojom::blink::ScrollbarMode autosize_h_scrollbar_mode_; mojom::blink::ScrollbarMode autosize_v_scrollbar_mode_; + struct CachedScrollDimensions { + LayoutUnit width; + LayoutUnit height; + gfx::Point origin; + ScrollOffset offset; + }; + + // This is set when a frame becomes display:none and reset in the first layout + // after exiting that state. + std::optional<CachedScrollDimensions> cached_scroll_dimensions_; + mutable PhysicalRect previous_background_rect_; };
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.cc b/third_party/blink/renderer/core/paint/box_painter_base.cc index f22f9db..292c0fa 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.cc +++ b/third_party/blink/renderer/core/paint/box_painter_base.cc
@@ -57,9 +57,8 @@ const PhysicalRect& rect, const BoxBackgroundPaintContext& bg_paint_context, BackgroundBleedAvoidance bleed) { - FillLayerOcclusionOutputList reversed_paint_list; - bool should_draw_background_in_separate_buffer = - CalculateFillLayerOcclusionCulling(reversed_paint_list, fill_layer); + auto [should_draw_background_in_separate_buffer, last_layer] = + AnalyzeFillLayersForPainting(fill_layer); // TODO(trchen): We can optimize out isolation group if we have a // non-transparent background color and the bottom layer encloses all other @@ -68,9 +67,12 @@ if (should_draw_background_in_separate_buffer) context.BeginLayer(); - for (auto* const paint : base::Reversed(reversed_paint_list)) { - PaintFillLayer(paint_info, c, *paint, rect, bleed, bg_paint_context); - } + FillLayer::IterateFillLayersInReverseOrder( + &fill_layer, last_layer, + [this, paint_info, c, rect, bleed, + bg_paint_context](const FillLayer& paint) { + PaintFillLayer(paint_info, c, paint, rect, bleed, bg_paint_context); + }); if (should_draw_background_in_separate_buffer) context.EndLayer(); @@ -459,13 +461,11 @@ !document.GetSettings()->GetShouldPrintBackgrounds()); } -bool BoxPainterBase::CalculateFillLayerOcclusionCulling( - FillLayerOcclusionOutputList& reversed_paint_list, +std::pair<bool, const FillLayer*> BoxPainterBase::AnalyzeFillLayersForPainting( const FillLayer& fill_layer) { bool is_non_associative = false; - for (auto* current_layer = &fill_layer; current_layer; - current_layer = current_layer->Next()) { - reversed_paint_list.push_back(current_layer); + const FillLayer* current_layer = &fill_layer; + for (; current_layer; current_layer = current_layer->Next()) { // Stop traversal when an opaque layer is encountered. // FIXME : It would be possible for the following occlusion culling test to // be more aggressive on layers with no repeat by testing whether the image @@ -488,7 +488,7 @@ break; } } - return is_non_associative; + return {is_non_associative, current_layer}; } BoxPainterBase::FillLayerInfo::FillLayerInfo(
diff --git a/third_party/blink/renderer/core/paint/box_painter_base.h b/third_party/blink/renderer/core/paint/box_painter_base.h index 9bd2debb..eddac0d6 100644 --- a/third_party/blink/renderer/core/paint/box_painter_base.h +++ b/third_party/blink/renderer/core/paint/box_painter_base.h
@@ -100,13 +100,14 @@ static bool ShouldForceWhiteBackgroundForPrintEconomy(const Document&, const ComputedStyle&); - typedef Vector<const FillLayer*, 8> FillLayerOcclusionOutputList; - // Returns true if the result fill layers have non-associative blending or - // compositing mode. (i.e. The rendering will be different without creating - // isolation group by context.saveLayer().) Note that the output list will be - // in top-bottom order. - bool CalculateFillLayerOcclusionCulling( - FillLayerOcclusionOutputList& reversed_paint_list, + // Analyzes the fill layers to determine painting requirements. + // Returns a pair containing: + // - bool: True if the layers require an isolation group (a separate buffer) + // due to non-associative blending modes. + // - const FillLayer*: The last layer to be painted. Subsequent layers are + // occluded and can be culled. This will be the last layer in the list + // if no occlusion occurs. + std::pair<bool, const FillLayer*> AnalyzeFillLayersForPainting( const FillLayer&); static bool ShouldSkipPaintUnderInvalidationChecking(const LayoutBox&);
diff --git a/third_party/blink/renderer/core/paint/view_painter.cc b/third_party/blink/renderer/core/paint/view_painter.cc index 1d33ec8..2ae24c8 100644 --- a/third_party/blink/renderer/core/paint/view_painter.cc +++ b/third_party/blink/renderer/core/paint/view_painter.cc
@@ -374,13 +374,10 @@ recorder.UniteVisualRect(paint_rect); - GC_PLUGIN_IGNORE("crbug.com/446536462") - BoxPainterBase::FillLayerOcclusionOutputList reversed_paint_list; - bool should_draw_background_in_separate_buffer = + const FillLayer& background_layers = style.BackgroundLayers(); + auto [should_draw_background_in_separate_buffer, last_background_layer] = BoxModelObjectPainter(layout_view) - .CalculateFillLayerOcclusionCulling(reversed_paint_list, - style.BackgroundLayers()); - DCHECK(reversed_paint_list.size()); + .AnalyzeFillLayersForPainting(background_layers); if (painted_separate_effect) { should_draw_background_in_separate_buffer = true; @@ -434,11 +431,14 @@ BoxBackgroundPaintContext bg_paint_context(layout_view, &box_fragment_, background_image_offset); BoxModelObjectPainter box_model_painter(layout_view); - for (const auto* fill_layer : base::Reversed(reversed_paint_list)) { - box_model_painter.PaintFillLayer(paint_info, Color(), *fill_layer, - PhysicalRect(paint_rect), - kBackgroundBleedNone, bg_paint_context); - } + FillLayer::IterateFillLayersInReverseOrder( + &background_layers, last_background_layer, + [&box_model_painter, paint_info, paint_rect, + bg_paint_context](const FillLayer& fill_layer) { + box_model_painter.PaintFillLayer( + paint_info, Color(), fill_layer, PhysicalRect(paint_rect), + kBackgroundBleedNone, bg_paint_context); + }); if (should_draw_background_in_separate_buffer && !painted_separate_effect) context.EndLayer();
diff --git a/third_party/blink/renderer/core/script/pending_import_map.cc b/third_party/blink/renderer/core/script/pending_import_map.cc index 35ce13c0..a29b2e6d 100644 --- a/third_party/blink/renderer/core/script/pending_import_map.cc +++ b/third_party/blink/renderer/core/script/pending_import_map.cc
@@ -41,12 +41,7 @@ // href="https://html.spec.whatwg.org/C#register-an-import-map"> This is // parallel to PendingScript::ExecuteScriptBlock(). void PendingImportMap::RegisterImportMap() { - // TODO(crbug.com/364917757): I don't think this ever happens, so we can - // replace this with a CHECK. - if (!import_map_) { - element_->DispatchErrorEvent(); - return; - } + CHECK(import_map_); // TODO(crbug.com/364917757): This step is no longer in the spec, and it's not // clear when this can actually happen.
diff --git a/third_party/blink/renderer/core/style/fill_layer.h b/third_party/blink/renderer/core/style/fill_layer.h index 8d0917ea..ea1a6dd 100644 --- a/third_party/blink/renderer/core/style/fill_layer.h +++ b/third_party/blink/renderer/core/style/fill_layer.h
@@ -300,6 +300,18 @@ } static StyleImage* InitialFillImage(EFillLayerType) { return nullptr; } + template <typename Callback> + static void IterateFillLayersInReverseOrder(const FillLayer* start, + const FillLayer* end, + Callback callback) { + if (start != end) { + IterateFillLayersInReverseOrder(start->Next(), end, callback); + } + if (start) { + callback(*start); + } + } + private: friend class ComputedStyle;
diff --git a/third_party/blink/renderer/core/style/style_border_shape.h b/third_party/blink/renderer/core/style/style_border_shape.h index 8934875..fc0f595 100644 --- a/third_party/blink/renderer/core/style/style_border_shape.h +++ b/third_party/blink/renderer/core/style/style_border_shape.h
@@ -7,6 +7,7 @@ #include "base/memory/values_equivalent.h" #include "third_party/blink/renderer/core/style/basic_shapes.h" +#include "third_party/blink/renderer/core/style/computed_style_constants.h" #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/heap/member.h" @@ -17,8 +18,14 @@ public: // A border shape always has an inner and outer shape, though in case they are // identical certain operations such as filling between them can be skipped. - explicit StyleBorderShape(BasicShape& outer, BasicShape* inner = nullptr) - : outer_(&outer), inner_(inner ? inner : &outer) {} + explicit StyleBorderShape(BasicShape& outer, + BasicShape* inner = nullptr, + CoordBox outer_coord_box = CoordBox::kBorderBox, + CoordBox inner_coord_box = CoordBox::kBorderBox) + : outer_(&outer), + inner_(inner ? inner : &outer), + outer_coord_box_(outer_coord_box), + inner_coord_box_(inner_coord_box) {} void Trace(Visitor* visitor) const { visitor->Trace(outer_); @@ -32,14 +39,21 @@ const BasicShape& OuterShape() const { return *outer_; } const BasicShape& InnerShape() const { return *inner_; } + CoordBox OuterCoordBox() const { return outer_coord_box_; } + CoordBox InnerCoordBox() const { return inner_coord_box_; } + bool operator==(const StyleBorderShape& o) const { return base::ValuesEquivalent(outer_, o.outer_) && - base::ValuesEquivalent(inner_, o.inner_); + base::ValuesEquivalent(inner_, o.inner_) && + outer_coord_box_ == o.outer_coord_box_ && + inner_coord_box_ == o.inner_coord_box_; } private: Member<BasicShape> outer_; Member<BasicShape> inner_; + CoordBox outer_coord_box_; + CoordBox inner_coord_box_; }; } // namespace blink
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 9074eb83..9dcceb3f 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
@@ -1623,6 +1623,31 @@ HitTestResult result(request, location); document.GetLayoutView()->HitTest(location, result); + // TODO(averge): At this point, hit_nodes may contain duplicates due to + // multiple passes over the same node while hit testing. These need to + // be filtered out. The most correct approach is probably to keep the first + // occurrence of each node, because it's more likely it was added in a later + // paint phase, which is more representative of what the page actually looks + // like to the user (or actor). + // + // result.ListBasedTestResult() already returns a NodeSet with predictable + // iteration order based on order of insertion, which is a fancy way of saying + // it already handles duplicates in exactly the way we need. We should eval + // using the NodeSet result directly, and if we see improvement, remove + // hit_nodes and the associated callback entirely. + if (base::FeatureList::IsEnabled( + blink::features::kAIPageContentZOrderEarlyFiltering)) { + std::vector<DOMNodeId> nodes_from_result; + for (auto& gc_member : result.ListBasedTestResult()) { + Node& node = *gc_member; + if (node.GetLayoutObject()) { + nodes_from_result.push_back(DOMNodeIds::IdForNode(&node)); + } + } + + hit_nodes = nodes_from_result; + } + int32_t next_z_order = 1; std::for_each(hit_nodes.rbegin(), hit_nodes.rend(), [&](auto node_id) { if (dom_node_to_z_order_.contains(node_id)) {
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 6ee27953..3d17e98 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
@@ -7,6 +7,7 @@ #include <cstddef> #include "base/strings/stringprintf.h" +#include "base/test/with_feature_override.h" #include "mojo/public/cpp/test_support/test_utils.h" #include "testing/gtest/include/gtest/gtest.h" #include "third_party/blink/public/common/frame/frame_ad_evidence.h" @@ -3285,262 +3286,6 @@ mojom::blink::AIPageContentAnnotatedRole::kPaidContent)); } -TEST_F(AIPageContentAgentTest, AnchorInInlineWithFloatingSiblingHitTesting) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <span>" - " <a href='https://www.google.com'>" - " <div style='position: relative; float: left;'>text in div</div>" - " <span>text</span>" - " </a>" - " </span>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - - const auto& root = ContentRootNode(); - const auto& span = *root.children_nodes.at(0); - const auto& anchor = *span.children_nodes.at(0); - - CheckAnchorNode(anchor, blink::KURL("https://www.google.com/"), {}); - ASSERT_TRUE(anchor.content_attributes->node_interaction_info); - EXPECT_TRUE(anchor.content_attributes->node_interaction_info - ->document_scoped_z_order); -} - -TEST_F(AIPageContentAgentTest, HitTestElementsBasic) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <p style='background:red'>Text 1</p>" - " <p>Text 2</p>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - - // The tree should look as follows, with the given z order. - // root - 1 - // |_html - 2 - // |_body - 3 - // |_p - 4 - // | |_Text1 - 6 - // |_p - 5 - // |_Text2 - 7 - const auto& root = *Content()->root_node; - - ASSERT_TRUE(root.content_attributes->node_interaction_info); - EXPECT_EQ( - root.content_attributes->node_interaction_info->document_scoped_z_order, - 1); - - ASSERT_EQ(root.children_nodes.size(), 1u); - const auto& html = *root.children_nodes.at(0); - EXPECT_EQ( - html.content_attributes->node_interaction_info->document_scoped_z_order, - 2); - - ASSERT_EQ(html.children_nodes.size(), 1u); - const auto& body = *html.children_nodes.at(0); - EXPECT_EQ( - body.content_attributes->node_interaction_info->document_scoped_z_order, - 3); - - ASSERT_EQ(body.children_nodes.size(), 2u); - const auto& p1 = *body.children_nodes.at(0); - EXPECT_EQ( - p1.content_attributes->node_interaction_info->document_scoped_z_order, 4); - - const auto& p2 = *body.children_nodes.at(1); - EXPECT_EQ( - p2.content_attributes->node_interaction_info->document_scoped_z_order, 5); - - ASSERT_EQ(p1.children_nodes.size(), 1u); - const auto& text1 = *p1.children_nodes.at(0); - CheckTextNode(text1, "Text 1"); - EXPECT_EQ( - text1.content_attributes->node_interaction_info->document_scoped_z_order, - 6); - - ASSERT_EQ(p2.children_nodes.size(), 1u); - const auto& text2 = *p2.children_nodes.at(0); - CheckTextNode(text2, "Text 2"); - EXPECT_EQ( - text2.content_attributes->node_interaction_info->document_scoped_z_order, - 7); -} - -TEST_F(AIPageContentAgentTest, HitTestElementsFixedPos) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <p style='position: fixed; top: 10px;'>Text 1</p>" - " <p>Text 2</p>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - - const auto& root = ContentRootNode(); - ASSERT_EQ(root.children_nodes.size(), 2u); - - // The first node is now on top. - const auto& p1 = *root.children_nodes.at(0); - ASSERT_TRUE(p1.content_attributes->node_interaction_info); - ASSERT_TRUE( - p1.content_attributes->node_interaction_info->document_scoped_z_order); - EXPECT_EQ( - p1.content_attributes->node_interaction_info->document_scoped_z_order, 6); - - const auto& p2 = *root.children_nodes.at(1); - ASSERT_TRUE(p2.content_attributes->node_interaction_info); - ASSERT_TRUE( - p2.content_attributes->node_interaction_info->document_scoped_z_order); - EXPECT_EQ( - p2.content_attributes->node_interaction_info->document_scoped_z_order, 4); -} - -TEST_F(AIPageContentAgentTest, HitTestElementsPointerNone) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <p style='pointer-events:none'>Text 1</p>" - " <p>Text 2</p>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - const auto& root = ContentRootNode(); - ASSERT_EQ(root.children_nodes.size(), 2u); - - // The first node is not actionable anymore. - const auto& p1 = *root.children_nodes.at(0); - EXPECT_FALSE(p1.content_attributes->node_interaction_info); - - const auto& p2 = *root.children_nodes.at(1); - ASSERT_TRUE(p2.content_attributes->node_interaction_info); - ASSERT_TRUE( - p2.content_attributes->node_interaction_info->document_scoped_z_order); -} - -TEST_F(AIPageContentAgentTest, HitTestElementsOffscreen) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <p style='cursor:pointer; position:fixed; top:110vh;'>Text 1</p>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - const auto& root = ContentRootNode(); - ASSERT_EQ(root.children_nodes.size(), 1u); - - // The first node is actionable but not in viewport - const auto& p1 = *root.children_nodes.at(0); - ASSERT_TRUE(p1.content_attributes->node_interaction_info); - const auto& interaction_info = *p1.content_attributes->node_interaction_info; - EXPECT_FALSE(interaction_info.clickability_reasons.empty()); - EXPECT_FALSE(interaction_info.document_scoped_z_order); -} - -TEST_F(AIPageContentAgentTest, HitTestElementsIframe) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - R"HTML( - <body> - <iframe srcdoc='<p>Text 1</p>'></iframe> - <p>Text 2</p> - </body> - )HTML", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - - // The iframe and outer p have z order relative to each other. - GetAIPageContentWithActionableElements(); - - const auto& root = ContentRootNode(); - ASSERT_EQ(root.children_nodes.size(), 2u); - - const auto& iframe = *root.children_nodes.at(0); - ASSERT_TRUE(iframe.content_attributes->node_interaction_info); - ASSERT_TRUE(iframe.content_attributes->node_interaction_info - ->document_scoped_z_order); - - const auto& p = *root.children_nodes.at(1); - ASSERT_TRUE(p.content_attributes->node_interaction_info); - ASSERT_TRUE( - p.content_attributes->node_interaction_info->document_scoped_z_order); - - EXPECT_GT( - *iframe.content_attributes->node_interaction_info - ->document_scoped_z_order, - *p.content_attributes->node_interaction_info->document_scoped_z_order); - - ASSERT_EQ(iframe.children_nodes.size(), 1u); - const auto& doc_inside_iframe = *iframe.children_nodes.at(0); - ASSERT_TRUE(doc_inside_iframe.content_attributes->node_interaction_info); - ASSERT_TRUE(doc_inside_iframe.content_attributes->node_interaction_info - ->document_scoped_z_order); - EXPECT_EQ(*doc_inside_iframe.content_attributes->node_interaction_info - ->document_scoped_z_order, - 1); -} - -TEST_F(AIPageContentAgentTest, OverflowHiddenGeometry) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <div style='width: 100px; height: 100px; overflow-y: hidden;'>" - " <article style='width: 50px; height: 300px;'></article>" - " </div>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - - const auto& outer = ContentRootNode().children_nodes[0]; - const auto& article = outer->children_nodes[0]; - CheckAnnotatedRole(*article, - mojom::blink::AIPageContentAnnotatedRole::kArticle); - - EXPECT_GT(*article->content_attributes->node_interaction_info - ->document_scoped_z_order, - *outer->content_attributes->node_interaction_info - ->document_scoped_z_order); - - CheckGeometry(*outer, gfx::Rect(8, 8, 100, 100), gfx::Rect(8, 8, 100, 100)); - CheckGeometry(*article, gfx::Rect(8, 8, 50, 300), gfx::Rect(8, 8, 50, 100)); -} - -TEST_F(AIPageContentAgentTest, OverflowVisibleGeometry) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <section style='width: 100px; height: 100px; overflow-y: visible;'>" - " <article style='width: 50px; height: 300px;'></article>" - " </section>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - - const auto& outer = ContentRootNode().children_nodes[0]; - const auto& article = outer->children_nodes[0]; - CheckAnnotatedRole(*article, - mojom::blink::AIPageContentAnnotatedRole::kArticle); - - EXPECT_GT(*article->content_attributes->node_interaction_info - ->document_scoped_z_order, - *outer->content_attributes->node_interaction_info - ->document_scoped_z_order); - - CheckGeometry(*outer, gfx::Rect(8, 8, 100, 100), gfx::Rect(8, 8, 100, 100)); - CheckGeometry(*article, gfx::Rect(8, 8, 50, 300), gfx::Rect(8, 8, 50, 300)); -} - TEST_F(AIPageContentAgentTest, BlurGeometry) { frame_test_helpers::LoadHTMLString( helper_.LocalMainFrame(), @@ -3579,35 +3324,6 @@ gfx::Rect(200, 200, 100, 100)); } -TEST_F(AIPageContentAgentTest, HitTestElementsRelativePos) { - frame_test_helpers::LoadHTMLString( - helper_.LocalMainFrame(), - "<body>" - " <section style='width: 100px; height: 100px; position: relative; " - "overflow: clip;'>" - " <article style='width: 50px; height: 50px; position: absolute; " - "left: " - "150px; top:0px;'></article>" - " </section>" - "</body>", - url_test_helpers::ToKURL("http://foobar.com")); - - GetAIPageContentWithActionableElements(); - - const auto& outer = ContentRootNode().children_nodes[0]; - const auto& article = outer->children_nodes[0]; - CheckAnnotatedRole(*article, - mojom::blink::AIPageContentAnnotatedRole::kArticle); - - EXPECT_GT(*article->content_attributes->node_interaction_info - ->document_scoped_z_order, - *outer->content_attributes->node_interaction_info - ->document_scoped_z_order); - - CheckGeometry(*outer, gfx::Rect(8, 8, 100, 100), gfx::Rect(8, 8, 100, 100)); - CheckGeometry(*article, gfx::Rect(158, 8, 50, 50), gfx::Rect()); -} - TEST_F(AIPageContentAgentTest, GeometryTransform) { frame_test_helpers::LoadHTMLString( helper_.LocalMainFrame(), @@ -4589,5 +4305,488 @@ CheckGeometry(div_node, gfx::Rect(), gfx::Rect()); } +// Tests hit-testing and z-order computations for AIPageContentAgent. +class AIPageContentAgentTestZOrder : public base::test::WithFeatureOverride, + public AIPageContentAgentTest { + public: + AIPageContentAgentTestZOrder() + : base::test::WithFeatureOverride( + blink::features::kAIPageContentZOrderEarlyFiltering) {} + ~AIPageContentAgentTestZOrder() override = default; +}; + +TEST_P(AIPageContentAgentTestZOrder, + AnchorInInlineWithFloatingSiblingHitTesting) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <span>" + " <a href='https://www.google.com'>" + " <div style='position: relative; float: left;'>text in div</div>" + " <span>text</span>" + " </a>" + " </span>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + const auto& root = ContentRootNode(); + const auto& span = *root.children_nodes.at(0); + const auto& anchor = *span.children_nodes.at(0); + + CheckAnchorNode(anchor, blink::KURL("https://www.google.com/"), {}); + ASSERT_TRUE(anchor.content_attributes->node_interaction_info); + EXPECT_TRUE(anchor.content_attributes->node_interaction_info + ->document_scoped_z_order); +} + +TEST_P(AIPageContentAgentTestZOrder, HitTestElementsBasic) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <p style='background:red'>Text 1</p>" + " <p>Text 2</p>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + const auto& root = *Content()->root_node; + + ASSERT_TRUE(root.content_attributes->node_interaction_info); + EXPECT_EQ( + root.content_attributes->node_interaction_info->document_scoped_z_order, + 1); + + ASSERT_EQ(root.children_nodes.size(), 1u); + const auto& html = *root.children_nodes.at(0); + EXPECT_EQ( + html.content_attributes->node_interaction_info->document_scoped_z_order, + 2); + + ASSERT_EQ(html.children_nodes.size(), 1u); + const auto& body = *html.children_nodes.at(0); + EXPECT_EQ( + body.content_attributes->node_interaction_info->document_scoped_z_order, + 3); + + if (IsParamFeatureEnabled()) { + // When relying directly on the hit test result for z order, the tree should + // look as follows, with the given z order. This is consistent with "tree + // order" depth-first traversal as defined in the CSS spec: + // https://www.w3.org/TR/CSS2/zindex.html + // root - 1 + // |_html - 2 + // |_body - 3 + // |_p - 4 + // | |_Text1 - 5 + // |_p - 6 + // |_Text2 - 7 + ASSERT_EQ(body.children_nodes.size(), 2u); + const auto& p1 = *body.children_nodes.at(0); + EXPECT_EQ( + p1.content_attributes->node_interaction_info->document_scoped_z_order, + 4); + + ASSERT_EQ(p1.children_nodes.size(), 1u); + const auto& text1 = *p1.children_nodes.at(0); + CheckTextNode(text1, "Text 1"); + EXPECT_EQ(text1.content_attributes->node_interaction_info + ->document_scoped_z_order, + 5); + + const auto& p2 = *body.children_nodes.at(1); + EXPECT_EQ( + p2.content_attributes->node_interaction_info->document_scoped_z_order, + 6); + + ASSERT_EQ(p2.children_nodes.size(), 1u); + const auto& text2 = *p2.children_nodes.at(0); + CheckTextNode(text2, "Text 2"); + EXPECT_EQ(text2.content_attributes->node_interaction_info + ->document_scoped_z_order, + 7); + } else { + // The tree should look as follows, with the given z order. + // root - 1 + // |_html - 2 + // |_body - 3 + // |_p - 4 + // | |_Text1 - 6 + // |_p - 5 + // |_Text2 - 7 + ASSERT_EQ(body.children_nodes.size(), 2u); + const auto& p1 = *body.children_nodes.at(0); + EXPECT_EQ( + p1.content_attributes->node_interaction_info->document_scoped_z_order, + 4); + + const auto& p2 = *body.children_nodes.at(1); + EXPECT_EQ( + p2.content_attributes->node_interaction_info->document_scoped_z_order, + 5); + + ASSERT_EQ(p1.children_nodes.size(), 1u); + const auto& text1 = *p1.children_nodes.at(0); + CheckTextNode(text1, "Text 1"); + EXPECT_EQ(text1.content_attributes->node_interaction_info + ->document_scoped_z_order, + 6); + + ASSERT_EQ(p2.children_nodes.size(), 1u); + const auto& text2 = *p2.children_nodes.at(0); + CheckTextNode(text2, "Text 2"); + EXPECT_EQ(text2.content_attributes->node_interaction_info + ->document_scoped_z_order, + 7); + } +} + +TEST_P(AIPageContentAgentTestZOrder, HitTestElementsFixedPos) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <p style='position: fixed; top: 10px;'>Text 1</p>" + " <p>Text 2</p>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + const auto& root = ContentRootNode(); + ASSERT_EQ(root.children_nodes.size(), 2u); + + // The first node is now on top. + const auto& p1 = *root.children_nodes.at(0); + ASSERT_TRUE(p1.content_attributes->node_interaction_info); + ASSERT_TRUE( + p1.content_attributes->node_interaction_info->document_scoped_z_order); + EXPECT_EQ( + p1.content_attributes->node_interaction_info->document_scoped_z_order, 6); + + const auto& p2 = *root.children_nodes.at(1); + ASSERT_TRUE(p2.content_attributes->node_interaction_info); + ASSERT_TRUE( + p2.content_attributes->node_interaction_info->document_scoped_z_order); + EXPECT_EQ( + p2.content_attributes->node_interaction_info->document_scoped_z_order, 4); +} + +TEST_P(AIPageContentAgentTestZOrder, HitTestElementsPointerNone) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <p style='pointer-events:none'>Text 1</p>" + " <p>Text 2</p>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + const auto& root = ContentRootNode(); + ASSERT_EQ(root.children_nodes.size(), 2u); + + // The first node is not actionable anymore. + const auto& p1 = *root.children_nodes.at(0); + EXPECT_FALSE(p1.content_attributes->node_interaction_info); + + const auto& p2 = *root.children_nodes.at(1); + ASSERT_TRUE(p2.content_attributes->node_interaction_info); + ASSERT_TRUE( + p2.content_attributes->node_interaction_info->document_scoped_z_order); +} + +TEST_P(AIPageContentAgentTestZOrder, HitTestElementsOffscreen) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <p style='cursor:pointer; position:fixed; top:110vh;'>Text 1</p>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + const auto& root = ContentRootNode(); + ASSERT_EQ(root.children_nodes.size(), 1u); + + // The first node is actionable but not in viewport + const auto& p1 = *root.children_nodes.at(0); + ASSERT_TRUE(p1.content_attributes->node_interaction_info); + const auto& interaction_info = *p1.content_attributes->node_interaction_info; + EXPECT_FALSE(interaction_info.clickability_reasons.empty()); + EXPECT_FALSE(interaction_info.document_scoped_z_order); +} + +TEST_P(AIPageContentAgentTestZOrder, HitTestElementsIframe) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + R"HTML( + <body> + <iframe srcdoc='<p>Text 1</p>'></iframe> + <p>Text 2</p> + </body> + )HTML", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + // The iframe and outer p have z order relative to each other. + GetAIPageContentWithActionableElements(); + + const auto& root = ContentRootNode(); + ASSERT_EQ(root.children_nodes.size(), 2u); + + const auto& iframe = *root.children_nodes.at(0); + ASSERT_TRUE(iframe.content_attributes->node_interaction_info); + ASSERT_TRUE(iframe.content_attributes->node_interaction_info + ->document_scoped_z_order); + + const auto& p = *root.children_nodes.at(1); + ASSERT_TRUE(p.content_attributes->node_interaction_info); + ASSERT_TRUE( + p.content_attributes->node_interaction_info->document_scoped_z_order); + + if (IsParamFeatureEnabled()) { + // If we're respecting tree-order traversal when computing z-order, the + // iframe will have a lower z-order because it is the first child. + EXPECT_LT( + *iframe.content_attributes->node_interaction_info + ->document_scoped_z_order, + *p.content_attributes->node_interaction_info->document_scoped_z_order); + } else { + EXPECT_GT( + *iframe.content_attributes->node_interaction_info + ->document_scoped_z_order, + *p.content_attributes->node_interaction_info->document_scoped_z_order); + } + + ASSERT_EQ(iframe.children_nodes.size(), 1u); + const auto& doc_inside_iframe = *iframe.children_nodes.at(0); + ASSERT_TRUE(doc_inside_iframe.content_attributes->node_interaction_info); + ASSERT_TRUE(doc_inside_iframe.content_attributes->node_interaction_info + ->document_scoped_z_order); + EXPECT_EQ(*doc_inside_iframe.content_attributes->node_interaction_info + ->document_scoped_z_order, + 1); +} + +TEST_P(AIPageContentAgentTestZOrder, OverflowHiddenGeometry) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <div style='width: 100px; height: 100px; overflow-y: hidden;'>" + " <article style='width: 50px; height: 300px;'></article>" + " </div>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + const auto& outer = ContentRootNode().children_nodes[0]; + const auto& article = outer->children_nodes[0]; + CheckAnnotatedRole(*article, + mojom::blink::AIPageContentAnnotatedRole::kArticle); + + EXPECT_GT(*article->content_attributes->node_interaction_info + ->document_scoped_z_order, + *outer->content_attributes->node_interaction_info + ->document_scoped_z_order); + + CheckGeometry(*outer, gfx::Rect(8, 8, 100, 100), gfx::Rect(8, 8, 100, 100)); + CheckGeometry(*article, gfx::Rect(8, 8, 50, 300), gfx::Rect(8, 8, 50, 100)); +} + +TEST_P(AIPageContentAgentTestZOrder, OverflowVisibleGeometry) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <section style='width: 100px; height: 100px; overflow-y: visible;'>" + " <article style='width: 50px; height: 300px;'></article>" + " </section>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + const auto& outer = ContentRootNode().children_nodes[0]; + const auto& article = outer->children_nodes[0]; + CheckAnnotatedRole(*article, + mojom::blink::AIPageContentAnnotatedRole::kArticle); + + EXPECT_GT(*article->content_attributes->node_interaction_info + ->document_scoped_z_order, + *outer->content_attributes->node_interaction_info + ->document_scoped_z_order); + + CheckGeometry(*outer, gfx::Rect(8, 8, 100, 100), gfx::Rect(8, 8, 100, 100)); + CheckGeometry(*article, gfx::Rect(8, 8, 50, 300), gfx::Rect(8, 8, 50, 300)); +} + +TEST_P(AIPageContentAgentTestZOrder, HitTestElementsRelativePos) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + "<body>" + " <section style='width: 100px; height: 100px; position: relative; " + "overflow: clip;'>" + " <article style='width: 50px; height: 50px; position: absolute; " + "left: " + "150px; top:0px;'></article>" + " </section>" + "</body>", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + const auto& outer = ContentRootNode().children_nodes[0]; + const auto& article = outer->children_nodes[0]; + CheckAnnotatedRole(*article, + mojom::blink::AIPageContentAnnotatedRole::kArticle); + + EXPECT_GT(*article->content_attributes->node_interaction_info + ->document_scoped_z_order, + *outer->content_attributes->node_interaction_info + ->document_scoped_z_order); + + CheckGeometry(*outer, gfx::Rect(8, 8, 100, 100), gfx::Rect(8, 8, 100, 100)); + CheckGeometry(*article, gfx::Rect(158, 8, 50, 50), gfx::Rect()); +} + +TEST_P(AIPageContentAgentTestZOrder, HitTestElementsAnchorWithSpanParent) { + frame_test_helpers::LoadHTMLString( + helper_.LocalMainFrame(), + R"HTML( + <body> + <span id="target-span"> + <a id="link" href="https://example.com"> + <span id="inner-span"> + This is the inner span. + </span> + <div id="inner-div"> + This is the inner div. + </div> + </a> + </span> + </body> + )HTML", + url_test_helpers::ToKURL("http://foobar.com")); + + GetAIPageContentWithActionableElements(); + + const auto& root = *Content()->root_node; + EXPECT_EQ( + root.content_attributes->node_interaction_info->document_scoped_z_order, + 1); + ASSERT_EQ(root.children_nodes.size(), 1u); + + const auto& html = *root.children_nodes.at(0); + EXPECT_EQ( + html.content_attributes->node_interaction_info->document_scoped_z_order, + 2); + ASSERT_EQ(html.children_nodes.size(), 1u); + + const auto& body = *html.children_nodes.at(0); + EXPECT_EQ( + body.content_attributes->node_interaction_info->document_scoped_z_order, + 3); + ASSERT_EQ(body.children_nodes.size(), 1u); + + if (IsParamFeatureEnabled()) { + // When filtering for duplicate hit test nodes early, the resulting z-order + // will follow "tree order", which is depth-first. The resulting tree with + // corresponding z-order will be: + // root - 1 + // |_html - 2 + // |_body - 3 + // |_span - 4 + // |_a - 5 + // |_span - 6 + // | |_text - 7 + // |_div - 8 + // |_text - 9 + + const auto& target_span = *body.children_nodes.at(0); + EXPECT_EQ(target_span.content_attributes->node_interaction_info + ->document_scoped_z_order, + 4); + ASSERT_EQ(target_span.children_nodes.size(), 1u); + + const auto& anchor = *target_span.children_nodes.at(0); + EXPECT_EQ(anchor.content_attributes->node_interaction_info + ->document_scoped_z_order, + 5); + ASSERT_EQ(anchor.children_nodes.size(), 2u); + + const auto& inner_span = *anchor.children_nodes.at(0); + EXPECT_EQ(inner_span.content_attributes->node_interaction_info + ->document_scoped_z_order, + 6); + ASSERT_EQ(inner_span.children_nodes.size(), 1u); + + const auto& span_text = *inner_span.children_nodes.at(0); + EXPECT_EQ(span_text.content_attributes->node_interaction_info + ->document_scoped_z_order, + 7); + + const auto& inner_div = *anchor.children_nodes.at(1); + EXPECT_EQ(inner_div.content_attributes->node_interaction_info + ->document_scoped_z_order, + 8); + ASSERT_EQ(inner_div.children_nodes.size(), 1u); + + const auto& div_text = *inner_div.children_nodes.at(0); + EXPECT_EQ(div_text.content_attributes->node_interaction_info + ->document_scoped_z_order, + 9); + } else { + // When we don't filter for duplicate hit test nodes early, the span + // containers will be included multiple times, causing tree order to be + // violated. The resulting tree with corresponding z-order will be: + // root - 1 + // |_html - 2 + // |_body - 3 + // |_span - 6 + // |_a - 4 + // |_span - 7 + // | |_text - 8 + // |_div - 5 + // |_text - 9 + + const auto& target_span = *body.children_nodes.at(0); + EXPECT_EQ(target_span.content_attributes->node_interaction_info + ->document_scoped_z_order, + 6); + ASSERT_EQ(target_span.children_nodes.size(), 1u); + + const auto& anchor = *target_span.children_nodes.at(0); + EXPECT_EQ(anchor.content_attributes->node_interaction_info + ->document_scoped_z_order, + 4); + ASSERT_EQ(anchor.children_nodes.size(), 2u); + + const auto& inner_span = *anchor.children_nodes.at(0); + EXPECT_EQ(inner_span.content_attributes->node_interaction_info + ->document_scoped_z_order, + 7); + ASSERT_EQ(inner_span.children_nodes.size(), 1u); + + const auto& span_text = *inner_span.children_nodes.at(0); + EXPECT_EQ(span_text.content_attributes->node_interaction_info + ->document_scoped_z_order, + 8); + + const auto& inner_div = *anchor.children_nodes.at(1); + EXPECT_EQ(inner_div.content_attributes->node_interaction_info + ->document_scoped_z_order, + 5); + ASSERT_EQ(inner_div.children_nodes.size(), 1u); + + const auto& div_text = *inner_div.children_nodes.at(0); + EXPECT_EQ(div_text.content_attributes->node_interaction_info + ->document_scoped_z_order, + 9); + } +} + +INSTANTIATE_FEATURE_OVERRIDE_TEST_SUITE(AIPageContentAgentTestZOrder); + } // namespace } // namespace blink
diff --git a/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.cc b/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.cc index 6a62f3eb2..ebba9d6 100644 --- a/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.cc +++ b/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.cc
@@ -61,21 +61,6 @@ } } -void ObserveDocument(WeakMember<Node>& observing, - MutationObserver* observer, - Element* document_element) { - if (observing.Get() == document_element) { - return; - } - observer->disconnect(); - MutationObserverInit* init = MutationObserverInit::Create(); - init->setChildList(true); - DummyExceptionStateForTesting exception_state; - observer->observe(document_element, init, exception_state); - DCHECK(!exception_state.HadException()); - observing = document_element; -} - template <typename ObserverSet, typename MutationObserver> bool UpdateObserver(Document* document, ObserverSet& observer_set, @@ -107,69 +92,7 @@ Member<FrameMetadataObserverRegistry> registry_; }; -class FrameMetadataObserverRegistry::PaidContentMutationObserver final - : public MutationObserver::Delegate { - public: - explicit PaidContentMutationObserver(FrameMetadataObserverRegistry* registry); - void ObserveHead(HTMLHeadElement* head); - void ObserveDocument(Element* document_element); - - void Disconnect() { - observer_->disconnect(); - observing_ = nullptr; - registry_->DisconnectAllPaidContentAttributeObservers(); - } - - ExecutionContext* GetExecutionContext() const override { - return registry_->GetSupplementable()->GetExecutionContext(); - } - - void Deliver(const HeapVector<Member<MutationRecord>>& records, - MutationObserver&) override { - bool needs_update = false; - for (const auto& record : records) { - if (record->type() == "childList") { - for (unsigned i = 0; i < record->addedNodes()->length(); ++i) { - if (IsA<HTMLHeadElement>(record->addedNodes()->item(i))) { - registry_->OnPaidContentMetadataChanged(); - return; - } - } - for (unsigned i = 0; i < record->addedNodes()->length(); ++i) { - if (auto* script = - DynamicTo<HTMLScriptElement>(record->addedNodes()->item(i))) { - registry_->ObservePaidContentScriptAttributes(script); - needs_update = true; - } - } - for (unsigned i = 0; i < record->removedNodes()->length(); ++i) { - if (auto* script = DynamicTo<HTMLScriptElement>( - record->removedNodes()->item(i))) { - registry_->StopObservingPaidContentScriptAttributes(script); - needs_update = true; - } - } - } - } - - if (needs_update) { - registry_->OnPaidContentMetadataChanged(); - } - } - - void Trace(Visitor* visitor) const override { - visitor->Trace(registry_); - visitor->Trace(observer_); - visitor->Trace(observing_); - MutationObserver::Delegate::Trace(visitor); - } - - private: - Member<FrameMetadataObserverRegistry> registry_; - Member<MutationObserver> observer_; - WeakMember<Node> observing_; -}; class FrameMetadataObserverRegistry::MetaTagAttributeObserver final : public MutationObserver::Delegate { @@ -193,157 +116,14 @@ private: Member<FrameMetadataObserverRegistry> registry_; }; - -// TODO(gklassen): Use templated class to avoid duplication between this and -// PaidContentMutationObserver. -class FrameMetadataObserverRegistry::MetaTagsMutationObserver final - : public MutationObserver::Delegate { - public: - explicit MetaTagsMutationObserver(FrameMetadataObserverRegistry* registry); - - void ObserveHead(HTMLHeadElement* head); - void ObserveDocument(Element* document_element); - - void Disconnect() { - observer_->disconnect(); - observing_ = nullptr; - registry_->DisconnectAllAttributeObservers(); - } - - ExecutionContext* GetExecutionContext() const override { - return registry_->GetSupplementable()->GetExecutionContext(); - } - - void Deliver(const HeapVector<Member<MutationRecord>>& records, - MutationObserver&) override { - bool needs_update = false; - for (const auto& record : records) { - if (record->type() == "childList") { - // This handles the case where the <head> element itself is added to the - // doc. - for (unsigned i = 0; i < record->addedNodes()->length(); ++i) { - if (IsA<HTMLHeadElement>(record->addedNodes()->item(i))) { - registry_->OnMetaTagsChanged(); - return; - } - } - - // This handles meta tags added/removed inside the head. - for (unsigned i = 0; i < record->addedNodes()->length(); ++i) { - if (auto* meta = - DynamicTo<HTMLMetaElement>(record->addedNodes()->item(i))) { - registry_->ObserveMetaTagAttributes(meta); - needs_update = true; - } - } - for (unsigned i = 0; i < record->removedNodes()->length(); ++i) { - if (auto* meta = - DynamicTo<HTMLMetaElement>(record->removedNodes()->item(i))) { - registry_->StopObservingMetaTagAttributes(meta); - needs_update = true; - } - } - } - } - - if (needs_update) { - registry_->OnMetaTagsChanged(); - } - } - - void Trace(Visitor* visitor) const override { - visitor->Trace(registry_); - visitor->Trace(observer_); - visitor->Trace(observing_); - MutationObserver::Delegate::Trace(visitor); - } - - private: - Member<FrameMetadataObserverRegistry> registry_; - Member<MutationObserver> observer_; - WeakMember<Node> observing_; -}; - FrameMetadataObserverRegistry::PaidContentAttributeObserver:: PaidContentAttributeObserver(FrameMetadataObserverRegistry* registry) : registry_(registry) {} -FrameMetadataObserverRegistry::PaidContentMutationObserver:: - PaidContentMutationObserver(FrameMetadataObserverRegistry* registry) - : registry_(registry), observer_(MutationObserver::Create(this)) {} - -void FrameMetadataObserverRegistry::PaidContentMutationObserver::ObserveHead( - HTMLHeadElement* head) { - if (observing_.Get() == head) { - return; - } - Disconnect(); - - observing_ = head; - if (!head) { - return; - } - - // Start observing childList changes in the head. - MutationObserverInit* init = MutationObserverInit::Create(); - init->setChildList(true); - init->setSubtree(true); - DummyExceptionStateForTesting exception_state; - observer_->observe(head, init, exception_state); - DCHECK(!exception_state.HadException()); - - // For all existing script tags, set up attribute observers. - for (HTMLScriptElement& script : - Traversal<HTMLScriptElement>::ChildrenOf(*head)) { - registry_->ObservePaidContentScriptAttributes(&script); - } -} - -void FrameMetadataObserverRegistry::PaidContentMutationObserver:: - ObserveDocument(Element* document_element) { - ::blink::ObserveDocument(observing_, observer_.Get(), document_element); -} - -FrameMetadataObserverRegistry::MetaTagsMutationObserver:: - MetaTagsMutationObserver(FrameMetadataObserverRegistry* registry) - : registry_(registry), - observer_(MutationObserver::Create(this)) {} // NO LINT - FrameMetadataObserverRegistry::MetaTagAttributeObserver:: MetaTagAttributeObserver(FrameMetadataObserverRegistry* registry) : registry_(registry) {} -void FrameMetadataObserverRegistry::MetaTagsMutationObserver::ObserveHead( - HTMLHeadElement* head) { - if (observing_.Get() == head) { - return; - } - Disconnect(); - - observing_ = head; - if (!head) { - return; - } - - // Start observing childList changes in the head. - MutationObserverInit* init = MutationObserverInit::Create(); - init->setChildList(true); - init->setSubtree(true); - DummyExceptionStateForTesting exception_state; - observer_->observe(head, init, exception_state); - DCHECK(!exception_state.HadException()); - - // For all existing meta tags, set up attribute observers. - for (HTMLMetaElement& meta : Traversal<HTMLMetaElement>::ChildrenOf(*head)) { - registry_->ObserveMetaTagAttributes(&meta); - } -} - -void FrameMetadataObserverRegistry::MetaTagsMutationObserver::ObserveDocument( - Element* document_element) { - ::blink::ObserveDocument(observing_, observer_.Get(), document_element); -} - // static const char FrameMetadataObserverRegistry::kSupplementName[] = "FrameMetadataObserverRegistry"; @@ -379,9 +159,12 @@ paid_content_metadata_observers_(frame.DomWindow()), metatags_observers_(frame.DomWindow()), meta_tags_mutation_observer_( - MakeGarbageCollected<MetaTagsMutationObserver>(this)), + MakeGarbageCollected<FrameMetadataMutationObserver< + FrameMetadataObserverRegistry::MetaTagsObserverTraits>>(this)), paid_content_mutation_observer_( - MakeGarbageCollected<PaidContentMutationObserver>(this)) { + MakeGarbageCollected<FrameMetadataMutationObserver< + FrameMetadataObserverRegistry::PaidContentObserverTraits>>( + this)) { // Observer endpoints are explicitly closed when the other side is no // longer interested, so clean up the meta tags requested by that // observer at disconnect time.
diff --git a/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.h b/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.h index 683dc1d..e6e169e5 100644 --- a/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.h +++ b/third_party/blink/renderer/modules/content_extraction/frame_metadata_observer_registry.h
@@ -18,14 +18,19 @@ #include "third_party/blink/renderer/platform/heap/garbage_collected.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_receiver_set.h" #include "third_party/blink/renderer/platform/mojo/heap_mojo_remote_set.h" +#include "third_party/blink/renderer/bindings/core/v8/v8_mutation_observer_init.h" +#include "third_party/blink/renderer/core/dom/element.h" +#include "third_party/blink/renderer/core/dom/mutation_observer.h" +#include "third_party/blink/renderer/core/dom/mutation_record.h" +#include "third_party/blink/renderer/core/html/html_head_element.h" +#include "third_party/blink/renderer/core/html/html_meta_element.h" +#include "third_party/blink/renderer/core/html/html_script_element.h" +#include "third_party/blink/renderer/platform/bindings/exception_state.h" #include "third_party/blink/renderer/platform/supplementable.h" namespace blink { -class HTMLMetaElement; -class HTMLScriptElement; class LocalFrame; -class MutationObserver; // Registry used to Add Observers for when frame metadata changes. class MODULES_EXPORT FrameMetadataObserverRegistry final @@ -59,13 +64,161 @@ mojo::PendingRemote<mojom::blink::MetaTagsObserver> observer) override; private: + struct MetaTagsObserverTraits; + struct PaidContentObserverTraits; + template <typename Traits> + class FrameMetadataMutationObserver; + class DomContentLoadedListener; class MetaTagAttributeObserver; - class MetaTagsMutationObserver; class PaidContentAttributeObserver; - class PaidContentMutationObserver; friend class DomContentLoadedListener; + struct MetaTagsObserverTraits { + using ElementType = HTMLMetaElement; + static void OnChanged(FrameMetadataObserverRegistry* registry) { + registry->OnMetaTagsChanged(); + } + static void ObserveAttributes(FrameMetadataObserverRegistry* registry, + ElementType* element) { + registry->ObserveMetaTagAttributes(element); + } + static void StopObservingAttributes(FrameMetadataObserverRegistry* registry, + ElementType* element) { + registry->StopObservingMetaTagAttributes(element); + } + static void DisconnectAllAttributeObservers( + FrameMetadataObserverRegistry* registry) { + registry->DisconnectAllAttributeObservers(); + } + }; + + struct PaidContentObserverTraits { + using ElementType = HTMLScriptElement; + static void OnChanged(FrameMetadataObserverRegistry* registry) { + registry->OnPaidContentMetadataChanged(); + } + static void ObserveAttributes(FrameMetadataObserverRegistry* registry, + ElementType* element) { + registry->ObservePaidContentScriptAttributes(element); + } + static void StopObservingAttributes(FrameMetadataObserverRegistry* registry, + ElementType* element) { + registry->StopObservingPaidContentScriptAttributes(element); + } + static void DisconnectAllAttributeObservers( + FrameMetadataObserverRegistry* registry) { + registry->DisconnectAllPaidContentAttributeObservers(); + } + }; + + template <typename Traits> + class FrameMetadataMutationObserver final + : public MutationObserver::Delegate { + public: + explicit FrameMetadataMutationObserver( + FrameMetadataObserverRegistry* registry) + : registry_(registry), observer_(MutationObserver::Create(this)) {} + + void ObserveHead(HTMLHeadElement* head) { + if (observing_.Get() == head) { + return; + } + Disconnect(); + + observing_ = head; + if (!head) { + return; + } + + // Start observing childList changes in the head. + MutationObserverInit* init = MutationObserverInit::Create(); + init->setChildList(true); + init->setSubtree(true); + DummyExceptionStateForTesting exception_state; + observer_->observe(head, init, exception_state); + DCHECK(!exception_state.HadException()); + + // For all existing elements, set up attribute observers. + for (typename Traits::ElementType& element : + Traversal<typename Traits::ElementType>::ChildrenOf(*head)) { + Traits::ObserveAttributes(registry_, &element); + } + } + + void ObserveDocument(Element* document_element) { + if (observing_.Get() == document_element) { + return; + } + observer_->disconnect(); + MutationObserverInit* init = MutationObserverInit::Create(); + init->setChildList(true); + DummyExceptionStateForTesting exception_state; + observer_->observe(document_element, init, exception_state); + DCHECK(!exception_state.HadException()); + observing_ = document_element; + } + + void Disconnect() { + observer_->disconnect(); + observing_ = nullptr; + Traits::DisconnectAllAttributeObservers(registry_); + } + + ExecutionContext* GetExecutionContext() const override { + return registry_->GetSupplementable()->GetExecutionContext(); + } + + void Deliver(const HeapVector<Member<MutationRecord>>& records, + MutationObserver&) override { + bool needs_update = false; + for (const auto& record : records) { + if (record->type() == "childList") { + // This handles the case where the <head> element itself is added to + // the doc. + for (unsigned i = 0; i < record->addedNodes()->length(); ++i) { + if (IsA<HTMLHeadElement>(record->addedNodes()->item(i))) { + Traits::OnChanged(registry_); + return; + } + } + + // This handles meta tags added/removed inside the head. + for (unsigned i = 0; i < record->addedNodes()->length(); ++i) { + if (auto* element = DynamicTo<typename Traits::ElementType>( + record->addedNodes()->item(i))) { + Traits::ObserveAttributes(registry_, element); + needs_update = true; + } + } + for (unsigned i = 0; i < record->removedNodes()->length(); ++i) { + if (auto* element = DynamicTo<typename Traits::ElementType>( + record->removedNodes()->item(i))) { + Traits::StopObservingAttributes(registry_, element); + needs_update = true; + } + } + } + } + + if (needs_update) { + Traits::OnChanged(registry_); + } + } + + void Trace(Visitor* visitor) const override { + visitor->Trace(registry_); + visitor->Trace(observer_); + visitor->Trace(observing_); + MutationObserver::Delegate::Trace(visitor); + } + + private: + Member<FrameMetadataObserverRegistry> registry_; + Member<MutationObserver> observer_; + WeakMember<Node> observing_; + }; + void Bind(mojo::PendingReceiver<mojom::blink::FrameMetadataObserverRegistry> receiver); @@ -115,8 +268,10 @@ Member<DomContentLoadedListener> dom_content_loaded_observer_; - Member<MetaTagsMutationObserver> meta_tags_mutation_observer_; - Member<PaidContentMutationObserver> paid_content_mutation_observer_; + Member<FrameMetadataMutationObserver<MetaTagsObserverTraits>> + meta_tags_mutation_observer_; + Member<FrameMetadataMutationObserver<PaidContentObserverTraits>> + paid_content_mutation_observer_; HeapHashMap<WeakMember<HTMLMetaElement>, Member<MutationObserver>> meta_tag_attribute_observers_;
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc index c0a30d4..b01f6985 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_builder.cc
@@ -2792,6 +2792,15 @@ ending_padding, BlinkPaddingModeToComponent(options->mode().AsEnum()), label)); + // Pad becomes a no-op if input is a scalar and the paddings are all empty. + if (input->Rank() == 0) { + return BuildElementWiseUnaryOperator( + ml_context_->GetProperties(), this, exception_state, + blink_mojom::ElementWiseUnary::Kind::kIdentity, + ml_context_->GetProperties().data_type_limits.identity_input, input, + options); + } + base::expected<webnn::MLNumber, String> pad_value = ToMLNumberAsType(*options->value(), input->DataType()); if (!pad_value.has_value()) { @@ -3152,6 +3161,16 @@ webnn::ValidateSliceAndInferOutput(ml_context_->GetProperties(), input->Descriptor(), attributes)); + // Slice becomes a no-op if the input is a scalar and starts, sizes, strides + // are all empty. + if (input->Rank() == 0) { + return BuildElementWiseUnaryOperator( + ml_context_->GetProperties(), this, exception_state, + blink_mojom::ElementWiseUnary::Kind::kIdentity, + ml_context_->GetProperties().data_type_limits.identity_input, input, + options); + } + auto* slice = MakeGarbageCollected<MLSliceOperator>(this, starts, sizes, strides, options); MLOperand* output =
diff --git a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc index 5ff9371..c2b1f87b 100644 --- a/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc +++ b/third_party/blink/renderer/modules/ml/webnn/ml_graph_test.cc
@@ -354,20 +354,14 @@ class WebNNContextHelper { public: - WebNNContextHelper() = default; - ~WebNNContextHelper() = default; + WebNNContextHelper(); + ~WebNNContextHelper(); void ConnectWebNNTensorImpl(const blink::WebNNTensorToken& handle, - std::unique_ptr<FakeWebNNTensor> tensor) { - const auto it = tensor_impls_.find(handle); - ASSERT_TRUE(it == tensor_impls_.end()); - tensor_impls_.try_emplace(handle, std::move(tensor)); - } + std::unique_ptr<FakeWebNNTensor> tensor); void DisconnectAndDestroyWebNNTensorImpl( - const blink::WebNNTensorToken& handle) { - tensor_impls_.erase(handle); - } + const blink::WebNNTensorToken& handle); private: std::map<blink::WebNNTensorToken, std::unique_ptr<FakeWebNNTensor>> @@ -450,6 +444,22 @@ mojo_base::BigBuffer buffer_; }; +WebNNContextHelper::WebNNContextHelper() = default; +WebNNContextHelper::~WebNNContextHelper() = default; + +void WebNNContextHelper::ConnectWebNNTensorImpl( + const blink::WebNNTensorToken& handle, + std::unique_ptr<FakeWebNNTensor> tensor) { + const auto it = tensor_impls_.find(handle); + ASSERT_TRUE(it == tensor_impls_.end()); + tensor_impls_.try_emplace(handle, std::move(tensor)); +} + +void WebNNContextHelper::DisconnectAndDestroyWebNNTensorImpl( + const blink::WebNNTensorToken& handle) { + tensor_impls_.erase(handle); +} + class FakeWebNNGraphBuilder : public blink_mojom::WebNNGraphBuilder { public: explicit FakeWebNNGraphBuilder(MLGraphTest& helper) : helper_(helper) {}
diff --git a/third_party/blink/renderer/platform/BUILD.gn b/third_party/blink/renderer/platform/BUILD.gn index 9efd4e34..bcdcce2 100644 --- a/third_party/blink/renderer/platform/BUILD.gn +++ b/third_party/blink/renderer/platform/BUILD.gn
@@ -757,8 +757,6 @@ "fonts/segmented_font_data.h", "fonts/shaping/caching_word_shape_iterator.cc", "fonts/shaping/caching_word_shape_iterator.h", - "fonts/shaping/caching_word_shaper.cc", - "fonts/shaping/caching_word_shaper.h", "fonts/shaping/case_mapping_harfbuzz_buffer_filler.cc", "fonts/shaping/case_mapping_harfbuzz_buffer_filler.h", "fonts/shaping/font_features.cc",
diff --git a/third_party/blink/renderer/platform/fonts/font.cc b/third_party/blink/renderer/platform/fonts/font.cc index 99e0db40..7341702 100644 --- a/third_party/blink/renderer/platform/fonts/font.cc +++ b/third_party/blink/renderer/platform/fonts/font.cc
@@ -29,7 +29,7 @@ #include "third_party/blink/renderer/platform/fonts/font_cache.h" #include "third_party/blink/renderer/platform/fonts/font_fallback_list.h" #include "third_party/blink/renderer/platform/fonts/font_fallback_map.h" -#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" +#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_spacing.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h" @@ -264,7 +264,9 @@ if (mark.empty()) return GlyphData(); if (!RuntimeEnabledFeatures::EmphasisMarkShapeCacheEnabled()) { - return CachingWordShaper(*this).EmphasisMarkGlyphData(TextRun(mark)); + return CachingWordShapeIterator::ShapeWordWithoutSpacing(TextRun(mark), + this) + ->EmphasisMarkGlyphData(font_description_); } return EnsureFontFallbackList() ->GetOrCreateEmphasisMarkShape(*this, mark)
diff --git a/third_party/blink/renderer/platform/fonts/plain_text_node.cc b/third_party/blink/renderer/platform/fonts/plain_text_node.cc index 918b112..e8a24ed 100644 --- a/third_party/blink/renderer/platform/fonts/plain_text_node.cc +++ b/third_party/blink/renderer/platform/fonts/plain_text_node.cc
@@ -6,7 +6,6 @@ #include "third_party/blink/renderer/platform/fonts/character_range.h" #include "third_party/blink/renderer/platform/fonts/font.h" -#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h" #include "third_party/blink/renderer/platform/fonts/shaping/frame_shape_cache.h" #include "third_party/blink/renderer/platform/fonts/shaping/harfbuzz_shaper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" @@ -81,6 +80,76 @@ return {text.ToString(), maybe_bidi}; } +template <bool split_by_zws> +bool IsWordDelimiter(UChar ch) { + // As of 2025 March, Google Docs always wraps text with BiDi control + // characters, and they are replaced with ZWS for HarfBuzzShaper. + // Assuming ZWS as a word delimiter improves hit rate of a shape cache. + return ch == uchar::kSpace || ch == uchar::kTab || + (split_by_zws && ch == uchar::kZeroWidthSpace); +} + +unsigned NextWordEndIndex(StringView text, unsigned start_index) { + const unsigned length = text.length(); + if (start_index >= length) { + return 0; + } + + if (start_index + 1u == length || IsWordDelimiter<true>(text[start_index])) { + return start_index + 1; + } + + // 8Bit words end at IsWordDelimiter(). + if (text.Is8Bit()) { + for (unsigned i = start_index + 1;; ++i) { + if (i == length || IsWordDelimiter<false>(text[i])) { + return i; + } + } + } + + // Non-CJK/Emoji words end at IsWordDelimiter() or CJK/Emoji characters. + unsigned end = start_index; + UChar32 ch = text.CodePointAtAndNext(end); + if (!Character::IsCJKIdeographOrSymbol(ch)) { + for (unsigned next_end = end; end < length; end = next_end) { + ch = text.CodePointAtAndNext(next_end); + if (IsWordDelimiter<true>(ch) || + Character::IsCJKIdeographOrSymbolBase(ch)) { + return end; + } + } + return length; + } + + // For CJK/Emoji words, delimit every character because these scripts do + // not delimit words by spaces, and delimiting only at IsWordDelimiter() + // worsen the cache efficiency. + bool has_any_script = !Character::IsCommonOrInheritedScript(ch); + for (unsigned next_end = end; end < length; end = next_end) { + ch = text.CodePointAtAndNext(next_end); + // Modifier check in order not to split Emoji sequences. + if (U_GET_GC_MASK(ch) & (U_GC_M_MASK | U_GC_LM_MASK | U_GC_SK_MASK) || + ch == uchar::kZeroWidthJoiner || Character::IsEmojiComponent(ch) || + Character::IsExtendedPictographic(ch)) { + continue; + } + // Avoid delimiting COMMON/INHERITED alone, which makes harder to + // identify the script. + if (Character::IsCJKIdeographOrSymbol(ch)) { + if (Character::IsCommonOrInheritedScript(ch)) { + continue; + } + if (!has_any_script) { + has_any_script = true; + continue; + } + } + return end; + } + return length; +} + } // namespace void PlainTextItem::Trace(Visitor* visitor) const { @@ -245,8 +314,7 @@ const wtf_size_t insertion_index = item_list_.size(); StringView text_content(text_content_, start_offset, run_length); for (wtf_size_t index = 0; index < run_length;) { - wtf_size_t new_index = - CachingWordShapeIterator::NextWordEndIndex<true>(text_content, index); + wtf_size_t new_index = NextWordEndIndex(text_content, index); PlainTextItem item(start_offset + index, new_index - index, direction, text_content_); if (IsLtr(direction)) {
diff --git a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h index fd3f2ab..e0e0b7d6 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h +++ b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h
@@ -28,9 +28,7 @@ #include "base/check_op.h" #include "third_party/blink/renderer/platform/fonts/font.h" -#include "third_party/blink/renderer/platform/fonts/simple_font_data.h" #include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" -#include "third_party/blink/renderer/platform/wtf/text/character_names.h" namespace blink { @@ -44,81 +42,6 @@ static const ShapeResult* ShapeWordWithoutSpacing(const TextRun&, const Font*); - - private: - template <bool split_by_zws> - static bool IsWordDelimiter(UChar ch) { - // As of 2025 March, Google Docs always wraps text with BiDi control - // characters, and they are replaced with ZWS for HarfBuzzShaper. - // Assuming ZWS as a word delimiter improves hit rate of a shape cache. - return ch == uchar::kSpace || ch == uchar::kTab || - (split_by_zws && ch == uchar::kZeroWidthSpace); - } - - // TODO(crbug.com/389726691): Move NextWordEndIndex() to a new file because - // CachingWordShapeIterator will be removed. - friend class PlainTextNode; - template <bool split_by_zws> - static unsigned NextWordEndIndex(StringView text, unsigned start_index) { - const unsigned length = text.length(); - if (start_index >= length) { - return 0; - } - - if (start_index + 1u == length || - IsWordDelimiter<split_by_zws>(text[start_index])) { - return start_index + 1; - } - - // 8Bit words end at IsWordDelimiter(). - if (text.Is8Bit()) { - for (unsigned i = start_index + 1;; ++i) { - if (i == length || IsWordDelimiter<false>(text[i])) { - return i; - } - } - } - - // Non-CJK/Emoji words end at IsWordDelimiter() or CJK/Emoji characters. - unsigned end = start_index; - UChar32 ch = text.CodePointAtAndNext(end); - if (!Character::IsCJKIdeographOrSymbol(ch)) { - for (unsigned next_end = end; end < length; end = next_end) { - ch = text.CodePointAtAndNext(next_end); - if (IsWordDelimiter<split_by_zws>(ch) || - Character::IsCJKIdeographOrSymbolBase(ch)) { - return end; - } - } - return length; - } - - // For CJK/Emoji words, delimit every character because these scripts do - // not delimit words by spaces, and delimiting only at isWordDelimiter() - // worsen the cache efficiency. - bool has_any_script = !Character::IsCommonOrInheritedScript(ch); - for (unsigned next_end = end; end < length; end = next_end) { - ch = text.CodePointAtAndNext(next_end); - // Modifier check in order not to split Emoji sequences. - if (U_GET_GC_MASK(ch) & (U_GC_M_MASK | U_GC_LM_MASK | U_GC_SK_MASK) || - ch == uchar::kZeroWidthJoiner || Character::IsEmojiComponent(ch) || - Character::IsExtendedPictographic(ch)) { - continue; - } - // Avoid delimiting COMMON/INHERITED alone, which makes harder to - // identify the script. - if (Character::IsCJKIdeographOrSymbol(ch)) { - if (Character::IsCommonOrInheritedScript(ch)) - continue; - if (!has_any_script) { - has_any_script = true; - continue; - } - } - return end; - } - return length; - } }; } // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc deleted file mode 100644 index 59b4908..0000000 --- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.cc +++ /dev/null
@@ -1,39 +0,0 @@ -/* - * Copyright (C) 2015 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" - -#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shape_iterator.h" - -namespace blink { - -GlyphData CachingWordShaper::EmphasisMarkGlyphData( - const TextRun& emphasis_mark_run) const { - return CachingWordShapeIterator::ShapeWordWithoutSpacing(emphasis_mark_run, - &font_) - ->EmphasisMarkGlyphData(font_.GetFontDescription()); -} - -} // namespace blink
diff --git a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h b/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h deleted file mode 100644 index a4a299d..0000000 --- a/third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h +++ /dev/null
@@ -1,55 +0,0 @@ -/* - * Copyright (C) 2015 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_CACHING_WORD_SHAPER_H_ -#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_CACHING_WORD_SHAPER_H_ - -#include "third_party/blink/renderer/platform/platform_export.h" -#include "third_party/blink/renderer/platform/wtf/allocator/allocator.h" - -namespace blink { - -class Font; -class TextRun; -struct GlyphData; - -class PLATFORM_EXPORT CachingWordShaper final { - STACK_ALLOCATED(); - - public: - explicit CachingWordShaper(const Font& font) : font_(font) {} - CachingWordShaper(const CachingWordShaper&) = delete; - CachingWordShaper& operator=(const CachingWordShaper&) = delete; - ~CachingWordShaper() = default; - - GlyphData EmphasisMarkGlyphData(const TextRun&) const; - - private: - const Font& font_; -}; - -} // namespace blink - -#endif // THIRD_PARTY_BLINK_RENDERER_PLATFORM_FONTS_SHAPING_CACHING_WORD_SHAPER_H_
diff --git a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc index 1e911e54..042287b6 100644 --- a/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc +++ b/third_party/blink/renderer/platform/fonts/shaping/shape_result_bloberizer.cc
@@ -13,7 +13,6 @@ #include "cc/paint/paint_canvas.h" #include "third_party/blink/renderer/platform/fonts/font.h" #include "third_party/blink/renderer/platform/fonts/plain_text_node.h" -#include "third_party/blink/renderer/platform/fonts/shaping/caching_word_shaper.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result.h" #include "third_party/blink/renderer/platform/fonts/shaping/shape_result_view.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h"
diff --git a/third_party/blink/renderer/platform/runtime_enabled_features.json5 b/third_party/blink/renderer/platform/runtime_enabled_features.json5 index 22be93b..ed3cf754f 100644 --- a/third_party/blink/renderer/platform/runtime_enabled_features.json5 +++ b/third_party/blink/renderer/platform/runtime_enabled_features.json5
@@ -329,6 +329,14 @@ name: "AIPageContentPaidContentAnnotation", status: "stable" }, + // In AIPageContentAgent::ComputeHitTestableNodesInViewport, the hit test + // may hit the same node multiple times, which causes issues with computing + // the final z-order of page elements. This flag will filter those + // duplicate results first before doing any further processing. + { + name: "AIPageContentZOrderEarlyFiltering", + status: "stable" + }, { name: "AIPromptAPI", public: true, @@ -2289,7 +2297,7 @@ // See crbug.com/421690393. name: "FileSystemAccessRevokeReadOnRemove", depends_on: ["FileSystemAccessWriteMode"], - status: "test", + status: "stable", }, { // Controls the internal write-only mode for various FileSystemAccess API. @@ -2297,7 +2305,7 @@ // user visible APIs. // This flag is part of crbug.com/421690393 and crbug.com/328458680. name: "FileSystemAccessWriteMode", - status: "test", + status: "stable", }, { // The FileSystemObserver interface for the File System Access API.
diff --git a/third_party/blink/web_tests/VIRTUAL_OWNERS b/third_party/blink/web_tests/VIRTUAL_OWNERS index a9a7d2e..99fe72e 100644 --- a/third_party/blink/web_tests/VIRTUAL_OWNERS +++ b/third_party/blink/web_tests/VIRTUAL_OWNERS
@@ -42,6 +42,7 @@ dom@chromium.org flackr@chromium.org ikilpatrick@chromium.org +jonathanjlee@google.com kojii@chromium.org masonf@chromium.org pdr@chromium.org
diff --git a/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-computed.html b/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-computed.html index b86198b..d4d5808 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-computed.html +++ b/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-computed.html
@@ -15,5 +15,11 @@ test_computed_value("border-shape", "shape(from 0px 0px, hline to 100px, vline to 100px, close)"); test_computed_value("border-shape", "circle() circle()", "circle()"); test_computed_value("border-shape", "circle() polygon(10px 10px, 100px 10px, 10px 100px)"); - +test_computed_value("border-shape", "circle() content-box"); +test_computed_value("border-shape", "circle() border-box", "circle()"); +test_computed_value("border-shape", "circle() border-box polygon(10px 10px, 100px 10px, 10px 100px) border-box", "circle() polygon(10px 10px, 100px 10px, 10px 100px)"); +test_computed_value("border-shape", "circle() padding-box polygon(10px 10px, 100px 10px, 10px 100px) border-box", "circle() padding-box polygon(10px 10px, 100px 10px, 10px 100px)"); +test_computed_value("border-shape", "circle() padding-box polygon(10px 10px, 100px 10px, 10px 100px) padding-box", "circle() padding-box polygon(10px 10px, 100px 10px, 10px 100px) padding-box"); +test_computed_value("border-shape", "circle() polygon(10px 10px, 100px 10px, 10px 100px) border-box", "circle() polygon(10px 10px, 100px 10px, 10px 100px)"); +test_computed_value("border-shape", "circle() polygon(10px 10px, 100px 10px, 10px 100px) content-box", "circle() polygon(10px 10px, 100px 10px, 10px 100px) content-box"); </script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-invalid.html b/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-invalid.html index 8d2aee6..36b40b1 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-invalid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-invalid.html
@@ -11,5 +11,11 @@ test_invalid_value("border-shape", "shape()"); test_invalid_value("border-shape", "nonsense"); test_invalid_value("border-shape", "1px"); - +test_invalid_value("border-shape", "circle() padding-box margin-box"); +test_invalid_value("border-shape", "padding-box margin-box"); +test_invalid_value("border-shape", "padding-box"); +test_invalid_value("border-shape", "padding-box circle()"); +test_invalid_value("border-shape", "circle() padding-box margin-box circle()"); +test_invalid_value("border-shape", "circle() padding-box circle() margin-box circle()"); +test_invalid_value("border-shape", "circle() padding-box circle() margin-box padding-box"); </script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-valid.html b/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-valid.html index 2f9d3a4b..4ebb68a 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-valid.html +++ b/third_party/blink/web_tests/external/wpt/css/css-borders/tentative/parsing/border-shape-valid.html
@@ -12,5 +12,5 @@ test_valid_value("border-shape", "shape(from 0px 0px, hline to 100px, vline to 100px, close)"); test_valid_value("border-shape", "circle() circle()", "circle()"); test_valid_value("border-shape", "circle() polygon(10px 10px, 100px 10px, 10px 100px)"); - +test_valid_value("border-shape", "circle() border-box circle() content-box"); </script> \ No newline at end of file
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.html b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.html new file mode 100644 index 0000000..c6e5b3da --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.html
@@ -0,0 +1,85 @@ +<!doctype html> +<meta charset="utf-8"> +<title>Ensure that the scroll position isn't lost when the iframe is set to display:none and shown again</title> +<link rel="author" href="mailto:perryuwang@gmail.com"> +<link rel="help" href="https://issues.chromium.org/issues/41368291"> +<script src="scroll_support.js"></script> +<script src="/common/get-host-info.sub.js"></script> +<script src="/resources/testharness.js"></script> +<script src="/resources/testharnessreport.js"></script> + +<div> + <iframe id="frame"></iframe> +</div> + +<script> +const IFRAME_PATH = '/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.sub.html'; + +function waitForFrameLoadAsync(frame) { + return new Promise(async (resolve) => { + frame.addEventListener('load', resolve, { once: true }); + }); +} + +function waitForMessageAsync(expected_frame_id, expected_command) { + return new Promise((resolve) => { + window.addEventListener('message', (event) => { + assert_equals(event.data.command, expected_command); + assert_equals(event.data.frame_id, expected_frame_id); + resolve({scrollX: event.data.scrollX, scrollY: event.data.scrollY}); + }, { once: true }); + }); +} + +function iframeScrollTo(frame, x, y) { + return new Promise(async (resolve) => { + const scroll_ack_waiter = waitForMessageAsync(frame.id, 'scrollTo'); + await frame.contentWindow.postMessage({ + command: 'scrollTo', + frame_id: frame.id, + scrollX: x, + scrollY: y, + }, '*'); + const ret = await scroll_ack_waiter; + resolve(ret); + }); +} + +function iframeGetScroll(frame) { + return new Promise(async (resolve) => { + const scroll_ack_waiter = waitForMessageAsync(frame.id, 'getScroll'); + await frame.contentWindow.postMessage({ + command: 'getScroll', + frame_id: frame.id, + }, '*'); + const ret = await scroll_ack_waiter; + resolve(ret); + }); +} + +async function testIFrame(src) { + const frame = document.getElementById('frame'); + frame.src = src; + await waitForFrameLoadAsync(frame); + let ret = await iframeScrollTo(frame, 1000, 2000); + assert_equals(ret.scrollX, 1000); + assert_equals(ret.scrollY, 2000); + frame.style.display = 'none'; + await waitForCompositorCommit(); + frame.style.display = ''; + await waitForCompositorCommit(); + ret = await iframeGetScroll(frame); + assert_equals(ret.scrollX, 1000); + assert_equals(ret.scrollY, 2000); +} + +window.onload = async () => { + promise_test(async () => { + await testIFrame(IFRAME_PATH); + }, 'Ensure that the scroll position is not lost when the local iframe is set to display:none and shown again.'); + + promise_test(async () => { + await testIFrame(get_host_info().HTTP_NOTSAMESITE_ORIGIN + IFRAME_PATH); + }, 'Ensure that the scroll position is not lost when the remote iframe is set to display:none and shown again.'); +} +</script>
diff --git a/third_party/blink/web_tests/external/wpt/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.sub.html b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.sub.html new file mode 100644 index 0000000..f9c22d9 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/dom/events/scrolling/save-iframe-scroll-offset-when-display-none.sub.html
@@ -0,0 +1,34 @@ +<!DOCTYPE html> +<div style="width: 10000px; height: 10000px"> + <!-- Adding <input> is to reproduce scroll offset reset when display:none --> + <input type="text"> +</div> +<script> +function postReplyMessage(target, frame_id, command) { + target.postMessage({ + command: command, + frame_id: frame_id, + scrollX: window.scrollX, + scrollY: window.scrollY + }, "*"); +} + +function handleMessage(event) { + switch (event.data.command) { + case 'scrollTo': + window.scrollTo(event.data.scrollX, event.data.scrollY); + break; + case 'getScroll': + // No-op, just reply with current scroll position. + break; + default: + throw Error(`Unknown command: ${event.data.command}`); + break; + } + requestAnimationFrame(() => { + postReplyMessage(event.source, event.data.frame_id, event.data.command); + }); +} + +window.addEventListener('message', handleMessage); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/select-toggle-multiple-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/select-toggle-multiple-ref.html new file mode 100644 index 0000000..e3563c0b --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/select-toggle-multiple-ref.html
@@ -0,0 +1,5 @@ +<!DOCTYPE html> +<select> + <option>one</option> + <option>two</option> +</select>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/select-toggle-multiple.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/select-toggle-multiple.html new file mode 100644 index 0000000..803af7e --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-select-element/select-toggle-multiple.html
@@ -0,0 +1,22 @@ +<!DOCTYPE html> +<html class=reftest-wait> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=help href="https://issues.chromium.org/issues/450045066"> +<link rel=match href="select-toggle-multiple-ref.html"> + +<select> + <option>one</option> + <option>two</option> +</select> + +<script> +(async () => { + const select = document.querySelector('select'); + await new Promise(requestAnimationFrame); + select.multiple = true; + await new Promise(requestAnimationFrame); + select.multiple = false; + await new Promise(requestAnimationFrame); + document.documentElement.classList.remove('reftest-wait'); +})(); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pad.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pad.https.any.js index f1b9151..8be69ecb 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pad.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/pad.https.any.js
@@ -29,6 +29,32 @@ const padTests = [ { + 'name': + 'padding float32 0D constant tensor with empty paddings should be no-op', + 'graph': { + 'inputs': { + 'padInput': { + 'data': [22.76361846923828], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'pad', + 'arguments': [ + {'input': 'padInput'}, {'beginningPadding': []}, {'endingPadding': []} + ], + 'outputs': 'padOutput' + }], + 'expectedOutputs': { + 'padOutput': { + 'data': [22.76361846923828], + 'descriptor': {shape: [], dataType: 'float32'} + } + } + } + }, + { 'name': 'pad float32 1D constant tensor default options', 'graph': { 'inputs': { @@ -690,11 +716,7 @@ 'graph': { 'inputs': { 'padInput': { - 'data': [ - 22, -21, -91, - 16, 60, -70, - -60, -47, 68 - ], + 'data': [22, -21, -91, 16, 60, -70, -60, -47, 68], 'descriptor': {shape: [3, 3], dataType: 'int64'} } }, @@ -764,30 +786,14 @@ 'expectedOutputs': { 'padOutput': { 'data': [ - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - 22.76361846923828, - -21.168529510498047, - -91.66168975830078, - -Infinity, - -Infinity, - 16.863798141479492, - 60.51472091674805, - -70.56755065917969, - -Infinity, - -Infinity, - -60.643272399902344, - -47.8821907043457, - 68.72557830810547, - -Infinity, - -Infinity, - -Infinity, - -Infinity, - -Infinity, + -Infinity, -Infinity, -Infinity, + -Infinity, -Infinity, -Infinity, + 22.76361846923828, -21.168529510498047, -91.66168975830078, + -Infinity, -Infinity, 16.863798141479492, + 60.51472091674805, -70.56755065917969, -Infinity, + -Infinity, -60.643272399902344, -47.8821907043457, + 68.72557830810547, -Infinity, -Infinity, + -Infinity, -Infinity, -Infinity, -Infinity ], 'descriptor': {shape: [5, 5], dataType: 'float32'}
diff --git a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/slice.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/slice.https.any.js index 479340e..bca4aa7 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/slice.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/conformance_tests/slice.https.any.js
@@ -17,6 +17,30 @@ const sliceTests = [ { + 'name': + 'slicing float32 0D constant tensor with empty starts and sizes should be a no-op', + 'graph': { + 'inputs': { + 'sliceInput': { + 'data': [28.846250534057617], + 'descriptor': {shape: [], dataType: 'float32'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'slice', + 'arguments': [{'input': 'sliceInput'}, {'starts': []}, {'sizes': []}], + 'outputs': 'sliceOutput' + }], + 'expectedOutputs': { + 'sliceOutput': { + 'data': [28.846250534057617], + 'descriptor': {shape: [], dataType: 'float32'} + } + } + } + }, + { 'name': 'slice float32 1D constant tensor', 'graph': { 'inputs': {
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/argMinMax.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/argMinMax.https.any.js index 563eb3af..2d3063a 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/argMinMax.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/argMinMax.https.any.js
@@ -62,6 +62,12 @@ label: label, }, }, + { + name: '[argMin/Max] Throw if outputDataType=float32', + input: {dataType: 'float32', shape: [1, 2, 3, 4]}, + axis: 1, + options: {outputDataType: 'float32', label: label} + } ]; function runTests(operatorName, tests) {
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/batchNormalization.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/batchNormalization.https.any.js index 6952ff0..5bf79af7 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/batchNormalization.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/batchNormalization.https.any.js
@@ -248,6 +248,16 @@ label: label, }, }, + { + name: '[batchNormalization] Throw if the input is a scalar.', + input: {dataType: 'float32', shape: []}, + mean: {dataType: 'float32', shape: [1]}, + variance: {dataType: 'float32', shape: [1]}, + options: { + axis: 0, + label: label, + } + } ]; tests.forEach(
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/cumulativeSum.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/cumulativeSum.https.any.js index f63a0399..04f68f9 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/cumulativeSum.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/cumulativeSum.https.any.js
@@ -15,6 +15,12 @@ output: {dataType: 'float32', shape: [3, 2, 5]} }, { + name: '[cumulativeSum] Test with integer input', + input: {dataType: 'int32', shape: [3, 2, 5]}, + axis: 0, + output: {dataType: 'int32', shape: [3, 2, 5]} + }, + { name: '[cumulativeSum] Test with axis=1', input: {dataType: 'float32', shape: [3, 2, 5]}, axis: 1,
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/pad.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/pad.https.any.js index fb285ed..adc0bd3 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/pad.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/pad.https.any.js
@@ -53,11 +53,12 @@ output: {dataType: 'float32', shape: [4, 7]} }, { - name: '[pad] Throw if building pad for scalar input.', + name: + '[pad] Test pad for scalar input with empty beginningPadding and endingPadding.', input: {dataType: 'float32', shape: []}, beginningPadding: [], endingPadding: [], - options: {label} + output: {dataType: 'float32', shape: []} }, { name:
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/slice.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/slice.https.any.js index 1350f5c..833628a 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/slice.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/slice.https.any.js
@@ -26,7 +26,14 @@ output: {dataType: 'float32', shape: [1, 2, 3]} }, { - name: '[slice] Throw if input is a scalar.', + name: '[slice] Test slicing a scalar with empty starts and sizes.', + input: {dataType: 'float32', shape: []}, + starts: [], + sizes: [], + output: {dataType: 'float32', shape: []} + }, + { + name: '[slice] Throw if input is a scalar and starts/sizes are not empty.', input: {dataType: 'float32', shape: []}, starts: [0], sizes: [1]
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/softmax.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/softmax.https.any.js index 0aaae63..13ac9968 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/softmax.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/softmax.https.any.js
@@ -80,6 +80,11 @@ name: '[softmax] Throw if the axis is greater than input rank - 1.', input: {dataType: 'float16', shape: [3, 1, 5, 2]}, axis: 4 + }, + { + name: '[softmax] Throw if the input is a scalar.', + input: {dataType: 'float32', shape: []}, + axis: 0 } ];
diff --git a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/split.https.any.js b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/split.https.any.js index 9bc3980..21b790bc 100644 --- a/third_party/blink/web_tests/external/wpt/webnn/validation_tests/split.https.any.js +++ b/third_party/blink/web_tests/external/wpt/webnn/validation_tests/split.https.any.js
@@ -41,7 +41,7 @@ { name: '[split] Throw if splitting a scalar.', input: {dataType: 'float32', shape: []}, - splits: [2], + splits: [1], options: {label} }, {
diff --git a/third_party/boringssl/src b/third_party/boringssl/src index 08a77f3..ed44d6f 160000 --- a/third_party/boringssl/src +++ b/third_party/boringssl/src
@@ -1 +1 @@ -Subproject commit 08a77f3d88475b092c365d12576de078a54a6d91 +Subproject commit ed44d6f8deb450d8178908027ff46a0252b2d405
diff --git a/third_party/catapult b/third_party/catapult index 179e385..423d5e6 160000 --- a/third_party/catapult +++ b/third_party/catapult
@@ -1 +1 @@ -Subproject commit 179e38564ddc7cdf0b58d5c923f2c5c3b132899a +Subproject commit 423d5e63ff44523b3e2895d94165b80d4a003227
diff --git a/third_party/compiler-rt/src b/third_party/compiler-rt/src index 5436a04..75e7832 160000 --- a/third_party/compiler-rt/src +++ b/third_party/compiler-rt/src
@@ -1 +1 @@ -Subproject commit 5436a04e9d9f47771ae83ac5942e1d0e690baf76 +Subproject commit 75e783208e3c6a8c6236cc9f45d11d10f601c14f
diff --git a/third_party/dawn b/third_party/dawn index d1ef389..895a2f1 160000 --- a/third_party/dawn +++ b/third_party/dawn
@@ -1 +1 @@ -Subproject commit d1ef389738224f8a92c5a4557a812db47cf042cc +Subproject commit 895a2f1fc2a1e02c99b3b9522fbb4474b0c8da93
diff --git a/third_party/depot_tools b/third_party/depot_tools index 8fc14e1..8c6304b 160000 --- a/third_party/depot_tools +++ b/third_party/depot_tools
@@ -1 +1 @@ -Subproject commit 8fc14e1deafc4356319f2534de813899a3e01094 +Subproject commit 8c6304befd2205384c73e73d214848e57d9a0239
diff --git a/third_party/lit/v3_0/BUILD.gn b/third_party/lit/v3_0/BUILD.gn index de34ff5..5245b4e 100644 --- a/third_party/lit/v3_0/BUILD.gn +++ b/third_party/lit/v3_0/BUILD.gn
@@ -62,6 +62,7 @@ "//chrome/browser/resources/privacy_sandbox/internals/private_state_tokens:build_ts", "//chrome/browser/resources/privacy_sandbox/internals/related_website_sets:build_ts", "//chrome/browser/resources/profile_internals:build_ts", + "//chrome/browser/resources/reload_button:build_ts", "//chrome/browser/resources/search_engine_choice:build_ts", "//chrome/browser/resources/settings:build_ts", "//chrome/browser/resources/side_panel/bookmarks:build_ts",
diff --git a/third_party/perfetto b/third_party/perfetto index ff11fbe..d7ea394 160000 --- a/third_party/perfetto +++ b/third_party/perfetto
@@ -1 +1 @@ -Subproject commit ff11fbe7c825083afe471945766e615bc675800b +Subproject commit d7ea394300667faed7b239e087a51447586a3132
diff --git a/third_party/rust/adler2/v2/README.chromium b/third_party/rust/adler2/v2/README.chromium index 7e87542..c8e30b0 100644 --- a/third_party/rust/adler2/v2/README.chromium +++ b/third_party/rust/adler2/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/adler2 Version: 2.0.1 Revision: 89a031a0f42eeff31c70dc598b398cbf31f1680f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/adler2-v2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/anstyle/v1/README.chromium b/third_party/rust/anstyle/v1/README.chromium index 08e0d30..25c4551 100644 --- a/third_party/rust/anstyle/v1/README.chromium +++ b/third_party/rust/anstyle/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/anstyle Version: 1.0.13 Revision: 14dd743496d1614f8261a093ce755f26d8e2069d -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/anstyle-v1/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/anyhow/v1/README.chromium b/third_party/rust/anyhow/v1/README.chromium index 8ed496ea..0f032122 100644 --- a/third_party/rust/anyhow/v1/README.chromium +++ b/third_party/rust/anyhow/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/anyhow Version: 1.0.100 Revision: 18c2598afa0f996f56217ef128aa3a20ea1e9512 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/anyhow-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/arrayvec/v0_7/README.chromium b/third_party/rust/arrayvec/v0_7/README.chromium index 5a3aa0b1..fdeed49 100644 --- a/third_party/rust/arrayvec/v0_7/README.chromium +++ b/third_party/rust/arrayvec/v0_7/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/arrayvec Version: 0.7.6 Revision: 0aede877fe0bfb1ba5e3c2024df8c0958d503a83 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/arrayvec-v0_7/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/autocfg/v1/README.chromium b/third_party/rust/autocfg/v1/README.chromium index b4ae907..ba5bac2 100644 --- a/third_party/rust/autocfg/v1/README.chromium +++ b/third_party/rust/autocfg/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/autocfg Version: 1.5.0 Revision: d912169ed67977efe5a465269b0e73cb66060c49 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/autocfg-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/base64/v0_22/README.chromium b/third_party/rust/base64/v0_22/README.chromium index 9205349..86a1a0c 100644 --- a/third_party/rust/base64/v0_22/README.chromium +++ b/third_party/rust/base64/v0_22/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/base64 Version: 0.22.1 Revision: e14400697453bcc85997119b874bc03d9601d0af -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/base64-v0_22/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/bitflags/v1/README.chromium b/third_party/rust/bitflags/v1/README.chromium index f92723e..81680d90 100644 --- a/third_party/rust/bitflags/v1/README.chromium +++ b/third_party/rust/bitflags/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/bitflags Version: 1.3.2 Revision: ed185cfb1c447c1b4bd6ac021c9ec3bb02c9e2f2 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/bitflags-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/bitflags/v2/README.chromium b/third_party/rust/bitflags/v2/README.chromium index 013b4a5..e0704886 100644 --- a/third_party/rust/bitflags/v2/README.chromium +++ b/third_party/rust/bitflags/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/bitflags Version: 2.9.4 Revision: de0ec28f9999bb8984fa92e19a2f53181098cc87 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/bitflags-v2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/bytemuck/v1/README.chromium b/third_party/rust/bytemuck/v1/README.chromium index 8035f7a..f9a05bf6 100644 --- a/third_party/rust/bytemuck/v1/README.chromium +++ b/third_party/rust/bytemuck/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/bytemuck Version: 1.23.2 Revision: c069a2f6a4c7f3416257d0378c799085aa5626bb -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/bytemuck-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/bytemuck_derive/v1/README.chromium b/third_party/rust/bytemuck_derive/v1/README.chromium index ab0ec4b..7f77a20b 100644 --- a/third_party/rust/bytemuck_derive/v1/README.chromium +++ b/third_party/rust/bytemuck_derive/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/bytemuck_derive Version: 1.10.1 Revision: 2524f62b76b0ec4804e3f4af4510fcd1253ffe66 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/bytemuck_derive-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/bytes/v1/README.chromium b/third_party/rust/bytes/v1/README.chromium index c6eba8f..7ea6aca 100644 --- a/third_party/rust/bytes/v1/README.chromium +++ b/third_party/rust/bytes/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/bytes Version: 1.10.1 Revision: 19d1427c971f6b619356966163459e43f797de2f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/bytes-v1/LICENSE Shipped: yes
diff --git a/third_party/rust/calendrical_calculations/v0_2/README.chromium b/third_party/rust/calendrical_calculations/v0_2/README.chromium index 4767b23..f59e75e 100644 --- a/third_party/rust/calendrical_calculations/v0_2/README.chromium +++ b/third_party/rust/calendrical_calculations/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/calendrical_calculations Version: 0.2.2 Revision: fbb3eebe2f65e64a69b3a1837dce8ed9cbbe677e -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/calendrical_calculations-v0_2/LICENSE Shipped: yes
diff --git a/third_party/rust/cfg_if/v1/README.chromium b/third_party/rust/cfg_if/v1/README.chromium index 7b57460..0194ec6 100644 --- a/third_party/rust/cfg_if/v1/README.chromium +++ b/third_party/rust/cfg_if/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/cfg-if Version: 1.0.3 Revision: 9c7bb0bf7184698c16ba60aad424b9b8263ac6db -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/cfg-if-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/clap/v4/README.chromium b/third_party/rust/clap/v4/README.chromium index 9d16d09..3406e82 100644 --- a/third_party/rust/clap/v4/README.chromium +++ b/third_party/rust/clap/v4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/clap Version: 4.5.48 Revision: 8e3d03639756241aa2b7dd624a7f5852bef76f31 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/clap-v4/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/clap_builder/v4/README.chromium b/third_party/rust/clap_builder/v4/README.chromium index f7a533c..24b833f4 100644 --- a/third_party/rust/clap_builder/v4/README.chromium +++ b/third_party/rust/clap_builder/v4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/clap_builder Version: 4.5.48 Revision: 8e3d03639756241aa2b7dd624a7f5852bef76f31 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/clap_builder-v4/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/clap_lex/v0_7/README.chromium b/third_party/rust/clap_lex/v0_7/README.chromium index 942b30b..e9348124 100644 --- a/third_party/rust/clap_lex/v0_7/README.chromium +++ b/third_party/rust/clap_lex/v0_7/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/clap_lex Version: 0.7.5 Revision: 3716f9f4289594b43abec42b2538efd1a90ff897 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/clap_lex-v0_7/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/codespan_reporting/v0_12/README.chromium b/third_party/rust/codespan_reporting/v0_12/README.chromium index b08d72f..18d11ee 100644 --- a/third_party/rust/codespan_reporting/v0_12/README.chromium +++ b/third_party/rust/codespan_reporting/v0_12/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/codespan-reporting Version: 0.12.0 Revision: 3d3a03a8fcc30cc10b783b16c62029d5c232059b -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/codespan-reporting-v0_12/LICENSE Shipped: yes
diff --git a/third_party/rust/core_maths/v0_1/README.chromium b/third_party/rust/core_maths/v0_1/README.chromium index f066a1da..f6af182 100644 --- a/third_party/rust/core_maths/v0_1/README.chromium +++ b/third_party/rust/core_maths/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/core_maths Version: 0.1.1 Revision: d8ea96acac3893ad9a7e16cd7526936fbfc51021 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/core_maths-v0_1/LICENSE Shipped: yes
diff --git a/third_party/rust/crc32fast/v1/README.chromium b/third_party/rust/crc32fast/v1/README.chromium index 8a417b8d..cc766f9a 100644 --- a/third_party/rust/crc32fast/v1/README.chromium +++ b/third_party/rust/crc32fast/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/crc32fast Version: 1.5.0 Revision: dbf4f76cd71cdcc57d9164cbd46890d53ce0423c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/crc32fast-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/cxx/v1/README.chromium b/third_party/rust/cxx/v1/README.chromium index 253b4ef..f2e6b8e 100644 --- a/third_party/rust/cxx/v1/README.chromium +++ b/third_party/rust/cxx/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/cxx Version: 1.0.186 Revision: 191684c5d2e88b7bc43c623f698a23b612d10772 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/cxx-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/cxxbridge_cmd/v1/README.chromium b/third_party/rust/cxxbridge_cmd/v1/README.chromium index f2e21e5..b4d14c55 100644 --- a/third_party/rust/cxxbridge_cmd/v1/README.chromium +++ b/third_party/rust/cxxbridge_cmd/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/cxxbridge-cmd Version: 1.0.186 Revision: 191684c5d2e88b7bc43c623f698a23b612d10772 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/cxxbridge-cmd-v1/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/cxxbridge_flags/v1/README.chromium b/third_party/rust/cxxbridge_flags/v1/README.chromium index de743902..fa5a8e0 100644 --- a/third_party/rust/cxxbridge_flags/v1/README.chromium +++ b/third_party/rust/cxxbridge_flags/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/cxxbridge-flags Version: 1.0.186 Revision: 191684c5d2e88b7bc43c623f698a23b612d10772 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/cxxbridge-flags-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/cxxbridge_macro/v1/README.chromium b/third_party/rust/cxxbridge_macro/v1/README.chromium index 7e3ddaa..623738a 100644 --- a/third_party/rust/cxxbridge_macro/v1/README.chromium +++ b/third_party/rust/cxxbridge_macro/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/cxxbridge-macro Version: 1.0.186 Revision: 191684c5d2e88b7bc43c623f698a23b612d10772 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/cxxbridge-macro-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/derivre/v0_3/README.chromium b/third_party/rust/derivre/v0_3/README.chromium index 3255cf2a..36baa72 100644 --- a/third_party/rust/derivre/v0_3/README.chromium +++ b/third_party/rust/derivre/v0_3/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/derivre Version: 0.3.8 Revision: c68f60791d191a05131796771f38c2e904417074 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/derivre-v0_3/LICENSE Shipped: yes
diff --git a/third_party/rust/diplomat/v0_13/README.chromium b/third_party/rust/diplomat/v0_13/README.chromium index 64c7026..9a3b18e 100644 --- a/third_party/rust/diplomat/v0_13/README.chromium +++ b/third_party/rust/diplomat/v0_13/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/diplomat Version: 0.13.0 Revision: f05fabd1bd2a23b2e28f3cbba812f3719b4748c8 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/diplomat-v0_13/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/diplomat_core/v0_13/README.chromium b/third_party/rust/diplomat_core/v0_13/README.chromium index 98b1aa5..47013e4 100644 --- a/third_party/rust/diplomat_core/v0_13/README.chromium +++ b/third_party/rust/diplomat_core/v0_13/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/diplomat_core Version: 0.13.0 Revision: f05fabd1bd2a23b2e28f3cbba812f3719b4748c8 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/diplomat_core-v0_13/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/diplomat_runtime/v0_13/README.chromium b/third_party/rust/diplomat_runtime/v0_13/README.chromium index b8844af..34fe90e 100644 --- a/third_party/rust/diplomat_runtime/v0_13/README.chromium +++ b/third_party/rust/diplomat_runtime/v0_13/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/diplomat-runtime Version: 0.13.0 Revision: f05fabd1bd2a23b2e28f3cbba812f3719b4748c8 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/diplomat-runtime-v0_13/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/displaydoc/v0_2/README.chromium b/third_party/rust/displaydoc/v0_2/README.chromium index 5aacdbf..bcfacd3b 100644 --- a/third_party/rust/displaydoc/v0_2/README.chromium +++ b/third_party/rust/displaydoc/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/displaydoc Version: 0.2.5 Revision: e4028851bfb82998300237f7568a45f589a19e40 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/displaydoc-v0_2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/either/v1/README.chromium b/third_party/rust/either/v1/README.chromium index e7a2819..e302d68 100644 --- a/third_party/rust/either/v1/README.chromium +++ b/third_party/rust/either/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/either Version: 1.15.0 Revision: 59ae1fce0cec62c886fcd486e06b7e219bc7ce48 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/either-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/encoding_rs/v0_8/README.chromium b/third_party/rust/encoding_rs/v0_8/README.chromium index fbd48de3..f09b1db 100644 --- a/third_party/rust/encoding_rs/v0_8/README.chromium +++ b/third_party/rust/encoding_rs/v0_8/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/encoding_rs Version: 0.8.35 Revision: 2fa58aecf537cc76ff52c0eb3d5e9f8fda466844 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0, BSD-3-Clause License File: //third_party/rust/chromium_crates_io/vendor/encoding_rs-v0_8/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/equivalent/v1/README.chromium b/third_party/rust/equivalent/v1/README.chromium index 003fc2b..f8cfbd9 100644 --- a/third_party/rust/equivalent/v1/README.chromium +++ b/third_party/rust/equivalent/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/equivalent Version: 1.0.2 Revision: 44cdd44f8b8ebb5f9ae096c7550a5e74ffb7d6ae -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/equivalent-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/fdeflate/v0_3/README.chromium b/third_party/rust/fdeflate/v0_3/README.chromium index 23da7f3..f5f1dc95 100644 --- a/third_party/rust/fdeflate/v0_3/README.chromium +++ b/third_party/rust/fdeflate/v0_3/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/fdeflate Version: 0.3.7 Revision: c365c7e6ffa81feb2e1fb762eed7299f05c9b0ca -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/fdeflate-v0_3/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/fend_core/v1/README.chromium b/third_party/rust/fend_core/v1/README.chromium index 4c3b09d4..df881ca9 100644 --- a/third_party/rust/fend_core/v1/README.chromium +++ b/third_party/rust/fend_core/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/fend-core Version: 1.5.7 Revision: 9886a0d35a1de1fae4975d99651285ef06f124b3 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/fend-core-v1/LICENSE.md Shipped: yes
diff --git a/third_party/rust/fixed_decimal/v0_7/README.chromium b/third_party/rust/fixed_decimal/v0_7/README.chromium index 9e0895c..17ab626 100644 --- a/third_party/rust/fixed_decimal/v0_7/README.chromium +++ b/third_party/rust/fixed_decimal/v0_7/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/fixed_decimal Version: 0.7.0 Revision: f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/fixed_decimal-v0_7/LICENSE Shipped: yes
diff --git a/third_party/rust/flate2/v1/README.chromium b/third_party/rust/flate2/v1/README.chromium index 46643ea..029b06e 100644 --- a/third_party/rust/flate2/v1/README.chromium +++ b/third_party/rust/flate2/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/flate2 Version: 1.1.2 Revision: ac4d950ffdeab209350423c528d876a7a7811abb -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/flate2-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/foldhash/v0_2/README.chromium b/third_party/rust/foldhash/v0_2/README.chromium index 6cc1d05..855d5b2 100644 --- a/third_party/rust/foldhash/v0_2/README.chromium +++ b/third_party/rust/foldhash/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/foldhash Version: 0.2.0 Revision: 8f878c636fda9c9e93384824ea45e06d03f009f5 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Zlib License File: //third_party/rust/chromium_crates_io/vendor/foldhash-v0_2/LICENSE Shipped: yes
diff --git a/third_party/rust/font_types/v0_10/README.chromium b/third_party/rust/font_types/v0_10/README.chromium index 9187a9d..38fb575 100644 --- a/third_party/rust/font_types/v0_10/README.chromium +++ b/third_party/rust/font_types/v0_10/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/font-types Version: 0.10.0 Revision: 1a8baba89aa129a899bc83b0b610881190f8bbad -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/font-types-v0_10/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/hashbrown/v0_15/README.chromium b/third_party/rust/hashbrown/v0_15/README.chromium index 00e051a0..fb8b61f 100644 --- a/third_party/rust/hashbrown/v0_15/README.chromium +++ b/third_party/rust/hashbrown/v0_15/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/hashbrown Version: 0.15.5 Revision: b751eef8e99ccf3652046ef4a9e1ec47c1bfb78d -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/hashbrown-v0_15/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/heck/v0_5/README.chromium b/third_party/rust/heck/v0_5/README.chromium index ffbdd88..ee4889a3 100644 --- a/third_party/rust/heck/v0_5/README.chromium +++ b/third_party/rust/heck/v0_5/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/heck Version: 0.5.0 Revision: 070693322aee7c5c7fbee7c9964bf8d7d3a29c96 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/heck-v0_5/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/hex/v0_4/README.chromium b/third_party/rust/hex/v0_4/README.chromium index eed24cf..86df884 100644 --- a/third_party/rust/hex/v0_4/README.chromium +++ b/third_party/rust/hex/v0_4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/hex Version: 0.4.3 Revision: b2b4370b5bf021b98ee7adc92233e8de3f2de792 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/hex-v0_4/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/icu_calendar/v2/README.chromium b/third_party/rust/icu_calendar/v2/README.chromium index 5977bdf..92c500ee 100644 --- a/third_party/rust/icu_calendar/v2/README.chromium +++ b/third_party/rust/icu_calendar/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_calendar Version: 2.0.5 Revision: 72e94a5baa4bc7840b27eae48cc9364fc018a483 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_calendar-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_calendar_data/v2/README.chromium b/third_party/rust/icu_calendar_data/v2/README.chromium index 7942c43..ee57b045 100644 --- a/third_party/rust/icu_calendar_data/v2/README.chromium +++ b/third_party/rust/icu_calendar_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_calendar_data Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_calendar_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_casemap/v2/README.chromium b/third_party/rust/icu_casemap/v2/README.chromium index 96c1918..165c87c 100644 --- a/third_party/rust/icu_casemap/v2/README.chromium +++ b/third_party/rust/icu_casemap/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_casemap Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_casemap-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_casemap_data/v2/README.chromium b/third_party/rust/icu_casemap_data/v2/README.chromium index 5025cb3..8c8a3a5 100644 --- a/third_party/rust/icu_casemap_data/v2/README.chromium +++ b/third_party/rust/icu_casemap_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_casemap_data Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_casemap_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_collections/v2/README.chromium b/third_party/rust/icu_collections/v2/README.chromium index 92d631b6..945b3bf6 100644 --- a/third_party/rust/icu_collections/v2/README.chromium +++ b/third_party/rust/icu_collections/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_collections Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_collections-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_decimal/v2/README.chromium b/third_party/rust/icu_decimal/v2/README.chromium index 6f729046..6b7d032 100644 --- a/third_party/rust/icu_decimal/v2/README.chromium +++ b/third_party/rust/icu_decimal/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_decimal Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_decimal-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_decimal_data/v2/README.chromium b/third_party/rust/icu_decimal_data/v2/README.chromium index c13c621..1c6b862 100644 --- a/third_party/rust/icu_decimal_data/v2/README.chromium +++ b/third_party/rust/icu_decimal_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_decimal_data Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_decimal_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_experimental/v0_3/README.chromium b/third_party/rust/icu_experimental/v0_3/README.chromium index ec244c2..a16f320c 100644 --- a/third_party/rust/icu_experimental/v0_3/README.chromium +++ b/third_party/rust/icu_experimental/v0_3/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_experimental Version: 0.3.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_experimental-v0_3/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_experimental_data/v0_3/README.chromium b/third_party/rust/icu_experimental_data/v0_3/README.chromium index 03d6441..52bc5e4 100644 --- a/third_party/rust/icu_experimental_data/v0_3/README.chromium +++ b/third_party/rust/icu_experimental_data/v0_3/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_experimental_data Version: 0.3.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_experimental_data-v0_3/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_list/v2/README.chromium b/third_party/rust/icu_list/v2/README.chromium index af412d3..60942c0 100644 --- a/third_party/rust/icu_list/v2/README.chromium +++ b/third_party/rust/icu_list/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_list Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_list-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_list_data/v2/README.chromium b/third_party/rust/icu_list_data/v2/README.chromium index e76f4c16..5ad618f 100644 --- a/third_party/rust/icu_list_data/v2/README.chromium +++ b/third_party/rust/icu_list_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_list_data Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_list_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_locale/v2/README.chromium b/third_party/rust/icu_locale/v2/README.chromium index 5295d25..deb9ab5 100644 --- a/third_party/rust/icu_locale/v2/README.chromium +++ b/third_party/rust/icu_locale/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_locale Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_locale-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_locale_core/v2/README.chromium b/third_party/rust/icu_locale_core/v2/README.chromium index e159099..7908ef9 100644 --- a/third_party/rust/icu_locale_core/v2/README.chromium +++ b/third_party/rust/icu_locale_core/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_locale_core Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_locale_core-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_locale_data/v2/README.chromium b/third_party/rust/icu_locale_data/v2/README.chromium index 883a815f..725607d 100644 --- a/third_party/rust/icu_locale_data/v2/README.chromium +++ b/third_party/rust/icu_locale_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_locale_data Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_locale_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_normalizer/v2/README.chromium b/third_party/rust/icu_normalizer/v2/README.chromium index 0555ebae..912a0cb 100644 --- a/third_party/rust/icu_normalizer/v2/README.chromium +++ b/third_party/rust/icu_normalizer/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_normalizer Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_normalizer-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_normalizer_data/v2/README.chromium b/third_party/rust/icu_normalizer_data/v2/README.chromium index 184d184..51df4ab 100644 --- a/third_party/rust/icu_normalizer_data/v2/README.chromium +++ b/third_party/rust/icu_normalizer_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_normalizer_data Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_normalizer_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_pattern/v0_4/README.chromium b/third_party/rust/icu_pattern/v0_4/README.chromium index 51b1726f..a908fe0c 100644 --- a/third_party/rust/icu_pattern/v0_4/README.chromium +++ b/third_party/rust/icu_pattern/v0_4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_pattern Version: 0.4.0 Revision: c8a616acb260000e0b8ef3545fd6de2c528d7f29 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_pattern-v0_4/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_plurals/v2/README.chromium b/third_party/rust/icu_plurals/v2/README.chromium index f081c99..99e6388 100644 --- a/third_party/rust/icu_plurals/v2/README.chromium +++ b/third_party/rust/icu_plurals/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_plurals Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_plurals-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_plurals_data/v2/README.chromium b/third_party/rust/icu_plurals_data/v2/README.chromium index a50d8fc..4e056c9d 100644 --- a/third_party/rust/icu_plurals_data/v2/README.chromium +++ b/third_party/rust/icu_plurals_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_plurals_data Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_plurals_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_properties/v2/README.chromium b/third_party/rust/icu_properties/v2/README.chromium index db0b63ff..2d1fe9ab 100644 --- a/third_party/rust/icu_properties/v2/README.chromium +++ b/third_party/rust/icu_properties/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_properties Version: 2.0.1 Revision: 6fe1953b1fe2e2df9d7727f74752c04e30181e78 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_properties-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_properties_data/v2/README.chromium b/third_party/rust/icu_properties_data/v2/README.chromium index b463405..632e00c2 100644 --- a/third_party/rust/icu_properties_data/v2/README.chromium +++ b/third_party/rust/icu_properties_data/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_properties_data Version: 2.0.1 Revision: 6fe1953b1fe2e2df9d7727f74752c04e30181e78 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_properties_data-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/icu_provider/v2/README.chromium b/third_party/rust/icu_provider/v2/README.chromium index 28fa830..4e27ae1 100644 --- a/third_party/rust/icu_provider/v2/README.chromium +++ b/third_party/rust/icu_provider/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/icu_provider Version: 2.0.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/icu_provider-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/indexmap/v2/README.chromium b/third_party/rust/indexmap/v2/README.chromium index d3ea96f..00047de 100644 --- a/third_party/rust/indexmap/v2/README.chromium +++ b/third_party/rust/indexmap/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/indexmap Version: 2.11.4 Revision: 03f9e58626ad7ef811b1522097bced2400c18b1a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/indexmap-v2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/itertools/v0_11/README.chromium b/third_party/rust/itertools/v0_11/README.chromium index fbacd46..68a08d5a 100644 --- a/third_party/rust/itertools/v0_11/README.chromium +++ b/third_party/rust/itertools/v0_11/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/itertools Version: 0.11.0 Revision: 62a6401afd6d45e1c2aea94c05cb5c70076b2ca4 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/itertools-v0_11/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/itoa/v1/README.chromium b/third_party/rust/itoa/v1/README.chromium index 575bd5d..642c3ad 100644 --- a/third_party/rust/itoa/v1/README.chromium +++ b/third_party/rust/itoa/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/itoa Version: 1.0.15 Revision: e2766b868e4ac1ae2bf5bea1ac43d4c0da23b899 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/itoa-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/ixdtf/v0_6/README.chromium b/third_party/rust/ixdtf/v0_6/README.chromium index a8e2138..eb9cb7e7 100644 --- a/third_party/rust/ixdtf/v0_6/README.chromium +++ b/third_party/rust/ixdtf/v0_6/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/ixdtf Version: 0.6.3 Revision: 4d53125a232c56fff3a947c2f4d1f4ae58b91d1d -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/ixdtf-v0_6/LICENSE Shipped: yes
diff --git a/third_party/rust/lazy_static/v1/README.chromium b/third_party/rust/lazy_static/v1/README.chromium index dbde242..786c824 100644 --- a/third_party/rust/lazy_static/v1/README.chromium +++ b/third_party/rust/lazy_static/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/lazy_static Version: 1.5.0 Revision: be7c1c43f264699f956b70ce8e29941bd1e61bde -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/lazy_static-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/libc/v0_2/README.chromium b/third_party/rust/libc/v0_2/README.chromium index 3bac76d..82776ea 100644 --- a/third_party/rust/libc/v0_2/README.chromium +++ b/third_party/rust/libc/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/libc Version: 0.2.176 Revision: 15e1389ae87935c9c08f4449a73c7b979cded21a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/libc-v0_2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/libm/v0_2/README.chromium b/third_party/rust/libm/v0_2/README.chromium index 1475241e..9d7db85 100644 --- a/third_party/rust/libm/v0_2/README.chromium +++ b/third_party/rust/libm/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/libm Version: 0.2.15 Revision: a4c748f72a1dce652cc3e41c3a8425731bd1519a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/libm-v0_2/LICENSE.txt Shipped: yes
diff --git a/third_party/rust/litemap/v0_8/README.chromium b/third_party/rust/litemap/v0_8/README.chromium index 1c07f81..0dc66bef3 100644 --- a/third_party/rust/litemap/v0_8/README.chromium +++ b/third_party/rust/litemap/v0_8/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/litemap Version: 0.8.0 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/litemap-v0_8/LICENSE Shipped: yes
diff --git a/third_party/rust/llguidance/v1/README.chromium b/third_party/rust/llguidance/v1/README.chromium index 1289c83..a12bb0b 100644 --- a/third_party/rust/llguidance/v1/README.chromium +++ b/third_party/rust/llguidance/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/llguidance Version: 1.2.0 Revision: c65e3c3244713b9ebcc204cc5676c8a4a57f78bf -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/llguidance-v1/LICENSE Shipped: yes
diff --git a/third_party/rust/log/v0_4/README.chromium b/third_party/rust/log/v0_4/README.chromium index 7eadf4c52..4e033e7 100644 --- a/third_party/rust/log/v0_4/README.chromium +++ b/third_party/rust/log/v0_4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/log Version: 0.4.28 Revision: 6e1735597bb21c5d979a077395df85e1d633e077 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/log-v0_4/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/memchr/v2/README.chromium b/third_party/rust/memchr/v2/README.chromium index c845930..45e1e06 100644 --- a/third_party/rust/memchr/v2/README.chromium +++ b/third_party/rust/memchr/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/memchr Version: 2.7.6 Revision: 9ba486e4ba7e865c0510305c5dacba73988d9f31 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/memchr-v2/LICENSE-MIT Shipped: yes
diff --git a/third_party/rust/miniz_oxide/v0_8/README.chromium b/third_party/rust/miniz_oxide/v0_8/README.chromium index b331d9cc..48bb146 100644 --- a/third_party/rust/miniz_oxide/v0_8/README.chromium +++ b/third_party/rust/miniz_oxide/v0_8/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/miniz_oxide Version: 0.8.9 Revision: 44e43c7786e379b2b1a7fde4aa0e63be719e583d -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/miniz_oxide-v0_8/LICENSE-APACHE.md Shipped: yes
diff --git a/third_party/rust/num_bigint/v0_4/README.chromium b/third_party/rust/num_bigint/v0_4/README.chromium index 4950d42..8beb064 100644 --- a/third_party/rust/num_bigint/v0_4/README.chromium +++ b/third_party/rust/num_bigint/v0_4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/num-bigint Version: 0.4.6 Revision: a25836ec6c341d1aa40c97335842f330b6a62911 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/num-bigint-v0_4/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/num_integer/v0_1/README.chromium b/third_party/rust/num_integer/v0_1/README.chromium index 4cfaa7ea..86be387 100644 --- a/third_party/rust/num_integer/v0_1/README.chromium +++ b/third_party/rust/num_integer/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/num-integer Version: 0.1.46 Revision: ede2d2cb993e55e7b1c992bfd22ecbf16601a652 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/num-integer-v0_1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/num_rational/v0_4/README.chromium b/third_party/rust/num_rational/v0_4/README.chromium index 5c11302..77eeb06 100644 --- a/third_party/rust/num_rational/v0_4/README.chromium +++ b/third_party/rust/num_rational/v0_4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/num-rational Version: 0.4.2 Revision: 4d55ad22ac86ebbc4cb45d79a956e4a1f7af57d1 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/num-rational-v0_4/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/num_traits/v0_2/README.chromium b/third_party/rust/num_traits/v0_2/README.chromium index fea35746..43635b9 100644 --- a/third_party/rust/num_traits/v0_2/README.chromium +++ b/third_party/rust/num_traits/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/num-traits Version: 0.2.19 Revision: 7ec3d41d39b28190ec1d42db38021107b3951f3a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/num-traits-v0_2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/png/v0_18/README.chromium b/third_party/rust/png/v0_18/README.chromium index d958b11..7a3a6611 100644 --- a/third_party/rust/png/v0_18/README.chromium +++ b/third_party/rust/png/v0_18/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/png Version: 0.18.0-rc Revision: eb9b5d7f371b88f15aaca6a8d21c58b86c400d76 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/png-v0_18/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/potential_utf/v0_1/README.chromium b/third_party/rust/potential_utf/v0_1/README.chromium index ef36f49c5..1bb4ae29 100644 --- a/third_party/rust/potential_utf/v0_1/README.chromium +++ b/third_party/rust/potential_utf/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/potential_utf Version: 0.1.3 Revision: fbb3eebe2f65e64a69b3a1837dce8ed9cbbe677e -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/potential_utf-v0_1/LICENSE Shipped: yes
diff --git a/third_party/rust/proc_macro2/v1/README.chromium b/third_party/rust/proc_macro2/v1/README.chromium index 11b270e..50f57ec 100644 --- a/third_party/rust/proc_macro2/v1/README.chromium +++ b/third_party/rust/proc_macro2/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/proc-macro2 Version: 1.0.101 Revision: d3188ea889e55be0433326695b2773c717b39bb9 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/proc-macro2-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/prost/v0_14/README.chromium b/third_party/rust/prost/v0_14/README.chromium index c7d9e1c..d3c23c6e 100644 --- a/third_party/rust/prost/v0_14/README.chromium +++ b/third_party/rust/prost/v0_14/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/prost Version: 0.14.1 Revision: 9965a988a7f95d55c106b933a82a3e657dce02c2 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/prost-v0_14/LICENSE Shipped: no
diff --git a/third_party/rust/prost_derive/v0_14/README.chromium b/third_party/rust/prost_derive/v0_14/README.chromium index 9d1b8df52..41a7988 100644 --- a/third_party/rust/prost_derive/v0_14/README.chromium +++ b/third_party/rust/prost_derive/v0_14/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/prost-derive Version: 0.14.1 Revision: 9965a988a7f95d55c106b933a82a3e657dce02c2 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/prost-derive-v0_14/LICENSE Shipped: no
diff --git a/third_party/rust/qr_code/v2/README.chromium b/third_party/rust/qr_code/v2/README.chromium index 317ee30..24a0616 100644 --- a/third_party/rust/qr_code/v2/README.chromium +++ b/third_party/rust/qr_code/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/qr_code Version: 2.0.0 Revision: 341f62be3a91ecb05e6e0870e61f763308eaf2ff -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/qr_code-v2/LICENSE-APACHE.txt Shipped: yes
diff --git a/third_party/rust/quote/v1/README.chromium b/third_party/rust/quote/v1/README.chromium index a9ffe7f..9ec00658 100644 --- a/third_party/rust/quote/v1/README.chromium +++ b/third_party/rust/quote/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/quote Version: 1.0.41 Revision: 594c865ce817b4adb5863713e4fa3749fbf47f0a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/quote-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/read_fonts/v0_35/README.chromium b/third_party/rust/read_fonts/v0_35/README.chromium index fb579efe..efc365f 100644 --- a/third_party/rust/read_fonts/v0_35/README.chromium +++ b/third_party/rust/read_fonts/v0_35/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/read-fonts Version: 0.35.0 Revision: 1a8baba89aa129a899bc83b0b610881190f8bbad -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/read-fonts-v0_35/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/regex_automata/v0_4/README.chromium b/third_party/rust/regex_automata/v0_4/README.chromium index 6919e5d8..a490ffb 100644 --- a/third_party/rust/regex_automata/v0_4/README.chromium +++ b/third_party/rust/regex_automata/v0_4/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/regex-automata Version: 0.4.11 Revision: 159fa3e1e0984ade1edf4831b80c94cdf4b3ed9f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/regex-automata-v0_4/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/regex_syntax/v0_8/README.chromium b/third_party/rust/regex_syntax/v0_8/README.chromium index a9f1feb..1157ec6 100644 --- a/third_party/rust/regex_syntax/v0_8/README.chromium +++ b/third_party/rust/regex_syntax/v0_8/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/regex-syntax Version: 0.8.6 Revision: ea834f8e1fd7b72a3c1b2319b1a47f0c50d43082 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/regex-syntax-v0_8/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/resb/v0_1/README.chromium b/third_party/rust/resb/v0_1/README.chromium index 590ee4b6..034ed67 100644 --- a/third_party/rust/resb/v0_1/README.chromium +++ b/third_party/rust/resb/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/resb Version: 0.1.0 Revision: 7d369fbb651d594322ef44f12ea56066973628e4 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/resb-v0_1/LICENSE Shipped: yes
diff --git a/third_party/rust/rustc_demangle/v0_1/README.chromium b/third_party/rust/rustc_demangle/v0_1/README.chromium index b76b9dc5..9305d1f9 100644 --- a/third_party/rust/rustc_demangle/v0_1/README.chromium +++ b/third_party/rust/rustc_demangle/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/rustc-demangle Version: 0.1.26 Revision: c5688cfec32d2bd00701836f12beb3560ee015b8 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/rustc-demangle-v0_1/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/rustc_demangle_capi/v0_1/README.chromium b/third_party/rust/rustc_demangle_capi/v0_1/README.chromium index 3a6af406..13cac6d4 100644 --- a/third_party/rust/rustc_demangle_capi/v0_1/README.chromium +++ b/third_party/rust/rustc_demangle_capi/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/rustc-demangle-capi Version: 0.1.1 Revision: 8145ea3869767f044ca63667ca17eab544f3a8ee -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/rustc-demangle-capi-v0_1/LICENSE-APACHE Shipped: no
diff --git a/third_party/rust/rustversion/v1/README.chromium b/third_party/rust/rustversion/v1/README.chromium index f7abbcf0..b924add 100644 --- a/third_party/rust/rustversion/v1/README.chromium +++ b/third_party/rust/rustversion/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/rustversion Version: 1.0.22 Revision: 9e86f839b6a34a7d9398f243d88bf400b7fa1f7c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/rustversion-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/ryu/v1/README.chromium b/third_party/rust/ryu/v1/README.chromium index 66becca..dda5b1b7 100644 --- a/third_party/rust/ryu/v1/README.chromium +++ b/third_party/rust/ryu/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/ryu Version: 1.0.20 Revision: 02237f8751db162e9ed0f5bd3e7135d1b256822e -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/ryu-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/serde/v1/README.chromium b/third_party/rust/serde/v1/README.chromium index efecfd6..e136a60 100644 --- a/third_party/rust/serde/v1/README.chromium +++ b/third_party/rust/serde/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/serde Version: 1.0.228 Revision: a866b336f14aa57a07f0d0be9f8762746e64ecb4 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/serde-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/serde_core/v1/README.chromium b/third_party/rust/serde_core/v1/README.chromium index d29eb40..bbe5a3f753 100644 --- a/third_party/rust/serde_core/v1/README.chromium +++ b/third_party/rust/serde_core/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/serde_core Version: 1.0.228 Revision: a866b336f14aa57a07f0d0be9f8762746e64ecb4 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/serde_core-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/serde_derive/v1/README.chromium b/third_party/rust/serde_derive/v1/README.chromium index d9571948..9167f7e1 100644 --- a/third_party/rust/serde_derive/v1/README.chromium +++ b/third_party/rust/serde_derive/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/serde_derive Version: 1.0.228 Revision: a866b336f14aa57a07f0d0be9f8762746e64ecb4 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/serde_derive-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/serde_json/v1/README.chromium b/third_party/rust/serde_json/v1/README.chromium index 74e3b95..54a3814 100644 --- a/third_party/rust/serde_json/v1/README.chromium +++ b/third_party/rust/serde_json/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/serde_json Version: 1.0.145 Revision: efa66e3a1d61459ab2d325f92ebe3acbd6ca18b1 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/serde_json-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/serde_json_lenient/v0_2/README.chromium b/third_party/rust/serde_json_lenient/v0_2/README.chromium index 6260b441..1979a99 100644 --- a/third_party/rust/serde_json_lenient/v0_2/README.chromium +++ b/third_party/rust/serde_json_lenient/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/serde_json_lenient Version: 0.2.4 Revision: ec5b6e7782647f8e165e3d2e619dbe4541071cf7 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/serde_json_lenient-v0_2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/simd_adler32/v0_3/README.chromium b/third_party/rust/simd_adler32/v0_3/README.chromium index 8071d9d..51c9ec6 100644 --- a/third_party/rust/simd_adler32/v0_3/README.chromium +++ b/third_party/rust/simd_adler32/v0_3/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/simd-adler32 Version: 0.3.7 Revision: 94f3f72eb7346d9e2bfe7e985a496582da409a63 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/simd-adler32-v0_3/LICENSE.md Shipped: yes
diff --git a/third_party/rust/skrifa/v0_37/README.chromium b/third_party/rust/skrifa/v0_37/README.chromium index 53b62f2..424ab5c6 100644 --- a/third_party/rust/skrifa/v0_37/README.chromium +++ b/third_party/rust/skrifa/v0_37/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/skrifa Version: 0.37.0 Revision: 1a8baba89aa129a899bc83b0b610881190f8bbad -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/skrifa-v0_37/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/small_ctor/v0_1/README.chromium b/third_party/rust/small_ctor/v0_1/README.chromium index cd7d385..11b29f1 100644 --- a/third_party/rust/small_ctor/v0_1/README.chromium +++ b/third_party/rust/small_ctor/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/small_ctor Version: 0.1.2 Revision: 81ca7a1ff7c309f784a4c20eb99a3aeea43b80ca -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/small_ctor-v0_1/LICENSE Shipped: no
diff --git a/third_party/rust/smallvec/v1/README.chromium b/third_party/rust/smallvec/v1/README.chromium index ab45bfa..e18355c 100644 --- a/third_party/rust/smallvec/v1/README.chromium +++ b/third_party/rust/smallvec/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/smallvec Version: 1.15.1 Revision: d0f47a3ea99296498ee940b5d99f59b403c498a2 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/smallvec-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/stable_deref_trait/v1/README.chromium b/third_party/rust/stable_deref_trait/v1/README.chromium index 40355fb..b8f3f34 100644 --- a/third_party/rust/stable_deref_trait/v1/README.chromium +++ b/third_party/rust/stable_deref_trait/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/stable_deref_trait Version: 1.2.0 Revision: 66f9d8a15b7209c45f58edee6c1b6bb497b7bd31 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/stable_deref_trait-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/static_assertions/v1/README.chromium b/third_party/rust/static_assertions/v1/README.chromium index 437c9d6d..32dc796 100644 --- a/third_party/rust/static_assertions/v1/README.chromium +++ b/third_party/rust/static_assertions/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/static_assertions Version: 1.1.0 Revision: 18bc65a094d890fe1faa5d3ccb70f12b89eabf56 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/static_assertions-v1/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/strck/v1/README.chromium b/third_party/rust/strck/v1/README.chromium index f215230..f3af842 100644 --- a/third_party/rust/strck/v1/README.chromium +++ b/third_party/rust/strck/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/strck Version: 1.0.0 Revision: 4c3add2f9964ce1c5720d7924dbf5291818fc37e -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/strck-v1/LICENSE Shipped: yes
diff --git a/third_party/rust/strsim/v0_11/README.chromium b/third_party/rust/strsim/v0_11/README.chromium index d6e79c6c..0f135ee 100644 --- a/third_party/rust/strsim/v0_11/README.chromium +++ b/third_party/rust/strsim/v0_11/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/strsim Version: 0.11.1 Revision: 76c5a900e6e12cfc605eee5ab6e36300384c8682 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/strsim-v0_11/LICENSE Shipped: no
diff --git a/third_party/rust/strum/v0_27/README.chromium b/third_party/rust/strum/v0_27/README.chromium index c373c60..0f9949e 100644 --- a/third_party/rust/strum/v0_27/README.chromium +++ b/third_party/rust/strum/v0_27/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/strum Version: 0.27.2 Revision: c8d6241123d68b2e56a8d546300508294338f69a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/strum-v0_27/LICENSE Shipped: yes
diff --git a/third_party/rust/strum_macros/v0_27/README.chromium b/third_party/rust/strum_macros/v0_27/README.chromium index 67dd2887..06669e22 100644 --- a/third_party/rust/strum_macros/v0_27/README.chromium +++ b/third_party/rust/strum_macros/v0_27/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/strum_macros Version: 0.27.2 Revision: c8d6241123d68b2e56a8d546300508294338f69a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/strum_macros-v0_27/LICENSE Shipped: yes
diff --git a/third_party/rust/subtle/v2/README.chromium b/third_party/rust/subtle/v2/README.chromium index 21923d8..c3f8c10b 100644 --- a/third_party/rust/subtle/v2/README.chromium +++ b/third_party/rust/subtle/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/subtle Version: 2.6.1 Revision: 5457b5448b021d1da101ababbb854e6657233943 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: BSD-3-Clause License File: //third_party/rust/chromium_crates_io/vendor/subtle-v2/LICENSE Shipped: yes
diff --git a/third_party/rust/symphonia/v0_5/README.chromium b/third_party/rust/symphonia/v0_5/README.chromium index f6b2562..1be7af7e 100644 --- a/third_party/rust/symphonia/v0_5/README.chromium +++ b/third_party/rust/symphonia/v0_5/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/symphonia Version: 0.5.4 Revision: d3b7742fa73674b70d9ab80cc5f8384cc653df3a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MPL-2.0 License File: //third_party/rust/chromium_crates_io/vendor/symphonia-v0_5/LICENSE Shipped: yes
diff --git a/third_party/rust/symphonia_bundle_flac/v0_5/README.chromium b/third_party/rust/symphonia_bundle_flac/v0_5/README.chromium index 67a0923..7cfeaf77 100644 --- a/third_party/rust/symphonia_bundle_flac/v0_5/README.chromium +++ b/third_party/rust/symphonia_bundle_flac/v0_5/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/symphonia-bundle-flac Version: 0.5.4 Revision: d3b7742fa73674b70d9ab80cc5f8384cc653df3a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MPL-2.0 License File: //third_party/rust/chromium_crates_io/vendor/symphonia-bundle-flac-v0_5/LICENSE Shipped: yes
diff --git a/third_party/rust/symphonia_core/v0_5/README.chromium b/third_party/rust/symphonia_core/v0_5/README.chromium index ffaace9..ea86231 100644 --- a/third_party/rust/symphonia_core/v0_5/README.chromium +++ b/third_party/rust/symphonia_core/v0_5/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/symphonia-core Version: 0.5.4 Revision: d3b7742fa73674b70d9ab80cc5f8384cc653df3a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MPL-2.0 License File: //third_party/rust/chromium_crates_io/vendor/symphonia-core-v0_5/LICENSE Shipped: yes
diff --git a/third_party/rust/symphonia_metadata/v0_5/README.chromium b/third_party/rust/symphonia_metadata/v0_5/README.chromium index 0b1e0c0..b52470e5 100644 --- a/third_party/rust/symphonia_metadata/v0_5/README.chromium +++ b/third_party/rust/symphonia_metadata/v0_5/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/symphonia-metadata Version: 0.5.4 Revision: d3b7742fa73674b70d9ab80cc5f8384cc653df3a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MPL-2.0 License File: //third_party/rust/chromium_crates_io/vendor/symphonia-metadata-v0_5/LICENSE Shipped: yes
diff --git a/third_party/rust/symphonia_utils_xiph/v0_5/README.chromium b/third_party/rust/symphonia_utils_xiph/v0_5/README.chromium index d621130..35aaf328 100644 --- a/third_party/rust/symphonia_utils_xiph/v0_5/README.chromium +++ b/third_party/rust/symphonia_utils_xiph/v0_5/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/symphonia-utils-xiph Version: 0.5.4 Revision: d3b7742fa73674b70d9ab80cc5f8384cc653df3a -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MPL-2.0 License File: //third_party/rust/chromium_crates_io/vendor/symphonia-utils-xiph-v0_5/LICENSE Shipped: yes
diff --git a/third_party/rust/syn/v2/README.chromium b/third_party/rust/syn/v2/README.chromium index 4e0f4ef..529c692 100644 --- a/third_party/rust/syn/v2/README.chromium +++ b/third_party/rust/syn/v2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/syn Version: 2.0.106 Revision: 0e4bc64fe1e07a574b6f3133927a27991fd40c2e -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/syn-v2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/synstructure/v0_13/README.chromium b/third_party/rust/synstructure/v0_13/README.chromium index 56c21d5..1ef879a 100644 --- a/third_party/rust/synstructure/v0_13/README.chromium +++ b/third_party/rust/synstructure/v0_13/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/synstructure Version: 0.13.2 Revision: 91ead072fa43c55f35880bd7f75a2b0eab72a04e -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/synstructure-v0_13/LICENSE Shipped: yes
diff --git a/third_party/rust/temporal_capi/v0_1/README.chromium b/third_party/rust/temporal_capi/v0_1/README.chromium index c419b1f..c976f82 100644 --- a/third_party/rust/temporal_capi/v0_1/README.chromium +++ b/third_party/rust/temporal_capi/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/temporal_capi Version: 0.1.0 Revision: 1d1b123ff78a3ab656d5aa19d803d1516f95e92f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/temporal_capi-v0_1/LICENSE-Apache Shipped: yes
diff --git a/third_party/rust/temporal_rs/v0_1/README.chromium b/third_party/rust/temporal_rs/v0_1/README.chromium index f5fba412..937412b 100644 --- a/third_party/rust/temporal_rs/v0_1/README.chromium +++ b/third_party/rust/temporal_rs/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/temporal_rs Version: 0.1.0 Revision: 1d1b123ff78a3ab656d5aa19d803d1516f95e92f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/temporal_rs-v0_1/LICENSE-Apache Shipped: yes
diff --git a/third_party/rust/termcolor/v1/README.chromium b/third_party/rust/termcolor/v1/README.chromium index 11cab0e..11fd00d 100644 --- a/third_party/rust/termcolor/v1/README.chromium +++ b/third_party/rust/termcolor/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/termcolor Version: 1.4.1 Revision: 71f0921f1eeceda85487098588a1602979d52493 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/termcolor-v1/LICENSE-MIT Shipped: yes
diff --git a/third_party/rust/timezone_provider/v0_1/README.chromium b/third_party/rust/timezone_provider/v0_1/README.chromium index 407b4658..8df37c1 100644 --- a/third_party/rust/timezone_provider/v0_1/README.chromium +++ b/third_party/rust/timezone_provider/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/timezone_provider Version: 0.1.0 Revision: 1d1b123ff78a3ab656d5aa19d803d1516f95e92f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/timezone_provider-v0_1/LICENSE-Apache Shipped: yes
diff --git a/third_party/rust/tinystr/v0_8/README.chromium b/third_party/rust/tinystr/v0_8/README.chromium index 05b0dbf..a573d1e 100644 --- a/third_party/rust/tinystr/v0_8/README.chromium +++ b/third_party/rust/tinystr/v0_8/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/tinystr Version: 0.8.1 Revision: f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/tinystr-v0_8/LICENSE Shipped: yes
diff --git a/third_party/rust/toktrie/v1/README.chromium b/third_party/rust/toktrie/v1/README.chromium index dea0cc1f..e49349e 100644 --- a/third_party/rust/toktrie/v1/README.chromium +++ b/third_party/rust/toktrie/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/toktrie Version: 1.2.0 Revision: c65e3c3244713b9ebcc204cc5676c8a4a57f78bf -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/toktrie-v1/LICENSE Shipped: yes
diff --git a/third_party/rust/unicode_ident/v1/README.chromium b/third_party/rust/unicode_ident/v1/README.chromium index 701f83e..fddef5d 100644 --- a/third_party/rust/unicode_ident/v1/README.chromium +++ b/third_party/rust/unicode_ident/v1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/unicode-ident Version: 1.0.19 Revision: dc018bf1ca82d295f72a84e7ed432e5d2bcbe2fe -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0, Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/unicode-ident-v1/LICENSE-APACHE,//third_party/rust/chromium_crates_io/vendor/unicode-ident-v1/LICENSE-UNICODE Shipped: yes
diff --git a/third_party/rust/unicode_width/v0_2/README.chromium b/third_party/rust/unicode_width/v0_2/README.chromium index 1bddd46..3b31c102 100644 --- a/third_party/rust/unicode_width/v0_2/README.chromium +++ b/third_party/rust/unicode_width/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/unicode-width Version: 0.2.1 Revision: 0085e91db72ae9a4498e62030d9651f1c1d09b4f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/unicode-width-v0_2/LICENSE-APACHE Shipped: yes
diff --git a/third_party/rust/winapi_util/v0_1/README.chromium b/third_party/rust/winapi_util/v0_1/README.chromium index 1213efd..171c2b7 100644 --- a/third_party/rust/winapi_util/v0_1/README.chromium +++ b/third_party/rust/winapi_util/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/winapi-util Version: 0.1.11 Revision: 803874c57dc1f10ecd42f7c86d9de72f53818432 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/winapi-util-v0_1/LICENSE-MIT Shipped: yes
diff --git a/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium b/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium index fb2a91ce..269fca600 100644 --- a/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium +++ b/third_party/rust/windows_aarch64_msvc/v0_52/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/windows_aarch64_msvc Version: 0.52.6 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/windows_aarch64_msvc-v0_52/license-apache-2.0 Shipped: yes
diff --git a/third_party/rust/windows_i686_msvc/v0_52/README.chromium b/third_party/rust/windows_i686_msvc/v0_52/README.chromium index a93faaa66..4df9253 100644 --- a/third_party/rust/windows_i686_msvc/v0_52/README.chromium +++ b/third_party/rust/windows_i686_msvc/v0_52/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/windows_i686_msvc Version: 0.52.6 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/windows_i686_msvc-v0_52/license-apache-2.0 Shipped: yes
diff --git a/third_party/rust/windows_sys/v0_52/README.chromium b/third_party/rust/windows_sys/v0_52/README.chromium index c8b0105..ed9829e 100644 --- a/third_party/rust/windows_sys/v0_52/README.chromium +++ b/third_party/rust/windows_sys/v0_52/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/windows-sys Version: 0.52.0 Revision: 3a605cba064b26f2a198ac58085f8c8836f47c38 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/windows-sys-v0_52/license-apache-2.0 Shipped: yes
diff --git a/third_party/rust/windows_targets/v0_52/README.chromium b/third_party/rust/windows_targets/v0_52/README.chromium index 95449a78..66226cb 100644 --- a/third_party/rust/windows_targets/v0_52/README.chromium +++ b/third_party/rust/windows_targets/v0_52/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/windows-targets Version: 0.52.6 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/windows-targets-v0_52/license-apache-2.0 Shipped: yes
diff --git a/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium b/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium index 3f3d03f..8aa1e9b1 100644 --- a/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium +++ b/third_party/rust/windows_x86_64_msvc/v0_52/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/windows_x86_64_msvc Version: 0.52.6 Revision: db06b51c2ebb743efb544d40e3064efa49f28d38 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Apache-2.0 License File: //third_party/rust/chromium_crates_io/vendor/windows_x86_64_msvc-v0_52/license-apache-2.0 Shipped: yes
diff --git a/third_party/rust/writeable/v0_6/README.chromium b/third_party/rust/writeable/v0_6/README.chromium index 3aea2866..367847b4 100644 --- a/third_party/rust/writeable/v0_6/README.chromium +++ b/third_party/rust/writeable/v0_6/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/writeable Version: 0.6.1 Revision: e9ab7308efb2fdc0fca96f71106c68f9f5840056 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/writeable-v0_6/LICENSE Shipped: yes
diff --git a/third_party/rust/yoke/v0_8/README.chromium b/third_party/rust/yoke/v0_8/README.chromium index bce5620..6dac633f 100644 --- a/third_party/rust/yoke/v0_8/README.chromium +++ b/third_party/rust/yoke/v0_8/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/yoke Version: 0.8.0 Revision: f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/yoke-v0_8/LICENSE Shipped: yes
diff --git a/third_party/rust/yoke_derive/v0_8/README.chromium b/third_party/rust/yoke_derive/v0_8/README.chromium index 57a6376..b8a7f75 100644 --- a/third_party/rust/yoke_derive/v0_8/README.chromium +++ b/third_party/rust/yoke_derive/v0_8/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/yoke-derive Version: 0.8.0 Revision: f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/yoke-derive-v0_8/LICENSE Shipped: yes
diff --git a/third_party/rust/zerofrom/v0_1/README.chromium b/third_party/rust/zerofrom/v0_1/README.chromium index 8c51421c..6cec69f3 100644 --- a/third_party/rust/zerofrom/v0_1/README.chromium +++ b/third_party/rust/zerofrom/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/zerofrom Version: 0.1.6 Revision: f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/zerofrom-v0_1/LICENSE Shipped: yes
diff --git a/third_party/rust/zerofrom_derive/v0_1/README.chromium b/third_party/rust/zerofrom_derive/v0_1/README.chromium index be30c4f..c694510 100644 --- a/third_party/rust/zerofrom_derive/v0_1/README.chromium +++ b/third_party/rust/zerofrom_derive/v0_1/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/zerofrom-derive Version: 0.1.6 Revision: f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/zerofrom-derive-v0_1/LICENSE Shipped: yes
diff --git a/third_party/rust/zerotrie/v0_2/README.chromium b/third_party/rust/zerotrie/v0_2/README.chromium index fe81530..9252b17 100644 --- a/third_party/rust/zerotrie/v0_2/README.chromium +++ b/third_party/rust/zerotrie/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/zerotrie Version: 0.2.2 Revision: 5e404744dd6c9dd7f86aac82586e3fa98ea75f7f -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/zerotrie-v0_2/LICENSE Shipped: yes
diff --git a/third_party/rust/zerovec/v0_11/README.chromium b/third_party/rust/zerovec/v0_11/README.chromium index 1f44b2e8..ab73938 100644 --- a/third_party/rust/zerovec/v0_11/README.chromium +++ b/third_party/rust/zerovec/v0_11/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/zerovec Version: 0.11.4 Revision: 23b31cd3b6fe6d6d58e9211e0c87689194638efd -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/zerovec-v0_11/LICENSE Shipped: yes
diff --git a/third_party/rust/zerovec_derive/v0_11/README.chromium b/third_party/rust/zerovec_derive/v0_11/README.chromium index 8aad5e09..68f9d9b 100644 --- a/third_party/rust/zerovec_derive/v0_11/README.chromium +++ b/third_party/rust/zerovec_derive/v0_11/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/zerovec-derive Version: 0.11.1 Revision: f4290a877dfcb0f87cad6de4abdd65f0cbb33c9c -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/zerovec-derive-v0_11/LICENSE Shipped: yes
diff --git a/third_party/rust/zip/v5/README.chromium b/third_party/rust/zip/v5/README.chromium index fe854aaf..851976b5 100644 --- a/third_party/rust/zip/v5/README.chromium +++ b/third_party/rust/zip/v5/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/zip Version: 5.1.1 Revision: 6423fee132a8819c82c2cf73ea6fb07dd3016b72 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: MIT License File: //third_party/rust/chromium_crates_io/vendor/zip-v5/LICENSE Shipped: yes
diff --git a/third_party/rust/zoneinfo64/v0_2/README.chromium b/third_party/rust/zoneinfo64/v0_2/README.chromium index aa3f52a7..4b3e513 100644 --- a/third_party/rust/zoneinfo64/v0_2/README.chromium +++ b/third_party/rust/zoneinfo64/v0_2/README.chromium
@@ -2,7 +2,7 @@ URL: https://crates.io/crates/zoneinfo64 Version: 0.2.0 Revision: c1c377b49af283bdf89937b4f5ce516710e55a37 -Update Mechanism: Manual +Update Mechanism: Manual (https://crbug.com/449898466) License: Unicode-3.0 License File: //third_party/rust/chromium_crates_io/vendor/zoneinfo64-v0_2/LICENSE Shipped: yes
diff --git a/third_party/skia b/third_party/skia index 3480f588..e4dc4fd 160000 --- a/third_party/skia +++ b/third_party/skia
@@ -1 +1 @@ -Subproject commit 3480f588eb09d25a4b1c15e643197a1eef058718 +Subproject commit e4dc4fdb541d30b786d373b09217d769d06ed946
diff --git a/third_party/vulkan-deps b/third_party/vulkan-deps index cd34cfe6..90603b2 160000 --- a/third_party/vulkan-deps +++ b/third_party/vulkan-deps
@@ -1 +1 @@ -Subproject commit cd34cfe6a579d03c0675b32844599294773634aa +Subproject commit 90603b2036a87d17dde4d38f5fa16fc770961e94
diff --git a/third_party/vulkan-validation-layers/src b/third_party/vulkan-validation-layers/src index 07a7e8a..1acbea5 160000 --- a/third_party/vulkan-validation-layers/src +++ b/third_party/vulkan-validation-layers/src
@@ -1 +1 @@ -Subproject commit 07a7e8afd318ba34ac2a999002e6602d88205c41 +Subproject commit 1acbea52c1e445b9398ecc228cb3bb115d97aac5
diff --git a/third_party/webrtc b/third_party/webrtc index 85cbfaf..661a2e6 160000 --- a/third_party/webrtc +++ b/third_party/webrtc
@@ -1 +1 @@ -Subproject commit 85cbfaf6b96394215415527d67546d4bd872208a +Subproject commit 661a2e642d3bec939e203650fb0b86e1af815c63
diff --git a/tools/crates/gnrt/lib/readme.rs b/tools/crates/gnrt/lib/readme.rs index 6bb911c..609a9c71 100644 --- a/tools/crates/gnrt/lib/readme.rs +++ b/tools/crates/gnrt/lib/readme.rs
@@ -20,12 +20,6 @@ use strum_macros::EnumIter; #[derive(Clone, Debug, Serialize)] -pub enum UpdateMechanism { - Autoroll, - Manual, -} - -#[derive(Clone, Debug, Serialize)] pub struct ReadmeFile { name: String, url: String, @@ -36,7 +30,7 @@ license: String, license_files: Vec<String>, revision: Option<String>, - update_mechanism: UpdateMechanism, + update_mechanism: String, } /// Returns a map keyed by the directory where the README file should be @@ -201,9 +195,10 @@ license, license_files, revision, - // TODO(crbug.com/427084604): Currently all packages are rolled manually. - // Set to `UpdateMechanism::Autoroll` when automatic rolls are supported. - update_mechanism: UpdateMechanism::Manual, + // All Rust dependencies are granted a shared temporary exemption for + // autorolling, because while they are manually rolled, they are + // well managed. + update_mechanism: "Manual (https://crbug.com/449898466)".to_string(), }; Ok((crate_build_dir, readme))
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 72cad6c..3e1ccfc 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -586,6 +586,10 @@ "META": {"sizes": {"includes": [20]}}, "includes": [4660], }, + "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/reload_button/resources.grd": { + "META": {"sizes": {"includes": [10]}}, + "includes": [4670], + }, "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/sandbox_internals/resources.grd": { "META": {"sizes": {"includes": [5],}}, "includes": [4680],
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index f30a3de..0d82c9a 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -2606,6 +2606,7 @@ <int value="49" label="Enter Picture in Picture"/> <int value="50" label="Exit Picture in Picture"/> <int value="51" label="Open in Incognito window"/> + <int value="52" label="View page source"/> </enum> <!-- LINT.ThenChange(//chrome/android/java/src/org/chromium/chrome/browser/contextmenu/ChromeContextMenuPopulator.java:ContextMenuUma.Action) --> @@ -16368,6 +16369,7 @@ label="UnifiedPasswordManagerLocalPasswordsAndroidAccessLossWarning:disabled"/> <int value="773919225" label="disable-office-editing-component-extension"/> <int value="773952982" label="ReduceIPAddressChangeNotification:disabled"/> + <int value="774417826" label="VidsAppPreinstall:enabled"/> <int value="775075949" label="ImeInputLogicHmm:enabled"/> <int value="775148009" label="OsSettingsDeepLinking:disabled"/> <int value="775373286" label="TabModelInitFixes:enabled"/> @@ -19146,6 +19148,7 @@ <int value="1764618580" label="MojoLinuxChannelSharedMem:disabled"/> <int value="1765184717" label="HighlightManagedPrefDisclaimerAndroid:disabled"/> + <int value="1765591001" label="VidsAppPreinstall:disabled"/> <int value="1766048620" label="FedCmError:enabled"/> <int value="1766676896" label="affiliation-based-matching:disabled"/> <int value="1767218791" label="TouchDragAndContextMenu:enabled"/>
diff --git a/tools/metrics/histograms/metadata/android/enums.xml b/tools/metrics/histograms/metadata/android/enums.xml index c183faf..fc87f016 100644 --- a/tools/metrics/histograms/metadata/android/enums.xml +++ b/tools/metrics/histograms/metadata/android/enums.xml
@@ -825,7 +825,7 @@ <enum name="BackupNavbarInsetsSource"> <int value="0" label="None"/> - <int value="1" label="Tappable Element"/> + <int value="1" label="Tappable Element (Deprecated)"/> <int value="2" label="Mandatory system gestures"/> <int value="3" label="Filtered explicitly disabled"/> <int value="4" label="Filtered weaker signals"/>
diff --git a/tools/metrics/histograms/metadata/android/histograms.xml b/tools/metrics/histograms/metadata/android/histograms.xml index 92f0628..9fbbf0d8 100644 --- a/tools/metrics/histograms/metadata/android/histograms.xml +++ b/tools/metrics/histograms/metadata/android/histograms.xml
@@ -1812,31 +1812,10 @@ <summary> Records the duration in ms of drag process when drop happend inside ContentView containing web contents, regardless DragEvent#getResult. Does - not capture drag events that end outside the ContentView (Use - Android.DragDrop.FromWebContent.Duration instead). Android only. + not capture drag events that end outside the ContentView. Android only. </summary> </histogram> -<histogram name="Android.DragDrop.FromWebContent.Duration.{DropResult}" - units="ms" expires_after="2025-09-14"> - <owner>wenyufu@chromium.org</owner> - <owner>clank-large-form-factors@google.com</owner> - <summary> - Records the duration in ms of drag process when {DropResult}. Recorded for - the drag process starts from the web content, and drop happens outside of - the web content. Does not capture drag events that end inside the - ContentView containing web contents. Recorded when such a drag event ends. - Android only. - - For more information regarding drag results, see: - https://developer.android.com/reference/android/view/DragEvent#getResult() - </summary> - <token key="DropResult"> - <variant name="Canceled" summary="DragEvent#getResult() returns false."/> - <variant name="Success" summary="DragEvent#getResult() returns true."/> - </token> -</histogram> - <histogram name="Android.DragDrop.FromWebContent.TargetType" enum="AndroidDragTargetType" expires_after="2026-03-01"> <owner>wenyufu@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index 02693fd..f6bec4f 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -5441,6 +5441,17 @@ </summary> </histogram> +<histogram name="IOS.SafariImport.Import.TapBackOnStage" + enum="SafariDataImportStage" expires_after="2026-03-29"> + <owner>ginnyhuang@chromium.org</owner> + <owner>bling-pandamonium@google.com</owner> + <summary> + Logs the import stage when the user taps the "back" button import + screen. Should only be applicable for "not started" and + "ready to import" stages. + </summary> +</histogram> + <histogram name="IOS.SafeBrowsing.Enhanced.Infobar.Interaction" enum="IOSEnhancedSafeBrowseringInfobarInteraction" expires_after="2026-06-26">
diff --git a/tools/metrics/histograms/metadata/net/histograms.xml b/tools/metrics/histograms/metadata/net/histograms.xml index 286e158..ed914ec 100644 --- a/tools/metrics/histograms/metadata/net/histograms.xml +++ b/tools/metrics/histograms/metadata/net/histograms.xml
@@ -8279,13 +8279,32 @@ expires_after="2026-02-09"> <owner>yoichio@chromium.org</owner> <owner>chrome-loading@google.com</owner> + <improvement direction="LOWER_IS_BETTER"/> <summary> Records the proportion of writes when URLLoader was blocked by - MOJO_RESULT_SHOULD_WAIT where the renderer process seems to be busy. Lower - is better. Logged every time a URLLoader completes a load. + MOJO_RESULT_SHOULD_WAIT where the renderer process seems to be busy. Logged + every time a URLLoader completes a load. </summary> </histogram> +<histogram + name="Net.URLLoader.SlopBucket.ProportionOfWritesBlockedByMojo.{CacheEntryStatus}" + units="%" expires_after="2026-02-09"> + <owner>yoichio@chromium.org</owner> + <owner>chrome-loading@google.com</owner> + <improvement direction="LOWER_IS_BETTER"/> + <summary> + Records the proportion of writes when URLLoader was blocked by + MOJO_RESULT_SHOULD_WAIT where the renderer process seems to be busy. Logged + every time a URLLoader completes a load and only when SlopBucket is actually + used and response cache type is {CacheEntryStatus}. + </summary> + <token key="CacheEntryStatus"> + <variant name="All"/> + <variant name="NoCache"/> + </token> +</histogram> + <histogram name="Net.URLLoaderThrottle.OnReceiveResponseTime" units="ms" expires_after="2026-03-01"> <owner>nidhijaju@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/page/histograms.xml b/tools/metrics/histograms/metadata/page/histograms.xml index 788ee65..f147f35 100644 --- a/tools/metrics/histograms/metadata/page/histograms.xml +++ b/tools/metrics/histograms/metadata/page/histograms.xml
@@ -1278,6 +1278,9 @@ <variant name="HST" summary="to reach the head chunk start"/> <variant name="SCT" summary="from the server response time to receive the body chunk"/> + <variant name="SGL" + summary="from the previous navigation to the reload that triggers + this navigation"/> <variant name="SRT" summary="from the navigation start to receive the HTTP headers"/> <variant name="TimeBetweenHCTAndSCT" @@ -1614,6 +1617,8 @@ </summary> <token key="MileStone"> <variant name="AFTEnd2" summary="AFT end event is sent"/> + <variant name="AFTEndWithPreNavigationLatency" + summary="AFT end event is sent with pre-navigation latency"/> <variant name="AFTStart2" summary="AFT start event is sent"/> <variant name="BodyChunkEnd2" summary="end of the header chunk start event is sent"/>
diff --git a/tools/metrics/histograms/metadata/startup/enums.xml b/tools/metrics/histograms/metadata/startup/enums.xml index 268a07e..7494e11 100644 --- a/tools/metrics/histograms/metadata/startup/enums.xml +++ b/tools/metrics/histograms/metadata/startup/enums.xml
@@ -113,6 +113,8 @@ <int value="3" label="Broadcast Receiver"/> </enum> +<!-- LINT.IfChange(StartupTemperature) --> + <enum name="StartupTemperature"> <int value="0" label="Cold startup (mostly hard faults)"/> <int value="1" label="Warm startup (nearly no hard faults)"/> @@ -120,6 +122,8 @@ <int value="3" label="Unable to determine the startup temperature"/> </enum> +<!-- LINT.ThenChange(//components/startup_metric_utils/browser/startup_metric_utils.h:StartupTemperature) --> + </enums> </histogram-configuration>
diff --git a/tools/metrics/histograms/metadata/ui/enums.xml b/tools/metrics/histograms/metadata/ui/enums.xml index 7483647..0515985 100644 --- a/tools/metrics/histograms/metadata/ui/enums.xml +++ b/tools/metrics/histograms/metadata/ui/enums.xml
@@ -624,6 +624,7 @@ <int value="-1949142440" label="chrome://smb-credentials-dialog/"/> <int value="-1941995226" label="chrome://attribution-internals/"/> <int value="-1911971715" label="chrome://history/"/> + <int value="-1905481895" label="chrome://reload-button.top-chrome/"/> <int value="-1899361569" label="chrome-untrusted://eche-app/"/> <int value="-1887206190" label="chrome://nfc-debug/"/> <int value="-1877210733" label="chrome-untrusted://privacy-sandbox-dialog/"/>
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index d840e63..54671fb 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -5,8 +5,8 @@ "full_remote_path": "perfetto-luci-artifacts/v52.0/linux-arm64/trace_processor_shell" }, "win": { - "hash": "6fdad3f95d3c19e7b9fa7c5e968f9cc3063fad94", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/eced455f5d17079fef42f07fc82fa37fcf17c338/trace_processor_shell.exe" + "hash": "6f322c5ad508809f050144220c0b0ca2c81aa3a6", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/d7ea394300667faed7b239e087a51447586a3132/trace_processor_shell.exe" }, "linux_arm": { "hash": "46d798c1864490cbb2ee053d6eda436184470e69", @@ -21,8 +21,8 @@ "full_remote_path": "perfetto-luci-artifacts/ebf44e57a3b734c5281bdff53d9945805486004e/mac-arm64/trace_processor_shell" }, "linux": { - "hash": "bfb880cc4d2608b1a324b2169d790d9b88e256da", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/11a3d5fb3890853111293ec0991ebff03b28a4f6/trace_processor_shell" + "hash": "a1ede3006d8e33c6c0533c36a1a66106549b0484", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/d7ea394300667faed7b239e087a51447586a3132/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/ui/accessibility/accessibility_features.cc b/ui/accessibility/accessibility_features.cc index 0377c03..f4a6867 100644 --- a/ui/accessibility/accessibility_features.cc +++ b/ui/accessibility/accessibility_features.cc
@@ -399,6 +399,11 @@ ::features::kDataCollectionModeForScreen2x); } +BASE_FEATURE(kImmersiveReadingMode, base::FEATURE_DISABLED_BY_DEFAULT); +bool IsImmersiveReadingModeEnabled() { + return base::FeatureList::IsEnabled(::features::kImmersiveReadingMode); +} + BASE_FEATURE(kMainNodeAnnotations, base::FEATURE_DISABLED_BY_DEFAULT); bool IsMainNodeAnnotationsEnabled() { return base::FeatureList::IsEnabled(::features::kMainNodeAnnotations);
diff --git a/ui/accessibility/accessibility_features.h b/ui/accessibility/accessibility_features.h index e1011b0..15f37f3 100644 --- a/ui/accessibility/accessibility_features.h +++ b/ui/accessibility/accessibility_features.h
@@ -316,6 +316,10 @@ AX_BASE_EXPORT BASE_DECLARE_FEATURE(kDataCollectionModeForScreen2x); AX_BASE_EXPORT bool IsDataCollectionModeForScreen2xEnabled(); +// Enable Immersive Mode for Read Anything. +AX_BASE_EXPORT BASE_DECLARE_FEATURE(kImmersiveReadingMode); +AX_BASE_EXPORT bool IsImmersiveReadingModeEnabled(); + // Identify and annotate the main node of the AXTree where one was not already // provided. AX_BASE_EXPORT BASE_DECLARE_FEATURE(kMainNodeAnnotations);
diff --git a/ui/android/BUILD.gn b/ui/android/BUILD.gn index 2a4ddd0b..4811910f 100644 --- a/ui/android/BUILD.gn +++ b/ui/android/BUILD.gn
@@ -565,6 +565,7 @@ "java/src/org/chromium/ui/widget/ViewLookupCachingFrameLayout.java", "java/src/org/chromium/ui/widget/ViewRectProvider.java", "java/src/org/chromium/ui/widget/ViewRectUpdater.java", + "java/src/org/chromium/ui/widget/WindowBoundsChangeDetector.java", "java/src/org/chromium/ui/xr/scenecore/XrSceneCoreSessionInitializer.java", "java/src/org/chromium/ui/xr/scenecore/XrSceneCoreSessionManager.java", ]
diff --git a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java index 66d2d9b..b422fb1 100644 --- a/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java +++ b/ui/android/java/src/org/chromium/ui/dragdrop/DragAndDropDelegateImpl.java
@@ -437,8 +437,6 @@ // Only record metrics when drop does not happen for ContentView. if (!mIsDropOnView) { assert mDragStartSystemElapsedTime > 0; - long dragDuration = SystemClock.elapsedRealtime() - mDragStartSystemElapsedTime; - recordDragDurationAndResult(dragDuration, dragResult); recordDragTargetType(mDragTargetType); } // Allow drop into ContentView when files are supported by clank. @@ -486,10 +484,4 @@ RecordHistogram.recordEnumeratedHistogram( "Android.DragDrop.FromWebContent.TargetType", type, DragTargetType.NUM_ENTRIES); } - - private void recordDragDurationAndResult(long duration, boolean result) { - String histogramPrefix = "Android.DragDrop.FromWebContent.Duration."; - String suffix = result ? "Success" : "Canceled"; - RecordHistogram.deprecatedRecordMediumTimesHistogram(histogramPrefix + suffix, duration); - } }
diff --git a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuHost.java b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuHost.java index 6501b39..c2697bec 100644 --- a/ui/android/java/src/org/chromium/ui/listmenu/ListMenuHost.java +++ b/ui/android/java/src/org/chromium/ui/listmenu/ListMenuHost.java
@@ -132,6 +132,11 @@ } } + /** Returns whether the popup menu is currently showing. */ + public boolean isMenuShowing() { + return mPopupMenus.size() > 0; + } + /** Shows a popupWindow built by ListMenuButton */ public void showMenu() { if (!mView.isAttachedToWindow()) return; @@ -182,6 +187,7 @@ new ColorDrawable(Color.TRANSPARENT), () -> contentView, mDelegate.getRectProvider(mView)) + .setDismissOnScreenSizeChange(true) .setVerticalOverlapAnchor(mMenuVerticalOverlapAnchor) .setHorizontalOverlapAnchor(mMenuHorizontalOverlapAnchor) .setMaxWidth(mMenuMaxWidth)
diff --git a/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java b/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java index 2a9adcfa..e1830fb 100644 --- a/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java +++ b/ui/android/java/src/org/chromium/ui/widget/AnchoredPopupWindow.java
@@ -243,6 +243,8 @@ private @StyleRes int mAnimationStyleId; private boolean mAnimateFromAnchor; + private boolean mDismissOnScreenSizeChange; + private @Nullable WindowBoundsChangeDetector mWindowBoundsChangeDetector; /** A builder for {@link AnchoredPopupWindow} instances. */ public static class Builder { @@ -270,6 +272,7 @@ private int mPreferredHorizontalOrientation = HorizontalOrientation.MAX_AVAILABLE_SPACE; private boolean mDismissOnTouchInteraction; + private boolean mDismissOnScreenSizeChange; private boolean mVerticalOverlapAnchor; private boolean mHorizontalOverlapAnchor; private boolean mUpdateOrientationOnChange; @@ -417,6 +420,14 @@ } /** + * @param dismiss Whether or not to dismiss this popup when the screen size changes. + */ + public Builder setDismissOnScreenSizeChange(boolean dismiss) { + mDismissOnScreenSizeChange = dismiss; + return this; + } + + /** * @param overlap Whether the popup should vertically overlap the anchor. */ public Builder setVerticalOverlapAnchor(boolean overlap) { @@ -538,6 +549,7 @@ setPreferredVerticalOrientation(builder.mPreferredVerticalOrientation); setPreferredHorizontalOrientation(builder.mPreferredHorizontalOrientation); setDismissOnTouchInteraction(builder.mDismissOnTouchInteraction); + setDismissOnScreenSizeChange(builder.mDismissOnScreenSizeChange); setVerticalOverlapAnchor(builder.mVerticalOverlapAnchor); setHorizontalOverlapAnchor(builder.mHorizontalOverlapAnchor); setUpdateOrientationOnChange(builder.mUpdateOrientationOnChange); @@ -665,6 +677,10 @@ public void show() { if (mPopupWindow.isShowing()) return; + if (mDismissOnScreenSizeChange) { + mWindowBoundsChangeDetector = new WindowBoundsChangeDetector(mRootView, this::dismiss); + } + mRectProvider.startObserving(this); mViewportRectProvider.startObserving(this); @@ -678,6 +694,10 @@ * @see PopupWindow#dismiss() */ public void dismiss() { + if (mWindowBoundsChangeDetector != null) { + mWindowBoundsChangeDetector.detach(); + mWindowBoundsChangeDetector = null; + } mPopupWindow.dismiss(); } @@ -744,6 +764,15 @@ } /** + * @param dismiss Whether or not to dismiss this popup when the screen size changes. + * @deprecated Use the {@link Builder} to set this value during construction. + */ + @Deprecated + public void setDismissOnScreenSizeChange(boolean dismiss) { + mDismissOnScreenSizeChange = dismiss; + } + + /** * If set to true, popup will be notified when an outside touch happens. It is not the * equivalent of closing the popup on all touch events. The user can still interact with the * popup by sending inside touch events. If set to false, the popup won't be notified about the
diff --git a/ui/android/java/src/org/chromium/ui/widget/WindowBoundsChangeDetector.java b/ui/android/java/src/org/chromium/ui/widget/WindowBoundsChangeDetector.java new file mode 100644 index 0000000..a04f00b8 --- /dev/null +++ b/ui/android/java/src/org/chromium/ui/widget/WindowBoundsChangeDetector.java
@@ -0,0 +1,55 @@ +// 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. + +package org.chromium.ui.widget; + +import android.graphics.Rect; +import android.view.View; + +import org.chromium.build.annotations.NullMarked; + +/** A utility class to detect changes in a view's bounds. */ +@NullMarked +public class WindowBoundsChangeDetector implements View.OnLayoutChangeListener { + private final View mView; + private final Runnable mOnBoundsChangedCallback; + private final Rect mCachedBounds = new Rect(); + + /** + * Constructs a new {@link WindowBoundsChangeDetector}. + * + * @param view The view to observe for layout changes. + * @param onBoundsChangedCallback The callback to run when the view's bounds change. + */ + public WindowBoundsChangeDetector(View view, Runnable onBoundsChangedCallback) { + mView = view; + mOnBoundsChangedCallback = onBoundsChangedCallback; + mView.addOnLayoutChangeListener(this); + mCachedBounds.set(0, 0, view.getWidth(), view.getHeight()); + } + + @Override + public void onLayoutChange( + View v, + int left, + int top, + int right, + int bottom, + int oldLeft, + int oldTop, + int oldRight, + int oldBottom) { + int width = right - left; + int height = bottom - top; + if (mCachedBounds.width() != width || mCachedBounds.height() != height) { + mCachedBounds.set(0, 0, width, height); + mOnBoundsChangedCallback.run(); + } + } + + /** Stops observing the view for layout changes. */ + public void detach() { + mView.removeOnLayoutChangeListener(this); + } +}
diff --git a/ui/android/junit/src/org/chromium/ui/dragdrop/DragAndDropDelegateImplUnitTest.java b/ui/android/junit/src/org/chromium/ui/dragdrop/DragAndDropDelegateImplUnitTest.java index 2c79c42..73c9c95 100644 --- a/ui/android/junit/src/org/chromium/ui/dragdrop/DragAndDropDelegateImplUnitTest.java +++ b/ui/android/junit/src/org/chromium/ui/dragdrop/DragAndDropDelegateImplUnitTest.java
@@ -700,11 +700,6 @@ } private void assertDragOutsideWebContentHistogramsRecorded(boolean dropResult) { - // Verify drop outside metrics recorded. - final String histogram = - "Android.DragDrop.FromWebContent.Duration." + (dropResult ? "Success" : "Canceled"); - assertHistogramRecorded(histogram, true, "Drop outside of web content."); - // Verify drop inside metrics not recorded. assertHistogramRecorded( "Android.DragDrop.FromWebContent.DropInWebContent.Duration", @@ -718,16 +713,6 @@ "Android.DragDrop.FromWebContent.DropInWebContent.Duration", true, "Drop inside web content."); - - // Verify drop outside metrics not recorded. - assertHistogramRecorded( - "Android.DragDrop.FromWebContent.Duration.Success", - false, - "Should not recorded when drop inside web content."); - assertHistogramRecorded( - "Android.DragDrop.FromWebContent.Duration.Canceled", - false, - "Should not recorded when drop inside web content."); } private void assertHistogramRecorded(String histogram, boolean recorded, String reason) {
diff --git a/ui/display/manager/display_change_observer_unittest.cc b/ui/display/manager/display_change_observer_unittest.cc index 8417818..ce62c37 100644 --- a/ui/display/manager/display_change_observer_unittest.cc +++ b/ui/display/manager/display_change_observer_unittest.cc
@@ -495,9 +495,8 @@ const auto display_color_spaces = display_info.display_color_spaces(); EXPECT_FALSE(display_color_spaces.SupportsHDR()); - EXPECT_EQ( - DisplaySnapshot::PrimaryFormat(), - display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kSRGB, + EXPECT_EQ(DisplaySnapshot::PrimarySharedImageFormat(), + display_color_spaces.GetOutputFormat(gfx::ContentColorUsage::kSRGB, /*needs_alpha=*/true)); const auto color_space = display_color_spaces.GetRasterAndCompositeColorSpace( @@ -528,9 +527,8 @@ const auto display_color_spaces = display_info.display_color_spaces(); EXPECT_FALSE(display_color_spaces.SupportsHDR()); - EXPECT_EQ( - DisplaySnapshot::PrimaryFormat(), - display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kSRGB, + EXPECT_EQ(DisplaySnapshot::PrimarySharedImageFormat(), + display_color_spaces.GetOutputFormat(gfx::ContentColorUsage::kSRGB, /*needs_alpha=*/true)); const auto color_space = display_color_spaces.GetRasterAndCompositeColorSpace( @@ -561,9 +559,8 @@ const auto display_color_spaces = display_info.display_color_spaces(); EXPECT_FALSE(display_color_spaces.SupportsHDR()); - EXPECT_EQ( - DisplaySnapshot::PrimaryFormat(), - display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kSRGB, + EXPECT_EQ(DisplaySnapshot::PrimarySharedImageFormat(), + display_color_spaces.GetOutputFormat(gfx::ContentColorUsage::kSRGB, /*needs_alpha=*/true)); const auto color_space = display_color_spaces.GetRasterAndCompositeColorSpace( @@ -609,17 +606,15 @@ EXPECT_TRUE(display_color_spaces.SupportsHDR()); // Ensure that all spaces be HDR10, and have headroom of 3x (609/203). - EXPECT_EQ( - gfx::BufferFormat::RGBA_1010102, - display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kSRGB, + EXPECT_EQ(viz::SinglePlaneFormat::kRGBA_1010102, + display_color_spaces.GetOutputFormat(gfx::ContentColorUsage::kSRGB, /*needs_alpha=*/true)); EXPECT_EQ( gfx::ColorSpace::CreateHDR10(), display_color_spaces.GetOutputColorSpace(gfx::ContentColorUsage::kSRGB, /*needs_alpha=*/true)); - EXPECT_EQ( - gfx::BufferFormat::RGBA_1010102, - display_color_spaces.GetOutputBufferFormat(gfx::ContentColorUsage::kHDR, + EXPECT_EQ(viz::SinglePlaneFormat::kRGBA_1010102, + display_color_spaces.GetOutputFormat(gfx::ContentColorUsage::kHDR, /*needs_alpha=*/true)); EXPECT_EQ( gfx::ColorSpace::CreateHDR10(),
diff --git a/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/EdgeToEdgeManager.java b/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/EdgeToEdgeManager.java index ca1374d..f500457f 100644 --- a/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/EdgeToEdgeManager.java +++ b/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/EdgeToEdgeManager.java
@@ -59,7 +59,7 @@ }) public @interface BackupNavbarInsetsSource { int NO_APPLICABLE_BACKUP = 0; - int TAPPABLE_ELEMENT = 1; + @Deprecated int TAPPABLE_ELEMENT = 1; int MANDATORY_SYSTEM_GESTURES = 2; int FILTERED_EXPLICITLY_DISABLED = 3; int FILTERED_WEAKER_SIGNALS = 4; @@ -173,7 +173,6 @@ WindowInsetsCompat windowInsets, @BackupNavbarInsetsCallSite String callSite, EdgeToEdgeFieldTrial useBackupNavbarInsetsFieldTrial, - boolean canUseTappableElementInsets, boolean canUseMandatoryGesturesInsets) { if (!useBackupNavbarInsetsFieldTrial.isEnabledForManufacturerVersion()) { recordBackupNavbarInsetsHistogram( @@ -181,22 +180,7 @@ return null; } - // Check clearer signals, like the tappable element, first. - - Insets tappableInsets = windowInsets.getInsets(WindowInsetsCompat.Type.tappableElement()); - // A single non-zero tappable inset is most likely the navigation bar, even if the - // navigation bar insets are missing for some reason. Tappable elements are strong - // signals for the presence of tappable system bars, and are used to distinguish between - // gesture and tappable navigation, and thus should be a reliable signal for detecting a - // navigation bar, even if the navigation bar inset is missing for some reason. - // The top inset should be ignored, as that would correspond to the status bar. - if (WindowInsetsUtils.hasOneNonZeroInsetExcludingTop(tappableInsets) - && canUseTappableElementInsets) { - recordBackupNavbarInsetsHistogram(callSite, BackupNavbarInsetsSource.TAPPABLE_ELEMENT); - return Insets.of(tappableInsets.left, 0, tappableInsets.right, tappableInsets.bottom); - } - - // Restrict less clear signals, like the system gestures, if non-zero navigation bar insets + // Restrict weak signals, like the system gestures, if non-zero navigation bar insets // have previously been seen during the session for this Activity / window. if (hasSeenNonZeroNavigationBarInsets) { recordBackupNavbarInsetsHistogram(
diff --git a/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java b/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java index 83359b0..026b731 100644 --- a/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java +++ b/ui/edge_to_edge/android/java/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutCoordinator.java
@@ -51,7 +51,6 @@ private final boolean mUseBackupNavbarInsetsEnabled; private final @Nullable EdgeToEdgeFieldTrial mUseBackupNavbarInsetsFieldTrial; - private final boolean mCanUseTappableElementInsets; private final boolean mCanUseMandatoryGesturesInsets; /** @@ -65,8 +64,6 @@ * seem to be missing. * @param useBackupNavbarInsetsFieldTrial The EdgeToEdgeFieldTrial to use to verify if backup * insets are allowed on devices by the current manufacturer. - * @param canUseTappableElementInsets Whether tappable element insets can be used as backup - * navbar insets. * @param canUseMandatoryGesturesInsets Whether mandatory system gesture insets can be used as * backup navbar insets. */ @@ -75,13 +72,11 @@ @Nullable InsetObserver insetObserver, boolean useBackupNavbarInsetsEnabled, @Nullable EdgeToEdgeFieldTrial useBackupNavbarInsetsFieldTrial, - boolean canUseTappableElementInsets, boolean canUseMandatoryGesturesInsets) { mContext = context; mInsetObserver = insetObserver; mUseBackupNavbarInsetsEnabled = useBackupNavbarInsetsEnabled; mUseBackupNavbarInsetsFieldTrial = useBackupNavbarInsetsFieldTrial; - mCanUseTappableElementInsets = canUseTappableElementInsets; mCanUseMandatoryGesturesInsets = canUseMandatoryGesturesInsets; } @@ -101,7 +96,6 @@ insetObserver, /* useBackupNavbarInsetsEnabled= */ false, /* useBackupNavbarInsetsFieldTrial= */ null, - /* canUseTappableElementInsets= */ false, /* canUseMandatoryGesturesInsets= */ false); } @@ -202,31 +196,38 @@ private Insets getNavigationBarInsets(WindowInsetsCompat windowInsets) { Insets navBarInsets = windowInsets.getInsets(Type.navigationBars()); + Insets tappableInsets = windowInsets.getInsets(WindowInsetsCompat.Type.tappableElement()); + Insets nonTopTappableInsets = + Insets.of(tappableInsets.left, 0, tappableInsets.right, tappableInsets.bottom); + Insets navBarAndTappableInsets = Insets.max(navBarInsets, nonTopTappableInsets); - if (!mUseBackupNavbarInsetsEnabled) return navBarInsets; - if (mInsetObserver == null || mUseBackupNavbarInsetsFieldTrial == null) return navBarInsets; + if (!mUseBackupNavbarInsetsEnabled) return navBarAndTappableInsets; + if (mInsetObserver == null || mUseBackupNavbarInsetsFieldTrial == null) { + return navBarAndTappableInsets; + } - if (navBarInsets.left == 0 && navBarInsets.right == 0 && navBarInsets.bottom == 0) { + if (navBarAndTappableInsets.left == 0 + && navBarAndTappableInsets.right == 0 + && navBarAndTappableInsets.bottom == 0) { @Nullable Insets backupNavbarInsets = EdgeToEdgeManager.getBackupNavbarInsets( mInsetObserver.hasSeenNonZeroNavigationBarInsets(), windowInsets, BackupNavbarInsetsCallSite.EDGE_TO_EDGE_LAYOUT, mUseBackupNavbarInsetsFieldTrial, - mCanUseTappableElementInsets, mCanUseMandatoryGesturesInsets); // If applicable, apply backup navbar insets to the left, right, and bottom (not the // top, as that's always the status bar). if (backupNavbarInsets != null) { - navBarInsets = + navBarAndTappableInsets = Insets.of( backupNavbarInsets.left, - navBarInsets.top, + navBarAndTappableInsets.top, backupNavbarInsets.right, backupNavbarInsets.bottom); } } - return navBarInsets; + return navBarAndTappableInsets; } /** Returns the edge-to-edge layout view. */
diff --git a/ui/edge_to_edge/android/javatests/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutViewTest.java b/ui/edge_to_edge/android/javatests/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutViewTest.java index 0cbff58e7..550ee978 100644 --- a/ui/edge_to_edge/android/javatests/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutViewTest.java +++ b/ui/edge_to_edge/android/javatests/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutViewTest.java
@@ -99,7 +99,6 @@ null, /* useBackupNavbarInsetsEnabled= */ true, /* useBackupNavbarInsetsFieldTrial= */ mUseBackupNavbarInsetsFieldTrial, - /* canUseTappableElementInsets= */ true, /* canUseMandatoryGesturesInsets= */ true); mContentView = new FrameLayout(sActivity, null);
diff --git a/ui/edge_to_edge/android/junit/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutUnitTest.java b/ui/edge_to_edge/android/junit/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutUnitTest.java index 19904c8..51c1d90 100644 --- a/ui/edge_to_edge/android/junit/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutUnitTest.java +++ b/ui/edge_to_edge/android/junit/src/org/chromium/ui/edge_to_edge/layout/EdgeToEdgeLayoutUnitTest.java
@@ -273,7 +273,7 @@ new WindowInsetsCompat.Builder() .setInsets(STATUS_BARS, Insets.of(0, STATUS_BAR_SIZE, 0, 0)) .setInsets(NAVIGATION_BARS, Insets.of(0, 0, 0, 0)) - .setInsets(TAPPABLE_ELEMENT, Insets.of(0, 0, 0, NAV_BAR_SIZE)) + .setInsets(TAPPABLE_ELEMENT, Insets.of(0, 0, 0, 0)) .setInsets( MANDATORY_SYSTEM_GESTURES, Insets.of(0, STATUS_BAR_SIZE, 0, NAV_BAR_SIZE)) @@ -1023,7 +1023,6 @@ insetObserver, /* useBackupNavbarInsetsEnabled= */ useBackupNavbarInsets, /* useBackupNavbarInsetsFieldTrial= */ mUseBackupNavbarFieldTrial, - /* canUseTappableElementInsets= */ true, /* canUseMandatoryGesturesInsets= */ true); mEdgeToEdgeLayout = (EdgeToEdgeBaseLayout)
diff --git a/ui/gfx/display_color_spaces.cc b/ui/gfx/display_color_spaces.cc index b26d6b47..ce73340 100644 --- a/ui/gfx/display_color_spaces.cc +++ b/ui/gfx/display_color_spaces.cc
@@ -113,10 +113,11 @@ return color_spaces_[GetIndex(color_usage, needs_alpha)]; } -BufferFormat DisplayColorSpaces::GetOutputBufferFormat( +viz::SharedImageFormat DisplayColorSpaces::GetOutputFormat( ContentColorUsage color_usage, bool needs_alpha) const { - return buffer_formats_[GetIndex(color_usage, needs_alpha)]; + return viz::GetSharedImageFormat( + buffer_formats_[GetIndex(color_usage, needs_alpha)]); } ColorSpace DisplayColorSpaces::GetRasterAndCompositeColorSpace( @@ -179,7 +180,7 @@ void DisplayColorSpaces::ToStrings( std::vector<std::string>* out_names, std::vector<gfx::ColorSpace>* out_color_spaces, - std::vector<gfx::BufferFormat>* out_buffer_formats) const { + std::vector<viz::SharedImageFormat>* out_formats) const { // The names of the configurations. std::array<const char*, kConfigCount> config_names = { "sRGB/no-alpha", "sRGB/alpha", "WCG/no-alpha", @@ -234,7 +235,7 @@ // Add an entry, and continue with the interval [j, j). out_names->push_back(name); - out_buffer_formats->push_back(buffer_formats_[i]); + out_formats->push_back(viz::GetSharedImageFormat(buffer_formats_[i])); out_color_spaces->push_back(color_spaces_[i]); i = j; };
diff --git a/ui/gfx/display_color_spaces.h b/ui/gfx/display_color_spaces.h index 847d4a7c..3f2ee89 100644 --- a/ui/gfx/display_color_spaces.h +++ b/ui/gfx/display_color_spaces.h
@@ -78,8 +78,8 @@ // Retrieve parameters for a specific usage and alpha. ColorSpace GetOutputColorSpace(ContentColorUsage color_usage, bool needs_alpha) const; - BufferFormat GetOutputBufferFormat(ContentColorUsage color_usage, - bool needs_alpha) const; + viz::SharedImageFormat GetOutputFormat(ContentColorUsage color_usage, + bool needs_alpha) const; // Set the maximum SDR luminance, in nits. This is a non-default value only // on Windows. @@ -128,10 +128,10 @@ // Output as a vector of strings. This is a helper function for printing in // about:gpu. All output vectors will be the same length. Each entry will be - // the configuration name, its buffer format, and its color space. + // the configuration name, its format, and its color space. void ToStrings(std::vector<std::string>* out_names, std::vector<gfx::ColorSpace>* out_color_spaces, - std::vector<gfx::BufferFormat>* out_buffer_formats) const; + std::vector<viz::SharedImageFormat>* out_formats) const; bool operator==(const DisplayColorSpaces& other) const;
diff --git a/ui/gfx/geometry/transform_util_unittest.cc b/ui/gfx/geometry/transform_util_unittest.cc index 42cdc3a9..e0ffd72d 100644 --- a/ui/gfx/geometry/transform_util_unittest.cc +++ b/ui/gfx/geometry/transform_util_unittest.cc
@@ -157,10 +157,7 @@ const float infinity_or_zero = std::numeric_limits<float>::has_infinity ? std::numeric_limits<float>::infinity() : 0; - const float denorm_min_or_zero = - (std::numeric_limits<float>::has_denorm == std::denorm_present) - ? std::numeric_limits<float>::denorm_min() - : 0; + const float denorm_min = std::numeric_limits<float>::denorm_min(); const struct { Transform transform; @@ -254,7 +251,7 @@ {Transform::RowMajor(3, 0, 0, -23, 0, 7, 0, 31, 0, 0, 11, 47, - 0, 0, 0, denorm_min_or_zero), + 0, 0, 0, denorm_min), std::nullopt}, // clang-format on };
diff --git a/ui/webui/resources/cr_components/searchbox/searchbox_action.css b/ui/webui/resources/cr_components/searchbox/searchbox_action.css index d542be5..c3b7ad96 100644 --- a/ui/webui/resources/cr_components/searchbox/searchbox_action.css +++ b/ui/webui/resources/cr_components/searchbox/searchbox_action.css
@@ -74,6 +74,11 @@ width: 16px; } +:host-context(:is(:focus, [selected])) #action-icon { + background-color: var(--color-searchbox-results-action-chip-icon-selected, + var(--color-searchbox-results-action-chip-icon)); +} + #text { overflow: hidden; padding-inline-start: 8px;
diff --git a/ui/webui/resources/cr_components/searchbox/searchbox_icon.css b/ui/webui/resources/cr_components/searchbox/searchbox_icon.css index d6d7ac6..46b1aa4 100644 --- a/ui/webui/resources/cr_components/searchbox/searchbox_icon.css +++ b/ui/webui/resources/cr_components/searchbox/searchbox_icon.css
@@ -101,6 +101,11 @@ background-color: var(--color-searchbox-answer-icon-foreground); } +:host([has-icon-container-background][is-starter-pack]:not([in-searchbox])) #icon { + background-color: var(--color-searchbox-results-starter-pack-icon, + var(--color-searchbox-answer-icon-foreground)); +} + #iconImg { height: var(--cr-searchbox-results-search-icon-size,16px); width: var(--cr-searchbox-results-search-icon-size,16px);
diff --git a/ui/webui/resources/cr_components/searchbox/searchbox_icon.ts b/ui/webui/resources/cr_components/searchbox/searchbox_icon.ts index 56c8de1..68a4fa1 100644 --- a/ui/webui/resources/cr_components/searchbox/searchbox_icon.ts +++ b/ui/webui/resources/cr_components/searchbox/searchbox_icon.ts
@@ -85,6 +85,14 @@ }, /** + * Whether icon belongs to a starter pack match. + */ + isStarterPack: { + type: Boolean, + reflect: true, + }, + + /** * Whether suggestion answer is of answer type weather. Weather answers * don't have the same background as other suggestion answers. */ @@ -151,6 +159,7 @@ accessor hasIconContainerBackground: boolean = false; accessor inSearchbox: boolean = false; accessor isAnswer: boolean = false; + accessor isStarterPack = false; accessor isWeatherAnswer: boolean = false; accessor isEnterpriseSearchAggregatorPeopleType: boolean = false; accessor maskImage: string = ''; @@ -174,6 +183,7 @@ this.isAnswer = this.computeIsAnswer_(); this.isEnterpriseSearchAggregatorPeopleType = this.computeIsEnterpriseSearchAggregatorPeopleType_(); + this.isStarterPack = this.computeIsStarterPack_(); this.isWeatherAnswer = this.computeIsWeatherAnswer_(); this.maskImage = this.computeMaskImage_(); } @@ -390,6 +400,10 @@ } return false; } + + private computeIsStarterPack_(): boolean { + return this.match?.type === STARTER_PACK; + } } declare global {
diff --git a/ui/webui/resources/cr_components/searchbox/searchbox_match.css b/ui/webui/resources/cr_components/searchbox/searchbox_match.css index 049d7748..382b058 100644 --- a/ui/webui/resources/cr_components/searchbox/searchbox_match.css +++ b/ui/webui/resources/cr_components/searchbox/searchbox_match.css
@@ -238,12 +238,20 @@ } #remove { - --cr-icon-button-fill-color: - var(--color-searchbox-results-icon-selected); display: none; margin-inline-end: 1px; } +:host-context(cr-searchbox-match:-webkit-any(:focus-within, [selected])) #remove { + --cr-icon-button-fill-color: var(--color-searchbox-results-icon-selected); +} + + +:host-context(cr-searchbox-match:-webkit-any(:focus-within, [selected])) #remove:hover { + --cr-icon-button-hover-background-color: + var(--color-searchbox-results-button-selected-hover); +} + :host-context(.vertical) .container:hover #remove, :host-context(cr-searchbox-match:-webkit-any(:focus-within, [selected])):host-context(.vertical) #remove { display: inline-flex;
diff --git a/url/gurl.cc b/url/gurl.cc index ee910fb..dda561c 100644 --- a/url/gurl.cc +++ b/url/gurl.cc
@@ -105,8 +105,7 @@ // We can't do this check on the inner_url of a filesystem URL, as // canonical_spec actually points to the start of the outer URL, so we'd // end up with infinite recursion in this constructor. - if (!url::FindAndCompareScheme(spec_.data(), spec_.length(), - url::kFileSystemScheme, &scheme) || + if (!url::FindAndCompareScheme(spec_, url::kFileSystemScheme, &scheme) || scheme.begin == parsed_.scheme.begin) { // We need to retain trailing whitespace on path URLs, as the |parsed_| // spec we originally received may legitimately contain trailing white-
diff --git a/url/url_util.cc b/url/url_util.cc index 0042c108..e47605c 100644 --- a/url/url_util.cc +++ b/url/url_util.cc
@@ -224,18 +224,15 @@ return false; } -// TODO(crbug.com/350788890): Replace `str` and `str_len` with a -// basic_string_view or a base::span. -template<typename CHAR> -bool DoFindAndCompareScheme(const CHAR* str, - int str_len, +template <typename CHAR> +bool DoFindAndCompareScheme(std::basic_string_view<CHAR> str, const char* compare, Component* found_scheme) { // Before extracting scheme, canonicalize the URL to remove any whitespace. // This matches the canonicalization done in DoCanonicalize function. STACK_UNINITIALIZED RawCanonOutputT<CHAR> whitespace_buffer; - std::basic_string_view<CHAR> spec = RemoveUrlWhitespace( - {str, base::checked_cast<size_t>(str_len)}, &whitespace_buffer, nullptr); + std::basic_string_view<CHAR> spec = + RemoveUrlWhitespace(str, &whitespace_buffer, nullptr); Component our_scheme; if (!ExtractScheme(spec, &our_scheme)) { @@ -749,18 +746,16 @@ GetSchemeRegistry().referrer_schemes); } -bool FindAndCompareScheme(const char* str, - int str_len, +bool FindAndCompareScheme(std::string_view str, const char* compare, Component* found_scheme) { - return DoFindAndCompareScheme(str, str_len, compare, found_scheme); + return DoFindAndCompareScheme(str, compare, found_scheme); } bool FindAndCompareScheme(std::u16string_view str, const char* compare, Component* found_scheme) { - return DoFindAndCompareScheme(str.data(), base::checked_cast<int>(str.size()), - compare, found_scheme); + return DoFindAndCompareScheme(str, compare, found_scheme); } bool DomainIs(std::string_view canonical_host,
diff --git a/url/url_util.h b/url/url_util.h index 3689cf4f..035d839 100644 --- a/url/url_util.h +++ b/url/url_util.h
@@ -146,15 +146,16 @@ // input (if any). The |compare| scheme must be a valid canonical scheme or // the result of the comparison is undefined. COMPONENT_EXPORT(URL) -bool FindAndCompareScheme(const char* str, - int str_len, +bool FindAndCompareScheme(std::string_view str, const char* compare, Component* found_scheme); -inline bool FindAndCompareScheme(std::string_view str, +inline bool FindAndCompareScheme(const char* str, + int str_len, const char* compare, Component* found_scheme) { - return FindAndCompareScheme(str.data(), static_cast<int>(str.size()), - compare, found_scheme); + return FindAndCompareScheme( + std::string_view(str, static_cast<size_t>(str_len)), compare, + found_scheme); } COMPONENT_EXPORT(URL) bool FindAndCompareScheme(std::u16string_view str,
diff --git a/url/url_util_unittest.cc b/url/url_util_unittest.cc index 2e42d3f..a10ea12 100644 --- a/url/url_util_unittest.cc +++ b/url/url_util_unittest.cc
@@ -90,47 +90,38 @@ // Simple case where the scheme is found and matches. const char kStr1[] = "http://www.com/"; - EXPECT_TRUE(FindAndCompareScheme(kStr1, static_cast<int>(strlen(kStr1)), - "http", nullptr)); - EXPECT_TRUE(FindAndCompareScheme( - kStr1, static_cast<int>(strlen(kStr1)), "http", &found_scheme)); + EXPECT_TRUE(FindAndCompareScheme(kStr1, "http", nullptr)); + EXPECT_TRUE(FindAndCompareScheme(kStr1, "http", &found_scheme)); EXPECT_TRUE(found_scheme == Component(0, 4)); // A case where the scheme is found and doesn't match. - EXPECT_FALSE(FindAndCompareScheme( - kStr1, static_cast<int>(strlen(kStr1)), "https", &found_scheme)); + EXPECT_FALSE(FindAndCompareScheme(kStr1, "https", &found_scheme)); EXPECT_TRUE(found_scheme == Component(0, 4)); // A case where there is no scheme. const char kStr2[] = "httpfoobar"; - EXPECT_FALSE(FindAndCompareScheme( - kStr2, static_cast<int>(strlen(kStr2)), "http", &found_scheme)); + EXPECT_FALSE(FindAndCompareScheme(kStr2, "http", &found_scheme)); EXPECT_TRUE(found_scheme == Component()); // When there is an empty scheme, it should match the empty scheme. const char kStr3[] = ":foo.com/"; - EXPECT_TRUE(FindAndCompareScheme( - kStr3, static_cast<int>(strlen(kStr3)), "", &found_scheme)); + EXPECT_TRUE(FindAndCompareScheme(kStr3, "", &found_scheme)); EXPECT_TRUE(found_scheme == Component(0, 0)); // But when there is no scheme, it should fail. - EXPECT_FALSE(FindAndCompareScheme("", 0, "", &found_scheme)); + EXPECT_FALSE(FindAndCompareScheme("", "", &found_scheme)); EXPECT_TRUE(found_scheme == Component()); // When there is a whitespace char in scheme, it should canonicalize the URL // before comparison. const char whtspc_str[] = " \r\n\tjav\ra\nscri\tpt:alert(1)"; - EXPECT_TRUE(FindAndCompareScheme(whtspc_str, - static_cast<int>(strlen(whtspc_str)), - "javascript", &found_scheme)); + EXPECT_TRUE(FindAndCompareScheme(whtspc_str, "javascript", &found_scheme)); EXPECT_TRUE(found_scheme == Component(1, 10)); // Control characters should be stripped out on the ends, and kept in the // middle. const char ctrl_str[] = "\02jav\02scr\03ipt:alert(1)"; - EXPECT_FALSE(FindAndCompareScheme(ctrl_str, - static_cast<int>(strlen(ctrl_str)), - "javascript", &found_scheme)); + EXPECT_FALSE(FindAndCompareScheme(ctrl_str, "javascript", &found_scheme)); EXPECT_TRUE(found_scheme == Component(1, 11)); }
diff --git a/v8 b/v8 index 033fd2f..99022d9 160000 --- a/v8 +++ b/v8
@@ -1 +1 @@ -Subproject commit 033fd2f04cb7ff9d69cbaf0876e808186ca2dc5c +Subproject commit 99022d9158c6e40babc442b84dc0b60ed64cd378