diff --git a/DEPS b/DEPS index 8c0819c1..dd9f399 100644 --- a/DEPS +++ b/DEPS
@@ -241,7 +241,7 @@ # luci-go CIPD package version. # Make sure the revision is uploaded by infra-packagers builder. # https://ci.chromium.org/p/infra-internal/g/infra-packagers/console - 'luci_go': 'git_revision:a8b84fba102daff5bf5e65975dcc0887da7ab62a', + 'luci_go': 'git_revision:f6b5518e872364f59bb17dd5a967270b38331b84', # This can be overridden, e.g. with custom_vars, to build clang from HEAD # instead of downloading the prebuilt pinned revision. @@ -299,15 +299,15 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling Skia # and whatever else without interference from each other. - 'skia_revision': '99a797d497fe983e63f3fbfe064c270973298b45', + 'skia_revision': 'db586ebd77a2acd3cadb4427dfc5dda7729849fb', # 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': '8256e3617c00bc91937853bf038cb30462b383fb', + 'v8_revision': 'a41a2e4571ec8847c7042d01f9d0afe2accb9730', # 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': 'b6cc575478e27c62500f43192aa602737b2f6257', + 'angle_revision': '92f26ce30581b0f5494b8e14ad77d2c6109f0c3a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling SwiftShader # and whatever else without interference from each other. @@ -350,7 +350,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. - 'freetype_revision': '27b2cd4101dfcf7d03904204e078b2de84cce8c4', + 'freetype_revision': '4c3916e901ac88243321b7518c023dc8c51a7586', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling freetype # and whatever else without interference from each other. @@ -382,7 +382,7 @@ # Three lines of non-changing comments so that # the commit queue can handle CLs rolling devtools-frontend # and whatever else without interference from each other. - 'devtools_frontend_revision': '798cf20faa5996e26d4e1d36f63f6cb0c021d173', + 'devtools_frontend_revision': '6ba2c8dee3953aefca236edf58d668d474363e6a', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling libprotobuf-mutator # and whatever else without interference from each other. @@ -422,7 +422,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': '5b50790d707908a3deb2afec01651a4fc80b28b5', + 'dawn_revision': '132be477374b7e23acfc6e11b3e160af1e92de79', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -458,7 +458,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. - 'cros_components_revision': '07072d38ddc54369486d61f0c60cd137d51dc37a', + 'cros_components_revision': '9fec96ff3e3d20b57e8ceb217efcfab081622dd4', # Three lines of non-changing comments so that # the commit queue can handle CLs rolling feed # and whatever else without interference from each other. @@ -760,7 +760,7 @@ 'src/clank': { 'url': 'https://chrome-internal.googlesource.com/clank/internal/apps.git' + '@' + - '885a039347998fb1c765b87509e85b3e2dde5321', + '4ae23a125384eae81dda4f96ec0c083cb50ab03b', 'condition': 'checkout_android and checkout_src_internal', }, @@ -789,7 +789,7 @@ }, 'src/ios/third_party/material_components_ios/src': { - 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '6ca84fe7c8f22132695ec92a7e069a580261aac9', + 'url': Var('chromium_git') + '/external/github.com/material-components/material-components-ios.git' + '@' + '6f2bbf825c4a513ac0842557a1186f75cdbe2954', 'condition': 'checkout_ios', }, @@ -1202,13 +1202,13 @@ }, 'src/third_party/depot_tools': - Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + '2ec2918216c61bdb2f4ab48bb0e761d0e2fc48fb', + Var('chromium_git') + '/chromium/tools/depot_tools.git' + '@' + 'cd2395991f80b66fb3549730c92de7b9fe11e649', 'src/third_party/devtools-frontend/src': Var('chromium_git') + '/devtools/devtools-frontend' + '@' + Var('devtools_frontend_revision'), 'src/third_party/devtools-frontend-internal': { - 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + 'b648d0eaa0ab60d049f8742673eb8a33aff29384', + 'url': 'https://chrome-internal.googlesource.com/devtools/devtools-internal.git' + '@' + 'b87886e8c087e3da7f7154550e524bf337d1af1a', 'condition': 'checkout_src_internal', }, @@ -1862,7 +1862,7 @@ Var('chromium_git') + '/external/github.com/gpuweb/cts.git' + '@' + '6c8361e98f1daba65902f5e2fc1297893ac14b67', 'src/third_party/webrtc': - Var('webrtc_git') + '/src.git' + '@' + 'fd4ddd1fb19b5e9678664cd0054d19a841e10220', + Var('webrtc_git') + '/src.git' + '@' + 'd8361ee6b7ab231ede75ff0528329b1153d60888', # 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. @@ -1889,7 +1889,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/linux-amd64', - 'version': '3N5ZxQ_Vej0R4hY-5r_rn2ks2HvZNKWZVPOF0IQsct8C', + 'version': 'B3ETgoPk2gSY8aomIHMZNixKf63RvZDpuJhnZFelSl0C', }, ], 'dep_type': 'cipd', @@ -1899,7 +1899,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/windows-amd64', - 'version': 'xY20wb1hbHLqq-NcBK8qSSRjGi_hK-_YmBT4Njm78kUC', + 'version': '4l2ybbWBlKkcGXEi6Z6MOOanDzH2X3JuwuKW3hlLcq8C', }, ], 'dep_type': 'cipd', @@ -1921,7 +1921,7 @@ 'packages': [ { 'package': 'skia/tools/goldctl/mac-arm64', - 'version': '0EJSEBdXC6iNCrOFINQw_EHpFey1tj_zSrlCX0N5zxcC', + 'version': 'xe7SkOafMEH4PikK8N-7c1Wt2rPEVLnTG10xrBCAExYC', }, ], 'dep_type': 'cipd', @@ -1932,7 +1932,7 @@ Var('chromium_git') + '/v8/v8.git' + '@' + Var('v8_revision'), 'src-internal': { - 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@6fd469560dc257381fae48a8d9842b04384a8581', + 'url': 'https://chrome-internal.googlesource.com/chrome/src-internal.git@9b7fe0dc2e17093b985ab596871c82fcb3b9acb7', 'condition': 'checkout_src_internal', },
diff --git a/ash/BUILD.gn b/ash/BUILD.gn index 332576f2..5e506c0 100644 --- a/ash/BUILD.gn +++ b/ash/BUILD.gn
@@ -1046,6 +1046,8 @@ "style/option_button_base.h", "style/option_button_group.cc", "style/option_button_group.h", + "style/pagination_view.cc", + "style/pagination_view.h", "style/pill_button.cc", "style/pill_button.h", "style/radio_button.cc",
diff --git a/ash/ash_strings.grd b/ash/ash_strings.grd index 1a70065..af55c90 100644 --- a/ash/ash_strings.grd +++ b/ash/ash_strings.grd
@@ -6215,6 +6215,14 @@ <message name="IDS_ASH_CURTAIN_DESCRIPTION" desc="Detailed description displayed to inform the user a remote admin has taken control of the ChromeOs device."> Your administrator has logged in to look into an issue. You can continue to use the device after the administrator gives the control back to you. </message> - </messages> - </release> + + <!-- pagination view --> + <message name="IDS_ASH_PAGINATION_LEFT_ARROW_TOOLTIP" desc="The tooltip text used for pagination left arrow button." > + Previous page + </message> + <message name="IDS_ASH_PAGINATION_RIGHT_ARROW_TOOLTIP" desc="The tooltip text used for pagination right arrow button." > + Next page + </message> + </messages> + </release> </grit>
diff --git a/ash/ash_strings_grd/IDS_ASH_PAGINATION_LEFT_ARROW_TOOLTIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_PAGINATION_LEFT_ARROW_TOOLTIP.png.sha1 new file mode 100644 index 0000000..0da1a8a --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_PAGINATION_LEFT_ARROW_TOOLTIP.png.sha1
@@ -0,0 +1 @@ +4b33cdfc18ffd36296e619dbb131ced8850cc55e \ No newline at end of file
diff --git a/ash/ash_strings_grd/IDS_ASH_PAGINATION_RIGHT_ARROW_TOOLTIP.png.sha1 b/ash/ash_strings_grd/IDS_ASH_PAGINATION_RIGHT_ARROW_TOOLTIP.png.sha1 new file mode 100644 index 0000000..10814c6 --- /dev/null +++ b/ash/ash_strings_grd/IDS_ASH_PAGINATION_RIGHT_ARROW_TOOLTIP.png.sha1
@@ -0,0 +1 @@ +40cb88bb7e2ff881d9b45372b4e8026cdde6ff56 \ No newline at end of file
diff --git a/ash/constants/ash_features.cc b/ash/constants/ash_features.cc index 8811b9b7..199a46c 100644 --- a/ash/constants/ash_features.cc +++ b/ash/constants/ash_features.cc
@@ -1019,6 +1019,9 @@ // native screen capture tool. BASE_FEATURE(kGifRecording, "GifRecording", base::FEATURE_DISABLED_BY_DEFAULT); +// Enables the displaying of animated gifs in ash. +BASE_FEATURE(kGifRendering, "GifRendering", base::FEATURE_DISABLED_BY_DEFAULT); + // Enables a Files banner about Google One offer. BASE_FEATURE(kGoogleOneOfferFilesBanner, "GoogleOneOfferFilesBanner", @@ -2574,6 +2577,10 @@ return base::FeatureList::IsEnabled(kGifRecording); } +bool IsGifRenderingEnabled() { + return base::FeatureList::IsEnabled(kGifRendering); +} + bool AreGlanceablesEnabled() { return base::FeatureList::IsEnabled(kGlanceables); }
diff --git a/ash/constants/ash_features.h b/ash/constants/ash_features.h index 0b3442d0..68925de 100644 --- a/ash/constants/ash_features.h +++ b/ash/constants/ash_features.h
@@ -294,6 +294,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGesturePropertiesDBusService); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGifRecording); +COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGifRendering); COMPONENT_EXPORT(ASH_CONSTANTS) BASE_DECLARE_FEATURE(kGoogleOneOfferFilesBanner); COMPONENT_EXPORT(ASH_CONSTANTS) @@ -695,6 +696,7 @@ COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGalleryAppPdfEditNotificationEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGameDashboardEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGifRecordingEnabled(); +COMPONENT_EXPORT(ASH_CONSTANTS) bool IsGifRenderingEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool AreGlanceablesEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsHibernateEnabled(); COMPONENT_EXPORT(ASH_CONSTANTS) bool IsHideArcMediaNotificationsEnabled();
diff --git a/ash/metrics/ui_metrics_recorder.cc b/ash/metrics/ui_metrics_recorder.cc index 2863cd10..a133ef6 100644 --- a/ash/metrics/ui_metrics_recorder.cc +++ b/ash/metrics/ui_metrics_recorder.cc
@@ -43,29 +43,28 @@ DCHECK_EQ(State::kDuringLogin, state_); state_ = State::kInSession; + user_session_start_time_ = base::TimeTicks::Now(); } void UiMetricsRecorder::ReportPercentDroppedFramesInOneSecondWindow( - double percentage) { + double percent) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); UMA_HISTOGRAM_PERCENTAGE("Ash.Smoothness.PercentDroppedFrames_1sWindow", - percentage); + percent); switch (state_) { case State::kBeforeLogin: UMA_HISTOGRAM_PERCENTAGE( - "Ash.Smoothness.PercentDroppedFrames_1sWindow.BeforeLogin", - percentage); + "Ash.Smoothness.PercentDroppedFrames_1sWindow.BeforeLogin", percent); break; case State::kDuringLogin: UMA_HISTOGRAM_PERCENTAGE( - "Ash.Smoothness.PercentDroppedFrames_1sWindow.DuringLogin", - percentage); + "Ash.Smoothness.PercentDroppedFrames_1sWindow.DuringLogin", percent); break; case State::kInSession: UMA_HISTOGRAM_PERCENTAGE( - "Ash.Smoothness.PercentDroppedFrames_1sWindow.InSession", percentage); + "Ash.Smoothness.PercentDroppedFrames_1sWindow.InSession", percent); break; } @@ -74,16 +73,16 @@ // take is as the signal that the user session is full initialized and set // `session_initialized_` flag. if (check_session_init_) { - // Threshold for `percentage` to be considered good. + // Threshold for `percent` to be considered good. constexpr double kGoodAdf = 20; - if (!last_good_dropped_frame_time_.has_value() && percentage <= kGoodAdf) { + if (!last_good_dropped_frame_time_.has_value() && percent <= kGoodAdf) { last_good_dropped_frame_time_ = base::TimeTicks::Now(); } else if (last_good_dropped_frame_time_.has_value() && - percentage > kGoodAdf) { + percent > kGoodAdf) { last_good_dropped_frame_time_.reset(); } - // Minimum duration for `percentage` to stay in good before the user session + // Minimum duration for `percent` to stay in good before the user session // is considered as fully initialized. constexpr base::TimeDelta kMinGoodAdfDuration = base::Seconds(5); if (last_good_dropped_frame_time_.has_value()) { @@ -101,7 +100,22 @@ if (session_initialized_) { UMA_HISTOGRAM_PERCENTAGE( - "Ash.Smoothness.PercentDroppedFrames_1sWindow.InSession2", percentage); + "Ash.Smoothness.PercentDroppedFrames_1sWindow.InSession2", percent); + } +} + +void UiMetricsRecorder::ReportPercentDroppedFramesInOneSecondWindow2( + double percent) { + UMA_HISTOGRAM_PERCENTAGE("Ash.Smoothness.PercentDroppedFrames_1sWindow2", + percent); + + // Time to exclude from user session to be reported under "InSession" metric. + constexpr base::TimeDelta chopped_user_session_time = base::Minutes(1); + if (user_session_start_time_ && + base::TimeTicks::Now() - user_session_start_time_.value() >= + chopped_user_session_time) { + UMA_HISTOGRAM_PERCENTAGE( + "Ash.Smoothness.PercentDroppedFrames_1sWindow2.InSession", percent); } }
diff --git a/ash/metrics/ui_metrics_recorder.h b/ash/metrics/ui_metrics_recorder.h index e13d8021..a634a19 100644 --- a/ash/metrics/ui_metrics_recorder.h +++ b/ash/metrics/ui_metrics_recorder.h
@@ -30,7 +30,8 @@ void OnPostLoginAnimationFinish(); // cc::CustomMetricRecorder: - void ReportPercentDroppedFramesInOneSecondWindow(double percentage) override; + void ReportPercentDroppedFramesInOneSecondWindow(double percent) override; + void ReportPercentDroppedFramesInOneSecondWindow2(double percent) override; void ReportEventLatency( std::vector<cc::EventLatencyTracker::LatencyData> latencies) override; @@ -52,7 +53,10 @@ // observing good ADF for 5s during login. bool session_initialized_ = false; + // Login time and session start time of the primary user. absl::optional<base::TimeTicks> user_logged_in_time_; + absl::optional<base::TimeTicks> user_session_start_time_; + absl::optional<base::TimeTicks> last_good_dropped_frame_time_; };
diff --git a/ash/public/cpp/input_device_settings_controller.h b/ash/public/cpp/input_device_settings_controller.h index ee47bef1..66a8a5e 100644 --- a/ash/public/cpp/input_device_settings_controller.h +++ b/ash/public/cpp/input_device_settings_controller.h
@@ -5,6 +5,8 @@ #ifndef ASH_PUBLIC_CPP_INPUT_DEVICE_SETTINGS_CONTROLLER_H_ #define ASH_PUBLIC_CPP_INPUT_DEVICE_SETTINGS_CONTROLLER_H_ +#include <vector> + #include "ash/public/cpp/ash_public_export.h" #include "ash/public/mojom/input_device_settings.mojom-forward.h" #include "base/observer_list_types.h" @@ -13,7 +15,6 @@ // An interface, implemented by ash, which allows chrome to retrieve and update // input device settings. -// TODO(dpad): Add equivalent methods for Touchpads/Mice/Pointing Stick. class ASH_PUBLIC_EXPORT InputDeviceSettingsController { public: using DeviceId = uint32_t; @@ -22,15 +23,34 @@ public: virtual void OnKeyboardConnected(const mojom::Keyboard& keyboard) {} virtual void OnKeyboardDisconnected(const mojom::Keyboard& keyboard) {} - virtual void OnKeyboardSettingsUpdated( - DeviceId id, - const mojom::KeyboardSettings& settings) {} + virtual void OnKeyboardSettingsUpdated(const mojom::Keyboard& keyboard) {} + + virtual void OnTouchpadConnected(const mojom::Touchpad& touchpad) {} + virtual void OnTouchpadDisconnected(const mojom::Touchpad& touchpad) {} + virtual void OnTouchpadSettingsUpdated(const mojom::Touchpad& touchpad) {} + + virtual void OnMouseConnected(const mojom::Mouse& mouse) {} + virtual void OnMouseDisconnected(const mojom::Mouse& mouse) {} + virtual void OnMouseSettingsUpdated(const mojom::Mouse& mouse) {} + + virtual void OnPointingStickConnected( + const mojom::PointingStick& pointing_stick) {} + virtual void OnPointingStickDisconnected( + const mojom::PointingStick& pointing_stick) {} + virtual void OnPointingStickSettingsUpdated( + const mojom::PointingStick& pointing_stick) {} }; static InputDeviceSettingsController* Get(); // Returns a list of currently connected keyboards and their settings. virtual std::vector<mojom::KeyboardPtr> GetConnectedKeyboards() = 0; + // Returns a list of currently connected touchpads and their settings. + virtual std::vector<mojom::TouchpadPtr> GetConnectedTouchpads() = 0; + // Returns a list of currently connected mice and their settings. + virtual std::vector<mojom::MousePtr> GetConnectedMice() = 0; + // Returns a list of currently connected pointing sticks and their settings. + virtual std::vector<mojom::PointingStickPtr> GetConnectedPointingSticks() = 0; // Configure the settings for keyboard of |id| with the provided |settings|. virtual void SetKeyboardSettings(DeviceId id,
diff --git a/ash/public/cpp/wallpaper/wallpaper_controller.h b/ash/public/cpp/wallpaper/wallpaper_controller.h index 832c94a..0c2d73f 100644 --- a/ash/public/cpp/wallpaper/wallpaper_controller.h +++ b/ash/public/cpp/wallpaper/wallpaper_controller.h
@@ -256,7 +256,8 @@ // Removes all of the user's saved wallpapers and related info. // |account_id|: The user's account id. - virtual void RemoveUserWallpaper(const AccountId& account_id) = 0; + virtual void RemoveUserWallpaper(const AccountId& account_id, + base::OnceClosure on_removed) = 0; // Removes all of the user's saved wallpapers and related info if the // wallpaper was set by |SetPolicyWallpaper|. In addition, sets the user's
diff --git a/ash/resources/vector_icons/BUILD.gn b/ash/resources/vector_icons/BUILD.gn index 7d5285a..56f7d8e 100644 --- a/ash/resources/vector_icons/BUILD.gn +++ b/ash/resources/vector_icons/BUILD.gn
@@ -482,6 +482,8 @@ "unified_menu_locale.icon", "unified_menu_lock.icon", "unified_menu_managed.icon", + "unified_menu_mic_noise_cancel_high.icon", + "unified_menu_mic_noise_cancel_off.icon", "unified_menu_more.icon", "unified_menu_nearby_share_not_visible.icon", "unified_menu_nearby_share_visible.icon",
diff --git a/ash/resources/vector_icons/unified_menu_mic_noise_cancel_high.icon b/ash/resources/vector_icons/unified_menu_mic_noise_cancel_high.icon new file mode 100644 index 0000000..af0c70f7 --- /dev/null +++ b/ash/resources/vector_icons/unified_menu_mic_noise_cancel_high.icon
@@ -0,0 +1,39 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 4.6f, 5.4f, +CUBIC_TO, 7.13f, 7.93f, 7.13f, 12.06f, 4.6f, 14.59f, +LINE_TO, 5.66f, 15.65f, +CUBIC_TO, 8.78f, 12.53f, 8.78f, 7.46f, 5.66f, 4.34f, +LINE_TO, 4.6f, 5.4f, +CLOSE, +NEW_PATH, +MOVE_TO, 3.54f, 6.46f, +LINE_TO, 2.48f, 7.52f, +CUBIC_TO, 3.84f, 8.88f, 3.84f, 11.1f, 2.48f, 12.47f, +LINE_TO, 3.54f, 13.53f, +CUBIC_TO, 5.49f, 11.58f, 5.49f, 8.41f, 3.54f, 6.46f, +CLOSE, +NEW_PATH, +MOVE_TO, 10.75f, 2, +H_LINE_TO, 9.25f, +V_LINE_TO, 18, +H_LINE_TO, 10.75f, +V_LINE_TO, 2, +CLOSE, +NEW_PATH, +MOVE_TO, 14, 9.25f, +H_LINE_TO, 12.5f, +V_LINE_TO, 10.75f, +H_LINE_TO, 14, +V_LINE_TO, 9.25f, +CLOSE, +NEW_PATH, +MOVE_TO, 17, 9.25f, +H_LINE_TO, 15.5f, +V_LINE_TO, 10.75f, +H_LINE_TO, 17, +V_LINE_TO, 9.25f, +CLOSE
diff --git a/ash/resources/vector_icons/unified_menu_mic_noise_cancel_off.icon b/ash/resources/vector_icons/unified_menu_mic_noise_cancel_off.icon new file mode 100644 index 0000000..8a5f761 --- /dev/null +++ b/ash/resources/vector_icons/unified_menu_mic_noise_cancel_off.icon
@@ -0,0 +1,48 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +CANVAS_DIMENSIONS, 20, +MOVE_TO, 14, 10.75f, +V_LINE_TO, 9.25f, +H_LINE_TO, 12.5f, +V_LINE_TO, 10.38f, +LINE_TO, 12.87f, 10.75f, +H_LINE_TO, 14, +CLOSE, +NEW_PATH, +MOVE_TO, 17, 9.25f, +H_LINE_TO, 15.5f, +V_LINE_TO, 10.75f, +H_LINE_TO, 17, +V_LINE_TO, 9.25f, +CLOSE, +NEW_PATH, +MOVE_TO, 3.54f, 6.46f, +LINE_TO, 2.48f, 7.52f, +CUBIC_TO, 3.84f, 8.88f, 3.84f, 11.11f, 2.48f, 12.47f, +LINE_TO, 3.54f, 13.53f, +CUBIC_TO, 5.49f, 11.58f, 5.49f, 8.41f, 3.54f, 6.46f, +CLOSE, +NEW_PATH, +MOVE_TO, 10.75f, 2, +H_LINE_TO, 9.25f, +V_LINE_TO, 7.13f, +LINE_TO, 10.75f, 8.63f, +V_LINE_TO, 2, +CLOSE, +NEW_PATH, +MOVE_TO, 3.06f, 3.06f, +LINE_TO, 2, 4.12f, +LINE_TO, 6.3f, 8.41f, +CUBIC_TO, 6.84f, 10.55f, 6.27f, 12.92f, 4.6f, 14.59f, +LINE_TO, 5.66f, 15.65f, +CUBIC_TO, 7.19f, 14.12f, 7.97f, 12.12f, 8, 10.11f, +LINE_TO, 9.26f, 11.37f, +V_LINE_TO, 18, +H_LINE_TO, 10.76f, +V_LINE_TO, 12.87f, +LINE_TO, 15.89f, 18, +LINE_TO, 16.95f, 16.94f, +LINE_TO, 3.06f, 3.06f, +CLOSE
diff --git a/ash/shelf/hotseat_widget.cc b/ash/shelf/hotseat_widget.cc index 6fddd10..7c85738 100644 --- a/ash/shelf/hotseat_widget.cc +++ b/ash/shelf/hotseat_widget.cc
@@ -913,12 +913,8 @@ const gfx::Size hotseat_target_size = CalculateTargetBoundsSize(hotseat_target_state); - if (hotseat_target_state == HotseatState::kShownHomeLauncher) { - target_size_for_shown_state_ = hotseat_target_size; - } else { - target_size_for_shown_state_ = - CalculateTargetBoundsSize(HotseatState::kShownHomeLauncher); - } + target_size_for_shown_state_ = + CalculateTargetBoundsSize(HotseatState::kShownHomeLauncher); const gfx::Rect shelf_bounds = shelf_->shelf_widget()->GetTargetBounds(); const gfx::Rect status_area_bounds =
diff --git a/ash/style/pagination_view.cc b/ash/style/pagination_view.cc new file mode 100644 index 0000000..4fd3a21 --- /dev/null +++ b/ash/style/pagination_view.cc
@@ -0,0 +1,585 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ash/style/pagination_view.h" + +#include "ash/public/cpp/pagination/pagination_model.h" +#include "ash/resources/vector_icons/vector_icons.h" +#include "ash/strings/grit/ash_strings.h" +#include "ash/style/style_util.h" +#include "base/i18n/number_formatting.h" +#include "third_party/abseil-cpp/absl/types/optional.h" +#include "ui/base/l10n/l10n_util.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/models/image_model.h" +#include "ui/chromeos/styles/cros_tokens_color_mappings.h" +#include "ui/compositor/layer.h" +#include "ui/gfx/animation/tween.h" +#include "ui/gfx/canvas.h" +#include "ui/gfx/geometry/rounded_corners_f.h" +#include "ui/views/background.h" +#include "ui/views/controls/button/image_button.h" +#include "ui/views/controls/scroll_view.h" +#include "ui/views/layout/box_layout_view.h" +#include "ui/views/view_class_properties.h" + +namespace ash { + +namespace { + +// Attributes of arrow buttons. +constexpr int kArrowButtonIconSize = 20; +constexpr ui::ColorId kArrowButtonColorId = cros_tokens::kCrosSysSecondary; +constexpr int kArrowIndicatorSpacing = 2; + +// Attributes of indicator. +constexpr int kIndicatorButtonSize = 20; +constexpr int kIndicatorRadius = 4; +constexpr int kIndicatorStrokeWidth = 1; +constexpr int kIndicatorSpacing = 2; +constexpr ui::ColorId kIndicatorColorId = cros_tokens::kCrosSysPrimary; +constexpr int kMaxNumVisibleIndicators = 5; + +// A structure holds the info needed by interpolation. +template <typename T> +struct InterpolationInterval { + // The start time and value. + double start_time; + T start_value; + // The end time and value. + double end_time; + T target_value; +}; + +// IndicatorButton: +// A button with a hollow circle in the center. +class IndicatorButton : public views::Button { + public: + METADATA_HEADER(IndicatorButton); + + IndicatorButton(PressedCallback callback, + const std::u16string& accessible_name) + : views::Button(callback) { + SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY); + SetAccessibleName(accessible_name); + } + + IndicatorButton(const IndicatorButton&) = delete; + IndicatorButton& operator=(const IndicatorButton&) = delete; + ~IndicatorButton() override = default; + + // Gets the bounds of the circle in the center. + gfx::Rect GetIndicatorBounds() const { + gfx::Rect indicator_bounds = bounds(); + indicator_bounds.Inset( + gfx::Insets(0.5 * kIndicatorButtonSize - kIndicatorRadius)); + return indicator_bounds; + } + + // views::Button: + gfx::Size CalculatePreferredSize() const override { + return gfx::Size(kIndicatorButtonSize, kIndicatorButtonSize); + } + + void PaintButtonContents(gfx::Canvas* canvas) override { + cc::PaintFlags flags; + flags.setAntiAlias(true); + flags.setColor(GetColorProvider()->GetColor(kIndicatorColorId)); + flags.setStyle(cc::PaintFlags::kStroke_Style); + flags.setStrokeWidth(kIndicatorStrokeWidth); + // Do inner stroke. + canvas->DrawCircle(GetLocalBounds().CenterPoint(), + kIndicatorRadius - 0.5f * kIndicatorStrokeWidth, flags); + } +}; + +BEGIN_METADATA(IndicatorButton, views::Button) +END_METADATA + +} // namespace + +//------------------------------------------------------------------------------ +// PaginationView::SelectorDotView: +// A solid circle that performs deformation with the pace of page transition. +class PaginationView::SelectorDotView : public views::View { + public: + METADATA_HEADER(SelectorDotView); + + using DeformInterval = InterpolationInterval<gfx::Rect>; + + SelectorDotView() { + SetBackground( + StyleUtil::CreateThemedFullyRoundedRectBackground(kIndicatorColorId)); + SetPaintToLayer(); + layer()->SetFillsBoundsOpaquely(false); + // Set selector dot ignored by layout since it will follow selected + // indicator and deform on page transition. + SetProperty(views::kViewIgnoredByLayoutKey, true); + } + + SelectorDotView(const SelectorDotView&) = delete; + SelectorDotView& operator=(const SelectorDotView&) = delete; + ~SelectorDotView() override = default; + + // Adds a new deform interval. + void AddDeformInterval(DeformInterval interval) { + DCHECK_LT(interval.start_time, interval.end_time); + deform_intervals_.push_back(interval); + // Sort the intervals according to the start time in ascending order. + std::sort( + deform_intervals_.begin(), deform_intervals_.end(), + [](const DeformInterval& interval_1, const DeformInterval& interval_2) { + return interval_1.start_time < interval_2.start_time; + }); + } + + // Performs deformation according to the given progress within deform + // intervals. + void Deform(double progress) { + if (deform_intervals_.empty()) { + return; + } + + auto iter = std::find_if(deform_intervals_.begin(), deform_intervals_.end(), + [&](DeformInterval& interval) { + return interval.start_time <= progress && + interval.end_time >= progress; + }); + + if (iter == deform_intervals_.end()) { + return; + } + + // Get intermediate bounds by interpolating the origin and target bounds. + const gfx::Rect intermediate_bounds = gfx::Tween::RectValueBetween( + (progress - iter->start_time) / (iter->end_time - iter->start_time), + iter->start_value, iter->target_value); + SetBoundsRect(intermediate_bounds); + } + + void ResetDeform(bool canceled) { + if (!deform_intervals_.empty()) { + SetBoundsRect(canceled ? deform_intervals_.front().start_value + : deform_intervals_.back().target_value); + } + deform_intervals_.clear(); + } + + // Returns true if deformation is still in progress. + bool DeformingInProgress() const { return !deform_intervals_.empty(); } + + private: + std::vector<DeformInterval> deform_intervals_; +}; + +BEGIN_METADATA(PaginationView, SelectorDotView, views::View) +END_METADATA + +//------------------------------------------------------------------------------ +// PaginationView::IndicatorContainer: +// The container of indicators. If the indicator to be selected is not visible, +// the container will scroll with the pace of pagination transition. +class PaginationView::IndicatorContainer : public views::BoxLayoutView { + public: + METADATA_HEADER(IndicatorContainer); + + IndicatorContainer() { + SetMainAxisAlignment(views::BoxLayout::MainAxisAlignment::kCenter); + SetCrossAxisAlignment(views::BoxLayout::CrossAxisAlignment::kCenter); + SetBetweenChildSpacing(kIndicatorSpacing); + } + + IndicatorContainer(const IndicatorContainer&) = delete; + IndicatorContainer& operator=(const IndicatorContainer&) = delete; + ~IndicatorContainer() override = default; + + // Attaches an indicator to the end of container. + void PushIndicator(PaginationModel* model) { + const int page = buttons_.size(); + // Since the selector dot will also be added in the container, we should use + // `AddChildViewAt` to ensure the indicator is in the expected position in + // the child views. + auto* indicator_button = AddChildViewAt( + std::make_unique<IndicatorButton>( + base::BindRepeating( + [](PaginationModel* model, int page, const ui::Event& event) { + model->SelectPage(page, /*animate=*/true); + }, + model, page), + l10n_util::GetStringFUTF16( + IDS_APP_LIST_PAGE_SWITCHER, base::FormatNumber(page + 1), + base::FormatNumber(model->total_pages()))), + page); + buttons_.emplace_back(indicator_button); + } + + // Discards the indicator at the end of the container. + void PopIndicator() { + DCHECK(buttons_.size()); + auto indicator_button = buttons_.back(); + buttons_.pop_back(); + RemoveChildViewT(indicator_button); + } + + // Gets indicator corresponding to the given page. + IndicatorButton* GetIndicatorByPage(int page) { + DCHECK_GE(page, 0); + DCHECK_LT(page, static_cast<int>(buttons_.size())); + return buttons_[page].get(); + } + + // Sets up scrolling if an invisible page is selected. + void StartScroll(int start_page, int target_page) { + // Scroll the indicator container by the distance of a indicator button size + // plus button spacing to reveal the next/previous indicator. + // TODO(zxdan): settings bounds at each step will cause repainting which is + // expensive. However, using transform sometimes makes the stroke of + // indicator circle become thicker. Will investigate the cause latter. + const bool left = start_page < target_page; + const int start_page_offset = + left ? kMaxNumVisibleIndicators - start_page - 1 : -start_page; + const int target_page_offset = + left ? kMaxNumVisibleIndicators - target_page - 1 : -target_page; + const int scroll_unit = kIndicatorButtonSize + kIndicatorSpacing; + scroll_interval_ = {0.0, start_page_offset * scroll_unit, 1.0, + target_page_offset * scroll_unit}; + } + + // Scrolls the indicator container according to the given progress value. + void Scroll(double progress) { + if (!scroll_interval_) { + return; + } + + // Interpolate the scroll interval to get current container bounds. + SetX(gfx::Tween::IntValueBetween(progress, scroll_interval_->start_value, + scroll_interval_->target_value)); + } + + void ResetScroll(bool canceled) { + if (scroll_interval_) { + SetX(canceled ? scroll_interval_->start_value + : scroll_interval_->target_value); + } + scroll_interval_ = absl::nullopt; + } + + // Returns true if the scrolling is in progress. + bool ScrollingInProgress() { return !!scroll_interval_; } + + private: + std::vector<base::raw_ptr<IndicatorButton>> buttons_; + absl::optional<InterpolationInterval<int>> scroll_interval_; +}; + +BEGIN_METADATA(PaginationView, IndicatorContainer, views::BoxLayoutView) +END_METADATA + +//------------------------------------------------------------------------------ +// PaginationView: +PaginationView::PaginationView(PaginationModel* model) + : model_(model), + indicator_scroll_view_( + AddChildView(std::make_unique<views::ScrollView>())), + indicator_container_(indicator_scroll_view_->SetContents( + std::make_unique<IndicatorContainer>())) { + DCHECK(model_); + + model_observation_.Observe(model_.get()); + + // The scroll view does not accept scroll event. + indicator_scroll_view_->SetHorizontalScrollBarMode( + views::ScrollView::ScrollBarMode::kDisabled); + indicator_scroll_view_->SetVerticalScrollBarMode( + views::ScrollView::ScrollBarMode::kDisabled); + + TotalPagesChanged(0, model_->total_pages()); + + if (model_->is_valid_page(model_->selected_page())) { + CreateSelectorDot(); + } +} + +PaginationView::~PaginationView() = default; + +gfx::Size PaginationView::CalculatePreferredSize() const { + const int total_pages = model_->total_pages(); + const int visible_num = std::min(total_pages, kMaxNumVisibleIndicators); + const int container_width = visible_num * kIndicatorButtonSize + + (visible_num - 1) * kIndicatorSpacing; + + // If the number of total pages does not exceed visible maximum, only show + // indicator container. + if (total_pages <= visible_num) { + return gfx::Size(container_width, kIndicatorButtonSize); + } + + // Otherwise, show indicator container and arrow buttons. + return gfx::Size( + container_width + 2 * (kArrowButtonIconSize + kArrowIndicatorSpacing), + kIndicatorButtonSize); +} + +void PaginationView::Layout() { + int offset_x = 0; + // Set the left arrow button if exists. + if (left_arrow_button_) { + left_arrow_button_->SetBounds(offset_x, 0, kArrowButtonIconSize, + kArrowButtonIconSize); + offset_x += left_arrow_button_->width() + kArrowIndicatorSpacing; + } + + // Set the indicator container. + indicator_container_->SizeToPreferredSize(); + const int visible_num = + std::min(model_->total_pages(), kMaxNumVisibleIndicators); + indicator_scroll_view_->SetBounds(offset_x, 0, + visible_num * kIndicatorButtonSize + + (visible_num - 1) * kIndicatorSpacing, + kIndicatorButtonSize); + + offset_x += indicator_scroll_view_->width() + kArrowIndicatorSpacing; + + // Set the right arrow button if exists. + if (right_arrow_button_) { + right_arrow_button_->SetBounds(offset_x, 0, kIndicatorButtonSize, + kIndicatorButtonSize); + } + + // Update arrow button visibility and selector dot position. + UpdateArrowButtonsVisiblity(); + UpdateSelectorDot(); +} + +void PaginationView::CreateArrowButtons() { + for (bool left : {true, false}) { + auto arrow_button = std::make_unique<views::ImageButton>( + base::BindRepeating(&PaginationView::OnArrowButtonPressed, + base::Unretained(this), left)); + + arrow_button->SetImageModel( + views::ImageButton::ButtonState::STATE_NORMAL, + ui::ImageModel::FromVectorIcon( + left ? kOverflowShelfLeftIcon : kOverflowShelfRightIcon, + kArrowButtonColorId, kArrowButtonIconSize)); + + if (left) { + arrow_button->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_PAGINATION_LEFT_ARROW_TOOLTIP)); + left_arrow_button_ = AddChildView(std::move(arrow_button)); + } else { + arrow_button->SetTooltipText( + l10n_util::GetStringUTF16(IDS_ASH_PAGINATION_RIGHT_ARROW_TOOLTIP)); + right_arrow_button_ = AddChildView(std::move(arrow_button)); + } + } +} + +void PaginationView::RemoveArrowButtons() { + RemoveChildViewT(left_arrow_button_); + left_arrow_button_ = nullptr; + + RemoveChildViewT(right_arrow_button_); + right_arrow_button_ = nullptr; +} + +void PaginationView::UpdateArrowButtonsVisiblity() { + // If the first page indicator is visible, hide the left arrow button. + if (left_arrow_button_) { + left_arrow_button_->SetVisible(!IsIndicatorVisible(0)); + } + + // If the last page indicator is visible, hide the right arrow button. + if (right_arrow_button_) { + right_arrow_button_->SetVisible( + !IsIndicatorVisible(model_->total_pages() - 1)); + } +} + +void PaginationView::OnArrowButtonPressed(bool left, const ui::Event& event) { + const int page_offset = left ? -1 : 1; + model_->SelectPage(model_->selected_page() + page_offset, /*animate=*/true); +} + +void PaginationView::MaybeSetUpScroll() { + const int current_page = model_->selected_page(); + const int target_page = model_->transition().target_page; + if (!model_->is_valid_page(current_page) || + !model_->is_valid_page(target_page)) { + return; + } + + // If the target page indicator is not in visible area, scroll the container. + if (!IsIndicatorVisible(target_page)) { + indicator_container_->StartScroll(current_page, target_page); + } +} + +void PaginationView::CreateSelectorDot() { + if (selector_dot_) { + return; + } + + selector_dot_ = + indicator_container_->AddChildView(std::make_unique<SelectorDotView>()); + UpdateSelectorDot(); +} + +void PaginationView::RemoveSelectorDot() { + if (!selector_dot_) { + return; + } + + indicator_container_->RemoveChildViewT(selector_dot_); + selector_dot_ = nullptr; +} + +void PaginationView::UpdateSelectorDot() { + if (!selector_dot_) { + return; + } + + // Move the selector dot to the position of selected page indicator if the + // selector dot is not deforming. + const int selected_page = model_->selected_page(); + DCHECK(model_->is_valid_page(selected_page)); + if (!selector_dot_->DeformingInProgress()) { + selector_dot_->SetBoundsRect( + indicator_container_->GetIndicatorByPage(selected_page) + ->GetIndicatorBounds()); + } +} + +void PaginationView::SetUpSelectorDotDeformation() { + DCHECK(!selector_dot_->DeformingInProgress()); + + const int current_page = model_->selected_page(); + const int target_page = model_->transition().target_page; + + if (!model_->is_valid_page(current_page) || + !model_->is_valid_page(target_page)) { + return; + } + + const gfx::Rect current_bounds = + indicator_container_->GetIndicatorByPage(current_page) + ->GetIndicatorBounds(); + const gfx::Rect target_bounds = + indicator_container_->GetIndicatorByPage(target_page) + ->GetIndicatorBounds(); + // If moves to a neighbor page, the selector dot will first be stretched into + // a pill shape until it connects the current indicator to the target + // indicator, and then shrink back to a circle at the target indicator + // position. + if (std::abs(target_page - current_page) == 1) { + const gfx::Rect intermediate_bounds = + gfx::UnionRects(current_bounds, target_bounds); + selector_dot_->AddDeformInterval( + {0.0, current_bounds, 0.5, intermediate_bounds}); + selector_dot_->AddDeformInterval( + {0.5, intermediate_bounds, 1.0, target_bounds}); + return; + } + + // If jumps across multiple pages, the selector dot will first shrink at the + // current indicator position, and then expand at the target indicator + // position. + selector_dot_->AddDeformInterval( + {0.0, current_bounds, 0.5, + gfx::Rect(current_bounds.CenterPoint(), gfx::Size())}); + selector_dot_->AddDeformInterval( + {0.5, gfx::Rect(target_bounds.CenterPoint(), gfx::Size()), 1.0, + target_bounds}); +} + +bool PaginationView::IsIndicatorVisible(int page) const { + // Check if the indicator is in the visible rect of the scroll view. + return indicator_scroll_view_->GetVisibleRect().Contains( + indicator_container_->GetIndicatorByPage(page)->bounds()); +} + +void PaginationView::SelectedPageChanged(int old_selected, int new_selected) { + // Update selector dot position and arrow buttons visibility. + if (model_->is_valid_page(new_selected)) { + if (!selector_dot_) { + CreateSelectorDot(); + } else { + // Finish and reset ongoing deformation. + selector_dot_->ResetDeform(/*canceled=*/false); + } + } else { + RemoveSelectorDot(); + } + + // Finish and reset ongoing indicator container scrolling. + if (indicator_container_->ScrollingInProgress()) { + indicator_container_->ResetScroll(/*canceled=*/false); + UpdateArrowButtonsVisiblity(); + } +} + +void PaginationView::TotalPagesChanged(int previous_page_count, + int new_page_count) { + if (previous_page_count < new_page_count) { + // Add more indicators at the end of container. + for (int i = previous_page_count; i < new_page_count; i++) { + indicator_container_->PushIndicator(model_.get()); + } + + // Add arrow buttons if the number of total pages exceeds the visible + // maximum. + if (previous_page_count <= kMaxNumVisibleIndicators && + new_page_count > kMaxNumVisibleIndicators) { + CreateArrowButtons(); + } + } else { + // Remove indicators from the end of the container. + for (int i = previous_page_count; i > new_page_count; i--) { + indicator_container_->PopIndicator(); + } + + // Remove arrow buttons if the number of total pages does not exceed the + // visible maximum. + if (previous_page_count > kMaxNumVisibleIndicators && + new_page_count <= kMaxNumVisibleIndicators) { + RemoveArrowButtons(); + } + + // Remove the selector dot if there is no pages. + if (new_page_count == 0) { + RemoveSelectorDot(); + } + } + + Layout(); +} + +void PaginationView::TransitionChanged() { + // If there is no transition, reset and cancel current selector dot + // deformation and indicator container scrolling. + if (!model_->has_transition()) { + selector_dot_->ResetDeform(/*canceled=*/true); + indicator_container_->ResetScroll(/*canceled=*/true); + return; + } + + const double progress = model_->transition().progress; + + // Scroll the indicator container if needed. + if (!indicator_container_->ScrollingInProgress()) { + MaybeSetUpScroll(); + } + indicator_container_->Scroll(progress); + + // Deform the selector dot. + if (!selector_dot_->DeformingInProgress()) { + SetUpSelectorDotDeformation(); + } + // Deform the selector dot. + selector_dot_->Deform(progress); +} + +BEGIN_METADATA(PaginationView, views::View) +END_METADATA +} // namespace ash
diff --git a/ash/style/pagination_view.h b/ash/style/pagination_view.h new file mode 100644 index 0000000..df44fb64 --- /dev/null +++ b/ash/style/pagination_view.h
@@ -0,0 +1,106 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ASH_STYLE_PAGINATION_VIEW_H_ +#define ASH_STYLE_PAGINATION_VIEW_H_ + +#include "ash/ash_export.h" +#include "ash/public/cpp/pagination/pagination_model_observer.h" +#include "base/scoped_observation.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/views/view.h" + +namespace views { +class ImageButton; +class ScrollView; +} // namespace views + +namespace ash { + +class PaginationModel; + +// PaginationView is used to paginate the UI surface with multiple pages of +// contents. It has as many indicators as pages. Pressing an indicator will jump +// to the corresponding page. There is a maximum number of visible indicators. +// If the number of total pages exceeds the visible maximum, two arrow-shaped +// overflow buttons will be shown on both sides. The arrow buttons can also +// control pagination. The layout of a pagination view with arrow buttons is +// like below: +// +---+---+---+---+---+---+---+ +// | < | o | o | o | o | o | > | +// +-|-+---+---+-|-+---+---+-|-+ +// left arrow button | right arrow button +// indicator +// +// When a page is selected, a selector dot (a solid circle) will move to the +// corresponding indicator. The selector dot has two motion effects: +// - If moves to a neighbor page, the selector dot will first be stretched into +// a pill shape until it connects the current indicator to the target indicator, +// and then shrink back to a circle at the target indicator position. +// - If jumps across multiple pages, the selector dot will first shrink at the +// current indicator position, and then expand at the target indicator position. +class ASH_EXPORT PaginationView : public views::View, + public PaginationModelObserver { + public: + METADATA_HEADER(PaginationView); + + // A paginaition view only binds with one pagination model, but the pagination + // model may control multiple views. Therefore, pagination model should + // outlive the pagination view. + explicit PaginationView(PaginationModel* model); + PaginationView(const PaginationView&) = delete; + PaginationView& operator=(const PaginationView*) = delete; + ~PaginationView() override; + + // views::View: + gfx::Size CalculatePreferredSize() const override; + void Layout() override; + + private: + // A filled circle with pagination motion effects. + class SelectorDotView; + // The container of indicators. + class IndicatorContainer; + + void CreateArrowButtons(); + void RemoveArrowButtons(); + void UpdateArrowButtonsVisiblity(); + void OnArrowButtonPressed(bool left, const ui::Event& event); + void MaybeSetUpScroll(); + + void CreateSelectorDot(); + void RemoveSelectorDot(); + void UpdateSelectorDot(); + void SetUpSelectorDotDeformation(); + + // Returns true if the indicator button corresponding to the given page is + // currently visible. + bool IsIndicatorVisible(int page) const; + + // PaginationModelObserver: + void TotalPagesChanged(int previous_page_count, int new_page_count) override; + void SelectedPageChanged(int old_selected, int new_selected) override; + void TransitionChanged() override; + + base::raw_ptr<PaginationModel> const model_; + + // The scroll view with an indicator container as its contents. The scroll + // view is owned by this and the container is owned by the scroll view. + base::raw_ptr<views::ScrollView> indicator_scroll_view_ = nullptr; + base::raw_ptr<IndicatorContainer> indicator_container_ = nullptr; + + // The selector dot view which is owned by this. + base::raw_ptr<SelectorDotView> selector_dot_ = nullptr; + + // The arrow buttons owned by this. + base::raw_ptr<views::ImageButton> left_arrow_button_ = nullptr; + base::raw_ptr<views::ImageButton> right_arrow_button_ = nullptr; + + base::ScopedObservation<PaginationModel, PaginationModelObserver> + model_observation_{this}; +}; + +} // namespace ash + +#endif // ASH_STYLE_PAGINATION_VIEW_H_
diff --git a/ash/system/audio/audio_detailed_view.cc b/ash/system/audio/audio_detailed_view.cc index 60045510..22b08a4d 100644 --- a/ash/system/audio/audio_detailed_view.cc +++ b/ash/system/audio/audio_detailed_view.cc
@@ -41,6 +41,7 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/paint_vector_icon.h" #include "ui/gfx/vector_icon_types.h" +#include "ui/views/accessibility/view_accessibility.h" #include "ui/views/border.h" #include "ui/views/controls/button/toggle_button.h" #include "ui/views/controls/focus_ring.h" @@ -61,6 +62,11 @@ constexpr auto kLiveCaptionContainerMargins = gfx::Insets::TLBR(0, 0, 8, 0); constexpr auto kToggleButtonRowLabelPadding = gfx::Insets::TLBR(16, 0, 15, 0); constexpr auto kToggleButtonRowViewPadding = gfx::Insets::TLBR(0, 56, 8, 0); +constexpr auto kQsToggleButtonRowViewPadding = gfx::Insets::VH(0, 32); +constexpr auto kQsToggleButtonRowPreferredSize = gfx::Size(0, 32); +constexpr auto kQsToggleButtonRowLabelPadding = gfx::Insets::VH(8, 12); +constexpr auto kQsToggleButtonRowMargins = gfx::Insets::VH(4, 0); +constexpr auto kSeparatorMargins = gfx::Insets::TLBR(4, 32, 12, 32); constexpr auto kTextRowInsets = gfx::Insets::VH(8, 24); constexpr auto kDevicesNameViewPreferredSize = gfx::Size(0, 44); constexpr auto kDevicesTriViewInsets = gfx::Insets::TLBR(0, 24, 0, 32); @@ -317,7 +323,7 @@ live_caption_enabled ? kUnifiedMenuLiveCaptionIcon : kUnifiedMenuLiveCaptionOffIcon, cros_tokens::kCrosSysOnSurface, kQsSliderIconSize)); - toggle_icon_ = toggle_icon.get(); + live_caption_icon_ = toggle_icon.get(); // TODO(b/262281693): Update the font and color for `live_caption_view_` text. live_caption_view_->AddViewAndLabel( std::move(toggle_icon), @@ -338,7 +344,7 @@ IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP); toggle->SetTooltipText(l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP, toggle_tooltip)); - toggle_button_ = toggle.get(); + live_caption_button_ = toggle.get(); live_caption_view_->AddRightView(toggle.release()); // Allows the row to be taller than a typical tray menu item. @@ -396,6 +402,65 @@ return noise_cancellation_toggle_row; } +std::unique_ptr<HoverHighlightView> +AudioDetailedView::CreateQsNoiseCancellationToggleRow( + const AudioDevice& device) { + bool noise_cancellation_state = + CrasAudioHandler::Get()->GetNoiseCancellationState(); + + auto noise_cancellation_view = + std::make_unique<HoverHighlightView>(/*listener=*/this); + + auto toggle_icon = + std::make_unique<views::ImageView>(ui::ImageModel::FromVectorIcon( + noise_cancellation_state ? kUnifiedMenuMicNoiseCancelHighIcon + : kUnifiedMenuMicNoiseCancelOffIcon, + cros_tokens::kCrosSysOnSurface, kQsSliderIconSize)); + noise_cancellation_icon_ = toggle_icon.get(); + + noise_cancellation_view->AddViewAndLabel( + std::move(toggle_icon), + l10n_util::GetStringUTF16( + IDS_ASH_STATUS_TRAY_AUDIO_INPUT_NOISE_CANCELLATION)); + + // Create a non-clickable non-focusable toggle button on the right. The events + // and focus behavior should be handled by `noise_cancellation_view_` instead. + auto toggle = + std::make_unique<TrayToggleButton>(views::Button::PressedCallback(), + /*accessible_name_id=*/absl::nullopt, + /*use_empty_border=*/true); + toggle->SetIsOn(noise_cancellation_state); + toggle->SetCanProcessEventsWithinSubtree(false); + toggle->SetFocusBehavior(views::View::FocusBehavior::NEVER); + // Ignore the toggle for accessibility. + auto& view_accessibility = toggle->GetViewAccessibility(); + view_accessibility.OverrideIsLeaf(true); + view_accessibility.OverrideIsIgnored(true); + noise_cancellation_button_ = toggle.get(); + noise_cancellation_view->AddRightView(toggle.release()); + + noise_cancellation_view->tri_view()->SetInsets(kQsToggleButtonRowViewPadding); + noise_cancellation_view->tri_view()->SetContainerLayout( + TriView::Container::CENTER, std::make_unique<views::BoxLayout>( + views::BoxLayout::Orientation::kVertical, + kQsToggleButtonRowLabelPadding)); + noise_cancellation_view->SetPreferredSize(kQsToggleButtonRowPreferredSize); + noise_cancellation_view->SetProperty(views::kMarginsKey, + kQsToggleButtonRowMargins); + noise_cancellation_view->SetAccessibilityState( + noise_cancellation_state + ? HoverHighlightView::AccessibilityState::CHECKED_CHECKBOX + : HoverHighlightView::AccessibilityState::UNCHECKED_CHECKBOX); + + // This is only used for testing. + if (g_noise_cancellation_toggle_callback) { + g_noise_cancellation_toggle_callback->Run(device.id, + noise_cancellation_view.get()); + } + + return noise_cancellation_view; +} + void AudioDetailedView::MaybeShowSodaMessage(speech::LanguageCode language_code, std::u16string message) { AccessibilityControllerImpl* controller = @@ -421,6 +486,13 @@ const bool new_state = !audio_handler->GetNoiseCancellationState(); audio_handler->SetNoiseCancellationState(new_state); audio_handler->SetNoiseCancellationPrefState(new_state); + if (features::IsQsRevampEnabled()) { + noise_cancellation_icon_->SetImage(ui::ImageModel::FromVectorIcon( + new_state ? kUnifiedMenuMicNoiseCancelHighIcon + : kUnifiedMenuMicNoiseCancelOffIcon, + cros_tokens::kCrosSysOnSurface, kQsSliderIconSize)); + noise_cancellation_button_->SetIsOn(new_state); + } } void AudioDetailedView::ToggleLiveCaptionState() { @@ -431,7 +503,7 @@ } void AudioDetailedView::UpdateLiveCaptionView(bool is_enabled) { - toggle_icon_->SetImage(ui::ImageModel::FromVectorIcon( + live_caption_icon_->SetImage(ui::ImageModel::FromVectorIcon( is_enabled ? kUnifiedMenuLiveCaptionIcon : kUnifiedMenuLiveCaptionOffIcon, cros_tokens::kCrosSysOnSurface, kQsSliderIconSize)); @@ -441,12 +513,12 @@ IDS_ASH_STATUS_TRAY_LIVE_CAPTION_ENABLED_STATE_TOOLTIP) : l10n_util::GetStringUTF16( IDS_ASH_STATUS_TRAY_LIVE_CAPTION_DISABLED_STATE_TOOLTIP); - toggle_button_->SetTooltipText(l10n_util::GetStringFUTF16( + live_caption_button_->SetTooltipText(l10n_util::GetStringFUTF16( IDS_ASH_STATUS_TRAY_LIVE_CAPTION_TOGGLE_TOOLTIP, toggle_tooltip)); // Ensures the toggle button is in sync with the current Live Caption state. - if (toggle_button_->GetIsOn() != is_enabled) { - toggle_button_->SetIsOn(is_enabled); + if (live_caption_button_->GetIsOn() != is_enabled) { + live_caption_button_->SetIsOn(is_enabled); } InvalidateLayout(); @@ -587,8 +659,22 @@ if (audio_handler->GetPrimaryActiveInputNode() == device.id && audio_handler->noise_cancellation_supported() && (device.audio_effect & cras::EFFECT_TYPE_NOISE_CANCELLATION)) { - container->AddChildView( - AudioDetailedView::CreateNoiseCancellationToggleRow(device)); + if (features::IsQsRevampEnabled()) { + noise_cancellation_view_ = container->AddChildView( + AudioDetailedView::CreateQsNoiseCancellationToggleRow(device)); + + // Adds a `Separator` if this input device is not the last one. + if (&device != &input_devices_.back()) { + auto* separator = + container->AddChildView(std::make_unique<views::Separator>()); + separator->SetColorId(cros_tokens::kCrosSysSeparator); + separator->SetOrientation(views::Separator::Orientation::kHorizontal); + separator->SetProperty(views::kMarginsKey, kSeparatorMargins); + } + } else { + container->AddChildView( + AudioDetailedView::CreateNoiseCancellationToggleRow(device)); + } } if (!features::IsQsRevampEnabled()) { @@ -607,6 +693,11 @@ return; } + if (noise_cancellation_view_ && view == noise_cancellation_view_) { + OnInputNoiseCancellationTogglePressed(); + return; + } + AudioDeviceMap::iterator iter = device_map_.find(view); if (iter == device_map_.end()) return;
diff --git a/ash/system/audio/audio_detailed_view.h b/ash/system/audio/audio_detailed_view.h index 28463b7..2763002 100644 --- a/ash/system/audio/audio_detailed_view.h +++ b/ash/system/audio/audio_detailed_view.h
@@ -11,6 +11,7 @@ #include "ash/accessibility/accessibility_observer.h" #include "ash/ash_export.h" +#include "ash/system/tray/hover_highlight_view.h" #include "ash/system/tray/tray_detailed_view.h" #include "chromeos/ash/components/audio/audio_device.h" #include "components/soda/soda_installer.h" @@ -77,6 +78,11 @@ std::unique_ptr<views::View> CreateNoiseCancellationToggleRow( const AudioDevice& device); + // For QsRevamp: Creates the noise cancellation toggle row in the input + // subsection. + std::unique_ptr<HoverHighlightView> CreateQsNoiseCancellationToggleRow( + const AudioDevice& device); + // Sets the subtext for `live_caption_view_` based on whether live caption has // updated if this feature is enabled and visible in tray. void MaybeShowSodaMessage(speech::LanguageCode language_code, @@ -119,8 +125,11 @@ uint64_t focused_device_id_ = -1; // Owned by the views hierarchy. HoverHighlightView* live_caption_view_ = nullptr; - views::ImageView* toggle_icon_ = nullptr; - views::ToggleButton* toggle_button_ = nullptr; + views::ImageView* live_caption_icon_ = nullptr; + views::ToggleButton* live_caption_button_ = nullptr; + HoverHighlightView* noise_cancellation_view_ = nullptr; + views::ImageView* noise_cancellation_icon_ = nullptr; + views::ToggleButton* noise_cancellation_button_ = nullptr; base::WeakPtrFactory<AudioDetailedView> weak_factory_{this}; };
diff --git a/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc b/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc index 16b9108..5bfb535 100644 --- a/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc +++ b/ash/system/audio/unified_audio_detailed_view_controller_unittest.cc
@@ -200,7 +200,13 @@ } void ToggleLiveCaption() { - audio_detailed_view()->HandleViewClicked(live_caption_view()); + GetAudioDetailedView()->HandleViewClicked(live_caption_view()); + } + + // Toggles the noise cancellation button for QsRevamp. + void ToggleNoiseCancellation() { + GetAudioDetailedView()->HandleViewClicked( + GetAudioDetailedView()->noise_cancellation_view_); } protected: @@ -208,7 +214,7 @@ return FakeCrasAudioClient::Get(); } - AudioDetailedView* audio_detailed_view() { + AudioDetailedView* GetAudioDetailedView() { if (!audio_detailed_view_) { audio_detailed_view_ = base::WrapUnique(static_cast<AudioDetailedView*>( audio_detailed_view_controller_->CreateView().release())); @@ -217,7 +223,11 @@ } HoverHighlightView* live_caption_view() { - return audio_detailed_view()->live_caption_view_; + return GetAudioDetailedView()->live_caption_view_; + } + + views::ToggleButton* noise_cancellation_button() { + return GetAudioDetailedView()->noise_cancellation_button_; } bool live_caption_enabled() { @@ -420,13 +430,18 @@ cras_audio_handler_->SwitchToDevice(internal_mic, true, CrasAudioHandler::ACTIVATE_BY_USER); - std::unique_ptr<views::View> view = - audio_detailed_view_controller_->CreateView(); + // If `audio_detailed_view_` doesn't exist, this getter method will create the + // view first. + GetAudioDetailedView(); EXPECT_EQ(1u, toggles_map_.size()); - views::ToggleButton* toggle = - (views::ToggleButton*)toggles_map_[internal_mic.id]->children()[1]; - EXPECT_TRUE(toggle->GetIsOn()); + if (!IsQsRevampEnabled()) { + views::ToggleButton* toggle = + (views::ToggleButton*)toggles_map_[internal_mic.id]->children()[1]; + EXPECT_TRUE(toggle->GetIsOn()); + } else { + EXPECT_TRUE(noise_cancellation_button()); + } } TEST_P(UnifiedAudioDetailedViewControllerTest, @@ -442,31 +457,47 @@ cras_audio_handler_->SwitchToDevice(internal_mic, true, CrasAudioHandler::ACTIVATE_BY_USER); - std::unique_ptr<views::View> view = - audio_detailed_view_controller_->CreateView(); + // If `audio_detailed_view_` doesn't exist, this getter method will create the + // view first. + GetAudioDetailedView(); EXPECT_EQ(1u, toggles_map_.size()); - views::ToggleButton* toggle = - (views::ToggleButton*)toggles_map_[internal_mic.id]->children()[1]; - auto widget = CreateFramelessTestWidget(); - widget->SetContentsView(toggle); + if (!IsQsRevampEnabled()) { + views::ToggleButton* toggle = + (views::ToggleButton*)toggles_map_[internal_mic.id]->children()[1]; + auto widget = CreateFramelessTestWidget(); + widget->SetContentsView(toggle); - // The toggle loaded the pref correctly. - EXPECT_FALSE(toggle->GetIsOn()); - EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState()); + // The toggle loaded the pref correctly. + EXPECT_FALSE(toggle->GetIsOn()); + EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState()); + ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::PointF(), gfx::PointF(), + ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, + ui::EF_NONE); - ui::MouseEvent press(ui::ET_MOUSE_PRESSED, gfx::PointF(), gfx::PointF(), - ui::EventTimeForNow(), ui::EF_LEFT_MOUSE_BUTTON, - ui::EF_NONE); + // Flipping the toggle. + views::test::ButtonTestApi(toggle).NotifyClick(press); + // The new state of the toggle must be saved to the prefs. + EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState()); - // Flipping the toggle. - views::test::ButtonTestApi(toggle).NotifyClick(press); - // The new state of the toggle must be saved to the prefs. - EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState()); + // Flipping back and checking the prefs again. + views::test::ButtonTestApi(toggle).NotifyClick(press); + EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState()); + } else { + auto widget = CreateFramelessTestWidget(); + widget->SetContentsView(noise_cancellation_button()); - // Flipping back and checking the prefs again. - views::test::ButtonTestApi(toggle).NotifyClick(press); - EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState()); + // The toggle loaded the pref correctly. + EXPECT_FALSE(noise_cancellation_button()->GetIsOn()); + EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState()); + + // For QsRevamp, the entire row of `noise_cancellation_view_` is clickable. + ToggleNoiseCancellation(); + EXPECT_TRUE(audio_pref_handler_->GetNoiseCancellationState()); + + ToggleNoiseCancellation(); + EXPECT_FALSE(audio_pref_handler_->GetNoiseCancellationState()); + } } TEST_P(UnifiedAudioDetailedViewControllerTest,
diff --git a/ash/system/input_device_settings/input_device_notifier.cc b/ash/system/input_device_settings/input_device_notifier.cc index 9c9251d..19c11fb 100644 --- a/ash/system/input_device_settings/input_device_notifier.cc +++ b/ash/system/input_device_settings/input_device_notifier.cc
@@ -3,6 +3,7 @@ // found in the LICENSE file. #include "ash/system/input_device_settings/input_device_notifier.h" + #include "ash/public/cpp/input_device_settings_controller.h" #include "ash/public/mojom/input_device_settings.mojom.h" #include "base/containers/flat_map.h" @@ -119,8 +120,32 @@ return ui::DeviceDataManager::GetInstance()->GetKeyboardDevices(); } +template <> +std::vector<ui::InputDevice> +InputDeviceNotifier<mojom::TouchpadPtr>::GetUpdatedDeviceList() { + return ui::DeviceDataManager::GetInstance()->GetTouchpadDevices(); +} + +template <> +std::vector<ui::InputDevice> +InputDeviceNotifier<mojom::MousePtr>::GetUpdatedDeviceList() { + return ui::DeviceDataManager::GetInstance()->GetMouseDevices(); +} + +template <> +std::vector<ui::InputDevice> +InputDeviceNotifier<mojom::PointingStickPtr>::GetUpdatedDeviceList() { + return ui::DeviceDataManager::GetInstance()->GetPointingStickDevices(); +} + // Explicit instantiations for each device type. template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) InputDeviceNotifier<mojom::KeyboardPtr>; +template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) + InputDeviceNotifier<mojom::TouchpadPtr>; +template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) + InputDeviceNotifier<mojom::MousePtr>; +template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) + InputDeviceNotifier<mojom::PointingStickPtr>; } // namespace ash
diff --git a/ash/system/input_device_settings/input_device_notifier.h b/ash/system/input_device_settings/input_device_notifier.h index ee3e48d..d0bb480 100644 --- a/ash/system/input_device_settings/input_device_notifier.h +++ b/ash/system/input_device_settings/input_device_notifier.h
@@ -58,9 +58,24 @@ template <> ASH_EXPORT std::vector<ui::InputDevice> InputDeviceNotifier<mojom::KeyboardPtr>::GetUpdatedDeviceList(); +template <> +ASH_EXPORT std::vector<ui::InputDevice> +InputDeviceNotifier<mojom::TouchpadPtr>::GetUpdatedDeviceList(); +template <> +ASH_EXPORT std::vector<ui::InputDevice> +InputDeviceNotifier<mojom::MousePtr>::GetUpdatedDeviceList(); +template <> +ASH_EXPORT std::vector<ui::InputDevice> +InputDeviceNotifier<mojom::PointingStickPtr>::GetUpdatedDeviceList(); extern template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) InputDeviceNotifier<mojom::KeyboardPtr>; +extern template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) + InputDeviceNotifier<mojom::TouchpadPtr>; +extern template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) + InputDeviceNotifier<mojom::MousePtr>; +extern template class EXPORT_TEMPLATE_DECLARE(ASH_EXPORT) + InputDeviceNotifier<mojom::PointingStickPtr>; } // namespace ash
diff --git a/ash/system/input_device_settings/input_device_settings_controller_impl.cc b/ash/system/input_device_settings/input_device_settings_controller_impl.cc index 5971086..cd3983d 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_impl.cc +++ b/ash/system/input_device_settings/input_device_settings_controller_impl.cc
@@ -8,9 +8,11 @@ #include <memory> #include <vector> +#include "ash/public/cpp/input_device_settings_controller.h" #include "ash/public/mojom/input_device_settings.mojom.h" #include "ash/session/session_controller_impl.h" #include "ash/shell.h" +#include "ash/system/input_device_settings/input_device_notifier.h" #include "ash/system/input_device_settings/input_device_settings_pref_names.h" #include "ash/system/input_device_settings/input_device_settings_utils.h" #include "ash/system/input_device_settings/pref_handlers/keyboard_pref_handler_impl.h" @@ -32,6 +34,34 @@ mojom_keyboard->device_key = BuildDeviceKey(keyboard); return mojom_keyboard; } + +mojom::MousePtr BuildMojomMouse(const ui::InputDevice& mouse) { + // TODO(dpad): Fully initialize the objects. + mojom::MousePtr mojom_mouse = mojom::Mouse::New(); + mojom_mouse->id = mouse.id; + mojom_mouse->name = mouse.name; + mojom_mouse->device_key = BuildDeviceKey(mouse); + return mojom_mouse; +} + +mojom::TouchpadPtr BuildMojomTouchpad(const ui::InputDevice& touchpad) { + // TODO(dpad): Fully initialize the objects. + mojom::TouchpadPtr mojom_touchpad = mojom::Touchpad::New(); + mojom_touchpad->id = touchpad.id; + mojom_touchpad->name = touchpad.name; + mojom_touchpad->device_key = BuildDeviceKey(touchpad); + return mojom_touchpad; +} + +mojom::PointingStickPtr BuildMojomPointingStick( + const ui::InputDevice& touchpad) { + // TODO(dpad): Fully initialize the objects. + mojom::PointingStickPtr mojom_pointing_stick = mojom::PointingStick::New(); + mojom_pointing_stick->id = touchpad.id; + mojom_pointing_stick->name = touchpad.name; + mojom_pointing_stick->device_key = BuildDeviceKey(touchpad); + return mojom_pointing_stick; +} } // namespace InputDeviceSettingsControllerImpl::InputDeviceSettingsControllerImpl() @@ -55,15 +85,28 @@ base::BindRepeating( &InputDeviceSettingsControllerImpl::OnKeyboardListUpdated, base::Unretained(this))); + mouse_notifier_ = std::make_unique<InputDeviceNotifier<mojom::MousePtr>>( + &mice_, base::BindRepeating( + &InputDeviceSettingsControllerImpl::OnMouseListUpdated, + base::Unretained(this))); + touchpad_notifier_ = + std::make_unique<InputDeviceNotifier<mojom::TouchpadPtr>>( + &touchpads_, + base::BindRepeating( + &InputDeviceSettingsControllerImpl::OnTouchpadListUpdated, + base::Unretained(this))); + pointing_stick_notifier_ = + std::make_unique<InputDeviceNotifier<mojom::PointingStickPtr>>( + &pointing_sticks_, + base::BindRepeating( + &InputDeviceSettingsControllerImpl::OnPointingStickListUpdated, + base::Unretained(this))); } InputDeviceSettingsControllerImpl::~InputDeviceSettingsControllerImpl() { if (features::IsInputDeviceSettingsSplitEnabled()) { Shell::Get()->session_controller()->RemoveObserver(this); } - // Manually reset `keyboard_notifier_` to avoid any race conditions between - // `keyboard_notifier_` and `keyboards_`. - keyboard_notifier_.reset(); } void InputDeviceSettingsControllerImpl::RegisterProfilePrefs( @@ -93,6 +136,42 @@ return keyboard_vector; } +std::vector<mojom::TouchpadPtr> +InputDeviceSettingsControllerImpl::GetConnectedTouchpads() { + std::vector<mojom::TouchpadPtr> mouse_vector; + mouse_vector.reserve(touchpads_.size()); + + for (const auto& [_, touchpad] : touchpads_) { + mouse_vector.push_back(touchpad->Clone()); + } + + return mouse_vector; +} + +std::vector<mojom::MousePtr> +InputDeviceSettingsControllerImpl::GetConnectedMice() { + std::vector<mojom::MousePtr> mouse_vector; + mouse_vector.reserve(mice_.size()); + + for (const auto& [_, mouse] : mice_) { + mouse_vector.push_back(mouse->Clone()); + } + + return mouse_vector; +} + +std::vector<mojom::PointingStickPtr> +InputDeviceSettingsControllerImpl::GetConnectedPointingSticks() { + std::vector<mojom::PointingStickPtr> pointing_stick_vector; + pointing_stick_vector.reserve(mice_.size()); + + for (const auto& [_, pointing_stick] : pointing_sticks_) { + pointing_stick_vector.push_back(pointing_stick->Clone()); + } + + return pointing_stick_vector; +} + // TODO(dpad): Implement updating of keyboard settings. void InputDeviceSettingsControllerImpl::SetKeyboardSettings( DeviceId id, @@ -125,13 +204,64 @@ } } +void InputDeviceSettingsControllerImpl::DispatchTouchpadConnected(DeviceId id) { + DCHECK(base::Contains(touchpads_, id)); + const auto& touchpad = *touchpads_.at(id); + for (auto& observer : observers_) { + observer.OnTouchpadConnected(touchpad); + } +} + +void InputDeviceSettingsControllerImpl::DispatchTouchpadDisconnected( + DeviceId id) { + DCHECK(base::Contains(touchpads_, id)); + const auto& touchpad = *touchpads_.at(id); + for (auto& observer : observers_) { + observer.OnTouchpadDisconnected(touchpad); + } +} + +void InputDeviceSettingsControllerImpl::DispatchMouseConnected(DeviceId id) { + DCHECK(base::Contains(mice_, id)); + const auto& mouse = *mice_.at(id); + for (auto& observer : observers_) { + observer.OnMouseConnected(mouse); + } +} + +void InputDeviceSettingsControllerImpl::DispatchMouseDisconnected(DeviceId id) { + DCHECK(base::Contains(mice_, id)); + const auto& mouse = *mice_.at(id); + for (auto& observer : observers_) { + observer.OnMouseDisconnected(mouse); + } +} + +void InputDeviceSettingsControllerImpl::DispatchPointingStickConnected( + DeviceId id) { + DCHECK(base::Contains(pointing_sticks_, id)); + const auto& pointing_stick = *pointing_sticks_.at(id); + for (auto& observer : observers_) { + observer.OnPointingStickConnected(pointing_stick); + } +} + +void InputDeviceSettingsControllerImpl::DispatchPointingStickDisconnected( + DeviceId id) { + DCHECK(base::Contains(pointing_sticks_, id)); + const auto& pointing_stick = *pointing_sticks_.at(id); + for (auto& observer : observers_) { + observer.OnPointingStickDisconnected(pointing_stick); + } +} + void InputDeviceSettingsControllerImpl::OnKeyboardListUpdated( std::vector<ui::InputDevice> keyboards_to_add, std::vector<DeviceId> keyboard_ids_to_remove) { for (const auto& keyboard : keyboards_to_add) { // Get initial settings from the pref manager and generate our local storage // of the device. - mojom::KeyboardPtr mojom_keyboard = BuildMojomKeyboard(keyboard); + auto mojom_keyboard = BuildMojomKeyboard(keyboard); if (active_pref_service_) { keyboard_pref_handler_->InitializeKeyboardSettings(active_pref_service_, mojom_keyboard.get()); @@ -146,6 +276,52 @@ } } +void InputDeviceSettingsControllerImpl::OnTouchpadListUpdated( + std::vector<ui::InputDevice> touchpads_to_add, + std::vector<DeviceId> touchpad_ids_to_remove) { + for (const auto& touchpad : touchpads_to_add) { + auto mojom_touchpad = BuildMojomTouchpad(touchpad); + touchpads_.insert_or_assign(touchpad.id, std::move(mojom_touchpad)); + DispatchTouchpadConnected(touchpad.id); + } + + for (const auto id : touchpad_ids_to_remove) { + DispatchTouchpadDisconnected(id); + touchpads_.erase(id); + } +} + +void InputDeviceSettingsControllerImpl::OnMouseListUpdated( + std::vector<ui::InputDevice> mice_to_add, + std::vector<DeviceId> mouse_ids_to_remove) { + for (const auto& mouse : mice_to_add) { + auto mojom_mouse = BuildMojomMouse(mouse); + mice_.insert_or_assign(mouse.id, std::move(mojom_mouse)); + DispatchMouseConnected(mouse.id); + } + + for (const auto id : mouse_ids_to_remove) { + DispatchMouseDisconnected(id); + mice_.erase(id); + } +} + +void InputDeviceSettingsControllerImpl::OnPointingStickListUpdated( + std::vector<ui::InputDevice> pointing_sticks_to_add, + std::vector<DeviceId> pointing_stick_ids_to_remove) { + for (const auto& pointing_stick : pointing_sticks_to_add) { + auto mojom_pointing_stick = BuildMojomPointingStick(pointing_stick); + pointing_sticks_.insert_or_assign(pointing_stick.id, + std::move(mojom_pointing_stick)); + DispatchPointingStickConnected(pointing_stick.id); + } + + for (const auto id : pointing_stick_ids_to_remove) { + DispatchPointingStickDisconnected(id); + pointing_sticks_.erase(id); + } +} + void InputDeviceSettingsControllerImpl::SetPrefHandlersForTesting( std::unique_ptr<KeyboardPrefHandler> keyboard_pref_handler) { keyboard_pref_handler_ = std::move(keyboard_pref_handler);
diff --git a/ash/system/input_device_settings/input_device_settings_controller_impl.h b/ash/system/input_device_settings/input_device_settings_controller_impl.h index 96b96230..ef616a7 100644 --- a/ash/system/input_device_settings/input_device_settings_controller_impl.h +++ b/ash/system/input_device_settings/input_device_settings_controller_impl.h
@@ -5,6 +5,8 @@ #ifndef ASH_SYSTEM_INPUT_DEVICE_SETTINGS_INPUT_DEVICE_SETTINGS_CONTROLLER_IMPL_H_ #define ASH_SYSTEM_INPUT_DEVICE_SETTINGS_INPUT_DEVICE_SETTINGS_CONTROLLER_IMPL_H_ +#include <memory> + #include "ash/ash_export.h" #include "ash/public/cpp/input_device_settings_controller.h" #include "ash/public/cpp/session/session_observer.h" @@ -38,6 +40,9 @@ // InputDeviceSettingsController: std::vector<mojom::KeyboardPtr> GetConnectedKeyboards() override; + std::vector<mojom::TouchpadPtr> GetConnectedTouchpads() override; + std::vector<mojom::MousePtr> GetConnectedMice() override; + std::vector<mojom::PointingStickPtr> GetConnectedPointingSticks() override; void SetKeyboardSettings(DeviceId id, const mojom::KeyboardSettings& settings) override; void AddObserver(Observer* observer) override; @@ -45,6 +50,13 @@ void OnKeyboardListUpdated(std::vector<ui::InputDevice> keyboards_to_add, std::vector<DeviceId> keyboard_ids_to_remove); + void OnTouchpadListUpdated(std::vector<ui::InputDevice> touchpads_to_add, + std::vector<DeviceId> touchpad_ids_to_remove); + void OnMouseListUpdated(std::vector<ui::InputDevice> mice_to_add, + std::vector<DeviceId> mouse_ids_to_remove); + void OnPointingStickListUpdated( + std::vector<ui::InputDevice> pointing_sticks_to_add, + std::vector<DeviceId> pointing_stick_ids_to_remove); // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* pref_service) override; @@ -58,11 +70,31 @@ void DispatchKeyboardConnected(DeviceId id); void DispatchKeyboardDisconnected(DeviceId id); - std::unique_ptr<KeyboardPrefHandler> keyboard_pref_handler_; - base::flat_map<DeviceId, mojom::KeyboardPtr> keyboards_; + void DispatchTouchpadConnected(DeviceId id); + void DispatchTouchpadDisconnected(DeviceId id); + + void DispatchMouseConnected(DeviceId id); + void DispatchMouseDisconnected(DeviceId id); + + void DispatchPointingStickConnected(DeviceId id); + void DispatchPointingStickDisconnected(DeviceId id); + base::ObserverList<InputDeviceSettingsController::Observer> observers_; + std::unique_ptr<KeyboardPrefHandler> keyboard_pref_handler_; + + base::flat_map<DeviceId, mojom::KeyboardPtr> keyboards_; + base::flat_map<DeviceId, mojom::TouchpadPtr> touchpads_; + base::flat_map<DeviceId, mojom::MousePtr> mice_; + base::flat_map<DeviceId, mojom::PointingStickPtr> pointing_sticks_; + + // Notifiers must be declared after the `flat_map` objects as the notifiers + // depend on these objects. std::unique_ptr<InputDeviceNotifier<mojom::KeyboardPtr>> keyboard_notifier_; + std::unique_ptr<InputDeviceNotifier<mojom::TouchpadPtr>> touchpad_notifier_; + std::unique_ptr<InputDeviceNotifier<mojom::MousePtr>> mouse_notifier_; + std::unique_ptr<InputDeviceNotifier<mojom::PointingStickPtr>> + pointing_stick_notifier_; raw_ptr<PrefService> active_pref_service_ = nullptr; // Not owned. };
diff --git a/ash/system/input_device_settings/input_device_tracker.cc b/ash/system/input_device_settings/input_device_tracker.cc index 0d6446a..9dbd903 100644 --- a/ash/system/input_device_settings/input_device_tracker.cc +++ b/ash/system/input_device_settings/input_device_tracker.cc
@@ -52,6 +52,20 @@ RecordDeviceConnected(InputDeviceCategory::kKeyboard, keyboard.device_key); } +void InputDeviceTracker::OnTouchpadConnected(const mojom::Touchpad& touchpad) { + RecordDeviceConnected(InputDeviceCategory::kTouchpad, touchpad.device_key); +} + +void InputDeviceTracker::OnMouseConnected(const mojom::Mouse& mouse) { + RecordDeviceConnected(InputDeviceCategory::kMouse, mouse.device_key); +} + +void InputDeviceTracker::OnPointingStickConnected( + const mojom::PointingStick& pointing_stick) { + RecordDeviceConnected(InputDeviceCategory::kPointingStick, + pointing_stick.device_key); +} + void InputDeviceTracker::OnActiveUserPrefServiceChanged( PrefService* pref_service) { // When the user's `pref_service` changes, we need to re-initialize our @@ -76,6 +90,25 @@ for (const auto& keyboard : keyboards) { OnKeyboardConnected(*keyboard); } + + const auto touchpads = + Shell::Get()->input_device_settings_controller()->GetConnectedTouchpads(); + for (const auto& touchpad : touchpads) { + OnTouchpadConnected(*touchpad); + } + + const auto mice = + Shell::Get()->input_device_settings_controller()->GetConnectedMice(); + for (const auto& mouse : mice) { + OnMouseConnected(*mouse); + } + + const auto pointing_sticks = Shell::Get() + ->input_device_settings_controller() + ->GetConnectedPointingSticks(); + for (const auto& pointing_stick : pointing_sticks) { + OnPointingStickConnected(*pointing_stick); + } } void InputDeviceTracker::Init(PrefService* pref_service) {
diff --git a/ash/system/input_device_settings/input_device_tracker.h b/ash/system/input_device_settings/input_device_tracker.h index d021dc8..e7f128e 100644 --- a/ash/system/input_device_settings/input_device_tracker.h +++ b/ash/system/input_device_settings/input_device_tracker.h
@@ -42,6 +42,10 @@ // InputDeviceSettingsController::Observer: void OnKeyboardConnected(const mojom::Keyboard& keyboard) override; + void OnTouchpadConnected(const mojom::Touchpad& touchpad) override; + void OnMouseConnected(const mojom::Mouse& mouse) override; + void OnPointingStickConnected( + const mojom::PointingStick& pointing_stick) override; // SessionObserver: void OnActiveUserPrefServiceChanged(PrefService* pref_service) override;
diff --git a/ash/system/input_device_settings/input_device_tracker_unittest.cc b/ash/system/input_device_settings/input_device_tracker_unittest.cc index 0aa17c22..11b4092f 100644 --- a/ash/system/input_device_settings/input_device_tracker_unittest.cc +++ b/ash/system/input_device_settings/input_device_tracker_unittest.cc
@@ -9,7 +9,6 @@ #include "ash/system/input_device_settings/input_device_settings_pref_names.h" #include "ash/test/ash_test_base.h" #include "base/containers/contains.h" -#include "base/notreached.h" #include "base/strings/string_piece_forward.h" #include "components/account_id/account_id.h" #include "components/prefs/pref_service.h" @@ -65,8 +64,6 @@ } } - // TODO(dpad): Implement for mouse/touchpad/pointing stick once mojo objects - // are available. void CallOnDeviceConnected(base::StringPiece device_key) { switch (category_) { case InputDeviceCategory::kKeyboard: { @@ -75,10 +72,22 @@ tracker_->OnKeyboardConnected(keyboard); break; } - case InputDeviceCategory::kMouse: - case InputDeviceCategory::kTouchpad: + case InputDeviceCategory::kMouse: { + mojom::Mouse mouse; + mouse.device_key = std::string(device_key); + tracker_->OnMouseConnected(mouse); + break; + } + case InputDeviceCategory::kTouchpad: { + mojom::Touchpad touchpad; + touchpad.device_key = std::string(device_key); + tracker_->OnTouchpadConnected(touchpad); + break; + } case InputDeviceCategory::kPointingStick: - NOTIMPLEMENTED(); + mojom::PointingStick pointing_stick; + pointing_stick.device_key = std::string(device_key); + tracker_->OnPointingStickConnected(pointing_stick); break; } } @@ -91,14 +100,18 @@ base::StringPiece pref_path_; }; -// TODO(dpad): Add in mouse/touchpad/pointing stick once implemented. INSTANTIATE_TEST_SUITE_P( , InputDeviceTrackerTest, testing::ValuesIn( std::vector<std::pair<InputDeviceCategory, base::StringPiece>>{ {InputDeviceCategory::kKeyboard, - prefs::kKeyboardObservedDevicesPref}})); + prefs::kKeyboardObservedDevicesPref}, + {InputDeviceCategory::kMouse, prefs::kMouseObservedDevicesPref}, + {InputDeviceCategory::kTouchpad, + prefs::kTouchpadObservedDevicesPref}, + {InputDeviceCategory::kPointingStick, + prefs::kPointingStickObservedDevicesPref}})); TEST_P(InputDeviceTrackerTest, RecordDevices) { CallOnDeviceConnected(kDeviceKey1); @@ -145,9 +158,6 @@ TEST_P(InputDeviceTrackerTest, WasDevicePreviouslyConnected) { EXPECT_FALSE(tracker_->WasDevicePreviouslyConnected(category_, kDeviceKey1)); CallOnDeviceConnected(kDeviceKey1); - // Device key is present and added to the correct prf list. - EXPECT_FALSE(tracker_->WasDevicePreviouslyConnected( - InputDeviceCategory::kMouse, kDeviceKey1)); EXPECT_TRUE(tracker_->WasDevicePreviouslyConnected(category_, kDeviceKey1)); }
diff --git a/ash/wallpaper/wallpaper_controller_impl.cc b/ash/wallpaper/wallpaper_controller_impl.cc index 6fd2f17..4133591f 100644 --- a/ash/wallpaper/wallpaper_controller_impl.cc +++ b/ash/wallpaper/wallpaper_controller_impl.cc
@@ -1152,7 +1152,7 @@ update_wallpaper_timer_.Stop(); - RemoveUserWallpaper(account_id); + RemoveUserWallpaper(account_id, /*on_removed=*/base::DoNothing()); if (!SetDefaultWallpaperInfo(account_id, base::Time::Now())) { LOG(ERROR) << "Initializing user wallpaper info fails. This should never " "happen except in tests."; @@ -1476,11 +1476,13 @@ ReloadWallpaper(/*clear_cache=*/false); } -void WallpaperControllerImpl::RemoveUserWallpaper(const AccountId& account_id) { +void WallpaperControllerImpl::RemoveUserWallpaper( + const AccountId& account_id, + base::OnceClosure on_removed) { if (base::Contains(wallpaper_cache_map_, account_id)) wallpaper_cache_map_.erase(account_id); pref_manager_->RemoveUserWallpaperInfo(account_id); - RemoveUserWallpaperImpl(account_id); + RemoveUserWallpaperImpl(account_id, std::move(on_removed)); } void WallpaperControllerImpl::RemovePolicyWallpaper( @@ -1898,13 +1900,14 @@ } void WallpaperControllerImpl::RemoveUserWallpaperImpl( - const AccountId& account_id) { + const AccountId& account_id, + base::OnceClosure on_removed) { if (wallpaper_controller_client_) { wallpaper_controller_client_->GetFilesId( account_id, base::BindOnce( &WallpaperControllerImpl::RemoveUserWallpaperImplWithFilesId, - weak_factory_.GetWeakPtr(), account_id)); + weak_factory_.GetWeakPtr(), account_id, std::move(on_removed))); } else { LOG(ERROR) << "Failed to remove wallpaper. wallpaper_controller_client_ no " "longer exists."; @@ -1913,6 +1916,7 @@ void WallpaperControllerImpl::RemoveUserWallpaperImplWithFilesId( const AccountId& account_id, + base::OnceClosure on_removed, const std::string& wallpaper_files_id) { if (wallpaper_files_id.empty()) return; @@ -1931,11 +1935,12 @@ wallpaper_path = GetCustomWallpaperDir(kOriginalWallpaperSubDir); files_to_remove.push_back(wallpaper_path.Append(wallpaper_files_id)); - base::ThreadPool::PostTask( + base::ThreadPool::PostTaskAndReply( FROM_HERE, {base::MayBlock(), base::TaskPriority::BEST_EFFORT, base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN}, - base::BindOnce(&DeleteWallpaperInList, std::move(files_to_remove))); + base::BindOnce(&DeleteWallpaperInList, std::move(files_to_remove)), + std::move(on_removed)); } void WallpaperControllerImpl::SetDefaultWallpaperImpl(
diff --git a/ash/wallpaper/wallpaper_controller_impl.h b/ash/wallpaper/wallpaper_controller_impl.h index 4e38f76..c4ea896f 100644 --- a/ash/wallpaper/wallpaper_controller_impl.h +++ b/ash/wallpaper/wallpaper_controller_impl.h
@@ -293,7 +293,8 @@ void ShowOneShotWallpaper(const gfx::ImageSkia& image) override; void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override; void RemoveAlwaysOnTopWallpaper() override; - void RemoveUserWallpaper(const AccountId& account_id) override; + void RemoveUserWallpaper(const AccountId& account_id, + base::OnceClosure on_removed) override; void RemovePolicyWallpaper(const AccountId& account_id) override; void SetAnimationDuration(base::TimeDelta animation_duration) override; void OpenWallpaperPickerIfAllowed() override; @@ -424,10 +425,12 @@ // Implementation of |RemoveUserWallpaper|, which deletes |account_id|'s // custom wallpapers and directories. - void RemoveUserWallpaperImpl(const AccountId& account_id); + void RemoveUserWallpaperImpl(const AccountId& account_id, + base::OnceClosure on_removed); void RemoveUserWallpaperImplWithFilesId( const AccountId& account_id, + base::OnceClosure on_removed, const std::string& wallpaper_files_id); // Implementation of |SetDefaultWallpaper|. Sets wallpaper to default if
diff --git a/ash/wallpaper/wallpaper_controller_unittest.cc b/ash/wallpaper/wallpaper_controller_unittest.cc index ee25b4c..2095f11 100644 --- a/ash/wallpaper/wallpaper_controller_unittest.cc +++ b/ash/wallpaper/wallpaper_controller_unittest.cc
@@ -2136,7 +2136,7 @@ EXPECT_TRUE(controller_->GetPathFromCache(kAccountId1, &path)); // Verify |RemoveUserWallpaper| clears wallpaper cache. - controller_->RemoveUserWallpaper(kAccountId1); + controller_->RemoveUserWallpaper(kAccountId1, base::DoNothing()); EXPECT_FALSE( controller_->GetWallpaperFromCache(kAccountId1, &cached_wallpaper)); EXPECT_FALSE(controller_->GetPathFromCache(kAccountId1, &path)); @@ -2425,7 +2425,7 @@ EXPECT_TRUE(base::PathExists(small_wallpaper_path_2)); // Simulate the removal of |kUser2|. - controller_->RemoveUserWallpaper(kAccountId2); + controller_->RemoveUserWallpaper(kAccountId2, base::DoNothing()); // Wait until all files under the user's custom wallpaper directory are // removed. WaitUntilCustomWallpapersDeleted(kAccountId2); @@ -2452,12 +2452,30 @@ base::DoNothing()); // Simulate the removal of |kUser2|. - controller_->RemoveUserWallpaper(kAccountId2); + controller_->RemoveUserWallpaper(kAccountId2, + /*on_removed=*/base::DoNothing()); // Verify that the other user's wallpaper is not affected. EXPECT_TRUE(base::PathExists(small_wallpaper_path_1)); } +// Tests that when a user who has a default wallpaper is removed from the +// device, the `on_remove` callback is called. +TEST_F(WallpaperControllerTest, RemoveUserWallpaperOnRemoveCallbackCalled) { + SimulateUserLogin(kAccountId1); + controller_->SetDefaultWallpaper(kAccountId1, /*show_wallpaper=*/true, + /*callback=*/base::DoNothing()); + + base::test::TestFuture<void> remove_was_called; + + // Simulate the removal of |kUser1|. + controller_->RemoveUserWallpaper(kAccountId1, + remove_was_called.GetCallback()); + + // Assert that the `on_remove` callback is called + ASSERT_TRUE(remove_was_called.Wait()); +} + TEST_F(WallpaperControllerTest, IsActiveUserWallpaperControlledByPolicy) { SetBypassDecode(); // Simulate the login screen. Verify that it returns false since there's no
diff --git a/ash/webui/personalization_app/resources/css/common.css b/ash/webui/personalization_app/resources/css/common.css index 3a0cde7..435fbe9b 100644 --- a/ash/webui/personalization_app/resources/css/common.css +++ b/ash/webui/personalization_app/resources/css/common.css
@@ -4,7 +4,9 @@ /* #css_wrapper_metadata_start * #type=style + * #import=chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js * #import=chrome://resources/cr_elements/cr_shared_vars.css.js + * #include=cros-color-overrides * #css_wrapper_metadata_end */ [hidden] { @@ -269,6 +271,19 @@ background-color: var(--cros-bg-color); } +:host-context(body.jelly-enabled) .ambient-toggle-row-container { + border: none; +} + +:host-context(body.jelly-enabled) .ambient-toggle-row { + margin: 0; +} + +:host-context(body.jelly-enabled) .ambient-toggle-row > p { + color: var(--cros-text-color-secondary); + font: var(--cros-body-2-font); +} + :host-context([dir=rtl]) iron-icon[icon='cr:chevron-right'] { transform: scaleX(-1); }
diff --git a/ash/webui/personalization_app/resources/css/wallpaper.css b/ash/webui/personalization_app/resources/css/wallpaper.css index 7f270dc..365fed9 100644 --- a/ash/webui/personalization_app/resources/css/wallpaper.css +++ b/ash/webui/personalization_app/resources/css/wallpaper.css
@@ -4,9 +4,7 @@ /* #css_wrapper_metadata_start * #type=style - * import=chrome://resources/cr_elements/chromeos/cros_color_overrides.css.js - * import=chrome://resources/cr_elements/cr_shared_vars.css.js - * import=chrome://resources/polymer/v3_0/paper-styles/color.js + * #import=chrome://resources/polymer/v3_0/paper-styles/color.js * #css_wrapper_metadata_end */ main {
diff --git a/ash/webui/personalization_app/resources/index.html b/ash/webui/personalization_app/resources/index.html index 48d7578..331370d 100644 --- a/ash/webui/personalization_app/resources/index.html +++ b/ash/webui/personalization_app/resources/index.html
@@ -2,7 +2,7 @@ Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> <!DOCTYPE html> -<html dir="$i18n{textdirection}" lang="$i18n{language}"> +<html dir="$i18n{textdirection}" lang="$i18n{language}" cros> <head> <title>$i18n{personalizationTitle}</title> <link rel="icon" type="image/png" sizes="192x192" href="/icon_192.png">
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html index 3c5002b1..8a219f5 100644 --- a/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html +++ b/ash/webui/personalization_app/resources/js/ambient/ambient_preview_large_element.html
@@ -96,6 +96,7 @@ font: var(--cros-body-1-font); line-height: 1.5; margin-top: 56px; + position: relative; text-align: center; width: 128px; } @@ -107,7 +108,6 @@ ambient-zero-state-svg { position: absolute; - z-index: -10000; } #messageContainer.jelly-disabled cr-button {
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.html b/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.html index cc9553d..d1119f6 100644 --- a/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.html +++ b/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.html
@@ -5,6 +5,15 @@ #container { display: grid; grid-template-areas: + '. . content . .'; + grid-template-columns: 1fr 16px minmax(568px, 920px) 16px 1fr; + grid-template-rows: minmax(0, 1fr); + height: 100%; + margin-block-end: 48px; + } + :host-context(body.jelly-enabled) #container { + display: grid; + grid-template-areas: '. . preview . .' '. . content . .'; grid-template-columns: 1fr 16px minmax(568px, 920px) 16px 1fr; @@ -19,11 +28,12 @@ } toggle-row, #toggleRowPlaceholder { - grid-area: toggles; margin: 0 8px; } - ambient-zero-state { - grid-area: zeroState; + .ambient-toggle-label-placeholder { + height: 20px; + margin: 34px 0 2px 0; + width: 10%; } /* TODO(b/253470553): Remove after Ambient subpage UI change is released. */ ambient-preview-small.jelly-disabled { @@ -71,7 +81,6 @@ justify-content: center; overflow: hidden; padding-inline: var(--cr-section-padding) var(--cr-icon-ripple-padding); - position: relative; width: 100%; } #topicSourceTextPlaceholder { @@ -98,28 +107,18 @@ <div id="container"> <template is="dom-if" if="[[isPersonalizationJellyEnabled_]]"> <ambient-preview-small></ambient-preview-small> - </template> - <!-- restamp to avoid layout issues with iron-list resizing while hidden --> - <template is="dom-if" if="[[shouldShowMainSettings_(path)]]" restamp> - <div id="mainSettings"> - <template is="dom-if" if="[[isLoadingAmbientMode_(ambientModeEnabled_)]]"> - <div id="toggleRowPlaceholder" class="ambient-toggle-row-container"> - <div class="ambient-toggle-row"> - <div class="ambient-primary-text-placeholder placeholder"></div> + <!-- restamp to avoid layout issues with iron-list resizing while hidden --> + <template is="dom-if" if="[[shouldShowMainSettings_(path)]]" restamp> + <div id="mainSettings"> + <template is="dom-if" if="[[loading_]]"> + <div id="toggleRowPlaceholder"> + <div class="ambient-toggle-label-placeholder placeholder"></div> + <div class="ambient-toggle-row-container"> + <div class="ambient-toggle-row"> + <div class="ambient-primary-text-placeholder placeholder"></div> + </div> + </div> </div> - </div> - </template> - <template is="dom-if" if="[[!isLoadingAmbientMode_(ambientModeEnabled_)]]"> - <toggle-row id="ambientToggleRow" checked="[[ambientModeEnabled_]]" - on-click="onClickAmbientModeButton_" on-change="onToggleStateChanged_"> - </toggle-row> - </template> - <template is="dom-if" if="[[ambientModeEnabled_]]"> - <!-- TODO(b/253470553): Remove after Ambient subpage UI change is released. --> - <template is="dom-if" if="[[!isPersonalizationJellyEnabled_]]"> - <ambient-preview-small class="jelly-disabled"></ambient-preview-small> - </template> - <template is="dom-if" if="[[loadingSettings_]]"> <div id="animationThemePlaceholder"> <h3 id="animationTitle" class="ambient-subpage-element-title" aria-hidden="true"> $i18n{ambientModeAnimationTitle} @@ -160,27 +159,108 @@ </iron-list> </div> </template> - <template is="dom-if" if="[[!loadingSettings_]]"> - <animation-theme-list - selected-animation-theme="[[animationTheme_]]"> - </animation-theme-list> - <topic-source-list selected-topic-source="[[topicSource_]]" - has-google-photos-albums="[[hasGooglePhotosAlbums_(albums_)]]"> - </topic-source-list> - <ambient-weather-unit - selected-temperature-unit="[[temperatureUnitToString_(temperatureUnit_)]]"> - </ambient-weather-unit> + <template is="dom-if" if="[[!loading_]]"> + <toggle-row id="ambientToggleRow" checked="[[ambientModeEnabled_]]" + on-click="onClickAmbientModeButton_" on-change="onToggleStateChanged_"> + </toggle-row> + <template is="dom-if" if="[[ambientModeEnabled_]]"> + <animation-theme-list + selected-animation-theme="[[animationTheme_]]"> + </animation-theme-list> + <topic-source-list selected-topic-source="[[topicSource_]]" + has-google-photos-albums="[[hasGooglePhotosAlbums_(albums_)]]"> + </topic-source-list> + <ambient-weather-unit + selected-temperature-unit="[[temperatureUnitToString_(temperatureUnit_)]]"> + </ambient-weather-unit> + </template> </template> - </template> - <template is="dom-if" if="[[shouldShowZeroState_(ambientModeEnabled_, isPersonalizationJellyEnabled_)]]"> - <ambient-zero-state id="zeroState"></ambient-zero-state> - </template> - </div> + </div> + </template> + <template is="dom-if" if="[[shouldShowAlbums_(path)]]" restamp> + <albums-subpage topic-source="[[getTopicSource_(queryParams)]]" + albums="[[getAlbums_(albums_, queryParams)]]"> + </albums-subpage> + </template> </template> - <!-- restamp to avoid layout issues with iron-list resizing while hidden --> - <template is="dom-if" if="[[shouldShowAlbums_(path)]]" restamp> - <albums-subpage topic-source="[[getTopicSource_(queryParams)]]" - albums="[[getAlbums_(albums_, queryParams)]]"> - </albums-subpage> + <template is="dom-if" if="[[!isPersonalizationJellyEnabled_]]"> + <!-- restamp to avoid layout issues with iron-list resizing while hidden --> + <template is="dom-if" if="[[shouldShowMainSettings_(path)]]" restamp> + <div id="mainSettings"> + <template is="dom-if" if="[[loading_]]"> + <div id="toggleRowPlaceholder" class="ambient-toggle-row-container"> + <div class="ambient-toggle-row"> + <div class="ambient-primary-text-placeholder placeholder"></div> + </div> + </div> + <ambient-preview-small class="jelly-disabled"></ambient-preview-small> + <div id="animationThemePlaceholder"> + <h3 id="animationTitle" class="ambient-subpage-element-title" aria-hidden="true"> + $i18n{ambientModeAnimationTitle} + </h3> + <iron-list class="animation-placeholder-list" items="[[getPlaceholders_(3)]]" grid> + <template> + <div class="animation-placeholder-container"> + <div class="animation-item-placeholder placeholder"></div> + <div class="animation-item-title-placeholder + ambient-primary-text-placeholder placeholder"></div> + </div> + </template> + </iron-list> + </div> + <div id="topicSourcePlaceholder"> + <h3 id="topicSourceTitle" class="ambient-subpage-element-title" aria-hidden="true"> + $i18n{ambientModeTopicSourceTitle} + </h3> + <iron-list items="[[getPlaceholders_(2)]]" grid> + <template> + <div id="topicSourceTextPlaceholder" class$="{{getClassContainer_(index)}}"> + <div class="ambient-primary-text-placeholder placeholder"></div> + <div class="ambient-secondary-text-placeholder placeholder"></div> + </div> + </template> + </iron-list> + </div> + <div id="weatherUnitPlaceholder"> + <h3 id="weatherTitle" class="ambient-subpage-element-title" aria-hidden="true"> + $i18n{ambientModeWeatherTitle} + </h3> + <iron-list items="[[getPlaceholders_(2)]]" grid> + <template> + <div id="weatherUnitTextPlaceholder" class$="{{getClassContainer_(index)}}"> + <div class="ambient-secondary-text-placeholder placeholder"></div> + </div> + </template> + </iron-list> + </div> + </template> + <template is="dom-if" if="[[!loading_]]"> + <toggle-row id="ambientToggleRow" checked="[[ambientModeEnabled_]]" + on-click="onClickAmbientModeButton_" on-change="onToggleStateChanged_"> + </toggle-row> + <template is="dom-if" if="[[!ambientModeEnabled_]]"> + <ambient-zero-state id="zeroState"></ambient-zero-state> + </template> + <template is="dom-if" if="[[ambientModeEnabled_]]"> + <ambient-preview-small class="jelly-disabled"></ambient-preview-small> + <animation-theme-list + selected-animation-theme="[[animationTheme_]]"> + </animation-theme-list> + <topic-source-list selected-topic-source="[[topicSource_]]" + has-google-photos-albums="[[hasGooglePhotosAlbums_(albums_)]]"> + </topic-source-list> + <ambient-weather-unit + selected-temperature-unit="[[temperatureUnitToString_(temperatureUnit_)]]"> + </ambient-weather-unit> + </template> + </template> + </div> + </template> + <!-- restamp to avoid layout issues with iron-list resizing while hidden --> + <template is="dom-if" if="[[shouldShowAlbums_(path)]]" restamp> + <albums-subpage topic-source="[[getTopicSource_(queryParams)]]" + albums="[[getAlbums_(albums_, queryParams)]]"> + </albums-subpage> + </template> </template> </div>
diff --git a/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.ts b/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.ts index 254f5df..c4ec5b9 100644 --- a/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.ts +++ b/ash/webui/personalization_app/resources/js/ambient/ambient_subpage_element.ts
@@ -63,10 +63,10 @@ type: Number, value: null, }, - loadingSettings_: { + loading_: { type: Boolean, computed: - 'computeLoadingSettings_(albums_, temperatureUnit_, topicSource_)', + 'computeLoading_(ambientModeEnabled_, albums_, temperatureUnit_, topicSource_)', }, isPersonalizationJellyEnabled_: { type: Boolean, @@ -201,9 +201,9 @@ return this.ambientModeEnabled_ === null; } - private computeLoadingSettings_(): boolean { - return this.albums_ === null || this.topicSource_ === null || - this.temperatureUnit_ === null; + private computeLoading_(): boolean { + return this.ambientModeEnabled_ === null || this.albums_ === null || + this.topicSource_ === null || this.temperatureUnit_ === null; } private getPlaceholders_(x: number): number[] {
diff --git a/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.html b/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.html index b34b72c..4b46788 100644 --- a/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.html +++ b/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.html
@@ -1,5 +1,13 @@ <style include="common"> + #toggleRowTitle { + margin: 34px 8px 2px 0; + } </style> +<template is="dom-if" if="[[isPersonalizationJellyEnabled_]]"> + <h3 id="toggleRowTitle" class="ambient-subpage-element-title" aria-hidden="true"> + [[getToggleRowTitle_(checked)]] + </h3> +</template> <div class="ambient-toggle-row-container"> <div class="ambient-toggle-row"> <p id="toggleDescription">$i18n{ambientModePageDescription}</p>
diff --git a/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.ts b/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.ts index 5c66621..6eeeb0e 100644 --- a/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.ts +++ b/ash/webui/personalization_app/resources/js/ambient/toggle_row_element.ts
@@ -11,6 +11,7 @@ import {CrToggleElement} from 'chrome://resources/cr_elements/cr_toggle/cr_toggle.js'; +import {isPersonalizationJellyEnabled} from '../load_time_booleans.js'; import {WithPersonalizationStore} from '../personalization_store.js'; import {getTemplate} from './toggle_row_element.html.js'; @@ -32,10 +33,18 @@ return { checked: {type: Boolean, value: false, notify: true, reflectToAttribute: true}, + + isPersonalizationJellyEnabled_: { + type: Boolean, + value() { + return isPersonalizationJellyEnabled(); + }, + }, }; } checked: boolean; + private isPersonalizationJellyEnabled_: boolean; override ariaLabel: string; override focus() { @@ -45,6 +54,10 @@ private getAriaLabel_(): string { return this.i18n(this.checked ? 'ambientModeOn' : 'ambientModeOff'); } + + private getToggleRowTitle_(): string { + return this.getAriaLabel_().toUpperCase(); + } } declare global {
diff --git a/ash/webui/personalization_app/resources/js/personalization_main_element.html b/ash/webui/personalization_app/resources/js/personalization_main_element.html index 211c432..e96008ec 100644 --- a/ash/webui/personalization_app/resources/js/personalization_main_element.html +++ b/ash/webui/personalization_app/resources/js/personalization_main_element.html
@@ -13,6 +13,10 @@ width: 100%; } + :host-context(body.jelly-enabled) #container { + grid-template-rows: 132px 1fr auto 32px; + } + user-preview { grid-area: userpreview; }
diff --git a/ash/webui/personalization_app/resources/js/user/user_preview_element.html b/ash/webui/personalization_app/resources/js/user/user_preview_element.html index df25ddbf..93813776 100644 --- a/ash/webui/personalization_app/resources/js/user/user_preview_element.html +++ b/ash/webui/personalization_app/resources/js/user/user_preview_element.html
@@ -10,6 +10,14 @@ height: 100%; } + :host-context(body.jelly-enabled) #container { + grid-template-areas: + '. . .' + 'image . text'; + grid-template-columns: 96px 20px minmax(0, 1fr); + grid-template-rows: 20px 96px; + } + #imageContainer { grid-area: image; position: relative; @@ -31,6 +39,12 @@ width: 80px; } + :host-context(body.jelly-enabled) #imageContainer #imageBorderContainer img { + background-size: 96px 96px; + height: 96px; + width: 96px; + } + #imageContainer img { border: 1px solid rgba(0, 0, 0, 0.08); border-radius: 50%; @@ -38,6 +52,13 @@ width: 80px; } + :host-context(body.jelly-enabled) #imageBorderContainer, + :host-context(body.jelly-enabled) #imageContainer img { + border: 0; + height: 96px; + width: 96px; + } + #imageContainer img.clickable { cursor: pointer; } @@ -64,6 +85,10 @@ font: 400 22px/28px var(--cros-font-family-google-sans); } + :host-context(body.jelly-enabled) #infoContainer > h2 { + font: 400 22px/24px var(--cros-font-family-google-sans); + } + .avatar-link { align-items: center; cursor: pointer; @@ -84,6 +109,11 @@ margin: 0; } + :host-context(body.jelly-enabled) .avatar-link > span { + color: var(--cros-sys-secondary, var(--cros-link-color)); + font: 400 13px/20px var(--cros-font-family-google-sans); + } + iron-icon[icon='cr:open-in-new'] { --iron-icon-height: 16px; --iron-icon-width: 16px; @@ -91,6 +121,12 @@ margin-inline-start: 6px; } + :host-context(body.jelly-enabled) iron-icon[icon='cr:open-in-new'] { + --iron-icon-height: 12px; + --iron-icon-width: 12px; + --iron-icon-fill-color: var(--cros-sys-secondary, var(--cros-link-color)); + } + paper-ripple { color: rgba(var(--cros-ripple-color-rgb), 1); --paper-ripple-opacity: var(--cros-button-primary-ripple-opacity); @@ -112,6 +148,14 @@ width: 24px; } + :host-context(body.jelly-enabled) #iconContainer, + :host-context(body.jelly-enabled) #enterpriseIconContainer { + height: 32px; + line-height: 32px; + right: 0; + width: 32px; + } + #iconContainer { align-items: center; background-color: var(--cros-icon-color-prominent); @@ -123,7 +167,7 @@ } #iconContainer > svg { - fill: var(--cros-button-label-color-primary); + fill: var(--cros-sys-on_primary, var(--cros-button-label-color-primary)); } #enterpriseIconContainer { @@ -139,6 +183,16 @@ } } + :host-context(body.jelly-enabled) #enterpriseIconContainer { + background-color: var(--cros-sys-on_primary_container); + } + + :host-context(body.jelly-enabled) #enterpriseIconContainer svg { + fill: var(--cros-sys-on_primary); + margin-top: 10px; + text-align: center; + } + #avatar:focus-visible { outline: 2px solid var(--cros-focus-ring-color); } @@ -152,8 +206,16 @@ <img id="avatar" class="managed" src$="[[imageUrl_.url]]" alt="$i18n{managedSetting}" title="$i18n{managedSetting}"> <div id="enterpriseIconContainer"> - <iron-icon icon="personalization:managed"> - </iron-icon> + <template is="dom-if" if="[[!isPersonalizationJellyEnabled_]]"> + <iron-icon icon="personalization:managed"> + </iron-icon> + </template> + <template is="dom-if" if="[[isPersonalizationJellyEnabled_]]"> + <svg width="13.33" height="12" viewBox="0 0 13.33 12" xmlns="http://www.w3.org/2000/svg"> + <path d="M7.00004 2.66667V0H0.333374V12H13.6667V2.66667H7.00004ZM5.66671 10.6667H1.66671V9.33333H5.66671V10.6667ZM5.66671 8H1.66671V6.66667H5.66671V8ZM5.66671 5.33333H1.66671V4H5.66671V5.33333ZM5.66671 2.66667H1.66671V1.33333H5.66671V2.66667ZM12.3334 10.6667H7.00004V4H12.3334V10.6667ZM11 5.33333H8.33337V6.66667H11V5.33333ZM11 8H8.33337V9.33333H11V8Z"> + </path> + </svg> + </template> </div> </template> <template is="dom-if" @@ -161,11 +223,20 @@ <div id="iconContainer" on-click="onClickUserSubpageLink_" on-keypress="onClickUserSubpageLink_"> - <svg viewBox="0 0 16 16" width="16" height="16"> - <path fill-rule="evenodd" clip-rule="evenodd" - d="M13.5575 3.45125L12.545 2.43875C11.96 1.85375 11.0075 1.85375 10.4225 2.43875L8.3 4.55375L2 10.8612V13.9962H5.135L13.5575 5.57375C14.15 4.98875 14.15 4.03625 13.5575 3.45125ZM3.5 12.4963V11.4763L9.365 5.61125L10.4225 6.66875L4.5575 12.5413L3.5 12.4963Z"> - </path> - </svg> + <template is="dom-if" if="[[!isPersonalizationJellyEnabled_]]"> + <svg viewBox="0 0 16 16" width="16" height="16"> + <path fill-rule="evenodd" clip-rule="evenodd" + d="M13.5575 3.45125L12.545 2.43875C11.96 1.85375 11.0075 1.85375 10.4225 2.43875L8.3 4.55375L2 10.8612V13.9962H5.135L13.5575 5.57375C14.15 4.98875 14.15 4.03625 13.5575 3.45125ZM3.5 12.4963V11.4763L9.365 5.61125L10.4225 6.66875L4.5575 12.5413L3.5 12.4963Z"> + </path> + </svg> + </template> + <template is="dom-if" if="[[isPersonalizationJellyEnabled_]]"> + <svg width="14" height="14" viewBox="0 0 14 14" xmlns="http://www.w3.org/2000/svg"> + <path fill-rule="evenodd" clip-rule="evenodd" + d="M12.928 2.148L11.848 1.068C11.224 0.443998 10.208 0.443998 9.58397 1.068L7.31997 3.324L0.599976 10.052V13.396H3.94398L12.928 4.412C13.56 3.788 13.56 2.772 12.928 2.148ZM2.19998 11.796V10.708L8.45598 4.452L9.58397 5.58L3.32798 11.844L2.19998 11.796Z"> + </path> + </svg> + </template> </div> <paper-ripple class="circle"></paper-ripple> <div id="imageBorderContainer">
diff --git a/ash/webui/personalization_app/resources/js/user/user_preview_element.ts b/ash/webui/personalization_app/resources/js/user/user_preview_element.ts index 5051a2c..6ad7b1b 100644 --- a/ash/webui/personalization_app/resources/js/user/user_preview_element.ts +++ b/ash/webui/personalization_app/resources/js/user/user_preview_element.ts
@@ -15,6 +15,7 @@ import {Url} from 'chrome://resources/mojo/url/mojom/url.mojom-webui.js'; import {IronA11yAnnouncer} from 'chrome://resources/polymer/v3_0/iron-a11y-announcer/iron-a11y-announcer.js'; +import {isPersonalizationJellyEnabled} from '../load_time_booleans.js'; import {UserImage, UserInfo} from '../personalization_app.mojom-webui.js'; import {Paths, PersonalizationRouter} from '../personalization_router_element.js'; import {WithPersonalizationStore} from '../personalization_store.js'; @@ -62,6 +63,12 @@ type: Boolean, value: null, }, + isPersonalizationJellyEnabled_: { + type: Boolean, + value() { + return isPersonalizationJellyEnabled(); + }, + }, }; } @@ -70,6 +77,7 @@ private image_: UserImage|null; private imageUrl_: Url|null; private imageIsEnterpriseManaged_: boolean|null; + private isPersonalizationJellyEnabled_: boolean; override ready() { super.ready();
diff --git a/ash/wm/window_positioner.cc b/ash/wm/window_positioner.cc index a93ac03d..810630e 100644 --- a/ash/wm/window_positioner.cc +++ b/ash/wm/window_positioner.cc
@@ -7,11 +7,13 @@ #include "ash/screen_util.h" #include "ash/shell.h" #include "ash/shell_delegate.h" +#include "ash/wm/float/float_controller.h" #include "ash/wm/mru_window_tracker.h" #include "ash/wm/window_positioning_utils.h" #include "ash/wm/window_state.h" #include "ash/wm/window_util.h" #include "base/ranges/algorithm.h" +#include "chromeos/ui/wm/features.h" #include "ui/compositor/layer.h" #include "ui/compositor/scoped_layer_animation_settings.h" #include "ui/display/display.h" @@ -280,6 +282,22 @@ void WindowPositioner::RearrangeVisibleWindowOnShow( aura::Window* added_window) { WindowState* added_window_state = WindowState::Get(added_window); + // TODO(b/267884882): Temporarily disable auto positioning if there is a + // floated window on the same desk, see b/265839238. + if (auto* float_controller = Shell::Get()->float_controller()) { + auto* floated_window = float_controller->FindFloatedWindowOfDesk( + Shell::Get()->desks_controller()->active_desk()); + if (floated_window && floated_window != added_window) { + // Place newly added window to the center of the screen to reduce chances + // of being hidden behind the floated window. Note that minimized windows + // should not be auto placed. + if (!added_window_state->bounds_changed_by_user()) { + AutoPlaceSingleWindow(added_window, /*animated=*/false); + } + return; + } + } + if (!added_window->TargetVisibility() || !UseAutoWindowManager(added_window) || added_window_state->bounds_changed_by_user()) {
diff --git a/base/BUILD.gn b/base/BUILD.gn index 3a64b319..90e9802 100644 --- a/base/BUILD.gn +++ b/base/BUILD.gn
@@ -1691,7 +1691,7 @@ ] } - if (!is_ios) { + if (use_blink) { sources += [ "memory/discardable_shared_memory.cc", "memory/discardable_shared_memory.h", @@ -2111,9 +2111,7 @@ configs += linux_configs all_dependent_configs += linux_configs - sources += [ - "system/sys_info_linux.cc", - ] + sources += [ "system/sys_info_linux.cc" ] if (!is_cronet_build) { # These dependencies are not required on Android, and in the case # of xdg_mime must be excluded due to licensing restrictions. @@ -2190,7 +2188,6 @@ "native_library_ios.mm", "power_monitor/power_monitor_device_source_ios.mm", "process/launch_ios.cc", - "process/memory_stubs.cc", "process/process_metrics_ios.cc", "process/process_stubs.cc", "profiler/module_cache_mac.cc", @@ -2203,6 +2200,17 @@ "time/time_mac.mm", ] + if (use_blink) { + sources += [ + "process/memory_mac.mm", + "process/process_iterator_ios.mm", + "sync_socket_posix.cc", + "synchronization/waitable_event_watcher_mac.cc", + ] + } else { + sources += [ "process/memory_stubs.cc" ] + } + if (is_cronet_build) { sources += [ "message_loop/message_pump_io_ios.cc", @@ -2248,7 +2256,7 @@ frameworks += [ "UIKit.framework" ] } - if (!is_ios) { + if (use_blink) { sources += [ "files/file_path_watcher.cc", "files/file_path_watcher.h", @@ -3425,6 +3433,10 @@ "//testing/buildbot/filters:base_unittests_filters", ] + if (is_android && enable_chrome_android_internal) { + data_deps += [ "//clank/build/bot/filters:base_unittests_filters" ] + } + if (toolchain_has_rust) { deps += [ "//build/rust:cxx_cppdeps" ] }
diff --git a/base/allocator/partition_alloc_support.cc b/base/allocator/partition_alloc_support.cc index 0b00a8b..148a776db 100644 --- a/base/allocator/partition_alloc_support.cc +++ b/base/allocator/partition_alloc_support.cc
@@ -775,24 +775,10 @@ PartitionAllocSupport::PartitionAllocSupport() = default; -void PartitionAllocSupport::ReconfigureForTests() { - ReconfigureEarlyish(""); - base::AutoLock scoped_lock(lock_); - called_for_tests_ = true; -} - void PartitionAllocSupport::ReconfigureEarlyish( const std::string& process_type) { { base::AutoLock scoped_lock(lock_); - - // In tests, ReconfigureEarlyish() is called by ReconfigureForTest(), which - // is earlier than ContentMain(). - if (called_for_tests_) { - DCHECK(called_earlyish_); - return; - } - // TODO(bartekn): Switch to DCHECK once confirmed there are no issues. CHECK(!called_earlyish_) << "ReconfigureEarlyish was already called for process '" @@ -843,11 +829,8 @@ } void PartitionAllocSupport::ReconfigureAfterFeatureListInit( - const std::string& process_type, - bool configure_dangling_pointer_detector) { - if (configure_dangling_pointer_detector) { - base::allocator::InstallDanglingRawPtrChecks(); - } + const std::string& process_type) { + base::allocator::InstallDanglingRawPtrChecks(); base::allocator::InstallUnretainedDanglingRawPtrChecks(); { base::AutoLock scoped_lock(lock_);
diff --git a/base/allocator/partition_alloc_support.h b/base/allocator/partition_alloc_support.h index 129dccb..ead3d47d 100644 --- a/base/allocator/partition_alloc_support.h +++ b/base/allocator/partition_alloc_support.h
@@ -66,12 +66,9 @@ // re-configuration steps exactly once. // // *AfterTaskRunnerInit() may be called more than once. - void ReconfigureForTests(); void ReconfigureEarlyish(const std::string& process_type); void ReconfigureAfterZygoteFork(const std::string& process_type); - void ReconfigureAfterFeatureListInit( - const std::string& process_type, - bool configure_dangling_pointer_detector = true); + void ReconfigureAfterFeatureListInit(const std::string& process_type); void ReconfigureAfterTaskRunnerInit(const std::string& process_type); // |has_main_frame| tells us if the renderer contains a main frame. @@ -87,7 +84,6 @@ PartitionAllocSupport(); base::Lock lock_; - bool called_for_tests_ GUARDED_BY(lock_) = false; bool called_earlyish_ GUARDED_BY(lock_) = false; bool called_after_zygote_fork_ GUARDED_BY(lock_) = false; bool called_after_feature_list_init_ GUARDED_BY(lock_) = false;
diff --git a/base/process/process_iterator.h b/base/process/process_iterator.h index 422a69bf..a819ae13 100644 --- a/base/process/process_iterator.h +++ b/base/process/process_iterator.h
@@ -114,10 +114,10 @@ #if BUILDFLAG(IS_WIN) HANDLE snapshot_; - bool started_iteration_; + bool started_iteration_ = false; #elif BUILDFLAG(IS_APPLE) || BUILDFLAG(IS_BSD) std::vector<kinfo_proc> kinfo_procs_; - size_t index_of_kinfo_proc_; + size_t index_of_kinfo_proc_ = 0; #elif BUILDFLAG(IS_POSIX) struct DIRClose { inline void operator()(DIR* x) const {
diff --git a/base/process/process_iterator_freebsd.cc b/base/process/process_iterator_freebsd.cc index fcc4bed..1673bdd 100644 --- a/base/process/process_iterator_freebsd.cc +++ b/base/process/process_iterator_freebsd.cc
@@ -17,9 +17,7 @@ namespace base { ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : index_of_kinfo_proc_(), - filter_(filter) { - + : filter_(filter) { int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid() }; bool done = false; @@ -62,8 +60,7 @@ } } -ProcessIterator::~ProcessIterator() { -} +ProcessIterator::~ProcessIterator() = default; bool ProcessIterator::CheckForNextProcess() { std::string data;
diff --git a/base/process/process_iterator_fuchsia.cc b/base/process/process_iterator_fuchsia.cc index 85163900..d64c3195 100644 --- a/base/process/process_iterator_fuchsia.cc +++ b/base/process/process_iterator_fuchsia.cc
@@ -2,9 +2,10 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "base/notreached.h" #include "base/process/process_iterator.h" +#include "base/notreached.h" + namespace base { ProcessIterator::ProcessIterator(const ProcessFilter* filter) { @@ -12,7 +13,7 @@ NOTREACHED(); } -ProcessIterator::~ProcessIterator() {} +ProcessIterator::~ProcessIterator() = default; bool ProcessIterator::CheckForNextProcess() { return false;
diff --git a/base/process/process_iterator_ios.mm b/base/process/process_iterator_ios.mm new file mode 100644 index 0000000..70a3c2c5 --- /dev/null +++ b/base/process/process_iterator_ios.mm
@@ -0,0 +1,25 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "base/notreached.h" +#include "base/process/process_iterator.h" + +namespace base { + +ProcessIterator::ProcessIterator(const ProcessFilter* filter) { + // TODO(crbug.com/1412835): Implement ProcessIterator on iOS. + NOTREACHED(); +} + +ProcessIterator::~ProcessIterator() {} + +bool ProcessIterator::CheckForNextProcess() { + return false; +} + +bool NamedProcessIterator::IncludeEntry() { + return false; +} + +} // namespace base
diff --git a/base/process/process_iterator_mac.cc b/base/process/process_iterator_mac.cc index e4873d6f..13b6f2a 100644 --- a/base/process/process_iterator_mac.cc +++ b/base/process/process_iterator_mac.cc
@@ -17,8 +17,7 @@ namespace base { ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : index_of_kinfo_proc_(0), - filter_(filter) { + : filter_(filter) { // Get a snapshot of all of my processes (yes, as we loop it can go stale, but // but trying to find where we were in a constantly changing list is basically // impossible. @@ -68,8 +67,7 @@ } } -ProcessIterator::~ProcessIterator() { -} +ProcessIterator::~ProcessIterator() = default; bool ProcessIterator::CheckForNextProcess() { std::string data;
diff --git a/base/process/process_iterator_openbsd.cc b/base/process/process_iterator_openbsd.cc index e7978fa8d..fc6e1ec 100644 --- a/base/process/process_iterator_openbsd.cc +++ b/base/process/process_iterator_openbsd.cc
@@ -15,9 +15,7 @@ namespace base { ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : index_of_kinfo_proc_(), - filter_(filter) { - + : filter_(filter) { int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_UID, getuid(), sizeof(struct kinfo_proc), 0 }; @@ -61,8 +59,7 @@ } } -ProcessIterator::~ProcessIterator() { -} +ProcessIterator::~ProcessIterator() = default; bool ProcessIterator::CheckForNextProcess() { std::string data;
diff --git a/base/process/process_iterator_win.cc b/base/process/process_iterator_win.cc index 6054168..f7dda9d 100644 --- a/base/process/process_iterator_win.cc +++ b/base/process/process_iterator_win.cc
@@ -9,10 +9,8 @@ namespace base { ProcessIterator::ProcessIterator(const ProcessFilter* filter) - : started_iteration_(false), - filter_(filter) { - snapshot_ = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); -} + : snapshot_(CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)), + filter_(filter) {} ProcessIterator::~ProcessIterator() { CloseHandle(snapshot_);
diff --git a/base/test/test_suite.cc b/base/test/test_suite.cc index 94c72345..287c6ab 100644 --- a/base/test/test_suite.cc +++ b/base/test/test_suite.cc
@@ -8,13 +8,11 @@ #include <memory> -#include "base/allocator/partition_allocator/partition_alloc_buildflags.h" #include "base/allocator/partition_allocator/tagging.h" #include "base/at_exit.h" #include "base/base_paths.h" #include "base/base_switches.h" #include "base/command_line.h" -#include "base/debug/asan_service.h" #include "base/debug/debugger.h" #include "base/debug/profiler.h" #include "base/debug/stack_trace.h" @@ -86,10 +84,6 @@ #include "base/debug/handle_hooks_win.h" #endif // BUILDFLAG(IS_WIN) -#if BUILDFLAG(USE_PARTITION_ALLOC) -#include "base/allocator/partition_alloc_support.h" -#endif // BUILDFLAG(USE_PARTITION_ALLOC) - namespace base { namespace { @@ -175,17 +169,6 @@ new_command_line.AppendSwitchNative(iter.first, iter.second); *CommandLine::ForCurrentProcess() = new_command_line; - - // TODO(https://crbug.com/1400059): Enable dangling pointer detector. - // TODO(https://crbug.com/1400058): Enable BackupRefPtr in unittests on - // Windows and Android too. - // TODO(https://crbug.com/1413674): Enable PartitionAlloc in unittests with - // ASAN. -#if BUILDFLAG(USE_PARTITION_ALLOC) && !BUILDFLAG(IS_WIN) && \ - !BUILDFLAG(IS_ANDROID) && !defined(ADDRESS_SANITIZER) - allocator::PartitionAllocSupport::Get()->ReconfigureAfterFeatureListInit( - "", /*configure_dangling_pointer_detector=*/false); -#endif } void OnTestEnd(const testing::TestInfo& test_info) override { @@ -589,22 +572,6 @@ void TestSuite::Initialize() { DCHECK(!is_initialized_); - // The AsanService causes ASAN errors to emit additional information. It is - // helpful on its own. It is also required by ASAN BackupRefPtr when - // reconfiguring PartitionAlloc below. -#if defined(ADDRESS_SANITIZER) - base::debug::AsanService::GetInstance()->Initialize(); -#endif - - // TODO(https://crbug.com/1400058): Enable BackupRefPtr in unittests on - // Windows and Android too. Same for ASAN. - // TODO(https://crbug.com/1413674): Enable PartitionAlloc in unittests with - // ASAN. -#if BUILDFLAG(USE_PARTITION_ALLOC) && !BUILDFLAG(IS_WIN) && \ - !BUILDFLAG(IS_ANDROID) && !defined(ADDRESS_SANITIZER) - allocator::PartitionAllocSupport::Get()->ReconfigureForTests(); -#endif // BUILDFLAG(IS_WIN) - test::ScopedRunLoopTimeout::SetAddGTestFailureOnTimeout(); const CommandLine* command_line = CommandLine::ForCurrentProcess();
diff --git a/cc/metrics/custom_metrics_recorder.h b/cc/metrics/custom_metrics_recorder.h index ced959e4..d013bff 100644 --- a/cc/metrics/custom_metrics_recorder.h +++ b/cc/metrics/custom_metrics_recorder.h
@@ -18,8 +18,12 @@ static CustomMetricRecorder* Get(); // Invoked to report "PercentDroppedFrames_1sWindow". + // Deprecated in favor of "PercentDroppedFrames_1sWindow2". virtual void ReportPercentDroppedFramesInOneSecondWindow(double percent) = 0; + // Invoked to report "PercentDroppedFrames_1sWindow2". + virtual void ReportPercentDroppedFramesInOneSecondWindow2(double percent) = 0; + // Invoked to report event latencies. virtual void ReportEventLatency( std::vector<EventLatencyTracker::LatencyData> latencies) = 0;
diff --git a/cc/metrics/dropped_frame_counter.cc b/cc/metrics/dropped_frame_counter.cc index 1610f66..77de94a 100644 --- a/cc/metrics/dropped_frame_counter.cc +++ b/cc/metrics/dropped_frame_counter.cc
@@ -292,6 +292,13 @@ if (fcp_received_) frame_sorter_.AddFrameResult(args, frame_info); + + // Report frames on every frame for UI. And this needs to happen after + // `frame_sorter_.AddFrameResult` so that the current ending frame is included + // in the sliding window. + if (report_for_ui_) { + ReportFramesOnEveryFrameForUI(); + } } void DroppedFrameCounter::ReportFrames() { @@ -398,12 +405,33 @@ void DroppedFrameCounter::ReportFramesForUI() { DCHECK(report_for_ui_); - auto* recorder = CustomMetricRecorder::Get(); - if (!recorder) + if (!sliding_window_current_percent_dropped_) { return; + } + + auto* recorder = CustomMetricRecorder::Get(); + if (!recorder) { + return; + } recorder->ReportPercentDroppedFramesInOneSecondWindow( - sliding_window_current_percent_dropped_); + *sliding_window_current_percent_dropped_); +} + +void DroppedFrameCounter::ReportFramesOnEveryFrameForUI() { + DCHECK(report_for_ui_); + + if (!sliding_window_current_percent_dropped_) { + return; + } + + auto* recorder = CustomMetricRecorder::Get(); + if (!recorder) { + return; + } + + recorder->ReportPercentDroppedFramesInOneSecondWindow2( + *sliding_window_current_percent_dropped_); } double DroppedFrameCounter::GetMostRecentAverageSmoothness() const { @@ -447,6 +475,7 @@ .Clear(); ring_buffer_.Clear(); last_reported_metrics_ = {}; + sliding_window_current_percent_dropped_.reset(); } base::TimeDelta DroppedFrameCounter::ComputeCurrentWindowSize() const {
diff --git a/cc/metrics/dropped_frame_counter.h b/cc/metrics/dropped_frame_counter.h index b1de1c23..b78a831 100644 --- a/cc/metrics/dropped_frame_counter.h +++ b/cc/metrics/dropped_frame_counter.h
@@ -91,6 +91,7 @@ void AddDroppedFrame(); void ReportFrames(); void ReportFramesForUI(); + void ReportFramesOnEveryFrameForUI(); void OnBeginFrame(const viz::BeginFrameArgs& args, bool is_scroll_active); void OnEndFrame(const viz::BeginFrameArgs& args, const FrameInfo& frame_info); @@ -162,7 +163,7 @@ } double sliding_window_current_percent_dropped() const { - return sliding_window_current_percent_dropped_; + return sliding_window_current_percent_dropped_.value_or(0); } private: @@ -220,7 +221,7 @@ absl::optional<SortedFrameCallback> sorted_frame_callback_; bool report_for_ui_ = false; - double sliding_window_current_percent_dropped_ = 0.0; + absl::optional<double> sliding_window_current_percent_dropped_; // Sets to true on a newly dropped frame and stays true as long as the frames // that follow are dropped. Reset when a frame is presented. It is used to
diff --git a/cc/metrics/dropped_frame_counter_unittest.cc b/cc/metrics/dropped_frame_counter_unittest.cc index 6c21d28..b16e078 100644 --- a/cc/metrics/dropped_frame_counter_unittest.cc +++ b/cc/metrics/dropped_frame_counter_unittest.cc
@@ -35,23 +35,27 @@ ~TestCustomMetricsRecorder() override = default; // CustomMetricRecorder: - void ReportPercentDroppedFramesInOneSecondWindow(double percentage) override { - ++percent_dropped_frames_count_; - last_percent_dropped_frames_ = percentage; + void ReportPercentDroppedFramesInOneSecondWindow(double percent) override {} + void ReportPercentDroppedFramesInOneSecondWindow2(double percent) override { + ++report_count_; + last_percent_dropped_frames_ = percent; } void ReportEventLatency( std::vector<EventLatencyTracker::LatencyData> latencies) override {} - int percent_dropped_frames_count() const { - return percent_dropped_frames_count_; + void Reset() { + report_count_ = 0u; + last_percent_dropped_frames_ = 0; } + int report_count() const { return report_count_; } + double last_percent_dropped_frames() const { return last_percent_dropped_frames_; } private: - int percent_dropped_frames_count_ = 0; + int report_count_ = 0u; double last_percent_dropped_frames_ = 0; }; @@ -586,7 +590,7 @@ // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); static_assert( kFps % 5 == 0, "kFps must be a multiple of 5 because this test depends on it."); @@ -621,7 +625,7 @@ // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); static_assert( kFps % 5 == 0, "kFps must be a multiple of 5 because this test depends on it."); @@ -655,7 +659,7 @@ // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); static_assert( kFps % 5 == 0, "kFps must be a multiple of 5 because this test depends on it."); @@ -696,7 +700,7 @@ // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); SetInterval(kInterval); // One good frame @@ -727,7 +731,7 @@ TEST_F(DroppedFrameCounterTest, ResetPendingFramesAccountingForPendingFrames) { // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); SetInterval(kInterval); // First 2 seconds with 20% dropped frames. @@ -751,7 +755,7 @@ TEST_F(DroppedFrameCounterTest, Reset) { // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); SetInterval(kInterval); // First 2 seconds with 20% dropped frames. @@ -775,7 +779,7 @@ TEST_F(DroppedFrameCounterTest, ConsistentSmoothnessRatings) { // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); static_assert(kFps == 100, "kFps must be 100 because this test depends on it."); SetInterval(kInterval); @@ -824,7 +828,7 @@ TEST_F(DroppedFrameCounterTest, MovingSmoothnessRatings) { // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); static_assert(kFps == 100, "kFps must be 100 because this test depends on it."); SetInterval(kInterval); @@ -897,7 +901,7 @@ TEST_F(DroppedFrameCounterTest, WorstSmoothnessTiming) { // Set an interval that rounds up nicely with 1 second. constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); static_assert( kFps % 5 == 0, "kFps must be a multiple of 5 because this test depends on it."); @@ -943,9 +947,9 @@ EXPECT_FLOAT_EQ(MaxPercentDroppedFrameAfter5Sec(), 100); } -TEST_F(DroppedFrameCounterTest, ReportForUI) { +TEST_F(DroppedFrameCounterTest, ReportOnEveryFrameForUI) { constexpr auto kInterval = base::Milliseconds(10); - constexpr size_t kFps = base::Seconds(1) / kInterval; + constexpr int kFps = base::Seconds(1).IntDiv(kInterval); static_assert( kFps % 5 == 0, "kFps must be a multiple of 5 because this test depends on it."); @@ -957,9 +961,19 @@ // 4 seconds with 20% dropped frames. SimulateFrameSequence({false, false, false, false, true}, (kFps / 5) * 4); - // Recorded more than 1 samples of 20% dropped frame percentage. - EXPECT_GE(recorder.percent_dropped_frames_count(), 1); - EXPECT_EQ(recorder.last_percent_dropped_frames(), 20.0f); + // Recorded (kFps * 3) samples of 20% dropped frame percentage. Only 3 seconds + // of frames reported because there is no reports for the very 1st second. + EXPECT_EQ(recorder.report_count(), kFps * 3); + EXPECT_FLOAT_EQ(recorder.last_percent_dropped_frames(), 20.0f); + + recorder.Reset(); + + // 4 seconds with 0 dropped frames. + SimulateFrameSequence({false, false, false, false, false}, (kFps / 5) * 4); + + // Recorded (kFps * 4) samples of 0% dropped frame percentage. + EXPECT_EQ(recorder.report_count(), kFps * 4); + EXPECT_FLOAT_EQ(recorder.last_percent_dropped_frames(), 0.0f); } } // namespace
diff --git a/cc/paint/image_transfer_cache_entry.cc b/cc/paint/image_transfer_cache_entry.cc index 913cbc7..1d0f1e9 100644 --- a/cc/paint/image_transfer_cache_entry.cc +++ b/cc/paint/image_transfer_cache_entry.cc
@@ -93,16 +93,13 @@ base::CheckedNumeric<uint32_t> SafeSizeForPixmap(const SkPixmap& pixmap) { base::CheckedNumeric<uint32_t> safe_size; - safe_size += sizeof(uint64_t); // color type - safe_size += sizeof(uint64_t); // width - safe_size += sizeof(uint64_t); // height - safe_size += sizeof(uint64_t); // has color space - if (pixmap.colorSpace()) - safe_size += pixmap.colorSpace()->writeToMemory(nullptr); // color space - safe_size += sizeof(uint64_t); // row bytes - safe_size += sizeof(uint64_t); // data size - safe_size += sizeof(16u); // alignment - safe_size += pixmap.computeByteSize(); // data + safe_size += PaintOpWriter::SerializedSize(pixmap.colorType()); + safe_size += PaintOpWriter::SerializedSize(pixmap.width()); + safe_size += PaintOpWriter::SerializedSize(pixmap.height()); + safe_size += PaintOpWriter::SerializedSize(pixmap.colorSpace()); + safe_size += PaintOpWriter::SerializedSize(pixmap.rowBytes()); + safe_size += 16u; // The max of GetAlignmentForColorType(). + safe_size += PaintOpWriter::SerializedSizeOfBytes(pixmap.computeByteSize()); return safe_size; } @@ -153,9 +150,9 @@ DLOG(ERROR) << "Invalid color type"; return false; } - uint32_t width = 0; + int width = 0; reader.Read(&width); - uint32_t height = 0; + int height = 0; reader.Read(&height); if (width == 0 || height == 0) { DLOG(ERROR) << "Empty width or height"; @@ -200,33 +197,34 @@ size_t TargetColorParamsSize( const absl::optional<TargetColorParams>& target_color_params) { - // uint32 for whether or not there are going to be parameters. - size_t target_color_params_size = sizeof(uint32_t); + // bool for whether or not there are going to be parameters. + size_t target_color_params_size = PaintOpWriter::SerializedSize<bool>(); if (target_color_params) { - // x64 has 8-byte alignment for uint64_t even though x86 has 4-byte - // alignment. Always use 8 byte alignment. - const size_t align = sizeof(uint64_t); - // The target color space. + target_color_params_size += PaintOpWriter::SerializedSize( + target_color_params->color_space.ToSkColorSpace().get()); + target_color_params_size += PaintOpWriter::SerializedSize( + target_color_params->sdr_max_luminance_nits); + target_color_params_size += PaintOpWriter::SerializedSize( + target_color_params->hdr_max_luminance_relative); target_color_params_size += - sizeof(uint64_t) + - target_color_params->color_space.ToSkColorSpace()->writeToMemory( - nullptr) + - align; - // Floats for the SDR and HDR maximum luminance. - target_color_params_size += sizeof(float); - target_color_params_size += sizeof(float); - // uint32_t for tone mapping enabled or disabled. - target_color_params_size += sizeof(uint32_t); - // uint32_t for whether or not there is HDR metadata. - target_color_params_size += sizeof(uint32_t); - if (target_color_params->hdr_metadata) { - // The x and y coordinates for primaries and white point. - target_color_params_size += 4 * 2 * sizeof(float); + PaintOpWriter::SerializedSize(target_color_params->enable_tone_mapping); + // bool for whether or not there is HDR metadata. + target_color_params_size += PaintOpWriter::SerializedSize<bool>(); + if (auto& hdr_metadata = target_color_params->hdr_metadata) { // The minimum and maximum luminance. - target_color_params_size += 2 * sizeof(float); + target_color_params_size += + PaintOpWriter::SerializedSize(hdr_metadata->max_content_light_level); + target_color_params_size += PaintOpWriter::SerializedSize( + hdr_metadata->max_frame_average_light_level); + // The x and y coordinates for primaries and white point. + target_color_params_size += PaintOpWriter::SerializedSizeOfElements( + &hdr_metadata->color_volume_metadata.primaries.fRX, 4 * 2); // The CLL and FALL - target_color_params_size += 2 * sizeof(unsigned); + target_color_params_size += PaintOpWriter::SerializedSize( + hdr_metadata->color_volume_metadata.luminance_max); + target_color_params_size += PaintOpWriter::SerializedSize( + hdr_metadata->color_volume_metadata.luminance_min); } } return target_color_params_size; @@ -235,7 +233,7 @@ void WriteTargetColorParams( PaintOpWriter& writer, const absl::optional<TargetColorParams>& target_color_params) { - const uint32_t has_target_color_params = target_color_params ? 1 : 0; + const bool has_target_color_params = !!target_color_params; writer.Write(has_target_color_params); if (target_color_params) { writer.Write(target_color_params->color_space.ToSkColorSpace().get()); @@ -243,7 +241,7 @@ writer.Write(target_color_params->hdr_max_luminance_relative); writer.Write(target_color_params->enable_tone_mapping); - const uint32_t has_hdr_metadata = !!target_color_params->hdr_metadata; + const bool has_hdr_metadata = !!target_color_params->hdr_metadata; writer.Write(has_hdr_metadata); if (target_color_params->hdr_metadata) { const auto& hdr_metadata = target_color_params->hdr_metadata; @@ -268,7 +266,7 @@ bool ReadTargetColorParams( PaintOpReader& reader, absl::optional<TargetColorParams>& target_color_params) { - uint32_t has_target_color_params = 0; + bool has_target_color_params = false; reader.Read(&has_target_color_params); if (!has_target_color_params) { target_color_params = absl::nullopt; @@ -286,7 +284,7 @@ reader.Read(&target_color_params->hdr_max_luminance_relative); reader.Read(&target_color_params->enable_tone_mapping); - uint32_t has_hdr_metadata = 0; + bool has_hdr_metadata = false; reader.Read(&has_hdr_metadata); if (has_hdr_metadata) { gfx::HDRMetadata hdr_metadata; @@ -341,32 +339,13 @@ id_(GetNextId()), pixmap_(pixmap), decoded_color_space_(nullptr) { - size_t pixmap_color_space_size = - pixmap_->colorSpace() ? pixmap_->colorSpace()->writeToMemory(nullptr) - : 0u; - - // x64 has 8-byte alignment for uint64_t even though x86 has 4-byte - // alignment. Always use 8 byte alignment. - const size_t align = sizeof(uint64_t); - // Compute and cache the size of the data. base::CheckedNumeric<uint32_t> safe_size; - safe_size += PaintOpWriter::HeaderBytes(); - safe_size += sizeof(uint32_t); // is_yuv - safe_size += sizeof(uint32_t); // color type - safe_size += sizeof(uint32_t); // width - safe_size += sizeof(uint32_t); // height - safe_size += sizeof(uint32_t); // has mips - safe_size += sizeof(uint64_t) + align; // pixels size + alignment - safe_size += sizeof(uint64_t) + align; // row bytes + alignment + safe_size += PaintOpWriter::SerializedSize(needs_mips_); safe_size += TargetColorParamsSize(target_color_params_); - safe_size += pixmap_color_space_size + sizeof(uint64_t) + align; - // Include 4 bytes of padding so we can always align our data pointer to a - // 4-byte boundary. - safe_size += 4; - safe_size += pixmap_->computeByteSize(); - size_ = base::bits::AlignUp(size_t{safe_size.ValueOrDefault(0)}, - PaintOpWriter::Alignment()); + safe_size += PaintOpWriter::SerializedSize(plane_config_); + safe_size += SafeSizeForPixmap(*pixmap_); + size_ = safe_size.ValueOrDefault(0); } ClientImageTransferCacheEntry::ClientImageTransferCacheEntry( @@ -394,29 +373,19 @@ yuv_pixmaps_->at(i) = &yuva_pixmaps[i]; } DCHECK(IsYuv()); - size_t decoded_color_space_size = - decoded_color_space ? decoded_color_space->writeToMemory(nullptr) : 0u; - - // x64 has 8-byte alignment for uint64_t even though x86 has 4-byte - // alignment. Always use 8 byte alignment. - const size_t align = sizeof(uint64_t); // Compute and cache the size of the data. base::CheckedNumeric<uint32_t> safe_size; - safe_size += PaintOpWriter::HeaderBytes(); - - safe_size += sizeof(uint32_t); // has mips - safe_size += sizeof(uint64_t); // target color space stub (is nullptr) + safe_size += PaintOpWriter::SerializedSize(needs_mips_); safe_size += TargetColorParamsSize(target_color_params_); - - safe_size += sizeof(uint32_t); // plane_config - safe_size += sizeof(uint32_t); // subsampling - safe_size += sizeof(uint32_t); // YUVA color matrix for YUVA image - safe_size += decoded_color_space_size + align; // SkColorSpace for YUVA image - for (size_t i = 0; i < num_yuva_pixmaps; ++i) + safe_size += PaintOpWriter::SerializedSize(plane_config_); + safe_size += PaintOpWriter::SerializedSize(subsampling_); + safe_size += PaintOpWriter::SerializedSize(yuv_color_space_); + safe_size += PaintOpWriter::SerializedSize(decoded_color_space_.get()); + for (size_t i = 0; i < num_yuva_pixmaps; ++i) { safe_size += SafeSizeForPixmap(*yuv_pixmaps_->at(i)); - size_ = base::bits::AlignUp(size_t{safe_size.ValueOrDefault(0)}, - PaintOpWriter::Alignment()); + } + size_ = safe_size.ValueOrDefault(0); } ClientImageTransferCacheEntry::~ClientImageTransferCacheEntry() = default; @@ -454,7 +423,7 @@ PaintOp::SerializeOptions options; PaintOpWriter writer(data.data(), data.size(), options); - writer.Write(static_cast<uint32_t>(needs_mips_ ? 1 : 0)); + writer.Write(needs_mips_); WriteTargetColorParams(writer, target_color_params_); writer.Write(plane_config_); @@ -556,7 +525,7 @@ PaintOpReader reader(data.data(), data.size(), options); // Parameters common to RGBA and YUVA images. - uint32_t needs_mips = 0; + bool needs_mips = false; reader.Read(&needs_mips); has_mips_ = needs_mips; absl::optional<TargetColorParams> target_color_params;
diff --git a/cc/paint/paint_filter.cc b/cc/paint/paint_filter.cc index 00fe240..f9ec2d47 100644 --- a/cc/paint/paint_filter.cc +++ b/cc/paint/paint_filter.cc
@@ -136,22 +136,13 @@ return base::OptionalToPtr(crop_rect_); } -size_t PaintFilter::GetFilterSize(const PaintFilter* filter) { - // A null type is used to indicate no filter. - if (!filter) - return sizeof(uint32_t); - return filter->SerializedSize() + PaintOpWriter::Alignment(); -} - size_t PaintFilter::BaseSerializedSize() const { size_t total_size = 0u; - // Filter type. - total_size += sizeof(uint32_t); + total_size += PaintOpWriter::SerializedSize(type_); // Bool to indicate whether crop exists. - total_size += sizeof(uint32_t); + total_size += PaintOpWriter::SerializedSize<bool>(); if (crop_rect_) { - // CropRect. - total_size += sizeof(*crop_rect_); + total_size += PaintOpWriter::SerializedSize(*crop_rect_); } return total_size; } @@ -240,8 +231,9 @@ size_t ColorFilterPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = 0u; total_size += BaseSerializedSize(); - total_size += PaintOpWriter::GetFlattenableSize(color_filter_.get()); - total_size += GetFilterSize(input_.get()); + total_size += PaintOpWriter::SerializedSize( + static_cast<const SkFlattenable*>(color_filter_.get())); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -279,9 +271,10 @@ size_t BlurPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(sigma_x_) + sizeof(sigma_y_) + - sizeof(tile_mode_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(sigma_x_) + + PaintOpWriter::SerializedSize(sigma_y_) + + PaintOpWriter::SerializedSize(tile_mode_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -331,9 +324,13 @@ size_t DropShadowPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(dx_) + sizeof(dy_) + sizeof(sigma_x_) + - sizeof(sigma_y_) + sizeof(color_) + sizeof(shadow_mode_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(dx_) + + PaintOpWriter::SerializedSize(dy_) + + PaintOpWriter::SerializedSize(sigma_x_) + + PaintOpWriter::SerializedSize(sigma_y_) + + PaintOpWriter::SerializedSize(color_) + + PaintOpWriter::SerializedSize(shadow_mode_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -368,8 +365,9 @@ size_t MagnifierPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(src_rect_) + sizeof(inset_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(src_rect_) + + PaintOpWriter::SerializedSize(inset_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -400,8 +398,8 @@ size_t ComposePaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = BaseSerializedSize(); - total_size += GetFilterSize(outer_.get()); - total_size += GetFilterSize(inner_.get()); + total_size += PaintOpWriter::SerializedSize(outer_.get()); + total_size += PaintOpWriter::SerializedSize(inner_.get()); return total_size.ValueOrDefault(0u); } @@ -436,10 +434,11 @@ size_t AlphaThresholdPaintFilter::SerializedSize() const { size_t region_size = region_.writeToMemory(nullptr); base::CheckedNumeric<size_t> total_size; - total_size = BaseSerializedSize() + sizeof(uint64_t) + - base::bits::AlignUp(region_size, PaintOpWriter::Alignment()) + - sizeof(inner_min_) + sizeof(outer_max_); - total_size += GetFilterSize(input_.get()); + total_size = BaseSerializedSize() + + PaintOpWriter::SerializedSizeOfBytes(region_size) + + PaintOpWriter::SerializedSize(inner_min_) + + PaintOpWriter::SerializedSize(outer_max_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -477,9 +476,9 @@ size_t XfermodePaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(blend_mode_); - total_size += GetFilterSize(background_.get()); - total_size += GetFilterSize(foreground_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(blend_mode_); + total_size += PaintOpWriter::SerializedSize(background_.get()); + total_size += PaintOpWriter::SerializedSize(foreground_.get()); return total_size.ValueOrDefault(0u); } @@ -525,10 +524,12 @@ size_t ArithmeticPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(k1_) + sizeof(k2_) + sizeof(k3_) + - sizeof(k4_) + sizeof(enforce_pm_color_); - total_size += GetFilterSize(background_.get()); - total_size += GetFilterSize(foreground_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(k1_) + + PaintOpWriter::SerializedSize(k2_) + PaintOpWriter::SerializedSize(k3_) + + PaintOpWriter::SerializedSize(k4_) + + PaintOpWriter::SerializedSize(enforce_pm_color_); + total_size += PaintOpWriter::SerializedSize(background_.get()); + total_size += PaintOpWriter::SerializedSize(foreground_.get()); return total_size.ValueOrDefault(0u); } @@ -582,10 +583,16 @@ size_t MatrixConvolutionPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(kernel_size_) + sizeof(size_t) + - kernel_->size() * sizeof(SkScalar) + sizeof(gain_) + sizeof(bias_) + - sizeof(kernel_offset_) + sizeof(tile_mode_) + sizeof(convolve_alpha_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(kernel_size_) + + PaintOpWriter::SerializedSize<size_t>() + + PaintOpWriter::SerializedSizeOfElements(kernel_->data(), + kernel_->size()) + + PaintOpWriter::SerializedSize(gain_) + + PaintOpWriter::SerializedSize(bias_) + + PaintOpWriter::SerializedSize(kernel_offset_) + + PaintOpWriter::SerializedSize(tile_mode_) + + PaintOpWriter::SerializedSize(convolve_alpha_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -631,11 +638,12 @@ DisplacementMapEffectPaintFilter::~DisplacementMapEffectPaintFilter() = default; size_t DisplacementMapEffectPaintFilter::SerializedSize() const { - base::CheckedNumeric<size_t> total_size = BaseSerializedSize() + - sizeof(channel_x_) + - sizeof(channel_y_) + sizeof(scale_); - total_size += GetFilterSize(displacement_.get()); - total_size += GetFilterSize(color_.get()); + base::CheckedNumeric<size_t> total_size = + BaseSerializedSize() + PaintOpWriter::SerializedSize(channel_x_) + + PaintOpWriter::SerializedSize(channel_y_) + + PaintOpWriter::SerializedSize(scale_); + total_size += PaintOpWriter::SerializedSize(displacement_.get()); + total_size += PaintOpWriter::SerializedSize(color_.get()); return total_size.ValueOrDefault(0u); } @@ -674,9 +682,10 @@ size_t ImagePaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(src_rect_) + sizeof(dst_rect_) + - sizeof(filter_quality_); - total_size += PaintOpWriter::GetImageSize(image_); + BaseSerializedSize() + PaintOpWriter::SerializedSize(src_rect_) + + PaintOpWriter::SerializedSize(dst_rect_) + + PaintOpWriter::SerializedSize(filter_quality_); + total_size += PaintOpWriter::SerializedSize(image_); return total_size.ValueOrDefault(0u); } @@ -795,9 +804,10 @@ size_t RecordPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(record_bounds_) + sizeof(raster_scale_) + - sizeof(scaling_behavior_) + sizeof(bool); - total_size += PaintOpWriter::GetRecordSize(&record_); + BaseSerializedSize() + PaintOpWriter::SerializedSize(record_bounds_) + + PaintOpWriter::SerializedSize(raster_scale_) + + PaintOpWriter::SerializedSize(scaling_behavior_); + total_size += PaintOpWriter::SerializedSize(record_); return total_size.ValueOrDefault(0u); } @@ -842,11 +852,11 @@ MergePaintFilter::~MergePaintFilter() = default; size_t MergePaintFilter::SerializedSize() const { - base::CheckedNumeric<size_t> total_size = 0u; - for (size_t i = 0; i < input_count(); ++i) - total_size += GetFilterSize(input_at(i)); - total_size += BaseSerializedSize(); - total_size += sizeof(input_count()); + base::CheckedNumeric<size_t> total_size = BaseSerializedSize(); + total_size += PaintOpWriter::SerializedSize(input_count()); + for (size_t i = 0; i < input_count(); ++i) { + total_size += PaintOpWriter::SerializedSize(input_at(i)); + } return total_size.ValueOrDefault(0u); } @@ -889,9 +899,10 @@ size_t MorphologyPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(morph_type_) + sizeof(radius_x_) + - sizeof(radius_y_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(morph_type_) + + PaintOpWriter::SerializedSize(radius_x_) + + PaintOpWriter::SerializedSize(radius_y_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -924,9 +935,10 @@ OffsetPaintFilter::~OffsetPaintFilter() = default; size_t OffsetPaintFilter::SerializedSize() const { - base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(dx_) + sizeof(dy_); - total_size += GetFilterSize(input_.get()); + base::CheckedNumeric<size_t> total_size = BaseSerializedSize() + + PaintOpWriter::SerializedSize(dx_) + + PaintOpWriter::SerializedSize(dy_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -956,8 +968,9 @@ size_t TilePaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(src_) + sizeof(dst_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(src_) + + PaintOpWriter::SerializedSize(dst_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -1006,9 +1019,13 @@ TurbulencePaintFilter::~TurbulencePaintFilter() = default; size_t TurbulencePaintFilter::SerializedSize() const { - return BaseSerializedSize() + sizeof(turbulence_type_) + - sizeof(base_frequency_x_) + sizeof(base_frequency_y_) + - sizeof(num_octaves_) + sizeof(seed_) + sizeof(tile_size_); + return BaseSerializedSize() + + PaintOpWriter::SerializedSize(turbulence_type_) + + PaintOpWriter::SerializedSize(base_frequency_x_) + + PaintOpWriter::SerializedSize(base_frequency_y_) + + PaintOpWriter::SerializedSize(num_octaves_) + + PaintOpWriter::SerializedSize(seed_) + + PaintOpWriter::SerializedSize(tile_size_); } sk_sp<PaintFilter> TurbulencePaintFilter::SnapshotWithImagesInternal( @@ -1057,9 +1074,10 @@ size_t ShaderPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = BaseSerializedSize(); total_size += PaintShader::GetSerializedSize(shader_.get()); - total_size += sizeof(alpha_); - total_size += sizeof(filter_quality_); // filter quality - total_size += sizeof(dither_); + total_size += PaintOpWriter::SerializedSize(alpha_); + total_size += + PaintOpWriter::SerializedSize(filter_quality_); // filter quality + total_size += PaintOpWriter::SerializedSize(dither_); return total_size.ValueOrDefault(0u); } @@ -1110,8 +1128,9 @@ size_t MatrixPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(matrix_) + sizeof(filter_quality_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(matrix_) + + PaintOpWriter::SerializedSize(filter_quality_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -1163,10 +1182,13 @@ size_t LightingDistantPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(lighting_type_) + sizeof(direction_) + - sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) + - sizeof(shininess_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(lighting_type_) + + PaintOpWriter::SerializedSize(direction_) + + PaintOpWriter::SerializedSize(light_color_) + + PaintOpWriter::SerializedSize(surface_scale_) + + PaintOpWriter::SerializedSize(kconstant_) + + PaintOpWriter::SerializedSize(shininess_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -1222,10 +1244,13 @@ size_t LightingPointPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(lighting_type_) + sizeof(location_) + - sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) + - sizeof(shininess_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(lighting_type_) + + PaintOpWriter::SerializedSize(location_) + + PaintOpWriter::SerializedSize(light_color_) + + PaintOpWriter::SerializedSize(surface_scale_) + + PaintOpWriter::SerializedSize(kconstant_) + + PaintOpWriter::SerializedSize(shininess_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); } @@ -1289,11 +1314,16 @@ size_t LightingSpotPaintFilter::SerializedSize() const { base::CheckedNumeric<size_t> total_size = - BaseSerializedSize() + sizeof(lighting_type_) + sizeof(location_) + - sizeof(target_) + sizeof(specular_exponent_) + sizeof(cutoff_angle_) + - sizeof(light_color_) + sizeof(surface_scale_) + sizeof(kconstant_) + - sizeof(shininess_); - total_size += GetFilterSize(input_.get()); + BaseSerializedSize() + PaintOpWriter::SerializedSize(lighting_type_) + + PaintOpWriter::SerializedSize(location_) + + PaintOpWriter::SerializedSize(target_) + + PaintOpWriter::SerializedSize(specular_exponent_) + + PaintOpWriter::SerializedSize(cutoff_angle_) + + PaintOpWriter::SerializedSize(light_color_) + + PaintOpWriter::SerializedSize(surface_scale_) + + PaintOpWriter::SerializedSize(kconstant_) + + PaintOpWriter::SerializedSize(shininess_); + total_size += PaintOpWriter::SerializedSize(input_.get()); return total_size.ValueOrDefault(0u); }
diff --git a/cc/paint/paint_filter.h b/cc/paint/paint_filter.h index f1a1267..532bc8dc 100644 --- a/cc/paint/paint_filter.h +++ b/cc/paint/paint_filter.h
@@ -77,10 +77,6 @@ static std::string TypeToString(Type type); - // Returns the size required to serialize the |filter|. Note that |filter| can - // be nullptr. - static size_t GetFilterSize(const PaintFilter* filter); - Type type() const { return type_; } SkIRect filter_bounds(const SkIRect& src, const SkMatrix& ctm,
diff --git a/cc/paint/paint_flags.cc b/cc/paint/paint_flags.cc index 20e7f9a..5f90f2e 100644 --- a/cc/paint/paint_flags.cc +++ b/cc/paint/paint_flags.cc
@@ -9,8 +9,8 @@ #include "base/memory/values_equivalent.h" #include "base/notreached.h" #include "cc/paint/paint_filter.h" +#include "cc/paint/paint_op.h" #include "cc/paint/paint_op_buffer.h" -#include "cc/paint/paint_op_writer.h" #include "cc/paint/paint_shader.h" #include "third_party/skia/include/core/SkPathUtils.h" @@ -202,18 +202,4 @@ (image_filter_ && image_filter_->has_discardable_images()); } -size_t PaintFlags::GetSerializedSize() const { - return sizeof(color_) + sizeof(width_) + sizeof(miter_limit_) + - sizeof(blend_mode_) + sizeof(bitfields_uint_) + - PaintOpWriter::GetFlattenableSize(path_effect_.get()) + - PaintOpWriter::Alignment() + - PaintOpWriter::GetFlattenableSize(mask_filter_.get()) + - PaintOpWriter::Alignment() + - PaintOpWriter::GetFlattenableSize(color_filter_.get()) + - PaintOpWriter::Alignment() + - PaintOpWriter::GetFlattenableSize(draw_looper_.get()) + - PaintFilter::GetFilterSize(image_filter_.get()) + - PaintShader::GetSerializedSize(shader_.get()); -} - } // namespace cc
diff --git a/cc/paint/paint_flags.h b/cc/paint/paint_flags.h index f843536..5b75b91 100644 --- a/cc/paint/paint_flags.h +++ b/cc/paint/paint_flags.h
@@ -188,8 +188,6 @@ bool HasDiscardableImages() const; - size_t GetSerializedSize() const; - private: friend class PaintOpReader; friend class PaintOpWriter;
diff --git a/cc/paint/paint_op.cc b/cc/paint/paint_op.cc index 056b3ad..9c81396 100644 --- a/cc/paint/paint_op.cc +++ b/cc/paint/paint_op.cc
@@ -491,7 +491,6 @@ writer.Write( CreateDrawImage(image, flags_to_serialize, sampling, current_ctm), &serialized_scale_adjustment); - writer.AssertAlignment(alignof(SkScalar)); writer.Write(serialized_scale_adjustment.width()); writer.Write(serialized_scale_adjustment.height()); @@ -513,7 +512,6 @@ SkSize serialized_scale_adjustment = SkSize::Make(1.f, 1.f); writer.Write(CreateDrawImage(image, flags_to_serialize, sampling, matrix), &serialized_scale_adjustment); - writer.AssertAlignment(alignof(SkScalar)); writer.Write(serialized_scale_adjustment.width()); writer.Write(serialized_scale_adjustment.height()); @@ -536,7 +534,6 @@ const SkM44& current_ctm, const SkM44& original_ctm) const { writer.Write(*flags_to_serialize, current_ctm); - writer.AssertAlignment(alignof(SkScalar)); writer.Write(x0); writer.Write(y0); writer.Write(x1); @@ -804,7 +801,6 @@ reader.Read(&op->flags); reader.Read(&op->image); - reader.AssertAlignment(alignof(SkScalar)); reader.Read(&op->scale_adjustment.fWidth); reader.Read(&op->scale_adjustment.fHeight); @@ -820,7 +816,6 @@ reader.Read(&op->flags); reader.Read(&op->image); - reader.AssertAlignment(alignof(SkScalar)); reader.Read(&op->scale_adjustment.fWidth); reader.Read(&op->scale_adjustment.fHeight); @@ -842,7 +837,6 @@ PaintOp* DrawLineOp::Deserialize(PaintOpReader& reader, void* output) { DrawLineOp* op = new (output) DrawLineOp; reader.Read(&op->flags); - reader.AssertAlignment(alignof(SkScalar)); reader.Read(&op->x0); reader.Read(&op->y0); reader.Read(&op->x1); @@ -1660,17 +1654,15 @@ const SkM44& current_ctm, const SkM44& original_ctm) const { // Need at least enough room for the header. - if (size < PaintOpWriter::HeaderBytes()) { + if (size < PaintOpWriter::kHeaderBytes) { return 0u; } - DCHECK_EQ(0u, - reinterpret_cast<uintptr_t>(memory) % PaintOpBuffer::kPaintOpAlign); - PaintOpWriter writer(memory, size, options); + writer.ReserveOpHeader(); g_serialize_functions[type](*this, writer, flags_to_serialize, current_ctm, original_ctm); - return writer.Finish(type); + return writer.FinishOp(type); } PaintOp* PaintOp::Deserialize(const volatile void* input, @@ -1679,15 +1671,13 @@ size_t output_size, size_t* read_bytes, const DeserializeOptions& options) { - DCHECK_GE(output_size, sizeof(LargestPaintOp)); + DCHECK_GE(output_size, kLargestPaintOpAlignedSize); uint8_t type; - if (!PaintOpReader::ReadAndValidateOpHeader(input, input_size, &type, - read_bytes)) { + PaintOpReader reader(input, input_size, options); + if (!reader.ReadAndValidateOpHeader(&type, read_bytes)) { return nullptr; } - - PaintOpReader reader(input, *read_bytes, options); return g_deserialize_functions[type](reader, output, output_size); } @@ -1698,12 +1688,11 @@ size_t* read_bytes, const DeserializeOptions& options) { uint8_t type; - if (!PaintOpReader::ReadAndValidateOpHeader(input, input_size, &type, - read_bytes)) { + PaintOpReader reader(input, input_size, options); + if (!reader.ReadAndValidateOpHeader(&type, read_bytes)) { return nullptr; } - PaintOpReader reader(input, *read_bytes, options); uint16_t op_aligned_size = g_type_to_aligned_size[type]; if (auto* op = g_deserialize_functions[type]( reader, buffer->AllocatePaintOp(op_aligned_size), op_aligned_size)) {
diff --git a/cc/paint/paint_op.h b/cc/paint/paint_op.h index e521da98..ce94e7b 100644 --- a/cc/paint/paint_op.h +++ b/cc/paint/paint_op.h
@@ -1034,6 +1034,12 @@ DrawImageRectOp, DrawDRRectOp>::type; +// When allocating a buffer for deserialization of a single PaintOp, the buffer +// should be aligned as PaintOpBuffer::kPaintOpAlign, and the size should be +// kLargestPaintOpAlignedSize instead of sizeof(LargestPaintOp). +inline constexpr size_t kLargestPaintOpAlignedSize = + PaintOpBuffer::ComputeOpAlignedSize<LargestPaintOp>(); + } // namespace cc #endif // CC_PAINT_PAINT_OP_H_
diff --git a/cc/paint/paint_op_buffer_fuzzer.cc b/cc/paint/paint_op_buffer_fuzzer.cc index a782f9c..1a15133 100644 --- a/cc/paint/paint_op_buffer_fuzzer.cc +++ b/cc/paint/paint_op_buffer_fuzzer.cc
@@ -73,7 +73,6 @@ const uint8_t* data, size_t size) { const size_t kRasterDimension = 32; - const size_t kMaxSerializedSize = 1000000; SkImageInfo image_info = SkImageInfo::MakeN32( kRasterDimension, kRasterDimension, kOpaque_SkAlphaType); @@ -89,16 +88,8 @@ &transfer_cache_helper, paint_cache, strike_client, &scratch_buffer, true /* is_privileged */, nullptr /* shared_image_provider */); - // Need HeaderBytes() bytes to be able to read the header. - while (size >= cc::PaintOpWriter::HeaderBytes()) { - uint8_t serialized_type = 0; - size_t serialized_size = 0; - cc::PaintOpReader::ReadAndValidateOpHeader(data, size, &serialized_type, - &serialized_size); - if (serialized_size > kMaxSerializedSize) { - break; - } - + // Need kHeaderBytes bytes to be able to read the header. + while (size >= cc::PaintOpWriter::kHeaderBytes) { std::unique_ptr<char, base::AlignedFreeDeleter> deserialized( static_cast<char*>(base::AlignedAlloc( sizeof(cc::LargestPaintOp), cc::PaintOpBuffer::kPaintOpAlign))); @@ -114,10 +105,6 @@ deserialized_op->DestroyThis(); - if (serialized_size >= size) { - break; - } - size -= bytes_read; data += bytes_read; } @@ -134,12 +121,16 @@ // Partition the data to use some bytes for populating the font cache. uint32_t bytes_for_fonts = data[0]; - if (bytes_for_fonts > size) + if (bytes_for_fonts > size) { bytes_for_fonts = size / 2; - // PaintOpBuffer only accepts 4 bytes aligned buffer. - bytes_for_fonts = base::bits::AlignDown( - bytes_for_fonts, - base::checked_cast<uint32_t>(cc::PaintOpWriter::Alignment())); + } + const uint8_t* raster_data = base::bits::AlignDown( + data + bytes_for_fonts, cc::PaintOpWriter::kMaxAlignment); + if (raster_data < data) { + return 0; + } + bytes_for_fonts = raster_data - data; + size_t raster_size = size - bytes_for_fonts; FontSupport font_support; scoped_refptr<gpu::ServiceFontManager> font_manager( @@ -150,15 +141,13 @@ if (bytes_for_fonts > 0u) { font_manager->Deserialize(reinterpret_cast<const char*>(data), bytes_for_fonts, &locked_handles); - data += bytes_for_fonts; - size -= bytes_for_fonts; } auto context_provider_no_support = viz::TestContextProvider::Create(); context_provider_no_support->BindToCurrentSequence(); CHECK(!context_provider_no_support->GrContext()->supportsDistanceFieldText()); Raster(context_provider_no_support, font_manager->strike_client(), - &paint_cache, data, size); + &paint_cache, raster_data, raster_size); auto context_provider_with_support = viz::TestContextProvider::Create( std::string("GL_OES_standard_derivatives")); @@ -166,7 +155,7 @@ CHECK( context_provider_with_support->GrContext()->supportsDistanceFieldText()); Raster(context_provider_with_support, font_manager->strike_client(), - &paint_cache, data, size); + &paint_cache, raster_data, raster_size); font_manager->Unlock(locked_handles); font_manager->Destroy();
diff --git a/cc/paint/paint_op_buffer_serializer.cc b/cc/paint/paint_op_buffer_serializer.cc index 44becf5..30fed4d 100644 --- a/cc/paint/paint_op_buffer_serializer.cc +++ b/cc/paint/paint_op_buffer_serializer.cc
@@ -13,6 +13,7 @@ #include "base/trace_event/trace_event.h" #include "cc/paint/clear_for_opaque_raster.h" #include "cc/paint/paint_op_buffer_iterator.h" +#include "cc/paint/paint_op_writer.h" #include "cc/paint/scoped_raster_flags.h" #include "skia/ext/legacy_display_globals.h" #include "third_party/skia/include/core/SkColorSpace.h" @@ -309,8 +310,7 @@ return false; } - DCHECK_GE(bytes, 4u); - DCHECK_EQ(bytes % PaintOpBuffer::kPaintOpAlign, 0u); + DCHECK_GE(bytes, PaintOpWriter::kHeaderBytes); return true; }
diff --git a/cc/paint/paint_op_buffer_unittest.cc b/cc/paint/paint_op_buffer_unittest.cc index 2cec213c..cc2392c 100644 --- a/cc/paint/paint_op_buffer_unittest.cc +++ b/cc/paint/paint_op_buffer_unittest.cc
@@ -67,17 +67,21 @@ // An arbitrary size guaranteed to fit the size of any serialized op in this // unit test. This can also be used for deserialized op size safely in this // unit test suite as generally deserialized ops are smaller. -static constexpr size_t kBufferBytesPerOp = 1000 + sizeof(LargestPaintOp); +static constexpr size_t kSerializedBytesPerOp = 1000 + sizeof(LargestPaintOp); -static constexpr size_t kDefaultBufferSize = 4096; - -std::unique_ptr<char, base::AlignedFreeDeleter> AllocateBuffer(size_t size) { - return std::unique_ptr<char, base::AlignedFreeDeleter>(static_cast<char*>( - base::AlignedAlloc(size, PaintOpBuffer::kPaintOpAlign))); +static constexpr size_t kDefaultSerializedBufferSize = 4096; +std::unique_ptr<char, base::AlignedFreeDeleter> AllocateSerializedBuffer( + size_t size = kDefaultSerializedBufferSize) { + return PaintOpWriter::AllocateAlignedBuffer(size); } -std::unique_ptr<char, base::AlignedFreeDeleter> AllocateDefaultBuffer() { - return AllocateBuffer(kDefaultBufferSize); +bool ReadAndValidateOpHeader(const void* memory, + size_t size, + uint8_t* op_type, + size_t* serialized_size) { + return PaintOpReader(memory, size, + TestOptionsProvider().deserialize_options()) + .ReadAndValidateOpHeader(op_type, serialized_size); } } // namespace @@ -1276,8 +1280,8 @@ uint8_t type = 0; size_t bytes_to_read = 0; - EXPECT_TRUE(PaintOpReader::ReadAndValidateOpHeader( - current_, remaining_, &type, &bytes_to_read)); + EXPECT_TRUE( + ReadAndValidateOpHeader(current_, remaining_, &type, &bytes_to_read)); EXPECT_EQ(op.type, type); EXPECT_EQ(bytes_written, bytes_to_read); @@ -1286,10 +1290,13 @@ current_ += bytes_written; remaining_ -= bytes_written; - // Number of bytes bytes_written must be a multiple of PaintOpAlign - // unless the buffer is filled entirely. + // Number of bytes bytes_written must be a multiple of + // PaintOpWriter::kMaxAlignment unless the buffer is filled + // entirely. if (remaining_ != 0u) { - DCHECK_EQ(0u, bytes_written % PaintOpBuffer::kPaintOpAlign); + EXPECT_EQ( + bytes_written, + base::bits::AlignUp(bytes_written, PaintOpWriter::kMaxAlignment)); } } } @@ -1362,8 +1369,7 @@ current_(current), input_size_(input_size), remaining_(remaining), - options_(options), - data_(AllocateBuffer(sizeof(LargestPaintOp))) { + options_(options) { DeserializeCurrentOp(); } @@ -1379,9 +1385,9 @@ if (!remaining_) return; - deserialized_op_ = PaintOp::Deserialize(current_, remaining_, data_.get(), - sizeof(LargestPaintOp), - &last_bytes_read_, options_); + deserialized_op_ = PaintOp::Deserialize( + current_, remaining_, paint_op_buffer_data_, + std::size(paint_op_buffer_data_), &last_bytes_read_, options_); } raw_ptr<const void> input_ = nullptr; @@ -1390,7 +1396,8 @@ size_t remaining_ = 0u; size_t last_bytes_read_ = 0u; PaintOp::DeserializeOptions options_; - std::unique_ptr<char, base::AlignedFreeDeleter> data_; + alignas(PaintOpBuffer::kPaintOpAlign) char paint_op_buffer_data_ + [kLargestPaintOpAlignedSize]; raw_ptr<PaintOp> deserialized_op_ = nullptr; }; @@ -1874,10 +1881,9 @@ } void ResizeOutputBuffer() { - // An arbitrary deserialization buffer size that should fit all the ops - // in the buffer_. - output_size_ = kBufferBytesPerOp * buffer_.size(); - output_ = AllocateBuffer(output_size_); + // An serialization buffer size that should fit all the ops in the buffer_. + output_size_ = kSerializedBytesPerOp * buffer_.size(); + output_ = AllocateSerializedBuffer(output_size_); } bool IsTypeSupported() { @@ -1974,8 +1980,9 @@ "%s #%zu", PaintOpTypeToString(GetParamType()).c_str(), op_idx)); size_t expected_bytes = bytes_written[op_idx]; EXPECT_GT(expected_bytes, 0u); - EXPECT_EQ(expected_bytes, - base::bits::AlignUp(expected_bytes, PaintOpWriter::Alignment())); + EXPECT_EQ( + expected_bytes, + base::bits::AlignUp(expected_bytes, PaintOpWriter::kMaxAlignment)); // Attempt to write op into a buffer of size |i|, and only expect // it to succeed if the buffer is large enough. @@ -2012,17 +2019,16 @@ char* first = static_cast<char*>(output_.get()); char* current = first; - static constexpr size_t kAlign = PaintOpBuffer::kPaintOpAlign; - static constexpr size_t kOutputOpSize = kBufferBytesPerOp; - auto deserialize_buffer = AllocateBuffer(kOutputOpSize); + static constexpr size_t kAlign = PaintOpWriter::kMaxAlignment; + static constexpr size_t kOutputOpSize = kSerializedBytesPerOp; + auto deserialize_buffer = AllocateSerializedBuffer(kOutputOpSize); size_t total_read = 0; for (size_t op_idx = 0; op_idx < buffer_.size(); ++op_idx) { uint8_t serialized_type = 0; size_t serialized_size = 0; - PaintOpReader::ReadAndValidateOpHeader(current, - PaintOpWriter::HeaderBytes(), - &serialized_type, &serialized_size); + ReadAndValidateOpHeader(current, PaintOpWriter::kHeaderBytes, + &serialized_type, &serialized_size); EXPECT_EQ(static_cast<uint8_t>(GetParamType()), serialized_type); // Read from buffers of various sizes to make sure that having a serialized @@ -2110,16 +2116,15 @@ ResizeOutputBuffer(); TestOptionsProvider options_provider; - size_t deserialized_size = - sizeof(LargestPaintOp) + PaintOpWriter::kMaxSerializedSize; - auto deserialized = AllocateBuffer(deserialized_size); + alignas(PaintOpBuffer::kPaintOpAlign) char + deserialized[kLargestPaintOpAlignedSize]; for (const PaintOp& op : buffer_) { size_t bytes_written = op.Serialize(output_.get(), output_size_, options_provider.serialize_options(), nullptr, SkM44(), SkM44()); size_t bytes_read = 0u; PaintOp* written = PaintOp::Deserialize( - output_.get(), bytes_written, deserialized.get(), deserialized_size, + output_.get(), bytes_written, deserialized, std::size(deserialized), &bytes_read, options_provider.deserialize_options()); ASSERT_TRUE(written) << PaintOpTypeToString(GetParamType()); EXPECT_THAT(op, PaintOpEq<const PaintOp&>(*written)); @@ -2131,9 +2136,9 @@ bytes_written = op.Serialize(output_.get(), output_size_, options_provider.serialize_options(), &override_flags, SkM44(), SkM44()); - written = PaintOp::Deserialize( - output_.get(), bytes_written, deserialized.get(), deserialized_size, - &bytes_read, options_provider.deserialize_options()); + written = PaintOp::Deserialize(output_.get(), bytes_written, deserialized, + std::size(deserialized), &bytes_read, + options_provider.deserialize_options()); ASSERT_TRUE(written); ASSERT_TRUE(written->IsPaintOpWithFlags()); EXPECT_EQ(static_cast<const PaintOpWithFlags*>(written)->flags.getAlpha(), @@ -2153,9 +2158,9 @@ preamble.full_raster_rect = preamble.playback_rect; preamble.requires_clear = true; - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer, nullptr, preamble); ASSERT_NE(serializer.written(), 0u); @@ -2188,9 +2193,9 @@ PaintOpBuffer buffer; buffer.push<DrawColorOp>(SkColors::kBlue, SkBlendMode::kSrc); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer, nullptr, preamble); ASSERT_NE(serializer.written(), 0u); @@ -2224,9 +2229,9 @@ PaintOpBuffer buffer; buffer.push<DrawRecordOp>(record); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); PaintOpBufferSerializer::Preamble preamble; serializer.Serialize(buffer, nullptr, preamble); @@ -2270,9 +2275,10 @@ static_cast<SkScalar>(test_case.image_rect.x()), static_cast<SkScalar>(test_case.image_rect.y())); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), + kDefaultSerializedBufferSize, options_provider.serialize_options()); PaintOpBufferSerializer::Preamble preamble; preamble.playback_rect = test_case.clip_rect; @@ -2319,9 +2325,9 @@ preamble.full_raster_rect = preamble.playback_rect; preamble.requires_clear = false; - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer, nullptr, preamble); ASSERT_NE(serializer.written(), 0u); @@ -2347,10 +2353,8 @@ // Test generic PaintOp deserializing failure cases. TEST(PaintOpBufferTest, PaintOpDeserialize) { - static constexpr size_t kSize = sizeof(LargestPaintOp) + 100; - static constexpr size_t kAlign = PaintOpBuffer::kPaintOpAlign; - auto input = AllocateBuffer(kSize); - auto output = AllocateBuffer(kSize); + auto input = AllocateSerializedBuffer(kSerializedBytesPerOp); + alignas(PaintOpBuffer::kPaintOpAlign) char output[kLargestPaintOpAlignedSize]; PaintOpBuffer buffer; buffer.push<DrawColorOp>(SkColors::kMagenta, SkBlendMode::kSrc); @@ -2360,16 +2364,16 @@ ASSERT_TRUE(op); TestOptionsProvider options_provider; - size_t bytes_written = - op->Serialize(input.get(), kSize, options_provider.serialize_options(), - nullptr, SkM44(), SkM44()); + size_t bytes_written = op->Serialize(input.get(), kSerializedBytesPerOp, + options_provider.serialize_options(), + nullptr, SkM44(), SkM44()); ASSERT_GT(bytes_written, 0u); // Can deserialize from exactly the right size. size_t bytes_read = 0; - PaintOp* success = - PaintOp::Deserialize(input.get(), bytes_written, output.get(), kSize, - &bytes_read, options_provider.deserialize_options()); + PaintOp* success = PaintOp::Deserialize( + input.get(), bytes_written, output, std::size(output), &bytes_read, + options_provider.deserialize_options()); ASSERT_TRUE(success); EXPECT_EQ(bytes_written, bytes_read); success->DestroyThis(); @@ -2377,7 +2381,7 @@ // Fail to deserialize if serialized_size goes past input size (the // DeserializationFailures test above tests if the serialized_size is lying). for (size_t i = 0; i < bytes_written - 1; ++i) { - EXPECT_FALSE(PaintOp::Deserialize(input.get(), i, output.get(), kSize, + EXPECT_FALSE(PaintOp::Deserialize(input.get(), i, output, std::size(output), &bytes_read, options_provider.deserialize_options())); } @@ -2385,21 +2389,22 @@ // Unaligned serialized_size should fail to deserialize. uint8_t serialized_type = 0; size_t serialized_size = 0; - PaintOpReader::ReadAndValidateOpHeader(input.get(), bytes_written, - &serialized_type, &serialized_size); - EXPECT_EQ(0u, serialized_size % kAlign); + ReadAndValidateOpHeader(input.get(), bytes_written, &serialized_type, + &serialized_size); + EXPECT_EQ(serialized_size, + base::bits::AlignUp(serialized_size, PaintOpWriter::kMaxAlignment)); PaintOpWriter::WriteHeaderForTesting(input.get(), serialized_type, serialized_size - 1); - EXPECT_FALSE(PaintOp::Deserialize(input.get(), bytes_written, output.get(), - kSize, &bytes_read, + EXPECT_FALSE(PaintOp::Deserialize(input.get(), bytes_written, output, + std::size(output), &bytes_read, options_provider.deserialize_options())); // Bogus types fail to deserialize. PaintOpWriter::WriteHeaderForTesting( input.get(), static_cast<uint8_t>(PaintOpType::LastPaintOpType) + 1, serialized_size); - EXPECT_FALSE(PaintOp::Deserialize(input.get(), bytes_written, output.get(), - kSize, &bytes_read, + EXPECT_FALSE(PaintOp::Deserialize(input.get(), bytes_written, output, + std::size(output), &bytes_read, options_provider.deserialize_options())); } @@ -2407,13 +2412,13 @@ // asserts on invalid values in several places so these are not safe to pass // them to the SkCanvas API. TEST(PaintOpBufferTest, ValidateRects) { - size_t buffer_size = kBufferBytesPerOp; - auto serialized = AllocateBuffer(buffer_size); - auto deserialized = AllocateBuffer(buffer_size); + auto serialized = AllocateSerializedBuffer(kSerializedBytesPerOp); + alignas(PaintOpBuffer::kPaintOpAlign) char + deserialized[kLargestPaintOpAlignedSize]; // We may read uninitialized gaps in this test. Initialize the buffer with a // special value to avoid MSAN errors. - memset(serialized.get(), 0xA5, buffer_size); - memset(deserialized.get(), 0x5A, buffer_size); + memset(serialized.get(), 0xA5, kSerializedBytesPerOp); + memset(deserialized, 0x5A, std::size(deserialized)); float rect_size = 0x8.765432p1; SkRect rect = SkRect::MakeWH(rect_size, rect_size); @@ -2438,14 +2443,14 @@ // Every op should serialize but fail to deserialize due to the bad rect. int op_idx = 0; for (const PaintOp& op : buffer) { - size_t bytes_written = op.Serialize(serialized.get(), buffer_size, + size_t bytes_written = op.Serialize(serialized.get(), kSerializedBytesPerOp, options_provider.serialize_options(), nullptr, SkM44(), SkM44()); ASSERT_GT(bytes_written, sizeof(float)); size_t bytes_read = 0; PaintOp* deserialized_op = PaintOp::Deserialize( - serialized.get(), bytes_written, deserialized.get(), buffer_size, + serialized.get(), bytes_written, deserialized, std::size(deserialized), &bytes_read, options_provider.deserialize_options()); EXPECT_TRUE(deserialized_op) << op_idx; deserialized_op->DestroyThis(); @@ -2460,7 +2465,7 @@ } } deserialized_op = PaintOp::Deserialize( - serialized.get(), bytes_written, deserialized.get(), buffer_size, + serialized.get(), bytes_written, deserialized, std::size(deserialized), &bytes_read, options_provider.deserialize_options()); EXPECT_FALSE(deserialized_op) << op_idx; @@ -3067,9 +3072,9 @@ SkTileMode::kRepeat, nullptr)); buffer.push<DrawOvalOp>(SkRect::MakeWH(10, 10), flags); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); ASSERT_NE(serializer.written(), 0u); @@ -3176,20 +3181,18 @@ SCOPED_TRACE(i); auto& filter = filters[i]; - std::vector<uint8_t> memory; size_t buffer_size = filter->type() == PaintFilter::Type::kPaintRecord - ? kDefaultBufferSize - : PaintFilter::GetFilterSize(filter.get()); - buffer_size += PaintOpWriter::HeaderBytes(); - memory.resize(buffer_size); + ? kDefaultSerializedBufferSize + : PaintOpWriter::SerializedSize(filter.get()); + auto memory = AllocateSerializedBuffer(buffer_size); - PaintOpWriter writer(memory.data(), memory.size(), + PaintOpWriter writer(memory.get(), buffer_size, options_provider.serialize_options(), GetParam()); writer.Write(filter.get(), ctm); ASSERT_GT(writer.size(), 0u) << PaintFilter::TypeToString(filter->type()); sk_sp<PaintFilter> deserialized_filter; - PaintOpReader reader(memory.data(), writer.size(), + PaintOpReader reader(memory.get(), writer.size(), options_provider.deserialize_options(), GetParam()); reader.Read(&deserialized_filter); ASSERT_TRUE(deserialized_filter); @@ -3237,7 +3240,7 @@ SkRect::MakeWH(100, 100)); TestOptionsProvider options_provider; - std::vector<uint8_t> memory(kDefaultBufferSize); + std::vector<uint8_t> memory(kDefaultSerializedBufferSize); PaintOpWriter writer(memory.data(), memory.size(), options_provider.serialize_options(), false); writer.Write(filter.get(), SkM44()); @@ -3260,7 +3263,7 @@ } TEST(PaintOpBufferTest, PaintRecordShaderSerialization) { - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); PaintOpBuffer shader_buffer; shader_buffer.push<DrawRectOp>(SkRect::MakeXYWH(0, 0, 1, 1), PaintFlags()); @@ -3272,7 +3275,7 @@ PaintOpBuffer buffer; buffer.push<DrawRectOp>(SkRect::MakeXYWH(1, 2, 3, 4), flags); - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); ASSERT_TRUE(serializer.valid()); @@ -3303,7 +3306,7 @@ // Skottie-specific deserialization failure case. TEST(PaintOpBufferTest, DrawSkottieOpSerializationFailureFromUnPrivilegedProcess) { - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); scoped_refptr<SkottieWrapper> skottie = CreateSkottie(gfx::Size(100, 100), /*duration_secs=*/1); @@ -3320,7 +3323,7 @@ // Serialize TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); ASSERT_TRUE(serializer.valid()); @@ -3530,9 +3533,9 @@ PaintFlags::FilterQuality::kLow); const bool enable_security_constraints = true; - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - PaintOpWriter writer(memory.get(), kDefaultBufferSize, + PaintOpWriter writer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options(), enable_security_constraints); writer.Write(filter.get(), SkM44()); @@ -3562,9 +3565,9 @@ buffer.push<DrawImageRectOp>(CreateDiscardablePaintImage(gfx::Size(32, 16)), src, dst, SkCanvas::kStrict_SrcRectConstraint); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); @@ -3589,9 +3592,9 @@ flags.setShader(shader); buffer.push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); @@ -3614,7 +3617,7 @@ auto* transfer_cache = options_provider.transfer_cache_helper(); // Generate serialized |memory|. - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); size_t memory_written = 0; { PaintOpBuffer buffer; @@ -3622,7 +3625,8 @@ flags.setShader(shader); buffer.push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags); - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), + kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); memory_written = serializer.written(); @@ -3630,7 +3634,7 @@ // Generate serialized |memory_scaled|, which is the same pob, but with // a scale factor. - auto memory_scaled = AllocateDefaultBuffer(); + auto memory_scaled = AllocateSerializedBuffer(); size_t memory_scaled_written = 0; { PaintOpBuffer buffer; @@ -3640,7 +3644,8 @@ buffer.push<ScaleOp>(2.0f, 3.7f); buffer.push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags); - SimpleBufferSerializer serializer(memory_scaled.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory_scaled.get(), + kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); memory_scaled_written = serializer.written(); @@ -3718,13 +3723,13 @@ auto* transfer_cache = options_provider.transfer_cache_helper(); // Generate serialized |memory|. - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); PaintOpBuffer buffer; PaintFlags flags; flags.setShader(shader); buffer.push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags); - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); options_provider.context_supports_distance_field_text(); serializer.Serialize(buffer); @@ -3759,9 +3764,9 @@ flags.setImageFilter(filter); buffer.push<DrawRectOp>(SkRect::MakeWH(10.f, 10.f), flags); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); @@ -3793,9 +3798,9 @@ PaintOpBuffer buffer; buffer.push<DrawImageOp>(PaintImage(), 0.f, 0.f); - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); TestOptionsProvider options_provider; - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer); ASSERT_TRUE(serializer.valid()); @@ -3943,10 +3948,10 @@ TestOptionsProvider options_provider; - auto memory = AllocateDefaultBuffer(); + auto memory = AllocateSerializedBuffer(); PaintOpBuffer buffer; buffer.push<DrawPathOp>(path, flags, UsePaintCache::kEnabled); - SimpleBufferSerializer serializer(memory.get(), kDefaultBufferSize, + SimpleBufferSerializer serializer(memory.get(), kDefaultSerializedBufferSize, options_provider.serialize_options()); serializer.Serialize(buffer);
diff --git a/cc/paint/paint_op_perftest.cc b/cc/paint/paint_op_perftest.cc index 89583a1..699ec58 100644 --- a/cc/paint/paint_op_perftest.cc +++ b/cc/paint/paint_op_perftest.cc
@@ -9,6 +9,7 @@ #include "base/timer/lap_timer.h" #include "cc/paint/paint_op_buffer.h" #include "cc/paint/paint_op_buffer_serializer.h" +#include "cc/paint/paint_op_writer.h" #include "cc/paint/paint_shader.h" #include "cc/test/test_options_provider.h" #include "testing/perf/perf_result_reporter.h" @@ -32,12 +33,8 @@ : timer_(kNumWarmupRuns, base::Milliseconds(kTimeLimitMillis), kTimeCheckInterval), - serialized_data_(static_cast<char*>( - base::AlignedAlloc(kMaxSerializedBufferBytes, - PaintOpBuffer::kPaintOpAlign))), - deserialized_data_(static_cast<char*>( - base::AlignedAlloc(sizeof(LargestPaintOp), - PaintOpBuffer::kPaintOpAlign))) {} + serialized_data_( + PaintOpWriter::AllocateAlignedBuffer(kMaxSerializedBufferBytes)) {} void RunTest(const std::string& name, const PaintOpBuffer& buffer) { TestOptionsProvider test_options_provider; @@ -73,8 +70,8 @@ while (true) { PaintOp* deserialized_op = PaintOp::Deserialize( - to_read, remaining_read_bytes, deserialized_data_.get(), - sizeof(LargestPaintOp), &bytes_read, + to_read, remaining_read_bytes, deserialized_data_, + kLargestPaintOpAlignedSize, &bytes_read, test_options_provider.deserialize_options()); CHECK(deserialized_op); deserialized_op->DestroyThis(); @@ -98,7 +95,8 @@ protected: base::LapTimer timer_; std::unique_ptr<char, base::AlignedFreeDeleter> serialized_data_; - std::unique_ptr<char, base::AlignedFreeDeleter> deserialized_data_; + alignas(PaintOpBuffer::kPaintOpAlign) char deserialized_data_ + [kLargestPaintOpAlignedSize]; }; // Ops that can be memcopied both when serializing and deserializing.
diff --git a/cc/paint/paint_op_reader.cc b/cc/paint/paint_op_reader.cc index 66b63c4..3399ff4 100644 --- a/cc/paint/paint_op_reader.cc +++ b/cc/paint/paint_op_reader.cc
@@ -54,6 +54,18 @@ } // namespace +PaintOpReader::PaintOpReader(const volatile void* memory, + size_t size, + const PaintOp::DeserializeOptions& options, + bool enable_security_constraints) + : memory_(static_cast<const volatile char*>(memory)), + remaining_bytes_( + base::bits::AlignDown(size, PaintOpWriter::kDefaultAlignment)), + options_(options), + enable_security_constraints_(enable_security_constraints) { + PaintOpWriter::AssertAlignment(memory, BufferAlignment()); +} + // static void PaintOpReader::FixupMatrixPostSerialization(SkMatrix* matrix) { // Can't trust malicious clients to provide the correct derived matrix type. @@ -64,25 +76,24 @@ matrix->dirtyMatrixTypeCache(); } -// static -bool PaintOpReader::ReadAndValidateOpHeader(const volatile void* input, - size_t input_size, - uint8_t* type, - size_t* bytes_to_read) { - static_assert(PaintOpWriter::HeaderBytes() == sizeof(uint32_t)); - if (input_size < PaintOpWriter::HeaderBytes()) { +bool PaintOpReader::ReadAndValidateOpHeader(uint8_t* type, + size_t* serialized_size) { + static_assert(PaintOpWriter::kHeaderBytes == sizeof(uint32_t)); + uint32_t header; + Read(&header); + if (!valid_) { return false; } - uint32_t header = reinterpret_cast<const volatile uint32_t*>(input)[0]; *type = static_cast<uint8_t>(header & 0xFF); - *bytes_to_read = header >> 8; + *serialized_size = header >> 8; - if (input_size < *bytes_to_read) { + size_t remaining_op_bytes = *serialized_size - PaintOpWriter::kHeaderBytes; + if (remaining_bytes_ < remaining_op_bytes) { return false; } - // For now we require serialized PaintOps are aligned to kPaintOpAlign. - // TODO(wangxianzhu): Revisit the requirement. - if (*bytes_to_read % PaintOpBuffer::kPaintOpAlign != 0) { + remaining_bytes_ = remaining_op_bytes; + + if (*serialized_size % BufferAlignment() != 0) { return false; } if (*type > static_cast<uint8_t>(PaintOpType::LastPaintOpType)) { @@ -95,10 +106,10 @@ void PaintOpReader::ReadSimple(T* val) { static_assert(std::is_trivially_copyable_v<T>); - DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment())); + AssertFieldAlignment(); // Align everything to 4 bytes, as the writer does. static constexpr size_t size = - base::bits::AlignUp(sizeof(T), PaintOpWriter::Alignment()); + base::bits::AlignUp(sizeof(T), PaintOpWriter::kDefaultAlignment); if (remaining_bytes_ < size) SetInvalid(DeserializationError::kInsufficientRemainingBytes_ReadSimple); @@ -114,6 +125,7 @@ memory_ += size; remaining_bytes_ -= size; + AssertFieldAlignment(); } uint8_t* PaintOpReader::CopyScratchSpace(size_t bytes) { @@ -153,7 +165,7 @@ } void PaintOpReader::ReadData(size_t bytes, void* data) { - DCHECK_EQ(memory_, base::bits::AlignUp(memory_, PaintOpWriter::Alignment())); + AssertFieldAlignment(); if (bytes == 0) return; @@ -167,20 +179,14 @@ } void PaintOpReader::ReadSize(size_t* size) { - AlignMemory(8); - if (!valid_) - return; - uint64_t size64 = 0; - ReadSimple(&size64); - *size = size64; + ReadSimple(size); } void PaintOpReader::Read(SkScalar* data) { ReadSimple(data); } - void - PaintOpReader::Read(uint8_t* data) { +void PaintOpReader::Read(uint8_t* data) { ReadSimple(data); } @@ -319,6 +325,13 @@ case PaintOp::SerializedImageType::kImageData: { SkColorType color_type; Read(&color_type); + // Color types requiring alignment larger than kDefaultAlignment is not + // supported. + if (static_cast<size_t>(SkColorTypeBytesPerPixel(color_type)) > + PaintOpWriter::kDefaultAlignment) { + SetInvalid(DeserializationError::kReadImageFailure); + return; + } uint32_t width; Read(&width); uint32_t height; @@ -477,7 +490,7 @@ } void PaintOpReader::Read(sk_sp<GrSlug>* slug) { - AssertAlignment(PaintOpWriter::Alignment()); + AssertFieldAlignment(); size_t data_bytes = 0u; ReadSize(&data_bytes); @@ -737,6 +750,10 @@ } void PaintOpReader::AlignMemory(size_t alignment) { + DCHECK_GE(alignment, PaintOpWriter::kDefaultAlignment); + DCHECK_LE(alignment, BufferAlignment()); + // base::bits::AlignUp() below will check if alignment is a power of two. + size_t padding = base::bits::AlignUp(memory_, alignment) - memory_; if (padding > remaining_bytes_) SetInvalid(DeserializationError::kInsufficientRemainingBytes_AlignMemory); @@ -794,7 +811,7 @@ crop_rect.emplace(rect); } - AssertAlignment(PaintOpWriter::Alignment()); + AssertFieldAlignment(); switch (type) { case PaintFilter::Type::kNullFilter: NOTREACHED(); @@ -1381,7 +1398,7 @@ size_t PaintOpReader::Read(absl::optional<PaintRecord>* record) { size_t size_bytes = 0; ReadSize(&size_bytes); - AlignMemory(PaintOpBuffer::kPaintOpAlign); + if (enable_security_constraints_) { // Validate that the record was not serialized if security constraints are // enabled. @@ -1393,6 +1410,8 @@ return 0; } + AlignMemory(BufferAlignment()); + if (size_bytes > remaining_bytes_) SetInvalid( DeserializationError::kInsufficientRemainingBytes_Read_PaintRecord); @@ -1429,9 +1448,9 @@ } inline void PaintOpReader::DidRead(size_t bytes_read) { - // All data are aligned with PaintOpWriter::Alignment() at least. + // All data are aligned with PaintOpWriter::kDefaultAlignment at least. size_t aligned_bytes = - base::bits::AlignUp(bytes_read, PaintOpWriter::Alignment()); + base::bits::AlignUp(bytes_read, PaintOpWriter::kDefaultAlignment); memory_ += aligned_bytes; DCHECK_LE(aligned_bytes, remaining_bytes_); remaining_bytes_ -= aligned_bytes;
diff --git a/cc/paint/paint_op_reader.h b/cc/paint/paint_op_reader.h index a4bd656..3bb9a94 100644 --- a/cc/paint/paint_op_reader.h +++ b/cc/paint/paint_op_reader.h
@@ -31,30 +31,22 @@ public: // The DeserializeOptions passed to the reader must set all fields if it can // be used to for deserializing images, paint records or text blobs. + // See PaintOpWriter for the alignment requirement for `memory`. PaintOpReader(const volatile void* memory, size_t size, const PaintOp::DeserializeOptions& options, - bool enable_security_constraints = false) - : memory_(static_cast<const volatile char*>(memory) + - PaintOpWriter::HeaderBytes()), - remaining_bytes_( - base::bits::AlignDown(size, PaintOpWriter::Alignment())), - options_(options), - enable_security_constraints_(enable_security_constraints) { - DCHECK_EQ(memory_, - base::bits::AlignUp(memory_, PaintOpWriter::Alignment())); - if (remaining_bytes_ < PaintOpWriter::HeaderBytes()) { - valid_ = false; - return; - } - remaining_bytes_ -= PaintOpWriter::HeaderBytes(); - } + bool enable_security_constraints = false); static void FixupMatrixPostSerialization(SkMatrix* matrix); - static bool ReadAndValidateOpHeader(const volatile void* input, - size_t input_size, - uint8_t* type, - size_t* bytes_to_read); + + // This should be called before before reading PaintOp data. This function + // should not be called if this PaintOpReader is used to read specific data + // instead of a whole PaintOp. + bool ReadAndValidateOpHeader(uint8_t* op_type, size_t* serialized_size); + + size_t BufferAlignment() const { + return PaintOpWriter::BufferAlignment(enable_security_constraints_); + } bool valid() const { return valid_; } size_t remaining_bytes() const { return remaining_bytes_; } @@ -131,13 +123,13 @@ // would exceed the available budfer. const volatile void* ExtractReadableMemory(size_t bytes); - // Aligns the memory to the given alignment. + // Aligns the memory to the given `alignment` which must be within the range + // of [PaintOpWriter::kDefaultAlignment, BufferAlignment()]. void AlignMemory(size_t alignment); - void AssertAlignment(size_t alignment) { + void AssertFieldAlignment() { #if DCHECK_IS_ON() - uintptr_t memory = reinterpret_cast<uintptr_t>(memory_); - DCHECK_EQ(base::bits::AlignUp(memory, alignment), memory); + PaintOpWriter::AssertAlignment(memory_, PaintOpWriter::kDefaultAlignment); #endif }
diff --git a/cc/paint/paint_op_writer.cc b/cc/paint/paint_op_writer.cc index abe1a30..af2002c 100644 --- a/cc/paint/paint_op_writer.cc +++ b/cc/paint/paint_op_writer.cc
@@ -57,79 +57,91 @@ } // namespace // static -size_t PaintOpWriter::GetFlattenableSize(const SkFlattenable* flattenable) { - // The first bit is always written to indicate the serialized size of the - // flattenable, or zero if it doesn't exist. - size_t total_size = sizeof(uint64_t) + sizeof(uint64_t) /* alignment */; - if (!flattenable) - return total_size; - - // There is no method to know the serialized size of a flattenable without - // serializing it. - sk_sp<SkData> data = flattenable->serialize(); - total_size += data->isEmpty() ? 0u : data->size(); - return total_size; -} - -// static -size_t PaintOpWriter::GetImageSize(const PaintImage& image) { +size_t PaintOpWriter::SerializedSize(const PaintImage& image) { // Image Serialization type. - size_t image_size = sizeof(PaintOp::SerializedImageType); + base::CheckedNumeric<size_t> image_size = + SerializedSize<PaintOp::SerializedImageType>(); if (image) { auto info = SkImageInfo::Make(image.width(), image.height(), kN32_SkColorType, kPremul_SkAlphaType); - image_size += sizeof(info.colorType()); - image_size += sizeof(info.width()); - image_size += sizeof(info.height()); - image_size += sizeof(uint64_t) + sizeof(uint64_t) /* alignment */; - image_size += info.computeMinByteSize(); + image_size += SerializedSize(info.colorType()); + image_size += SerializedSize(info.width()); + image_size += SerializedSize(info.height()); + image_size += SerializedSizeOfBytes(info.computeMinByteSize()); } - return image_size; + return image_size.ValueOrDie(); } // static -size_t PaintOpWriter::GetRecordSize(const PaintRecord* record) { - // Zero size indicates no record. +size_t PaintOpWriter::SerializedSize(const SkFlattenable* flattenable) { + // There is no method to know the serialized size of a flattenable without + // serializing it. + return SerializedSizeOfBytes(flattenable ? flattenable->serialize()->size() + : 0u); +} + +// static +size_t PaintOpWriter::SerializedSize(const SkColorSpace* color_space) { + return SerializedSizeOfBytes(color_space ? color_space->writeToMemory(nullptr) + : 0u); +} + +// static +size_t PaintOpWriter::SerializedSize(const PaintRecord& record) { // TODO(khushalsagar): Querying the size of a PaintRecord is not supported. // This works only for security constrained serialization which ignores - // records. - return sizeof(uint64_t); + // records and writes only a size_t(0). + return SerializedSize<size_t>(); +} + +// static +size_t PaintOpWriter::SerializedSize(const PaintFilter* filter) { + if (!filter) { + return SerializedSize(PaintFilter::Type::kNullFilter); + } + return filter->SerializedSize(); } PaintOpWriter::PaintOpWriter(void* memory, size_t size, const PaintOp::SerializeOptions& options, bool enable_security_constraints) - : memory_(static_cast<char*>(memory) + HeaderBytes()), - size_(base::bits::AlignDown(size, Alignment())), - remaining_bytes_(size_ - HeaderBytes()), + : memory_(static_cast<char*>(memory)), + size_(base::bits::AlignDown(size, kDefaultAlignment)), + remaining_bytes_(size_), options_(options), enable_security_constraints_(enable_security_constraints) { - // Leave space for header of type/skip. - DCHECK_GE(size, HeaderBytes()); - DCHECK_EQ(memory_.get(), base::bits::AlignUp(memory_.get(), Alignment())); + AssertAlignment(memory, BufferAlignment()); } PaintOpWriter::~PaintOpWriter() = default; -size_t PaintOpWriter::Finish(uint8_t type) { +void PaintOpWriter::ReserveOpHeader() { + // Pretend we have written the header to leave a space for the header. + DCHECK_GE(size_, kHeaderBytes); + DidWrite(kHeaderBytes); +} + +size_t PaintOpWriter::FinishOp(uint8_t type) { if (!valid_) { return 0u; } size_t written = size(); - DCHECK_GE(written, HeaderBytes()); + DCHECK_GE(written, kHeaderBytes); - size_t aligned_written = - base::bits::AlignUp(written, PaintOpBuffer::kPaintOpAlign); - if (aligned_written > kMaxSerializedSize || - aligned_written - written > remaining_bytes_) { + size_t aligned_written = base::bits::AlignUp(written, BufferAlignment()); + size_t padding = aligned_written - written; + if (aligned_written > kMaxSerializedSize || padding > remaining_bytes_) { valid_ = false; return 0u; } // Write type and skip into the header bytes. WriteHeader(memory_.get() - written, type, aligned_written); + + memory_ += padding; + remaining_bytes_ -= padding; return aligned_written; } @@ -143,8 +155,9 @@ void PaintOpWriter::WriteSimple(const T& val) { static_assert(std::is_trivially_copyable_v<T>); - DCHECK_EQ(memory_.get(), base::bits::AlignUp(memory_.get(), Alignment())); - static constexpr size_t size = base::bits::AlignUp(sizeof(T), Alignment()); + AssertFieldAlignment(); + static constexpr size_t size = + base::bits::AlignUp(sizeof(T), kDefaultAlignment); EnsureBytes(size); if (!valid_) return; @@ -153,19 +166,21 @@ memory_ += size; remaining_bytes_ -= size; + AssertFieldAlignment(); } + void PaintOpWriter::WriteFlattenable(const SkFlattenable* val) { if (!val) { WriteSize(static_cast<size_t>(0u)); return; } - uint64_t* size_memory = WriteSize(0u); + size_t* size_memory = WriteSize(0u); if (!valid_) return; size_t bytes_written = val->serialize( - memory_, base::bits::AlignDown(remaining_bytes_, Alignment())); + memory_, base::bits::AlignDown(remaining_bytes_, kDefaultAlignment)); if (bytes_written == 0u) { valid_ = false; return; @@ -174,10 +189,9 @@ DidWrite(bytes_written); } -uint64_t* PaintOpWriter::WriteSize(size_t size) { - AlignMemory(8); - uint64_t* memory = reinterpret_cast<uint64_t*>(memory_.get()); - WriteSimple<uint64_t>(size); +size_t* PaintOpWriter::WriteSize(size_t size) { + size_t* memory = reinterpret_cast<size_t*>(memory_.get()); + WriteSimple(size); return memory; } @@ -242,7 +256,7 @@ } else { Write(static_cast<uint32_t>(PaintCacheEntryState::kInlinedDoNotCache)); } - uint64_t* bytes_to_skip = WriteSize(0u); + size_t* bytes_to_skip = WriteSize(0u); if (!valid_) return; @@ -284,7 +298,7 @@ const PaintImage& paint_image = draw_image.paint_image(); // Empty image. - if (!draw_image.paint_image()) { + if (!paint_image) { Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kNoImage)); return; } @@ -296,13 +310,19 @@ // Security constrained serialization inlines the image bitmap. if (enable_security_constraints_) { SkBitmap bm; - if (!draw_image.paint_image().GetSwSkImage()->asLegacyBitmap(&bm)) { + if (!paint_image.GetSwSkImage()->asLegacyBitmap(&bm)) { Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kNoImage)); return; } Write(static_cast<uint8_t>(PaintOp::SerializedImageType::kImageData)); const auto& pixmap = bm.pixmap(); + // Pixmaps requiring alignments larger than kDefaultAlignment [1] are not + // supported because the buffer is only guaranteed to align to + // kDefaultAlignment when enable_security_constraits_ is true. + // [1] See https://crbug.com/1300188 and https://crrev.com/c/3485859. + DCHECK_LE(static_cast<size_t>(SkColorTypeBytesPerPixel(pixmap.colorType())), + kDefaultAlignment); Write(pixmap.colorType()); Write(pixmap.width()); Write(pixmap.height()); @@ -329,7 +349,7 @@ uint32_t id = skottie->id(); Write(id); - uint64_t* bytes_to_skip = WriteSize(0u); + size_t* bytes_to_skip = WriteSize(0u); if (!valid_) return; @@ -337,7 +357,7 @@ options_->transfer_cache->LockEntry(TransferCacheEntryType::kSkottie, id); // Add a cache entry for the skottie animation. - uint64_t bytes_written = 0u; + size_t bytes_written = 0u; if (!locked) { bytes_written = options_->transfer_cache->CreateEntry( ClientSkottieTransferCacheEntry(skottie), memory_); @@ -432,8 +452,8 @@ if (!valid_) return; - AssertAlignment(Alignment()); - uint64_t* size_memory = WriteSize(0u); + AssertFieldAlignment(); + size_t* size_memory = WriteSize(0u); if (!valid_) return; @@ -442,7 +462,7 @@ // TODO(penghuang): should we use a unique id to avoid sending the same // slug? bytes_written = slug->serialize( - memory_, base::bits::AlignDown(remaining_bytes_, Alignment())); + memory_, base::bits::AlignDown(remaining_bytes_, kDefaultAlignment)); if (bytes_written == 0u) { valid_ = false; return; @@ -599,30 +619,28 @@ } void PaintOpWriter::WriteData(size_t bytes, const void* input) { - DCHECK_EQ(memory_.get(), - base::bits::AlignUp(memory_.get(), PaintOpWriter::Alignment())); - if (bytes == 0) + AssertFieldAlignment(); + + if (bytes == 0) { return; + } EnsureBytes(bytes); - if (!valid_) + if (!valid_) { return; + } memcpy(memory_, input, bytes); DidWrite(bytes); } void PaintOpWriter::AlignMemory(size_t alignment) { - // Due to the math below, alignment must be a power of two. - DCHECK_GT(alignment, 0u); - DCHECK_EQ(alignment & (alignment - 1), 0u); + DCHECK_GE(alignment, kDefaultAlignment); + DCHECK_LE(alignment, BufferAlignment()); + // base::bits::AlignUp() below will check if alignment is a power of two. uintptr_t memory = reinterpret_cast<uintptr_t>(memory_.get()); - // The following is equivalent to: - // padding = (alignment - memory % alignment) % alignment; - // because alignment is a power of two. This doesn't use modulo operator - // however, since it can be slow. size_t padding = base::bits::AlignUp(memory, alignment) - memory; EnsureBytes(padding); if (!valid_) @@ -647,7 +665,7 @@ if (!valid_) return; - AssertAlignment(Alignment()); + AssertFieldAlignment(); switch (filter->type()) { case PaintFilter::Type::kNullFilter: NOTREACHED(); @@ -950,17 +968,10 @@ void PaintOpWriter::Write(const PaintRecord& record, const gfx::Rect& playback_rect, const gfx::SizeF& post_scale) { - AlignMemory(PaintOpBuffer::kPaintOpAlign); - // We need to record how many bytes we will serialize, but we don't know this - // information until we do the serialization. So, skip the amount needed - // before writing. - size_t size_offset = sizeof(uint64_t); - EnsureBytes(size_offset); - if (!valid_) - return; - - uint64_t* size_memory = WriteSize(0u); + // information until we do the serialization. So, write 0 as the size first, + // and amend it after writing. + size_t* size_memory = WriteSize(0u); if (!valid_) return; @@ -969,6 +980,8 @@ return; } + AlignMemory(BufferAlignment()); + // Nested records are used for picture shaders and filters. These are always // converted to a fixed scale mode (hence |post_scale|), which means they are // first rendered offscreen via SkImage::MakeFromPicture. This inherently does @@ -1009,8 +1022,8 @@ } inline void PaintOpWriter::DidWrite(size_t bytes_written) { - // All data are aligned with PaintOpWriter::Alignment() at least. - size_t aligned_bytes = base::bits::AlignUp(bytes_written, Alignment()); + // All data are aligned with kDefaultAlignment at least. + size_t aligned_bytes = base::bits::AlignUp(bytes_written, kDefaultAlignment); memory_ += aligned_bytes; DCHECK_LE(aligned_bytes, remaining_bytes_); remaining_bytes_ -= aligned_bytes;
diff --git a/cc/paint/paint_op_writer.h b/cc/paint/paint_op_writer.h index 920df172..d1de951 100644 --- a/cc/paint/paint_op_writer.h +++ b/cc/paint/paint_op_writer.h
@@ -5,9 +5,13 @@ #ifndef CC_PAINT_PAINT_OP_WRITER_H_ #define CC_PAINT_PAINT_OP_WRITER_H_ +#include <memory> + #include "base/bits.h" +#include "base/memory/aligned_memory.h" #include "base/memory/raw_ptr.h" #include "base/memory/raw_ref.h" +#include "base/numerics/checked_math.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_export.h" #include "cc/paint/paint_filter.h" @@ -33,36 +37,127 @@ public: // The SerializeOptions passed to the writer must set the required fields // if it can be used for serializing images, paint records or text blobs. + // If `enable_security_constraints` is false, `memory` must be aligned to + // kMaxAlignment, and AllocateAlignedBuffer() is the preferred way to + // allocate `memory`. Otherwise `memory` can be allocated in any way that can + // ensure kDefaultAlignment. See BufferAlignment() for more details. + // If `size` is not enough to contain serialized data, the buffer won't + // overflow, but Write() will be silent no-ops. PaintOpWriter(void* memory, size_t size, const PaintOp::SerializeOptions& options, bool enable_security_constraints = false); ~PaintOpWriter(); + static std::unique_ptr<char, base::AlignedFreeDeleter> AllocateAlignedBuffer( + size_t size) { + return std::unique_ptr<char, base::AlignedFreeDeleter>( + static_cast<char*>(base::AlignedAlloc(size, kMaxAlignment))); + } + const PaintOp::SerializeOptions& options() const { return *options_; } - // Type and serialized_size fit in HeaderBytes, using 1 byte and 3 bytes, + // Type and serialized_size fit in kHeaderBytes, using 1 byte and 3 bytes, // respectively. Note that serialized_size in the header is different from // PaintOp::aligned_size because serialized data may have different byte // format and serialization of reference data fields may be make // serialized_size much bigger than PaintOp::aligned_size. - static size_t constexpr HeaderBytes() { return sizeof(uint32_t); } + static constexpr size_t kHeaderBytes = sizeof(uint32_t); static constexpr size_t kMaxSerializedSize = (1u << 24) - 1; - // Round up each field to 4 bytes. This is not technically perfect alignment, - // but it is about 30% faster to post-align each write to 4 bytes than it is - // to pre-align memory to the correct alignment. - // The whole serialized PaintOp is aligned to PaintOpBuffer::kPaintOpAlign. - // TODO(wangxianzhu): Revisit the kPaintOpAlign requirement for serialization. - static size_t constexpr Alignment() { return alignof(uint32_t); } + // The start/end of the buffer for a serialized PaintOp must be aligned to + // BufferAlignment() which is the maximum alignment of all serialized fields, + // to ensure the alignment padding of any field to be constant. + // + // When enable_security_constraints is true, we won't serialize PaintRecords + // or images that require alignments greater than kDefaultAlignment. We can't + // require larger alignment because the buffer may be a part of another + // buffer (e.g. mojom data) for which the caller can't control the alignment. + // + // When enable_security_constraints is false, the alignment is 16 which is + // the maximum alignment requirement of particular types of pixmaps (see + // image_transfer_data_cache.cc). + static constexpr size_t BufferAlignment(bool enable_security_constraints) { + return enable_security_constraints ? kDefaultAlignment : kMaxAlignment; + } + static constexpr size_t kMaxAlignment = 16; + size_t BufferAlignment() const { + return BufferAlignment(enable_security_constraints_); + } - static size_t GetFlattenableSize(const SkFlattenable* flattenable); - static size_t GetImageSize(const PaintImage& image); - static size_t GetRecordSize(const PaintRecord* record); + // Round up each field to 4 bytes by default. This is not technically perfect + // alignment, but it is about 30% faster to post-align each write to 4 bytes + // than it is to pre-align memory to the correct alignment. + // A field can also use a larger alignment by calling AlignMemory(). + static constexpr size_t kDefaultAlignment = alignof(uint32_t); - // Called after serializing data of a PaintOp. Returns the serialized size - // of the PaintOp aligned to PaintOpBuffer::kPaintOpAlign, or 0 on any errors. - size_t Finish(uint8_t type); + // SerializedSize() returns the maximum serialized size of the given type or + // the given parameter. For a buffer to contain serialization of multiple + // data, the size can be the accumulated results of SerializedSize() of each + // data. + template <typename T> + static constexpr size_t SerializedSize() { + static_assert(std::is_arithmetic_v<T> || std::is_enum_v<T>); + return base::bits::AlignUp(sizeof(T), kDefaultAlignment); + } + template <typename T> + static constexpr size_t SerializedSize(const T& data) { + static_assert(!std::is_pointer_v<T>); + return base::bits::AlignUp(sizeof(T), kDefaultAlignment); + } + static size_t SerializedSize(const PaintImage& image); + static size_t SerializedSize(const PaintRecord& record); + + // Serialization of raw/smart pointers is not supported by default. + template <typename T> + static inline size_t SerializedSize(const T* p); + template <typename T> + static inline size_t SerializedSize(const std::unique_ptr<T>& p); + template <typename T> + static inline size_t SerializedSize(const scoped_refptr<T>& p); + template <typename T> + static inline size_t SerializedSize(const raw_ptr<T>& p); + + template <typename T> + static inline size_t SerializedSize(T* p) { + return SerializedSize(static_cast<const T*>(p)); + } + static size_t SerializedSize(const SkFlattenable* flattenable); + static size_t SerializedSize(const SkColorSpace* color_space); + static size_t SerializedSize(const PaintFilter* filter); + + template <typename T> + static size_t SerializedSize(const absl::optional<T>& o) { + if (o) { + return (base::CheckedNumeric<size_t>(SerializedSize<bool>()) + + SerializedSize<T>(*o)) + .ValueOrDie(); + } + return SerializedSize<bool>(); + } + + // Size of serialized (size_t, bytes). + static size_t SerializedSizeOfBytes(size_t num_bytes) { + return (base::CheckedNumeric<size_t>(SerializedSize<size_t>()) + + base::bits::AlignUp(num_bytes, kDefaultAlignment)) + .ValueOrDie(); + } + // Size of serialized (size_t, elements> + template <typename T> + static size_t SerializedSizeOfElements(const T* elements, size_t count) { + return (SerializedSize<size_t>() + + base::CheckedNumeric<size_t>(count) * SerializedSize(*elements)) + .ValueOrDie(); + } + + // These two functions should be called before and after (respectively) + // serializing the data of a PaintOp. These functions should not be called + // if this PaintOpWriter is used to write specific data instead of a whole + // PaintOp. + void ReserveOpHeader(); + // Returns the serialized size (aligned to BufferAlignment()) of the PaintOp, + // or 0 on any errors. + size_t FinishOp(uint8_t type); static void WriteHeaderForTesting(void* memory, uint8_t type, @@ -71,9 +166,11 @@ // Write a sequence of arbitrary bytes. void WriteData(size_t bytes, const void* input); + // Returns the size of successfully written data, including paddings for + // alignment. size_t size() const { return valid_ ? size_ - remaining_bytes_ : 0u; } - uint64_t* WriteSize(size_t size); + size_t* WriteSize(size_t size); void Write(SkScalar data); void Write(SkMatrix data); @@ -120,13 +217,19 @@ void Write(bool data) { Write(static_cast<uint8_t>(data)); } - // Aligns the memory to the given alignment. + // Aligns the memory to the given `alignment` which must be within the range + // of [kDefaultAlignment, BufferAlignment()]. void AlignMemory(size_t alignment); - void AssertAlignment(size_t alignment) { + static void AssertAlignment(const volatile void* memory, size_t alignment) { #if DCHECK_IS_ON() - uintptr_t memory = reinterpret_cast<uintptr_t>(memory_.get()); - DCHECK_EQ(base::bits::AlignUp(memory, alignment), memory); + uintptr_t uintptr = reinterpret_cast<uintptr_t>(memory); + DCHECK_EQ(uintptr, base::bits::AlignUp(uintptr, alignment)); +#endif + } + void AssertFieldAlignment() { +#if DCHECK_IS_ON() + AssertAlignment(memory_.get(), kDefaultAlignment); #endif }
diff --git a/cc/paint/paint_shader.cc b/cc/paint/paint_shader.cc index da505ef..a23ba7a 100644 --- a/cc/paint/paint_shader.cc +++ b/cc/paint/paint_shader.cc
@@ -4,10 +4,12 @@ #include "cc/paint/paint_shader.h" +#include <algorithm> #include <utility> #include "base/atomic_sequence_num.h" #include "base/notreached.h" +#include "base/numerics/checked_math.h" #include "base/types/optional_util.h" #include "cc/paint/image_provider.h" #include "cc/paint/paint_image_builder.h" @@ -219,26 +221,35 @@ // static size_t PaintShader::GetSerializedSize(const PaintShader* shader) { - size_t bool_size = sizeof(bool); - if (!shader) - return bool_size; + if (!shader) { + return PaintOpWriter::SerializedSize<bool>(); + } - return bool_size + sizeof(shader->shader_type_) + sizeof(shader->flags_) + - sizeof(shader->end_radius_) + sizeof(shader->start_radius_) + - sizeof(shader->tx_) + sizeof(shader->ty_) + - sizeof(shader->fallback_color_) + sizeof(shader->scaling_behavior_) + - bool_size + sizeof(*shader->local_matrix_) + sizeof(shader->center_) + - sizeof(shader->tile_) + sizeof(shader->start_point_) + - sizeof(shader->end_point_) + sizeof(shader->start_degrees_) + - sizeof(shader->end_degrees_) + - PaintOpWriter::GetImageSize(shader->image_) + - PaintOpWriter::GetImageSize(shader->image_) + bool_size + - sizeof(shader->id_) + - PaintOpWriter::GetRecordSize(shader->paint_record()) + - sizeof(shader->colors_.size()) + - shader->colors_.size() * sizeof(SkColor4f) + - sizeof(shader->positions_.size()) + - shader->positions_.size() * sizeof(SkScalar); + return (base::CheckedNumeric<size_t>(PaintOpWriter::SerializedSize<bool>()) + + PaintOpWriter::SerializedSize(shader->shader_type_) + + PaintOpWriter::SerializedSize(shader->flags_) + + PaintOpWriter::SerializedSize(shader->end_radius_) + + PaintOpWriter::SerializedSize(shader->start_radius_) + + PaintOpWriter::SerializedSize(shader->tx_) + + PaintOpWriter::SerializedSize(shader->ty_) + + PaintOpWriter::SerializedSize(shader->fallback_color_) + + PaintOpWriter::SerializedSize(shader->scaling_behavior_) + + PaintOpWriter::SerializedSize(shader->local_matrix_) + + PaintOpWriter::SerializedSize(shader->center_) + + PaintOpWriter::SerializedSize(shader->tile_) + + PaintOpWriter::SerializedSize(shader->start_point_) + + PaintOpWriter::SerializedSize(shader->end_point_) + + PaintOpWriter::SerializedSize(shader->start_degrees_) + + PaintOpWriter::SerializedSize(shader->end_degrees_) + + PaintOpWriter::SerializedSize(shader->gradient_interpolation_) + + PaintOpWriter::SerializedSize(shader->image_) + + PaintOpWriter::SerializedSize(shader->id_) + + PaintOpWriter::SerializedSize(shader->record_) + + PaintOpWriter::SerializedSizeOfElements(shader->colors_.data(), + shader->colors_.size()) + + PaintOpWriter::SerializedSizeOfElements(shader->positions_.data(), + shader->positions_.size())) + .ValueOrDie(); } PaintShader::PaintShader(Type type) : shader_type_(type) {}
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/MostVisitedSuggestionsUiDelegate.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/MostVisitedSuggestionsUiDelegate.java new file mode 100644 index 0000000..7a3f290 --- /dev/null +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/MostVisitedSuggestionsUiDelegate.java
@@ -0,0 +1,31 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.chrome.features.start_surface; + +import android.view.View; + +import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate; +import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; +import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; + +/** Suggestions UI Delegate for constructing the TileGroup. */ +public class MostVisitedSuggestionsUiDelegate extends SuggestionsUiDelegateImpl { + private final View mView; + + public MostVisitedSuggestionsUiDelegate(View view, + SuggestionsNavigationDelegate navigationDelegate, Profile profile, + SnackbarManager snackbarManager) { + super(navigationDelegate, profile, /*host=*/null, snackbarManager); + mView = view; + } + + @Override + public boolean isVisible() { + return mView.getVisibility() == View.VISIBLE + && mView.findViewById(org.chromium.chrome.R.id.mv_tiles_layout).getVisibility() + == View.VISIBLE; + } +} \ No newline at end of file
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinder.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinder.java index 0811b3c..9c70343 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinder.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinder.java
@@ -16,8 +16,8 @@ /** The binder controls the display of the secondary {@link TasksView} in its parent. */ class SecondaryTasksSurfaceViewBinder { - public static void bind(PropertyModel model, TasksSurfaceViewBinder.ViewHolder viewHolder, - PropertyKey propertyKey) { + public static void bind(PropertyModel model, + StartSurfaceWithParentViewBinder.ViewHolder viewHolder, PropertyKey propertyKey) { if (IS_SECONDARY_SURFACE_VISIBLE == propertyKey) { updateVisibility(viewHolder, model); } else if (TOP_MARGIN == propertyKey) { @@ -28,7 +28,7 @@ } private static void updateVisibility( - TasksSurfaceViewBinder.ViewHolder viewHolder, PropertyModel model) { + StartSurfaceWithParentViewBinder.ViewHolder viewHolder, PropertyModel model) { boolean isShowing = model.get(IS_SECONDARY_SURFACE_VISIBLE); if (isShowing && viewHolder.tasksSurfaceView.getParent() == null) { viewHolder.parentView.addView(viewHolder.tasksSurfaceView); @@ -42,13 +42,14 @@ } private static void bringSurfaceToFront( - TasksSurfaceViewBinder.ViewHolder viewHolder, PropertyModel model) { + StartSurfaceWithParentViewBinder.ViewHolder viewHolder, PropertyModel model) { if (model.get(IS_SECONDARY_SURFACE_VISIBLE)) { viewHolder.tasksSurfaceView.bringToFront(); } } - private static void setTopMargin(TasksSurfaceViewBinder.ViewHolder viewHolder, int topMargin) { + private static void setTopMargin( + StartSurfaceWithParentViewBinder.ViewHolder viewHolder, int topMargin) { MarginLayoutParams layoutParams = (MarginLayoutParams) viewHolder.tasksSurfaceView.getLayoutParams(); if (layoutParams == null) return;
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurface.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurface.java index aaa318f..30831eb 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurface.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurface.java
@@ -17,7 +17,7 @@ import org.chromium.chrome.browser.ntp.NewTabPageLaunchOrigin; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcherCustomViewManager; -import org.chromium.chrome.features.tasks.TasksSurface; +import org.chromium.chrome.features.tasks.TasksView; /** Interface to communicate with the start surface. */ public interface StartSurface { @@ -162,7 +162,8 @@ * Show the overview. * @param animate Whether we should animate while showing. */ - // TODO(crbug.com/1315676): Decouple Start surface layout and Grid tab switcher layout. + // TODO(crbug.com/1315676): Rename this function once the Start surface layout and Grid tab + // switcher layout are decoupled. void showOverview(boolean animate); /** @@ -255,6 +256,7 @@ * carousel/single tab switcher when start surface is enabled; when start surface is disabled, * null should be returned. */ + // TODO(crbug.com/1315676): Remove this API after the refactoring is done. TabSwitcher.TabListDelegate getCarouselOrSingleTabListDelegate(); /** @@ -272,11 +274,11 @@ boolean isOverviewShownOnStartup, final long activityCreationTimeMs); /** - * Returns the primary {@link TasksSurface} (omnibox, most visited, feed, etc.). Can be null if + * Returns the primary {@link TasksView} (omnibox, most visited, feed, etc.). Can be null if * grid tab switcher is enabled but Start surface is disabled. */ @Nullable - TasksSurface getPrimaryTasksSurface(); + TasksView getPrimarySurfaceView(); /** * TODO(crbug.com/1315676): Remove this API after the bug is resolved.
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java index ba824cc..4dcebf1 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java
@@ -7,6 +7,7 @@ import android.app.Activity; import android.os.SystemClock; import android.text.TextUtils; +import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -24,6 +25,7 @@ import org.chromium.base.MathUtils; import org.chromium.base.ObserverList; import org.chromium.base.jank_tracker.JankTracker; +import org.chromium.base.library_loader.LibraryLoader; import org.chromium.base.metrics.RecordHistogram; import org.chromium.base.supplier.ObservableSupplier; import org.chromium.base.supplier.ObservableSupplierImpl; @@ -45,9 +47,16 @@ import org.chromium.chrome.browser.multiwindow.MultiWindowModeStateDispatcher; import org.chromium.chrome.browser.omnibox.OmniboxStub; import org.chromium.chrome.browser.omnibox.SearchEngineLogoUtils; +import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; +import org.chromium.chrome.browser.preferences.SharedPreferencesManager; +import org.chromium.chrome.browser.profiles.OriginalProfileSupplier; import org.chromium.chrome.browser.profiles.Profile; +import org.chromium.chrome.browser.profiles.ProfileManager; +import org.chromium.chrome.browser.query_tiles.QueryTileSection; +import org.chromium.chrome.browser.query_tiles.QueryTileUtils; import org.chromium.chrome.browser.share.ShareDelegate; import org.chromium.chrome.browser.share.crow.CrowButtonDelegate; +import org.chromium.chrome.browser.suggestions.tile.MostVisitedTilesCoordinator; import org.chromium.chrome.browser.suggestions.tile.TileGroupDelegateImpl; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tabmodel.TabCreatorManager; @@ -57,15 +66,22 @@ import org.chromium.chrome.browser.tasks.tab_management.TabManagementModuleProvider; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcherCustomViewManager; +import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.toolbar.top.Toolbar; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; +import org.chromium.chrome.browser.util.BrowserUiUtils; +import org.chromium.chrome.features.tasks.MostVisitedTileNavigationDelegate; +import org.chromium.chrome.features.tasks.SingleTabSwitcherCoordinator; import org.chromium.chrome.features.tasks.TasksSurface; import org.chromium.chrome.features.tasks.TasksSurfaceCoordinator; import org.chromium.chrome.features.tasks.TasksSurfaceProperties; +import org.chromium.chrome.features.tasks.TasksView; +import org.chromium.chrome.features.tasks.TasksViewBinder; import org.chromium.components.browser_ui.bottomsheet.BottomSheetController; import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; import org.chromium.components.user_prefs.UserPrefs; +import org.chromium.ui.base.DeviceFormFactor; import org.chromium.ui.base.ViewUtils; import org.chromium.ui.base.WindowAndroid; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -76,6 +92,7 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** * Root coordinator that is responsible for showing start surfaces, like a grid of Tabs, explore @@ -113,6 +130,7 @@ @VisibleForTesting static final String START_SHOWN_AT_STARTUP_UMA = "Startup.Android.StartSurfaceShownAtStartup"; private static final String TAG = "StartSurface"; + private static final int MAX_TILE_ROWS_FOR_GRID_MVT = 2; // Non-null in SurfaceMode.SINGLE_PANE mode. @Nullable @@ -122,6 +140,9 @@ @Nullable private PropertyModelChangeProcessor mTasksSurfacePropertyModelChangeProcessor; + private PropertyModelChangeProcessor mStartSurfaceWithParentViewPropertyModelChangeProcessor; + private PropertyModelChangeProcessor mStartSurfacePropertyModelChangeProcessor; + // TODO(crbug.com/1315676): Remove this once the start surface refactoring is done, since the // secondary tasks surface will go away. // Non-null in SurfaceMode.SINGLE_PANE mode to show more tabs. @@ -134,7 +155,7 @@ // Non-null in SurfaceMode.NO_START_SURFACE to show the tabs. @Nullable - private TabSwitcher mTabSwitcher; + private TabSwitcher mGridTabSwitcher; // Non-null in SurfaceMode.SINGLE_PANE modes. @Nullable @@ -176,6 +197,21 @@ @Nullable private FeedSwipeRefreshLayout mSwipeRefreshLayout; + // The single or carousel Tab switcher module on the Start surface. + // None-null when the Start surface refactoring is enabled. + @Nullable + private TabSwitcher mTabSwitcherModule; + // The view of Start surface layout. + // None-null when the Start surface refactoring is enabled. + @Nullable + private TasksView mView; + private MostVisitedTilesCoordinator mMostVisitedCoordinator; + private MostVisitedSuggestionsUiDelegate mSuggestionsUiDelegate; + private TileGroupDelegateImpl mTileGroupDelegate; + private OneshotSupplier<Profile> mQueryTileProfileSupplier; + private QueryTileSection mQueryTileSection; + private boolean mIsMVTilesInitialized; + private class ScrollableContainerDelegateImpl implements ScrollableContainerDelegate { @Override public void addScrollListener(ScrollListener listener) { @@ -290,42 +326,51 @@ || !ChromeFeatureList.sQueryTilesOnStart.isEnabled(); mIsStartSurfaceRefactorEnabled = ReturnToChromeUtil.isStartSurfaceRefactorEnabled(mActivity); + TabSwitcher.Controller controller; + Runnable initializeMVTilesRunnable = null; + View logoContainerView = null; + ViewGroup feedPlaceholderParentView = null; if (!mIsStartSurfaceEnabled && !mIsStartSurfaceRefactorEnabled) { // Create Tab switcher directly to save one layer in the view hierarchy. - mTabSwitcher = TabManagementModuleProvider.getDelegate().createGridTabSwitcher(activity, - activityLifecycleDispatcher, tabModelSelector, tabContentManager, + mGridTabSwitcher = TabManagementModuleProvider.getDelegate().createGridTabSwitcher( + activity, activityLifecycleDispatcher, tabModelSelector, tabContentManager, browserControlsManager, tabCreatorManager, menuOrKeyboardActionController, containerView, shareDelegateSupplier, multiWindowModeStateDispatcher, scrimCoordinator, /* rootView= */ containerView, dynamicResourceLoaderSupplier, snackbarManager, modalDialogManager, incognitoReauthControllerSupplier, backPressManager); mTabSwitcherCustomViewManagerSupplier.set( - mTabSwitcher.getTabSwitcherCustomViewManager()); - } else { + mGridTabSwitcher.getTabSwitcherCustomViewManager()); + controller = mGridTabSwitcher.getController(); + } else if (!mIsStartSurfaceRefactorEnabled) { + assert mIsStartSurfaceEnabled; + // createSwipeRefreshLayout has to be called before creating any surface. createSwipeRefreshLayout(); createAndSetStartSurface(excludeQueryTiles); - } + controller = mTasksSurface.getController(); + initializeMVTilesRunnable = mTasksSurface::initializeMVTiles; + logoContainerView = mTasksSurface.getView().findViewById(R.id.logo_container); + feedPlaceholderParentView = mTasksSurface.getBodyViewContainer(); + } else { + assert mIsStartSurfaceEnabled && mIsStartSurfaceRefactorEnabled; - TabSwitcher.Controller controller = - mTabSwitcher != null ? mTabSwitcher.getController() : mTasksSurface.getController(); - Runnable initializeMVTilesRunnable = - mTasksSurface == null ? null : mTasksSurface::initializeMVTiles; - View logoContainerView = mTasksSurface == null - ? null - : mTasksSurface.getView().findViewById(R.id.logo_container); - ViewGroup feedPlaceholderParentView = - mTasksSurface == null ? null : mTasksSurface.getBodyViewContainer(); + // createSwipeRefreshLayout has to be called before creating any surface. + createSwipeRefreshLayout(); + createStartSurfaceWithoutTasksSurface(excludeQueryTiles); + controller = mTabSwitcherModule.getController(); + initializeMVTilesRunnable = this::initializeMVTiles; + logoContainerView = mView.findViewById(R.id.logo_container); + feedPlaceholderParentView = mView.findViewById(R.id.tasks_surface_body); + } mStartSurfaceMediator = new StartSurfaceMediator(controller, containerView, - mTabModelSelector, mPropertyModel, - mIsStartSurfaceEnabled && !mIsStartSurfaceRefactorEnabled - ? this::initializeSecondaryTasksSurface - : null, + mTabSwitcherModule, mTabModelSelector, mPropertyModel, + mTasksSurface != null ? this::initializeSecondaryTasksSurface : null, mIsStartSurfaceEnabled, mActivity, mBrowserControlsManager, this::isActivityFinishingOrDestroyed, excludeQueryTiles, startSurfaceOneshotSupplier, hadWarmStart, jankTracker, initializeMVTilesRunnable, mParentTabSupplier, logoContainerView, - mTabSwitcher == null ? backPressManager : null, feedPlaceholderParentView, + mGridTabSwitcher == null ? backPressManager : null, feedPlaceholderParentView, mActivityLifecycleDispatcher, tabSwitcherClickHandler); startSurfaceOneshotSupplier.set(this); @@ -370,8 +415,20 @@ assert !mIsStartSurfaceRefactorEnabled; mSecondaryTasksSurface.onHide(); } + if (mSuggestionsUiDelegate != null) { + mSuggestionsUiDelegate.onDestroy(); + mSuggestionsUiDelegate = null; + } + if (mTileGroupDelegate != null) { + mTileGroupDelegate.destroy(); + mTileGroupDelegate = null; + } + if (mMostVisitedCoordinator != null) { + mMostVisitedCoordinator.destroyMvtiles(); + mIsMVTilesInitialized = false; + } } - mStartSurfaceMediator.maybeDestroyFeedPlaceholder(); + mStartSurfaceMediator.onHide(); } @Override @@ -392,6 +449,8 @@ // TODO (crbug.com/1113852): Add a header offset change listener for incognito homepage. if (mTasksSurface != null) { mTasksSurface.addHeaderOffsetChangeListener(onOffsetChangedListener); + } else if (mView != null) { + mView.addHeaderOffsetChangeListener(onOffsetChangedListener); } } @@ -400,6 +459,8 @@ AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { if (mTasksSurface != null) { mTasksSurface.removeHeaderOffsetChangeListener(onOffsetChangedListener); + } else if (mView != null) { + mView.removeHeaderOffsetChangeListener(onOffsetChangedListener); } } @@ -418,8 +479,10 @@ mStartSurfaceMediator.setOnTabSelectingListener(listener); if (mTasksSurface != null) { mTasksSurface.setOnTabSelectingListener(mStartSurfaceMediator); + } else if (mGridTabSwitcher != null) { + mGridTabSwitcher.setOnTabSelectingListener(mStartSurfaceMediator); } else { - mTabSwitcher.setOnTabSelectingListener(mStartSurfaceMediator); + mTabSwitcherModule.setOnTabSelectingListener(mStartSurfaceMediator); } if (mIsStartSurfaceRefactorEnabled) return; @@ -441,19 +504,21 @@ mIsInitializedWithNative = true; if (mIsStartSurfaceEnabled) { + ViewGroup parentView = mView != null ? mView.getBodyViewContainer() + : mTasksSurface.getBodyViewContainer(); mExploreSurfaceCoordinatorFactory = new ExploreSurfaceCoordinatorFactory(mActivity, - mTasksSurface.getBodyViewContainer(), mPropertyModel, mBottomSheetController, - mParentTabSupplier, new ScrollableContainerDelegateImpl(), mSnackbarManager, - mShareDelegateSupplier, mWindowAndroid, mTabModelSelector, mToolbarSupplier, - mConstructedTimeNs, mSwipeRefreshLayout, mCrowButtonDelegate); + parentView, mPropertyModel, mBottomSheetController, mParentTabSupplier, + new ScrollableContainerDelegateImpl(), mSnackbarManager, mShareDelegateSupplier, + mWindowAndroid, mTabModelSelector, mToolbarSupplier, mConstructedTimeNs, + mSwipeRefreshLayout, mCrowButtonDelegate); } mStartSurfaceMediator.initWithNative( mIsStartSurfaceEnabled ? mOmniboxStubSupplier.get() : null, mExploreSurfaceCoordinatorFactory, UserPrefs.get(Profile.getLastUsedRegularProfile()), mSnackbarManager); - if (mTabSwitcher != null) { - mTabSwitcher.initWithNative(); + if (mGridTabSwitcher != null) { + mGridTabSwitcher.initWithNative(); } if (mTasksSurface != null) { mTasksSurface.onFinishNativeInitialization(mActivity, mOmniboxStubSupplier.get(), @@ -538,8 +603,8 @@ @Override public boolean onBackPressed() { - if (mTabSwitcher != null) { - return mTabSwitcher.onBackPressed(); + if (mGridTabSwitcher != null) { + return mGridTabSwitcher.onBackPressed(); } return mStartSurfaceMediator.onBackPressed(); } @@ -587,15 +652,20 @@ } return mSecondaryTasksSurface.getTabListDelegate(); } else { - return mTabSwitcher.getTabListDelegate(); + return mGridTabSwitcher.getTabListDelegate(); } } @Override public TabSwitcher.TabListDelegate getCarouselOrSingleTabListDelegate() { if (mIsStartSurfaceEnabled) { - assert mTasksSurface != null; - return mTasksSurface.getTabListDelegate(); + if (mIsStartSurfaceRefactorEnabled) { + assert mTabSwitcherModule != null; + return mTabSwitcherModule.getTabListDelegate(); + } else { + assert mTasksSurface != null; + return mTasksSurface.getTabListDelegate(); + } } else { return null; } @@ -605,8 +675,10 @@ public Supplier<Boolean> getTabGridDialogVisibilitySupplier() { // If TabSwitcher has been created directly, use the TabGridDialogVisibilitySupplier from // TabSwitcher. - if (mTabSwitcher != null) { - return mTabSwitcher.getTabGridDialogVisibilitySupplier(); + if (mGridTabSwitcher != null) { + return mGridTabSwitcher.getTabGridDialogVisibilitySupplier(); + } else if (mTabSwitcherModule != null) { + return () -> mTabSwitcherModule.getTabGridDialogVisibilitySupplier() != null; } return () -> { // Return true if either mTasksSurface or mSecondaryTasksSurface has a visible dialog. @@ -650,8 +722,11 @@ @Override @Nullable - public TasksSurface getPrimaryTasksSurface() { - return mTasksSurface; + public TasksView getPrimarySurfaceView() { + if (mTasksSurface != null) { + return (TasksView) mTasksSurface.getView(); + } + return mView; } @Override @@ -730,17 +805,29 @@ @VisibleForTesting public boolean isMVTilesCleanedUpForTesting() { - return mTasksSurface.isMVTilesCleanedUp(); + if (mTasksSurface != null) { + return mTasksSurface.isMVTilesCleanedUp(); + } + if (mMostVisitedCoordinator != null) { + return mMostVisitedCoordinator.isMVTilesCleanedUp(); + } + return false; } @VisibleForTesting public boolean isMVTilesInitializedForTesting() { - return mTasksSurface.isMVTilesInitialized(); + if (mTasksSurface != null) { + return mTasksSurface.isMVTilesInitialized(); + } + return mIsMVTilesInitialized; } @VisibleForTesting public TileGroupDelegateImpl getTileGroupDelegateForTesting() { - return mTasksSurface.getTileGroupDelegate(); + if (mTasksSurface != null) { + return mTasksSurface.getTileGroupDelegate(); + } + return mTileGroupDelegate; } /** @@ -770,9 +857,79 @@ mTasksSurfacePropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, - new TasksSurfaceViewBinder.ViewHolder( + new StartSurfaceWithParentViewBinder.ViewHolder( mContainerView, mTasksSurface.getView(), mSwipeRefreshLayout), - TasksSurfaceViewBinder::bind); + StartSurfaceWithParentViewBinder::bind); + } + + private void createStartSurfaceWithoutTasksSurface(boolean excludeQueryTiles) { + ArrayList<PropertyKey> allProperties = + new ArrayList<>(Arrays.asList(TasksSurfaceProperties.ALL_KEYS)); + allProperties.addAll(Arrays.asList(StartSurfaceProperties.ALL_KEYS)); + mPropertyModel = new PropertyModel(allProperties); + + assert mIsStartSurfaceEnabled; + + int tabSwitcherType = + StartSurfaceConfiguration.START_SURFACE_LAST_ACTIVE_TAB_ONLY.getValue() + ? TabSwitcherType.SINGLE + : TabSwitcherType.CAROUSEL; + + mView = (TasksView) LayoutInflater.from(mActivity).inflate( + R.layout.tasks_view_layout, null); + mView.setId(R.id.primary_tasks_surface_view); + mView.initialize(mActivityLifecycleDispatcher, + mParentTabSupplier.hasValue() && mParentTabSupplier.get().isIncognito(), + mWindowAndroid); + if (tabSwitcherType == TabSwitcherType.CAROUSEL) { + mTabSwitcherModule = + TabManagementModuleProvider.getDelegate().createCarouselTabSwitcher(mActivity, + mActivityLifecycleDispatcher, mTabModelSelector, mTabContentManager, + mBrowserControlsManager, mTabCreatorManager, + mMenuOrKeyboardActionController, + mView.getCarouselTabSwitcherContainer(), mShareDelegateSupplier, + mMultiWindowModeStateDispatcher, mScrimCoordinator, mView, + mDynamicResourceLoaderSupplier, mSnackbarManager, mModalDialogManager); + } else { + mTabSwitcherModule = new SingleTabSwitcherCoordinator( + mActivity, mView.getCarouselTabSwitcherContainer(), mTabModelSelector); + } + boolean isScrollableMVTEnabled = + !ReturnToChromeUtil.shouldImproveStartWhenFeedIsDisabled(mActivity); + int maxRowsForGridMVT = getQueryTilesVisibility() + ? QueryTileSection.getMaxRowsForMostVisitedTiles(mActivity) + : MAX_TILE_ROWS_FOR_GRID_MVT; + View mvTilesContainer = mView.findViewById(R.id.mv_tiles_container); + mMostVisitedCoordinator = new MostVisitedTilesCoordinator(mActivity, + mActivityLifecycleDispatcher, mvTilesContainer, mWindowAndroid, + TabUiFeatureUtilities.supportInstantStart( + DeviceFormFactor.isNonMultiDisplayContextOnTablet(mActivity), mActivity), + isScrollableMVTEnabled, + isScrollableMVTEnabled ? Integer.MAX_VALUE : maxRowsForGridMVT, + /*snapshotTileGridChangedRunnable=*/null, + /*tileCountChangedRunnable=*/null); + + if (!excludeQueryTiles) { + if (ProfileManager.isInitialized()) { + initializeQueryTileSection(Profile.getLastUsedRegularProfile()); + } else { + mQueryTileProfileSupplier = new OriginalProfileSupplier(); + mQueryTileProfileSupplier.onAvailable(this::initializeQueryTileSection); + } + } else { + storeQueryTilesVisibility(false); + } + initializeOffsetChangedListener(); + addHeaderOffsetChangeListener(mOffsetChangedListenerToGenerateScrollEvents); + + mStartSurfaceWithParentViewPropertyModelChangeProcessor = + PropertyModelChangeProcessor.create(mPropertyModel, + new StartSurfaceWithParentViewBinder.ViewHolder( + mContainerView, mView, mSwipeRefreshLayout), + StartSurfaceWithParentViewBinder::bind); + + mStartSurfacePropertyModelChangeProcessor = + PropertyModelChangeProcessor.create(mPropertyModel, mView, TasksViewBinder::bind); } // TODO(crbug.com/1315676): Remove this function once the start surface refactoring is done, @@ -802,7 +959,7 @@ mSecondaryTasksSurface.getView().setId(R.id.secondary_tasks_surface_view); mSecondaryTasksSurfacePropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, - new TasksSurfaceViewBinder.ViewHolder( + new StartSurfaceWithParentViewBinder.ViewHolder( mContainerView, mSecondaryTasksSurface.getView(), null), SecondaryTasksSurfaceViewBinder::bind); if (mOnTabSelectingListener != null) { @@ -900,7 +1057,9 @@ // This function should be called together with // StartSurfaceToolbarMediator#updateTranslationY, which scroll up the start surface // toolbar together with the header. - mTasksSurface.updateFakeSearchBox(fakeHeight - reducedHeight, reducedHeight, + TasksView tasksView = + mTasksSurface != null ? (TasksView) mTasksSurface.getView() : mView; + tasksView.updateFakeSearchBox(fakeHeight - reducedHeight, reducedHeight, (int) (fakeEndPadding * (1 - expansionFraction)), SearchEngineLogoUtils.getInstance().shouldShowSearchEngineLogo(false) ? realTranslationX * expansionFraction @@ -914,6 +1073,56 @@ return mActivity.getResources().getDimensionPixelSize(id); } + public void initializeMVTiles() { + if (!LibraryLoader.getInstance().isInitialized() || mIsMVTilesInitialized + || mMostVisitedCoordinator == null) { + return; + } + + Profile profile = Profile.getLastUsedRegularProfile(); + MostVisitedTileNavigationDelegate navigationDelegate = + new MostVisitedTileNavigationDelegate(mActivity, profile, mParentTabSupplier); + mSuggestionsUiDelegate = new MostVisitedSuggestionsUiDelegate( + mView, navigationDelegate, profile, mSnackbarManager); + mTileGroupDelegate = new TileGroupDelegateImpl(mActivity, profile, navigationDelegate, + mSnackbarManager, BrowserUiUtils.HostSurface.START_SURFACE); + + mMostVisitedCoordinator.initWithNative( + mSuggestionsUiDelegate, mTileGroupDelegate, enabled -> {}); + mIsMVTilesInitialized = true; + } + + private void storeQueryTilesVisibility(boolean isShown) { + SharedPreferencesManager.getInstance().writeBoolean( + ChromePreferenceKeys.QUERY_TILES_SHOWN_ON_START_SURFACE, isShown); + } + + private boolean getQueryTilesVisibility() { + return SharedPreferencesManager.getInstance().readBoolean( + ChromePreferenceKeys.QUERY_TILES_SHOWN_ON_START_SURFACE, false); + } + + private void initializeQueryTileSection(Profile profile) { + assert profile != null; + if (!QueryTileUtils.isQueryTilesEnabledOnStartSurface()) { + storeQueryTilesVisibility(false); + return; + } + mQueryTileSection = new QueryTileSection(mView.findViewById(R.id.query_tiles_layout), + profile, query -> performSearchQuery(query.queryText, query.searchParams)); + storeQueryTilesVisibility(true); + mQueryTileProfileSupplier = null; + } + + /** + * Called to send the search query and params to omnibox to kick off a search. + * @param queryText Text of the search query to perform. + * @param searchParams A list of params to sent along with the search query. + */ + void performSearchQuery(String queryText, List<String> searchParams) { + mStartSurfaceMediator.performSearchQuery(queryText, searchParams); + } + @VisibleForTesting boolean isSecondaryTasksSurfaceEmptyForTesting() { return mSecondaryTasksSurface == null; @@ -923,4 +1132,12 @@ FeedSwipeRefreshLayout getFeedSwipeRefreshLayoutForTesting() { return mSwipeRefreshLayout; } + + TasksSurface getTasksSurfaceForTesting() { + return mTasksSurface; + } + + TasksView getViewForTesting() { + return mView; + } }
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceHomeLayout.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceHomeLayout.java index 197f2a7..24c107e 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceHomeLayout.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceHomeLayout.java
@@ -6,7 +6,6 @@ import android.animation.Animator; import android.content.Context; -import android.view.ViewGroup; import androidx.annotation.VisibleForTesting; @@ -17,7 +16,7 @@ import org.chromium.chrome.browser.layouts.EventFilter; import org.chromium.chrome.browser.layouts.LayoutType; import org.chromium.chrome.browser.layouts.scene_layer.SceneLayer; -import org.chromium.chrome.features.tasks.TasksSurface; +import org.chromium.chrome.features.tasks.TasksView; /** * A {@link Layout} that shows Start Surface home view. @@ -131,15 +130,14 @@ if (!background || newIsIncognito || !mIsShown) { return; } - TasksSurface primaryTasksSurface = mStartSurface.getPrimaryTasksSurface(); - assert primaryTasksSurface != null; + TasksView startSurfaceView = mStartSurface.getPrimarySurfaceView(); + assert startSurfaceView != null; if (mBackgroundTabAnimation != null && mBackgroundTabAnimation.isStarted()) { mBackgroundTabAnimation.end(); } - mBackgroundTabAnimation = - BackgroundTabAnimation.create(this, (ViewGroup) primaryTasksSurface.getView(), - originX, originY, getOrientation() == Orientation.PORTRAIT); + mBackgroundTabAnimation = BackgroundTabAnimation.create( + this, startSurfaceView, originX, originY, getOrientation() == Orientation.PORTRAIT); mBackgroundTabAnimation.start(); }
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java index a941343..901b11622 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java
@@ -11,6 +11,8 @@ import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SHOWING_OVERVIEW; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.RESET_FEED_SURFACE_SCROLL_POSITION; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.TOP_MARGIN; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_CLICK_LISTENER; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_TEXT_WATCHER; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_FAKE_SEARCH_BOX_VISIBLE; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_INCOGNITO; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_INCOGNITO_DESCRIPTION_INITIALIZED; @@ -20,6 +22,7 @@ import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_TITLE_VISIBLE; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_VISIBLE; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_VOICE_RECOGNITION_BUTTON_VISIBLE; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.LENS_BUTTON_CLICK_LISTENER; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.MORE_TABS_CLICK_LISTENER; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.MV_TILES_CONTAINER_LEFT_RIGHT_MARGIN; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.MV_TILES_CONTAINER_TOP_MARGIN; @@ -30,9 +33,12 @@ import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.TAB_SWITCHER_TITLE_TOP_MARGIN; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.TASKS_SURFACE_BODY_TOP_MARGIN; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.TOP_TOOLBAR_PLACEHOLDER_HEIGHT; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.VOICE_SEARCH_BUTTON_CLICK_LISTENER; import android.content.Context; import android.content.res.Resources; +import android.text.Editable; +import android.text.TextWatcher; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; @@ -64,8 +70,10 @@ import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; import org.chromium.chrome.browser.logo.LogoCoordinator; import org.chromium.chrome.browser.ntp.NewTabPageLaunchOrigin; +import org.chromium.chrome.browser.omnibox.OmniboxFocusReason; import org.chromium.chrome.browser.omnibox.OmniboxStub; import org.chromium.chrome.browser.omnibox.UrlFocusChangeListener; +import org.chromium.chrome.browser.omnibox.voice.VoiceRecognitionHandler; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.Pref; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; @@ -90,6 +98,8 @@ import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.util.ColorUtils; +import java.util.List; + /** The mediator implements the logic to interact with the surfaces and caller. */ class StartSurfaceMediator implements TabSwitcher.TabSwitcherViewObserver, View.OnClickListener, StartSurface.OnTabSelectingListener, BackPressHandler, @@ -201,6 +211,10 @@ private boolean mHideOverviewOnTabSelecting = true; private StartSurface.OnTabSelectingListener mOnTabSelectingListener; private ViewGroup mTabSwitcherContainer; + // The single or carousel Tab switcher module on the Start surface. + // None-null when the Start surface refactoring is enabled. + @Nullable + private TabSwitcher mTabSwitcherModule; private SnackbarManager mSnackbarManager; private boolean mIsNativeInitialized; // The timestamp at which the Start Surface was last shown to the user. @@ -208,8 +222,11 @@ private boolean mIsStartSurfaceRefactorEnabled; private OnClickListener mTabSwitcherClickHandler; + // TODO(crbug.com/1315676): Clean up TabSwitcher#Controller once the start surface refactoring + // is done. StartSurfaceMediator(Controller controller, ViewGroup tabSwitcherContainer, - TabModelSelector tabModelSelector, @Nullable PropertyModel propertyModel, + @Nullable TabSwitcher tabSwitcherModule, TabModelSelector tabModelSelector, + @Nullable PropertyModel propertyModel, @Nullable SecondaryTasksSurfaceInitializer secondaryTasksSurfaceInitializer, boolean isStartSurfaceEnabled, Context context, BrowserControlsStateProvider browserControlsStateProvider, @@ -222,6 +239,7 @@ OnClickListener tabSwitcherClickHandler) { mController = controller; mTabSwitcherContainer = tabSwitcherContainer; + mTabSwitcherModule = tabSwitcherModule; mTabModelSelector = tabModelSelector; mPropertyModel = propertyModel; mSecondaryTasksSurfaceInitializer = secondaryTasksSurfaceInitializer; @@ -251,6 +269,19 @@ if (mPropertyModel != null) { assert mIsStartSurfaceEnabled; + if (mTabSwitcherModule != null) { + boolean isTabCarousel = mTabSwitcherModule.getController().getTabSwitcherType() + == TabSwitcherType.CAROUSEL; + mPropertyModel.set(IS_TAB_CAROUSEL_VISIBLE, isTabCarousel); + mPropertyModel.set(IS_TAB_CAROUSEL_TITLE_VISIBLE, isTabCarousel); + + // Set the initial state. + mPropertyModel.set(IS_SURFACE_BODY_VISIBLE, true); + mPropertyModel.set(IS_FAKE_SEARCH_BOX_VISIBLE, true); + mPropertyModel.set(IS_VOICE_RECOGNITION_BUTTON_VISIBLE, false); + mPropertyModel.set(IS_LENS_BUTTON_VISIBLE, false); + } + // Show feed loading image if necessary. if (shouldShowFeedPlaceholder()) { assert feedPlaceholderParentView != null; @@ -459,8 +490,51 @@ if (mLogoCoordinator != null) mLogoCoordinator.initWithNative(); } } - } + if (mTabSwitcherModule != null) { + mPropertyModel.set(FAKE_SEARCH_BOX_CLICK_LISTENER, v -> { + mOmniboxStub.setUrlBarFocus( + true, null, OmniboxFocusReason.TASKS_SURFACE_FAKE_BOX_TAP); + RecordUserAction.record("TasksSurface.FakeBox.Tapped"); + }); + mPropertyModel.set(FAKE_SEARCH_BOX_TEXT_WATCHER, new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence s, int start, int count, int after) { + } + + @Override + public void onTextChanged(CharSequence s, int start, int before, int count) {} + + @Override + public void afterTextChanged(Editable s) { + if (s.length() == 0) return; + mOmniboxStub.setUrlBarFocus(true, s.toString(), + OmniboxFocusReason.TASKS_SURFACE_FAKE_BOX_LONG_PRESS); + RecordUserAction.record("TasksSurface.FakeBox.LongPressed"); + + // This won't cause infinite loop since we checked s.length() == 0 above. + s.clear(); + } + }); + mPropertyModel.set(VOICE_SEARCH_BUTTON_CLICK_LISTENER, v -> { + FeedReliabilityLogger feedReliabilityLogger = getFeedReliabilityLogger(); + if (feedReliabilityLogger != null) { + feedReliabilityLogger.onVoiceSearch(); + } + mOmniboxStub.getVoiceRecognitionHandler().startVoiceRecognition( + VoiceRecognitionHandler.VoiceInteractionSource.TASKS_SURFACE); + RecordUserAction.record("TasksSurface.FakeBox.VoiceSearch"); + }); + + mPropertyModel.set(LENS_BUTTON_CLICK_LISTENER, v -> { + LensMetrics.recordClicked(LensEntryPoint.TASKS_SURFACE); + mOmniboxStub.startLens(LensEntryPoint.TASKS_SURFACE); + }); + } + } + if (mTabSwitcherModule != null) { + mTabSwitcherModule.initWithNative(); + } mFeedVisibilityPrefOnStartUp = prefService.getBoolean(Pref.ARTICLES_LIST_VISIBLE); } @@ -668,7 +742,7 @@ // reset the scrolling position. resetScrollPosition(); } else if (mStartSurfaceState == StartSurfaceState.SHOWING_TABSWITCHER) { - maybeDestroyFeedPlaceholder(); + onHide(); // Set secondary surface visible to make sure tab list recyclerview is updated in time // (before GTS animations start). We need to skip // mSecondaryTasksSurfaceController#showOverview here since it will hide GTS animations. @@ -887,11 +961,14 @@ return ret; } - void maybeDestroyFeedPlaceholder() { + void onHide() { if (mFeedPlaceholderCoordinator != null) { mFeedPlaceholderCoordinator.destroy(); mFeedPlaceholderCoordinator = null; } + if (mTabSwitcherModule != null) { + mTabSwitcherModule.getTabListDelegate().postHiding(); + } } @Override @@ -1365,6 +1442,12 @@ return mLogoCoordinator != null && mLogoCoordinator.isLogoVisible(); } + void performSearchQuery(String queryText, List<String> searchParams) { + if (mOmniboxStub != null) { + mOmniboxStub.performSearchQuery(queryText, searchParams); + } + } + void setOnTabSelectingListener(StartSurface.OnTabSelectingListener onTabSelectingListener) { mOnTabSelectingListener = onTabSelectingListener; } @@ -1496,4 +1579,12 @@ return mPropertyModel.get(EXPLORE_SURFACE_COORDINATOR) .getFeedActionDelegateForTesting(); // IN-TEST } + + TabSwitcher getTabSwitcherModuleForTesting() { + return mTabSwitcherModule; + } + + Runnable getInitializeMVTilesRunnableForTesting() { + return mInitializeMVTilesRunnable; + } }
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinder.java similarity index 98% rename from chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java rename to chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinder.java index 7037d7d..a170acce 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinder.java
@@ -17,7 +17,7 @@ import org.chromium.ui.modelutil.PropertyModel; /** The binder controls the display of the {@link TasksView} in its parent. */ -class TasksSurfaceViewBinder { +class StartSurfaceWithParentViewBinder { private static final long FADE_IN_DURATION_MS = 50; /**
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java index 6c841ef..bba6c60 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java
@@ -48,7 +48,7 @@ import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.util.ChromeAccessibilityUtil; import org.chromium.chrome.features.start_surface.StartSurface.TabSwitcherViewObserver; -import org.chromium.chrome.features.tasks.TasksSurface; +import org.chromium.chrome.features.tasks.TasksView; import org.chromium.components.browser_ui.styles.ChromeColors; import org.chromium.components.browser_ui.widget.animation.Interpolators; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; @@ -484,15 +484,14 @@ || mStartSurface.getStartSurfaceState() != StartSurfaceState.SHOWN_HOMEPAGE) { return; } - TasksSurface primaryTasksSurface = mStartSurface.getPrimaryTasksSurface(); + TasksView primaryTasksSurface = mStartSurface.getPrimarySurfaceView(); assert primaryTasksSurface != null; if (mBackgroundTabAnimation != null && mBackgroundTabAnimation.isStarted()) { mBackgroundTabAnimation.end(); } - mBackgroundTabAnimation = - BackgroundTabAnimation.create(this, (ViewGroup) primaryTasksSurface.getView(), - originX, originY, getOrientation() == Orientation.PORTRAIT); + mBackgroundTabAnimation = BackgroundTabAnimation.create(this, primaryTasksSurface, originX, + originY, getOrientation() == Orientation.PORTRAIT); mBackgroundTabAnimation.start(); }
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java index 317aac5..cbef4369 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java
@@ -27,14 +27,14 @@ import org.chromium.ui.modelutil.PropertyModelChangeProcessor; /** Coordinator of the single tab tab switcher. */ -class SingleTabSwitcherCoordinator implements TabSwitcher { +public class SingleTabSwitcherCoordinator implements TabSwitcher { private final PropertyModelChangeProcessor mPropertyModelChangeProcessor; private final SingleTabSwitcherMediator mMediator; private final TabListFaviconProvider mTabListFaviconProvider; private final TabSwitcher.TabListDelegate mTabListDelegate; private final TabModelSelector mTabModelSelector; - SingleTabSwitcherCoordinator(@NonNull Activity activity, @NonNull ViewGroup container, + public SingleTabSwitcherCoordinator(@NonNull Activity activity, @NonNull ViewGroup container, @NonNull TabModelSelector tabModelSelector) { mTabModelSelector = tabModelSelector; PropertyModel propertyModel = new PropertyModel(SingleTabViewProperties.ALL_KEYS); @@ -149,7 +149,6 @@ @Override public Supplier<Boolean> getTabGridDialogVisibilitySupplier() { - assert false : "should not reach here"; return null; }
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java index f4ba433..0c61140 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksSurfaceCoordinator.java
@@ -37,8 +37,6 @@ import org.chromium.chrome.browser.query_tiles.QueryTileSection; import org.chromium.chrome.browser.query_tiles.QueryTileUtils; import org.chromium.chrome.browser.share.ShareDelegate; -import org.chromium.chrome.browser.suggestions.SuggestionsNavigationDelegate; -import org.chromium.chrome.browser.suggestions.SuggestionsUiDelegateImpl; import org.chromium.chrome.browser.suggestions.tile.MostVisitedTilesCoordinator; import org.chromium.chrome.browser.suggestions.tile.TileGroupDelegateImpl; import org.chromium.chrome.browser.tab.Tab; @@ -52,6 +50,7 @@ import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; import org.chromium.chrome.browser.ui.messages.snackbar.SnackbarManager; import org.chromium.chrome.browser.util.BrowserUiUtils; +import org.chromium.chrome.features.start_surface.MostVisitedSuggestionsUiDelegate; import org.chromium.components.browser_ui.widget.MenuOrKeyboardActionController; import org.chromium.components.browser_ui.widget.scrim.ScrimCoordinator; import org.chromium.ui.base.DeviceFormFactor; @@ -225,8 +224,8 @@ Profile profile = Profile.getLastUsedRegularProfile(); MostVisitedTileNavigationDelegate navigationDelegate = new MostVisitedTileNavigationDelegate(mActivity, profile, mParentTabSupplier); - mSuggestionsUiDelegate = - new MostVisitedSuggestionsUiDelegate(navigationDelegate, profile, mSnackbarManager); + mSuggestionsUiDelegate = new MostVisitedSuggestionsUiDelegate( + mView, navigationDelegate, profile, mSnackbarManager); mTileGroupDelegate = new TileGroupDelegateImpl(mActivity, profile, navigationDelegate, mSnackbarManager, BrowserUiUtils.HostSurface.START_SURFACE); @@ -342,20 +341,6 @@ return (mTabSwitcher != null) ? mTabSwitcher.getTabSwitcherCustomViewManager() : null; } - /** Suggestions UI Delegate for constructing the TileGroup. */ - private class MostVisitedSuggestionsUiDelegate extends SuggestionsUiDelegateImpl { - public MostVisitedSuggestionsUiDelegate(SuggestionsNavigationDelegate navigationDelegate, - Profile profile, SnackbarManager snackbarManager) { - super(navigationDelegate, profile, /*host=*/null, snackbarManager); - } - - @Override - public boolean isVisible() { - return mView.getVisibility() == View.VISIBLE - && mView.findViewById(R.id.mv_tiles_layout).getVisibility() == View.VISIBLE; - } - } - private void storeQueryTilesVisibility(boolean isShown) { SharedPreferencesManager.getInstance().writeBoolean( ChromePreferenceKeys.QUERY_TILES_SHOWN_ON_START_SURFACE, isShown);
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksView.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksView.java index 0ac3a7ed..9175b93 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksView.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksView.java
@@ -46,7 +46,6 @@ * The view of the tasks surface. Set public for testing. */ public class TasksView extends CoordinatorLayoutForPointer { - private static final int OMNIBOX_BOTTOM_PADDING_DP = 4; private static final MutableFlagWithSafeDefault sIncognitoRevampFlag = new MutableFlagWithSafeDefault(ChromeFeatureList.INCOGNITO_NTP_REVAMP, false); @@ -63,7 +62,6 @@ CookieControlsEnforcement.NO_ENFORCEMENT; private View.OnClickListener mIncognitoCookieControlsIconClickListener; private UiConfig mUiConfig; - private boolean mIsIncognito; /** Default constructor needed to inflate via XML. */ public TasksView(Context context, AttributeSet attrs) { @@ -117,11 +115,11 @@ titleDescription.getPaddingBottom()); } - ViewGroup getCarouselTabSwitcherContainer() { + public ViewGroup getCarouselTabSwitcherContainer() { return mCarouselTabSwitcherContainer; } - ViewGroup getBodyViewContainer() { + public ViewGroup getBodyViewContainer() { return findViewById(R.id.tasks_surface_body); } @@ -208,7 +206,6 @@ int hintTextColor = mContext.getColor(isIncognito ? R.color.locationbar_light_hint_text : R.color.locationbar_dark_hint_text); mSearchBoxCoordinator.setSearchBoxHintColor(hintTextColor); - mIsIncognito = isIncognito; } /** @@ -388,7 +385,7 @@ * Add a header offset change listener. * @param onOffsetChangedListener The given header offset change listener. */ - void addHeaderOffsetChangeListener( + public void addHeaderOffsetChangeListener( AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { if (mHeaderView != null) { mHeaderView.addOnOffsetChangedListener(onOffsetChangedListener); @@ -399,7 +396,7 @@ * Remove the given header offset change listener. * @param onOffsetChangedListener The header offset change listener which should be removed. */ - void removeHeaderOffsetChangeListener( + public void removeHeaderOffsetChangeListener( AppBarLayout.OnOffsetChangedListener onOffsetChangedListener) { if (mHeaderView != null) { mHeaderView.removeOnOffsetChangedListener(onOffsetChangedListener); @@ -415,7 +412,7 @@ * @param buttonSize Current height and width of the buttons in fake search box layout. * @param lensButtonLeftMargin Current left margin of the lens button in fake search box layout. */ - void updateFakeSearchBox(int height, int topMargin, int endPadding, float translationX, + public void updateFakeSearchBox(int height, int topMargin, int endPadding, float translationX, int buttonSize, int lensButtonLeftMargin) { if (mSearchBoxCoordinator.getView().getVisibility() != View.VISIBLE) return; mSearchBoxCoordinator.setHeight(height);
diff --git a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksViewBinder.java b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksViewBinder.java index 85e0b8ee..db4db0b 100644 --- a/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksViewBinder.java +++ b/chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/TasksViewBinder.java
@@ -39,8 +39,10 @@ import org.chromium.ui.modelutil.PropertyKey; import org.chromium.ui.modelutil.PropertyModel; -// The view binder of the tasks surface view. -class TasksViewBinder { +/** + * The view binder of the tasks surface view. + */ +public class TasksViewBinder { public static void bind(PropertyModel model, TasksView view, PropertyKey propertyKey) { if (propertyKey == FAKE_SEARCH_BOX_CLICK_LISTENER) { view.getSearchBoxCoordinator().setSearchBoxClickListener(
diff --git a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java index 257a0025..727ff34e 100644 --- a/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java +++ b/chrome/android/features/start_surface/javatests/src/org/chromium/chrome/features/start_surface/StartSurfaceBackButtonTest.java
@@ -320,6 +320,7 @@ @Feature({"StartSurface"}) // clang-format off @CommandLineFlags.Add({START_SURFACE_TEST_SINGLE_ENABLED_PARAMS}) + @DisabledTest(message = "https://crbug.com/1246457") @DisableFeatures({ChromeFeatureList.BACK_GESTURE_REFACTOR}) public void testSwipeBackOnStartSurfaceHomePage() throws ExecutionException { // clang-format on
diff --git a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java index 610c3f1b..b59b4a3 100644 --- a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java +++ b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinderUnitTest.java
@@ -61,7 +61,8 @@ mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, - new TasksSurfaceViewBinder.ViewHolder(mParentView, mTasksSurfaceView, null), + new StartSurfaceWithParentViewBinder.ViewHolder( + mParentView, mTasksSurfaceView, null), SecondaryTasksSurfaceViewBinder::bind); }
diff --git a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinatorUnitTest.java b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinatorUnitTest.java index 0ae2fc00..46f963a9 100644 --- a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinatorUnitTest.java +++ b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinatorUnitTest.java
@@ -5,6 +5,10 @@ package org.chromium.chrome.features.start_surface; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.times; @@ -42,8 +46,12 @@ import org.chromium.chrome.browser.suggestions.tile.TileSource; import org.chromium.chrome.browser.suggestions.tile.TileTitleSource; import org.chromium.chrome.browser.tasks.ReturnToChromeUtil; +import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate.TabSwitcherType; +import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; import org.chromium.chrome.browser.util.BrowserUiUtils; import org.chromium.chrome.test.util.browser.Features; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; +import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.ui.base.PageTransition; import org.chromium.ui.mojom.WindowOpenDisposition; @@ -85,7 +93,36 @@ } @Test + @EnableFeatures(ChromeFeatureList.START_SURFACE_REFACTOR) + public void testShowAndHideWithRefactorEnabled() { + assertTrue(ChromeFeatureList.sStartSurfaceRefactor.isEnabled()); + assertNull(mCoordinator.getTasksSurfaceForTesting()); + TabSwitcher tabSwitcherModule = + mCoordinator.getMediatorForTesting().getTabSwitcherModuleForTesting(); + assertNotNull(tabSwitcherModule); + assertEquals(TabSwitcherType.SINGLE, + tabSwitcherModule.getTabListDelegate().getListModeForTesting()); + assertNotNull(mCoordinator.getViewForTesting()); + + mCoordinator.showOverview(false); + assertTrue(mCoordinator.isMVTilesInitializedForTesting()); + assertFalse(mCoordinator.isMVTilesCleanedUpForTesting()); + assertNotNull(mCoordinator.getTileGroupDelegateForTesting()); + + mCoordinator.onHide(); + assertTrue(mCoordinator.isMVTilesCleanedUpForTesting()); + assertFalse(mCoordinator.isMVTilesInitializedForTesting()); + assertNull(mCoordinator.getTileGroupDelegateForTesting()); + } + + @Test + @DisableFeatures(ChromeFeatureList.START_SURFACE_REFACTOR) public void testCleanUpMVTilesAfterHiding() { + assertFalse(ChromeFeatureList.sStartSurfaceRefactor.isEnabled()); + assertNotNull(mCoordinator.getTasksSurfaceForTesting()); + assertNull(mCoordinator.getMediatorForTesting().getTabSwitcherModuleForTesting()); + assertNull(mCoordinator.getViewForTesting()); + mCoordinator.setStartSurfaceState(StartSurfaceState.SHOWING_HOMEPAGE); mCoordinator.showOverview(false);
diff --git a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java index e42b726e..c7267974 100644 --- a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java +++ b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java
@@ -34,10 +34,14 @@ import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SECONDARY_SURFACE_VISIBLE; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.IS_SHOWING_OVERVIEW; import static org.chromium.chrome.features.start_surface.StartSurfaceProperties.TOP_MARGIN; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_CLICK_LISTENER; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.FAKE_SEARCH_BOX_TEXT_WATCHER; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_FAKE_SEARCH_BOX_VISIBLE; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_INCOGNITO; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_INCOGNITO_DESCRIPTION_INITIALIZED; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_INCOGNITO_DESCRIPTION_VISIBLE; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_LENS_BUTTON_VISIBLE; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_SURFACE_BODY_VISIBLE; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_TITLE_VISIBLE; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_TAB_CAROUSEL_VISIBLE; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.IS_VOICE_RECOGNITION_BUTTON_VISIBLE; @@ -47,6 +51,7 @@ import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.SINGLE_TAB_TOP_MARGIN; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.TAB_SWITCHER_TITLE_TOP_MARGIN; import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.TASKS_SURFACE_BODY_TOP_MARGIN; +import static org.chromium.chrome.features.tasks.TasksSurfaceProperties.VOICE_SEARCH_BUTTON_CLICK_LISTENER; import android.content.Context; import android.content.res.Resources; @@ -81,6 +86,7 @@ import org.chromium.chrome.browser.browser_controls.BrowserControlsStateProvider; import org.chromium.chrome.browser.feed.FeedReliabilityLogger; import org.chromium.chrome.browser.flags.ChromeFeatureList; +import org.chromium.chrome.browser.lens.LensEntryPoint; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.lifecycle.PauseResumeWithNativeObserver; import org.chromium.chrome.browser.logo.LogoBridge; @@ -108,6 +114,7 @@ import org.chromium.chrome.browser.tasks.ReturnToChromeUtil; import org.chromium.chrome.browser.tasks.tab_management.TabManagementDelegate.TabSwitcherType; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher; +import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher.TabListDelegate; import org.chromium.chrome.browser.tasks.tab_management.TabSwitcher.TabSwitcherViewObserver; import org.chromium.chrome.features.start_surface.StartSurfaceMediator.SecondaryTasksSurfaceInitializer; import org.chromium.chrome.features.tasks.TasksSurfaceProperties; @@ -197,6 +204,12 @@ private ActivityLifecycleDispatcher mActivityLifecycleDispatcher; @Mock private OnClickListener mTabSwitcherClickHandler; + @Mock + private TabSwitcher mTabSwitcherModule; + @Mock + private TabListDelegate mTabListDelegate; + @Mock + private TabSwitcher.Controller mSingleTabSwitcherModuleController; @Captor private ArgumentCaptor<TabModelSelectorObserver> mTabModelSelectorObserverCaptor; @Captor @@ -1259,7 +1272,7 @@ StartSurfaceMediator mediator = createStartSurfaceMediatorWithoutInit( /* isStartSurfaceEnabled= */ true, - /* hadWarmStart= */ false); + /* isRefactorEnabled */ false, /* hadWarmStart= */ false); verify(mCarouselOrSingleTabSwitcherModuleController) .addTabSwitcherViewObserver( mCarouselTabSwitcherModuleVisibilityObserverCaptor.capture()); @@ -1293,7 +1306,7 @@ resources.getDimensionPixelSize(R.dimen.tab_switcher_title_top_margin); createStartSurfaceMediatorWithoutInit(/* isStartSurfaceEnabled= */ true, - /* hadWarmStart= */ false); + /* isRefactorEnabled */ false, /* hadWarmStart= */ false); assertThat(mPropertyModel.get(TASKS_SURFACE_BODY_TOP_MARGIN), equalTo(tasksSurfaceBodyTopMargin)); assertThat(mPropertyModel.get(MV_TILES_CONTAINER_TOP_MARGIN), @@ -1331,7 +1344,7 @@ StartSurfaceMediator mediator = createStartSurfaceMediatorWithoutInit(/* isStartSurfaceEnabled= */ true, - /* hadWarmStart= */ false); + /* isRefactorEnabled */ false, /* hadWarmStart= */ false); assertThat(mPropertyModel.get(TASKS_SURFACE_BODY_TOP_MARGIN), equalTo(tasksSurfaceBodyTopMarginWithTab)); assertThat(mPropertyModel.get(MV_TILES_CONTAINER_TOP_MARGIN), @@ -1365,7 +1378,7 @@ StartSurfaceMediator mediator = createStartSurfaceMediator( /* isStartSurfaceEnabled= */ true, - /* hadWarmStart= */ true); + /* isRefactorEnabled */ false, /* hadWarmStart= */ true); assertFalse(mediator.shouldShowFeedPlaceholder()); mPropertyModel.set(IS_EXPLORE_SURFACE_VISIBLE, true); @@ -1470,8 +1483,8 @@ Assert.assertTrue(ReturnToChromeUtil.shouldImproveStartWhenFeedIsDisabled( ContextUtils.getApplicationContext())); - StartSurfaceMediator mediator = - createStartSurfaceMediator(/*isStartSurfaceEnabled=*/true, false); + StartSurfaceMediator mediator = createStartSurfaceMediator(/*isStartSurfaceEnabled=*/true, + /* isRefactorEnabled */ false, /* hadWarmStart= */ false); showHomepageAndVerify(mediator, StartSurfaceState.SHOWN_HOMEPAGE); verify(mLogoContainerView).setVisibility(View.VISIBLE); @@ -1490,8 +1503,8 @@ Assert.assertFalse(ReturnToChromeUtil.shouldImproveStartWhenFeedIsDisabled( ContextUtils.getApplicationContext())); - StartSurfaceMediator mediator = - createStartSurfaceMediator(/*isStartSurfaceEnabled=*/true, false); + StartSurfaceMediator mediator = createStartSurfaceMediator(/*isStartSurfaceEnabled=*/true, + /* isRefactorEnabled */ false, /* hadWarmStart= */ false); showHomepageAndVerify(mediator, StartSurfaceState.SHOWN_HOMEPAGE); verify(mLogoContainerView, times(0)).setVisibility(View.VISIBLE); @@ -1608,14 +1621,27 @@ * showing but Tab switcher hasn't been created yet. */ @Test + @DisableFeatures(ChromeFeatureList.START_SURFACE_REFACTOR) public void testBackPressHandlerOnStartSurfaceWithoutTabSwitcherCreated() { + backPressHandlerOnStartSurfaceWithoutTabSwitcherCreatedImpl( + StartSurfaceState.SHOWN_HOMEPAGE); + } + + @Test + @EnableFeatures(ChromeFeatureList.START_SURFACE_REFACTOR) + public void testBackPressHandlerOnStartSurfaceWithoutTabSwitcherCreated_RefactorEnabled() { + backPressHandlerOnStartSurfaceWithoutTabSwitcherCreatedImpl(null); + } + + private void backPressHandlerOnStartSurfaceWithoutTabSwitcherCreatedImpl( + @StartSurfaceState Integer state) { doReturn(false).when(mTabModelSelector).isIncognitoSelected(); doReturn(false).when(mTabModelSelector).isIncognitoSelected(); doReturn(mVoiceRecognitionHandler).when(mOmniboxStub).getVoiceRecognitionHandler(); doReturn(true).when(mVoiceRecognitionHandler).isVoiceSearchEnabled(); StartSurfaceMediator mediator = createStartSurfaceMediator(/*isStartSurfaceEnabled=*/true); - showHomepageAndVerify(mediator, StartSurfaceState.SHOWN_HOMEPAGE); + showHomepageAndVerify(mediator, state); doReturn(true).when(mCarouselOrSingleTabSwitcherModuleController).isDialogVisible(); mediator.onBackPressed(); @@ -1766,14 +1792,58 @@ histogramWatcher.assertExpected(); } + @Test + @EnableFeatures(ChromeFeatureList.START_SURFACE_REFACTOR) + public void testShowAndOnHide() { + doReturn(false).when(mTabModelSelector).isIncognitoSelected(); + doReturn(mVoiceRecognitionHandler).when(mOmniboxStub).getVoiceRecognitionHandler(); + doReturn(true).when(mVoiceRecognitionHandler).isVoiceSearchEnabled(); + doReturn(mSingleTabSwitcherModuleController).when(mTabSwitcherModule).getController(); + doReturn(TabSwitcherType.SINGLE) + .when(mSingleTabSwitcherModuleController) + .getTabSwitcherType(); + doReturn(true).when(mOmniboxStub).isLensEnabled(LensEntryPoint.TASKS_SURFACE); + + StartSurfaceMediator mediator = createStartSurfaceMediator(/*isStartSurfaceEnabled=*/true, + /* isRefactorEnabled */ true); + assertEquals(mInitializeMVTilesRunnable, mediator.getInitializeMVTilesRunnableForTesting()); + assertEquals(mTabSwitcherModule, mediator.getTabSwitcherModuleForTesting()); + + showHomepageAndVerify(mediator, null); + verify(mOmniboxStub, times(2)) + .addUrlFocusChangeListener(mUrlFocusChangeListenerCaptor.capture()); + assertFalse(mPropertyModel.get(IS_INCOGNITO)); + assertTrue(mPropertyModel.get(IS_VOICE_RECOGNITION_BUTTON_VISIBLE)); + assertTrue(mPropertyModel.get(IS_EXPLORE_SURFACE_VISIBLE)); + assertTrue(mPropertyModel.get(MV_TILES_VISIBLE)); + assertTrue(mPropertyModel.get(IS_SHOWING_OVERVIEW)); + assertTrue(mPropertyModel.get(IS_SURFACE_BODY_VISIBLE)); + assertTrue(mPropertyModel.get(IS_FAKE_SEARCH_BOX_VISIBLE)); + assertTrue(mPropertyModel.get(IS_LENS_BUTTON_VISIBLE)); + assertNotNull(mPropertyModel.get(FAKE_SEARCH_BOX_CLICK_LISTENER)); + assertNotNull(mPropertyModel.get(FAKE_SEARCH_BOX_TEXT_WATCHER)); + assertNotNull(mPropertyModel.get(VOICE_SEARCH_BUTTON_CLICK_LISTENER)); + + doReturn(mTabListDelegate).when(mTabSwitcherModule).getTabListDelegate(); + mediator.onHide(); + verify(mTabListDelegate).postHiding(); + } + private StartSurfaceMediator createStartSurfaceMediator(boolean isStartSurfaceEnabled) { - return createStartSurfaceMediator(isStartSurfaceEnabled, /* hadWarmStart= */ false); + return createStartSurfaceMediator(isStartSurfaceEnabled, /* isRefactorEnabled */ false, + /* hadWarmStart= */ false); } private StartSurfaceMediator createStartSurfaceMediator( - boolean isStartSurfaceEnabled, boolean hadWarmStart) { - StartSurfaceMediator mediator = - createStartSurfaceMediatorWithoutInit(isStartSurfaceEnabled, hadWarmStart); + boolean isStartSurfaceEnabled, boolean isRefactorEnabled) { + return createStartSurfaceMediator(isStartSurfaceEnabled, isRefactorEnabled, + /* hadWarmStart= */ false); + } + + private StartSurfaceMediator createStartSurfaceMediator( + boolean isStartSurfaceEnabled, boolean isRefactorEnabled, boolean hadWarmStart) { + StartSurfaceMediator mediator = createStartSurfaceMediatorWithoutInit( + isStartSurfaceEnabled, isRefactorEnabled, hadWarmStart); mediator.initWithNative(mOmniboxStub, isStartSurfaceEnabled ? mExploreSurfaceCoordinatorFactory : null, mPrefService, null); @@ -1784,17 +1854,20 @@ } private StartSurfaceMediator createStartSurfaceMediatorWithoutInit( - boolean isStartSurfaceEnabled, boolean hadWarmStart) { + boolean isStartSurfaceEnabled, boolean isRefactorEnabled, boolean hadWarmStart) { + boolean hasTasksView = isStartSurfaceEnabled && !isRefactorEnabled; + boolean hasTabSwitcherModule = isStartSurfaceEnabled && isRefactorEnabled; return new StartSurfaceMediator(mCarouselOrSingleTabSwitcherModuleController, - null /* tabSwitcherContainer */, mTabModelSelector, - !isStartSurfaceEnabled ? null : mPropertyModel, - isStartSurfaceEnabled ? mSecondaryTasksSurfaceInitializer : null, - isStartSurfaceEnabled, ContextUtils.getApplicationContext(), - mBrowserControlsStateProvider, mActivityStateChecker, true /* excludeQueryTiles */, - mStartSurfaceSupplier, hadWarmStart, new DummyJankTracker(), - mInitializeMVTilesRunnable, mParentTabSupplier, mLogoContainerView, - mBackPressManager, null /* feedPlaceholderParentView */, - mActivityLifecycleDispatcher, mTabSwitcherClickHandler); + null /* tabSwitcherContainer */, hasTabSwitcherModule ? mTabSwitcherModule : null, + mTabModelSelector, !isStartSurfaceEnabled ? null : mPropertyModel, + hasTasksView ? mSecondaryTasksSurfaceInitializer : null, isStartSurfaceEnabled, + ContextUtils.getApplicationContext(), mBrowserControlsStateProvider, + mActivityStateChecker, true /* excludeQueryTiles */, mStartSurfaceSupplier, + hadWarmStart, new DummyJankTracker(), + hasTasksView || hasTabSwitcherModule ? mInitializeMVTilesRunnable : null, + mParentTabSupplier, mLogoContainerView, mBackPressManager, + null /* feedPlaceholderParentView */, mActivityLifecycleDispatcher, + mTabSwitcherClickHandler); } private void onControlsOffsetChanged(int topOffset, int topControlsMinHeightOffset) {
diff --git a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinderUnitTest.java similarity index 94% rename from chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java rename to chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinderUnitTest.java index f8c4a71..858da471 100644 --- a/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java +++ b/chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinderUnitTest.java
@@ -32,10 +32,10 @@ import org.chromium.ui.modelutil.PropertyModel; import org.chromium.ui.modelutil.PropertyModelChangeProcessor; -/** Tests for {@link TasksSurfaceViewBinder}. */ +/** Tests for {@link StartSurfaceWithParentViewBinder}. */ @RunWith(BaseRobolectricTestRunner.class) @Config(manifest = Config.NONE) -public class TasksSurfaceViewBinderUnitTest { +public class StartSurfaceWithParentViewBinderUnitTest { private Activity mActivity; private ViewGroup mParentView; private ViewGroup mTasksSurfaceView; @@ -57,9 +57,9 @@ mPropertyModel = new PropertyModel(StartSurfaceProperties.ALL_KEYS); mPropertyModelChangeProcessor = PropertyModelChangeProcessor.create(mPropertyModel, - new TasksSurfaceViewBinder.ViewHolder( + new StartSurfaceWithParentViewBinder.ViewHolder( mParentView, mTasksSurfaceView, mFeedSwipeRefreshLayout), - TasksSurfaceViewBinder::bind); + StartSurfaceWithParentViewBinder::bind); } @Test
diff --git a/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni b/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni index af329ef..aced0a98 100644 --- a/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni +++ b/chrome/android/features/start_surface/junit/start_surface_junit_java_sources.gni
@@ -8,7 +8,7 @@ "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinatorUnitTest.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinatorUnitTestRule.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceMediatorUnitTest.java", - "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinderUnitTest.java", + "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinderUnitTest.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/SingleTabSwitcherMediatorUnitTest.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/SingleTabViewBinderUnitTest.java", "//chrome/android/features/start_surface/junit/src/org/chromium/chrome/features/tasks/TasksSurfaceMediatorUnitTest.java",
diff --git a/chrome/android/features/start_surface/start_surface_java_sources.gni b/chrome/android/features/start_surface/start_surface_java_sources.gni index d8eaa4d4..e17d858 100644 --- a/chrome/android/features/start_surface/start_surface_java_sources.gni +++ b/chrome/android/features/start_surface/start_surface_java_sources.gni
@@ -11,6 +11,7 @@ "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceNavigationDelegate.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/ExploreSurfaceViewBinder.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/FeedPlaceholderCoordinator.java", + "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/MostVisitedSuggestionsUiDelegate.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/SecondaryTasksSurfaceViewBinder.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurface.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceCoordinator.java", @@ -18,8 +19,8 @@ "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceHomeLayout.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceMediator.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceProperties.java", + "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/StartSurfaceWithParentViewBinder.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TabSwitcherAndStartSurfaceLayout.java", - "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/start_surface/TasksSurfaceViewBinder.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/MostVisitedTileNavigationDelegate.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherCoordinator.java", "//chrome/android/features/start_surface/java/src/org/chromium/chrome/features/tasks/SingleTabSwitcherMediator.java",
diff --git a/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java b/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java index 5983c6a..409d1bb 100644 --- a/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java +++ b/chrome/android/features/tab_ui/public/android/java/src/org/chromium/chrome/browser/tasks/tab_management/TabUiThemeUtil.java
@@ -19,9 +19,10 @@ * Internal themes are provided via @{@link TabUiThemeProvider} */ public class TabUiThemeUtil { - private static final float MAX_TAB_STRIP_TAB_WIDTH_DP = 265.f; private static final String TAG = "TabUiThemeProvider"; + private static final float MAX_TAB_STRIP_TAB_WIDTH_DP = 265.f; private static final float DETACHED_TAB_OVERLAY_ALPHA = 0.85f; + private static final float DETACHED_TAB_OVERLAY_ALPHA_EDIT_MODE = 0.2f; /** * Returns the color for the tab strip background. @@ -62,12 +63,12 @@ * @return The color for the tab container. */ public static int getTabStripContainerColor( - Context context, boolean isIncognito, boolean foreground) { + Context context, boolean isIncognito, boolean foreground, boolean isReordering) { if (foreground) { if (TabManagementFieldTrial.isTabStripFolioEnabled()) { return ChromeColors.getDefaultThemeColor(context, isIncognito); } else if (TabManagementFieldTrial.isTabStripDetachedEnabled()) { - return getTabStripDetachedTabColor(context, isIncognito); + return getTabStripDetachedTabColor(context, isIncognito, isReordering); } } else { if (TabManagementFieldTrial.isTabStripFolioEnabled()) { @@ -88,9 +89,22 @@ * @param isIncognito Whether the color is used for incognito mode. * @return The color for the detached tab container. */ - private static int getTabStripDetachedTabColor(Context context, boolean isIncognito) { + private static int getTabStripDetachedTabColor( + Context context, boolean isIncognito, boolean isReordering) { assert TabManagementFieldTrial.isTabStripDetachedEnabled(); + if (isReordering) { + if (isIncognito) { + return context.getColor(R.color.default_bg_color_dark_elev_4_baseline); + } else { + final int baseColor = getTabStripBackgroundColor(context, isIncognito); + final int overlayColor = SemanticColorUtils.getDefaultControlColorActive(context); + + return ColorUtils.getColorWithOverlay( + baseColor, overlayColor, DETACHED_TAB_OVERLAY_ALPHA_EDIT_MODE); + } + } + if (isIncognito) return Color.BLACK; if (!ChromeFeatureList.sBaselineGm3SurfaceColors.isEnabled()
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index f96353b..5a38798 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java
@@ -2823,6 +2823,10 @@ return mStartSurfaceSupplier.get(); } + public TabSwitcher getTabSwitcherForTesting() { + return mTabSwitcherSupplier.get(); + } + private ComposedBrowserControlsVisibilityDelegate getAppBrowserControlsVisibilityDelegate() { // TODO(jinsukkim): Move this to RootUiCoordinator. return ((TabbedRootUiCoordinator) mRootUiCoordinator)
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java index 834ed9a..089dcc1 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/layouts/content/TabContentManager.java
@@ -34,6 +34,7 @@ import org.chromium.chrome.browser.flags.BooleanCachedFieldTrialParameter; import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; +import org.chromium.chrome.browser.flags.PostNativeFlag; import org.chromium.chrome.browser.tab.Tab; import org.chromium.chrome.browser.tab.TabUtils; import org.chromium.chrome.browser.tasks.tab_management.TabUiFeatureUtilities; @@ -58,6 +59,9 @@ */ @JNINamespace("android") public class TabContentManager { + private static PostNativeFlag sThumbnailCacheRefactor = + new PostNativeFlag(ChromeFeatureList.THUMBNAIL_CACHE_REFACTOR); + // These are used for UMA logging, so append only. Please update the // GridTabSwitcherThumbnailFetchingResult enum in enums.xml if these change. @IntDef({ThumbnailFetchingResult.GOT_JPEG, ThumbnailFetchingResult.GOT_ETC1, @@ -191,7 +195,8 @@ ChromeSwitches.APPROXIMATION_THUMBNAILS); boolean useApproximationThumbnails = - !DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext); + !DeviceFormFactor.isNonMultiDisplayContextOnTablet(mContext) + && !sThumbnailCacheRefactor.isEnabled(); boolean saveJpegThumbnails = TabUiFeatureUtilities.isGridTabSwitcherEnabled(mContext); mNativeTabContentManager =
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 6feeae3e..60fcc90 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
@@ -918,11 +918,15 @@ /** * Start divider should be visible when: - * 1. In reorder mode and currTab container is hidden + * 1. In reorder mode and currTab container is hidden and + * (a) prevTab has trailing margin (ie: currTab is start of group or an individual tab) + * OR (b) prevTab container is also hidden. * 2. Not in reorder mode and prevTab is not selected and currTab is not selected */ boolean startDividerVisible = - (mInReorderMode && currTab.getContainerOpacity() == TAB_OPACITY_HIDDEN) + (mInReorderMode && currTab.getContainerOpacity() == TAB_OPACITY_HIDDEN + && (prevTab.getTrailingMargin() > 0 + || prevTab.getContainerOpacity() == TAB_OPACITY_HIDDEN)) || (!mInReorderMode && prevTab.getId() != selectedTabId && currTab.getId() != selectedTabId); currTab.setStartDividerVisible(startDividerVisible); @@ -2016,6 +2020,7 @@ } // 7. Lift the TSR folio container off the toolbar. + mInteractingTab.setIsReordering(true); if (TabManagementFieldTrial.isTabStripFolioEnabled()) { updateFolioTabAttachState(mInteractingTab, false, animationList); } @@ -2060,6 +2065,7 @@ } // 5. Reattach the TSR folio container to the toolbar. + mInteractingTab.setIsReordering(false); if (TabManagementFieldTrial.isTabStripFolioEnabled()) { updateFolioTabAttachState(mInteractingTab, true, animationList); }
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java index 82d8671c..a388daa 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -204,6 +204,7 @@ private boolean mVisible = true; private boolean mIsDying; + private boolean mIsReordering; private boolean mCanShowCloseButton = true; private boolean mFolioAttached = true; private boolean mStartDividerVisible; @@ -336,6 +337,14 @@ } /** + * Marks if we are currently reordering this tab. + * @param isReordering Whether the tab is reordering. + */ + public void setIsReordering(boolean isReordering) { + mIsReordering = isReordering; + } + + /** * Marks if tab container is attached to the toolbar for the Tab Strip Redesign folio treatment. * @param folioAttached Whether the tab should be attached or not. */ @@ -385,7 +394,8 @@ // TODO(https://crbug.com/1408276): Avoid calculating every time. Instead, store the tab's // color and only re-determine when the color could have changed (i.e. on selection). if (ChromeFeatureList.sTabStripRedesign.isEnabled()) { - return TabUiThemeUtil.getTabStripContainerColor(mContext, mIncognito, foreground); + return TabUiThemeUtil.getTabStripContainerColor( + mContext, mIncognito, foreground, mIsReordering); } if (foreground) {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java index 661b500d..724e78c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/share/ShareDelegateImpl.java
@@ -15,6 +15,7 @@ import org.chromium.base.supplier.Supplier; import org.chromium.chrome.browser.AppHooks; import org.chromium.chrome.browser.feature_engagement.TrackerFactory; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.history_clusters.HistoryClustersTabHelper; import org.chromium.chrome.browser.lifecycle.ActivityLifecycleDispatcher; import org.chromium.chrome.browser.offlinepages.OfflinePageUtils; @@ -244,7 +245,8 @@ @Override public boolean isSharingHubEnabled() { - return !mIsCustomTab; + return !(mIsCustomTab + || ChromeFeatureList.isEnabled(ChromeFeatureList.SHARE_SHEET_MIGRATION_ANDROID)); } /**
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java index 9155fa0..023497a5 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/tab/RequestDesktopUtils.java
@@ -380,31 +380,29 @@ return false; } + // TODO(shuyng): Add downgrade path support for smallestScreenWidthDp or displaySizeInInches + // change. // If the smallest screen size in dp is below threshold, avoid default-enabling the setting. if (context.getResources().getConfiguration().smallestScreenWidthDp < ChromeFeatureList.getFieldTrialParamByFeatureAsInt(feature, PARAM_GLOBAL_SETTING_DEFAULT_ON_SMALLEST_SCREEN_WIDTH, DEFAULT_GLOBAL_SETTING_DEFAULT_ON_SMALLEST_SCREEN_WIDTH_THRESHOLD_DP)) { - updateNoLongerInCohort(); - return false; - } - - double screenSizeThreshold = ChromeFeatureList.getFieldTrialParamByFeatureAsDouble(feature, - PARAM_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES, - DEFAULT_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES); - if (displaySizeInInches < screenSizeThreshold) { - updateNoLongerInCohort(); return false; } SharedPreferencesManager sharedPreferencesManager = SharedPreferencesManager.getInstance(); + boolean previouslyDefaultEnabled = sharedPreferencesManager.readBoolean( ChromePreferenceKeys.DEFAULT_ENABLED_DESKTOP_SITE_GLOBAL_SETTING, false); boolean previouslyUpdatedByUser = sharedPreferencesManager.contains( SingleCategorySettingsConstants .USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY); - boolean inCohort = !previouslyUpdatedByUser; + double screenSizeThreshold = ChromeFeatureList.getFieldTrialParamByFeatureAsDouble(feature, + PARAM_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES, + DEFAULT_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES); + + boolean inCohort = !previouslyUpdatedByUser && displaySizeInInches >= screenSizeThreshold; boolean wouldEnable = !previouslyDefaultEnabled && inCohort; if (wouldEnable) { // Store a SharedPreferences key to tag the device as qualified for the feature
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java index d03d2eb..f9b7e47 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/compositor/layouts/LayoutManagerTest.java
@@ -782,11 +782,19 @@ TestThreadUtils.runOnUiThreadBlocking(() -> { Layout activeLayout = getActiveLayout(); Assert.assertEquals(LayoutType.TAB_SWITCHER, activeLayout.getLayoutType()); - Assert.assertEquals(expectedTabListMode, - mActivityTestRule.getActivity() - .getStartSurface() - .getGridTabListDelegate() - .getListModeForTesting()); + int tabListMode; + if (mIsStartSurfaceRefactorEnabled) { + tabListMode = mActivityTestRule.getActivity() + .getTabSwitcherForTesting() + .getTabListDelegate() + .getListModeForTesting(); + } else { + tabListMode = mActivityTestRule.getActivity() + .getStartSurface() + .getGridTabListDelegate() + .getListModeForTesting(); + } + Assert.assertEquals(expectedTabListMode, tabListMode); }); }
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieSettingsTest.java index b61d0ab..5729aefe 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/CookieSettingsTest.java
@@ -10,14 +10,22 @@ import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed; import static androidx.test.espresso.matcher.ViewMatchers.withId; import static androidx.test.espresso.matcher.ViewMatchers.withText; -import static org.chromium.ui.test.util.ViewUtils.onViewWaiting; + import static org.hamcrest.CoreMatchers.allOf; import static org.hamcrest.CoreMatchers.is; +import static org.chromium.ui.test.util.ViewUtils.onViewWaiting; + import android.os.Bundle; import android.view.View; + import androidx.test.filters.SmallTest; -import java.io.IOException; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; @@ -27,7 +35,9 @@ import org.chromium.chrome.browser.settings.SettingsActivityTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeRenderTestRule; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; +import org.chromium.components.browser_ui.settings.SettingsFeatureList; import org.chromium.components.browser_ui.site_settings.FourStateCookieSettingsPreference; import org.chromium.components.browser_ui.site_settings.FourStateCookieSettingsPreference.CookieSettingsState; import org.chromium.components.browser_ui.site_settings.R; @@ -36,14 +46,10 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.RenderTestRule; import org.chromium.ui.test.util.RenderTestRule.Component; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -/** - * Render tests for the Cookie page and subpages under Settings > Site Settings > Cookies. - */ +import java.io.IOException; + +/** Render tests for the Cookie page and subpages under Settings > Site Settings > Cookies. */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @@ -82,16 +88,34 @@ @Test @SmallTest @Feature({"RenderTest"}) + @EnableFeatures({ChromeFeatureList.PRIVACY_SANDBOX_FPS_UI, + SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID}) + public void + testRenderCookieFPSSubpage_EnableHighlightManagedPrefDisclaimerAndroid() throws IOException { + showCookieFPSSubpage(); + mRenderTestRule.render( + getRootView(R.string.website_settings_category_cookie_block_third_party_subtitle), + "settings_cookie_fps_subpage"); + } + + @Test + @SmallTest + @Feature({"RenderTest"}) @EnableFeatures(ChromeFeatureList.PRIVACY_SANDBOX_FPS_UI) - public void testRenderCookieFPSSubpage() throws IOException { + @DisableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) + public void testRenderCookieFPSSubpage_DisableHighlightManagedPrefDisclaimerAndroid() + throws IOException { + showCookieFPSSubpage(); + mRenderTestRule.render( + getRootView(R.string.website_settings_category_cookie_block_third_party_subtitle), + "settings_cookie_fps_subpage_DisableHighlightManagedPrefDisclaimerAndroid"); + } + + private void showCookieFPSSubpage() { onView(withId(R.id.block_third_party_with_aux)).perform(click()); onView(allOf(withId(R.id.expand_arrow), isDescendantOfA(withId(R.id.block_third_party_with_aux)))) .perform(click()); - - mRenderTestRule.render( - getRootView(R.string.website_settings_category_cookie_block_third_party_subtitle), - "settings_cookie_fps_subpage"); } private void setCookiesEnabled(final SettingsActivity settingsActivity, final boolean enabled) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java index c093281..6a0ba41 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/site_settings/SiteSettingsTest.java
@@ -146,9 +146,7 @@ import java.util.Map; import java.util.concurrent.TimeoutException; -/** - * Tests for everything under Settings > Site Settings. - */ +/** Tests for everything under Settings > Site Settings. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ContentSwitches.HOST_RESOLVER_RULES + "=MAP * 127.0.0.1", "ignore-certificate-errors"}) @@ -294,9 +292,7 @@ }); } - /** - * Sets Allow Location Enabled to be true and make sure it is set correctly. - */ + /** Sets Allow Location Enabled to be true and make sure it is set correctly. */ @Test @SmallTest @Feature({"Preferences"}) @@ -319,9 +315,7 @@ "/chrome/test/data/geolocation/geolocation_on_load.html", "", 0, false, true); } - /** - * Sets Allow Location Enabled to be false and make sure it is set correctly. - */ + /** Sets Allow Location Enabled to be false and make sure it is set correctly. */ @Test @SmallTest @Feature({"Preferences"}) @@ -386,15 +380,12 @@ return WebsitePreferenceBridge.isCategoryEnabled( getBrowserContextHandle(), ContentSettingsType.COOKIES); } - }); } private enum ToggleButtonState { EnabledUnchecked, EnabledChecked, Disabled } - /** - * Checks if the button representing the given state matches the managed expectation. - */ + /** Checks if the button representing the given state matches the managed expectation. */ private void checkFourStateCookieToggleButtonState(final SettingsActivity settingsActivity, final CookieSettingsState state, final ToggleButtonState toggleState) { TestThreadUtils.runOnUiThreadBlocking(() -> { @@ -490,9 +481,8 @@ } /** - * Tests that the Preferences designated by keys in |expectedKeys|, and only - * these preferences, will be shown for the category specified by |type|. The - * order of Preferences matters. + * Tests that the Preferences designated by keys in |expectedKeys|, and only these preferences, + * will be shown for the category specified by |type|. The order of Preferences matters. */ private void checkPreferencesForCategory( final @SiteSettingsCategory.Type int type, String[] expectedKeys) { @@ -536,9 +526,7 @@ checkPreferencesForCategory(type, enabledExpectedKeys); } - /** - * Allows cookies to be set and ensures that they are. - */ + /** Allows cookies to be set and ensures that they are. */ @Test @SmallTest @Feature({"Preferences"}) @@ -564,9 +552,7 @@ "\"Foo=Bar\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } - /** - * Clicks on cookies radio buttons and verify the right FPS subpage is launched. - */ + /** Clicks on cookies radio buttons and verify the right FPS subpage is launched. */ @Test @SmallTest @Feature({"Preferences"}) @@ -618,9 +604,7 @@ }); } - /** - * Blocks cookies from being set and ensures that no cookies can be set. - */ + /** Blocks cookies from being set and ensures that no cookies can be set. */ @Test @SmallTest @Feature({"Preferences"}) @@ -644,9 +628,7 @@ Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } - /** - * Blocks specific sites from setting cookies and ensures that no cookies can be set. - */ + /** Blocks specific sites from setting cookies and ensures that no cookies can be set. */ @Test @SmallTest @Feature({"Preferences"}) @@ -683,9 +665,7 @@ Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } - /** - * Blocks specific sites from setting cookies and ensures that no cookies can be set. - */ + /** Blocks specific sites from setting cookies and ensures that no cookies can be set. */ @Test @SmallTest @Feature({"Preferences"}) @@ -719,9 +699,7 @@ Assert.assertEquals("\"\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } - /** - * Set a cookie and check that it is removed when a site is cleared. - */ + /** Set a cookie and check that it is removed when a site is cleared. */ @Test @SmallTest @Feature({"Preferences"}) @@ -786,9 +764,7 @@ "\"Foo=Bar\"", mPermissionRule.runJavaScriptCodeInCurrentTab("getCookie()")); } - /** - * Set cookies for domains and check that they are removed when a site is cleared. - */ + /** Set cookies for domains and check that they are removed when a site is cleared. */ @Test @SmallTest @Feature({"Preferences"}) @@ -857,11 +833,11 @@ } /** - * Set the cookie content setting to allow through policy, disable incognito - * mode and ensure the correct radio buttons are enabled. This test is executed with experiment - * {@link SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID} either enabled or - * disabled, and the only expected difference in both cases is the UI that shows the disclaimer - * that the preference is managed. + * Set the cookie content setting to allow through policy, disable incognito mode and ensure the + * correct radio buttons are enabled. This test is executed with experiment {@link + * SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID} either enabled or disabled, + * and the only expected difference in both cases is the UI that shows the disclaimer that the + * preference is managed. */ @Test @SmallTest @@ -1217,9 +1193,7 @@ settingsActivity.finish(); } - /** - * Sets Allow Popups Enabled to be false and make sure it is set correctly. - */ + /** Sets Allow Popups Enabled to be false and make sure it is set correctly. */ @Test @SmallTest @Feature({"Preferences"}) @@ -1236,9 +1210,7 @@ Assert.assertEquals(1, getTabCount()); } - /** - * Sets Allow Popups Enabled to be true and make sure it is set correctly. - */ + /** Sets Allow Popups Enabled to be true and make sure it is set correctly. */ @Test @SmallTest @Feature({"Preferences"}) @@ -1255,9 +1227,7 @@ Assert.assertEquals(2, getTabCount()); } - /** - * Test that showing the Site Settings menu doesn't crash (crbug.com/610576). - */ + /** Test that showing the Site Settings menu doesn't crash (crbug.com/610576). */ @Test @SmallTest @Feature({"Preferences"}) @@ -1266,9 +1236,7 @@ settingsActivity.finish(); } - /** - * Test that showing the Site Settings menu contains only the "Cookies" row. - */ + /** Test that showing the Site Settings menu contains only the "Cookies" row. */ @Test @SmallTest @Feature({"Preferences"}) @@ -1300,9 +1268,8 @@ } /** - * Tests that only expected Preferences are shown for a category. This - * santiy checks the number of categories only. Each category has its own - * individual test below. + * Tests that only expected Preferences are shown for a category. This santiy checks the number + * of categories only. Each category has its own individual test below. */ @Test @SmallTest @@ -1638,7 +1605,8 @@ testExpectedPreferences( SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE, BINARY_TOGGLE, BINARY_TOGGLE); Assert.assertTrue( - "SharedPreference USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY should be updated.", + "SharedPreference USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY should be" + + " updated.", ContextUtils.getAppSharedPreferences().contains( SingleCategorySettingsConstants .USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY)); @@ -1652,7 +1620,8 @@ testExpectedPreferences(SiteSettingsCategory.Type.REQUEST_DESKTOP_SITE, BINARY_TOGGLE_WITH_EXCEPTION, BINARY_TOGGLE_WITH_EXCEPTION); Assert.assertTrue( - "SharedPreference USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY should be updated.", + "SharedPreference USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY should be" + + " updated.", ContextUtils.getAppSharedPreferences().contains( SingleCategorySettingsConstants .USER_ENABLED_DESKTOP_SITE_GLOBAL_SETTING_PREFERENCE_KEY)); @@ -1706,9 +1675,7 @@ SiteSettingsCategory.Type.VIRTUAL_REALITY, BINARY_TOGGLE, BINARY_TOGGLE); } - /** - * Tests system NFC support in Preferences. - */ + /** Tests system NFC support in Preferences. */ @Test @SmallTest @Feature({"Preferences"}) @@ -1720,8 +1687,8 @@ } /** - * Tests that {@link SingleWebsiteSettings#resetSite} doesn't crash - * (see e.g. the crash on host names in issue 600232). + * Tests that {@link SingleWebsiteSettings#resetSite} doesn't crash (see e.g. the crash on host + * names in issue 600232). */ @Test @SmallTest @@ -1733,6 +1700,7 @@ /** * Sets Allow Camera Enabled to be false and make sure it is set correctly. + * * @throws Exception */ @Test @@ -2303,8 +2271,8 @@ @Test @MediumTest @Feature({"Preferences"}) - @DisableIf.Build(message = "https://crbug.com/1269556", - sdk_is_greater_than = Build.VERSION_CODES.P) + @DisableIf. + Build(message = "https://crbug.com/1269556", sdk_is_greater_than = Build.VERSION_CODES.P) @DisableIf.Device(type = {UiDisableIf.TABLET}) // https://crbug.com/1234530 public void testProtectedContentAllowThenBlock() throws Exception { initializeUpdateWaiter(true /* expectGranted */); @@ -2435,21 +2403,33 @@ @Test @SmallTest + @EnableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) @Feature({"RenderTest"}) - public void testRenderLocationPage() throws Exception { + public void testRenderLocationPage_EnableHighlightManagedPrefDisclaimerAndroid() + throws Exception { renderCategoryPage( SiteSettingsCategory.Type.DEVICE_LOCATION, "site_settings_location_page"); } @Test @SmallTest + @DisableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) + @Feature({"RenderTest"}) + public void testRenderLocationPage_DisableHighlightManagedPrefDisclaimerAndroid() + throws Exception { + renderCategoryPage(SiteSettingsCategory.Type.DEVICE_LOCATION, + "site_settings_location_page_DisableHighlightManagedPrefDisclaimerAndroid"); + } + + @Test + @SmallTest @Feature({"RenderTest"}) public void testRenderProtectedMediaPage() throws Exception { renderCategoryPage( SiteSettingsCategory.Type.PROTECTED_MEDIA, "site_settings_protected_media_page"); } - /** Test case for checking that settings with binary toggles are disabled by policy.*/ + /** Test case for checking that settings with binary toggles are disabled by policy. */ @Test @SmallTest @Feature({"Preferences"}) @@ -2480,8 +2460,8 @@ } /** - * Allows third party cookies for a website, and tests that the UI shows a managed preference - * in the allowed group. Checks that it shows the toast when the preference is clicked. + * Allows third party cookies for a website, and tests that the UI shows a managed preference in + * the allowed group. Checks that it shows the toast when the preference is clicked. */ @Test @SmallTest @@ -2506,8 +2486,8 @@ } /** - * Blocks third party cookies for a website, and tests that the UI shows a managed preference - * in the blocked group. Checks that it shows toast when the preference is clicked. + * Blocks third party cookies for a website, and tests that the UI shows a managed preference in + * the blocked group. Checks that it shows toast when the preference is clicked. */ @Test @SmallTest @@ -2622,7 +2602,7 @@ } } - /** Test case for site settings with a global toggle. */ + /** Test case for site settings with a global toggle. */ static class TwoStatePermissionTestCase extends PermissionTestCase { TwoStatePermissionTestCase( String testName, int siteSettingsType, int contentSettingsType, boolean enabled) {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java index e4bdbfc..3aaeab3d 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/sync/AccountManagementFragmentTest.java
@@ -30,6 +30,7 @@ import org.junit.rules.RuleChain; import org.junit.runner.RunWith; +import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.CriteriaHelper; import org.chromium.base.test.util.Feature; @@ -47,6 +48,7 @@ import org.chromium.chrome.test.util.browser.Features.EnableFeatures; import org.chromium.chrome.test.util.browser.signin.AccountManagerTestRule; import org.chromium.chrome.test.util.browser.signin.SigninTestRule; +import org.chromium.components.browser_ui.settings.SettingsFeatureList; import org.chromium.components.signin.base.AccountInfo; import org.chromium.components.signin.base.CoreAccountInfo; import org.chromium.components.signin.identitymanager.ConsentLevel; @@ -55,6 +57,7 @@ /** Tests {@link AccountManagementFragment}. */ @RunWith(ChromeJUnit4ClassRunner.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) +@Batch(Batch.PER_CLASS) public class AccountManagementFragmentTest { private static final String CHILD_ACCOUNT_NAME = AccountManagerTestRule.generateChildEmail("account@gmail.com"); @@ -90,6 +93,7 @@ @Feature("RenderTest") @DisableFeatures({ChromeFeatureList.ADD_EDU_ACCOUNT_FROM_ACCOUNT_SETTINGS_FOR_SUPERVISED_USERS, ChromeFeatureList.HIDE_NON_DISPLAYABLE_ACCOUNT_EMAIL}) + @EnableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) public void testAccountManagementFragmentView() throws Exception { mSigninTestRule.addTestAccountThenSigninAndEnableSync(); @@ -102,8 +106,10 @@ @Test @MediumTest @Feature("RenderTest") - @EnableFeatures({ChromeFeatureList.ADD_EDU_ACCOUNT_FROM_ACCOUNT_SETTINGS_FOR_SUPERVISED_USERS}) - public void testAccountManagementFragmentViewWithAddEduAccountEnabled() throws Exception { + @EnableFeatures({ChromeFeatureList.ADD_EDU_ACCOUNT_FROM_ACCOUNT_SETTINGS_FOR_SUPERVISED_USERS, + SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID}) + public void + testAccountManagementFragmentViewWithAddEduAccountEnabled() throws Exception { mSigninTestRule.addTestAccountThenSigninAndEnableSync(); mSettingsActivityTestRule.startSettingsActivity(); View view = mSettingsActivityTestRule.getFragment().getView(); @@ -115,9 +121,10 @@ @Test @MediumTest @Feature("RenderTest") - @EnableFeatures({ChromeFeatureList.HIDE_NON_DISPLAYABLE_ACCOUNT_EMAIL}) - public void testAccountManagementFragmentViewWithHideNonDisplayableAccountEmailEnabled() - throws Exception { + @EnableFeatures({ChromeFeatureList.HIDE_NON_DISPLAYABLE_ACCOUNT_EMAIL, + SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID}) + public void + testAccountManagementFragmentViewWithHideNonDisplayableAccountEmailEnabled() throws Exception { mSigninTestRule.addTestAccountThenSigninAndEnableSync(); mSettingsActivityTestRule.startSettingsActivity(); View view = mSettingsActivityTestRule.getFragment().getView(); @@ -128,6 +135,7 @@ @Test @MediumTest + @EnableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) @Feature("RenderTest") public void testSignedInAccountShownOnTop() throws Exception { mSigninTestRule.addAccount("testSecondary@gmail.com"); @@ -213,9 +221,10 @@ @Test @MediumTest @Feature("RenderTest") - @EnableFeatures({ChromeFeatureList.ADD_EDU_ACCOUNT_FROM_ACCOUNT_SETTINGS_FOR_SUPERVISED_USERS}) - public void testAccountManagementViewForChildAccountWithAddEduAccountEnabled() - throws Exception { + @EnableFeatures({ChromeFeatureList.ADD_EDU_ACCOUNT_FROM_ACCOUNT_SETTINGS_FOR_SUPERVISED_USERS, + SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID}) + public void + testAccountManagementViewForChildAccountWithAddEduAccountEnabled() throws Exception { mSigninTestRule.addAccountAndWaitForSeeding(CHILD_ACCOUNT_NAME); final Profile profile = TestThreadUtils.runOnUiThreadBlockingNoException( Profile::getLastUsedRegularProfile); @@ -259,7 +268,8 @@ @Test @MediumTest @Feature("RenderTest") - @EnableFeatures({ChromeFeatureList.ADD_EDU_ACCOUNT_FROM_ACCOUNT_SETTINGS_FOR_SUPERVISED_USERS}) + @EnableFeatures({ChromeFeatureList.ADD_EDU_ACCOUNT_FROM_ACCOUNT_SETTINGS_FOR_SUPERVISED_USERS, + SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID}) public void testAccountManagementViewForChildAccountWithSecondaryEduAccountAndAddEduAccountEnabled() throws Exception {
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java index 641a1de..941d291b 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebApkUpdateManagerTest.java
@@ -25,9 +25,9 @@ import org.chromium.base.test.params.ParameterProvider; import org.chromium.base.test.params.ParameterSet; import org.chromium.base.test.params.ParameterizedRunner; +import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.CommandLineFlags; -import org.chromium.base.test.util.DoNotBatch; import org.chromium.base.test.util.Feature; import org.chromium.blink.mojom.DisplayMode; import org.chromium.chrome.browser.ActivityTabProvider; @@ -51,7 +51,6 @@ import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.device.mojom.ScreenOrientationLockType; import org.chromium.net.test.EmbeddedTestServer; -import org.chromium.net.test.EmbeddedTestServerRule; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; @@ -66,7 +65,7 @@ * Tests WebApkUpdateManager. This class contains tests which cannot be done as JUnit tests. */ @RunWith(ParameterizedRunner.class) -@DoNotBatch(reason = "The update pipeline runs once per startup.") +@Batch(Batch.PER_CLASS) @ParameterAnnotations.UseRunnerDelegate(ChromeJUnit4RunnerDelegate.class) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE, ChromeSwitches.CHECK_FOR_WEB_MANIFEST_UPDATE_ON_STARTUP}) @@ -75,9 +74,6 @@ @Rule public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); - @Rule - public EmbeddedTestServerRule mTestServerRule = new EmbeddedTestServerRule(); - /** * The parameters for the App Identity tests (for which flag is enabled). */ @@ -245,7 +241,7 @@ mActivityTestRule.startMainActivityOnBlankPage(); mActivity = mActivityTestRule.getActivity(); mTab = mActivity.getActivityTab(); - mTestServer = mTestServerRule.getServer(); + mTestServer = mActivityTestRule.getTestServer(); mTestValues = new FeatureList.TestValues(); FeatureList.setTestValues(mTestValues); @@ -471,6 +467,8 @@ boolean allowShellVersion, boolean changeName, boolean changeShortName, boolean changeIcon) throws Exception { mIconOrNameUpdateDialogShown = false; + WebappDataStorage storage = WebappRegistry.getInstance().getWebappDataStorage(WEBAPK_ID); + storage.updateLastWebApkUpdateHashAccepted(""); CreationData creationData = defaultCreationData(); creationData.startUrl =
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java index 7b01586..d460c3d2 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutHelperTest.java
@@ -514,6 +514,35 @@ // Setup with 5 tabs. Select 2nd tab. initializeTest(false, false, true, 1, 5); mStripLayoutHelper.onSizeChanged(SCREEN_WIDTH, SCREEN_HEIGHT, false, TIMESTAMP); + + // Start reorder mode at 2nd tab + mStripLayoutHelper.startReorderModeAtIndexForTesting(1); + // Trigger update to set divider values. + mStripLayoutHelper.updateLayout(TIMESTAMP); + + StripLayoutTab[] tabs = mStripLayoutHelper.getStripLayoutTabs(); + // Verify only 4th and 5th tab's start divider is visible. + assertFalse( + "First start divider should always be hidden.", tabs[0].isStartDividerVisible()); + assertFalse("Start divider should be hidden.", tabs[1].isStartDividerVisible()); + assertFalse("Start divider should be hidden.", tabs[2].isStartDividerVisible()); + assertTrue("Start divider should be hidden.", tabs[3].isStartDividerVisible()); + assertTrue("Start divider should be visible.", tabs[4].isStartDividerVisible()); + + // Verify end divider visible only for 5th tab. + assertFalse("End divider should be hidden.", tabs[0].isEndDividerVisible()); + assertFalse("End divider should be hidden.", tabs[1].isEndDividerVisible()); + assertFalse("End divider should be hidden.", tabs[2].isEndDividerVisible()); + assertFalse("End divider should be hidden.", tabs[3].isEndDividerVisible()); + assertTrue("End divider should be visible.", tabs[4].isEndDividerVisible()); + } + + @Test + @Feature("Tab Strip Redesign") + public void testUpdateDividers_InReorderModeWithTabGroups() { + // Setup with 5 tabs. Select 2nd tab. + initializeTest(false, false, true, 1, 5); + mStripLayoutHelper.onSizeChanged(SCREEN_WIDTH, SCREEN_HEIGHT, false, TIMESTAMP); // group 2nd and 3rd tab. groupTabs(1, 3);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java index 76c311f..39fd8fd7 100644 --- a/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java +++ b/chrome/android/junit/src/org/chromium/chrome/browser/tab/RequestDesktopUtilsUnitTest.java
@@ -779,78 +779,6 @@ } @Test - public void testMaybeDisableGlobalSetting_FinchParamChanged_ScreenWidthDp() { - // Default-enable the global setting. - Map<String, String> params = new HashMap<>(); - params.put( - RequestDesktopUtils.PARAM_GLOBAL_SETTING_DEFAULT_ON_SMALLEST_SCREEN_WIDTH, "600"); - enableFeatureWithParams(ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS, params, true); - RequestDesktopUtils.maybeDefaultEnableGlobalSetting( - RequestDesktopUtils.DEFAULT_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES, - mProfile, mActivity); - - // Update finch param and initiate downgrade. - params.put( - RequestDesktopUtils.PARAM_GLOBAL_SETTING_DEFAULT_ON_SMALLEST_SCREEN_WIDTH, "800"); - enableFeatureWithParams(ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS, params, true); - RequestDesktopUtils.maybeDefaultEnableGlobalSetting( - RequestDesktopUtils.DEFAULT_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES, - mProfile, mActivity); - enableFeatureWithParams( - ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS_DOWNGRADE, null, true); - boolean didDisable = RequestDesktopUtils.maybeDisableGlobalSetting(mProfile); - - Assert.assertTrue( - "Desktop site global setting should be disabled on downgrade.", didDisable); - Assert.assertEquals("Desktop site content setting should be set correctly.", - ContentSettingValues.BLOCK, mRdsDefaultValue); - Assert.assertFalse( - "SharedPreference DEFAULT_ENABLED_DESKTOP_SITE_GLOBAL_SETTING should be removed.", - mSharedPreferencesManager.contains( - ChromePreferenceKeys.DEFAULT_ENABLED_DESKTOP_SITE_GLOBAL_SETTING)); - Assert.assertFalse( - "SharedPreference DEFAULT_ENABLE_DESKTOP_SITE_GLOBAL_SETTING_COHORT should be removed.", - mSharedPreferencesManager.contains( - ChromePreferenceKeys.DEFAULT_ENABLE_DESKTOP_SITE_GLOBAL_SETTING_COHORT)); - } - - @Test - public void testMaybeDisableGlobalSetting_FinchParamChanged_ScreenSizeInches() { - // Default-enable the global setting. - Map<String, String> params = new HashMap<>(); - params.put( - RequestDesktopUtils.PARAM_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES, - "10.0"); - enableFeatureWithParams(ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS, params, true); - RequestDesktopUtils.maybeDefaultEnableGlobalSetting( - /*displaySizeInInches*/ 10.5, mProfile, mActivity); - - // Update finch param and initiate downgrade. - params.put( - RequestDesktopUtils.PARAM_GLOBAL_SETTING_DEFAULT_ON_DISPLAY_SIZE_THRESHOLD_INCHES, - "11.0"); - enableFeatureWithParams(ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS, params, true); - RequestDesktopUtils.maybeDefaultEnableGlobalSetting( - /*displaySizeInInches*/ 10.5, mProfile, mActivity); - enableFeatureWithParams( - ChromeFeatureList.REQUEST_DESKTOP_SITE_DEFAULTS_DOWNGRADE, null, true); - boolean didDisable = RequestDesktopUtils.maybeDisableGlobalSetting(mProfile); - - Assert.assertTrue( - "Desktop site global setting should be disabled on downgrade.", didDisable); - Assert.assertEquals("Desktop site content setting should be set correctly.", - ContentSettingValues.BLOCK, mRdsDefaultValue); - Assert.assertFalse( - "SharedPreference DEFAULT_ENABLED_DESKTOP_SITE_GLOBAL_SETTING should be removed.", - mSharedPreferencesManager.contains( - ChromePreferenceKeys.DEFAULT_ENABLED_DESKTOP_SITE_GLOBAL_SETTING)); - Assert.assertFalse( - "SharedPreference DEFAULT_ENABLE_DESKTOP_SITE_GLOBAL_SETTING_COHORT should be removed.", - mSharedPreferencesManager.contains( - ChromePreferenceKeys.DEFAULT_ENABLE_DESKTOP_SITE_GLOBAL_SETTING_COHORT)); - } - - @Test public void testShouldShowGlobalSettingOptInMessage_ExperimentControlGroup() { when(mTracker.wouldTriggerHelpUI(FeatureConstants.REQUEST_DESKTOP_SITE_OPT_IN_FEATURE)) .thenReturn(true);
diff --git a/chrome/android/profiles/arm.newest.txt b/chrome/android/profiles/arm.newest.txt index 130c4e3c..b598f96 100644 --- a/chrome/android/profiles/arm.newest.txt +++ b/chrome/android/profiles/arm.newest.txt
@@ -1 +1 @@ -chromeos-chrome-arm-112.0.5579.0_rc-r2-merged.afdo.bz2 +chromeos-chrome-arm-112.0.5583.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/android/profiles/newest.txt b/chrome/android/profiles/newest.txt index 20c8405..a1fc6f7 100644 --- a/chrome/android/profiles/newest.txt +++ b/chrome/android/profiles/newest.txt
@@ -1 +1 @@ -chromeos-chrome-amd64-112.0.5579.0_rc-r2-merged.afdo.bz2 +chromeos-chrome-amd64-112.0.5583.0_rc-r1-merged.afdo.bz2
diff --git a/chrome/app/os_settings_search_tag_strings.grdp b/chrome/app/os_settings_search_tag_strings.grdp index 0fc1394..20bf39d6 100644 --- a/chrome/app/os_settings_search_tag_strings.grdp +++ b/chrome/app/os_settings_search_tag_strings.grdp
@@ -388,6 +388,9 @@ <message name="IDS_OS_SETTINGS_TAG_LOCK_SCREEN_PIN_OR_PASSWORD_ALT1" desc="Text for search result item which, when clicked, navigates the user to lock screen settings, with an option to determine whether the device can be unlocked with a PIN or a password. Alternate phrase for: 'Screen lock PIN'"> Screen lock password </message> + <message name="IDS_OS_SETTINGS_TAG_MANAGE_OTHER_PEOPLE_PAGE" desc="Text for search result item which, when clicked, navigates the user to manage other user account privileges."> + Manage other people + </message> <message name="IDS_OS_SETTINGS_TAG_GUEST_BROWSING" desc="Text for search result item which, when clicked, navigates the user to account settings, with a toggle to enable/disable guest browsing."> Guest browsing </message>
diff --git a/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_MANAGE_OTHER_PEOPLE_PAGE.png.sha1 b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_MANAGE_OTHER_PEOPLE_PAGE.png.sha1 new file mode 100644 index 0000000..77dc2839 --- /dev/null +++ b/chrome/app/os_settings_search_tag_strings_grdp/IDS_OS_SETTINGS_TAG_MANAGE_OTHER_PEOPLE_PAGE.png.sha1
@@ -0,0 +1 @@ +76337d76bb76ac05d312e72f8eef098f711a4b5d \ No newline at end of file
diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index b9ab678..278d2be 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc
@@ -642,36 +642,6 @@ #endif // BUILDFLAG(IS_ANDROID) -const FeatureEntry::FeatureParam - kAutofillSaveCardUiExperimentEnableCurrentWithUserAvatarAndEmail[] = { - {"autofill_save_card_ui_experiment_selector_in_number", "3"}, -}; - -const FeatureEntry::FeatureParam - kAutofillSaveCardUiExperimentEnableEncryptedAndSecure[] = { - {"autofill_save_card_ui_experiment_selector_in_number", "2"}, -}; - -const FeatureEntry::FeatureParam - kAutofillSaveCardUiExperimentEnableFasterAndProtected[] = { - {"autofill_save_card_ui_experiment_selector_in_number", "1"}, -}; - -const FeatureEntry::FeatureVariation kAutofillSaveCardUiExperimentOptions[] = { - {flag_descriptions::kAutofillSaveCardUiExperimentFasterAndProtected, - kAutofillSaveCardUiExperimentEnableFasterAndProtected, - std::size(kAutofillSaveCardUiExperimentEnableFasterAndProtected), nullptr}, - {flag_descriptions::kAutofillSaveCardUiExperimentEncryptedAndSecure, - kAutofillSaveCardUiExperimentEnableEncryptedAndSecure, - std::size(kAutofillSaveCardUiExperimentEnableEncryptedAndSecure), nullptr}, - {flag_descriptions:: - kAutofillSaveCardUiExperimentCurrentWithUserAvatarAndEmail, - kAutofillSaveCardUiExperimentEnableCurrentWithUserAvatarAndEmail, - std::size( - kAutofillSaveCardUiExperimentEnableCurrentWithUserAvatarAndEmail), - nullptr}, -}; - #if !BUILDFLAG(IS_CHROMEOS_ASH) const FeatureEntry::FeatureParam kForceDark_SimpleHsl[] = { {"inversion_method", "hsl_based"}, @@ -4496,6 +4466,11 @@ flag_descriptions::kInfobarScrollOptimizationName, flag_descriptions::kInfobarScrollOptimizationDescription, kOsAndroid, FEATURE_VALUE_TYPE(chrome::android::kInfobarScrollOptimization)}, + {"share-sheet-migration-android", + flag_descriptions::kShareSheetMigrationAndroidName, + flag_descriptions::kShareSheetMigrationAndroidDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kShareSheetMigrationAndroid)}, + #endif // BUILDFLAG(IS_ANDROID) {"disallow-doc-written-script-loads", flag_descriptions::kDisallowDocWrittenScriptsUiName, @@ -8747,14 +8722,6 @@ permissions::features::kRecordPermissionExpirationTimestamps)}, #endif // !BUILDFLAG(IS_ANDROID) - {"autofill-enable-upstream-save-card-offer-ui-experiment", - flag_descriptions::kAutofillSaveCardUiExperimentName, - flag_descriptions::kAutofillSaveCardUiExperimentDescription, kOsDesktop, - FEATURE_WITH_PARAMS_VALUE_TYPE( - autofill::features::kAutofillSaveCardUiExperiment, - kAutofillSaveCardUiExperimentOptions, - "AutofillSaveCardUiExperiment")}, - #if BUILDFLAG(IS_ANDROID) {"network-service-in-process", flag_descriptions::kNetworkServiceInProcessName, @@ -9308,6 +9275,12 @@ flag_descriptions::kWebViewTagMPArchBehaviorDescription, kOsDesktop, FEATURE_VALUE_TYPE(extensions_features::kWebviewTagMPArchBehavior)}, #endif // BUILDFLAG(ENABLE_EXTENSIONS) + // +#if BUILDFLAG(IS_ANDROID) + {"thumbnail-cache-refactor", flag_descriptions::kThumbnailCacheRefactorName, + flag_descriptions::kThumbnailCacheRefactorDescription, kOsAndroid, + FEATURE_VALUE_TYPE(chrome::android::kThumbnailCacheRefactor)}, +#endif // BUILDFLAG(IS_ANDROID) {"autofill-enable-page-load-metadata-integration", flag_descriptions::kAutofillEnablePageLoadMetadataIntegrationName,
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java index 4be657f7..b0199a95 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java +++ b/chrome/browser/android/examples/custom_tabs_client/src/java/org/chromium/customtabsclient/MainActivity.java
@@ -81,6 +81,7 @@ private static final String SHARED_PREF_THEME = "Theme"; private static final String SHARED_PREF_URL_HIDING = "UrlHiding"; private static final String SHARED_PREF_FORCE_ENGAGEMENT_SIGNALS = "ForceEngagementSignals"; + private static final String SHARED_PREF_SIDE_SHEET_MAX_BUTTON = "SideSheetMaxButton"; private static final int CLOSE_ICON_X = 0; private static final int CLOSE_ICON_BACK = 1; private static final int CLOSE_ICON_CHECK = 2; @@ -88,6 +89,11 @@ private static final int CHECKED = 1; private static final int ACTIVITY_HEIGHT_FIXED = 2; private static final int BACKGROUND_INTERACT_OFF_VALUE = 2; + + /** Extra that enables the maximization button on the side sheet Custom Tab toolbar. */ + public static final String EXTRA_ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION = + "androix.browser.customtabs.extra.EXTRA_ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION"; + /** * Minimal height the bottom sheet CCT should show is half of the display height. */ @@ -123,6 +129,7 @@ private CheckBox mUrlHidingCheckbox; private CheckBox mBackgroundInteractCheckbox; private CheckBox mForceEngagementSignalsCheckbox; + private CheckBox mSideSheetMaxButtonCheckbox; private TextView mPcctBreakpointLabel; private SeekBar mPcctBreakpointSlider; private TextView mPcctInitialHeightLabel; @@ -409,6 +416,9 @@ mForceEngagementSignalsCheckbox = findViewById(R.id.force_engagement_signals_checkbox); mForceEngagementSignalsCheckbox.setChecked( mSharedPref.getInt(SHARED_PREF_FORCE_ENGAGEMENT_SIGNALS, CHECKED) == CHECKED); + mSideSheetMaxButtonCheckbox = findViewById(R.id.side_sheet_max_button_checkbox); + mSideSheetMaxButtonCheckbox.setChecked( + mSharedPref.getInt(SHARED_PREF_SIDE_SHEET_MAX_BUTTON, CHECKED) == CHECKED); } private void initializeCctSpinner() { @@ -699,6 +709,10 @@ customTabsIntent.intent.putExtra( "androidx.browser.customtabs.extra.ACTIVITY_SIDE_SHEET_BREAKPOINT_DP", pcctBreakpointDp); + if (mSideSheetMaxButtonCheckbox.isChecked()) { + customTabsIntent.intent.putExtra( + EXTRA_ACTIVITY_SIDE_SHEET_ENABLE_MAXIMIZATION, true); + } if (!mPcctHeightResizableCheckbox.isChecked()) { customTabsIntent.intent.putExtra( "androidx.browser.customtabs.extra.ACTIVITY_HEIGHT_RESIZE_BEHAVIOR", @@ -745,6 +759,8 @@ editor.putInt(SHARED_PREF_CLOSE_POSITION, closeButtonPosition); editor.putInt(SHARED_PREF_HEIGHT_RESIZABLE, mPcctHeightResizableCheckbox.isChecked() ? CHECKED : UNCHECKED); + editor.putInt(SHARED_PREF_SIDE_SHEET_MAX_BUTTON, + mSideSheetMaxButtonCheckbox.isChecked() ? CHECKED : UNCHECKED); editor.apply(); } }
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml index a32b619c..000f700 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml +++ b/chrome/browser/android/examples/custom_tabs_client/src/res/layout/main.xml
@@ -478,5 +478,12 @@ android:layout_height="wrap_content" android:checked = "true" android:text="@string/background_interact_text" /> + + <CheckBox + android:id="@+id/side_sheet_max_button_checkbox" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:checked = "true" + android:text="@string/side_sheet_max_button_text" /> </LinearLayout> </ScrollView>
diff --git a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml index 78f3265..d70c980 100644 --- a/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml +++ b/chrome/browser/android/examples/custom_tabs_client/src/res/values/strings.xml
@@ -55,5 +55,5 @@ <string name="theme_button_dark">Dark</string> <string name="cct_type">CCT Type:</string> <string name="background_interact_text">Interact with Background App</string> - + <string name="side_sheet_max_button_text">Add Max Button(SideSheet only)</string> </resources>
diff --git a/chrome/browser/apps/app_preload_service/app_preload_service.cc b/chrome/browser/apps/app_preload_service/app_preload_service.cc index 2b077fa..d18d6909 100644 --- a/chrome/browser/apps/app_preload_service/app_preload_service.cc +++ b/chrome/browser/apps/app_preload_service/app_preload_service.cc
@@ -12,7 +12,10 @@ #include "base/feature_list.h" #include "base/functional/bind.h" #include "base/logging.h" +#include "base/metrics/histogram_functions.h" #include "base/ranges/algorithm.h" +#include "base/strings/strcat.h" +#include "base/time/time.h" #include "chrome/browser/apps/app_preload_service/app_preload_service_factory.h" #include "chrome/browser/apps/app_preload_service/device_info_manager.h" #include "chrome/browser/apps/app_preload_service/preload_app_definition.h" @@ -43,6 +46,11 @@ static constexpr char kFirstLoginFlowCompletedKey[] = "first_login_flow_completed"; +static constexpr char kFirstLoginFlowHistogramSuccessName[] = + "AppPreloadService.FirstLoginFlowTime.Success"; +static constexpr char kFirstLoginFlowHistogramFailureName[] = + "AppPreloadService.FirstLoginFlowTime.Failure"; + } // namespace namespace apps { @@ -84,6 +92,8 @@ } void AppPreloadService::StartFirstLoginFlow() { + auto start_time = base::TimeTicks::Now(); + // Preloads currently run for new users only. The "completed" pref is only set // when preloads finish successfully, so preloads will be retried if they have // been "started" but never "completed". @@ -101,22 +111,24 @@ base::FeatureList::IsEnabled(kAppPreloadServiceForceRun)) { device_info_manager_->GetDeviceInfo( base::BindOnce(&AppPreloadService::StartAppInstallationForFirstLogin, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), start_time)); } } void AppPreloadService::StartAppInstallationForFirstLogin( + base::TimeTicks start_time, DeviceInfo device_info) { server_connector_->GetAppsForFirstLogin( device_info, profile_->GetURLLoaderFactory(), base::BindOnce(&AppPreloadService::OnGetAppsForFirstLoginCompleted, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), start_time)); } void AppPreloadService::OnGetAppsForFirstLoginCompleted( + base::TimeTicks start_time, absl::optional<std::vector<PreloadAppDefinition>> apps) { if (!apps.has_value()) { - OnFirstLoginFlowComplete(/*success=*/false); + OnFirstLoginFlowComplete(/*success=*/false, start_time); return; } @@ -130,7 +142,7 @@ const auto install_barrier_callback_ = base::BarrierCallback<bool>( apps.value().size(), base::BindOnce(&AppPreloadService::OnAllAppInstallationFinished, - weak_ptr_factory_.GetWeakPtr())); + weak_ptr_factory_.GetWeakPtr(), start_time)); for (const PreloadAppDefinition& app : apps.value()) { web_app_installer_->InstallApp(app, install_barrier_callback_); @@ -138,17 +150,23 @@ } void AppPreloadService::OnAllAppInstallationFinished( + base::TimeTicks start_time, const std::vector<bool>& results) { OnFirstLoginFlowComplete( - base::ranges::all_of(results, [](bool b) { return b; })); + base::ranges::all_of(results, [](bool b) { return b; }), start_time); } -void AppPreloadService::OnFirstLoginFlowComplete(bool success) { +void AppPreloadService::OnFirstLoginFlowComplete(bool success, + base::TimeTicks start_time) { if (success) { ScopedDictPrefUpdate(profile_->GetPrefs(), prefs::kApsStateManager) ->Set(kFirstLoginFlowCompletedKey, true); } + base::UmaHistogramMediumTimes(success ? kFirstLoginFlowHistogramSuccessName + : kFirstLoginFlowHistogramFailureName, + base::TimeTicks::Now() - start_time); + if (installation_complete_callback_) { std::move(installation_complete_callback_).Run(success); }
diff --git a/chrome/browser/apps/app_preload_service/app_preload_service.h b/chrome/browser/apps/app_preload_service/app_preload_service.h index 7477c3a..0b33f2a 100644 --- a/chrome/browser/apps/app_preload_service/app_preload_service.h +++ b/chrome/browser/apps/app_preload_service/app_preload_service.h
@@ -18,6 +18,10 @@ class Profile; +namespace base { +class TimeTicks; +} // namespace base + namespace user_prefs { class PrefRegistrySyncable; } // namespace user_prefs @@ -66,15 +70,18 @@ // service, processes the list and installs the app list. This call should // only be used the first time a profile is created on the device as this call // installs a set of default and OEM apps. - void StartAppInstallationForFirstLogin(DeviceInfo device_info); + void StartAppInstallationForFirstLogin(base::TimeTicks start_time, + DeviceInfo device_info); // Processes the list of apps retrieved by the server connector. void OnGetAppsForFirstLoginCompleted( + base::TimeTicks start_time, absl::optional<std::vector<PreloadAppDefinition>> apps); - void OnAllAppInstallationFinished(const std::vector<bool>& results); + void OnAllAppInstallationFinished(base::TimeTicks start_time, + const std::vector<bool>& results); // Called when the installation flow started by // `StartAppInstallationForFirstLogin` is complete, with `success` indicating // whether the overall flow was successful. - void OnFirstLoginFlowComplete(bool success); + void OnFirstLoginFlowComplete(bool success, base::TimeTicks start_time); bool ShouldInstallApp(const PreloadAppDefinition& app);
diff --git a/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc b/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc index 8743a86..cf969499 100644 --- a/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc +++ b/chrome/browser/apps/app_preload_service/app_preload_service_browsertest.cc
@@ -10,6 +10,7 @@ #include "base/functional/bind.h" #include "base/strings/strcat.h" #include "base/strings/string_util.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "base/test/test_future.h" #include "chrome/browser/apps/app_preload_service/app_preload_service.h" @@ -30,7 +31,12 @@ namespace { constexpr char kDefaultManifestUrl[] = "/manifest.json"; -} + +static constexpr char kFirstLoginFlowHistogramSuccessName[] = + "AppPreloadService.FirstLoginFlowTime.Success"; +static constexpr char kFirstLoginFlowHistogramFailureName[] = + "AppPreloadService.FirstLoginFlowTime.Failure"; +} // namespace class AppPreloadServiceBrowserTest : public InProcessBrowserTest { public: @@ -123,6 +129,7 @@ }; IN_PROC_BROWSER_TEST_F(AppPreloadServiceBrowserTest, OemWebAppInstall) { + base::HistogramTester histograms; proto::AppProvisioningListAppsResponse response; auto* app = response.add_apps_to_install(); app->set_name("Example App"); @@ -159,6 +166,9 @@ EXPECT_EQ(update.PublisherId(), "https://www.example.com/index.html"); }); ASSERT_TRUE(found); + + histograms.ExpectTotalCount(kFirstLoginFlowHistogramSuccessName, 1); + histograms.ExpectTotalCount(kFirstLoginFlowHistogramFailureName, 0); } IN_PROC_BROWSER_TEST_F(AppPreloadServiceBrowserTest, IgnoreDefaultAppInstall) { @@ -303,6 +313,7 @@ // Verifies that failed installations are retried on the next login flow, and // already installed apps are ignored. IN_PROC_BROWSER_TEST_F(AppPreloadServiceBrowserTest, RetryFailedApps) { + base::HistogramTester histograms; constexpr char kOriginalManifestUrl1[] = "https://www.foo.com/manifest.json"; constexpr char kOriginalManifestUrl2[] = "https://www.bar.com/manifest.json"; @@ -350,6 +361,9 @@ service->StartFirstLoginFlowForTesting(result.GetCallback()); ASSERT_FALSE(result.Get()); + histograms.ExpectTotalCount(kFirstLoginFlowHistogramSuccessName, 0); + histograms.ExpectTotalCount(kFirstLoginFlowHistogramFailureName, 1); + // bar.json should be retried, and will now succeed. foo.json is skipped // (ignoring the error it would give), and so the whole flow is successful. SetManifestResponse("/manifest/foo.json", ""); @@ -369,6 +383,9 @@ web_app::GenerateAppId(absl::nullopt, GURL("https://www.bar.com/")); found = app_registry_cache().ForOneApp(app_id2, [](const AppUpdate&) {}); ASSERT_TRUE(found); + + histograms.ExpectTotalCount(kFirstLoginFlowHistogramSuccessName, 1); + histograms.ExpectTotalCount(kFirstLoginFlowHistogramFailureName, 1); } } // namespace apps
diff --git a/chrome/browser/ash/bluetooth/debug_logs_manager.cc b/chrome/browser/ash/bluetooth/debug_logs_manager.cc index 92ca8e1e..8befe1e 100644 --- a/chrome/browser/ash/bluetooth/debug_logs_manager.cc +++ b/chrome/browser/ash/bluetooth/debug_logs_manager.cc
@@ -116,11 +116,13 @@ VLOG(1) << (enable ? "Enabling" : "Disabling") << " bluetooth verbose logs"; if (floss::features::IsFlossEnabled()) { - floss::FlossDBusManager::Get()->GetLoggingClient()->SetDebugLogging( - base::BindOnce(&DebugLogsManager::OnFlossSetDebugLogging, - weak_ptr_factory_.GetWeakPtr(), enable, - num_completed_attempts), - enable); + if (adapter_ && adapter_->IsPowered()) { + floss::FlossDBusManager::Get()->GetLoggingClient()->SetDebugLogging( + base::BindOnce(&DebugLogsManager::OnFlossSetDebugLogging, + weak_ptr_factory_.GetWeakPtr(), enable, + num_completed_attempts), + enable); + } } else { bluez::BluezDBusManager::Get() ->GetBluetoothDebugManagerClient()
diff --git a/chrome/browser/ash/bluetooth/debug_logs_manager_unittest.cc b/chrome/browser/ash/bluetooth/debug_logs_manager_unittest.cc index 865e36c98..d1f5f64 100644 --- a/chrome/browser/ash/bluetooth/debug_logs_manager_unittest.cc +++ b/chrome/browser/ash/bluetooth/debug_logs_manager_unittest.cc
@@ -144,6 +144,11 @@ base::RunLoop().RunUntilIdle(); } + bool IsDebugEnabled() { + return debug_logs_manager_->GetDebugLogsState() == + DebugLogsManager::DebugLogsState::kSupportedAndEnabled; + } + private: base::test::ScopedFeatureList feature_list_; bool is_debug_toggle_flag_enabled_ = false; @@ -267,12 +272,14 @@ EnableFlossFlag(); InitFeatures(); + // Until we're powered, setting debug logging should fail but the default + // state should be persisted. EXPECT_EQ(fake_floss_logging_client()->GetDebugEnabledForTesting(), false); InstantiateDebugManager(kTestGooglerEmail); - EXPECT_EQ(fake_floss_logging_client()->GetDebugEnabledForTesting(), true); - - fake_floss_logging_client()->SetDebugEnabledForTesting(false); EXPECT_EQ(fake_floss_logging_client()->GetDebugEnabledForTesting(), false); + EXPECT_EQ(IsDebugEnabled(), true); + + // Powering on should enable the flag. SimulatePowered(/*powered=*/true); EXPECT_EQ(fake_floss_logging_client()->GetDebugEnabledForTesting(), true); SimulatePowered(/*powered=*/false);
diff --git a/chrome/browser/ash/drive/drive_integration_service.cc b/chrome/browser/ash/drive/drive_integration_service.cc index f5882a9..939ae1c 100644 --- a/chrome/browser/ash/drive/drive_integration_service.cc +++ b/chrome/browser/ash/drive/drive_integration_service.cc
@@ -56,6 +56,7 @@ #include "components/drive/drive_notification_manager.h" #include "components/drive/drive_pref_names.h" #include "components/drive/event_logger.h" +#include "components/drive/file_errors.h" #include "components/drive/resource_metadata_storage.h" #include "components/metrics/metrics_pref_names.h" #include "components/prefs/pref_change_registrar.h" @@ -1208,8 +1209,7 @@ } auto query_params = drivefs::mojom::QueryParameters::New(); - query_params->query_source = - drivefs::mojom::QueryParameters::QuerySource::kLocalOnly; + query_params->page_size = 1000; query_params->available_offline = true; int64_t total_size = 0; @@ -1232,7 +1232,10 @@ drive::FileError error, absl::optional<std::vector<drivefs::mojom::QueryItemPtr>> results) { if (!ash::features::IsDriveFsBulkPinningEnabled() || - error != drive::FILE_ERROR_OK || results->empty()) { + error != drive::FILE_ERROR_OK || results->empty() || + callback.IsCancelled()) { + LOG_IF(ERROR, error != drive::FILE_ERROR_OK) + << "Failed to get offline size: " << drive::FileErrorToString(error); std::move(callback).Run(total_size); return; }
diff --git a/chrome/browser/ash/events/OWNERS b/chrome/browser/ash/events/OWNERS index 637480f..1c7633b7 100644 --- a/chrome/browser/ash/events/OWNERS +++ b/chrome/browser/ash/events/OWNERS
@@ -1,2 +1,3 @@ +zentaro@chromium.org per-file *event_rewriter* = kpschoedel@chromium.org
diff --git a/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc b/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc index 3a853b0a..f0e2c7a0 100644 --- a/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc +++ b/chrome/browser/ash/login/configuration_based_oobe_browsertest.cc
@@ -26,6 +26,7 @@ #include "chromeos/ash/components/dbus/shill/shill_manager_client.h" #include "chromeos/ash/components/dbus/update_engine/fake_update_engine_client.h" #include "chromeos/ash/components/install_attributes/stub_install_attributes.h" +#include "chromeos/ash/components/network/network_state_handler.h" #include "chromeos/dbus/constants/dbus_switches.h" #include "chromeos/test/chromeos_test_utils.h" #include "components/language/core/browser/pref_names.h" @@ -103,6 +104,9 @@ // Make sure that OOBE is run as an "official" build. LoginDisplayHost::default_host()->GetWizardContext()->is_branded_build = true; + + // Clear portal list (as it is by default in OOBE). + NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); } protected:
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc index 4f9c6b6f..98df496 100644 --- a/chrome/browser/ash/login/users/chrome_user_manager_impl.cc +++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.cc
@@ -16,6 +16,7 @@ #include "ash/constants/ash_pref_names.h" #include "ash/constants/ash_switches.h" #include "ash/public/cpp/session/session_controller.h" +#include "base/barrier_closure.h" #include "base/command_line.h" #include "base/compiler_specific.h" #include "base/containers/adapters.h" @@ -916,10 +917,27 @@ void ChromeUserManagerImpl::RemoveNonCryptohomeData( const AccountId& account_id) { - // Wallpaper removal depends on user preference, so it must happen before - // `known_user::RemovePrefs`. See https://crbug.com/778077. - for (auto& handler : cloud_external_data_policy_handlers_) - handler->RemoveForAccountId(account_id); + // Wallpaper removal can be async if system salt is not yet received (see + // `WallpaperControllerClientImpl::GetFilesId`), and depends on user + // preference, so it must happen before `known_user::RemovePrefs`. + // See https://crbug.com/778077. Here we use a latch to ensure that + // `known_user::RemovePrefs` does indeed get invoked after wallpaper and other + // external data that might be associated with `account_id` are removed (in + // case those removal operations are async). + remove_non_cryptohome_data_barrier_ = base::BarrierClosure( + cloud_external_data_policy_handlers_.size(), + base::BindOnce(&ChromeUserManagerImpl:: + RemoveNonCryptohomeDataPostExternalDataRemoval, + weak_factory_.GetWeakPtr(), account_id)); + + for (auto& handler : cloud_external_data_policy_handlers_) { + handler->RemoveForAccountId(account_id, + remove_non_cryptohome_data_barrier_); + } +} + +void ChromeUserManagerImpl::RemoveNonCryptohomeDataPostExternalDataRemoval( + const AccountId& account_id) { // TODO(tbarzic): Forward data removal request to HammerDeviceHandler, // instead of removing the prefs value here. if (GetLocalState()->FindPreference(prefs::kDetachableBaseDevices)) {
diff --git a/chrome/browser/ash/login/users/chrome_user_manager_impl.h b/chrome/browser/ash/login/users/chrome_user_manager_impl.h index 7d3b301..ed311670 100644 --- a/chrome/browser/ash/login/users/chrome_user_manager_impl.h +++ b/chrome/browser/ash/login/users/chrome_user_manager_impl.h
@@ -11,6 +11,7 @@ #include <string> #include <vector> +#include "base/functional/callback_forward.h" #include "base/memory/weak_ptr.h" #include "base/scoped_observation.h" #include "base/synchronization/lock.h" @@ -232,6 +233,15 @@ void UpdateOwnerId(); + // Remove non cryptohome data associated with the given `account_id` after + // having removed all external data (such as wallpapers and avatars) + // associated with that `account_id`, this function is guarded by a latch + // `remove_non_cryptohome_data_latch_` that ensures that all external data is + // removed prior to clearing prefs for `account_id`, as the removal of certain + // external data depends on prefs. + void RemoveNonCryptohomeDataPostExternalDataRemoval( + const AccountId& account_id); + // Interface to the signed settings store. CrosSettings* cros_settings_; @@ -281,6 +291,8 @@ bool user_added_removed_reporter_intialized_ = false; + base::RepeatingClosure remove_non_cryptohome_data_barrier_; + base::WeakPtrFactory<ChromeUserManagerImpl> weak_factory_{this}; };
diff --git a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc index 6591aae..6075a1e 100644 --- a/chrome/browser/ash/login/users/fake_chrome_user_manager.cc +++ b/chrome/browser/ash/login/users/fake_chrome_user_manager.cc
@@ -291,7 +291,7 @@ WallpaperControllerClientImpl::Get(); // `wallpaper_client` could be nullptr in tests. if (wallpaper_client) - wallpaper_client->RemoveUserWallpaper(account_id); + wallpaper_client->RemoveUserWallpaper(account_id, base::DoNothing()); ProfileHelper::Get()->RemoveUserFromListForTesting(account_id); const user_manager::UserList::iterator it =
diff --git a/chrome/browser/ash/login/wizard_controller.cc b/chrome/browser/ash/login/wizard_controller.cc index ab439ef..70aedb8 100644 --- a/chrome/browser/ash/login/wizard_controller.cc +++ b/chrome/browser/ash/login/wizard_controller.cc
@@ -199,8 +199,11 @@ #include "chromeos/ash/components/dbus/session_manager/session_manager_client.h" #include "chromeos/ash/components/dbus/update_engine/update_engine_client.h" #include "chromeos/ash/components/geolocation/simple_geolocation_provider.h" +#include "chromeos/ash/components/network/network_handler.h" +#include "chromeos/ash/components/network/network_handler_callbacks.h" #include "chromeos/ash/components/network/network_state.h" #include "chromeos/ash/components/network/network_state_handler.h" +#include "chromeos/ash/components/network/portal_detector/network_portal_detector.h" #include "chromeos/ash/components/settings/cros_settings_names.h" #include "chromeos/ash/components/settings/cros_settings_provider.h" #include "chromeos/ash/components/settings/timezone_settings.h" @@ -2165,7 +2168,12 @@ ServicesCustomizationDocument::GetInstance() ->EnsureCustomizationAppliedClosure()); + // Enable portal check for official builds. + // ChromiumOS builds would go though this code path too. + NetworkHandler::Get()->network_state_handler()->SetCheckPortalList( + NetworkStateHandler::kDefaultCheckPortalList); GetAutoEnrollmentController()->Start(); + network_portal_detector::GetInstance()->Enable(); } void WizardController::PerformOOBECompletedActions() {
diff --git a/chrome/browser/ash/login/wizard_controller_browsertest.cc b/chrome/browser/ash/login/wizard_controller_browsertest.cc index c67678ad..8e2f014 100644 --- a/chrome/browser/ash/login/wizard_controller_browsertest.cc +++ b/chrome/browser/ash/login/wizard_controller_browsertest.cc
@@ -529,6 +529,9 @@ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>( &test_url_loader_factory_)); + // Clear portal list (as it is by default in OOBE). + NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); + // Set up the mocks for all screens. mock_welcome_screen_ = MockScreenExpectLifecycle(std::make_unique<MockWelcomeScreen>( @@ -744,6 +747,9 @@ EXPECT_CALL(*mock_auto_enrollment_check_screen_, HideImpl()).Times(0); EXPECT_FALSE(ExistingUserController::current_controller() == nullptr); + EXPECT_EQ("ethernet,wifi,cellular", NetworkHandler::Get() + ->network_state_handler() + ->GetCheckPortalListForTest()); WaitUntilTimezoneResolved(); EXPECT_EQ( @@ -897,6 +903,10 @@ EXPECT_CALL(*mock_auto_enrollment_check_screen_, HideImpl()).Times(0); EXPECT_CALL(*mock_enrollment_screen_, HideImpl()).Times(0); content::RunAllPendingInMessageLoop(); + + EXPECT_EQ("ethernet,wifi,cellular", NetworkHandler::Get() + ->network_state_handler() + ->GetCheckPortalListForTest()); } IN_PROC_BROWSER_TEST_F(WizardControllerFlowTest, @@ -2522,6 +2532,9 @@ WizardController::default_controller(); wizard_controller->SetCurrentScreen(nullptr); + // Clear portal list (as it is by default in OOBE). + NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); + // Set up the mocks for all screens. mock_welcome_view_ = std::make_unique<MockWelcomeView>(); mock_welcome_screen_ = @@ -2645,6 +2658,13 @@ command_line->AppendSwitchPath(chromeos::switches::kFakeOobeConfiguration, configuration_file); } + + // WizardControllerTest: + void SetUpOnMainThread() override { + WizardControllerTest::SetUpOnMainThread(); + // Clear portal list (as it is by default in OOBE). + NetworkHandler::Get()->network_state_handler()->SetCheckPortalList(""); + } }; IN_PROC_BROWSER_TEST_F(WizardControllerOobeConfigurationTest, @@ -2712,8 +2732,15 @@ run_loop.Run(); } +#if BUILDFLAG(IS_CHROMEOS) +// Disabled due to crbug.com/1414116. +#define MAYBE_AdvanceToEnrollmentAfterRollback \ + DISABLED_AdvanceToEnrollmentAfterRollback +#else +#define MAYBE_AdvanceToEnrollmentAfterRollback AdvanceToEnrollmentAfterRollback +#endif IN_PROC_BROWSER_TEST_F(WizardControllerRollbackFlowTest, - AdvanceToEnrollmentAfterRollback) { + MAYBE_AdvanceToEnrollmentAfterRollback) { CheckCurrentScreen(WelcomeView::kScreenId); EXPECT_CALL(*mock_enrollment_screen_, ShowImpl()).Times(1);
diff --git a/chrome/browser/ash/net/network_portal_detector_impl.cc b/chrome/browser/ash/net/network_portal_detector_impl.cc index aba7bf7..d111b082 100644 --- a/chrome/browser/ash/net/network_portal_detector_impl.cc +++ b/chrome/browser/ash/net/network_portal_detector_impl.cc
@@ -14,6 +14,7 @@ #include "base/metrics/histogram_functions.h" #include "base/task/single_thread_task_runner.h" #include "build/branding_buildflags.h" +#include "chrome/browser/ash/login/startup_utils.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/net/system_network_context_manager.h" @@ -142,13 +143,18 @@ if (enabled_) return; +#if BUILDFLAG(GOOGLE_CHROME_BRANDING) + if (!StartupUtils::IsEulaAccepted()) { + NET_LOG(EVENT) << "NetworkPortalDetector: Eula not accepted."; + return; + } +#endif + NET_LOG(EVENT) << "NetworkPortalDetector Enabled."; DCHECK(is_idle()); enabled_ = true; // Ensure that Shill portal detection is enabled. - // TODO(b/265806000): Remove calls to SetCheckPortalList entirely once - // shill/init/shill.sh is updated. NetworkHandler::Get()->network_state_handler()->SetCheckPortalList( NetworkStateHandler::kDefaultCheckPortalList);
diff --git a/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.h b/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.h index a7cff55..137fabd 100644 --- a/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.h +++ b/chrome/browser/ash/policy/external_data/handlers/cloud_external_data_policy_handler.h
@@ -21,7 +21,8 @@ CloudExternalDataPolicyHandler& operator=( const CloudExternalDataPolicyHandler&) = delete; - virtual void RemoveForAccountId(const AccountId& account_id) = 0; + virtual void RemoveForAccountId(const AccountId& account_id, + base::OnceClosure on_removed) = 0; static AccountId GetAccountId(const std::string& user_id); };
diff --git a/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.cc b/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.cc index c42f49a..e5117e0 100644 --- a/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.cc +++ b/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.cc
@@ -61,17 +61,20 @@ } void CrostiniAnsiblePlaybookExternalDataHandler::RemoveForAccountId( - const AccountId& account_id) { + const AccountId& account_id, + base::OnceClosure on_removed) { Profile* profile = ash::ProfileHelper::Get()->GetProfileByAccountId(account_id); if (!profile) { LOG(ERROR) << "No profile for user is specified"; + std::move(on_removed).Run(); return; } profile->GetPrefs()->ClearPref( crostini::prefs::kCrostiniAnsiblePlaybookFilePath); profile->GetPrefs()->ClearPref( crostini::prefs::kCrostiniDefaultContainerConfigured); + std::move(on_removed).Run(); } } // namespace policy
diff --git a/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.h b/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.h index 1ab8d6cc..192dc65 100644 --- a/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.h +++ b/chrome/browser/ash/policy/external_data/handlers/crostini_ansible_playbook_external_data_handler.h
@@ -39,7 +39,8 @@ const std::string& user_id, std::unique_ptr<std::string> data, const base::FilePath& file_path) override; - void RemoveForAccountId(const AccountId& account_id) override; + void RemoveForAccountId(const AccountId& account_id, + base::OnceClosure on_removed) override; private: CloudExternalDataPolicyObserver crostini_ansible_observer_;
diff --git a/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.cc b/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.cc index 400f670..165c6e1 100644 --- a/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.cc +++ b/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.cc
@@ -49,10 +49,12 @@ } void PreconfiguredDeskTemplatesExternalDataHandler::RemoveForAccountId( - const AccountId& account_id) { + const AccountId& account_id, + base::OnceClosure on_removed) { DesksClient* dc = DesksClient::Get(); if (dc) dc->RemovePolicyPreconfiguredTemplate(account_id); + std::move(on_removed).Run(); } } // namespace policy
diff --git a/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.h b/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.h index cd36889..57abca61 100644 --- a/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.h +++ b/chrome/browser/ash/policy/external_data/handlers/preconfigured_desk_templates_external_data_handler.h
@@ -39,7 +39,8 @@ const std::string& user_id, std::unique_ptr<std::string> data, const base::FilePath& file_path) override; - void RemoveForAccountId(const AccountId& account_id) override; + void RemoveForAccountId(const AccountId& account_id, + base::OnceClosure on_removed) override; private: CloudExternalDataPolicyObserver preconfigured_desk_templates_observer_;
diff --git a/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.cc b/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.cc index 024ed50..414c6a7 100644 --- a/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.cc +++ b/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.cc
@@ -57,8 +57,10 @@ } void PrintServersExternalDataHandler::RemoveForAccountId( - const AccountId& account_id) { + const AccountId& account_id, + base::OnceClosure on_removed) { ash::PrintServersProviderFactory::Get()->RemoveForAccountId(account_id); + std::move(on_removed).Run(); } } // namespace policy
diff --git a/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.h b/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.h index 36614a0..00d9b58 100644 --- a/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.h +++ b/chrome/browser/ash/policy/external_data/handlers/print_servers_external_data_handler.h
@@ -42,7 +42,8 @@ const std::string& user_id, std::unique_ptr<std::string> data, const base::FilePath& file_path) override; - void RemoveForAccountId(const AccountId& account_id) override; + void RemoveForAccountId(const AccountId& account_id, + base::OnceClosure on_removed) override; private: CloudExternalDataPolicyObserver print_servers_observer_;
diff --git a/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.cc b/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.cc index 2c3df37..3b4dd2f 100644 --- a/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.cc +++ b/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.cc
@@ -70,11 +70,13 @@ } void PrintersExternalDataHandler::RemoveForAccountId( - const AccountId& account_id) { + const AccountId& account_id, + base::OnceClosure on_removed) { auto* factory = ash::BulkPrintersCalculatorFactory::Get(); if (factory) { factory->RemoveForUserId(account_id); } + std::move(on_removed).Run(); } } // namespace policy
diff --git a/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.h b/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.h index 8a96183..28fba2e 100644 --- a/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.h +++ b/chrome/browser/ash/policy/external_data/handlers/printers_external_data_handler.h
@@ -37,7 +37,8 @@ const std::string& user_id, std::unique_ptr<std::string> data, const base::FilePath& file_path) override; - void RemoveForAccountId(const AccountId& account_id) override; + void RemoveForAccountId(const AccountId& account_id, + base::OnceClosure on_removed) override; private: CloudExternalDataPolicyObserver printers_observer_;
diff --git a/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.cc b/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.cc index a92bd0c0..1b03b907 100644 --- a/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.cc +++ b/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.cc
@@ -56,10 +56,13 @@ } void UserAvatarImageExternalDataHandler::RemoveForAccountId( - const AccountId& account_id) { + const AccountId& account_id, + base::OnceClosure on_removed) { ash::ChromeUserManager::Get() ->GetUserImageManager(account_id) ->DeleteUserImage(); + + std::move(on_removed).Run(); } } // namespace policy
diff --git a/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.h b/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.h index 8c05c976..f864618 100644 --- a/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.h +++ b/chrome/browser/ash/policy/external_data/handlers/user_avatar_image_external_data_handler.h
@@ -41,7 +41,8 @@ const std::string& user_id, std::unique_ptr<std::string> data, const base::FilePath& file_path) override; - void RemoveForAccountId(const AccountId& account_id) override; + void RemoveForAccountId(const AccountId& account_id, + base::OnceClosure on_removed) override; private: CloudExternalDataPolicyObserver user_avatar_image_observer_;
diff --git a/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.cc b/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.cc index 1a318293..edaf268 100644 --- a/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.cc +++ b/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.cc
@@ -42,8 +42,10 @@ } void WallpaperImageExternalDataHandler::RemoveForAccountId( - const AccountId& account_id) { - WallpaperControllerClientImpl::Get()->RemoveUserWallpaper(account_id); + const AccountId& account_id, + base::OnceClosure on_removed) { + WallpaperControllerClientImpl::Get()->RemoveUserWallpaper( + account_id, std::move(on_removed)); } } // namespace policy
diff --git a/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.h b/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.h index 5a48cb1..0631efc 100644 --- a/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.h +++ b/chrome/browser/ash/policy/external_data/handlers/wallpaper_image_external_data_handler.h
@@ -39,7 +39,8 @@ const std::string& user_id, std::unique_ptr<std::string> data, const base::FilePath& file_path) override; - void RemoveForAccountId(const AccountId& account_id) override; + void RemoveForAccountId(const AccountId& account_id, + base::OnceClosure on_removed) override; private: CloudExternalDataPolicyObserver wallpaper_image_observer_;
diff --git a/chrome/browser/ash/video_conference/video_conference_app_service_client.cc b/chrome/browser/ash/video_conference/video_conference_app_service_client.cc index fdb9d72..1f2b5d08 100644 --- a/chrome/browser/ash/video_conference/video_conference_app_service_client.cc +++ b/chrome/browser/ash/video_conference/video_conference_app_service_client.cc
@@ -25,7 +25,7 @@ namespace ash { namespace { VideoConferenceAppServiceClient* g_client_instance = nullptr; -} +} // namespace VideoConferenceAppServiceClient::VideoConferenceAppServiceClient() : client_id_(base::UnguessableToken::Create()), @@ -148,11 +148,15 @@ const bool is_capturing_camera = update.Camera().value_or(false); const bool is_capturing_microphone = update.Microphone().value_or(false); + const bool is_already_tracked = base::Contains(id_to_app_state_, app_id); // We only want to start tracking a app if it starts to accessing // microphone/camera. - if (!is_capturing_camera && !is_capturing_microphone && - !base::Contains(id_to_app_state_, app_id)) { + if (!is_capturing_camera && !is_capturing_microphone && !is_already_tracked) { + return; + } + + if (!is_already_tracked && ::video_conference::ShouldSkipId(app_id)) { return; }
diff --git a/chrome/browser/ash/video_conference/video_conference_app_service_client.h b/chrome/browser/ash/video_conference/video_conference_app_service_client.h index af844ea..3a3ba62 100644 --- a/chrome/browser/ash/video_conference/video_conference_app_service_client.h +++ b/chrome/browser/ash/video_conference/video_conference_app_service_client.h
@@ -14,6 +14,7 @@ #include "base/scoped_observation.h" #include "base/time/time.h" #include "base/unguessable_token.h" +#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h" #include "chromeos/crosapi/mojom/video_conference.mojom.h" #include "components/services/app_service/public/cpp/app_capability_access_cache.h" #include "components/services/app_service/public/cpp/app_types.h" @@ -36,6 +37,8 @@ public SessionObserver { public: using AppIdString = std::string; + using VideoConferencePermissions = + video_conference::VideoConferencePermissions; // AppState records information that is required for VideoConferenceManagerAsh // to show correct icons. @@ -47,13 +50,6 @@ bool is_capturing_camera = false; }; - // Struct holding the granted status of media device permissions used by - // videoconferencing apps. - struct VideoConferencePermissions { - bool has_camera_permission = false; - bool has_microphone_permission = false; - }; - VideoConferenceAppServiceClient(); VideoConferenceAppServiceClient(const VideoConferenceAppServiceClient&) =
diff --git a/chrome/browser/ash/video_conference/video_conference_app_service_client_browsertest.cc b/chrome/browser/ash/video_conference/video_conference_app_service_client_browsertest.cc index 8078487..b5583462 100644 --- a/chrome/browser/ash/video_conference/video_conference_app_service_client_browsertest.cc +++ b/chrome/browser/ash/video_conference/video_conference_app_service_client_browsertest.cc
@@ -15,6 +15,7 @@ #include "ash/system/video_conference/video_conference_media_state.h" #include "ash/test/test_window_builder.h" #include "base/run_loop.h" +#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/utf_string_conversions.h" #include "base/test/bind.h" @@ -25,6 +26,7 @@ #include "chrome/browser/ash/crosapi/crosapi_ash.h" #include "chrome/browser/ash/crosapi/crosapi_manager.h" #include "chrome/browser/ash/video_conference/video_conference_manager_ash.h" +#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h" #include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" @@ -60,6 +62,9 @@ if (app_id == kAppId2) { app->name = kAppName2; } + if (base::Contains(::video_conference::kSkipAppIds, app_id)) { + app->name = base::StrCat({"AppName-", app_id}); + } app->publisher_id = app_id; @@ -698,4 +703,18 @@ 2u); } +IN_PROC_BROWSER_TEST_F(VideoConferenceAppServiceClientTest, + SomeAppsAreNotTracked) { + // Install all apps that should be skipped. + for (const std::string& app_id : ::video_conference::kSkipAppIds) { + InstallApp(app_id); + // Accessing mic and camera should trigger tracking except the app_id is + // skipped. + SetAppCapabilityAccess(app_id, /*is_capturing_camera=*/true, + /*is_capturing_microphone=*/true); + } + + EXPECT_TRUE(GetMediaApps().empty()); +} + } // namespace ash
diff --git a/chrome/browser/chrome_content_browser_client_unittest.cc b/chrome/browser/chrome_content_browser_client_unittest.cc index 0a81177..bd7fb33 100644 --- a/chrome/browser/chrome_content_browser_client_unittest.cc +++ b/chrome/browser/chrome_content_browser_client_unittest.cc
@@ -480,6 +480,31 @@ EXPECT_FALSE(client.GetLoggingFileName(cmd_line).empty()); } +#if BUILDFLAG(IS_WIN) +TEST_F(ChromeContentBrowserClientGetLoggingFileTest, + GetLoggingFileFromCommandLine) { + base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM); + cmd_line.AppendSwitchASCII(switches::kLogFile, "c:\\path\\test_log.txt"); + ChromeContentBrowserClient client; + base::FilePath log_file_name; + EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("test_log.txt")).value(), + client.GetLoggingFileName(cmd_line).BaseName().value()); + // Path must be absolute. + EXPECT_TRUE(client.GetLoggingFileName(cmd_line).IsAbsolute()); +} +TEST_F(ChromeContentBrowserClientGetLoggingFileTest, + GetLoggingFileFromCommandLineFallback) { + base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM); + cmd_line.AppendSwitchASCII(switches::kLogFile, "test_log.txt"); + ChromeContentBrowserClient client; + base::FilePath log_file_name; + // Windows falls back to the default if an absolute path is not provided. + EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("chrome_debug.log")).value(), + client.GetLoggingFileName(cmd_line).BaseName().value()); + // Path must be absolute. + EXPECT_TRUE(client.GetLoggingFileName(cmd_line).IsAbsolute()); +} +#else TEST_F(ChromeContentBrowserClientGetLoggingFileTest, GetLoggingFileFromCommandLine) { base::CommandLine cmd_line(base::CommandLine::NO_PROGRAM); @@ -489,6 +514,7 @@ EXPECT_EQ(base::FilePath(FILE_PATH_LITERAL("test_log.txt")).value(), client.GetLoggingFileName(cmd_line).value()); } +#endif // BUILDFLAG(IS_WIN) class TestChromeContentBrowserClient : public ChromeContentBrowserClient { public:
diff --git a/chrome/browser/chromeos/BUILD.gn b/chrome/browser/chromeos/BUILD.gn index 5cf16dd4..f8d9253 100644 --- a/chrome/browser/chromeos/BUILD.gn +++ b/chrome/browser/chromeos/BUILD.gn
@@ -147,9 +147,10 @@ "tablet_mode/chrome_content_browser_client_tablet_mode_part.h", "tablet_mode/tablet_mode_page_behavior.cc", "tablet_mode/tablet_mode_page_behavior.h", - "video_conference/video_conference_app_permissions.h", "video_conference/video_conference_manager_client.cc", "video_conference/video_conference_manager_client.h", + "video_conference/video_conference_manager_client_common.cc", + "video_conference/video_conference_manager_client_common.h", "video_conference/video_conference_media_listener.cc", "video_conference/video_conference_media_listener.h", "video_conference/video_conference_web_app.cc",
diff --git a/chrome/browser/chromeos/video_conference/video_conference_manager_client.cc b/chrome/browser/chromeos/video_conference/video_conference_manager_client.cc index e1dfee8..c08dc950 100644 --- a/chrome/browser/chromeos/video_conference/video_conference_manager_client.cc +++ b/chrome/browser/chromeos/video_conference/video_conference_manager_client.cc
@@ -13,7 +13,7 @@ #include "base/logging.h" #include "base/unguessable_token.h" #include "build/chromeos_buildflags.h" -#include "chrome/browser/chromeos/video_conference/video_conference_app_permissions.h" +#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h" #include "chrome/browser/chromeos/video_conference/video_conference_media_listener.h" #include "chrome/browser/chromeos/video_conference/video_conference_web_app.h" #include "content/public/browser/web_contents.h"
diff --git a/chrome/browser/chromeos/video_conference/video_conference_manager_client_common.cc b/chrome/browser/chromeos/video_conference/video_conference_manager_client_common.cc new file mode 100644 index 0000000..5c1df1cb --- /dev/null +++ b/chrome/browser/chromeos/video_conference/video_conference_manager_client_common.cc
@@ -0,0 +1,22 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h" + +#include <string> + +#include "base/containers/contains.h" + +namespace video_conference { + +const char* kSkipAppIds[2] = { + "behllobkkfkfnphdnhnkndlbkcpglgmj", // TestExtensionID + "mecfefiddjlmabpeilblgegnbioikfmp", // SigninProfileTestExtensionID +}; + +bool ShouldSkipId(const std::string& id) { + return base::Contains(kSkipAppIds, id); +} + +} // namespace video_conference
diff --git a/chrome/browser/chromeos/video_conference/video_conference_app_permissions.h b/chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h similarity index 67% rename from chrome/browser/chromeos/video_conference/video_conference_app_permissions.h rename to chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h index cc8a2ec..9dd92185 100644 --- a/chrome/browser/chromeos/video_conference/video_conference_app_permissions.h +++ b/chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h
@@ -2,11 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CHROME_BROWSER_CHROMEOS_VIDEO_CONFERENCE_VIDEO_CONFERENCE_APP_PERMISSIONS_H_ -#define CHROME_BROWSER_CHROMEOS_VIDEO_CONFERENCE_VIDEO_CONFERENCE_APP_PERMISSIONS_H_ +#ifndef CHROME_BROWSER_CHROMEOS_VIDEO_CONFERENCE_VIDEO_CONFERENCE_MANAGER_CLIENT_COMMON_H_ +#define CHROME_BROWSER_CHROMEOS_VIDEO_CONFERENCE_VIDEO_CONFERENCE_MANAGER_CLIENT_COMMON_H_ + +#include <array> +#include <string> namespace video_conference { +// AppIds that we want to skip tracking. +extern const char* kSkipAppIds[2]; + +// Returns whether we should skip the contents for tracking. +bool ShouldSkipId(const std::string& id); + // Struct holding the granted status of media device permissions used by // videoconferencing apps. struct VideoConferencePermissions { @@ -16,4 +25,4 @@ } // namespace video_conference -#endif // CHROME_BROWSER_CHROMEOS_VIDEO_CONFERENCE_VIDEO_CONFERENCE_APP_PERMISSIONS_H_ +#endif // CHROME_BROWSER_CHROMEOS_VIDEO_CONFERENCE_VIDEO_CONFERENCE_MANAGER_CLIENT_COMMON_H_
diff --git a/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc b/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc index dee756e8..fa6eca8 100644 --- a/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc +++ b/chrome/browser/chromeos/video_conference/video_conference_media_listener.cc
@@ -5,6 +5,7 @@ #include "chrome/browser/chromeos/video_conference/video_conference_media_listener.h" #include "base/memory/scoped_refptr.h" +#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h" #include "chrome/browser/chromeos/video_conference/video_conference_web_app.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "content/public/browser/web_contents.h" @@ -103,6 +104,11 @@ if (!is_capturing) { return nullptr; } + + if (ShouldSkipId(contents->GetURL().host())) { + return nullptr; + } + vc_app = create_vc_web_app_callback_.Run(contents); }
diff --git a/chrome/browser/chromeos/video_conference/video_conference_media_listener_browsertest.cc b/chrome/browser/chromeos/video_conference/video_conference_media_listener_browsertest.cc index 461b793..b775801 100644 --- a/chrome/browser/chromeos/video_conference/video_conference_media_listener_browsertest.cc +++ b/chrome/browser/chromeos/video_conference/video_conference_media_listener_browsertest.cc
@@ -7,11 +7,14 @@ #include <memory> #include "base/functional/bind.h" +#include "base/strings/strcat.h" #include "base/unguessable_token.h" +#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h" #include "chrome/browser/chromeos/video_conference/video_conference_web_app.h" #include "chrome/browser/media/webrtc/media_capture_devices_dispatcher.h" #include "chrome/browser/ui/browser.h" #include "chrome/test/base/in_process_browser_test.h" +#include "content/public/browser/navigation_entry.h" #include "content/public/browser/web_contents_user_data.h" #include "content/public/test/browser_test.h" #include "testing/gtest/include/gtest/gtest.h" @@ -227,4 +230,37 @@ EXPECT_EQ(media_listener->state().window_capture_count, 0); } +IN_PROC_BROWSER_TEST_F(VideoConferenceMediaListenerBrowserTest, + TestExtensionIDShouldNotBeTracked) { + std::unique_ptr<FakeVcMediaListener> media_listener = + std::make_unique<FakeVcMediaListener>(); + + // We can't directly navigate to TestExtensionUrl, so we use this workaround + // to set the url afterwards. + EXPECT_TRUE(AddTabAtIndex(0, GURL("about:blank"), ui::PAGE_TRANSITION_LINK)); + auto* web_contents = browser()->tab_strip_model()->GetWebContentsAt(0); + + for (const std::string& app_id : kSkipAppIds) { + const GURL url = GURL(base::StrCat( + {"chrome-extension://", app_id, "/_generated_background_page.html"})); + web_contents->GetController().GetLastCommittedEntry()->SetURL(GURL(url)); + + // Verify that the url is indeed changed. + EXPECT_EQ(web_contents->GetURL().host(), app_id); + + // Access video. + StartCapture(web_contents, + blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE); + + // Verify no app is tracked. + EXPECT_EQ(media_listener->state().window_capture_count, 0); + + // Verify that VideoConferenceWebApp is not created for web_contents. + EXPECT_EQ( + content::WebContentsUserData<VideoConferenceWebApp>::FromWebContents( + web_contents), + nullptr); + } +} + } // namespace video_conference
diff --git a/chrome/browser/chromeos/video_conference/video_conference_web_app.cc b/chrome/browser/chromeos/video_conference/video_conference_web_app.cc index 3fd87638..d6a1957 100644 --- a/chrome/browser/chromeos/video_conference/video_conference_web_app.cc +++ b/chrome/browser/chromeos/video_conference/video_conference_web_app.cc
@@ -9,7 +9,7 @@ #include "base/check.h" #include "base/time/time.h" #include "base/unguessable_token.h" -#include "chrome/browser/chromeos/video_conference/video_conference_app_permissions.h" +#include "chrome/browser/chromeos/video_conference/video_conference_manager_client_common.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/page.h" #include "content/public/browser/permission_controller.h"
diff --git a/chrome/browser/download/bubble/download_bubble_controller.cc b/chrome/browser/download/bubble/download_bubble_controller.cc index 4aec509..aeadb8a 100644 --- a/chrome/browser/download/bubble/download_bubble_controller.cc +++ b/chrome/browser/download/bubble/download_bubble_controller.cc
@@ -207,18 +207,21 @@ } } if (any_new) { - display_controller_->OnNewItem(/*show_details=*/( - any_in_progress && - (browser_ == chrome::FindLastActiveWithProfile(profile_.get())))); + display_controller_->OnNewItem( + /*show_details=*/( + any_in_progress && + (browser_ == chrome::FindLastActiveWithProfile(profile_.get()))), + /*show_animation=*/false); } } void DownloadBubbleUIController::OnNewItem(download::DownloadItem* item, bool show_details) { - std::make_unique<DownloadItemModel>(item)->SetActionedOn(false); + auto model = std::make_unique<DownloadItemModel>(item); + model->SetActionedOn(false); display_controller_->OnNewItem( - (item->GetState() == download::DownloadItem::IN_PROGRESS) && - show_details); + (item->GetState() == download::DownloadItem::IN_PROGRESS) && show_details, + model->ShouldShowDownloadStartedAnimation()); } bool DownloadBubbleUIController::ShouldShowIncognitoIcon(
diff --git a/chrome/browser/download/bubble/download_bubble_controller_unittest.cc b/chrome/browser/download/bubble/download_bubble_controller_unittest.cc index 3bfbb2a..05917ef 100644 --- a/chrome/browser/download/bubble/download_bubble_controller_unittest.cc +++ b/chrome/browser/download/bubble/download_bubble_controller_unittest.cc
@@ -33,6 +33,7 @@ using testing::_; using testing::NiceMock; using testing::Return; +using testing::ReturnRef; using testing::ReturnRefOfCopy; using testing::SetArgPointee; @@ -48,7 +49,7 @@ DownloadBubbleUIController* bubble_controller) : DownloadDisplayController(nullptr, browser, bubble_controller) {} void MaybeShowButtonWhenCreated() override {} - MOCK_METHOD1(OnNewItem, void(bool)); + MOCK_METHOD2(OnNewItem, void(bool, bool)); MOCK_METHOD2(OnUpdatedItem, void(bool, bool)); MOCK_METHOD1(OnRemovedItem, void(const ContentId&)); }; @@ -165,7 +166,7 @@ items_.push_back(std::make_unique<StrictMockDownloadItem>()); EXPECT_CALL(item(index), GetId()) .WillRepeatedly(Return(static_cast<uint32_t>(items_.size() + 1))); - EXPECT_CALL(item(index), GetGuid()).WillRepeatedly(testing::ReturnRef(id)); + EXPECT_CALL(item(index), GetGuid()).WillRepeatedly(ReturnRef(id)); EXPECT_CALL(item(index), GetState()).WillRepeatedly(Return(state)); EXPECT_CALL(item(index), GetStartTime()).WillRepeatedly(Return(start_time)); EXPECT_CALL(item(index), GetTargetFilePath()) @@ -188,6 +189,15 @@ .WillRepeatedly(Return(download::DownloadItem::DownloadCreationType:: TYPE_ACTIVE_DOWNLOAD)); EXPECT_CALL(item(index), IsPaused()).WillRepeatedly(Return(false)); + // Functions called when checking ShouldShowDownloadStartedAnimation(). + EXPECT_CALL(item(index), IsSavePackageDownload()) + .WillRepeatedly(Return(false)); + EXPECT_CALL(item(index), GetTargetDisposition()) + .WillRepeatedly( + Return(download::DownloadItem::TARGET_DISPOSITION_PROMPT)); + EXPECT_CALL(item(index), GetMimeType()).WillRepeatedly(Return("")); + EXPECT_CALL(item(index), GetURL()) + .WillRepeatedly(ReturnRef(GURL::EmptyGURL())); std::vector<download::DownloadItem*> items; for (size_t i = 0; i < items_.size(); ++i) { items.push_back(&item(i)); @@ -255,15 +265,15 @@ TEST_F(DownloadBubbleUIControllerTest, ProcessesNewItems) { std::vector<std::string> ids = {"Download 1", "Download 2", "Offline 1", "Download 3"}; - EXPECT_CALL(display_controller(), OnNewItem(true)).Times(1); + EXPECT_CALL(display_controller(), OnNewItem(true, true)).Times(1); InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), download::DownloadItem::IN_PROGRESS, ids[0]); - EXPECT_CALL(display_controller(), OnNewItem(false)).Times(1); + EXPECT_CALL(display_controller(), OnNewItem(false, true)).Times(1); InitDownloadItem(FILE_PATH_LITERAL("/foo/bar2.pdf"), download::DownloadItem::COMPLETE, ids[1]); - EXPECT_CALL(display_controller(), OnNewItem(true)).Times(1); + EXPECT_CALL(display_controller(), OnNewItem(true, false)).Times(1); InitOfflineItem(OfflineItemState::IN_PROGRESS, ids[2]); - EXPECT_CALL(display_controller(), OnNewItem(false)).Times(1); + EXPECT_CALL(display_controller(), OnNewItem(false, true)).Times(1); InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), download::DownloadItem::IN_PROGRESS, ids[3], /*is_transient=*/false, base::Time::Now(), @@ -272,7 +282,7 @@ TEST_F(DownloadBubbleUIControllerTest, ProcessesUpdatedItems) { std::vector<std::string> ids = {"Download 1", "Offline 1"}; - EXPECT_CALL(display_controller(), OnNewItem(true)).Times(1); + EXPECT_CALL(display_controller(), OnNewItem(true, true)).Times(1); InitDownloadItem(FILE_PATH_LITERAL("/foo/bar.pdf"), download::DownloadItem::IN_PROGRESS, ids[0]); EXPECT_CALL(display_controller(), OnUpdatedItem(false, true)).Times(1); @@ -280,7 +290,7 @@ EXPECT_CALL(display_controller(), OnUpdatedItem(true, true)).Times(1); UpdateDownloadItem(/*item_index=*/0, DownloadState::COMPLETE); - EXPECT_CALL(display_controller(), OnNewItem(true)).Times(1); + EXPECT_CALL(display_controller(), OnNewItem(true, false)).Times(1); InitOfflineItem(OfflineItemState::IN_PROGRESS, ids[1]); EXPECT_CALL(display_controller(), OnUpdatedItem(true, true)).Times(1); UpdateOfflineItem(/*item_index=*/0, OfflineItemState::COMPLETE);
diff --git a/chrome/browser/download/bubble/download_display.h b/chrome/browser/download/bubble/download_display.h index 8843ef6..25759419 100644 --- a/chrome/browser/download/bubble/download_display.h +++ b/chrome/browser/download/bubble/download_display.h
@@ -21,7 +21,8 @@ virtual void UpdateDownloadIcon() = 0; // Shows detailed information on the download display. It can be a popup or // dialog or partial view, essentially anything other than the main view. - virtual void ShowDetails() = 0; + // If |show_animation| is true, an animated icon will be shown. + virtual void ShowDetails(bool show_animation) = 0; // Hide the detailed information on the download display. virtual void HideDetails() = 0; // Returns whether the details are visible.
diff --git a/chrome/browser/download/bubble/download_display_controller.cc b/chrome/browser/download/bubble/download_display_controller.cc index f85d020..71a5f83 100644 --- a/chrome/browser/download/bubble/download_display_controller.cc +++ b/chrome/browser/download/bubble/download_display_controller.cc
@@ -118,7 +118,8 @@ base::PowerMonitor::RemovePowerSuspendObserver(this); } -void DownloadDisplayController::OnNewItem(bool show_details) { +void DownloadDisplayController::OnNewItem(bool show_details, + bool show_animation) { if (!download::ShouldShowDownloadBubble(browser_->profile())) { return; } @@ -142,7 +143,7 @@ /*force_update=*/true); } } else { - display_->ShowDetails(); + display_->ShowDetails(show_animation); } } @@ -242,7 +243,7 @@ int in_progress_count = InProgressDownloadCount(all_models); if (in_progress_count > 0 && download::ShouldShowDownloadBubble(browser_->profile())) { - display_->ShowDetails(); + display_->ShowDetails(/*show_animation=*/false); } }
diff --git a/chrome/browser/download/bubble/download_display_controller.h b/chrome/browser/download/bubble/download_display_controller.h index bec4689..a6e75fa 100644 --- a/chrome/browser/download/bubble/download_display_controller.h +++ b/chrome/browser/download/bubble/download_display_controller.h
@@ -80,9 +80,10 @@ // Common methods for new downloads or new offline items. // Called from bubble controller when new item(s) are added, with // |show_details| as argument if the partial view should be shown. + // |show_animation| specifies whether a small animated arrow should be shown. // These methods are virtual so that they can be overridden for fake // controllers in testing. - virtual void OnNewItem(bool show_details); + virtual void OnNewItem(bool show_details, bool show_animation); // Called from bubble controller when an item is updated, with |is_done| // indicating if it was marked done, and with // |show_details_if_done| as argument if the partial view should be shown.
diff --git a/chrome/browser/download/bubble/download_display_controller_unittest.cc b/chrome/browser/download/bubble/download_display_controller_unittest.cc index aeb6452..13fbff5 100644 --- a/chrome/browser/download/bubble/download_display_controller_unittest.cc +++ b/chrome/browser/download/bubble/download_display_controller_unittest.cc
@@ -79,7 +79,7 @@ is_active_ = controller_->GetIconInfo().is_active; } - void ShowDetails() override { detail_shown_ = true; } + void ShowDetails(bool show_animation) override { detail_shown_ = true; } void HideDetails() override { detail_shown_ = false; } bool IsShowingDetails() override { return detail_shown_; } bool IsFullscreenWithParentViewHidden() override { return is_fullscreen_; } @@ -259,15 +259,17 @@ item(index).AddObserver(&controller().get_download_notifier_for_testing()); content::DownloadItemUtils::AttachInfoForTesting(&(item(index)), profile_, nullptr); - controller().OnNewItem((state == download::DownloadItem::IN_PROGRESS) && - show_details); + controller().OnNewItem( + (state == download::DownloadItem::IN_PROGRESS) && show_details, + /*show_animation=*/false); } void InitOfflineItem(OfflineItemState state) { OfflineItem item; item.state = state; bubble_controller().AddOfflineItem(item); - controller().OnNewItem(state == OfflineItemState::IN_PROGRESS); + controller().OnNewItem(state == OfflineItemState::IN_PROGRESS, + /*show_animation=*/false); } void UpdateOfflineItem(int item_index, OfflineItemState state) { @@ -583,7 +585,7 @@ EXPECT_CALL(item(0), GetTargetFilePath()) .WillRepeatedly( ReturnRefOfCopy(base::FilePath(FILE_PATH_LITERAL("bar.pdf")))); - controller().OnNewItem(/*show_details=*/true); + controller().OnNewItem(/*show_details=*/true, /*show_animation=*/false); EXPECT_TRUE(VerifyDisplayState(/*shown=*/true, /*detail_shown=*/true, /*icon_state=*/DownloadIconState::kProgress, /*is_active=*/true));
diff --git a/chrome/browser/download/download_browsertest.cc b/chrome/browser/download/download_browsertest.cc index 9405e5d..0844db4c 100644 --- a/chrome/browser/download/download_browsertest.cc +++ b/chrome/browser/download/download_browsertest.cc
@@ -3769,15 +3769,8 @@ return std::move(response); } -// TODO(https://crbug.com/1244128): Flaky on Win7 -#if BUILDFLAG(IS_WIN) -#define MAYBE_AltClickDownloadReferrerPolicy \ - DISABLED_AltClickDownloadReferrerPolicy -#else -#define MAYBE_AltClickDownloadReferrerPolicy AltClickDownloadReferrerPolicy -#endif IN_PROC_BROWSER_TEST_P(DownloadReferrerPolicyTest, - MAYBE_AltClickDownloadReferrerPolicy) { + AltClickDownloadReferrerPolicy) { embedded_test_server()->RegisterRequestHandler( base::BindRepeating(&EchoReferrerRequestHandler)); embedded_test_server()->ServeFilesFromDirectory(GetTestDataDirectory()); @@ -3854,17 +3847,10 @@ } } -// TODO(https://crbug.com/1244128): Flaky on Win7 -#if BUILDFLAG(IS_WIN) -#define MAYBE_SaveLinkAsReferrerPolicy DISABLED_SaveLinkAsReferrerPolicy -#else -#define MAYBE_SaveLinkAsReferrerPolicy SaveLinkAsReferrerPolicy -#endif // This test ensures that the Referer header is properly sanitized when // Save Link As is chosen from the context menu from a page with all possible // referrer policies. -IN_PROC_BROWSER_TEST_P(DownloadReferrerPolicyTest, - MAYBE_SaveLinkAsReferrerPolicy) { +IN_PROC_BROWSER_TEST_P(DownloadReferrerPolicyTest, SaveLinkAsReferrerPolicy) { embedded_test_server()->RegisterRequestHandler( base::BindRepeating(&EchoReferrerRequestHandler)); ASSERT_TRUE(embedded_test_server()->Start()); @@ -3943,9 +3929,8 @@ } } -// TODO(https://crbug.com/1244128): Flaky on Win7 // TODO(crbug.com/1269422): Flaky on Lacros -#if BUILDFLAG(IS_WIN) || BUILDFLAG(IS_CHROMEOS) +#if BUILDFLAG(IS_CHROMEOS) #define MAYBE_SaveLinkAsVsCrossOriginResourcePolicy \ DISABLED_SaveLinkAsVsCrossOriginResourcePolicy #else @@ -4109,18 +4094,10 @@ } } -// TODO(https://crbug.com/1244128): Flaky on Win7 -#if BUILDFLAG(IS_WIN) -#define MAYBE_DownloadCrossDomainReferrerPolicy \ - DISABLED_DownloadCrossDomainReferrerPolicy -#else -#define MAYBE_DownloadCrossDomainReferrerPolicy \ - DownloadCrossDomainReferrerPolicy -#endif // This test ensures that a cross-domain download correctly sets the referrer // according to the referrer policy. IN_PROC_BROWSER_TEST_P(DownloadReferrerPolicyTest, - MAYBE_DownloadCrossDomainReferrerPolicy) { + DownloadCrossDomainReferrerPolicy) { embedded_test_server()->RegisterRequestHandler( base::BindRepeating(&ServerRedirectRequestHandler)); embedded_test_server()->RegisterRequestHandler(
diff --git a/chrome/browser/extensions/extension_browsertest.cc b/chrome/browser/extensions/extension_browsertest.cc index c75ba8af..44f87b8 100644 --- a/chrome/browser/extensions/extension_browsertest.cc +++ b/chrome/browser/extensions/extension_browsertest.cc
@@ -223,8 +223,8 @@ base::Value::Dict& manifest_dict) { base::ScopedAllowBlockingForTesting allow_blocking; - // Retrieve the value of the "background" key and verify that it has - // the "persistent" key and specifies JS files. + // Retrieve the value of the `background` key and verify that it has + // the `persistent` key and specifies JS files. // Background pages that specify HTML files are not supported. base::Value::Dict* background_dict = manifest_dict.FindDict("background"); if (!background_dict) {
diff --git a/chrome/browser/flag-metadata.json b/chrome/browser/flag-metadata.json index db21b17..19d82aff 100644 --- a/chrome/browser/flag-metadata.json +++ b/chrome/browser/flag-metadata.json
@@ -5507,7 +5507,7 @@ // This flag is used by ChromeOS for some accessibility users. // TODO(b/172341945): Fix this asap. "name": "overscroll-history-navigation", - "owners": [ "mohsen", "jinsukkim" ], + "owners": [ "jinsukkim" ], "expiry_milestone": 118 }, { @@ -6256,6 +6256,11 @@ "expiry_milestone": 96 }, { + "name": "share-sheet-migration-android", + "owners": [ "wenyufu" ], + "expiry_milestone": 121 + }, + { "name": "shared-highlighting-amp", "owners": ["cheickcisse@google.com"], "expiry_milestone": 97 @@ -6731,6 +6736,11 @@ "expiry_milestone": 114 }, { + "name": "thumbnail-cache-refactor", + "owners": [ "ckitagawa", "fredmello" ], + "expiry_milestone": 118 + }, + { "name": "tint-composited-content", "owners": [ "chromeos-gfx@google.com" ], // This flag is used for QA & development on ChromeOS, which has no way to
diff --git a/chrome/browser/flag_descriptions.cc b/chrome/browser/flag_descriptions.cc index fe052a2..5226211 100644 --- a/chrome/browser/flag_descriptions.cc +++ b/chrome/browser/flag_descriptions.cc
@@ -534,18 +534,6 @@ "it will offer to save it. If saved, it will be offered for filling in " "fields which expect a VPA."; -const char kAutofillSaveCardUiExperimentName[] = - "Enable different UI variants for the upload credit card save bubble"; -const char kAutofillSaveCardUiExperimentDescription[] = - "When enabled, it will trigger slightly different UI variants along with " - "notification texts, when the upload credit card save bubble is shown."; -const char kAutofillSaveCardUiExperimentCurrentWithUserAvatarAndEmail[] = - "Current with Avatar and Email"; -const char kAutofillSaveCardUiExperimentEncryptedAndSecure[] = - "Encrypted and Secure"; -const char kAutofillSaveCardUiExperimentFasterAndProtected[] = - "Faster and Protected"; - const char kAutofillShowManualFallbackInContextMenuName[] = "Show Autofill options in Context Menu"; const char kAutofillShowManualFallbackInContextMenuDescription[] = @@ -3004,6 +2992,11 @@ "the frame has zero viewport intersection, a non-zero area, and is " "not display:none."; +const char kThumbnailCacheRefactorName[] = "Thumbnail Cache Refactor"; +const char kThumbnailCacheRefactorDescription[] = + "When enabled the thumbnail cache for Android is updated to improve " + "memory usage and performance."; + const char kNewBaseUrlInheritanceBehaviorName[] = "Enable new base url inheritance behaviors for srcdoc and about:blank"; const char kNewBaseUrlInheritanceBehaviorDescription[] = @@ -3986,6 +3979,10 @@ "When enabled, sets the market URL for use in testing the update menu " "item."; +const char kShareSheetMigrationAndroidName[] = "Share sheet refactor Android"; +const char kShareSheetMigrationAndroidDescription[] = + "When enabled, use the Android OS share sheet."; + const char kSiteIsolationForPasswordSitesName[] = "Site Isolation For Password Sites"; const char kSiteIsolationForPasswordSitesDescription[] =
diff --git a/chrome/browser/flag_descriptions.h b/chrome/browser/flag_descriptions.h index e4b8630..f6855ce1 100644 --- a/chrome/browser/flag_descriptions.h +++ b/chrome/browser/flag_descriptions.h
@@ -290,12 +290,6 @@ extern const char kAutofillSaveAndFillVPAName[]; extern const char kAutofillSaveAndFillVPADescription[]; -extern const char kAutofillSaveCardUiExperimentName[]; -extern const char kAutofillSaveCardUiExperimentDescription[]; -extern const char kAutofillSaveCardUiExperimentCurrentWithUserAvatarAndEmail[]; -extern const char kAutofillSaveCardUiExperimentEncryptedAndSecure[]; -extern const char kAutofillSaveCardUiExperimentFasterAndProtected[]; - extern const char kAutofillShowManualFallbackInContextMenuName[]; extern const char kAutofillShowManualFallbackInContextMenuDescription[]; @@ -1712,6 +1706,9 @@ extern const char kThrottleDisplayNoneAndVisibilityHiddenCrossOriginIframesDescription[]; +extern const char kThumbnailCacheRefactorName[]; +extern const char kThumbnailCacheRefactorDescription[]; + extern const char kNewBaseUrlInheritanceBehaviorName[]; extern const char kNewBaseUrlInheritanceBehaviorDescription[]; @@ -2280,6 +2277,9 @@ extern const char kSetMarketUrlForTestingName[]; extern const char kSetMarketUrlForTestingDescription[]; +extern const char kShareSheetMigrationAndroidName[]; +extern const char kShareSheetMigrationAndroidDescription[]; + extern const char kSiteIsolationForPasswordSitesName[]; extern const char kSiteIsolationForPasswordSitesDescription[];
diff --git a/chrome/browser/flags/android/chrome_feature_list.cc b/chrome/browser/flags/android/chrome_feature_list.cc index 1869bfa..153ad90a 100644 --- a/chrome/browser/flags/android/chrome_feature_list.cc +++ b/chrome/browser/flags/android/chrome_feature_list.cc
@@ -246,6 +246,7 @@ &kOmniboxModernizeVisualUpdate, &kOpaqueOriginForIncomingIntents, &kOptimizeGeolocationHeaderGeneration, + &kPartnerHomepageInitialLoadImprovement, &kPostTaskFocusTab, &kProbabilisticCryptidRenderer, &kQuickDeleteForAndroid, @@ -276,6 +277,7 @@ &kShowScrollableMVTOnNTPAndroid, &kFeedPositionAndroid, &kSearchResumptionModuleAndroid, + &kShareSheetMigrationAndroid, &kShouldIgnoreIntentSkipInternalCheck, &kSpecialLocaleWrapper, &kSpecialUserDecision, @@ -297,6 +299,7 @@ &kTabToGTSAnimation, &kTestDefaultDisabled, &kTestDefaultEnabled, + &kThumbnailCacheRefactor, &kToolbarMicIphAndroid, &kToolbarScrollAblationAndroid, &kTrustedWebActivityPostMessage, @@ -777,6 +780,10 @@ "OptimizeGeolocationHeaderGeneration", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kPartnerHomepageInitialLoadImprovement, + "PartnerHomepageInitialLoadImprovement", + base::FEATURE_ENABLED_BY_DEFAULT); + BASE_FEATURE(kPostTaskFocusTab, "PostTaskFocusTab", base::FEATURE_ENABLED_BY_DEFAULT); @@ -889,6 +896,10 @@ "ShowScrollableMVTOnNTPAndroid", base::FEATURE_DISABLED_BY_DEFAULT); +BASE_FEATURE(kShareSheetMigrationAndroid, + "ShareSheetMigrationAndroid", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kSpecialLocaleWrapper, "SpecialLocaleWrapper", base::FEATURE_ENABLED_BY_DEFAULT); @@ -969,6 +980,10 @@ "TestDefaultEnabled", base::FEATURE_ENABLED_BY_DEFAULT); +BASE_FEATURE(kThumbnailCacheRefactor, + "ThumbnailCacheRefactor", + base::FEATURE_DISABLED_BY_DEFAULT); + BASE_FEATURE(kToolbarMicIphAndroid, "ToolbarMicIphAndroid", base::FEATURE_DISABLED_BY_DEFAULT);
diff --git a/chrome/browser/flags/android/chrome_feature_list.h b/chrome/browser/flags/android/chrome_feature_list.h index f9881e6..e3fa33a0 100644 --- a/chrome/browser/flags/android/chrome_feature_list.h +++ b/chrome/browser/flags/android/chrome_feature_list.h
@@ -110,6 +110,7 @@ BASE_DECLARE_FEATURE(kBackGestureRefactorActivityAndroid); BASE_DECLARE_FEATURE(kBackGestureRefactorAndroid); BASE_DECLARE_FEATURE(kOpaqueOriginForIncomingIntents); +BASE_DECLARE_FEATURE(kPartnerHomepageInitialLoadImprovement); BASE_DECLARE_FEATURE(kPostTaskFocusTab); BASE_DECLARE_FEATURE(kProbabilisticCryptidRenderer); BASE_DECLARE_FEATURE(kQuickDeleteForAndroid); @@ -142,6 +143,7 @@ BASE_DECLARE_FEATURE(kSafeModeForCachedFlags); BASE_DECLARE_FEATURE(kSearchResumptionModuleAndroid); BASE_DECLARE_FEATURE(kShouldIgnoreIntentSkipInternalCheck); +BASE_DECLARE_FEATURE(kShareSheetMigrationAndroid); BASE_DECLARE_FEATURE(kSpecialLocaleWrapper); BASE_DECLARE_FEATURE(kSpecialUserDecision); BASE_DECLARE_FEATURE(kSplitCompositorTask); @@ -162,6 +164,7 @@ BASE_DECLARE_FEATURE(kTabToGTSAnimation); BASE_DECLARE_FEATURE(kTestDefaultDisabled); BASE_DECLARE_FEATURE(kTestDefaultEnabled); +BASE_DECLARE_FEATURE(kThumbnailCacheRefactor); BASE_DECLARE_FEATURE(kToolbarMicIphAndroid); BASE_DECLARE_FEATURE(kToolbarScrollAblationAndroid); BASE_DECLARE_FEATURE(kToolbarUseHardwareBitmapDraw);
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 7533a96..44ea32f 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
@@ -404,6 +404,8 @@ "PageInfoAboutThisSiteImprovedBottomSheet"; public static final String PAINT_PREVIEW_DEMO = "PaintPreviewDemo"; public static final String PAINT_PREVIEW_SHOW_ON_STARTUP = "PaintPreviewShowOnStartup"; + public static final String PARTNER_HOMEPAGE_INITIAL_LOAD_IMPROVEMENT = + "PartnerHomepageInitialLoadImprovement"; public static final String PASSWORD_DOMAIN_CAPABILITIES_FETCHING = "PasswordDomainCapabilitiesFetching"; public static final String PASSWORD_EDIT_DIALOG_WITH_DETAILS = "PasswordEditDialogWithDetails"; @@ -463,6 +465,7 @@ public static final String SEARCH_RESUMPTION_MODULE_ANDROID = "SearchResumptionModuleAndroid"; public static final String SHOULD_IGNORE_INTENT_SKIP_INTERNAL_CHECK = "ShouldIgnoreIntentSkipInternalCheck"; + public static final String SHARE_SHEET_MIGRATION_ANDROID = "ShareSheetMigrationAndroid"; public static final String SEND_TAB_TO_SELF_SIGNIN_PROMO = "SendTabToSelfSigninPromo"; public static final String SEND_TAB_TO_SELF_V2 = "SendTabToSelfV2"; public static final String SHARED_HIGHLIGHTING_AMP = "SharedHighlightingAmp"; @@ -506,6 +509,7 @@ public static final String TANGIBLE_SYNC = "TangibleSync"; public static final String TEST_DEFAULT_DISABLED = "TestDefaultDisabled"; public static final String TEST_DEFAULT_ENABLED = "TestDefaultEnabled"; + public static final String THUMBNAIL_CACHE_REFACTOR = "ThumbnailCacheRefactor"; public static final String TOOLBAR_MIC_IPH_ANDROID = "ToolbarMicIphAndroid"; public static final String TOOLBAR_SCROLL_ABLATION_ANDROID = "ToolbarScrollAblationAndroid"; public static final String TOOLBAR_USE_HARDWARE_BITMAP_DRAW = "ToolbarUseHardwareBitmapDraw"; @@ -627,6 +631,8 @@ public static final CachedFlag sOptimizationGuidePushNotifications = new CachedFlag(OPTIMIZATION_GUIDE_PUSH_NOTIFICATIONS, false); public static final CachedFlag sPaintPreviewDemo = new CachedFlag(PAINT_PREVIEW_DEMO, false); + public static final CachedFlag sPartnerHomepageInitialLoadImprovement = + new CachedFlag(PARTNER_HOMEPAGE_INITIAL_LOAD_IMPROVEMENT, true); public static final CachedFlag sPrefetchNotificationSchedulingIntegration = new CachedFlag(PREFETCH_NOTIFICATION_SCHEDULING_INTEGRATION, false); public static final CachedFlag sQueryTiles = new CachedFlag(QUERY_TILES, false);
diff --git a/chrome/browser/lacros/input_method_lacros_browsertest.cc b/chrome/browser/lacros/input_method_lacros_browsertest.cc index 47da4b74..c9be4787 100644 --- a/chrome/browser/lacros/input_method_lacros_browsertest.cc +++ b/chrome/browser/lacros/input_method_lacros_browsertest.cc
@@ -140,34 +140,53 @@ return ExecJs(web_content, script); } -mojom::KeyEventPtr CreateKeyPressEvent(uint32_t dom_key, ui::DomCode dom_code) { - return mojom::KeyEvent::New( - mojom::KeyEventType::kKeyPress, - static_cast<int>(ui::DomKey::FromCharacter(dom_key)), - static_cast<int>(dom_code), - static_cast<int>(ui::KeyboardCode::VKEY_UNKNOWN)); +mojom::KeyEventPtr CreateKeyPressEvent(ui::DomKey dom_key, + ui::DomCode dom_code) { + return mojom::KeyEvent::New(mojom::KeyEventType::kKeyPress, + static_cast<int>(dom_key), + static_cast<int>(dom_code), + static_cast<int>(ui::KeyboardCode::VKEY_UNKNOWN)); } -mojom::KeyEventPtr CreateKeyReleaseEvent(uint32_t dom_key, +mojom::KeyEventPtr CreateKeyReleaseEvent(ui::DomKey dom_key, ui::DomCode dom_code) { - return mojom::KeyEvent::New( - mojom::KeyEventType::kKeyRelease, - static_cast<int>(ui::DomKey::FromCharacter(dom_key)), - static_cast<int>(dom_code), - static_cast<int>(ui::KeyboardCode::VKEY_UNKNOWN)); + return mojom::KeyEvent::New(mojom::KeyEventType::kKeyRelease, + static_cast<int>(dom_key), + static_cast<int>(dom_code), + static_cast<int>(ui::KeyboardCode::VKEY_UNKNOWN)); } -// Send the key event to the input method. The input method will not handle the -// given key event. +std::vector<mojom::KeyEventPtr> CreateKeyPressAndReleaseEvents( + ui::DomKey dom_key, + ui::DomCode dom_code) { + std::vector<mojom::KeyEventPtr> key_events; + key_events.push_back(CreateKeyPressEvent(dom_key, dom_code)); + key_events.push_back(CreateKeyReleaseEvent(dom_key, dom_code)); + return key_events; +} + +// Sends the key events to the input method. The input method will not handle +// the given key events. +void SendKeyEventsSync( + InputMethodTestInterfaceAsyncWaiter& input_method_async_waiter, + std::vector<mojom::KeyEventPtr> key_events) { + uint64_t key_event_id; + for (mojom::KeyEventPtr& key_event : key_events) { + input_method_async_waiter.SendKeyEvent(std::move(key_event), &key_event_id); + input_method_async_waiter.KeyEventHandled(key_event_id, false); + } +} + +// Convenient version of `SendKeyEventsSync` for a single key event. void SendKeyEventSync( InputMethodTestInterfaceAsyncWaiter& input_method_async_waiter, mojom::KeyEventPtr key_event) { - uint64_t key_event_id; - input_method_async_waiter.SendKeyEvent(std::move(key_event), &key_event_id); - input_method_async_waiter.KeyEventHandled(key_event_id, false); + std::vector<mojom::KeyEventPtr> key_events; + key_events.push_back(std::move(key_event)); + SendKeyEventsSync(input_method_async_waiter, std::move(key_events)); } -// Send the key event to the input method. The input method will handle the +// Sends the key event to the input method. The input method will handle the // given key event by running `callback`. void SendKeyEventAsync( InputMethodTestInterfaceAsyncWaiter& input_method_async_waiter, @@ -418,18 +437,15 @@ input_method.get()); input_method_async_waiter.WaitForFocus(); - SendKeyEventSync(input_method_async_waiter, - CreateKeyPressEvent('a', ui::DomCode::US_A)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyReleaseEvent('a', ui::DomCode::US_A)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyPressEvent('b', ui::DomCode::US_B)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyReleaseEvent('b', ui::DomCode::US_B)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyPressEvent('c', ui::DomCode::US_C)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyReleaseEvent('c', ui::DomCode::US_C)); + SendKeyEventsSync(input_method_async_waiter, + CreateKeyPressAndReleaseEvents( + ui::DomKey::FromCharacter('a'), ui::DomCode::US_A)); + SendKeyEventsSync(input_method_async_waiter, + CreateKeyPressAndReleaseEvents( + ui::DomKey::FromCharacter('b'), ui::DomCode::US_B)); + SendKeyEventsSync(input_method_async_waiter, + CreateKeyPressAndReleaseEvents( + ui::DomKey::FromCharacter('c'), ui::DomCode::US_C)); EXPECT_TRUE(WaitUntilInputFieldHasText(GetActiveWebContents(browser()), id, "abc", gfx::Range(3))); @@ -452,24 +468,21 @@ input_method.get()); input_method_async_waiter.WaitForFocus(); - SendKeyEventSync(input_method_async_waiter, - CreateKeyPressEvent('\b', ui::DomCode::BACKSPACE)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyReleaseEvent('\b', ui::DomCode::BACKSPACE)); + SendKeyEventsSync(input_method_async_waiter, + CreateKeyPressAndReleaseEvents(ui::DomKey::BACKSPACE, + ui::DomCode::BACKSPACE)); EXPECT_TRUE(WaitUntilInputFieldHasText(GetActiveWebContents(browser()), id, "helo", gfx::Range(2))); - SendKeyEventSync(input_method_async_waiter, - CreateKeyPressEvent('\b', ui::DomCode::BACKSPACE)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyReleaseEvent('\b', ui::DomCode::BACKSPACE)); + SendKeyEventsSync(input_method_async_waiter, + CreateKeyPressAndReleaseEvents(ui::DomKey::BACKSPACE, + ui::DomCode::BACKSPACE)); EXPECT_TRUE(WaitUntilInputFieldHasText(GetActiveWebContents(browser()), id, "hlo", gfx::Range(1))); - SendKeyEventSync(input_method_async_waiter, - CreateKeyPressEvent('\b', ui::DomCode::BACKSPACE)); - SendKeyEventSync(input_method_async_waiter, - CreateKeyReleaseEvent('\b', ui::DomCode::BACKSPACE)); + SendKeyEventsSync(input_method_async_waiter, + CreateKeyPressAndReleaseEvents(ui::DomKey::BACKSPACE, + ui::DomCode::BACKSPACE)); EXPECT_TRUE(WaitUntilInputFieldHasText(GetActiveWebContents(browser()), id, "lo", gfx::Range(0))); } @@ -492,14 +505,16 @@ input_method_async_waiter.WaitForFocus(); SendKeyEventAsync( - input_method_async_waiter, CreateKeyPressEvent('g', ui::DomCode::US_A), + input_method_async_waiter, + CreateKeyPressEvent(ui::DomKey::FromCharacter('g'), ui::DomCode::US_G), base::BindOnce( [](InputMethodTestInterfaceAsyncWaiter& input_method_async_waiter) { input_method_async_waiter.SetComposition("ã…Ž", 1); return true; })); - SendKeyEventSync(input_method_async_waiter, - CreateKeyReleaseEvent('g', ui::DomCode::US_A)); + SendKeyEventSync( + input_method_async_waiter, + CreateKeyReleaseEvent(ui::DomKey::FromCharacter('g'), ui::DomCode::US_G)); EXPECT_TRUE(WaitUntilInputFieldHasText(GetActiveWebContents(browser()), id, "ã…Ž", gfx::Range(1)));
diff --git a/chrome/browser/lacros/ui_metric_recorder_lacros.cc b/chrome/browser/lacros/ui_metric_recorder_lacros.cc index 785a1583..145ccb5 100644 --- a/chrome/browser/lacros/ui_metric_recorder_lacros.cc +++ b/chrome/browser/lacros/ui_metric_recorder_lacros.cc
@@ -10,9 +10,15 @@ UiMetricRecorderLacros::~UiMetricRecorderLacros() = default; void UiMetricRecorderLacros::ReportPercentDroppedFramesInOneSecondWindow( - double percentage) { + double percent) { UMA_HISTOGRAM_PERCENTAGE( - "Chrome.Lacros.Smoothness.PercentDroppedFrames_1sWindow", percentage); + "Chrome.Lacros.Smoothness.PercentDroppedFrames_1sWindow", percent); +} + +void UiMetricRecorderLacros::ReportPercentDroppedFramesInOneSecondWindow2( + double percent) { + UMA_HISTOGRAM_PERCENTAGE( + "Chrome.Lacros.Smoothness.PercentDroppedFrames_1sWindow2", percent); } // A stub method for CustomMetricRecorder::ReportEventLatency.
diff --git a/chrome/browser/lacros/ui_metric_recorder_lacros.h b/chrome/browser/lacros/ui_metric_recorder_lacros.h index 03a97f6..1b235ea8 100644 --- a/chrome/browser/lacros/ui_metric_recorder_lacros.h +++ b/chrome/browser/lacros/ui_metric_recorder_lacros.h
@@ -14,7 +14,8 @@ ~UiMetricRecorderLacros() override; // cc::CustomMetricRecorder: - void ReportPercentDroppedFramesInOneSecondWindow(double percentage) override; + void ReportPercentDroppedFramesInOneSecondWindow(double percent) override; + void ReportPercentDroppedFramesInOneSecondWindow2(double percent) override; void ReportEventLatency( std::vector<cc::EventLatencyTracker::LatencyData> latencies) override; };
diff --git a/chrome/browser/logging_chrome_unittest.cc b/chrome/browser/logging_chrome_unittest.cc index 2e89407..9c3f964c 100644 --- a/chrome/browser/logging_chrome_unittest.cc +++ b/chrome/browser/logging_chrome_unittest.cc
@@ -55,42 +55,83 @@ base::FilePath filename = logging::GetLogFileName(cmd_line()); ASSERT_NE(base::FilePath::StringType::npos, filename.value().find(FILE_PATH_LITERAL("chrome_debug.log"))); +#if BUILDFLAG(IS_WIN) + ASSERT_TRUE(filename.IsAbsolute()); +#endif // BUILDFLAG(IS_WIN) RestoreEnvironmentVariable(); } // Tests the log file name getter with an environment variable. +#if BUILDFLAG(IS_WIN) TEST_F(ChromeLoggingTest, EnvironmentLogFileName) { - SaveEnvironmentVariable("test env value"); - + SaveEnvironmentVariable("c:\\path\\test env value"); base::FilePath filename = logging::GetLogFileName(cmd_line()); - ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("test env value")).value(), - filename.value()); - + ASSERT_NE(base::FilePath::StringType::npos, + filename.value().find(FILE_PATH_LITERAL("test env value"))); + ASSERT_TRUE(filename.IsAbsolute()); RestoreEnvironmentVariable(); } +#else +TEST_F(ChromeLoggingTest, EnvironmentLogFileName) { + SaveEnvironmentVariable("test env value"); + base::FilePath filename = logging::GetLogFileName(cmd_line()); + ASSERT_NE(base::FilePath::StringType::npos, + filename.value().find(FILE_PATH_LITERAL("test env value"))); + RestoreEnvironmentVariable(); +} +#endif // BUILDFLAG(IS_WIN) // Tests the log file name getter with a command-line flag. +#if BUILDFLAG(IS_WIN) +TEST_F(ChromeLoggingTest, FlagLogFileName) { + SetLogFileFlag("c:\\path\\test flag value"); + base::FilePath filename = logging::GetLogFileName(cmd_line()); + ASSERT_NE(base::FilePath::StringType::npos, + filename.value().find(FILE_PATH_LITERAL("test flag value"))); + ASSERT_TRUE(filename.IsAbsolute()); +} +// Non-absolute path falls back to default. +TEST_F(ChromeLoggingTest, FlagLogFileNameNonAbsolute) { + SetLogFileFlag("test file value"); + base::FilePath filename = logging::GetLogFileName(cmd_line()); + ASSERT_NE(base::FilePath::StringType::npos, + filename.value().find(FILE_PATH_LITERAL("chrome_debug.log"))); + ASSERT_TRUE(filename.IsAbsolute()); +} +#else TEST_F(ChromeLoggingTest, FlagLogFileName) { SetLogFileFlag("test flag value"); - base::FilePath filename = logging::GetLogFileName(cmd_line()); - ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("test flag value")).value(), - filename.value()); + ASSERT_NE(base::FilePath::StringType::npos, + filename.value().find(FILE_PATH_LITERAL("test flag value"))); } +#endif // BUILDFLAG(IS_WIN) // Tests the log file name getter with with an environment variable and a // command-line flag. The flag takes precedence. +#if BUILDFLAG(IS_WIN) +TEST_F(ChromeLoggingTest, EnvironmentAndFlagLogFileName) { + SaveEnvironmentVariable("c:\\path\\test env value"); + SetLogFileFlag("d:\\path\\test flag value"); + + base::FilePath filename = logging::GetLogFileName(cmd_line()); + ASSERT_NE(base::FilePath::StringType::npos, + filename.value().find(FILE_PATH_LITERAL("test flag value"))); + ASSERT_TRUE(filename.IsAbsolute()); + RestoreEnvironmentVariable(); +} +#else TEST_F(ChromeLoggingTest, EnvironmentAndFlagLogFileName) { SaveEnvironmentVariable("test env value"); SetLogFileFlag("test flag value"); base::FilePath filename = logging::GetLogFileName(cmd_line()); - ASSERT_EQ(base::FilePath(FILE_PATH_LITERAL("test flag value")).value(), - filename.value()); - + ASSERT_NE(base::FilePath::StringType::npos, + filename.value().find(FILE_PATH_LITERAL("test flag value"))); RestoreEnvironmentVariable(); } +#endif // BUILDFLAG(IS_WIN) #if BUILDFLAG(IS_CHROMEOS_ASH) TEST_F(ChromeLoggingTest, TimestampedName) {
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_controller.cc b/chrome/browser/net/trial_comparison_cert_verifier_controller.cc index faa7c969..221084af 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_controller.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_controller.cc
@@ -43,11 +43,16 @@ return; } - pref_change_registrar_.Init(profile_->GetPrefs()); - pref_change_registrar_.Add( - prefs::kSafeBrowsingScoutReportingEnabled, + base::RepeatingClosure refresh_state_callback = base::BindRepeating(&TrialComparisonCertVerifierController::RefreshState, - base::Unretained(this))); + base::Unretained(this)); + pref_change_registrar_.Init(profile_->GetPrefs()); + pref_change_registrar_.Add(prefs::kSafeBrowsingEnabled, + refresh_state_callback); + pref_change_registrar_.Add(prefs::kSafeBrowsingEnhanced, + refresh_state_callback); + pref_change_registrar_.Add(prefs::kSafeBrowsingScoutReportingEnabled, + refresh_state_callback); } TrialComparisonCertVerifierController::
diff --git a/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc b/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc index 625ca9e..0e528b9 100644 --- a/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc +++ b/chrome/browser/net/trial_comparison_cert_verifier_controller_unittest.cc
@@ -98,7 +98,8 @@ receiver_; }; -class TrialComparisonCertVerifierControllerTest : public testing::Test { +class TrialComparisonCertVerifierControllerTest + : public testing::TestWithParam<bool> { public: void SetUp() override { cert_chain_1_ = CreateCertificateChainFromFile( @@ -148,6 +149,21 @@ base::RunLoop().RunUntilIdle(); } + void SetExtendedReportingPref(bool enabled) { + if (GetParam()) { + // SetEnhancedProtectionPrefForTests sets both kSafeBrowsingEnabled and + // kSafeBrowsingEnhanced. + safe_browsing::SetEnhancedProtectionPrefForTests(pref_service(), enabled); + } else { + // SetExtendedReportingPrefForTests only sets + // kSafeBrowsingScoutReportingEnabled, so first set kSafeBrowsingEnabled. + // Keeping this consistent between the branches makes the test conditions + // easier to write. + safe_browsing::SetStandardProtectionPref(pref_service(), enabled); + safe_browsing::SetExtendedReportingPrefForTests(pref_service(), enabled); + } + } + void CreateController(Profile* profile) { mojo::PendingRemote< cert_verifier::mojom::TrialComparisonCertVerifierConfigClient> @@ -228,7 +244,7 @@ mock_config_client_; }; -TEST_F(TrialComparisonCertVerifierControllerTest, NothingEnabled) { +TEST_P(TrialComparisonCertVerifierControllerTest, NothingEnabled) { CreateController(); // Trial should not be allowed. @@ -236,7 +252,7 @@ // Enable the SBER pref, shouldn't matter since it's a non-official build and // field trial isn't enabled. - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), true); + SetExtendedReportingPref(true); // Trial still not allowed, and OnTrialConfigUpdated should not be called // either. @@ -253,13 +269,13 @@ reporting_service_test_helper()->ExpectNoRequests(reporting_service()); } -TEST_F(TrialComparisonCertVerifierControllerTest, +TEST_P(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialNotEnabled) { TrialComparisonCertVerifierController::SetFakeOfficialBuildForTesting(true); CreateController(); EXPECT_FALSE(trial_controller().IsAllowed()); - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), true); + SetExtendedReportingPref(true); // Trial still not allowed, and OnTrialConfigUpdated should not be called // either. @@ -278,7 +294,7 @@ reporting_service_test_helper()->ExpectNoRequests(reporting_service()); } -TEST_F(TrialComparisonCertVerifierControllerTest, +TEST_P(TrialComparisonCertVerifierControllerTest, NotOfficialBuildTrialEnabled) { #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { @@ -301,7 +317,7 @@ // In a real official build, expect the trial config to be updated. EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(true)).Times(1); #endif - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), true); + SetExtendedReportingPref(true); #if defined(OFFICIAL_BUILD) && BUILDFLAG(GOOGLE_CHROME_BRANDING) // In a real official build, expect the trial to be allowed now. (Don't @@ -327,7 +343,7 @@ #endif } -TEST_F(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialEnabled) { +TEST_P(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialEnabled) { #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { // If ChromeRootStoreUsed feature is enabled by default, @@ -349,8 +365,9 @@ // Enable the SBER pref, which should trigger the OnTrialConfigUpdated // callback. + EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(false)).Times(1); EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(true)).Times(1); - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), true); + SetExtendedReportingPref(true); // Trial should now be allowed. EXPECT_TRUE(trial_controller().IsAllowed()); @@ -401,8 +418,8 @@ // Disable the SBER pref again, which should trigger the OnTrialConfigUpdated // callback. - EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(false)).Times(1); - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), false); + EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(false)).Times(2); + SetExtendedReportingPref(false); // Not allowed now. EXPECT_FALSE(trial_controller().IsAllowed()); @@ -418,7 +435,7 @@ reporting_service_test_helper()->ExpectNoRequests(reporting_service()); } -TEST_F(TrialComparisonCertVerifierControllerTest, +TEST_P(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialEnabledTwoClients) { #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { @@ -456,9 +473,12 @@ // Enable the SBER pref, which should trigger the OnTrialConfigUpdated // callback. + EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(false)).Times(1); EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(true)).Times(1); + + EXPECT_CALL(mock_config_client_2, OnTrialConfigUpdated(false)).Times(1); EXPECT_CALL(mock_config_client_2, OnTrialConfigUpdated(true)).Times(1); - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), true); + SetExtendedReportingPref(true); // Trial should now be allowed. EXPECT_TRUE(trial_controller().IsAllowed()); @@ -516,9 +536,9 @@ // Disable the SBER pref again, which should trigger the OnTrialConfigUpdated // callback. - EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(false)).Times(1); - EXPECT_CALL(mock_config_client_2, OnTrialConfigUpdated(false)).Times(1); - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), false); + EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(false)).Times(2); + EXPECT_CALL(mock_config_client_2, OnTrialConfigUpdated(false)).Times(2); + SetExtendedReportingPref(false); // Not allowed now. EXPECT_FALSE(trial_controller().IsAllowed()); @@ -538,7 +558,7 @@ reporting_service_test_helper()->ExpectNoRequests(reporting_service()); } -TEST_F(TrialComparisonCertVerifierControllerTest, +TEST_P(TrialComparisonCertVerifierControllerTest, OfficialBuildTrialEnabledUmaOnly) { #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { @@ -561,8 +581,9 @@ // Enable the SBER pref, which should trigger the OnTrialConfigUpdated // callback. + EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(false)).Times(1); EXPECT_CALL(mock_config_client(), OnTrialConfigUpdated(true)).Times(1); - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), true); + SetExtendedReportingPref(true); // Trial should now be allowed. EXPECT_TRUE(trial_controller().IsAllowed()); @@ -585,7 +606,7 @@ reporting_service_test_helper()->ExpectNoRequests(reporting_service()); } -TEST_F(TrialComparisonCertVerifierControllerTest, +TEST_P(TrialComparisonCertVerifierControllerTest, IncognitoOfficialBuildTrialEnabled) { #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED) if (base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed)) { @@ -607,7 +628,7 @@ EXPECT_FALSE(trial_controller().IsAllowed()); // Enable the SBER pref, shouldn't matter since it's an incognito profile. - safe_browsing::SetExtendedReportingPrefForTests(pref_service(), true); + SetExtendedReportingPref(true); // Trial still not allowed, and OnTrialConfigUpdated should not be called // either. @@ -623,3 +644,7 @@ // Expect no report since the trial is not allowed. reporting_service_test_helper()->ExpectNoRequests(reporting_service()); } + +INSTANTIATE_TEST_SUITE_P(Impl, + TrialComparisonCertVerifierControllerTest, + testing::Bool());
diff --git a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc index abd30ae..ea0ced3 100644 --- a/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc +++ b/chrome/browser/page_load_metrics/observers/from_gws_page_load_metrics_observer.cc
@@ -125,7 +125,8 @@ "MainFrame"; const char kHistogramFromGWSMaxCumulativeShiftScoreSessionWindow[] = - "PageLoad.LayoutInstability.MaxCumulativeShiftScore.SessionWindow.Gap1000ms" + "PageLoad.Clients.FromGoogleSearch.LayoutInstability." + "MaxCumulativeShiftScore.SessionWindow.Gap1000ms" ".Max5000ms2"; const char kHistogramFromGWSFromSidePanelFirstInputDelay[] =
diff --git a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java index 21c91ee0..c81a725 100644 --- a/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java +++ b/chrome/browser/partnercustomizations/java/src/org/chromium/chrome/browser/partnercustomizations/PartnerBrowserCustomizations.java
@@ -14,6 +14,7 @@ import org.chromium.base.annotations.CalledByNative; import org.chromium.base.task.AsyncTask; import org.chromium.base.task.PostTask; +import org.chromium.chrome.browser.flags.ChromeFeatureList; import org.chromium.chrome.browser.flags.ChromeSwitches; import org.chromium.chrome.browser.preferences.ChromePreferenceKeys; import org.chromium.chrome.browser.preferences.SharedPreferencesManager; @@ -204,14 +205,23 @@ CustomizationProviderDelegateImpl delegate = new CustomizationProviderDelegateImpl(); + if (ChromeFeatureList.sPartnerHomepageInitialLoadImprovement.isEnabled()) { + // Refresh the homepage first, as it has potential impact on the URL to use + // for the initial tab. + if (isCancelled()) return null; + mHomepageUriChanged = refreshHomepage(delegate); + } + if (isCancelled()) return null; refreshIncognitoModeDisabled(delegate); if (isCancelled()) return null; refreshBookmarksEditingDisabled(delegate); - if (isCancelled()) return null; - mHomepageUriChanged = refreshHomepage(delegate); + if (!ChromeFeatureList.sPartnerHomepageInitialLoadImprovement.isEnabled()) { + if (isCancelled()) return null; + mHomepageUriChanged = refreshHomepage(delegate); + } } catch (Exception e) { Log.w(TAG, "Fetching partner customizations failed", e); }
diff --git a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc index ebc9fc8d..986ab342 100644 --- a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc +++ b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.cc
@@ -161,27 +161,27 @@ FrozenDataImpl::GetOrCreate(page_impl); } -base::Value FrozenFrameAggregator::DescribePageNodeData( +base::Value::Dict FrozenFrameAggregator::DescribePageNodeData( const PageNode* node) const { FrozenDataImpl* data = FrozenDataImpl::Get(PageNodeImpl::FromNode(node)); if (data == nullptr) - return base::Value(); + return base::Value::Dict(); - base::Value ret(base::Value::Type::DICT); - ret.SetIntKey("current_frame_count", data->current_frame_count); - ret.SetIntKey("frozen_frame_count", data->frozen_frame_count); + base::Value::Dict ret; + ret.Set("current_frame_count", static_cast<int>(data->current_frame_count)); + ret.Set("frozen_frame_count", static_cast<int>(data->frozen_frame_count)); return ret; } -base::Value FrozenFrameAggregator::DescribeProcessNodeData( +base::Value::Dict FrozenFrameAggregator::DescribeProcessNodeData( const ProcessNode* node) const { FrozenDataImpl* data = FrozenDataImpl::Get(ProcessNodeImpl::FromNode(node)); if (data == nullptr) - return base::Value(); + return base::Value::Dict(); - base::Value ret(base::Value::Type::DICT); - ret.SetIntKey("current_frame_count", data->current_frame_count); - ret.SetIntKey("frozen_frame_count", data->frozen_frame_count); + base::Value::Dict ret; + ret.Set("current_frame_count", static_cast<int>(data->current_frame_count)); + ret.Set("frozen_frame_count", static_cast<int>(data->frozen_frame_count)); return ret; }
diff --git a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h index 442963d5..668772e 100644 --- a/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h +++ b/chrome/browser/performance_manager/decorators/frozen_frame_aggregator.h
@@ -52,8 +52,9 @@ void OnPageNodeAdded(const PageNode* page_node) override; // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* node) const override; - base::Value DescribeProcessNodeData(const ProcessNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const override; protected: friend class FrozenFrameAggregatorTest;
diff --git a/chrome/browser/performance_manager/decorators/page_aggregator.cc b/chrome/browser/performance_manager/decorators/page_aggregator.cc index a3d83a08..d9774e4b 100644 --- a/chrome/browser/performance_manager/decorators/page_aggregator.cc +++ b/chrome/browser/performance_manager/decorators/page_aggregator.cc
@@ -243,18 +243,19 @@ graph->RemoveFrameNodeObserver(this); } -base::Value PageAggregator::DescribePageNodeData(const PageNode* node) const { +base::Value::Dict PageAggregator::DescribePageNodeData( + const PageNode* node) const { Data* data = Data::Get(PageNodeImpl::FromNode(node)); if (data == nullptr) - return base::Value(); + return base::Value::Dict(); - base::Value ret(base::Value::Type::DICT); - ret.SetIntKey("num_frames_holding_web_lock", - data->num_frames_holding_web_lock_); - ret.SetIntKey("num_frames_holding_indexeddb_lock", - data->num_frames_holding_web_lock_); - ret.SetIntKey("num_current_frames_with_form_interaction", - data->num_current_frames_with_form_interaction_); + base::Value::Dict ret; + ret.Set("num_frames_holding_web_lock", + static_cast<int>(data->num_frames_holding_web_lock_)); + ret.Set("num_frames_holding_indexeddb_lock", + static_cast<int>(data->num_frames_holding_web_lock_)); + ret.Set("num_current_frames_with_form_interaction", + static_cast<int>(data->num_current_frames_with_form_interaction_)); return ret; }
diff --git a/chrome/browser/performance_manager/decorators/page_aggregator.h b/chrome/browser/performance_manager/decorators/page_aggregator.h index 43127a3..0c6092f8 100644 --- a/chrome/browser/performance_manager/decorators/page_aggregator.h +++ b/chrome/browser/performance_manager/decorators/page_aggregator.h
@@ -45,7 +45,7 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; }; } // namespace performance_manager
diff --git a/chrome/browser/performance_manager/decorators/process_priority_aggregator.cc b/chrome/browser/performance_manager/decorators/process_priority_aggregator.cc index 9dc66e5..4d14bf2 100644 --- a/chrome/browser/performance_manager/decorators/process_priority_aggregator.cc +++ b/chrome/browser/performance_manager/decorators/process_priority_aggregator.cc
@@ -147,15 +147,15 @@ graph->RemoveGraphObserver(this); } -base::Value ProcessPriorityAggregator::DescribeProcessNodeData( +base::Value::Dict ProcessPriorityAggregator::DescribeProcessNodeData( const ProcessNode* node) const { DataImpl* data = DataImpl::Get(ProcessNodeImpl::FromNode(node)); if (data == nullptr) - return base::Value(); + return base::Value::Dict(); - base::Value ret(base::Value::Type::DICT); - ret.SetIntKey("user_visible_count", data->user_visible_count_); - ret.SetIntKey("user_blocking_count", data->user_blocking_count_); + base::Value::Dict ret; + ret.Set("user_visible_count", static_cast<int>(data->user_visible_count_)); + ret.Set("user_blocking_count", static_cast<int>(data->user_blocking_count_)); return ret; }
diff --git a/chrome/browser/performance_manager/decorators/process_priority_aggregator.h b/chrome/browser/performance_manager/decorators/process_priority_aggregator.h index 308a2c2..e43b787 100644 --- a/chrome/browser/performance_manager/decorators/process_priority_aggregator.h +++ b/chrome/browser/performance_manager/decorators/process_priority_aggregator.h
@@ -44,7 +44,8 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: - base::Value DescribeProcessNodeData(const ProcessNode* node) const override; + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const override; // ProcessNodeObserver implementation: void OnProcessNodeAdded(const ProcessNode* process_node) override;
diff --git a/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc b/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc index 544574c..e3833f17e 100644 --- a/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc +++ b/chrome/browser/performance_manager/policies/background_tab_loading_policy.cc
@@ -292,28 +292,27 @@ } }; -base::Value BackgroundTabLoadingPolicy::DescribePageNodeData( +base::Value::Dict BackgroundTabLoadingPolicy::DescribePageNodeData( const PageNode* node) const { - base::Value dict(base::Value::Type::DICT); + base::Value::Dict dict; if (base::Contains(page_nodes_load_initiated_, node)) { // Transient state between InitiateLoad() and OnLoadingStateChanged(), // shouldn't be sticking around for long. - dict.SetBoolKey("page_load_initiated", true); + dict.Set("page_load_initiated", true); } if (base::Contains(page_nodes_loading_, node)) { - dict.SetBoolKey("page_loading", true); + dict.Set("page_loading", true); } - return !dict.DictEmpty() ? std::move(dict) : base::Value(); + return !dict.empty() ? std::move(dict) : base::Value::Dict(); } -base::Value BackgroundTabLoadingPolicy::DescribeSystemNodeData( +base::Value::Dict BackgroundTabLoadingPolicy::DescribeSystemNodeData( const SystemNode* node) const { - base::Value dict(base::Value::Type::DICT); - dict.SetIntKey("max_simultaneous_tab_loads", - base::saturated_cast<int>(max_simultaneous_tab_loads_)); - dict.SetIntKey("tab_loads_started", - base::saturated_cast<int>(tab_loads_started_)); - dict.SetIntKey("tabs_scored", base::saturated_cast<int>(tabs_scored_)); + base::Value::Dict dict; + dict.Set("max_simultaneous_tab_loads", + base::saturated_cast<int>(max_simultaneous_tab_loads_)); + dict.Set("tab_loads_started", base::saturated_cast<int>(tab_loads_started_)); + dict.Set("tabs_scored", base::saturated_cast<int>(tabs_scored_)); return dict; }
diff --git a/chrome/browser/performance_manager/policies/background_tab_loading_policy.h b/chrome/browser/performance_manager/policies/background_tab_loading_policy.h index f976f88..bcb3024 100644 --- a/chrome/browser/performance_manager/policies/background_tab_loading_policy.h +++ b/chrome/browser/performance_manager/policies/background_tab_loading_policy.h
@@ -113,8 +113,9 @@ struct ScoredTabComparator; // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* node) const override; - base::Value DescribeSystemNodeData(const SystemNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribeSystemNodeData( + const SystemNode* node) const override; // SystemNodeObserver: void OnMemoryPressure(
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper.cc b/chrome/browser/performance_manager/policies/page_discarding_helper.cc index e7f5637a..ed49a7b7 100644 --- a/chrome/browser/performance_manager/policies/page_discarding_helper.cc +++ b/chrome/browser/performance_manager/policies/page_discarding_helper.cc
@@ -400,14 +400,14 @@ return !it->second->MatchURL(url).empty(); } -base::Value PageDiscardingHelper::DescribePageNodeData( +base::Value::Dict PageDiscardingHelper::DescribePageNodeData( const PageNode* node) const { auto* data = DiscardAttemptMarker::Get(PageNodeImpl::FromNode(node)); if (data == nullptr) - return base::Value(); + return base::Value::Dict(); - base::Value ret(base::Value::Type::DICT); - ret.SetKey("has_discard_attempt_marker", base::Value("true")); + base::Value::Dict ret; + ret.Set("has_discard_attempt_marker", base::Value("true")); return ret; }
diff --git a/chrome/browser/performance_manager/policies/page_discarding_helper.h b/chrome/browser/performance_manager/policies/page_discarding_helper.h index e795b525..564a527f 100644 --- a/chrome/browser/performance_manager/policies/page_discarding_helper.h +++ b/chrome/browser/performance_manager/policies/page_discarding_helper.h
@@ -147,7 +147,7 @@ const GURL& url) const; // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; // Called after each discard attempt. |success| will indicate whether or not // the attempt has been successful. |post_discard_cb| will be called once
diff --git a/chrome/browser/performance_manager/policies/working_set_trimmer_policy.cc b/chrome/browser/performance_manager/policies/working_set_trimmer_policy.cc index f43376a..b377a605 100644 --- a/chrome/browser/performance_manager/policies/working_set_trimmer_policy.cc +++ b/chrome/browser/performance_manager/policies/working_set_trimmer_policy.cc
@@ -101,16 +101,16 @@ return false; } -base::Value WorkingSetTrimmerPolicy::DescribeProcessNodeData( +base::Value::Dict WorkingSetTrimmerPolicy::DescribeProcessNodeData( const ProcessNode* node) const { auto* data = WorkingSetTrimData::Get(ProcessNodeImpl::FromNode(node)); if (data == nullptr) - return base::Value(); + return base::Value::Dict(); - base::Value ret(base::Value::Type::DICT); + base::Value::Dict ret; auto last_trim_age = base::TimeTicks::Now() - data->last_trim_; - ret.SetKey( + ret.Set( "last_trim", base::Value(base::StrCat( {base::NumberToString(last_trim_age.InSeconds()), " seconds ago"})));
diff --git a/chrome/browser/performance_manager/policies/working_set_trimmer_policy.h b/chrome/browser/performance_manager/policies/working_set_trimmer_policy.h index 0e3c243..9b62cde2 100644 --- a/chrome/browser/performance_manager/policies/working_set_trimmer_policy.h +++ b/chrome/browser/performance_manager/policies/working_set_trimmer_policy.h
@@ -82,7 +82,8 @@ void SetLastTrimTime(const ProcessNode* process_node, base::TimeTicks time); // NodeDataDescriber implementation: - base::Value DescribeProcessNodeData(const ProcessNode* node) const override; + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const override; }; } // namespace policies
diff --git a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java index dced11e..da49df41 100644 --- a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java +++ b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/PrivacySandboxSettingsFragmentV3Test.java
@@ -60,6 +60,7 @@ import org.chromium.chrome.test.ChromeTabbedActivityTestRule; import org.chromium.chrome.test.util.ChromeRenderTestRule; import org.chromium.chrome.test.util.browser.Features; +import org.chromium.components.browser_ui.settings.SettingsFeatureList; import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; import org.chromium.ui.test.util.RenderTestRule; @@ -69,9 +70,7 @@ import java.util.List; import java.util.concurrent.ExecutionException; -/** - * Tests {@link PrivacySandboxSettingsFragment}. - */ +/** Tests {@link PrivacySandboxSettingsFragment}. */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @@ -156,7 +155,9 @@ @Test @SmallTest @Feature({"RenderTest"}) - public void testRenderMainPage() throws IOException { + @Features.EnableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) + public void testRenderMainPage_EnableHighlightManagedPrefDisclaimerAndroid() + throws IOException { openPrivacySandboxSettings(); mRenderTestRule.render( getRootView(R.string.privacy_sandbox_trials_title), "privacy_sandbox_main_view"); @@ -165,6 +166,17 @@ @Test @SmallTest @Feature({"RenderTest"}) + @Features.DisableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) + public void testRenderMainPage_DisableHighlightManagedPrefDisclaimerAndroid() + throws IOException { + openPrivacySandboxSettings(); + mRenderTestRule.render(getRootView(R.string.privacy_sandbox_trials_title), + "privacy_sandbox_main_view_DisableHighlightManagedPrefDisclaimerAndroid"); + } + + @Test + @SmallTest + @Feature({"RenderTest"}) public void testRenderAdPersonalizationView() throws IOException { mFakePrivacySandboxBridge.setCurrentTopTopics("Generated sample data", "More made up data"); mFakePrivacySandboxBridge.setCurrentFledgeSites("a.com", "b.com");
diff --git a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/v4/AdMeasurementFragmentV4Test.java b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/v4/AdMeasurementFragmentV4Test.java index f3a46d9..8a54f19 100644 --- a/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/v4/AdMeasurementFragmentV4Test.java +++ b/chrome/browser/privacy_sandbox/android/javatests/src/org/chromium/chrome/browser/privacy_sandbox/v4/AdMeasurementFragmentV4Test.java
@@ -45,8 +45,10 @@ import org.chromium.chrome.test.ChromeBrowserTestRule; import org.chromium.chrome.test.ChromeJUnit4ClassRunner; import org.chromium.chrome.test.util.ChromeRenderTestRule; -import org.chromium.components.policy.test.annotations.Policies; +import org.chromium.chrome.test.util.browser.Features.DisableFeatures; import org.chromium.chrome.test.util.browser.Features.EnableFeatures; +import org.chromium.components.browser_ui.settings.SettingsFeatureList; +import org.chromium.components.policy.test.annotations.Policies; import org.chromium.components.prefs.PrefService; import org.chromium.components.user_prefs.UserPrefs; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -55,9 +57,7 @@ import java.io.IOException; -/** - * Tests {@link AdMeasurementFragmentV4} - */ +/** Tests {@link AdMeasurementFragmentV4} */ @RunWith(ChromeJUnit4ClassRunner.class) @Batch(Batch.PER_CLASS) @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) @@ -124,8 +124,10 @@ @Test @SmallTest + @EnableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) @Feature({"RenderTest"}) - public void testRenderAdMeasurement() throws IOException { + public void testRenderAdMeasurement_EnableHighlightManagedPrefDisclaimerAndroid() + throws IOException { setAdMeasurementPrefEnabled(true); startAdMeasuremenSettings(); mRenderTestRule.render(getRootView(R.string.settings_ad_measurement_page_toggle_sub_label), @@ -134,6 +136,18 @@ @Test @SmallTest + @DisableFeatures(SettingsFeatureList.HIGHLIGHT_MANAGED_PREF_DISCLAIMER_ANDROID) + @Feature({"RenderTest"}) + public void testRenderAdMeasurement_DisableHighlightManagedPrefDisclaimerAndroid() + throws IOException { + setAdMeasurementPrefEnabled(true); + startAdMeasuremenSettings(); + mRenderTestRule.render(getRootView(R.string.settings_ad_measurement_page_toggle_sub_label), + "ad_measurement_page_toggle_on_DisableHighlightManagedPrefDisclaimerAndroid"); + } + + @Test + @SmallTest public void testToggleUncheckedWhenAdMeasurementOff() { setAdMeasurementPrefEnabled(false); startAdMeasuremenSettings();
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js index c93b1c2..e03d5fb 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/braille/braille_background.js
@@ -7,8 +7,6 @@ */ import {BrailleKeyEvent} from '../../common/braille/braille_key_types.js'; import {NavBraille} from '../../common/braille/nav_braille.js'; -import {BridgeConstants} from '../../common/bridge_constants.js'; -import {BridgeHelper} from '../../common/bridge_helper.js'; import {LogType} from '../../common/log_types.js'; import {SettingsManager} from '../../common/settings_manager.js'; import {ChromeVoxState} from '../chromevox_state.js'; @@ -20,9 +18,6 @@ import {BrailleKeyEventRewriter} from './braille_key_event_rewriter.js'; import {BrailleTranslatorManager} from './braille_translator_manager.js'; -const Action = BridgeConstants.BrailleBackground.Action; -const TARGET = BridgeConstants.BrailleBackground.TARGET; - /** @implements {BrailleInterface} */ export class BrailleBackground { /** @@ -64,8 +59,8 @@ static init() { BrailleBackground.instance = new BrailleBackground(); - BridgeHelper.registerHandler( - TARGET, Action.REFRESH_BRAILLE_TABLE, + SettingsManager.addListenerForKey( + 'brailleTable', brailleTable => BrailleBackground.instance.getTranslatorManager().refresh( brailleTable));
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js index fee128b..aa399b6 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/background/chromevox.js
@@ -42,7 +42,6 @@ }); BridgeHelper.registerHandler( - BridgeConstants.BrailleBackground.TARGET, - BridgeConstants.BrailleBackground.Action.WRITE, + BridgeConstants.Braille.TARGET, BridgeConstants.Braille.Action.WRITE, text => ChromeVox.braille.write(new NavBraille({text: new Spannable(text)})));
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js index 81fb9a8..3adde0fa7 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/background_bridge.js
@@ -29,19 +29,6 @@ BridgeConstants.Braille.TARGET, BridgeConstants.Braille.Action.BACK_TRANSLATE, cells); }, -}; - -BackgroundBridge.BrailleBackground = { - /** - * @param {string} brailleTable The table for this translator to use. - * @return {!Promise<boolean>} - */ - async refreshBrailleTable(brailleTable) { - return BridgeHelper.sendMessage( - BridgeConstants.BrailleBackground.TARGET, - BridgeConstants.BrailleBackground.Action.REFRESH_BRAILLE_TABLE, - brailleTable); - }, /** * @param {!string} text The text to write in Braille. @@ -49,8 +36,8 @@ */ async write(text) { return BridgeHelper.sendMessage( - BridgeConstants.BrailleBackground.TARGET, - BridgeConstants.BrailleBackground.Action.WRITE, text); + BridgeConstants.Braille.TARGET, BridgeConstants.Braille.Action.WRITE, + text); }, };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_constants.js b/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_constants.js index bad2b832..449e115 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_constants.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/common/bridge_constants.js
@@ -39,14 +39,6 @@ TARGET: 'Braille', Action: { BACK_TRANSLATE: 'backTranslate', - }, -}; - -/** @public {!BridgeEntry} */ -BridgeConstants.BrailleBackground = { - TARGET: 'BrailleBackground', - Action: { - REFRESH_BRAILLE_TABLE: 'refreshBrailleTable', WRITE: 'write', }, };
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/learn_mode/learn_mode.js b/chrome/browser/resources/chromeos/accessibility/chromevox/learn_mode/learn_mode.js index 39c6857..b8f968e 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/learn_mode/learn_mode.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/learn_mode/learn_mode.js
@@ -287,7 +287,7 @@ LearnMode.shouldFlushSpeech_ ? QueueMode.CATEGORY_FLUSH : QueueMode.QUEUE, new TtsSpeechProperties({endCallback: opt_outputCallback})); - BackgroundBridge.BrailleBackground.write(text); + BackgroundBridge.Braille.write(text); LearnMode.shouldFlushSpeech_ = false; if (opt_outputCallback) { opt_outputCallback();
diff --git a/chrome/browser/resources/chromeos/accessibility/chromevox/options/options.js b/chrome/browser/resources/chromeos/accessibility/chromevox/options/options.js index dddfdfe3..f1cf0a8 100644 --- a/chrome/browser/resources/chromeos/accessibility/chromevox/options/options.js +++ b/chrome/browser/resources/chromeos/accessibility/chromevox/options/options.js
@@ -341,8 +341,6 @@ const sel = node.options[selIndex]; SettingsManager.set('brailleTable', sel.id); SettingsManager.set(node.id, sel.id); - BackgroundBridge.BrailleBackground.refreshBrailleTable( - SettingsManager.getString('brailleTable')); }; }; @@ -376,8 +374,6 @@ tableTypeButton.textContent = Msgs.getMsg('options_braille_table_type_8'); } - BackgroundBridge.BrailleBackground.refreshBrailleTable( - SettingsManager.getString('brailleTable')); }; updateTableType(false);
diff --git a/chrome/browser/resources/chromeos/accessibility/common/local_storage.js b/chrome/browser/resources/chromeos/accessibility/common/local_storage.js index 553d303..a80f35a 100644 --- a/chrome/browser/resources/chromeos/accessibility/common/local_storage.js +++ b/chrome/browser/resources/chromeos/accessibility/common/local_storage.js
@@ -11,7 +11,7 @@ constructor(onInit) { /** @private {?Object} */ this.values_ = null; - /** @private {!Object<string, Function>} */ + /** @private {!Object<string, !Array<!Function>>} */ this.keyCallbacks_ = {}; chrome.storage.local.get( @@ -42,7 +42,12 @@ * @param {Function} callback */ static addListenerForKey(key, callback) { - LocalStorage.instance.keyCallbacks_[key] = callback; + if (!LocalStorage.instance.keyCallbacks_[key]) { + LocalStorage.instance.keyCallbacks_[key] = []; + } + if (callback) { + LocalStorage.instance.keyCallbacks_[key].push(callback); + } } /** @@ -158,7 +163,8 @@ for (const key in updates) { this.values_[key] = updates[key].newValue; if (this.keyCallbacks_[key]) { - this.keyCallbacks_[key](updates[key].newValue); + this.keyCallbacks_[key].forEach( + callback => callback(updates[key].newValue)); } } }
diff --git a/chrome/browser/resources/chromeos/emoji_picker/constants.ts b/chrome/browser/resources/chromeos/emoji_picker/constants.ts index eff8d2a..d922ca8 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/constants.ts +++ b/chrome/browser/resources/chromeos/emoji_picker/constants.ts
@@ -57,3 +57,31 @@ // 24 hours is equivalent to 86400000 milliseconds. export const TWENTY_FOUR_HOURS = 86400000; export const GIF_VALIDATION_DATE = 'gifValidationDate'; + +export const V2_5_EMOJI_PICKER_SIDE_PADDING = 18; +export const V2_5_GROUP_ICON_SIZE = + (EMOJI_PICKER_WIDTH - 2 * V2_5_EMOJI_PICKER_SIDE_PADDING) / EMOJI_PER_ROW; +export const V2_5_VISUAL_CONTENT_WIDTH = + (EMOJI_PICKER_WIDTH - 2 * V2_5_EMOJI_PICKER_SIDE_PADDING) / 2 - + VISUAL_CONTENT_PADDING / 2; + +export const V2_5_EMOJI_SPACING = + (EMOJI_PICKER_WIDTH - 2 * V2_5_EMOJI_PICKER_SIDE_PADDING - + EMOJI_PER_ROW * EMOJI_ICON_SIZE) / + (EMOJI_PER_ROW - 1); +export const V2_5_EMOJI_SPACING_PX = `${V2_5_EMOJI_SPACING}px`; +export const V2_5_EMOJI_GROUP_SIZE_PX = `${V2_5_GROUP_ICON_SIZE}px`; +export const V2_5_EMOJI_PICKER_SIDE_PADDING_PX = + `${V2_5_EMOJI_PICKER_SIDE_PADDING}px`; +export const V2_5_VISUAL_CONTENT_WIDTH_PX = `${V2_5_VISUAL_CONTENT_WIDTH}px`; + +export const V2_5_EMOJI_GROUP_SPACING = + (EMOJI_PICKER_WIDTH - 2 * V2_5_EMOJI_PICKER_SIDE_PADDING - + GROUP_PER_ROW * EMOJI_ICON_SIZE) / + (GROUP_PER_ROW - 1); +export const V2_5_EMOJI_PICKER_TOTAL_EMOJI_WIDTH = + EMOJI_ICON_SIZE + V2_5_EMOJI_GROUP_SPACING; + +export const V2_5_EMOJI_GROUP_SPACING_PX = `${V2_5_EMOJI_GROUP_SPACING}px`; +export const V2_5_EMOJI_PICKER_TOTAL_EMOJI_WIDTH_PX = + `${V2_5_EMOJI_PICKER_TOTAL_EMOJI_WIDTH}px`; \ No newline at end of file
diff --git a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.ts b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.ts index cd3fb67..bbb9530e 100644 --- a/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.ts +++ b/chrome/browser/resources/chromeos/emoji_picker/emoji_picker.ts
@@ -263,10 +263,16 @@ ) .then(values => values[0]); // Map to the fetched data only. - this.updateStyles({ - '--emoji-size': constants.EMOJI_ICON_SIZE_PX, - '--emoji-spacing': constants.EMOJI_SPACING_PX, - }); + if (this.gifSupport) { + this.updateStyles({ + '--emoji-group-button-size': constants.V2_5_EMOJI_GROUP_SIZE_PX, + '--emoji-picker-side-padding': + constants.V2_5_EMOJI_PICKER_SIDE_PADDING_PX, + '--emoji-spacing': constants.V2_5_EMOJI_SPACING_PX, + '--emoji-group-spacing': constants.V2_5_EMOJI_GROUP_SPACING_PX, + '--visual-content-width': constants.V2_5_VISUAL_CONTENT_WIDTH_PX, + }); + } // Update UI and relevant features based on the initial data. this.updateCategoryData(
diff --git a/chrome/browser/resources/chromeos/login/BUILD.gn b/chrome/browser/resources/chromeos/login/BUILD.gn index 39d895a..b324dd88 100644 --- a/chrome/browser/resources/chromeos/login/BUILD.gn +++ b/chrome/browser/resources/chromeos/login/BUILD.gn
@@ -27,19 +27,35 @@ # for convenience. # ----------------------------------------------------------------------------- grit("conditional_resources") { + defines = chrome_grit_defines + # Needed since some of the files are generated during build time. enable_input_discovery_for_gn_analyze = false - source = "oobe_conditional_resources.grd" + source = "$target_gen_dir/oobe_conditional_resources.grd" outputs = [ "grit/oobe_conditional_resources.h", + "grit/oobe_conditional_resources_map.h", + "grit/oobe_conditional_resources_map.cc", "oobe_conditional_resources.pak", ] - deps = [ ":preprocess_conditional" ] + deps = [ ":build_oobe_conditional_grd" ] output_dir = "$root_gen_dir/chrome" } +generate_grd("build_oobe_conditional_grd") { + grd_prefix = "oobe_conditional" + out_grd = "$target_gen_dir/${grd_prefix}_resources.grd" + deps = [ ":preprocess_conditional" ] + manifest_files = [ "$target_gen_dir/$conditional_files_manifest" ] + input_files_base_dir = rebase_path(".", "//") + input_files = [ + "debug/no_debug.js", + "test_api/no_test_api.js", + ] +} + # Files that are served conditionally preprocess_if_expr("preprocess_conditional") { deps = [
diff --git a/chrome/browser/resources/chromeos/login/oobe_conditional_resources.grd b/chrome/browser/resources/chromeos/login/oobe_conditional_resources.grd deleted file mode 100644 index 30c556d9..0000000 --- a/chrome/browser/resources/chromeos/login/oobe_conditional_resources.grd +++ /dev/null
@@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<grit latest_public_release="0" current_release="1" output_all_resource_defines="false"> - <outputs> - <output filename="grit/oobe_conditional_resources.h" type="rc_header"> - <emit emit_type='prepend'></emit> - </output> - <output filename="oobe_conditional_resources.pak" type="data_package" /> - </outputs> - <release seq="1"> - <includes> - <!-- Resources that are dynamically chosen to be served in runtime --> - <!-- OOBE Custom CSS Variables --> - <include name="IDR_OOBE_COMPONENTS_OOBE_CUSTOM_VARS_CSS_JS" use_base_dir="false" type="chrome_html" - file="${root_gen_dir}/chrome/browser/resources/chromeos/login/oobe_preprocessed/components/oobe_vars/oobe_custom_vars.css.js" /> - <include name="IDR_OOBE_COMPONENTS_OOBE_CUSTOM_VARS_REMORA_CSS_JS" use_base_dir="false" type="chrome_html" - file="${root_gen_dir}/chrome/browser/resources/chromeos/login/oobe_preprocessed/components/oobe_vars/oobe_custom_vars_remora.css.js" /> - - <!-- OOBE Test API --> - <include name="IDR_OOBE_TEST_API_JS" use_base_dir="false" type="chrome_html" - file="${root_gen_dir}/chrome/browser/resources/chromeos/login/oobe_preprocessed/test_api/test_api.js" /> - <include name="IDR_OOBE_TEST_API_STUB_JS" file="test_api/no_test_api.js" type="chrome_html" /> - - <!-- OOBE Debugger --> - <include name="IDR_OOBE_DEBUGGER_JS" use_base_dir="false" type="chrome_html" - file="${root_gen_dir}/chrome/browser/resources/chromeos/login/oobe_preprocessed/debug/debug.js" /> - <include name="IDR_OOBE_DEBUGGER_STUB_JS" file="debug\no_debug.js" type="chrome_html" /> - - </includes> - </release> -</grit>
diff --git a/chrome/browser/resources/settings/chromeos/device_page/OWNERS b/chrome/browser/resources/settings/chromeos/device_page/OWNERS index 84da6c79..1167dbbe 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/OWNERS +++ b/chrome/browser/resources/settings/chromeos/device_page/OWNERS
@@ -2,3 +2,4 @@ zentaro@chromium.org michaelcheco@google.com dpad@google.com +gavinwill@chromium.org \ No newline at end of file
diff --git a/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_data.ts b/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_data.ts index d3731112..42bfd90 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_data.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/fake_input_device_data.ts
@@ -23,6 +23,11 @@ [ModifierKey.META, ModifierKey.VOID], [ModifierKey.CAPS_LOCK, ModifierKey.ASSISTANT], ]), + topRowAreFKeys: false, + suppressMetaFKeyRewrites: false, + autoRepeatEnabled: false, + autoRepeatDelay: 2000, + autoRepeatInterval: 2000, }, }, { @@ -40,6 +45,11 @@ ], settings: { modifierRemappings: new Map<ModifierKey, ModifierKey>(), + topRowAreFKeys: true, + suppressMetaFKeyRewrites: true, + autoRepeatEnabled: true, + autoRepeatDelay: 150, + autoRepeatInterval: 20, }, }, ]; @@ -50,12 +60,36 @@ name: 'Default Touchpad', isExternal: false, isHaptic: true, + settings: { + sensitivity: 1, + reverseScrolling: false, + accelerationEnabled: false, + tapToClickEnabled: false, + threeFingerClickEnabled: false, + tapDraggingEnabled: false, + scrollSensitivity: 1, + scrollAcceleration: false, + hapticSensitivity: 1, + hapticEnabled: false, + }, }, { id: 3, name: 'Logitech T650', isExternal: true, isHaptic: false, + settings: { + sensitivity: 5, + reverseScrolling: true, + accelerationEnabled: true, + tapToClickEnabled: true, + threeFingerClickEnabled: true, + tapDraggingEnabled: true, + scrollSensitivity: 5, + scrollAcceleration: true, + hapticSensitivity: 5, + hapticEnabled: true, + }, }, ]; @@ -64,11 +98,27 @@ id: 4, name: 'Razer Basilisk V3', isExternal: true, + settings: { + swapRight: true, + sensitivity: 5, + reverseScrolling: true, + accelerationEnabled: true, + scrollSensitivity: 5, + scrollAcceleration: true, + }, }, { id: 5, name: 'MX Anywhere 2S', isExternal: false, + settings: { + swapRight: false, + sensitivity: 1, + reverseScrolling: false, + accelerationEnabled: false, + scrollSensitivity: 1, + scrollAcceleration: false, + }, }, ]; @@ -77,10 +127,20 @@ id: 6, name: 'Default Pointing Stick', isExternal: false, + settings: { + swapRight: false, + sensitivity: 1, + accelerationEnabled: false, + }, }, { id: 7, name: 'Lexmark-Unicomp FSR', isExternal: true, + settings: { + swapRight: true, + sensitivity: 5, + accelerationEnabled: true, + }, }, ];
diff --git a/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts b/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts index 32a843a..e9ab1474 100644 --- a/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts +++ b/chrome/browser/resources/settings/chromeos/device_page/input_device_settings_types.ts
@@ -48,6 +48,7 @@ isExternal: boolean; // Some settings are only available on haptic touchpads. isHaptic: boolean; + settings: TouchpadSettings; } export interface Mouse { @@ -55,6 +56,7 @@ name: string; // This property represents whether or not the mouse is an external device. isExternal: boolean; + settings: MouseSettings; } export interface PointingStick { @@ -63,11 +65,44 @@ // This property represents whether or not the pointing stick is an // external device. isExternal: boolean; + settings: PointingStickSettings; } export interface KeyboardSettings { modifierRemappings: Map<ModifierKey, ModifierKey>; - // TODO: Populate other KeyboardSettings interface. + topRowAreFKeys: boolean; + suppressMetaFKeyRewrites: boolean; + autoRepeatEnabled: boolean; + autoRepeatDelay: number; + autoRepeatInterval: number; +} + +export interface TouchpadSettings { + sensitivity: number; + reverseScrolling: boolean; + accelerationEnabled: boolean; + tapToClickEnabled: boolean; + threeFingerClickEnabled: boolean; + tapDraggingEnabled: boolean; + scrollSensitivity: number; + scrollAcceleration: boolean; + hapticSensitivity: number; + hapticEnabled: boolean; +} + +export interface MouseSettings { + swapRight: boolean; + sensitivity: number; + reverseScrolling: boolean; + accelerationEnabled: boolean; + scrollSensitivity: number; + scrollAcceleration: boolean; +} + +export interface PointingStickSettings { + swapRight: boolean; + sensitivity: number; + accelerationEnabled: boolean; } export interface KeyboardObserverInterface {
diff --git a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html index 37eace30..b0e01a6 100644 --- a/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html +++ b/chrome/browser/resources/settings/chromeos/multidevice_page/multidevice_feature_toggle.html
@@ -1,3 +1,4 @@ +<style include="cr-shared-style settings-shared"></style> <cr-toggle id="toggle" aria-label$="[[getToggleA11yLabel_(feature)]]" checked="{{checked_}}"
diff --git a/chrome/browser/task_manager/providers/render_process_host_task_provider.cc b/chrome/browser/task_manager/providers/render_process_host_task_provider.cc index 96911c5..1ae4b2c5 100644 --- a/chrome/browser/task_manager/providers/render_process_host_task_provider.cc +++ b/chrome/browser/task_manager/providers/render_process_host_task_provider.cc
@@ -53,8 +53,6 @@ } } - registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CREATED, - content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, content::NotificationService::AllBrowserContextsAndSources()); registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_TERMINATED, @@ -104,6 +102,11 @@ tasks_by_rph_id_.erase(itr); } +void RenderProcessHostTaskProvider::OnRenderProcessHostCreated( + content::RenderProcessHost* host) { + CreateTask(host->GetID()); +} + void RenderProcessHostTaskProvider::Observe( int type, const content::NotificationSource& source, @@ -112,9 +115,6 @@ content::Source<content::RenderProcessHost>(source).ptr(); ChildProcessData data(content::PROCESS_TYPE_RENDERER); switch (type) { - case content::NOTIFICATION_RENDERER_PROCESS_CREATED: - CreateTask(host->GetID()); - break; case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: case content::NOTIFICATION_RENDERER_PROCESS_TERMINATED: DeleteTask(host->GetID());
diff --git a/chrome/browser/task_manager/providers/render_process_host_task_provider.h b/chrome/browser/task_manager/providers/render_process_host_task_provider.h index bf0dba8..d33a9d6 100644 --- a/chrome/browser/task_manager/providers/render_process_host_task_provider.h +++ b/chrome/browser/task_manager/providers/render_process_host_task_provider.h
@@ -13,6 +13,7 @@ #include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_service.h" +#include "content/public/browser/render_process_host_creation_observer.h" namespace task_manager { @@ -21,8 +22,10 @@ // This provides tasks that represent RenderProcessHost processes. It does so by // listening to the notification service for the creation and destruction of the // RenderProcessHost. -class RenderProcessHostTaskProvider : public TaskProvider, - public content::NotificationObserver { +class RenderProcessHostTaskProvider + : public TaskProvider, + public content::RenderProcessHostCreationObserver, + public content::NotificationObserver { public: RenderProcessHostTaskProvider(); RenderProcessHostTaskProvider(const RenderProcessHostTaskProvider&) = delete; @@ -33,6 +36,9 @@ // task_manager::TaskProvider: Task* GetTaskOfUrlRequest(int child_id, int route_id) override; + // content::RenderProcessHostCreationObserver: + void OnRenderProcessHostCreated(content::RenderProcessHost* host) override; + // content::NotificationObserver: void Observe(int type, const content::NotificationSource& source,
diff --git a/chrome/browser/ui/BUILD.gn b/chrome/browser/ui/BUILD.gn index f9a230ad..4ad88038 100644 --- a/chrome/browser/ui/BUILD.gn +++ b/chrome/browser/ui/BUILD.gn
@@ -4509,6 +4509,8 @@ "views/download/bubble/download_bubble_row_view.h", "views/download/bubble/download_bubble_security_view.cc", "views/download/bubble/download_bubble_security_view.h", + "views/download/bubble/download_bubble_started_animation_views.cc", + "views/download/bubble/download_bubble_started_animation_views.h", "views/download/bubble/download_dialog_view.cc", "views/download/bubble/download_dialog_view.h", "views/download/bubble/download_toolbar_button_view.cc",
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 389ca3de..01c6f65 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
@@ -162,7 +162,7 @@ Drawable bdgTabImage = ResourcesCompat.getDrawable(getContext().getResources(), TabUiThemeUtil.getTSRTabResource(), getContext().getTheme()); bdgTabImage.setTint( - TabUiThemeUtil.getTabStripContainerColor(getContext(), false, true)); + TabUiThemeUtil.getTabStripContainerColor(getContext(), false, true, false)); LayerDrawable backgroundDrawable = new LayerDrawable(new Drawable[] {bgdColor, bdgTabImage}); // Set image size to match tab size.
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.cc b/chrome/browser/ui/ash/test_wallpaper_controller.cc index 15fb9930..805304a 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.cc +++ b/chrome/browser/ui/ash/test_wallpaper_controller.cc
@@ -215,7 +215,9 @@ ++remove_always_on_top_wallpaper_count_; } -void TestWallpaperController::RemoveUserWallpaper(const AccountId& account_id) { +void TestWallpaperController::RemoveUserWallpaper( + const AccountId& account_id, + base::OnceClosure on_removed) { ++remove_user_wallpaper_count_; }
diff --git a/chrome/browser/ui/ash/test_wallpaper_controller.h b/chrome/browser/ui/ash/test_wallpaper_controller.h index 46de456..bb73889 100644 --- a/chrome/browser/ui/ash/test_wallpaper_controller.h +++ b/chrome/browser/ui/ash/test_wallpaper_controller.h
@@ -140,7 +140,8 @@ void ShowOneShotWallpaper(const gfx::ImageSkia& image) override; void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path) override; void RemoveAlwaysOnTopWallpaper() override; - void RemoveUserWallpaper(const AccountId& account_id) override; + void RemoveUserWallpaper(const AccountId& account_id, + base::OnceClosure on_removed) override; void RemovePolicyWallpaper(const AccountId& account_id) override; void SetAnimationDuration(base::TimeDelta animation_duration) override; void OpenWallpaperPickerIfAllowed() override;
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc index 03abc70d..01cfa12 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.cc
@@ -354,11 +354,14 @@ } void WallpaperControllerClientImpl::RemoveUserWallpaper( - const AccountId& account_id) { - if (!IsKnownUser(account_id)) + const AccountId& account_id, + base::OnceClosure on_removed) { + if (!IsKnownUser(account_id)) { + std::move(on_removed).Run(); return; + } - wallpaper_controller_->RemoveUserWallpaper(account_id); + wallpaper_controller_->RemoveUserWallpaper(account_id, std::move(on_removed)); } void WallpaperControllerClientImpl::RemovePolicyWallpaper(
diff --git a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h index 9d9618f..71719938 100644 --- a/chrome/browser/ui/ash/wallpaper_controller_client_impl.h +++ b/chrome/browser/ui/ash/wallpaper_controller_client_impl.h
@@ -120,7 +120,8 @@ void ShowSigninWallpaper(); void ShowAlwaysOnTopWallpaper(const base::FilePath& image_path); void RemoveAlwaysOnTopWallpaper(); - void RemoveUserWallpaper(const AccountId& account_id); + void RemoveUserWallpaper(const AccountId& account_id, + base::OnceClosure on_removed); void RemovePolicyWallpaper(const AccountId& account_id); void SetAnimationDuration(const base::TimeDelta& animation_duration); void OpenWallpaperPickerIfAllowed();
diff --git a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc index 7f3add6..0fead82 100644 --- a/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/save_card_bubble_controller_impl.cc
@@ -46,27 +46,6 @@ #include "content/public/browser/navigation_handle.h" #include "ui/base/l10n/l10n_util.h" -namespace { - -autofill::SaveCardUiExperiment GetSaveCardUiExperimentArm() { - if (!base::FeatureList::IsEnabled( - autofill::features::kAutofillSaveCardUiExperiment)) { - return autofill::SaveCardUiExperiment::DEFAULT; - } - - switch ( - autofill::features::kAutofillSaveCardUiExperimentSelectorInNumber.Get()) { - case 1: - return autofill::SaveCardUiExperiment::FASTER_AND_PROTECTED; - case 2: - return autofill::SaveCardUiExperiment::ENCRYPTED_AND_SECURE; - default: - return autofill::SaveCardUiExperiment::DEFAULT; - } -} - -} // namespace - namespace autofill { SaveCardBubbleControllerImpl::SaveCardBubbleControllerImpl( @@ -187,16 +166,6 @@ return l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_LOCAL); case BubbleType::UPLOAD_SAVE: - if (GetSaveCardUiExperimentArm() == - SaveCardUiExperiment::FASTER_AND_PROTECTED) { - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_EXPERIMENT_FASTER_AND_PROTECTED); - } - if (GetSaveCardUiExperimentArm() == - SaveCardUiExperiment::ENCRYPTED_AND_SECURE) { - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_EXPERIMENT_ENCRYPTED_AND_SECURE); - } return features::ShouldShowImprovedUserConsentForCreditCardSave() ? l10n_util::GetStringUTF16( IDS_AUTOFILL_SAVE_CARD_PROMPT_TITLE_TO_CLOUD_V4) @@ -225,17 +194,8 @@ IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V3_WITH_NAME); } - switch (GetSaveCardUiExperimentArm()) { - case SaveCardUiExperiment::FASTER_AND_PROTECTED: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_EXPERIMENT_FASTER_AND_PROTECTED); - case SaveCardUiExperiment::ENCRYPTED_AND_SECURE: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_EXPERIMENT_ENCRYPTED_AND_SECURE); - default: - return l10n_util::GetStringUTF16( - IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V3); - } + return l10n_util::GetStringUTF16( + IDS_AUTOFILL_SAVE_CARD_PROMPT_UPLOAD_EXPLANATION_V3); } std::u16string SaveCardBubbleControllerImpl::GetAcceptButtonText() const {
diff --git a/chrome/browser/ui/autofill/payments/save_card_ui.h b/chrome/browser/ui/autofill/payments/save_card_ui.h index a59d560..693e7532 100644 --- a/chrome/browser/ui/autofill/payments/save_card_ui.h +++ b/chrome/browser/ui/autofill/payments/save_card_ui.h
@@ -31,18 +31,6 @@ INACTIVE }; -// The type of experiment running for the save card ui. -enum SaveCardUiExperiment { - // Show the text for default/current image. - DEFAULT = 0, - - // Show the text for faster and protected image. - FASTER_AND_PROTECTED = 1, - - // Show the text for encrypted and secure image. - ENCRYPTED_AND_SECURE = 2 -}; - } // namespace autofill #endif // CHROME_BROWSER_UI_AUTOFILL_PAYMENTS_SAVE_CARD_UI_H_
diff --git a/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.cc b/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.cc index 1e927d0..86f20099 100644 --- a/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.cc +++ b/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.cc
@@ -16,6 +16,8 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/page_action/page_action_icon_type.h" #include "chrome/grit/generated_resources.h" +#include "components/autofill/core/browser/metrics/autofill_metrics.h" +#include "components/autofill/core/browser/metrics/payments/iban_metrics.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/strings/grit/components_strings.h" #include "ui/base/l10n/l10n_util.h" @@ -45,6 +47,7 @@ } iban_ = iban; + is_reshow_ = false; local_save_iban_prompt_callback_ = std::move(save_iban_prompt_callback); current_bubble_type_ = IbanBubbleType::kLocalSave; @@ -55,12 +58,13 @@ } } -void SaveIbanBubbleControllerImpl::EnsureBubbleShown() { +void SaveIbanBubbleControllerImpl::ReshowBubble() { // Don't show the bubble if it's already visible. if (bubble_view()) { return; } + is_reshow_ = true; ShowBubble(); } @@ -107,6 +111,8 @@ // Show an animated IBAN saved confirmation message next time // UpdatePageActionIcon() is called. should_show_iban_saved_label_animation_ = true; + autofill_metrics::LogSaveIbanBubbleResultSavedWithNicknameMetric( + !nickname.empty()); std::move(local_save_iban_prompt_callback_) .Run(AutofillClient::SaveIBANOfferUserDecision::kAccepted, nickname); break; @@ -127,16 +133,36 @@ PaymentsBubbleClosedReason closed_reason) { set_bubble_view(nullptr); - // Handles `current_bubble_type_` change according to its current type and the - // `closed_reason`. - if (closed_reason == PaymentsBubbleClosedReason::kAccepted) { - if (current_bubble_type_ == IbanBubbleType::kLocalSave) { - // TODO(crbug.com/1349109): Add kManageIban type to open IBAN bubble for - // managing the saved IBAN. - } else { - current_bubble_type_ = IbanBubbleType::kInactive; + // Log save IBAN prompt result according to the closed reason. + if (current_bubble_type_ == IbanBubbleType::kLocalSave) { + autofill_metrics::SaveIbanBubbleResult metric; + switch (closed_reason) { + case PaymentsBubbleClosedReason::kAccepted: + metric = autofill_metrics::SaveIbanBubbleResult::kAccepted; + break; + case PaymentsBubbleClosedReason::kCancelled: + metric = autofill_metrics::SaveIbanBubbleResult::kCancelled; + break; + case PaymentsBubbleClosedReason::kClosed: + metric = autofill_metrics::SaveIbanBubbleResult::kClosed; + break; + case PaymentsBubbleClosedReason::kNotInteracted: + metric = autofill_metrics::SaveIbanBubbleResult::kNotInteracted; + break; + case PaymentsBubbleClosedReason::kLostFocus: + metric = autofill_metrics::SaveIbanBubbleResult::kLostFocus; + break; + case PaymentsBubbleClosedReason::kUnknown: + metric = autofill_metrics::SaveIbanBubbleResult::kUnknown; + NOTREACHED(); + break; } - } else if (closed_reason == PaymentsBubbleClosedReason::kCancelled) { + autofill_metrics::LogSaveIbanBubbleResultMetric(metric, is_reshow_); + } + + // Handles `current_bubble_type_` change according to the `closed_reason`. + if (closed_reason == PaymentsBubbleClosedReason::kAccepted || + closed_reason == PaymentsBubbleClosedReason::kCancelled) { current_bubble_type_ = IbanBubbleType::kInactive; } @@ -217,9 +243,18 @@ current_bubble_type_ == IbanBubbleType::kLocalSave)); DCHECK(!bubble_view()); Show(); + switch (current_bubble_type_) { + case IbanBubbleType::kLocalSave: + autofill_metrics::LogSaveIbanBubbleOfferMetric( + autofill_metrics::SaveIbanPromptOffer::kShown, is_reshow_); + break; + case IbanBubbleType::kInactive: + NOTREACHED(); + } } void SaveIbanBubbleControllerImpl::ShowIconOnly() { + DCHECK(!is_reshow_); DCHECK(current_bubble_type_ != IbanBubbleType::kInactive); // Local save callback should not be null for LOCAL_SAVE state. DCHECK(!local_save_iban_prompt_callback_.is_null() || @@ -230,6 +265,16 @@ // explicitly clicks the icon. UpdatePageActionIcon(); + switch (current_bubble_type_) { + case IbanBubbleType::kLocalSave: + autofill_metrics::LogSaveIbanBubbleOfferMetric( + autofill_metrics::SaveIbanPromptOffer::kNotShownMaxStrikesReached, + is_reshow_); + break; + case IbanBubbleType::kInactive: + NOTREACHED(); + } + if (observer_for_testing_) { observer_for_testing_->OnIconShown(); }
diff --git a/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.h b/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.h index 99fecf7..7c80587 100644 --- a/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.h +++ b/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.h
@@ -48,7 +48,7 @@ AutofillClient::LocalSaveIBANPromptCallback save_iban_prompt_callback); // No-op if the bubble is already shown, otherwise, shows the bubble. - void EnsureBubbleShown(); + void ReshowBubble(); // SaveIbanBubbleController: std::u16string GetWindowTitle() const override; @@ -109,6 +109,9 @@ // IBAN offer-to-save prompt. AutofillClient::LocalSaveIBANPromptCallback local_save_iban_prompt_callback_; + // Whether the bubble is shown after user interacted with the omnibox icon. + bool is_reshow_ = false; + // Contains the details of the IBAN that will be saved if the user accepts. IBAN iban_;
diff --git a/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl_unittest.cc b/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl_unittest.cc index 3d2b220d..18d995c0 100644 --- a/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl_unittest.cc +++ b/chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl_unittest.cc
@@ -4,10 +4,12 @@ #include "chrome/browser/ui/autofill/payments/save_iban_bubble_controller_impl.h" +#include "base/test/metrics/histogram_tester.h" #include "chrome/browser/ui/autofill/autofill_bubble_base.h" #include "chrome/test/base/browser_with_test_window_test.h" #include "components/autofill/core/browser/autofill_test_utils.h" #include "components/autofill/core/browser/data_model/iban.h" +#include "components/autofill/core/browser/metrics/payments/iban_metrics.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -55,6 +57,10 @@ } } + void CloseBubble(PaymentsBubbleClosedReason closed_reason) { + controller()->OnBubbleClosed(closed_reason); + } + std::u16string saved_nickname() { return saved_nickname_; } protected: @@ -84,4 +90,72 @@ EXPECT_EQ(nickname, saved_nickname()); } +TEST_F(SaveIbanBubbleControllerImplTest, Metrics_LocalIbanOffered) { + base::HistogramTester histogram_tester; + ShowLocalBubble(autofill::test::GetIBAN()); + + histogram_tester.ExpectBucketCount( + "Autofill.SaveIbanPromptOffer.Local.FirstShow", + autofill_metrics::SaveIbanPromptOffer::kShown, 1); +} + +TEST_F(SaveIbanBubbleControllerImplTest, Metrics_LocalIbanResult_Accepted) { + base::HistogramTester histogram_tester; + ShowLocalBubble(autofill::test::GetIBAN()); + CloseBubble(PaymentsBubbleClosedReason::kAccepted); + + histogram_tester.ExpectBucketCount( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kAccepted, 1); +} + +TEST_F(SaveIbanBubbleControllerImplTest, Metrics_LocalIbanResult_Cancelled) { + base::HistogramTester histogram_tester; + ShowLocalBubble(autofill::test::GetIBAN()); + CloseBubble(PaymentsBubbleClosedReason::kCancelled); + + histogram_tester.ExpectBucketCount( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kCancelled, 1); +} + +TEST_F(SaveIbanBubbleControllerImplTest, + Metrics_LocalIbanResult_NotInteracted) { + base::HistogramTester histogram_tester; + ShowLocalBubble(autofill::test::GetIBAN()); + CloseBubble(PaymentsBubbleClosedReason::kNotInteracted); + + histogram_tester.ExpectBucketCount( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kNotInteracted, 1); +} + +TEST_F(SaveIbanBubbleControllerImplTest, Metrics_LocalIbanResult_LostFocus) { + base::HistogramTester histogram_tester; + ShowLocalBubble(autofill::test::GetIBAN()); + CloseBubble(PaymentsBubbleClosedReason::kLostFocus); + + histogram_tester.ExpectBucketCount( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kLostFocus, 1); +} + +TEST_F(SaveIbanBubbleControllerImplTest, Metrics_LocalIbanSaved_WithNickname) { + base::HistogramTester histogram_tester; + ShowLocalBubble(autofill::test::GetIBAN()); + ClickSaveButton(u"My doctor's IBAN"); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.SavedWithNickname", true, 1); +} + +TEST_F(SaveIbanBubbleControllerImplTest, Metrics_LocalIbanSaved_NoNickname) { + base::HistogramTester histogram_tester; + ShowLocalBubble(autofill::test::GetIBAN()); + ClickSaveButton(u""); + + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.SavedWithNickname", false, 1); +} + } // namespace autofill
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc index 62ceedc..17c134b 100644 --- a/chrome/browser/ui/browser_commands.cc +++ b/chrome/browser/ui/browser_commands.cc
@@ -1276,7 +1276,7 @@ browser->tab_strip_model()->GetActiveWebContents(); autofill::SaveIbanBubbleControllerImpl* controller = autofill::SaveIbanBubbleControllerImpl::FromWebContents(web_contents); - controller->EnsureBubbleShown(); + controller->ReshowBubble(); } void MigrateLocalCards(Browser* browser) {
diff --git a/chrome/browser/ui/color/chrome_color_id.h b/chrome/browser/ui/color/chrome_color_id.h index 43fe9836..0f15f72 100644 --- a/chrome/browser/ui/color/chrome_color_id.h +++ b/chrome/browser/ui/color/chrome_color_id.h
@@ -63,6 +63,8 @@ E_CPONLY(kColorDownloadShelfForeground) \ E_CPONLY(kColorDownloadStartedAnimationForeground) \ E_CPONLY(kColorDownloadToolbarButtonActive) \ + E_CPONLY(kColorDownloadToolbarButtonAnimationBackground) \ + E_CPONLY(kColorDownloadToolbarButtonAnimationForeground) \ E_CPONLY(kColorDownloadToolbarButtonInactive) \ E_CPONLY(kColorDownloadToolbarButtonRingBackground) \ /* Extension colors. */ \
diff --git a/chrome/browser/ui/color/chrome_color_mixer.cc b/chrome/browser/ui/color/chrome_color_mixer.cc index 6fd69309..0fad10c 100644 --- a/chrome/browser/ui/color/chrome_color_mixer.cc +++ b/chrome/browser/ui/color/chrome_color_mixer.cc
@@ -191,6 +191,13 @@ mixer[kColorDownloadToolbarButtonActive] = ui::PickGoogleColor(ui::kColorThrobber, kColorToolbar, color_utils::kMinimumVisibleContrastRatio); + // TODO(chlily): The opacity should be kToolbarInkDropHighlightVisibleOpacity + // (same as used in AdjustHighlightColorForContrast()). Pull out usages of the + // constant. + mixer[kColorDownloadToolbarButtonAnimationBackground] = ui::AlphaBlend( + kColorDownloadToolbarButtonAnimationForeground, kColorToolbar, 0x14); + mixer[kColorDownloadToolbarButtonAnimationForeground] = + AdjustHighlightColorForContrast(ui::kColorAccent, kColorToolbar); mixer[kColorDownloadToolbarButtonInactive] = {kColorToolbarButtonIcon}; mixer[kColorDownloadToolbarButtonRingBackground] = { SkColorSetA(kColorDownloadToolbarButtonInactive, 0x33)};
diff --git a/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h b/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h index 8876454..7d2fbed 100644 --- a/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h +++ b/chrome/browser/ui/views/autofill/payments/dialog_view_ids.h
@@ -50,6 +50,7 @@ // The following are views::Textfield objects. CARDHOLDER_NAME_TEXTFIELD, // Used for cardholder name entry/confirmation + NICKNAME_TEXTFIELD, // Used for IBAN nickname entry/confirmation // The following are views::TooltipIcon objects. CARDHOLDER_NAME_TOOLTIP, // Appears during cardholder name entry/confirmation
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc index 0640bf4..efaec77 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc +++ b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.cc
@@ -53,28 +53,6 @@ #include "ui/views/layout/box_layout.h" #include "ui/views/style/typography.h" -namespace { - -ui::ImageModel GetProfileAvatar(AccountInfo account_info) { - // Get the user avatar icon. - gfx::Image account_avatar = account_info.account_image; - - // Check for avatar being empty and replacing it with a - // placeholder if that is the case. - if (account_avatar.IsEmpty()) { - account_avatar = ui::ResourceBundle::GetSharedInstance().GetImageNamed( - profiles::GetPlaceholderAvatarIconResourceID()); - } - - int avatar_size = views::style::GetLineHeight( - views::style::CONTEXT_DIALOG_BODY_TEXT, views::style::STYLE_SECONDARY); - - return ui::ImageModel::FromImage(profiles::GetSizedAvatarIcon( - account_avatar, avatar_size, avatar_size, profiles::SHAPE_CIRCLE)); -} - -} // namespace - namespace autofill { SaveCardOfferBubbleViews::SaveCardOfferBubbleViews( @@ -86,21 +64,11 @@ const LegalMessageLines message_lines = controller->GetLegalMessageLines(); if (!message_lines.empty()) { - if (IsSaveCardUiExperimentEnabled()) { - std::string user_email = controller->GetAccountInfo().email; - // Display TOS with user avatar and email present in the footer. - legal_message_view_ = SetFootnoteView(std::make_unique<LegalMessageView>( - message_lines, base::UTF8ToUTF16(user_email), - GetProfileAvatar(controller->GetAccountInfo()), - base::BindRepeating(&SaveCardOfferBubbleViews::LinkClicked, - base::Unretained(this)))); - } else { - legal_message_view_ = SetFootnoteView(std::make_unique<LegalMessageView>( - message_lines, /*user_email=*/absl::nullopt, - /*user_avatar=*/absl::nullopt, - base::BindRepeating(&SaveCardOfferBubbleViews::LinkClicked, - base::Unretained(this)))); - } + legal_message_view_ = SetFootnoteView(std::make_unique<LegalMessageView>( + message_lines, /*user_email=*/absl::nullopt, + /*user_avatar=*/absl::nullopt, + base::BindRepeating(&SaveCardOfferBubbleViews::LinkClicked, + base::Unretained(this)))); InitFootnoteView(legal_message_view_); } @@ -180,24 +148,13 @@ // Set the header image. ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); - // Boolean to show the shield image for save card bubble. It is - // active/shown only when save card ui experiment is enabled and when the - // active experiment selected != 3 (existing option with user information - // view). - bool show_shield_header_image = - IsSaveCardUiExperimentEnabled() && - features::kAutofillSaveCardUiExperimentSelectorInNumber.Get() != 3; - // Ternary operator added for the save card ui experiment where the feature // flag and the experiment selected would determine if the experiment is // active or not. Currently, any option != 0 and experiment flag enabled // should trigger the experiment. auto image_view = std::make_unique<ThemeTrackingNonAccessibleImageView>( - *bundle.GetImageSkiaNamed( - show_shield_header_image ? IDR_SAVE_CARD_SECURELY : IDR_SAVE_CARD), - *bundle.GetImageSkiaNamed(show_shield_header_image - ? IDR_SAVE_CARD_SECURELY_DARK - : IDR_SAVE_CARD_DARK), + *bundle.GetImageSkiaNamed(IDR_SAVE_CARD), + *bundle.GetImageSkiaNamed(IDR_SAVE_CARD_DARK), base::BindRepeating(&views::BubbleDialogDelegate::GetBackgroundColor, base::Unretained(this))); GetBubbleFrameView()->SetHeaderView(std::move(image_view)); @@ -384,12 +341,6 @@ return upload_explanation_tooltip; } -bool SaveCardOfferBubbleViews::IsSaveCardUiExperimentEnabled() { - return ( - base::FeatureList::IsEnabled(features::kAutofillSaveCardUiExperiment) && - features::kAutofillSaveCardUiExperimentSelectorInNumber.Get() != 0); -} - void SaveCardOfferBubbleViews::LinkClicked(const GURL& url) { if (controller()) controller()->OnLegalMessageLinkClicked(url);
diff --git a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.h b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.h index b9981183..767c6af3 100644 --- a/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.h +++ b/chrome/browser/ui/views/autofill/payments/save_card_offer_bubble_views.h
@@ -54,10 +54,6 @@ std::unique_ptr<views::View> CreateRequestExpirationDateView(); std::unique_ptr<views::View> CreateUploadExplanationView(); - // Method to check if the save card ui experiment is enabled where one of the - // 3 experimental save card bubble UI treatments are shown. - bool IsSaveCardUiExperimentEnabled(); - void LinkClicked(const GURL& url); raw_ptr<views::Textfield> cardholder_name_textfield_ = nullptr;
diff --git a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc index b446d4d3..2dbeac1 100644 --- a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc +++ b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view.cc
@@ -201,6 +201,10 @@ DCHECK(iban_value_); iban_value_->SetID(DialogViewId::IBAN_VALUE_LABEL); + + if (nickname_textfield_) { + nickname_textfield_->SetID(DialogViewId::NICKNAME_TEXTFIELD); + } } void SaveIbanBubbleView::OnDialogAccepted() {
diff --git a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view_uitest.cc b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view_uitest.cc index 78a91dd..2d1f2aa 100644 --- a/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view_uitest.cc +++ b/chrome/browser/ui/views/autofill/payments/save_iban_bubble_view_uitest.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/test/metrics/histogram_tester.h" #include "base/test/scoped_feature_list.h" #include "build/build_config.h" #include "chrome/browser/autofill/autofill_uitest_util.h" @@ -19,6 +20,7 @@ #include "components/autofill/content/browser/test_autofill_manager_injector.h" #include "components/autofill/core/browser/browser_autofill_manager.h" #include "components/autofill/core/browser/form_data_importer.h" +#include "components/autofill/core/browser/metrics/payments/iban_metrics.h" #include "components/autofill/core/browser/payments/iban_save_manager.h" #include "components/autofill/core/browser/personal_data_manager.h" #include "components/autofill/core/browser/strike_databases/payments/iban_save_strike_database.h" @@ -338,6 +340,11 @@ EXPECT_FALSE(GetSaveIbanBubbleView()); } + views::Textfield* nickname_input() { + return static_cast<views::Textfield*>( + FindViewInBubbleById(DialogViewId::NICKNAME_TEXTFIELD)); + } + void WaitForObservedEvent() { event_waiter_->Wait(); } raw_ptr<IBANSaveManager, DanglingUntriaged> iban_save_manager_ = nullptr; @@ -352,6 +359,7 @@ // successfully causes the bubble to go away, and causes a strike to be added. IN_PROC_BROWSER_TEST_F(SaveIbanBubbleViewFullFormBrowserTest, Local_ClickingNoThanksClosesBubble) { + base::HistogramTester histogram_tester; FillForm(kIbanValue); SubmitFormAndWaitForIbanLocalSaveBubble(); @@ -364,6 +372,12 @@ EXPECT_EQ( 1, iban_save_manager_->GetIBANSaveStrikeDatabaseForTesting()->GetStrikes( kIbanValue)); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptOffer.Local.FirstShow", + autofill_metrics::SaveIbanPromptOffer::kShown, 1); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kCancelled, 1); } // Tests overall StrikeDatabase interaction with the local save bubble. Runs an @@ -372,6 +386,7 @@ // strikes are added if the IBAN already has max strikes. IN_PROC_BROWSER_TEST_F(SaveIbanBubbleViewFullFormBrowserTest, StrikeDatabase_Local_FullFlowTest) { + base::HistogramTester histogram_tester; // Show and ignore the bubble enough times in order to accrue maximum strikes. for (int i = 0; i < iban_save_manager_->GetIBANSaveStrikeDatabaseForTesting() ->GetMaxStrikesLimit(); @@ -408,15 +423,25 @@ WaitForObservedEvent(); EXPECT_TRUE(FindViewInBubbleById(DialogViewId::MAIN_CONTENT_VIEW_LOCAL) ->GetVisible()); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptOffer.Local.Reshows", + autofill_metrics::SaveIbanPromptOffer::kShown, 1); ClickOnCancelButton(); WaitForObservedEvent(); + histogram_tester.ExpectBucketCount( + "Autofill.SaveIbanPromptOffer.Local.FirstShow", + autofill_metrics::SaveIbanPromptOffer::kNotShownMaxStrikesReached, 1); + histogram_tester.ExpectBucketCount( + "Autofill.SaveIbanPromptOffer.Local.FirstShow", + autofill_metrics::SaveIbanPromptOffer::kShown, 3); } // Tests the local save bubble. Ensures that clicking the 'Save' button // successfully causes the bubble to go away. IN_PROC_BROWSER_TEST_F(SaveIbanBubbleViewFullFormBrowserTest, Local_ClickingSaveClosesBubble) { + base::HistogramTester histogram_tester; FillForm(); SubmitFormAndWaitForIbanLocalSaveBubble(); @@ -425,18 +450,57 @@ WaitForObservedEvent(); EXPECT_FALSE(GetSaveIbanBubbleView()); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptOffer.Local.FirstShow", + autofill_metrics::SaveIbanPromptOffer::kShown, 1); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kAccepted, 1); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.SavedWithNickname", false, 1); +} + +// Tests the local save bubble. Ensures that clicking the 'Save' button +// successfully causes the bubble to go away. +IN_PROC_BROWSER_TEST_F(SaveIbanBubbleViewFullFormBrowserTest, + Local_ClickingSaveClosesBubble_WithNickname) { + base::HistogramTester histogram_tester; + FillForm(); + SubmitFormAndWaitForIbanLocalSaveBubble(); + nickname_input()->SetText(u"My doctor's IBAN"); + + ResetEventWaiterForSequence({DialogEvent::ACCEPT_SAVE_IBAN_COMPLETE}); + ClickOnSaveButton(); + WaitForObservedEvent(); + + EXPECT_FALSE(GetSaveIbanBubbleView()); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptOffer.Local.FirstShow", + autofill_metrics::SaveIbanPromptOffer::kShown, 1); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kAccepted, 1); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.SavedWithNickname", true, 1); } // Tests the local save bubble. Ensures that clicking the [X] button will still // see the omnibox icon. IN_PROC_BROWSER_TEST_F(SaveIbanBubbleViewFullFormBrowserTest, Local_ClickingClosesBubbleStillShowOmnibox) { + base::HistogramTester histogram_tester; FillForm(); SubmitFormAndWaitForIbanLocalSaveBubble(); ClickOnCloseButton(); EXPECT_TRUE(GetSaveIbanIconView()->GetVisible()); EXPECT_FALSE(GetSaveIbanBubbleView()); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptOffer.Local.FirstShow", + autofill_metrics::SaveIbanPromptOffer::kShown, 1); + histogram_tester.ExpectUniqueSample( + "Autofill.SaveIbanPromptResult.Local.FirstShow", + autofill_metrics::SaveIbanBubbleResult::kClosed, 1); } // Tests the local save bubble. Ensures that clicking the eye icon button
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.cc b/chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.cc new file mode 100644 index 0000000..2e26c3c --- /dev/null +++ b/chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.cc
@@ -0,0 +1,135 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.h" + +#include "chrome/app/vector_icons/vector_icons.h" +#include "chrome/browser/ui/views/download/download_started_animation_views.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/base/metadata/metadata_impl_macros.h" +#include "ui/base/models/image_model.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/image/image_skia.h" +#include "ui/gfx/image/image_skia_operations.h" +#include "ui/gfx/paint_vector_icon.h" + +namespace { + +// The animation is piecewise linear, composed of 2 phases, phase one is 300 ms +// and phase two is 200 ms. +constexpr base::TimeDelta kAnimationDuration = base::Milliseconds(500); +constexpr double kAnimationPhaseSwitchProgress = 0.6; +constexpr int kIconSize = 26; +constexpr int kIconBackgroundRadius = 32; + +ui::ImageModel GetDownloadIconImageModel(SkColor image_foreground_color, + SkColor image_background_color) { + gfx::ImageSkia icon = gfx::CreateVectorIcon(gfx::IconDescription( + kDownloadToolbarButtonIcon, kIconSize, image_foreground_color)); + gfx::ImageSkia image = + gfx::ImageSkiaOperations::CreateImageWithCircleBackground( + kIconBackgroundRadius, image_background_color, icon); + return ui::ImageModel::FromImageSkia(image); +} + +// Rescales the current progress value of the animation such that the progress +// goes from 0.0 to 1.0 within phase one. +double GetPhaseOneProgress(double current_value) { + DCHECK_LE(current_value, kAnimationPhaseSwitchProgress); + return current_value / kAnimationPhaseSwitchProgress; +} + +// Rescales the current progress value of the animation such that the progress +// goes from 0.0 to 1.0 within phase two. +double GetPhaseTwoProgress(double current_value) { + DCHECK_GE(current_value, kAnimationPhaseSwitchProgress); + return (current_value - kAnimationPhaseSwitchProgress) / + (1.0 - kAnimationPhaseSwitchProgress); +} + +// Breaks down the y-axis movement for each phase for simplicity. +int GetYForPhaseOne(double phase_one_progress, + const gfx::Rect& web_contents_bounds, + const gfx::Rect& toolbar_icon_bounds, + const gfx::Size& image_size) { + // Start centered at 50% of viewport height. + const int start = + web_contents_bounds.CenterPoint().y() - image_size.height() / 2; + // End phase one at 40 px below the center of the toolbar icon. + const int end = toolbar_icon_bounds.bottom_center().y() + 40; + return static_cast<int>(start + (end - start) * phase_one_progress); +} + +int GetYForPhaseTwo(double phase_two_progress, + const gfx::Rect& web_contents_bounds, + const gfx::Rect& toolbar_icon_bounds, + const gfx::Size& image_size) { + // Start where phase one ended. + const int start = toolbar_icon_bounds.bottom_center().y() + 40; + // End centered over the toolbar icon. + const int end = + toolbar_icon_bounds.CenterPoint().y() - image_size.height() / 2; + return static_cast<int>(start + (end - start) * phase_two_progress); +} + +// Breaks down the opacity changes for each phase for simplicity. +float GetOpacityForPhaseOne(double phase_one_progress) { + // Go from 0 to 1 opacity. + return static_cast<float>(phase_one_progress); +} + +float GetOpacityForPhaseTwo(double phase_two_progress) { + // Go from 1 to 0 opacity. + return static_cast<float>(1 - phase_two_progress); +} + +} // namespace + +DownloadBubbleStartedAnimationViews::DownloadBubbleStartedAnimationViews( + content::WebContents* web_contents, + const gfx::Rect& toolbar_icon_bounds, + SkColor image_foreground_color, + SkColor image_background_color) + : DownloadStartedAnimationViews( + web_contents, + kAnimationDuration, + GetDownloadIconImageModel(image_foreground_color, + image_background_color)), + toolbar_icon_bounds_(toolbar_icon_bounds) {} + +DownloadBubbleStartedAnimationViews::~DownloadBubbleStartedAnimationViews() = + default; + +int DownloadBubbleStartedAnimationViews::GetX() const { + // Align the centers of the animation and the toolbar icon. + return toolbar_icon_bounds_.CenterPoint().x() - + GetPreferredSize().width() / 2; +} + +int DownloadBubbleStartedAnimationViews::GetY() const { + if (GetCurrentValue() <= kAnimationPhaseSwitchProgress) { + return GetYForPhaseOne(GetPhaseOneProgress(GetCurrentValue()), + web_contents_bounds(), toolbar_icon_bounds_, + GetPreferredSize()); + } + return GetYForPhaseTwo(GetPhaseTwoProgress(GetCurrentValue()), + web_contents_bounds(), toolbar_icon_bounds_, + GetPreferredSize()); +} + +float DownloadBubbleStartedAnimationViews::GetOpacity() const { + if (GetCurrentValue() <= kAnimationPhaseSwitchProgress) { + return GetOpacityForPhaseOne(GetPhaseOneProgress(GetCurrentValue())); + } + return GetOpacityForPhaseTwo(GetPhaseTwoProgress(GetCurrentValue())); +} + +bool DownloadBubbleStartedAnimationViews::WebContentsTooSmall( + const gfx::Size& image_size) const { + return web_contents_bounds().height() < image_size.height() + 40; +} + +BEGIN_METADATA(DownloadBubbleStartedAnimationViews, + DownloadStartedAnimationViews) +END_METADATA
diff --git a/chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.h b/chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.h new file mode 100644 index 0000000..0eff523 --- /dev/null +++ b/chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.h
@@ -0,0 +1,52 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_STARTED_ANIMATION_VIEWS_H_ +#define CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_STARTED_ANIMATION_VIEWS_H_ + +#include "chrome/browser/ui/views/download/download_started_animation_views.h" +#include "ui/base/metadata/metadata_header_macros.h" +#include "ui/gfx/geometry/rect.h" + +namespace content { +class WebContents; +} // namespace content + +namespace gfx { +class Rect; +class Size; +} // namespace gfx + +// An animation that starts halfway down the screen and moves upwards towards +// the download bubble toolbar icon. The animation is piecewise linear, composed +// of 2 phases. During phase one, the icon moves upwards and fades in. During +// phase two, the icon continues moving upwards and fades out. +// TODO(crbug.com/1414062): Investigate writing this using more modern +// frameworks like layers and views animation builder. +class DownloadBubbleStartedAnimationViews + : public DownloadStartedAnimationViews { + public: + METADATA_HEADER(DownloadBubbleStartedAnimationViews); + DownloadBubbleStartedAnimationViews(content::WebContents* web_contents, + const gfx::Rect& toolbar_icon_bounds, + SkColor image_foreground_color, + SkColor image_background_color); + DownloadBubbleStartedAnimationViews( + const DownloadBubbleStartedAnimationViews&) = delete; + DownloadBubbleStartedAnimationViews& operator=( + const DownloadBubbleStartedAnimationViews&) = delete; + ~DownloadBubbleStartedAnimationViews() override; + + private: + // DownloadStartedAnimationViews + int GetX() const override; + int GetY() const override; + float GetOpacity() const override; + bool WebContentsTooSmall(const gfx::Size& image_size) const override; + + // Bounds of the download bubble icon in the screen coordinate system. + gfx::Rect toolbar_icon_bounds_; +}; + +#endif // CHROME_BROWSER_UI_VIEWS_DOWNLOAD_BUBBLE_DOWNLOAD_BUBBLE_STARTED_ANIMATION_VIEWS_H_
diff --git a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc index f13857c..61f07833 100644 --- a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc +++ b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.cc
@@ -14,6 +14,7 @@ #include "chrome/browser/download/bubble/download_bubble_controller.h" #include "chrome/browser/download/bubble/download_display_controller.h" #include "chrome/browser/download/download_ui_model.h" +#include "chrome/browser/platform_util.h" #include "chrome/browser/themes/theme_properties.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/color/chrome_color_id.h" @@ -23,6 +24,7 @@ #include "chrome/browser/ui/views/download/bubble/download_bubble_row_list_view.h" #include "chrome/browser/ui/views/download/bubble/download_bubble_row_view.h" #include "chrome/browser/ui/views/download/bubble/download_bubble_security_view.h" +#include "chrome/browser/ui/views/download/bubble/download_bubble_started_animation_views.h" #include "chrome/browser/ui/views/download/bubble/download_dialog_view.h" #include "chrome/browser/ui/views/frame/browser_view.h" #include "chrome/browser/ui/views/toolbar/toolbar_view.h" @@ -30,6 +32,8 @@ #include "ui/base/l10n/l10n_util.h" #include "ui/base/metadata/metadata_impl_macros.h" #include "ui/base/resource/resource_bundle.h" +#include "ui/color/color_id.h" +#include "ui/color/color_provider.h" #include "ui/compositor/layer.h" #include "ui/gfx/canvas.h" #include "ui/gfx/geometry/point.h" @@ -267,11 +271,17 @@ // This function shows the partial view. If the main view is already showing, // we do not show the partial view. If the partial view is already showing, // there is nothing to do here, the controller should update the partial view. -void DownloadToolbarButtonView::ShowDetails() { +void DownloadToolbarButtonView::ShowDetails(bool show_animation) { if (!bubble_delegate_) { is_primary_partial_view_ = true; CreateBubbleDialogDelegate(GetPrimaryView()); } + if (show_animation && gfx::Animation::ShouldRenderRichAnimation()) { + has_pending_download_started_animation_ = true; + if (!needs_layout()) { + ShowPendingDownloadStartedAnimation(); + } + } } void DownloadToolbarButtonView::HideDetails() { @@ -334,6 +344,10 @@ } badge_image_view_->SetBoundsRect( gfx::Rect(badge_offset_x, badge_offset_y, badge_height, badge_height)); + + // If there is a pending animation, show it now after we have laid out the + // view properly. + ShowPendingDownloadStartedAnimation(); } std::unique_ptr<views::View> DownloadToolbarButtonView::GetPrimaryView() { @@ -460,6 +474,25 @@ return std::move(scroll_view); } +void DownloadToolbarButtonView::ShowPendingDownloadStartedAnimation() { + if (!has_pending_download_started_animation_) { + return; + } + content::WebContents* const web_contents = + browser_->tab_strip_model()->GetActiveWebContents(); + if (!web_contents || + !platform_util::IsVisible(web_contents->GetNativeView())) { + return; + } + const ui::ColorProvider* color_provider = GetColorProvider(); + // Animation cleans itself up after it's done. + new DownloadBubbleStartedAnimationViews( + web_contents, image()->GetBoundsInScreen(), + color_provider->GetColor(kColorDownloadToolbarButtonAnimationForeground), + color_provider->GetColor(kColorDownloadToolbarButtonAnimationBackground)); + has_pending_download_started_animation_ = false; +} + SkColor DownloadToolbarButtonView::GetIconColor() const { return icon_color_.value_or( controller_->GetIconInfo().is_active
diff --git a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h index 16cc406..9ea13b94 100644 --- a/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h +++ b/chrome/browser/ui/views/download/bubble/download_toolbar_button_view.h
@@ -53,7 +53,7 @@ void Enable() override; void Disable() override; void UpdateDownloadIcon() override; - void ShowDetails() override; + void ShowDetails(bool show_animation) override; void HideDetails() override; bool IsShowingDetails() override; bool IsFullscreenWithParentViewHidden() override; @@ -101,6 +101,10 @@ std::unique_ptr<View> CreateRowListView( std::vector<DownloadUIModel::DownloadUIModelPtr> model_list); + // If |has_pending_download_started_animation_| is true, shows an animation of + // a download icon moving upwards towards the toolbar icon. + void ShowPendingDownloadStartedAnimation(); + SkColor GetProgressColor(bool is_disabled, bool is_active) const; raw_ptr<Browser> browser_; @@ -113,6 +117,12 @@ raw_ptr<View> primary_view_ = nullptr; raw_ptr<DownloadBubbleSecurityView> security_view_ = nullptr; + // Marks whether there is a pending download started animation. This is needed + // because the animation should only be triggered after the view has been + // laid out properly, so this provides a way to remember to show the animation + // if needed, when calling Layout(). + bool has_pending_download_started_animation_ = false; + // RenderTexts used for the number in the badge. Stores the text for "n" at // index n - 1, and stores the text for the placeholder ("9+") at index 0. // This is done to avoid re-creating the same RenderText on each paint. Text
diff --git a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc index 325cd86..4535b3b 100644 --- a/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc +++ b/chrome/browser/ui/views/payments/payment_handler_web_flow_view_controller.cc
@@ -357,9 +357,7 @@ if (has_icon) { views::ImageView* app_icon_view = container->AddChildView(CreateAppIconView( /*icon_resource_id=*/0, icon_bitmap, - // TODO(crbug.com/1414090): Determine correct text (used for both - // tooltip and screen reader). - /*tooltip_text=*/GetPaymentHandlerDialogTitle(web_contents()))); + /*tooltip_text=*/l10n_util::GetStringUTF16(IDS_PAYMENT_HANDLER_ICON))); app_icon_view->SetID( static_cast<int>(DialogViewID::PAYMENT_APP_HEADER_ICON)); float adjusted_width =
diff --git a/chrome/browser/ui/webui/ash/login/oobe_ui.cc b/chrome/browser/ui/webui/ash/login/oobe_ui.cc index 0a7abe8..ef42b7d 100644 --- a/chrome/browser/ui/webui/ash/login/oobe_ui.cc +++ b/chrome/browser/ui/webui/ash/login/oobe_ui.cc
@@ -233,18 +233,18 @@ base::SysInfo::CrashIfChromeOSNonTestImage(); } - source->AddResourcePath(kDebuggerMJSPath, enabled ? - IDR_OOBE_DEBUGGER_JS : - IDR_OOBE_DEBUGGER_STUB_JS); + source->AddResourcePath(kDebuggerMJSPath, + enabled ? IDR_OOBE_CONDITIONAL_DEBUG_DEBUG_JS + : IDR_OOBE_CONDITIONAL_DEBUG_NO_DEBUG_JS); } void AddTestAPIResources(content::WebUIDataSource* source) { base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); const bool enabled = command_line->HasSwitch(switches::kEnableOobeTestAPI); - source->AddResourcePath(kTestAPIJsMPath, enabled ? - IDR_OOBE_TEST_API_JS : - IDR_OOBE_TEST_API_STUB_JS); + source->AddResourcePath( + kTestAPIJsMPath, enabled ? IDR_OOBE_CONDITIONAL_TEST_API_TEST_API_JS + : IDR_OOBE_CONDITIONAL_TEST_API_NO_TEST_API_JS); } // Creates a WebUIDataSource for chrome://oobe @@ -604,10 +604,11 @@ if (policy::EnrollmentRequisitionManager::IsRemoraRequisition()) { source->AddResourcePath( kOobeCustomVarsCssJs, - IDR_OOBE_COMPONENTS_OOBE_CUSTOM_VARS_REMORA_CSS_JS); + IDR_OOBE_CONDITIONAL_COMPONENTS_OOBE_VARS_OOBE_CUSTOM_VARS_REMORA_CSS_JS); } else { - source->AddResourcePath(kOobeCustomVarsCssJs, - IDR_OOBE_COMPONENTS_OOBE_CUSTOM_VARS_CSS_JS); + source->AddResourcePath( + kOobeCustomVarsCssJs, + IDR_OOBE_CONDITIONAL_COMPONENTS_OOBE_VARS_OOBE_CUSTOM_VARS_CSS_JS); } source->OverrideContentSecurityPolicy(
diff --git a/chrome/browser/ui/webui/discards/graph_dump_impl.cc b/chrome/browser/ui/webui/discards/graph_dump_impl.cc index 405502d..027c0bb1 100644 --- a/chrome/browser/ui/webui/discards/graph_dump_impl.cc +++ b/chrome/browser/ui/webui/discards/graph_dump_impl.cc
@@ -34,7 +34,7 @@ namespace { // Best effort convert |value| to a string. -std::string ToJSON(const base::Value& value) { +std::string ToJSON(const base::Value::Dict& value) { std::string result; JSONStringValueSerializer serializer(&result); if (serializer.Serialize(value))
diff --git a/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc b/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc index ed15a288..cecf97e 100644 --- a/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc +++ b/chrome/browser/ui/webui/discards/graph_dump_impl_unittest.cc
@@ -147,25 +147,35 @@ class TestNodeDataDescriber : public performance_manager::NodeDataDescriber { public: // NodeDataDescriber implementations: - base::Value DescribeFrameNodeData( + base::Value::Dict DescribeFrameNodeData( const performance_manager::FrameNode* node) const override { - return base::Value("frame"); + base::Value::Dict dict; + dict.Set("type", "frame"); + return dict; } - base::Value DescribePageNodeData( + base::Value::Dict DescribePageNodeData( const performance_manager::PageNode* node) const override { - return base::Value("page"); + base::Value::Dict dict; + dict.Set("type", "page"); + return dict; } - base::Value DescribeProcessNodeData( + base::Value::Dict DescribeProcessNodeData( const performance_manager::ProcessNode* node) const override { - return base::Value("process"); + base::Value::Dict dict; + dict.Set("type", "process"); + return dict; } - base::Value DescribeSystemNodeData( + base::Value::Dict DescribeSystemNodeData( const performance_manager::SystemNode* node) const override { - return base::Value("system"); + base::Value::Dict dict; + dict.Set("type", "system"); + return dict; } - base::Value DescribeWorkerNodeData( + base::Value::Dict DescribeWorkerNodeData( const performance_manager::WorkerNode* node) const override { - return base::Value("worker"); + base::Value::Dict dict; + dict.Set("type", "worker"); + return dict; } }; @@ -222,18 +232,18 @@ for (const auto& kv : change_stream.process_map()) { const auto* process_info = kv.second.get(); EXPECT_NE(0u, process_info->id); - EXPECT_EQ(base::JSONReader::Read("{\"test\":\"process\"}"), + EXPECT_EQ(base::JSONReader::Read("{\"test\":{\"type\":\"process\"}}"), base::JSONReader::Read(process_info->description_json)); } EXPECT_EQ(3u, change_stream.frame_map().size()); for (const auto& kv : change_stream.frame_map()) { - EXPECT_EQ(base::JSONReader::Read("{\"test\":\"frame\"}"), + EXPECT_EQ(base::JSONReader::Read("{\"test\":{\"type\":\"frame\"}}"), base::JSONReader::Read(kv.second->description_json)); } EXPECT_EQ(1u, change_stream.worker_map().size()); for (const auto& kv : change_stream.worker_map()) { - EXPECT_EQ(base::JSONReader::Read("{\"test\":\"worker\"}"), + EXPECT_EQ(base::JSONReader::Read("{\"test\":{\"type\":\"worker\"}}"), base::JSONReader::Read(kv.second->description_json)); } @@ -263,7 +273,7 @@ const auto& page = kv.second; EXPECT_NE(0u, page->id); EXPECT_EQ(kExampleUrl, page->main_frame_url); - EXPECT_EQ(base::JSONReader::Read("{\"test\":\"page\"}"), + EXPECT_EQ(base::JSONReader::Read("{\"test\":{\"type\":\"page\"}}"), base::JSONReader::Read(kv.second->description_json)); } @@ -315,7 +325,9 @@ absl::optional<base::Value> v = base::JSONReader::Read(kv.second); EXPECT_TRUE(v->is_dict()); - std::string* str = v->GetDict().FindString("test"); + base::Value::Dict* dict = v->GetDict().FindDict("test"); + EXPECT_TRUE(dict); + std::string* str = dict->FindString("type"); EXPECT_TRUE(str); if (str) { EXPECT_TRUE(*str == "frame" || *str == "page" ||
diff --git a/chrome/browser/ui/webui/settings/ash/privacy_section.cc b/chrome/browser/ui/webui/settings/ash/privacy_section.cc index 1c9b709..2b1b34a 100644 --- a/chrome/browser/ui/webui/settings/ash/privacy_section.cc +++ b/chrome/browser/ui/webui/settings/ash/privacy_section.cc
@@ -69,7 +69,13 @@ if (!IsGuestModeActive()) { all_tags.insert( all_tags.end(), - {{IDS_OS_SETTINGS_TAG_GUEST_BROWSING, + {{IDS_OS_SETTINGS_TAG_MANAGE_OTHER_PEOPLE_PAGE, + mojom::kManageOtherPeopleSubpagePathV2, + mojom::SearchResultIcon::kAvatar, + mojom::SearchResultDefaultRank::kMedium, + mojom::SearchResultType::kSubpage, + {.subpage = mojom::Subpage::kManageOtherPeopleV2}}, + {IDS_OS_SETTINGS_TAG_GUEST_BROWSING, mojom::kManageOtherPeopleSubpagePathV2, mojom::SearchResultIcon::kAvatar, mojom::SearchResultDefaultRank::kMedium,
diff --git a/chrome/browser/ui/window_sizer/window_sizer_chromeos.cc b/chrome/browser/ui/window_sizer/window_sizer_chromeos.cc index f49b6dd..05efbdc 100644 --- a/chrome/browser/ui/window_sizer/window_sizer_chromeos.cc +++ b/chrome/browser/ui/window_sizer/window_sizer_chromeos.cc
@@ -190,6 +190,13 @@ if (state_provider() && state_provider()->GetLastActiveWindowState( bounds_in_screen, show_state)) { + // TODO(crbug.com/1413902): This is broken when the last active window is + // minimized as bounds_in_screen doesn't get updated. If + // GetLastActiveWindowState can return false for minimized windows, this + // code can be reverted. + if (bounds_in_screen->IsEmpty()) { + return false; + } bounds_in_screen->Offset(kWindowTilePixels, kWindowTilePixels); // Adjusting bounds_in_screen to fit on the display as returned by // GetDisplayForNewWindow here matches behavior for tabbed browsers above.
diff --git a/chrome/browser/updater/browser_updater_client.cc b/chrome/browser/updater/browser_updater_client.cc index ad69cad8..15502bb8 100644 --- a/chrome/browser/updater/browser_updater_client.cc +++ b/chrome/browser/updater/browser_updater_client.cc
@@ -80,11 +80,7 @@ update_service_->Update( GetAppId(), {}, updater::UpdateService::Priority::kForeground, updater::UpdateService::PolicySameVersionUpdate::kNotAllowed, -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) /*do_update_check_only=*/false, -#endif // BUILDFLAG(IS_WIN) base::BindPostTaskToCurrentDefault(version_updater_callback), base::BindPostTaskToCurrentDefault( base::BindOnce(&BrowserUpdaterClient::UpdateCompleted, this,
diff --git a/chrome/build/linux.pgo.txt b/chrome/build/linux.pgo.txt index af8b28b..cefc09c 100644 --- a/chrome/build/linux.pgo.txt +++ b/chrome/build/linux.pgo.txt
@@ -1 +1 @@ -chrome-linux-main-1675857453-00018d09b9488676f4e62fc4f098a70b914f341a.profdata +chrome-linux-main-1675879071-de5449db0835d4307884608d78cf4d6584967438.profdata
diff --git a/chrome/build/mac-arm.pgo.txt b/chrome/build/mac-arm.pgo.txt index babe15ee..e18b902a 100644 --- a/chrome/build/mac-arm.pgo.txt +++ b/chrome/build/mac-arm.pgo.txt
@@ -1 +1 @@ -chrome-mac-arm-main-1675857453-c87864e17e0f2a3bd15e535ebfe767753033cf18.profdata +chrome-mac-arm-main-1675879071-6cd22de8f284233159de30900fd9fc75243c54f7.profdata
diff --git a/chrome/build/mac.pgo.txt b/chrome/build/mac.pgo.txt index c31e4c96..388bd0b5 100644 --- a/chrome/build/mac.pgo.txt +++ b/chrome/build/mac.pgo.txt
@@ -1 +1 @@ -chrome-mac-main-1675857453-c29bcc0492cb2a435201d8b25ab39d03f6d9b35c.profdata +chrome-mac-main-1675879071-c69d906359361007cc25c3ef6e5ea3cd157e520b.profdata
diff --git a/chrome/build/win32.pgo.txt b/chrome/build/win32.pgo.txt index a2a8407..67b99b7 100644 --- a/chrome/build/win32.pgo.txt +++ b/chrome/build/win32.pgo.txt
@@ -1 +1 @@ -chrome-win32-main-1675868378-1e5d86b1ee35f4a2c318fa716bb9027e93de9907.profdata +chrome-win32-main-1675879071-8fca267e557ec8e1bab890f1c20615c0722cf40e.profdata
diff --git a/chrome/build/win64.pgo.txt b/chrome/build/win64.pgo.txt index 518173e..05e3e35b 100644 --- a/chrome/build/win64.pgo.txt +++ b/chrome/build/win64.pgo.txt
@@ -1 +1 @@ -chrome-win64-main-1675857453-9990fd0751f03d7fab84708b7f6d36993476a38e.profdata +chrome-win64-main-1675879071-77b76da3619883a65bed54afa16213373c0343a7.profdata
diff --git a/chrome/common/logging_chrome.cc b/chrome/common/logging_chrome.cc index 30bb27e5..a5b0e4db0 100644 --- a/chrome/common/logging_chrome.cc +++ b/chrome/common/logging_chrome.cc
@@ -173,15 +173,14 @@ return LOG_TO_SYSTEM_DEBUG_LOG | LOG_TO_STDERR; } else if (logging_destination != "") { PLOG(ERROR) << "Invalid logging destination: " << logging_destination; - } #if BUILDFLAG(IS_WIN) - else if (base::IsCurrentProcessInAppContainer() && - !command_line.HasSwitch(switches::kLogFile)) { + } else if (base::IsCurrentProcessInAppContainer() && + !command_line.HasSwitch(switches::kLogFile)) { // Sandboxed appcontainer processes are unable to resolve the default log // file path without asserting. return kDefaultLoggingMode & ~LOG_TO_FILE; - } #endif + } } return kDefaultLoggingMode; } @@ -494,15 +493,38 @@ } base::FilePath GetLogFileName(const base::CommandLine& command_line) { + // Try the command line. auto filename = command_line.GetSwitchValueNative(switches::kLogFile); - if (!filename.empty()) - return base::FilePath(filename); + // Try the environment. + if (filename.empty()) { + std::string env_filename; + base::Environment::Create()->GetVar(env_vars::kLogFileName, &env_filename); +#if BUILDFLAG(IS_WIN) + filename = base::UTF8ToWide(env_filename); +#else + filename = env_filename; +#endif // BUILDFLAG(IS_WIN) + } - std::string env_filename; - base::Environment::Create()->GetVar(env_vars::kLogFileName, &env_filename); - if (!env_filename.empty()) - return base::FilePath::FromUTF8Unsafe(env_filename); + if (!filename.empty()) { + base::FilePath candidate_path(filename); +#if BUILDFLAG(IS_WIN) + // Windows requires an absolute path for the --log-file switch. Windows + // cannot log to the current directory as it cds() to the exe's directory + // earlier than this function runs. + candidate_path = candidate_path.NormalizePathSeparators(); + if (candidate_path.IsAbsolute()) { + return candidate_path; + } else { + PLOG(ERROR) << "Invalid logging destination: " << filename; + } +#else + return candidate_path; +#endif // BUILDFLAG(IS_WIN) + } + // If command line and environment do not provide a log file we can use, + // fallback to the default. const base::FilePath log_filename(FILE_PATH_LITERAL("chrome_debug.log")); base::FilePath log_path; @@ -510,8 +532,13 @@ log_path = log_path.Append(log_filename); return log_path; } else { - // error with path service, just use some default file somewhere +#if BUILDFLAG(IS_WIN) + // On Windows we cannot use a non-absolute path so we cannot provide a file. + return base::FilePath(); +#else + // Error with path service, just use the default in our current directory. return log_filename; +#endif // BUILDFLAG(IS_WIN) } }
diff --git a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeApplicationTestUtils.java b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeApplicationTestUtils.java index 69e71d25..d73dae01 100644 --- a/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeApplicationTestUtils.java +++ b/chrome/test/android/javatests/src/org/chromium/chrome/test/util/ChromeApplicationTestUtils.java
@@ -39,7 +39,7 @@ // Increase the default timeout, as it can take a long time for Android to // fully stop/start Chrome. private static final long CHROME_STOP_START_TIMEOUT_MS = - Math.max(20000L, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); + Math.max(10000L, CriteriaHelper.DEFAULT_MAX_TIME_TO_POLL); private static PowerManager.WakeLock sWakeLock;
diff --git a/chrome/test/data/extensions/api_test/tabs/basics/duplicate.js b/chrome/test/data/extensions/api_test/tabs/basics/duplicate.js index cd57818..a796c3d 100644 --- a/chrome/test/data/extensions/api_test/tabs/basics/duplicate.js +++ b/chrome/test/data/extensions/api_test/tabs/basics/duplicate.js
@@ -34,8 +34,7 @@ })); }, - // TODO(crbug.com/149924): This test was broken by - // https://chromium-review.googlesource.com/c/chromium/src/+/3029302 + // TODO(crbug.com/149924): This test was broken by crrev.com/c/3029302. /* function duplicateTabFromNewPopupWindow() { chrome.windows.create({
diff --git a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts index e155569..8aee938c 100644 --- a/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts +++ b/chrome/test/data/webui/chromeos/personalization_app/ambient_subpage_element_test.ts
@@ -80,25 +80,6 @@ '#toggleRowPlaceholder'); assertTrue(!!toggleRowPlaceholder); - personalizationStore.data.ambient.ambientModeEnabled = false; - personalizationStore.notifyObservers(); - await waitAfterNextRender(ambientSubpageElement); - - // Ambient mode is loaded, should not show toggle row placeholder. - assertTrue(!!toggleRowPlaceholder); - assertEquals(getComputedStyle(toggleRowPlaceholder).display, 'none'); - - const toggleRow = - ambientSubpageElement.shadowRoot!.querySelector('toggle-row'); - assertTrue(!!toggleRow, 'toggle-row element exists'); - const toggleButton = toggleRow!.shadowRoot!.querySelector('cr-toggle'); - assertTrue(!!toggleButton, 'cr-toggle element exists'); - assertFalse(toggleButton!.checked); - - personalizationStore.data.ambient.ambientModeEnabled = true; - personalizationStore.notifyObservers(); - await waitAfterNextRender(ambientSubpageElement); - // Preview element should show placeholders for preview images, preview // album info and preview album collage. const ambientPreview = ambientSubpageElement.shadowRoot!.querySelector( @@ -138,6 +119,7 @@ '#weatherUnitTextPlaceholder:not([hidden])'); assertEquals(2, weatherUnitItemPlaceholders!.length); + personalizationStore.data.ambient.ambientModeEnabled = false; personalizationStore.data.ambient.albums = ambientProvider.albums; personalizationStore.data.ambient.topicSource = TopicSource.kGooglePhotos; personalizationStore.data.ambient.temperatureUnit = @@ -145,6 +127,18 @@ personalizationStore.notifyObservers(); await waitAfterNextRender(ambientSubpageElement); + // Loading finished, should not show toggle row placeholder. + assertTrue(!!toggleRowPlaceholder); + assertEquals(getComputedStyle(toggleRowPlaceholder).display, 'none'); + + // Toggle row is shown but in off status (the button is unchecked). + const toggleRow = + ambientSubpageElement.shadowRoot!.querySelector('toggle-row'); + assertTrue(!!toggleRow, 'toggle-row element exists'); + const toggleButton = toggleRow!.shadowRoot!.querySelector('cr-toggle'); + assertTrue(!!toggleButton, 'cr-toggle element exists'); + assertFalse(toggleButton!.checked); + // Placeholders will be hidden for animation theme, topic source // and temperature unit elements. assertTrue(!!animationThemePlaceholder);
diff --git a/chrome/updater/app/app_install.cc b/chrome/updater/app/app_install.cc index dc7ba861..d6fd19f9 100644 --- a/chrome/updater/app/app_install.cc +++ b/chrome/updater/app/app_install.cc
@@ -10,13 +10,10 @@ #include "base/check.h" #include "base/check_op.h" #include "base/command_line.h" -#include "base/files/file_path.h" #include "base/functional/bind.h" #include "base/functional/callback.h" -#include "base/i18n/icu_util.h" #include "base/logging.h" #include "base/memory/scoped_refptr.h" -#include "base/notreached.h" #include "base/task/sequenced_task_runner.h" #include "base/task/task_traits.h" #include "base/task/thread_pool.h" @@ -24,7 +21,6 @@ #include "build/build_config.h" #include "chrome/updater/constants.h" #include "chrome/updater/external_constants.h" -#include "chrome/updater/persisted_data.h" #include "chrome/updater/prefs.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/service_proxy_factory.h"
diff --git a/chrome/updater/app/app_install_win.cc b/chrome/updater/app/app_install_win.cc index 98e3ff13..c773a3b 100644 --- a/chrome/updater/app/app_install_win.cc +++ b/chrome/updater/app/app_install_win.cc
@@ -25,7 +25,6 @@ #include "base/memory/raw_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" -#include "base/process/launch.h" #include "base/sequence_checker.h" #include "base/strings/escape.h" #include "base/strings/strcat.h" @@ -39,11 +38,7 @@ #include "base/threading/thread_restrictions.h" #include "base/time/time.h" #include "base/values.h" -#include "base/win/atl.h" #include "base/win/registry.h" -#include "base/win/scoped_bstr.h" -#include "base/win/scoped_variant.h" -#include "base/win/shlwapi.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/service_proxy_factory.h" #include "chrome/updater/update_service.h" @@ -54,9 +49,7 @@ #include "chrome/updater/util/win_util.h" #include "chrome/updater/win/install_progress_observer.h" #include "chrome/updater/win/manifest_util.h" -#include "chrome/updater/win/scoped_impersonation.h" #include "chrome/updater/win/ui/resources/resources.grh" -#include "chrome/updater/win/user_info.h" #include "chrome/updater/win/win_constants.h" #pragma clang diagnostic push @@ -65,7 +58,6 @@ #include "chrome/updater/win/ui/progress_wnd.h" #include "chrome/updater/win/ui/resources/updater_installer_strings.h" #include "chrome/updater/win/ui/splash_screen.h" -#include "chrome/updater/win/ui/ui_util.h" #pragma clang diagnostic pop #include "third_party/abseil-cpp/absl/types/optional.h" @@ -495,10 +487,12 @@ request.app_id = app_id_; absl::optional<tagging::AppArgs> app_args = GetAppArgs(app_id_); absl::optional<tagging::TagArgs> tag_args = GetTagArgs().tag_args; - if (app_args) + if (app_args) { request.ap = app_args->ap; - if (tag_args) + } + if (tag_args) { request.brand_code = tag_args->brand_code; + } base::ThreadPool::PostTaskAndReply( FROM_HERE, @@ -616,10 +610,12 @@ absl::optional<tagging::AppArgs> app_args = GetAppArgsForCommandLine(cmd_line, app_id_); - if (app_args) + if (app_args) { request.ap = app_args->ap; - if (tag_args) + } + if (tag_args) { request.brand_code = tag_args->brand_code; + } VLOG(1) << __func__ << ": " << installer_path << ": " << install_args << ": " << install_data;
diff --git a/chrome/updater/app/app_server.cc b/chrome/updater/app/app_server.cc index ef28150..c81bad5c 100644 --- a/chrome/updater/app/app_server.cc +++ b/chrome/updater/app/app_server.cc
@@ -95,8 +95,9 @@ } if (this_version > active_version || global_prefs->GetSwapping()) { - if (!SwapVersions(global_prefs.get())) + if (!SwapVersions(global_prefs.get())) { return base::BindOnce(&AppServer::Shutdown, this, kErrorFailedToSwap); + } } if (IsInternalService()) { @@ -113,8 +114,9 @@ } void AppServer::Uninitialize() { - if (prefs_) + if (prefs_) { PrefsCommitPendingWrites(prefs_->GetPrefService()); + } if (uninstall_self_) { VLOG(1) << "Uninstalling version " << kUpdaterVersion; UninstallSelf(); @@ -124,8 +126,9 @@ } void AppServer::MaybeUninstall() { - if (!prefs_) + if (!prefs_) { return; + } auto persisted_data = base::MakeRefCounted<PersistedData>( updater_scope(), prefs_->GetPrefService()); @@ -161,8 +164,9 @@ bool AppServer::SwapVersions(GlobalPrefs* global_prefs) { global_prefs->SetSwapping(true); PrefsCommitPendingWrites(global_prefs->GetPrefService()); - if (!SwapInNewVersion()) + if (!SwapInNewVersion()) { return false; + } if (!global_prefs->GetMigratedLegacyUpdaters()) { if (!MigrateLegacyUpdaters(base::BindRepeating( &PersistedData::RegisterApp,
diff --git a/chrome/updater/app/app_server.h b/chrome/updater/app/app_server.h index 2020f85..90303666 100644 --- a/chrome/updater/app/app_server.h +++ b/chrome/updater/app/app_server.h
@@ -5,7 +5,6 @@ #ifndef CHROME_UPDATER_APP_APP_SERVER_H_ #define CHROME_UPDATER_APP_APP_SERVER_H_ -#include "base/functional/bind.h" #include "base/functional/callback_forward.h" #include "base/memory/scoped_refptr.h" #include "chrome/updater/app/app.h"
diff --git a/chrome/updater/app/app_server_unittest.cc b/chrome/updater/app/app_server_unittest.cc index d533d14f0..abc784a 100644 --- a/chrome/updater/app/app_server_unittest.cc +++ b/chrome/updater/app/app_server_unittest.cc
@@ -10,10 +10,8 @@ #include "base/files/file_util.h" #include "base/functional/callback.h" #include "base/memory/scoped_refptr.h" -#include "base/message_loop/message_pump_type.h" #include "base/test/task_environment.h" #include "build/build_config.h" -#include "chrome/updater/constants.h" #include "chrome/updater/prefs.h" #include "chrome/updater/update_service.h" #include "chrome/updater/update_service_internal.h"
diff --git a/chrome/updater/app/app_update.cc b/chrome/updater/app/app_update.cc index ef63910..daa0a5d 100644 --- a/chrome/updater/app/app_update.cc +++ b/chrome/updater/app/app_update.cc
@@ -6,7 +6,6 @@ #include "base/functional/bind.h" #include "base/memory/scoped_refptr.h" -#include "base/task/sequenced_task_runner.h" #include "chrome/updater/app/app.h" #include "chrome/updater/setup.h" @@ -22,11 +21,9 @@ void SetupDone(int result); }; -void AppUpdate::Initialize() { -} +void AppUpdate::Initialize() {} -void AppUpdate::Uninitialize() { -} +void AppUpdate::Uninitialize() {} void AppUpdate::FirstTaskRun() { InstallCandidate(updater_scope(),
diff --git a/chrome/updater/app/server/posix/mojom/updater_service.mojom b/chrome/updater/app/server/posix/mojom/updater_service.mojom index f633b157..7320cd6 100644 --- a/chrome/updater/app/server/posix/mojom/updater_service.mojom +++ b/chrome/updater/app/server/posix/mojom/updater_service.mojom
@@ -247,7 +247,10 @@ Priority priority, // Whether a same-version update is allowed. - PolicySameVersionUpdate policy_same_version_update) => + PolicySameVersionUpdate policy_same_version_update, + + // Only checks for updates if `do_update_check_only` is `true`. + [MinVersion=1] bool do_update_check_only) => (pending_receiver<StateChangeObserver> observer); // Registers and installs an application from the network.
diff --git a/chrome/updater/app/server/posix/rpc_unittests.cc b/chrome/updater/app/server/posix/rpc_unittests.cc index 9c8c098..c795fdc 100644 --- a/chrome/updater/app/server/posix/rpc_unittests.cc +++ b/chrome/updater/app/server/posix/rpc_unittests.cc
@@ -8,16 +8,13 @@ #include <utility> #include <vector> -#include "base/base_paths.h" #include "base/command_line.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/functional/bind.h" #include "base/functional/callback.h" #include "base/functional/callback_forward.h" #include "base/functional/callback_helpers.h" #include "base/memory/scoped_refptr.h" -#include "base/path_service.h" #include "base/ranges/algorithm.h" #include "base/run_loop.h" #include "base/test/bind.h" @@ -27,20 +24,14 @@ #include "base/test/test_timeouts.h" #include "base/time/time.h" #include "base/version.h" -#include "chrome/updater/app/server/posix/mojom/updater_service.mojom.h" #include "chrome/updater/app/server/posix/update_service_internal_stub.h" #include "chrome/updater/app/server/posix/update_service_stub.h" #include "chrome/updater/ipc/ipc_support.h" -#include "chrome/updater/ipc/update_service_internal_proxy_posix.h" -#include "chrome/updater/ipc/update_service_proxy_posix.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/service_proxy_factory.h" #include "chrome/updater/update_service.h" #include "chrome/updater/updater_scope.h" #include "chrome/updater/util/util.h" -#include "mojo/core/embedder/configuration.h" -#include "mojo/core/embedder/embedder.h" -#include "mojo/public/cpp/bindings/remote.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/multiprocess_func_list.h" @@ -197,6 +188,7 @@ const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, + bool do_update_check_only, StateChangeCallback state_update, Callback callback), (override)); @@ -271,6 +263,7 @@ [](const std::string& app_id, const std::string& install_data_index, UpdateService::Priority priority, UpdateService::PolicySameVersionUpdate policy_same_version_update, + bool do_update_check_only, UpdateService::StateChangeCallback state_change_callback, UpdateService::Callback callback) { EXPECT_EQ(app_id, "ex1"); @@ -411,6 +404,7 @@ client_proxy->Update("ex1", "install_data_index", UpdateService::Priority::kBackground, UpdateService::PolicySameVersionUpdate::kAllowed, + /*do_update_check_only=*/false, UpdaterIPCTestCase::ExpectUpdateStatesCallback(), UpdaterIPCTestCase::ExpectResultCallback(run_loop)); run_loop.Run();
diff --git a/chrome/updater/app/server/posix/update_service_internal_stub.cc b/chrome/updater/app/server/posix/update_service_internal_stub.cc index 84de1c8..997fac8 100644 --- a/chrome/updater/app/server/posix/update_service_internal_stub.cc +++ b/chrome/updater/app/server/posix/update_service_internal_stub.cc
@@ -7,16 +7,11 @@ #include <iterator> #include <utility> -#include "base/check.h" #include "base/functional/bind.h" #include "base/functional/callback.h" -#include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" -#include "base/process/process_handle.h" -#include "chrome/updater/app/server/posix/mojom/updater_service_internal.mojom-forward.h" #include "chrome/updater/ipc/ipc_names.h" #include "chrome/updater/ipc/ipc_security.h" -#include "chrome/updater/updater_version.h" #include "components/named_mojo_ipc_server/connection_info.h" #include "components/named_mojo_ipc_server/named_mojo_ipc_server.h"
diff --git a/chrome/updater/app/server/posix/update_service_stub.cc b/chrome/updater/app/server/posix/update_service_stub.cc index 3b2c676..0a4cde8 100644 --- a/chrome/updater/app/server/posix/update_service_stub.cc +++ b/chrome/updater/app/server/posix/update_service_stub.cc
@@ -15,7 +15,6 @@ #include "base/logging.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_refptr.h" -#include "base/process/process_handle.h" #include "base/ranges/algorithm.h" #include "base/sequence_checker.h" #include "base/version.h" @@ -23,7 +22,6 @@ #include "chrome/updater/ipc/ipc_names.h" #include "chrome/updater/ipc/ipc_security.h" #include "chrome/updater/registration_data.h" -#include "chrome/updater/updater_version.h" #include "components/named_mojo_ipc_server/connection_info.h" #include "components/named_mojo_ipc_server/endpoint_options.h" #include "components/named_mojo_ipc_server/named_mojo_ipc_server.h" @@ -130,10 +128,12 @@ const std::string& install_data_index, UpdateService::Priority priority, UpdateService::PolicySameVersionUpdate policy_same_version_update, + bool do_update_check_only, UpdateCallback callback) override { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); impl_->Update(app_id, install_data_index, priority, - policy_same_version_update, std::move(callback)); + policy_same_version_update, do_update_check_only, + std::move(callback)); } // The rest of updater::mojom::UpdateService is rejected. @@ -296,6 +296,7 @@ const std::string& install_data_index, UpdateService::Priority priority, UpdateService::PolicySameVersionUpdate policy_same_version_update, + bool do_update_check_only, UpdateCallback callback) { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); task_start_listener_.Run(); @@ -308,7 +309,7 @@ static_cast<updater::UpdateService::Priority>(priority), static_cast<updater::UpdateService::PolicySameVersionUpdate>( policy_same_version_update), - state_change_callback, + do_update_check_only, state_change_callback, std::move(on_complete_callback).Then(task_end_listener_)); }
diff --git a/chrome/updater/app/server/posix/update_service_stub.h b/chrome/updater/app/server/posix/update_service_stub.h index 82ea7c36..e54c7918 100644 --- a/chrome/updater/app/server/posix/update_service_stub.h +++ b/chrome/updater/app/server/posix/update_service_stub.h
@@ -44,6 +44,7 @@ const std::string& install_data_index, UpdateService::Priority priority, UpdateService::PolicySameVersionUpdate policy_same_version_update, + bool do_update_check_only, UpdateCallback callback) override; void Install(mojom::RegistrationRequestPtr registration, const std::string& client_install_data,
diff --git a/chrome/updater/app/server/win/com_classes.h b/chrome/updater/app/server/win/com_classes.h index b15633f..e5d688b 100644 --- a/chrome/updater/app/server/win/com_classes.h +++ b/chrome/updater/app/server/win/com_classes.h
@@ -13,7 +13,6 @@ #include "chrome/updater/app/server/win/updater_idl.h" #include "chrome/updater/app/server/win/updater_internal_idl.h" #include "chrome/updater/update_service.h" -#include "chrome/updater/updater_scope.h" #include "chrome/updater/util/win_util.h" // Definitions for native COM updater classes.
diff --git a/chrome/updater/app/server/win/com_classes_legacy.cc b/chrome/updater/app/server/win/com_classes_legacy.cc index a9819cd..2cef945 100644 --- a/chrome/updater/app/server/win/com_classes_legacy.cc +++ b/chrome/updater/app/server/win/com_classes_legacy.cc
@@ -14,15 +14,11 @@ #include "base/check.h" #include "base/check_op.h" -#include "base/files/file_path.h" #include "base/functional/bind.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" #include "base/memory/ref_counted.h" -#include "base/path_service.h" -#include "base/process/launch.h" #include "base/process/process.h" -#include "base/strings/strcat.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" @@ -33,14 +29,10 @@ #include "base/task/thread_pool.h" #include "base/time/time.h" #include "base/types/expected.h" -#include "base/win/registry.h" #include "base/win/scoped_bstr.h" #include "base/win/scoped_handle.h" -#include "base/win/scoped_process_information.h" -#include "base/win/win_util.h" #include "chrome/updater/app/server/win/server.h" #include "chrome/updater/constants.h" -#include "chrome/updater/external_constants.h" #include "chrome/updater/persisted_data.h" #include "chrome/updater/policy/manager.h" #include "chrome/updater/policy/service.h" @@ -53,7 +45,6 @@ #include "chrome/updater/win/app_command_runner.h" #include "chrome/updater/win/scoped_handle.h" #include "chrome/updater/win/setup/setup_util.h" -#include "chrome/updater/win/win_constants.h" #include "third_party/abseil-cpp/absl/types/optional.h" namespace { @@ -634,8 +625,9 @@ IFACEMETHODIMP createInstalledApp(BSTR app_id) override { base::AutoLock lock{lock_}; - if (app_web_) + if (app_web_) { return E_UNEXPECTED; + } return Microsoft::WRL::MakeAndInitialize<AppWebImpl>(&app_web_, app_id); } @@ -662,8 +654,9 @@ IFACEMETHODIMP get_appWeb(int index, IDispatch** app_web) override { base::AutoLock lock{lock_}; - if (index != 0 || !app_web_) + if (index != 0 || !app_web_) { return E_UNEXPECTED; + } return app_web_.CopyTo(app_web); } @@ -674,8 +667,9 @@ IFACEMETHODIMP checkForUpdate() override { base::AutoLock lock{lock_}; - if (!app_web_) + if (!app_web_) { return E_UNEXPECTED; + } return app_web_->Update(/*do_update_check_only=*/true); } @@ -862,8 +856,9 @@ substitution9}) { const absl::optional<std::wstring> substitution_string = StringFromVariant(substitution); - if (!substitution_string) + if (!substitution_string) { break; + } VLOG(2) << __func__ << " substitution_string: " << substitution_string.value(); @@ -887,8 +882,9 @@ DCHECK(minutes); PolicyStatus<base::TimeDelta> period = policy_service_->GetLastCheckPeriod(); - if (!period) + if (!period) { return E_FAIL; + } *minutes = period.policy().InMinutes(); return S_OK; @@ -1104,8 +1100,9 @@ GetUpdaterScope(), AppServerSingletonInstance()->prefs()->GetPrefService()) ->GetLastChecked(); - if (last_checked_time.is_null()) + if (last_checked_time.is_null()) { return; + } const FILETIME last_checked_filetime = last_checked_time.ToFileTime(); @@ -1164,12 +1161,14 @@ auto policy_status = PolicyStatusResult<UpdatesSuppressedTimes>::Get(base::BindRepeating( &PolicyService::GetUpdatesSuppressedTimes, policy_service_)); - if (!policy_status.has_value()) + if (!policy_status.has_value()) { return E_FAIL; + } const UpdatesSuppressedTimes updates_suppressed_times = policy_status->effective_policy()->policy; - if (!updates_suppressed_times.valid()) + if (!updates_suppressed_times.valid()) { return E_FAIL; + } base::Time::Exploded now; base::Time::Now().LocalExplode(&now); *are_updates_suppressed =
diff --git a/chrome/updater/app/server/win/com_classes_legacy.h b/chrome/updater/app/server/win/com_classes_legacy.h index c449478..8e9fa168 100644 --- a/chrome/updater/app/server/win/com_classes_legacy.h +++ b/chrome/updater/app/server/win/com_classes_legacy.h
@@ -16,7 +16,6 @@ #include "base/memory/scoped_refptr.h" #include "base/path_service.h" #include "base/process/process.h" -#include "base/synchronization/lock.h" #include "base/types/expected.h" #include "base/win/win_util.h" #include "chrome/updater/app/server/win/updater_legacy_idl.h" @@ -27,7 +26,6 @@ #include "chrome/updater/util/win_util.h" #include "chrome/updater/win/app_command_runner.h" #include "chrome/updater/win/setup/setup_util.h" -#include "third_party/abseil-cpp/absl/types/optional.h" // Definitions for COM updater classes provided for backward compatibility // with Google Update. @@ -53,8 +51,9 @@ // Overrides for IDispatch. IFACEMETHODIMP GetTypeInfoCount(UINT* type_info_count) override { - if (FAILED(hr_load_typelib_)) + if (FAILED(hr_load_typelib_)) { return hr_load_typelib_; + } *type_info_count = 1; return S_OK; @@ -63,8 +62,9 @@ IFACEMETHODIMP GetTypeInfo(UINT type_info_index, LCID locale_id, ITypeInfo** type_info) override { - if (FAILED(hr_load_typelib_)) + if (FAILED(hr_load_typelib_)) { return hr_load_typelib_; + } return type_info_index == 0 ? type_info_.CopyTo(type_info) : E_INVALIDARG; } @@ -74,8 +74,9 @@ UINT count_of_names_to_be_mapped, LCID locale_id, DISPID* dispatch_ids) override { - if (FAILED(hr_load_typelib_)) + if (FAILED(hr_load_typelib_)) { return hr_load_typelib_; + } return type_info_->GetIDsOfNames(names_to_be_mapped, count_of_names_to_be_mapped, dispatch_ids); @@ -89,8 +90,9 @@ VARIANT* result, EXCEPINFO* exception_info, UINT* arg_error_index) override { - if (FAILED(hr_load_typelib_)) + if (FAILED(hr_load_typelib_)) { return hr_load_typelib_; + } HRESULT hr = type_info_->Invoke(Microsoft::WRL::ComPtr<T>(this).Get(), dispatch_id, flags, dispatch_parameters, @@ -104,8 +106,9 @@ // Loads the typelib and typeinfo for interface `T`. HRESULT InitializeTypeInfo() { base::FilePath typelib_path; - if (!base::PathService::Get(base::DIR_EXE, &typelib_path)) + if (!base::PathService::Get(base::DIR_EXE, &typelib_path)) { return E_UNEXPECTED; + } typelib_path = typelib_path.Append(GetExecutableRelativePath()) .Append(GetComTypeLibResourceIndex(__uuidof(T)));
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 cebcd864..2b6b12b 100644 --- a/chrome/updater/app/server/win/com_classes_legacy_unittest.cc +++ b/chrome/updater/app/server/win/com_classes_legacy_unittest.cc
@@ -13,16 +13,11 @@ #include "base/command_line.h" #include "base/files/file_path.h" -#include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/path_service.h" #include "base/strings/strcat.h" -#include "base/strings/string_number_conversions.h" #include "base/synchronization/waitable_event.h" #include "base/test/bind.h" -#include "base/test/test_timeouts.h" -#include "base/time/time.h" -#include "base/win/scoped_handle.h" #include "base/win/scoped_variant.h" #include "base/win/win_util.h" #include "build/branding_buildflags.h" @@ -31,13 +26,11 @@ #include "chrome/updater/util/unittest_util.h" #include "chrome/updater/util/unittest_util_win.h" #include "chrome/updater/util/util.h" -#include "chrome/updater/util/win_util.h" #include "chrome/updater/win/setup/setup_util.h" #include "chrome/updater/win/test/test_executables.h" #include "chrome/updater/win/test/test_strings.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/abseil-cpp/absl/types/optional.h" namespace updater { namespace { @@ -185,8 +178,9 @@ } TEST_F(LegacyAppCommandWebImplTest, CommandRunningStatus) { - if (IsSystemInstall(GetTestScope())) + if (IsSystemInstall(GetTestScope())) { return; + } Microsoft::WRL::ComPtr<LegacyAppCommandWebImpl> app_command_web; base::CommandLine command_line =
diff --git a/chrome/updater/app/server/win/server.cc b/chrome/updater/app/server/win/server.cc index 45672e1..3c6750f 100644 --- a/chrome/updater/app/server/win/server.cc +++ b/chrome/updater/app/server/win/server.cc
@@ -18,8 +18,6 @@ #include "base/functional/callback.h" #include "base/functional/callback_helpers.h" #include "base/logging.h" -#include "base/memory/ref_counted.h" -#include "base/path_service.h" #include "base/strings/strcat.h" #include "base/strings/sys_string_conversions.h" #include "base/strings/utf_string_conversions.h" @@ -28,8 +26,6 @@ #include "base/win/registry.h" #include "base/win/windows_types.h" #include "chrome/installer/util/work_item_list.h" -#include "chrome/updater/app/server/win/com_classes.h" -#include "chrome/updater/app/server/win/com_classes_legacy.h" #include "chrome/updater/constants.h" #include "chrome/updater/registration_data.h" #include "chrome/updater/update_service.h" @@ -70,8 +66,9 @@ // TODO(crbug.com/1270520) - use a switch that can uninstall immediately if // unused, instead of requiring server starts. uninstall_if_unused_command.AppendSwitch(kWakeSwitch); - if (IsSystemInstall(scope)) + if (IsSystemInstall(scope)) { uninstall_if_unused_command.AppendSwitch(kSystemSwitch); + } uninstall_if_unused_command.AppendSwitch(kEnableLoggingSwitch); uninstall_if_unused_command.AppendSwitchASCII(kLoggingModuleSwitch, kLoggingModuleSwitchValue); @@ -149,8 +146,9 @@ const absl::optional<base::FilePath> target_path = GetGoogleUpdateExePath(scope); - if (!target_path) + if (!target_path) { return false; + } list->AddCopyTreeWorkItem(updater_path, *target_path, temp_path, WorkItem::ALWAYS); @@ -236,8 +234,9 @@ main_task_runner_ = base::SequencedTaskRunner::GetCurrentDefault(); CreateWRLModule(); HRESULT hr = std::move(register_callback).Run(); - if (FAILED(hr)) + if (FAILED(hr)) { Shutdown(hr); + } } void ComServerApp::UninstallSelf() { @@ -249,8 +248,9 @@ const absl::optional<base::FilePath> versioned_directory = GetVersionedInstallDirectory(updater_scope()); - if (!versioned_directory) + if (!versioned_directory) { return false; + } const base::FilePath updater_path = versioned_directory->Append(GetExecutableRelativePath()); @@ -260,8 +260,9 @@ } absl::optional<base::ScopedTempDir> temp_dir = CreateSecureTempDir(); - if (!temp_dir) + if (!temp_dir) { return false; + } if (!SwapGoogleUpdate(updater_scope(), updater_path, temp_dir->GetPath(), UpdaterScopeToHKeyRoot(updater_scope()), list.get())) { @@ -290,8 +291,9 @@ const std::wstring app_id = it.Name(); // Skip importing legacy updater. - if (base::EqualsCaseInsensitiveASCII(app_id, kLegacyGoogleUpdaterAppID)) + if (base::EqualsCaseInsensitiveASCII(app_id, kLegacyGoogleUpdaterAppID)) { continue; + } base::win::RegKey key; if (key.Open(root, GetAppClientsKey(app_id).c_str(), Wow6432(KEY_READ)) != @@ -302,20 +304,24 @@ RegistrationRequest registration; registration.app_id = base::SysWideToUTF8(app_id); std::wstring pv; - if (key.ReadValue(kRegValuePV, &pv) != ERROR_SUCCESS) + if (key.ReadValue(kRegValuePV, &pv) != ERROR_SUCCESS) { continue; + } registration.version = base::Version(base::SysWideToUTF8(pv)); - if (!registration.version.IsValid()) + if (!registration.version.IsValid()) { continue; + } std::wstring brand_code; - if (key.ReadValue(kRegValueBrandCode, &brand_code) == ERROR_SUCCESS) + if (key.ReadValue(kRegValueBrandCode, &brand_code) == ERROR_SUCCESS) { registration.brand_code = base::SysWideToUTF8(brand_code); + } std::wstring ap; - if (key.ReadValue(kRegValueAP, &ap) == ERROR_SUCCESS) + if (key.ReadValue(kRegValueAP, &ap) == ERROR_SUCCESS) { registration.ap = base::SysWideToUTF8(ap); + } register_callback.Run(registration); }
diff --git a/chrome/updater/app/server/win/server.h b/chrome/updater/app/server/win/server.h index d931824..76e9fb03 100644 --- a/chrome/updater/app/server/win/server.h +++ b/chrome/updater/app/server/win/server.h
@@ -11,7 +11,6 @@ #include "base/functional/callback_forward.h" #include "base/memory/scoped_refptr.h" #include "base/task/sequenced_task_runner.h" -#include "chrome/updater/app/app.h" #include "chrome/updater/app/app_server.h" #include "chrome/updater/update_service.h" #include "chrome/updater/update_service_internal.h"
diff --git a/chrome/updater/app/server/win/service_main.cc b/chrome/updater/app/server/win/service_main.cc index 765e42e..c3de27d0 100644 --- a/chrome/updater/app/server/win/service_main.cc +++ b/chrome/updater/app/server/win/service_main.cc
@@ -11,18 +11,14 @@ #include <type_traits> #include "base/command_line.h" -#include "base/cxx17_backports.h" #include "base/logging.h" #include "base/no_destructor.h" #include "base/process/launch.h" #include "base/task/single_thread_task_executor.h" #include "base/win/scoped_com_initializer.h" -#include "chrome/updater/app/server/win/com_classes.h" -#include "chrome/updater/app/server/win/com_classes_legacy.h" #include "chrome/updater/app/server/win/server.h" #include "chrome/updater/constants.h" #include "chrome/updater/util/win_util.h" -#include "chrome/updater/win/win_constants.h" namespace updater { @@ -59,8 +55,9 @@ int ServiceMain::RunWindowsService(const base::CommandLine* command_line) { ServiceMain* service = ServiceMain::GetInstance(); - if (!service->InitWithCommandLine(command_line)) + if (!service->InitWithCommandLine(command_line)) { return ERROR_BAD_ARGUMENTS; + } int ret = service->Start(); DCHECK_NE(ret, int{STILL_ACTIVE}); @@ -80,8 +77,9 @@ } // Run interactively if needed. - if (command_line->HasSwitch(kConsoleSwitchName)) + if (command_line->HasSwitch(kConsoleSwitchName)) { run_routine_ = &ServiceMain::RunInteractive; + } return true; } @@ -186,8 +184,9 @@ } HRESULT hr = InitializeComSecurity(); - if (FAILED(hr)) + if (FAILED(hr)) { return hr; + } return AppServerSingletonInstance()->Run(); }
diff --git a/chrome/updater/app/server/win/service_main.h b/chrome/updater/app/server/win/service_main.h index 41e596f3..8af9e03 100644 --- a/chrome/updater/app/server/win/service_main.h +++ b/chrome/updater/app/server/win/service_main.h
@@ -8,7 +8,6 @@ #include <windows.h> #include "base/no_destructor.h" -#include "base/synchronization/waitable_event.h" #include "base/win/atl.h" namespace base {
diff --git a/chrome/updater/ipc/update_service_proxy_posix.cc b/chrome/updater/ipc/update_service_proxy_posix.cc index da3d9fcf..962cf0e1 100644 --- a/chrome/updater/ipc/update_service_proxy_posix.cc +++ b/chrome/updater/ipc/update_service_proxy_posix.cc
@@ -291,6 +291,7 @@ const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, + bool do_update_check_only, StateChangeCallback state_update, Callback callback) { VLOG(1) << __func__; @@ -303,6 +304,7 @@ static_cast<mojom::UpdateService::Priority>(priority), static_cast<mojom::UpdateService::PolicySameVersionUpdate>( policy_same_version_update), + do_update_check_only, std::move(state_change_observer_callback)); }
diff --git a/chrome/updater/ipc/update_service_proxy_posix.h b/chrome/updater/ipc/update_service_proxy_posix.h index f7becb9..3cb5e87 100644 --- a/chrome/updater/ipc/update_service_proxy_posix.h +++ b/chrome/updater/ipc/update_service_proxy_posix.h
@@ -63,6 +63,7 @@ const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, + bool do_update_check_only, StateChangeCallback state_update, Callback callback) override; void Install(const RegistrationRequest& registration,
diff --git a/chrome/updater/mac/keystone/ksadmin.mm b/chrome/updater/mac/keystone/ksadmin.mm index f5790c9a..e50d474e 100644 --- a/chrome/updater/mac/keystone/ksadmin.mm +++ b/chrome/updater/mac/keystone/ksadmin.mm
@@ -422,6 +422,7 @@ HasSwitch(kCommandUserInitiated) ? UpdateService::Priority::kForeground : UpdateService::Priority::kBackground, UpdateService::PolicySameVersionUpdate::kNotAllowed, + /*do_update_check_only=*/false, base::BindRepeating([](const UpdateService::UpdateState& update_state) { if (update_state.state == UpdateService::UpdateState::State::kUpdated) { printf("Finished updating (errors=%d reboot=%s)\n", 0, "YES");
diff --git a/chrome/updater/test/integration_test_commands.h b/chrome/updater/test/integration_test_commands.h index 6d15ee73..7ac38279 100644 --- a/chrome/updater/test/integration_test_commands.h +++ b/chrome/updater/test/integration_test_commands.h
@@ -77,16 +77,9 @@ virtual void RunWakeAll() const = 0; virtual void RunWakeActive(int exit_code) const = 0; -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) virtual void Update(const std::string& app_id, const std::string& install_data_index, bool do_update_check_only) const = 0; -#else // BUILDFLAG(IS_WIN) - virtual void Update(const std::string& app_id, - const std::string& install_data_index) const = 0; -#endif // BUILDFLAG(IS_WIN) virtual void UpdateAll() const = 0; virtual void DeleteUpdaterDirectory() const = 0;
diff --git a/chrome/updater/test/integration_test_commands_system.cc b/chrome/updater/test/integration_test_commands_system.cc index 0effb569..704fa5e 100644 --- a/chrome/updater/test/integration_test_commands_system.cc +++ b/chrome/updater/test/integration_test_commands_system.cc
@@ -197,9 +197,6 @@ {Param("exit_code", base::NumberToString(expected_exit_code))}); } -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) void Update(const std::string& app_id, const std::string& install_data_index, bool do_update_check_only) const override { @@ -208,13 +205,6 @@ Param("do_update_check_only", do_update_check_only ? "true" : "false")}); } -#else // BUILDFLAG(IS_WIN) - void Update(const std::string& app_id, - const std::string& install_data_index) const override { - RunCommand("update", {Param("app_id", app_id), - Param("install_data_index", install_data_index)}); - } -#endif // BUILDFLAG(IS_WIN) void UpdateAll() const override { RunCommand("update_all", {}); }
diff --git a/chrome/updater/test/integration_test_commands_user.cc b/chrome/updater/test/integration_test_commands_user.cc index 4eb6b96..925e0af3 100644 --- a/chrome/updater/test/integration_test_commands_user.cc +++ b/chrome/updater/test/integration_test_commands_user.cc
@@ -176,21 +176,12 @@ updater::test::RunWakeActive(updater_scope_, exit_code); } -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) void Update(const std::string& app_id, const std::string& install_data_index, bool do_update_check_only) const override { updater::test::Update(updater_scope_, app_id, install_data_index, do_update_check_only); } -#else // BUILDFLAG(IS_WIN) - void Update(const std::string& app_id, - const std::string& install_data_index) const override { - updater::test::Update(updater_scope_, app_id, install_data_index); - } -#endif // BUILDFLAG(IS_WIN) void UpdateAll() const override { updater::test::UpdateAll(updater_scope_); }
diff --git a/chrome/updater/test/integration_tests.cc b/chrome/updater/test/integration_tests.cc index 412e81f..ce64bcf3 100644 --- a/chrome/updater/test/integration_tests.cc +++ b/chrome/updater/test/integration_tests.cc
@@ -275,20 +275,11 @@ test_commands_->RunWakeActive(exit_code); } -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) void Update(const std::string& app_id, const std::string& install_data_index, bool do_update_check_only) { test_commands_->Update(app_id, install_data_index, do_update_check_only); } -#else // BUILDFLAG(IS_WIN) - void Update(const std::string& app_id, - const std::string& install_data_index) { - test_commands_->Update(app_id, install_data_index); - } -#endif // BUILDFLAG(IS_WIN) void UpdateAll() { test_commands_->UpdateAll(); } @@ -566,9 +557,6 @@ ASSERT_NO_FATAL_FAILURE(Uninstall()); } -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) TEST_F(IntegrationTest, CheckForUpdate) { ScopedServer test_server(test_commands_); ASSERT_NO_FATAL_FAILURE(Install()); @@ -581,7 +569,6 @@ ASSERT_NO_FATAL_FAILURE(Uninstall()); } -#endif // BUILDFLAG(IS_WIN) TEST_F(IntegrationTest, UpdateApp) { ScopedServer test_server(test_commands_); @@ -598,15 +585,8 @@ const std::string kInstallDataIndex("test_install_data_index"); ASSERT_NO_FATAL_FAILURE( ExpectUpdateSequence(&test_server, kAppId, kInstallDataIndex, v1, v2)); - -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) ASSERT_NO_FATAL_FAILURE(Update(kAppId, kInstallDataIndex, /*do_update_check_only=*/false)); -#else // BUILDFLAG(IS_WIN) - ASSERT_NO_FATAL_FAILURE(Update(kAppId, kInstallDataIndex)); -#endif // BUILDFLAG(IS_WIN) ASSERT_TRUE(WaitForUpdaterExit()); ASSERT_NO_FATAL_FAILURE(ExpectAppVersion(kAppId, v2));
diff --git a/chrome/updater/test/integration_tests_helper.cc b/chrome/updater/test/integration_tests_helper.cc index 0a507621..4e5fcdbe 100644 --- a/chrome/updater/test/integration_tests_helper.cc +++ b/chrome/updater/test/integration_tests_helper.cc
@@ -286,21 +286,11 @@ {"run_wake_all", WithSystemScope(Wrap(&RunWakeAll))}, {"run_wake_active", WithSwitch("exit_code", WithSystemScope(Wrap(&RunWakeActive)))}, - -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) {"update", WithSwitch( "do_update_check_only", WithSwitch("install_data_index", (WithSwitch("app_id", WithSystemScope(Wrap(&Update))))))}, -#else // BUILDFLAG(IS_WIN) - {"update", - WithSwitch("install_data_index", - (WithSwitch("app_id", WithSystemScope(Wrap(&Update)))))}, -#endif // BUILDFLAG(IS_WIN) - {"update_all", WithSystemScope(Wrap(&UpdateAll))}, {"delete_updater_directory", WithSystemScope(Wrap(&DeleteUpdaterDirectory))},
diff --git a/chrome/updater/test/integration_tests_impl.cc b/chrome/updater/test/integration_tests_impl.cc index b239440..6ba6e13 100644 --- a/chrome/updater/test/integration_tests_impl.cc +++ b/chrome/updater/test/integration_tests_impl.cc
@@ -372,9 +372,6 @@ RunUpdaterWithSwitch(active_version, scope, kWakeSwitch, expected_exit_code); } -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) void Update(UpdaterScope scope, const std::string& app_id, const std::string& install_data_index, @@ -389,21 +386,6 @@ [&loop](UpdateService::Result result_unused) { loop.Quit(); })); loop.Run(); } -#else // BUILDFLAG(IS_WIN) - -void Update(UpdaterScope scope, - const std::string& app_id, - const std::string& install_data_index) { - scoped_refptr<UpdateService> update_service = CreateUpdateServiceProxy(scope); - base::RunLoop loop; - update_service->Update( - app_id, install_data_index, UpdateService::Priority::kForeground, - UpdateService::PolicySameVersionUpdate::kNotAllowed, base::DoNothing(), - base::BindLambdaForTesting( - [&loop](UpdateService::Result result_unused) { loop.Quit(); })); - loop.Run(); -} -#endif // BUILDFLAG(IS_WIN) void UpdateAll(UpdaterScope scope) { scoped_refptr<UpdateService> update_service = CreateUpdateServiceProxy(scope); @@ -707,11 +689,7 @@ service_proxy->Update( app_id, install_data_index, UpdateService::Priority::kForeground, policy_same_version_update, -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) /*do_update_check_only=*/false, -#endif // BUILDFLAG(IS_WIN) base::BindLambdaForTesting([](const UpdateService::UpdateState&) {}), base::BindLambdaForTesting([&](UpdateService::Result result) { EXPECT_EQ(result, UpdateService::Result::kSuccess);
diff --git a/chrome/updater/test/integration_tests_impl.h b/chrome/updater/test/integration_tests_impl.h index 1de19adb..da7aca2 100644 --- a/chrome/updater/test/integration_tests_impl.h +++ b/chrome/updater/test/integration_tests_impl.h
@@ -101,20 +101,11 @@ void RunWakeActive(UpdaterScope scope, int exit_code); // Invokes the active instance's UpdateService::Update (via RPC) for an app. -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) void Update(UpdaterScope scope, const std::string& app_id, const std::string& install_data_index, bool do_update_check_only); -#else // BUILDFLAG(IS_WIN) -void Update(UpdaterScope scope, - const std::string& app_id, - const std::string& install_data_index); -#endif // BUILDFLAG(IS_WIN) - // Invokes the active instance's UpdateService::UpdateAll (via RPC). void UpdateAll(UpdaterScope scope);
diff --git a/chrome/updater/test/integration_tests_win.cc b/chrome/updater/test/integration_tests_win.cc index 240adc86..cc634f4 100644 --- a/chrome/updater/test/integration_tests_win.cc +++ b/chrome/updater/test/integration_tests_win.cc
@@ -265,6 +265,12 @@ EXPECT_EQ(is_installed, RegKeyExistsCOM(root, GetComServerAppidRegistryPath(clsid))); } + + const std::wstring progid(GetProgIdForClsid(scope, clsid)); + if (!progid.empty()) { + EXPECT_EQ(is_installed, + RegKeyExistsCOM(root, GetComProgIdRegistryPath(progid))); + } } for (const IID& iid : @@ -558,6 +564,11 @@ EXPECT_TRUE(DeleteRegKeyCOM(root, GetComServerClsidRegistryPath(clsid))); if (IsSystemInstall(scope)) EXPECT_TRUE(DeleteRegKeyCOM(root, GetComServerAppidRegistryPath(clsid))); + + const std::wstring progid(GetProgIdForClsid(scope, clsid)); + if (!progid.empty()) { + EXPECT_TRUE(DeleteRegKeyCOM(root, GetComProgIdRegistryPath(progid))); + } } for (const IID& iid : JoinVectors(GetSideBySideInterfaces(scope), @@ -769,6 +780,16 @@ : __uuidof(IUpdaterUser), IID_PPV_ARGS_Helper(&updater))); + // Verifies that the progid for the legacy clsid is registered. + CLSID expected_clsid = {}; + EXPECT_HRESULT_SUCCEEDED(::CLSIDFromProgID( + IsSystemInstall(scope) ? L"GoogleUpdate.Update3WebMachine" + : L"GoogleUpdate.Update3WebUser", + &expected_clsid)); + EXPECT_EQ(expected_clsid, IsSystemInstall(scope) + ? __uuidof(GoogleUpdate3WebSystemClass) + : __uuidof(GoogleUpdate3WebUserClass)); + for (const CLSID& clsid : [&scope]() -> std::vector<CLSID> { if (IsSystemInstall(scope)) { return {__uuidof(GoogleUpdate3WebSystemClass),
diff --git a/chrome/updater/update_service.h b/chrome/updater/update_service.h index d0a5a3188..95e090a 100644 --- a/chrome/updater/update_service.h +++ b/chrome/updater/update_service.h
@@ -236,11 +236,7 @@ // `install_data_index`: Index of the server install data. // `priority`: Priority for processing this update. // `policy_same_version_update`: Whether a same-version update is allowed. - // - // TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are - // done in separate CL. - // Windows-only: `do_update_check_only`: Only checks for updates if `true`. - // + // `do_update_check_only`: Only checks for updates if `true`. // `state_update`: The callback will be invoked every time the update // changes state when the engine starts. It will be called on the // sequence used by the update service, so this callback must not block. @@ -257,11 +253,7 @@ const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) bool do_update_check_only, -#endif // BUILDFLAG(IS_WIN) StateChangeCallback state_update, Callback callback) = 0;
diff --git a/chrome/updater/update_service_impl.cc b/chrome/updater/update_service_impl.cc index 095f38e..cf26a88 100644 --- a/chrome/updater/update_service_impl.cc +++ b/chrome/updater/update_service_impl.cc
@@ -122,9 +122,6 @@ } } -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) update_client::UpdateClient::CrxStateChangeCallback MakeUpdateClientCrxStateChangeCallbackForUpdateCheck( scoped_refptr<update_client::Configurator> config, @@ -165,7 +162,6 @@ }, config, callback, base::MakeRefCounted<RefCountedState>()); } -#endif // BUILDFLAG(IS_WIN) update_client::UpdateClient::CrxStateChangeCallback MakeUpdateClientCrxStateChangeCallback( @@ -292,15 +288,6 @@ if (request.app_id != kUpdaterAppId) { persisted_data_->SetHadApps(); } - base::Version current_version = - persisted_data_->GetProductVersion(request.app_id); - if (current_version.IsValid() && - current_version.CompareTo(request.version) == 1) { - main_task_runner_->PostTask( - FROM_HERE, - base::BindOnce(std::move(callback), kRegistrationAlreadyRegistered)); - return; - } persisted_data_->RegisterApp(request); std::move(callback).Run(kRegistrationSuccess); } @@ -479,11 +466,7 @@ const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) bool do_update_check_only, -#endif // BUILDFLAG(IS_WIN) StateChangeCallback state_update, Callback callback) { VLOG(1) << __func__; @@ -496,9 +479,6 @@ return; } -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) if (do_update_check_only) { main_task_runner_->PostTask( FROM_HERE, @@ -517,7 +497,6 @@ MakeUpdateClientCallback(std::move(callback)))); return; } -#endif // BUILDFLAG(IS_WIN) ShouldBlockUpdateForMeteredNetwork( priority,
diff --git a/chrome/updater/update_service_impl.h b/chrome/updater/update_service_impl.h index 6d47e58f..d709203 100644 --- a/chrome/updater/update_service_impl.h +++ b/chrome/updater/update_service_impl.h
@@ -56,11 +56,7 @@ const std::string& install_data_index, Priority priority, PolicySameVersionUpdate policy_same_version_update, -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) bool do_update_check_only, -#endif // BUILDFLAG(IS_WIN) StateChangeCallback state_update, Callback callback) override; void Install(const RegistrationRequest& registration,
diff --git a/chrome/updater/update_service_impl_inactive.cc b/chrome/updater/update_service_impl_inactive.cc index a12d644..9f6fa40 100644 --- a/chrome/updater/update_service_impl_inactive.cc +++ b/chrome/updater/update_service_impl_inactive.cc
@@ -68,11 +68,7 @@ const std::string& /*install_data_index*/, Priority /*priority*/, PolicySameVersionUpdate /*policy_same_version_update*/, -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) bool /*do_update_check_only*/, -#endif // BUILDFLAG(IS_WIN) StateChangeCallback /*state_update*/, Callback callback) override { VLOG(1) << __func__ << " (Inactive)";
diff --git a/chrome/updater/update_service_internal_impl_qualifying.cc b/chrome/updater/update_service_internal_impl_qualifying.cc index 1a5230b..669e432c 100644 --- a/chrome/updater/update_service_internal_impl_qualifying.cc +++ b/chrome/updater/update_service_internal_impl_qualifying.cc
@@ -109,12 +109,7 @@ kQualificationAppId, "", UpdateService::Priority::kBackground, UpdateService::PolicySameVersionUpdate::kNotAllowed, -// TODO(crbug.com/1396103): remove this `#if` once mojo interface changes are -// done in separate CL. -#if BUILDFLAG(IS_WIN) - /*do_update_check_only=*/false, -#endif // BUILDFLAG(IS_WIN) - base::DoNothing())) + /*do_update_check_only=*/false, base::DoNothing())) ->Run(base::BindOnce( &UpdateServiceInternalQualifyingImpl::UpdateCheckDone, this, std::move(callback)));
diff --git a/chrome/updater/win/setup/setup_util.cc b/chrome/updater/win/setup/setup_util.cc index 083c352a..8f9237f 100644 --- a/chrome/updater/win/setup/setup_util.cc +++ b/chrome/updater/win/setup/setup_util.cc
@@ -62,6 +62,107 @@ : std::wstring(); } +// Adds work items to `list` to install the progid corresponding to `clsid`. +void AddInstallComProgIdWorkItems(UpdaterScope scope, + CLSID clsid, + WorkItemList* list) { + const std::wstring progid(GetProgIdForClsid(scope, clsid)); + if (!progid.empty()) { + const HKEY root = UpdaterScopeToHKeyRoot(scope); + const std::wstring progid_reg_path(GetComProgIdRegistryPath(progid)); + + // Delete any old registrations first. + for (const auto& key_flag : {KEY_WOW64_32KEY, KEY_WOW64_64KEY}) { + list->AddDeleteRegKeyWorkItem(root, progid_reg_path, key_flag); + } + + list->AddCreateRegKeyWorkItem(root, progid_reg_path + L"\\CLSID", + WorkItem::kWow64Default); + list->AddSetRegValueWorkItem(root, progid_reg_path + L"\\CLSID", + WorkItem::kWow64Default, L"", + base::win::WStringFromGUID(clsid), true); + } +} + +// Adds work items to `list` to install the interface `iid`. +void AddInstallComInterfaceWorkItems(HKEY root, + const base::FilePath& typelib_path, + GUID iid, + WorkItemList* list) { + const std::wstring iid_reg_path = GetComIidRegistryPath(iid); + const std::wstring typelib_reg_path = GetComTypeLibRegistryPath(iid); + + // Delete any old registrations first. + for (const auto& reg_path : {iid_reg_path, typelib_reg_path}) { + for (const auto& key_flag : {KEY_WOW64_32KEY, KEY_WOW64_64KEY}) { + list->AddDeleteRegKeyWorkItem(root, reg_path, key_flag); + } + } + + // Registering the Ole Automation marshaler with the CLSID + // {00020424-0000-0000-C000-000000000046} as the proxy/stub for the + // interfaces. + list->AddCreateRegKeyWorkItem(root, iid_reg_path + L"\\ProxyStubClsid32", + WorkItem::kWow64Default); + list->AddSetRegValueWorkItem(root, iid_reg_path + L"\\ProxyStubClsid32", + WorkItem::kWow64Default, L"", + L"{00020424-0000-0000-C000-000000000046}", true); + list->AddCreateRegKeyWorkItem(root, iid_reg_path + L"\\TypeLib", + WorkItem::kWow64Default); + list->AddSetRegValueWorkItem(root, iid_reg_path + L"\\TypeLib", + WorkItem::kWow64Default, L"", + base::win::WStringFromGUID(iid), true); + + // The TypeLib registration for the Ole Automation marshaler. + const base::FilePath qualified_typelib_path = + typelib_path.Append(GetComTypeLibResourceIndex(iid)); + list->AddCreateRegKeyWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win32", + WorkItem::kWow64Default); + list->AddSetRegValueWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win32", + WorkItem::kWow64Default, L"", + qualified_typelib_path.value(), true); + list->AddCreateRegKeyWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win64", + WorkItem::kWow64Default); + list->AddSetRegValueWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win64", + WorkItem::kWow64Default, L"", + qualified_typelib_path.value(), true); +} + +// Adds work items to `list` to install the server `iid`. +void AddInstallServerWorkItems(HKEY root, + CLSID clsid, + const base::FilePath& com_server_path, + bool internal_service, + WorkItemList* list) { + const std::wstring clsid_reg_path = GetComServerClsidRegistryPath(clsid); + + // Delete any old registrations first. + for (const auto& reg_path : {clsid_reg_path}) { + for (const auto& key_flag : {KEY_WOW64_32KEY, KEY_WOW64_64KEY}) { + list->AddDeleteRegKeyWorkItem(root, reg_path, key_flag); + } + } + + list->AddCreateRegKeyWorkItem(root, clsid_reg_path, WorkItem::kWow64Default); + const std::wstring local_server32_reg_path = + base::StrCat({clsid_reg_path, L"\\LocalServer32"}); + list->AddCreateRegKeyWorkItem(root, local_server32_reg_path, + WorkItem::kWow64Default); + + base::CommandLine run_com_server_command(com_server_path); + run_com_server_command.AppendSwitch(kServerSwitch); + run_com_server_command.AppendSwitchASCII( + kServerServiceSwitch, internal_service + ? kServerUpdateServiceInternalSwitchValue + : kServerUpdateServiceSwitchValue); + run_com_server_command.AppendSwitch(kEnableLoggingSwitch); + run_com_server_command.AppendSwitchASCII(kLoggingModuleSwitch, + kLoggingModuleSwitchValue); + list->AddSetRegValueWorkItem( + root, local_server32_reg_path, WorkItem::kWow64Default, L"", + run_com_server_command.GetCommandLineString(), true); +} + } // namespace bool RegisterWakeTask(const base::CommandLine& run_command, @@ -205,81 +306,6 @@ return is_internal ? GetSideBySideServers(scope) : GetActiveServers(scope); } -void AddInstallComInterfaceWorkItems(HKEY root, - const base::FilePath& typelib_path, - GUID iid, - WorkItemList* list) { - const std::wstring iid_reg_path = GetComIidRegistryPath(iid); - const std::wstring typelib_reg_path = GetComTypeLibRegistryPath(iid); - - // Delete any old registrations first. - for (const auto& reg_path : {iid_reg_path, typelib_reg_path}) { - for (const auto& key_flag : {KEY_WOW64_32KEY, KEY_WOW64_64KEY}) - list->AddDeleteRegKeyWorkItem(root, reg_path, key_flag); - } - - // Registering the Ole Automation marshaler with the CLSID - // {00020424-0000-0000-C000-000000000046} as the proxy/stub for the - // interfaces. - list->AddCreateRegKeyWorkItem(root, iid_reg_path + L"\\ProxyStubClsid32", - WorkItem::kWow64Default); - list->AddSetRegValueWorkItem(root, iid_reg_path + L"\\ProxyStubClsid32", - WorkItem::kWow64Default, L"", - L"{00020424-0000-0000-C000-000000000046}", true); - list->AddCreateRegKeyWorkItem(root, iid_reg_path + L"\\TypeLib", - WorkItem::kWow64Default); - list->AddSetRegValueWorkItem(root, iid_reg_path + L"\\TypeLib", - WorkItem::kWow64Default, L"", - base::win::WStringFromGUID(iid), true); - - // The TypeLib registration for the Ole Automation marshaler. - const base::FilePath qualified_typelib_path = - typelib_path.Append(GetComTypeLibResourceIndex(iid)); - list->AddCreateRegKeyWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win32", - WorkItem::kWow64Default); - list->AddSetRegValueWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win32", - WorkItem::kWow64Default, L"", - qualified_typelib_path.value(), true); - list->AddCreateRegKeyWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win64", - WorkItem::kWow64Default); - list->AddSetRegValueWorkItem(root, typelib_reg_path + L"\\1.0\\0\\win64", - WorkItem::kWow64Default, L"", - qualified_typelib_path.value(), true); -} - -void AddInstallServerWorkItems(HKEY root, - CLSID clsid, - const base::FilePath& com_server_path, - bool internal_service, - WorkItemList* list) { - const std::wstring clsid_reg_path = GetComServerClsidRegistryPath(clsid); - - // Delete any old registrations first. - for (const auto& reg_path : {clsid_reg_path}) { - for (const auto& key_flag : {KEY_WOW64_32KEY, KEY_WOW64_64KEY}) - list->AddDeleteRegKeyWorkItem(root, reg_path, key_flag); - } - - list->AddCreateRegKeyWorkItem(root, clsid_reg_path, WorkItem::kWow64Default); - const std::wstring local_server32_reg_path = - base::StrCat({clsid_reg_path, L"\\LocalServer32"}); - list->AddCreateRegKeyWorkItem(root, local_server32_reg_path, - WorkItem::kWow64Default); - - base::CommandLine run_com_server_command(com_server_path); - run_com_server_command.AppendSwitch(kServerSwitch); - run_com_server_command.AppendSwitchASCII( - kServerServiceSwitch, internal_service - ? kServerUpdateServiceInternalSwitchValue - : kServerUpdateServiceSwitchValue); - run_com_server_command.AppendSwitch(kEnableLoggingSwitch); - run_com_server_command.AppendSwitchASCII(kLoggingModuleSwitch, - kLoggingModuleSwitchValue); - list->AddSetRegValueWorkItem( - root, local_server32_reg_path, WorkItem::kWow64Default, L"", - run_com_server_command.GetCommandLineString(), true); -} - void AddComServerWorkItems(const base::FilePath& com_server_path, bool is_internal, WorkItemList* list) { @@ -292,6 +318,7 @@ for (const auto& clsid : GetServers(is_internal, UpdaterScope::kUser)) { AddInstallServerWorkItems(HKEY_CURRENT_USER, clsid, com_server_path, is_internal, list); + AddInstallComProgIdWorkItems(UpdaterScope::kUser, clsid, list); } for (const auto& iid : GetInterfaces(is_internal, UpdaterScope::kUser)) { @@ -325,11 +352,16 @@ base::CommandLine com_switch(base::CommandLine::NO_PROGRAM); com_switch.AppendSwitch(kComServiceSwitch); + const std::vector<CLSID> clsids( + GetServers(internal_service, UpdaterScope::kSystem)); list->AddWorkItem(new installer::InstallServiceWorkItem( GetServiceName(internal_service).c_str(), GetServiceDisplayName(internal_service).c_str(), SERVICE_AUTO_START, - com_service_command, com_switch, UPDATER_KEY, - GetServers(internal_service, UpdaterScope::kSystem), {})); + com_service_command, com_switch, UPDATER_KEY, clsids, {})); + + for (const auto& clsid : clsids) { + AddInstallComProgIdWorkItems(UpdaterScope::kSystem, clsid, list); + } for (const auto& iid : GetInterfaces(internal_service, UpdaterScope::kSystem)) { @@ -338,6 +370,23 @@ } } +std::wstring GetProgIdForClsid(UpdaterScope scope, CLSID clsid) { + switch (scope) { + case UpdaterScope::kUser: + return clsid == __uuidof(GoogleUpdate3WebUserClass) + ? L"GoogleUpdate.Update3WebUser" + : L""; + case UpdaterScope::kSystem: + return clsid == __uuidof(GoogleUpdate3WebSystemClass) + ? L"GoogleUpdate.Update3WebMachine" + : L""; + } +} + +std::wstring GetComProgIdRegistryPath(const std::wstring& progid) { + return base::StrCat({L"Software\\Classes\\", progid}); +} + std::wstring GetComServerClsidRegistryPath(REFCLSID clsid) { return base::StrCat( {L"Software\\Classes\\CLSID\\", base::win::WStringFromGUID(clsid)});
diff --git a/chrome/updater/win/setup/setup_util.h b/chrome/updater/win/setup/setup_util.h index b9de5ac5..cb564c4 100644 --- a/chrome/updater/win/setup/setup_util.h +++ b/chrome/updater/win/setup/setup_util.h
@@ -38,6 +38,8 @@ bool RegisterWakeTask(const base::CommandLine& run_command, UpdaterScope scope); void UnregisterWakeTask(UpdaterScope scope); +std::wstring GetProgIdForClsid(UpdaterScope scope, CLSID clsid); +std::wstring GetComProgIdRegistryPath(const std::wstring& progid); std::wstring GetComServerClsidRegistryPath(REFCLSID clsid); std::wstring GetComServerAppidRegistryPath(REFGUID appid); std::wstring GetComIidRegistryPath(REFIID iid); @@ -88,19 +90,6 @@ return joined_vector; } -// Adds work items to `list` to install the interface `iid`. -void AddInstallComInterfaceWorkItems(HKEY root, - const base::FilePath& typelib_path, - GUID iid, - WorkItemList* list); - -// Adds work items to `list` to install the server `iid`. -void AddInstallServerWorkItems(HKEY root, - CLSID iid, - const base::FilePath& executable_path, - bool internal_service, - WorkItemList* list); - // Adds work items to register the per-user COM server. void AddComServerWorkItems(const base::FilePath& com_server_path, bool is_internal,
diff --git a/chrome/updater/win/setup/uninstall.cc b/chrome/updater/win/setup/uninstall.cc index b172573..19984fd1 100644 --- a/chrome/updater/win/setup/uninstall.cc +++ b/chrome/updater/win/setup/uninstall.cc
@@ -45,6 +45,13 @@ installer::DeleteRegistryKey(UpdaterScopeToHKeyRoot(scope), GetComServerClsidRegistryPath(clsid), WorkItem::kWow64Default); + + const std::wstring progid(GetProgIdForClsid(scope, clsid)); + if (!progid.empty()) { + installer::DeleteRegistryKey(UpdaterScopeToHKeyRoot(scope), + GetComProgIdRegistryPath(progid), + WorkItem::kWow64Default); + } } }
diff --git a/chromeos/ash/components/device_activity/churn_cohort_use_case_impl.cc b/chromeos/ash/components/device_activity/churn_cohort_use_case_impl.cc index f0d639e6..253fd730 100644 --- a/chromeos/ash/components/device_activity/churn_cohort_use_case_impl.cc +++ b/chromeos/ash/components/device_activity/churn_cohort_use_case_impl.cc
@@ -41,12 +41,8 @@ absl::optional<FresnelImportDataRequest> ChurnCohortUseCaseImpl::GenerateImportRequestBody() { - std::string psm_id_str = GetPsmIdentifier().value().sensitive_id(); - std::string window_id_str = GetWindowIdentifier().value(); - // Generate Fresnel PSM import request body. FresnelImportDataRequest import_request; - import_request.set_window_identifier(window_id_str); // Create fresh |DeviceMetadata| object. // Note every dimension added to this proto must be approved by privacy. @@ -57,7 +53,14 @@ device_metadata->set_hardware_id(GetFullHardwareClass()); import_request.set_use_case(GetPsmUseCase()); - import_request.set_plaintext_identifier(psm_id_str); + + std::string psm_id_str = GetPsmIdentifier().value().sensitive_id(); + std::string window_id_str = GetWindowIdentifier().value(); + + FresnelImportData* import_data = import_request.add_import_data(); + import_data->set_plaintext_id(psm_id_str); + import_data->set_window_identifier(window_id_str); + import_data->set_is_pt_window_identifier(true); return import_request; }
diff --git a/chromeos/ash/components/network/portal_detector/network_portal_detector.h b/chromeos/ash/components/network/portal_detector/network_portal_detector.h index d396d7f..55c7ce3 100644 --- a/chromeos/ash/components/network/portal_detector/network_portal_detector.h +++ b/chromeos/ash/components/network/portal_detector/network_portal_detector.h
@@ -37,8 +37,12 @@ // Returns true if portal detection is enabled. virtual bool IsEnabled() = 0; - // Enable portal detection. Once enabled, portal detection for the default - // network will be handled any time the default network state changes. + // Enable portal detection. This will do nothing if the EULA has not been + // accepted (i.e. OOBE has not completed) since we do not want to show a + // captive portal signin page until the user accepts the EULA. Once accepted, + // Enable() should be called again. + // Once enabled, portal detection for the default network will be handled any + // time the default network state changes. virtual void Enable() = 0; // Returns non-localized string representation of |status|.
diff --git a/chromeos/crosapi/mojom/ui_constants_mojom_traits.cc b/chromeos/crosapi/mojom/ui_constants_mojom_traits.cc index ee24a07cd..c181f854 100644 --- a/chromeos/crosapi/mojom/ui_constants_mojom_traits.cc +++ b/chromeos/crosapi/mojom/ui_constants_mojom_traits.cc
@@ -37,7 +37,7 @@ *output = ui::ResourceScaleFactor::k100Percent; return true; case crosapi::mojom::ResourceScaleFactor::k200Percent: - *output = ui::ResourceScaleFactor::k100Percent; + *output = ui::ResourceScaleFactor::k200Percent; return true; case crosapi::mojom::ResourceScaleFactor::k300Percent: *output = ui::ResourceScaleFactor::k300Percent;
diff --git a/components/autofill/core/browser/metrics/payments/iban_metrics.cc b/components/autofill/core/browser/metrics/payments/iban_metrics.cc index e430aac7..c3e2fb0 100644 --- a/components/autofill/core/browser/metrics/payments/iban_metrics.cc +++ b/components/autofill/core/browser/metrics/payments/iban_metrics.cc
@@ -16,8 +16,27 @@ void LogIBANSaveNotOfferedDueToMaxStrikesMetric( AutofillMetrics::SaveTypeMetric metric) { - UMA_HISTOGRAM_ENUMERATION( + base::UmaHistogramEnumeration( "Autofill.StrikeDatabase.IbanSaveNotOfferedDueToMaxStrikes", metric); } +void LogSaveIbanBubbleOfferMetric(SaveIbanPromptOffer metric, bool is_reshow) { + std::string base_histogram_name = "Autofill.SaveIbanPromptOffer.Local"; + std::string show = is_reshow ? ".Reshows" : ".FirstShow"; + base::UmaHistogramEnumeration(base_histogram_name + show, metric); +} + +void LogSaveIbanBubbleResultMetric(SaveIbanBubbleResult metric, + bool is_reshow) { + std::string base_histogram_name = "Autofill.SaveIbanPromptResult.Local"; + std::string show = is_reshow ? ".Reshows" : ".FirstShow"; + base::UmaHistogramEnumeration(base_histogram_name + show, metric); +} + +void LogSaveIbanBubbleResultSavedWithNicknameMetric(bool save_with_nickname) { + base::UmaHistogramBoolean( + "Autofill.SaveIbanPromptResult.Local.SavedWithNickname", + save_with_nickname); +} + } // namespace autofill::autofill_metrics
diff --git a/components/autofill/core/browser/metrics/payments/iban_metrics.h b/components/autofill/core/browser/metrics/payments/iban_metrics.h index e67d4d7..7cec9b80 100644 --- a/components/autofill/core/browser/metrics/payments/iban_metrics.h +++ b/components/autofill/core/browser/metrics/payments/iban_metrics.h
@@ -10,6 +10,36 @@ namespace autofill::autofill_metrics { +// This includes all possible results. +// They will be used in metrics, and should not be renumbered. +enum class SaveIbanBubbleResult { + // The user explicitly accepted the bubble by clicking the ok button. + kAccepted = 0, + // The user explicitly cancelled the bubble by clicking the cancel button. + kCancelled = 1, + // The user explicitly closed the bubble with the close button or ESC. + kClosed = 2, + // The user did not interact with the bubble. + kNotInteracted = 3, + // The bubble lost focus and was deactivated. + kLostFocus = 4, + // The reason why the bubble is closed is not clear. Possible reason is the + // logging function is invoked before the closed reason is correctly set. + kUnknown = 5, + kMaxValue = kUnknown, +}; + +// Metrics to track event when the IBAN prompt is offered. +// They will be used in metrics, and should not be renumbered. +enum class SaveIbanPromptOffer { + // The prompt is actually shown. + kShown = 0, + // The prompt is not shown because the prompt has been declined by the user + // too many times. + kNotShownMaxStrikesReached = 1, + kMaxValue = kNotShownMaxStrikesReached, +}; + // Logs the number of strikes that an IBAN had when save was accepted. void LogStrikesPresentWhenIBANSaved(const int num_strikes); @@ -17,6 +47,16 @@ void LogIBANSaveNotOfferedDueToMaxStrikesMetric( AutofillMetrics::SaveTypeMetric metric); +// Logs when IBAN save bubble is offered to users. +void LogSaveIbanBubbleOfferMetric(SaveIbanPromptOffer metric, bool is_reshow); + +// Logs when the user makes a decision on the IBAN save bubble. +void LogSaveIbanBubbleResultMetric(SaveIbanBubbleResult metric, bool is_reshow); + +// Logs when the user accepts the bubble to save an IBAN. +// `save_with_nickname` donates the user has input a nickname. +void LogSaveIbanBubbleResultSavedWithNicknameMetric(bool save_with_nickname); + } // namespace autofill::autofill_metrics #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_METRICS_PAYMENTS_IBAN_METRICS_H_
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager.cc b/components/autofill/core/browser/payments/credit_card_save_manager.cc index b8de8fc..a107b75b 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager.cc
@@ -277,23 +277,6 @@ show_save_prompt_ = !GetCreditCardSaveStrikeDatabase()->ShouldBlockFeature( base::UTF16ToUTF8(upload_request_.card.LastFourDigits())); -#if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) - - int save_card_ui_experiment_arm = - features::kAutofillSaveCardUiExperimentSelectorInNumber.Get(); - - // Adding the Save Card UI Experiment to the active experiments in upload - // request if the experiment is active. If 3rd save card ui experiment, aka - // Current with Avatar and Email, is selected then we would not add - // AutofillSaveCardUiExperiment to the active experiments list, as we want the - // current footer to be displayed. - if (base::FeatureList::IsEnabled(features::kAutofillSaveCardUiExperiment) && - (save_card_ui_experiment_arm == 1 || save_card_ui_experiment_arm == 2)) { - upload_request_.active_experiments.push_back( - "AutofillSaveCardUiExperiment"); - } -#endif - payments_client_->GetUploadDetails( country_only_profiles, upload_request_.detected_values, upload_request_.active_experiments, app_locale_,
diff --git a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc index 88b2019..791fbff 100644 --- a/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc +++ b/components/autofill/core/browser/payments/credit_card_save_manager_unittest.cc
@@ -1688,102 +1688,6 @@ } #endif -#if !BUILDFLAG(IS_IOS) && !BUILDFLAG(IS_ANDROID) -TEST_F(CreditCardSaveManagerTest, - AttemptToOfferCardUploadSave_SaveCardUiExperimentEnabled) { - // Setting the flag and params for the save card ui experiment. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeatureWithParameters( - features::kAutofillSaveCardUiExperiment, - {{"autofill_save_card_ui_experiment_selector_in_number", "2"}}); - - // Set up our credit card form data. - FormData credit_card_form; - CreateTestCreditCardFormData(&credit_card_form, CreditCardFormOptions()); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - credit_card_form.fields[0].value = u"Jane Doe"; - credit_card_form.fields[1].value = u"4111111111111111"; - credit_card_form.fields[2].value = ASCIIToUTF16(test::NextMonth()); - credit_card_form.fields[3].value = ASCIIToUTF16(test::NextYear()); - credit_card_form.fields[4].value = u"123"; - FormSubmitted(credit_card_form); - - EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled()); - EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded()); - - // Confirm that active experiments vector has the correct value. - std::vector<const char*> active_experiments_in_request = - payments_client_->active_experiments_in_request(); - EXPECT_THAT( - active_experiments_in_request, - testing::Contains(testing::StrEq("AutofillSaveCardUiExperiment"))); -} - -TEST_F(CreditCardSaveManagerTest, - AttemptToOfferCardUploadSave_SaveCardUiExperimentDisabled) { - // Disabling the flag for the save card ui experiment. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndDisableFeature( - features::kAutofillSaveCardUiExperiment); - - FormData credit_card_form; - CreateTestCreditCardFormData(&credit_card_form, CreditCardFormOptions()); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - credit_card_form.fields[0].value = u"Jane Doe"; - credit_card_form.fields[1].value = u"4111111111111111"; - credit_card_form.fields[2].value = ASCIIToUTF16(test::NextMonth()); - credit_card_form.fields[3].value = ASCIIToUTF16(test::NextYear()); - credit_card_form.fields[4].value = u"123"; - FormSubmitted(credit_card_form); - - EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled()); - EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded()); - - std::vector<const char*> active_experiments_in_request = - payments_client_->active_experiments_in_request(); - EXPECT_THAT(active_experiments_in_request, - testing::Not(testing::Contains( - testing::StrEq("AutofillSaveCardUiExperiment")))); -} - -TEST_F( - CreditCardSaveManagerTest, - AttemptToOfferCardUploadSave_SaveCardUiExperimentEnabledWithoutAddedInOutgoingRequest) { - // Setting the flag and params for the save card ui experiment with value 3 as - // we are not getting the updated/experimental TOS for that experiment arm. - base::test::ScopedFeatureList scoped_feature_list; - scoped_feature_list.InitAndEnableFeatureWithParameters( - features::kAutofillSaveCardUiExperiment, - {{"autofill_save_card_ui_experiment_selector_in_number", "3"}}); - - // Set up our credit card form data. - FormData credit_card_form; - CreateTestCreditCardFormData(&credit_card_form, CreditCardFormOptions()); - FormsSeen(std::vector<FormData>(1, credit_card_form)); - - // Edit the data, and submit. - credit_card_form.fields[0].value = u"Jane Doe"; - credit_card_form.fields[1].value = u"4111111111111111"; - credit_card_form.fields[2].value = ASCIIToUTF16(test::NextMonth()); - credit_card_form.fields[3].value = ASCIIToUTF16(test::NextYear()); - credit_card_form.fields[4].value = u"123"; - FormSubmitted(credit_card_form); - - EXPECT_FALSE(autofill_client_.ConfirmSaveCardLocallyWasCalled()); - EXPECT_TRUE(credit_card_save_manager_->CreditCardWasUploaded()); - - // Confirm that active experiments vector has the correct value. - std::vector<const char*> active_experiments_in_request = - payments_client_->active_experiments_in_request(); - EXPECT_THAT(active_experiments_in_request, - testing::Not(testing::Contains( - testing::StrEq("AutofillSaveCardUiExperiment")))); -} -#endif - // TODO(crbug.com/1113034): Create an equivalent test for iOS, or skip // permanently if the test doesn't apply to iOS flow. #if !BUILDFLAG(IS_IOS)
diff --git a/components/autofill/core/common/autofill_payments_features.cc b/components/autofill/core/common/autofill_payments_features.cc index d34007b..677b576c 100644 --- a/components/autofill/core/common/autofill_payments_features.cc +++ b/components/autofill/core/common/autofill_payments_features.cc
@@ -198,18 +198,6 @@ "AutofillSaveCardInfobarEditSupport", base::FEATURE_ENABLED_BY_DEFAULT); -// When enabled, Chrome will display experimental UI variants to the user -// during the upload save card process. -BASE_FEATURE(kAutofillSaveCardUiExperiment, - "AutofillSaveCardUiExperiment", - base::FEATURE_DISABLED_BY_DEFAULT); - -// This will select one of the options for the save card UI bubble which we -// want to display to the user. The value will be an integer(number). -const base::FeatureParam<int> kAutofillSaveCardUiExperimentSelectorInNumber{ - &kAutofillSaveCardUiExperiment, - "autofill_save_card_ui_experiment_selector_in_number", 0}; - // When enabled, the entire PAN and the CVC details of the unmasked cached card // will be shown in the manual filling view. BASE_FEATURE(kAutofillShowUnmaskedCachedCardInManualFillingView,
diff --git a/components/autofill/core/common/autofill_payments_features.h b/components/autofill/core/common/autofill_payments_features.h index 0c41191..146d19e9 100644 --- a/components/autofill/core/common/autofill_payments_features.h +++ b/components/autofill/core/common/autofill_payments_features.h
@@ -39,9 +39,6 @@ BASE_DECLARE_FEATURE(kAutofillParseVcnCardOnFileStandaloneCvcFields); BASE_DECLARE_FEATURE(kAutofillRemoveCardExpirationAndTypeTitles); BASE_DECLARE_FEATURE(kAutofillSaveCardInfobarEditSupport); -BASE_DECLARE_FEATURE(kAutofillSaveCardUiExperiment); -extern const base::FeatureParam<int> - kAutofillSaveCardUiExperimentSelectorInNumber; BASE_DECLARE_FEATURE(kAutofillShowUnmaskedCachedCardInManualFillingView); BASE_DECLARE_FEATURE(kAutofillSuggestServerCardInsteadOfLocalCard); BASE_DECLARE_FEATURE(kAutofillUpstream);
diff --git a/components/exo/buffer.cc b/components/exo/buffer.cc index 4e6cdaf2..436bf74 100644 --- a/components/exo/buffer.cc +++ b/components/exo/buffer.cc
@@ -457,9 +457,10 @@ const bool request_release_fence = !per_commit_explicit_release_callback.is_null(); - if (per_commit_explicit_release_callback) + if (per_commit_explicit_release_callback) { pending_explicit_releases_.emplace( next_commit_id_, std::move(per_commit_explicit_release_callback)); + } resource->id = resource_manager->AllocateResourceId(); resource->format = viz::SharedImageFormat::SinglePlane(viz::RGBA_8888); @@ -566,8 +567,12 @@ return true; } +void Buffer::SkipLegacyRelease() { + legacy_release_skippable_ = true; +} + void Buffer::OnAttach() { - DLOG_IF(WARNING, attach_count_) + DLOG_IF(WARNING, attach_count_ && !legacy_release_skippable_) << "Reattaching a buffer that is already attached to another surface."; TRACE_EVENT2("exo", "Buffer::OnAttach", "buffer_id", static_cast<const void*>(gfx_buffer()), "count", attach_count_); @@ -614,8 +619,9 @@ TRACE_EVENT_ASYNC_END0("exo", kBufferInUse, gpu_memory_buffer_.get()); // Run release callback to notify the client that buffer has been released. - if (!release_callback_.is_null()) + if (!release_callback_.is_null() && !legacy_release_skippable_) { release_callback_.Run(); + } } void Buffer::ReleaseTexture(std::unique_ptr<Texture> texture, @@ -662,7 +668,11 @@ // We are still required to send these wl_buffer.release events even if // the client supports explicit synchronization. - if (release_fence.is_null()) { + if (!buffer_release_callback) { + return; + } + + if (release_fence.is_null() || legacy_release_skippable_) { std::move(buffer_release_callback).Run(); } else { // Watching the release fence's fd results in a context switch to the I/O @@ -716,9 +726,10 @@ gfx::ColorSpace color_space, ProtectedNativePixmapQueryDelegate* protected_native_pixmap_query, PerCommitExplicitReleaseCallback per_commit_explicit_release_callback) { - if (per_commit_explicit_release_callback) + if (per_commit_explicit_release_callback) { std::move(per_commit_explicit_release_callback) .Run(/*release_fence=*/gfx::GpuFenceHandle()); + } return false; }
diff --git a/components/exo/buffer.h b/components/exo/buffer.h index 1f6430f..5808c00 100644 --- a/components/exo/buffer.h +++ b/components/exo/buffer.h
@@ -53,6 +53,9 @@ release_callback_ = release_callback; } + // The client does not need release_callback_ to notify buffer usage. + void SkipLegacyRelease(); + // Returns if this buffer's contents are vertically inverted. bool y_invert() const { return y_invert_; } @@ -212,6 +215,8 @@ // protocol requires us to send regular buffer release events. base::flat_map<uint64_t, BufferRelease> buffer_releases_; + bool legacy_release_skippable_ = false; + #if BUILDFLAG(USE_ARC_PROTECTED_MEDIA) ProtectedBufferState protected_buffer_state_ = ProtectedBufferState::UNKNOWN; #endif // BUILDFLAG(USE_ARC_PROTECTED_MEDIA)
diff --git a/components/exo/surface.cc b/components/exo/surface.cc index 478d70a..4463c7d 100644 --- a/components/exo/surface.cc +++ b/components/exo/surface.cc
@@ -1302,6 +1302,10 @@ if (!buffer_color_space.IsValid()) { buffer_color_space = gfx::ColorSpace::CreateSRGB(); } + if (legacy_buffer_release_skippable_ && + state_.per_commit_explicit_release_callback_) { + state_.buffer->buffer()->SkipLegacyRelease(); + } if (state_.buffer->buffer()->ProduceTransferableResource( resource_manager, std::move(state_.acquire_fence), state_.basic_state.only_visible_on_secure_output,
diff --git a/components/exo/surface.h b/components/exo/surface.h index 7ad1fd4..3d25c96 100644 --- a/components/exo/surface.h +++ b/components/exo/surface.h
@@ -107,6 +107,10 @@ leave_enter_callback_ = callback; } + void set_legacy_buffer_release_skippable(bool skippable) { + legacy_buffer_release_skippable_ = skippable; + } + // Called when the display the surface is on has changed. // Returns true if successful, and false if it fails. bool UpdateDisplay(int64_t old_id, int64_t new_id); @@ -659,6 +663,7 @@ LeaveEnterCallback leave_enter_callback_; bool keyboard_shortcuts_inhibited_ = false; + bool legacy_buffer_release_skippable_ = false; }; class ScopedSurface {
diff --git a/components/exo/wayland/surface_augmenter.cc b/components/exo/wayland/surface_augmenter.cc index 072cf6e3..13e900e 100644 --- a/components/exo/wayland/surface_augmenter.cc +++ b/components/exo/wayland/surface_augmenter.cc
@@ -39,6 +39,7 @@ explicit AugmentedSurface(Surface* surface) : surface_(surface) { surface_->AddSurfaceObserver(this); surface_->SetProperty(kSurfaceHasAugmentedSurfaceKey, true); + surface_->set_legacy_buffer_release_skippable(true); } AugmentedSurface(const AugmentedSurface&) = delete; AugmentedSurface& operator=(const AugmentedSurface&) = delete;
diff --git a/components/media_router/common/providers/cast/channel/cast_channel_metrics.cc b/components/media_router/common/providers/cast/channel/cast_channel_metrics.cc index 51b3d95..1cf6788 100644 --- a/components/media_router/common/providers/cast/channel/cast_channel_metrics.cc +++ b/components/media_router/common/providers/cast/channel/cast_channel_metrics.cc
@@ -9,9 +9,6 @@ namespace cast_channel { -constexpr char kLaunchSessionChannelFlagsHistogram[] = - "Cast.Channel.LaunchSession.Flags"; - void RecordLaunchSessionChannelFlags(CastChannelFlags flags) { if (!flags) { UMA_HISTOGRAM_ENUMERATION(kLaunchSessionChannelFlagsHistogram,
diff --git a/components/media_router/common/providers/cast/channel/cast_channel_metrics.h b/components/media_router/common/providers/cast/channel/cast_channel_metrics.h index 724251c3..9d57df90 100644 --- a/components/media_router/common/providers/cast/channel/cast_channel_metrics.h +++ b/components/media_router/common/providers/cast/channel/cast_channel_metrics.h
@@ -9,6 +9,9 @@ namespace cast_channel { +constexpr char kLaunchSessionChannelFlagsHistogram[] = + "Cast.Channel.LaunchSession.Flags"; + // Records the flags set on a Cast channel when a Cast LAUNCH message is sent. void RecordLaunchSessionChannelFlags(CastChannelFlags flags);
diff --git a/components/media_router/common/providers/cast/channel/cast_message_handler_unittest.cc b/components/media_router/common/providers/cast/channel/cast_message_handler_unittest.cc index cd024b09..50d3f7e 100644 --- a/components/media_router/common/providers/cast/channel/cast_message_handler_unittest.cc +++ b/components/media_router/common/providers/cast/channel/cast_message_handler_unittest.cc
@@ -12,10 +12,13 @@ #include "base/run_loop.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" +#include "base/test/metrics/histogram_tester.h" #include "base/test/mock_callback.h" #include "base/test/task_environment.h" #include "base/test/test_simple_task_runner.h" #include "base/test/values_test_util.h" +#include "components/media_router/common/providers/cast/channel/cast_channel_enum.h" +#include "components/media_router/common/providers/cast/channel/cast_channel_metrics.h" #include "components/media_router/common/providers/cast/channel/cast_message_util.h" #include "components/media_router/common/providers/cast/channel/cast_test_util.h" #include "content/public/test/browser_task_environment.h" @@ -419,6 +422,10 @@ } TEST_F(CastMessageHandlerTest, LaunchSession) { + base::HistogramTester histogram_tester; + cast_socket_.SetFlags( + static_cast<CastChannelFlags>(CastChannelFlag::kSha1DigestAlgorithm) | + static_cast<CastChannelFlags>(CastChannelFlag::kCRLMissing)); ExpectEnsureConnectionThen(CastMessageType::kLaunch); const absl::optional<base::Value> json = base::JSONReader::Read(kAppParams); @@ -457,6 +464,13 @@ OnMessage(response); run_loop_->Run(); EXPECT_EQ(1, session_launch_response_count_); + // Flags associated with the CastSocket should be recorded on launch. + histogram_tester.ExpectBucketCount(kLaunchSessionChannelFlagsHistogram, + CastChannelFlag::kFlagsNone, 0); + histogram_tester.ExpectBucketCount(kLaunchSessionChannelFlagsHistogram, + CastChannelFlag::kSha1DigestAlgorithm, 1); + histogram_tester.ExpectBucketCount(kLaunchSessionChannelFlagsHistogram, + CastChannelFlag::kCRLMissing, 1); } TEST_F(CastMessageHandlerTest, LaunchSessionTimedOut) {
diff --git a/components/media_router/common/providers/cast/channel/cast_test_util.h b/components/media_router/common/providers/cast/channel/cast_test_util.h index f346052..e97e688 100644 --- a/components/media_router/common/providers/cast/channel/cast_test_util.h +++ b/components/media_router/common/providers/cast/channel/cast_test_util.h
@@ -148,9 +148,8 @@ error_state_ = error_state; } - CastChannelFlags flags() const override { - return static_cast<CastChannelFlags>(CastChannelFlag::kFlagsNone); - } + CastChannelFlags flags() const override { return flags_; } + void SetFlags(CastChannelFlags flags) { flags_ = flags; } bool keep_alive() const override { return keep_alive_; } void SetKeepAlive(bool keep_alive) { keep_alive_ = keep_alive; } @@ -165,6 +164,8 @@ net::IPEndPoint ip_endpoint_; int channel_id_; ChannelError error_state_; + CastChannelFlags flags_{ + static_cast<CastChannelFlags>(CastChannelFlag::kFlagsNone)}; bool keep_alive_; bool audio_only_;
diff --git a/components/payments_strings.grdp b/components/payments_strings.grdp index 9b35b99..983ec556 100644 --- a/components/payments_strings.grdp +++ b/components/payments_strings.grdp
@@ -588,6 +588,9 @@ <message name="IDS_PAYMENT_HANDLER_SHEET_CLOSED" desc="Accessibility string read when the payment-handler bottom sheet is closed." formatter_data="android_java"> Payment handler sheet is closed </message> + <message name="IDS_PAYMENT_HANDLER_ICON" desc="The alt text for the payment handler icon. Used for accessibility."> + Payment handler icon + </message> <!-- Secure Payment Confirmation strings --> <if expr="not is_win and not is_macosx">
diff --git a/components/payments_strings_grdp/IDS_PAYMENT_HANDLER_ICON.png.sha1 b/components/payments_strings_grdp/IDS_PAYMENT_HANDLER_ICON.png.sha1 new file mode 100644 index 0000000..f7967fa6 --- /dev/null +++ b/components/payments_strings_grdp/IDS_PAYMENT_HANDLER_ICON.png.sha1
@@ -0,0 +1 @@ +a4914f944acc47c8932fe1646a177f216f3b28cc \ No newline at end of file
diff --git a/components/pdf/renderer/pdf_accessibility_tree.cc b/components/pdf/renderer/pdf_accessibility_tree.cc index d47c9beb..7d9cf91 100644 --- a/components/pdf/renderer/pdf_accessibility_tree.cc +++ b/components/pdf/renderer/pdf_accessibility_tree.cc
@@ -818,6 +818,9 @@ button.control_count); button_node->AddIntAttribute(ax::mojom::IntAttribute::kPosInSet, button.control_index + 1); + button_node->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kCheck); + } else { + button_node->SetDefaultActionVerb(ax::mojom::DefaultActionVerb::kPress); } button_node->relative_bounds.bounds = button.bounds; @@ -836,6 +839,9 @@ listbox_option_node->AddBoolAttribute(ax::mojom::BoolAttribute::kSelected, choice_field_option.is_selected); listbox_option_node->AddState(ax::mojom::State::kFocusable); + listbox_option_node->SetDefaultActionVerb( + ax::mojom::DefaultActionVerb::kSelect); + return listbox_option_node; } @@ -902,6 +908,11 @@ combobox_input_node->AddState(ax::mojom::State::kFocusable); combobox_input_node->relative_bounds.bounds = choice_field.bounds; + if (input_role == ax::mojom::Role::kComboBoxMenuButton) { + combobox_input_node->SetDefaultActionVerb( + ax::mojom::DefaultActionVerb::kOpen); + } + return combobox_input_node; }
diff --git a/components/performance_manager/decorators/page_live_state_decorator.cc b/components/performance_manager/decorators/page_live_state_decorator.cc index 07c8c7b74..5cacfbf 100644 --- a/components/performance_manager/decorators/page_live_state_decorator.cc +++ b/components/performance_manager/decorators/page_live_state_decorator.cc
@@ -365,11 +365,11 @@ graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this); } -base::Value PageLiveStateDecorator::DescribePageNodeData( +base::Value::Dict PageLiveStateDecorator::DescribePageNodeData( const PageNode* node) const { auto* data = Data::FromPageNode(node); if (!data) - return base::Value(); + return base::Value::Dict(); base::Value::Dict ret; ret.Set("IsConnectedToUSBDevice", data->IsConnectedToUSBDevice()); @@ -383,7 +383,7 @@ ret.Set("WasDiscarded", data->WasDiscarded()); ret.Set("IsActiveTab", data->IsActiveTab()); - return base::Value(std::move(ret)); + return ret; } void PageLiveStateDecorator::OnMainFrameUrlChanged(const PageNode* page_node) {
diff --git a/components/performance_manager/decorators/page_load_tracker_decorator.cc b/components/performance_manager/decorators/page_load_tracker_decorator.cc index 9323c673..35cded30f 100644 --- a/components/performance_manager/decorators/page_load_tracker_decorator.cc +++ b/components/performance_manager/decorators/page_load_tracker_decorator.cc
@@ -102,18 +102,18 @@ UnregisterObservers(graph); } -base::Value PageLoadTrackerDecorator::DescribePageNodeData( +base::Value::Dict PageLoadTrackerDecorator::DescribePageNodeData( const PageNode* page_node) const { auto* data = DataImpl::Get(PageNodeImpl::FromNode(page_node)); if (data == nullptr) - return base::Value(); + return base::Value::Dict(); base::Value::Dict ret; ret.Set("load_idle_state", ToString(data->load_idle_state())); ret.Set("is_loading", data->is_loading_); ret.Set("did_commit", data->did_commit_); - return base::Value(std::move(ret)); + return ret; } void PageLoadTrackerDecorator::OnMainThreadTaskLoadIsLow(
diff --git a/components/performance_manager/decorators/page_load_tracker_decorator.h b/components/performance_manager/decorators/page_load_tracker_decorator.h index bf17c49a..23f1dcad 100644 --- a/components/performance_manager/decorators/page_load_tracker_decorator.h +++ b/components/performance_manager/decorators/page_load_tracker_decorator.h
@@ -46,7 +46,7 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; // ProcessNodeObserver implementation: void OnMainThreadTaskLoadIsLow(const ProcessNode* process_node) override;
diff --git a/components/performance_manager/freezing/freezing_vote_aggregator.cc b/components/performance_manager/freezing/freezing_vote_aggregator.cc index ac8d3e39..dc9bf11 100644 --- a/components/performance_manager/freezing/freezing_vote_aggregator.cc +++ b/components/performance_manager/freezing/freezing_vote_aggregator.cc
@@ -116,15 +116,15 @@ graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this); } -base::Value FreezingVoteAggregator::DescribePageNodeData( +base::Value::Dict FreezingVoteAggregator::DescribePageNodeData( const PageNode* node) const { auto votes_for_page = vote_data_map_.find(node); if (votes_for_page == vote_data_map_.end()) - return base::Value(); + return base::Value::Dict(); base::Value::Dict ret; votes_for_page->second.DescribeVotes(ret); - return base::Value(std::move(ret)); + return ret; } FreezingVoteAggregator::FreezingVoteData::FreezingVoteData() = default;
diff --git a/components/performance_manager/freezing/freezing_vote_aggregator.h b/components/performance_manager/freezing/freezing_vote_aggregator.h index 5820752..49522c80b 100644 --- a/components/performance_manager/freezing/freezing_vote_aggregator.h +++ b/components/performance_manager/freezing/freezing_vote_aggregator.h
@@ -60,7 +60,7 @@ void UnregisterNodeDataDescriber(Graph* graph); // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; private: friend class performance_manager::FreezingVoteDecorator;
diff --git a/components/performance_manager/graph/frame_node_impl_describer.cc b/components/performance_manager/graph/frame_node_impl_describer.cc index 44c4376..24c0965 100644 --- a/components/performance_manager/graph/frame_node_impl_describer.cc +++ b/components/performance_manager/graph/frame_node_impl_describer.cc
@@ -52,7 +52,7 @@ graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this); } -base::Value FrameNodeImplDescriber::DescribeFrameNodeData( +base::Value::Dict FrameNodeImplDescriber::DescribeFrameNodeData( const FrameNode* node) const { const FrameNodeImpl* impl = FrameNodeImpl::FromNode(node); @@ -86,7 +86,7 @@ ViewportIntersectionToString(impl->viewport_intersection_.value())); ret.Set("visibility", FrameNodeVisibilityToString(impl->visibility_.value())); - return base::Value(std::move(ret)); + return ret; } } // namespace performance_manager
diff --git a/components/performance_manager/graph/frame_node_impl_describer.h b/components/performance_manager/graph/frame_node_impl_describer.h index 8453e70..78d2a421 100644 --- a/components/performance_manager/graph/frame_node_impl_describer.h +++ b/components/performance_manager/graph/frame_node_impl_describer.h
@@ -23,7 +23,7 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriberDefaultImpl impl: - base::Value DescribeFrameNodeData(const FrameNode* node) const override; + base::Value::Dict DescribeFrameNodeData(const FrameNode* node) const override; }; } // namespace performance_manager
diff --git a/components/performance_manager/graph/graph_impl.cc b/components/performance_manager/graph/graph_impl.cc index 45170138..a0f555d9 100644 --- a/components/performance_manager/graph/graph_impl.cc +++ b/components/performance_manager/graph/graph_impl.cc
@@ -65,7 +65,7 @@ void RegisterDescriber(const NodeDataDescriber* describer, base::StringPiece name) override; void UnregisterDescriber(const NodeDataDescriber* describer) override; - base::Value DescribeNodeData(const Node* node) const override; + base::Value::Dict DescribeNodeData(const Node* node) const override; size_t size() const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); @@ -74,8 +74,8 @@ private: template <typename NodeType, typename NodeImplType> - base::Value DescribeNodeImpl( - base::Value (NodeDataDescriber::*DescribeFn)(const NodeType*) const, + base::Value::Dict DescribeNodeImpl( + base::Value::Dict (NodeDataDescriber::*DescribeFn)(const NodeType*) const, const NodeImplType* node) const VALID_CONTEXT_REQUIRED(sequence_checker_); base::flat_map<const NodeDataDescriber*, std::string> describers_ @@ -84,16 +84,16 @@ }; template <typename NodeType, typename NodeImplType> -base::Value NodeDataDescriberRegistryImpl::DescribeNodeImpl( - base::Value (NodeDataDescriber::*Describe)(const NodeType*) const, +base::Value::Dict NodeDataDescriberRegistryImpl::DescribeNodeImpl( + base::Value::Dict (NodeDataDescriber::*Describe)(const NodeType*) const, const NodeImplType* node) const { - base::Value result(base::Value::Type::DICT); + base::Value::Dict result; for (const auto& name_and_describer : describers_) { - base::Value description = (name_and_describer.first->*Describe)(node); - if (!description.is_none()) { - DCHECK_EQ(nullptr, result.FindDictKey(name_and_describer.second)); - result.SetKey(name_and_describer.second, std::move(description)); + base::Value::Dict description = (name_and_describer.first->*Describe)(node); + if (!description.empty()) { + DCHECK_EQ(nullptr, result.FindDict(name_and_describer.second)); + result.Set(name_and_describer.second, std::move(description)); } } @@ -126,14 +126,14 @@ DCHECK_EQ(1u, erased); } -base::Value NodeDataDescriberRegistryImpl::DescribeNodeData( +base::Value::Dict NodeDataDescriberRegistryImpl::DescribeNodeData( const Node* node) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const NodeBase* node_base = NodeBase::FromNode(node); switch (node_base->type()) { case NodeTypeEnum::kInvalidType: NOTREACHED(); - return base::Value(); + return base::Value::Dict(); case NodeTypeEnum::kFrame: return DescribeNodeImpl(&NodeDataDescriber::DescribeFrameNodeData, FrameNodeImpl::FromNodeBase(node_base));
diff --git a/components/performance_manager/graph/graph_impl_unittest.cc b/components/performance_manager/graph/graph_impl_unittest.cc index 32528d0b..96ae0477 100644 --- a/components/performance_manager/graph/graph_impl_unittest.cc +++ b/components/performance_manager/graph/graph_impl_unittest.cc
@@ -205,57 +205,59 @@ public: explicit TestNodeDataDescriber(base::StringPiece name) : name_(name) {} - base::Value DescribeFrameNodeData(const FrameNode* node) const override { - base::Value::List list; - list.Append(name_); - list.Append("FrameNode"); - return base::Value(std::move(list)); + base::Value::Dict DescribeFrameNodeData( + const FrameNode* node) const override { + base::Value::Dict dict; + dict.Set("name", name_); + dict.Set("type", "FrameNode"); + return dict; } - base::Value DescribePageNodeData(const PageNode* node) const override { - base::Value::List list; - list.Append(name_); - list.Append("PageNode"); - return base::Value(std::move(list)); + base::Value::Dict DescribePageNodeData(const PageNode* node) const override { + base::Value::Dict dict; + dict.Set("name", name_); + dict.Set("type", "PageNode"); + return dict; } - base::Value DescribeProcessNodeData(const ProcessNode* node) const override { - base::Value::List list; - list.Append(name_); - list.Append("ProcessNode"); - return base::Value(std::move(list)); + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const override { + base::Value::Dict dict; + dict.Set("name", name_); + dict.Set("type", "ProcessNode"); + return dict; } - base::Value DescribeSystemNodeData(const SystemNode* node) const override { - base::Value::List list; - list.Append(name_); - list.Append("SystemNode"); - return base::Value(std::move(list)); + base::Value::Dict DescribeSystemNodeData( + const SystemNode* node) const override { + base::Value::Dict dict; + dict.Set("name", name_); + dict.Set("type", "SystemNode"); + return dict; } - base::Value DescribeWorkerNodeData(const WorkerNode* node) const override { - base::Value::List list; - list.Append(name_); - list.Append("WorkerNode"); - return base::Value(std::move(list)); + base::Value::Dict DescribeWorkerNodeData( + const WorkerNode* node) const override { + base::Value::Dict dict; + dict.Set("name", name_); + dict.Set("type", "WorkerNode"); + return dict; } private: const std::string name_; }; -void AssertDictValueContainsListKey(const base::Value& descr, +void AssertDictValueContainsListKey(const base::Value::Dict& descr, const char* key, - const char* s1, - const char* s2) { - ASSERT_TRUE(descr.is_dict()); - const base::Value* v = descr.FindListKey(key); - ASSERT_NE(nullptr, v); + const std::string s1, + const std::string s2) { + const base::Value::Dict* dict = descr.FindDict(key); + ASSERT_NE(nullptr, dict); - const auto& list = v->GetList(); - ASSERT_EQ(2u, list.size()); - ASSERT_EQ(list[0], base::Value(s1)); - ASSERT_EQ(list[1], base::Value(s2)); + ASSERT_EQ(2u, dict->size()); + ASSERT_EQ(*(dict->FindString("name")), s1); + ASSERT_EQ(*(dict->FindString("type")), s2); } } // namespace @@ -265,8 +267,8 @@ NodeDataDescriberRegistry* registry = graph()->GetNodeDataDescriberRegistry(); // No describers->no description. - base::Value descr = registry->DescribeNodeData(mock_graph.frame.get()); - EXPECT_EQ(0u, descr.DictSize()); + base::Value::Dict descr = registry->DescribeNodeData(mock_graph.frame.get()); + EXPECT_EQ(0u, descr.size()); // Test that the default impl does nothing. NodeDataDescriberDefaultImpl default_impl; @@ -278,25 +280,25 @@ descr = registry->DescribeNodeData(mock_graph.frame.get()); AssertDictValueContainsListKey(descr, "d1", "d1", "FrameNode"); - EXPECT_EQ(1u, descr.DictSize()); + EXPECT_EQ(1u, descr.size()); descr = registry->DescribeNodeData(mock_graph.page.get()); AssertDictValueContainsListKey(descr, "d1", "d1", "PageNode"); - EXPECT_EQ(1u, descr.DictSize()); + EXPECT_EQ(1u, descr.size()); descr = registry->DescribeNodeData(mock_graph.process.get()); AssertDictValueContainsListKey(descr, "d1", "d1", "ProcessNode"); - EXPECT_EQ(1u, descr.DictSize()); + EXPECT_EQ(1u, descr.size()); descr = registry->DescribeNodeData(graph()->GetSystemNode()); AssertDictValueContainsListKey(descr, "d1", "d1", "SystemNode"); - EXPECT_EQ(1u, descr.DictSize()); + EXPECT_EQ(1u, descr.size()); auto worker = CreateNode<WorkerNodeImpl>(WorkerNode::WorkerType::kDedicated, mock_graph.process.get()); descr = registry->DescribeNodeData(worker.get()); AssertDictValueContainsListKey(descr, "d1", "d1", "WorkerNode"); - EXPECT_EQ(1u, descr.DictSize()); + EXPECT_EQ(1u, descr.size()); // Unregister the default impl now that it's been verified to say nothing // about all node types. @@ -307,7 +309,7 @@ registry->RegisterDescriber(&d2, "d2"); descr = registry->DescribeNodeData(mock_graph.frame.get()); - EXPECT_EQ(2u, descr.DictSize()); + EXPECT_EQ(2u, descr.size()); AssertDictValueContainsListKey(descr, "d1", "d1", "FrameNode"); AssertDictValueContainsListKey(descr, "d2", "d2", "FrameNode"); @@ -316,7 +318,7 @@ // No describers after unregistration->no description. descr = registry->DescribeNodeData(mock_graph.frame.get()); - EXPECT_EQ(0u, descr.DictSize()); + EXPECT_EQ(0u, descr.size()); } TEST_F(GraphImplTest, OpenersAndEmbeddersClearedOnTeardown) {
diff --git a/components/performance_manager/graph/node_data_describer.cc b/components/performance_manager/graph/node_data_describer.cc index 3103611..a167946 100644 --- a/components/performance_manager/graph/node_data_describer.cc +++ b/components/performance_manager/graph/node_data_describer.cc
@@ -6,29 +6,29 @@ namespace performance_manager { -base::Value NodeDataDescriberDefaultImpl::DescribeFrameNodeData( +base::Value::Dict NodeDataDescriberDefaultImpl::DescribeFrameNodeData( const FrameNode* node) const { - return base::Value(); + return base::Value::Dict(); } -base::Value NodeDataDescriberDefaultImpl::DescribePageNodeData( +base::Value::Dict NodeDataDescriberDefaultImpl::DescribePageNodeData( const PageNode* node) const { - return base::Value(); + return base::Value::Dict(); } -base::Value NodeDataDescriberDefaultImpl::DescribeProcessNodeData( +base::Value::Dict NodeDataDescriberDefaultImpl::DescribeProcessNodeData( const ProcessNode* node) const { - return base::Value(); + return base::Value::Dict(); } -base::Value NodeDataDescriberDefaultImpl::DescribeSystemNodeData( +base::Value::Dict NodeDataDescriberDefaultImpl::DescribeSystemNodeData( const SystemNode* node) const { - return base::Value(); + return base::Value::Dict(); } -base::Value NodeDataDescriberDefaultImpl::DescribeWorkerNodeData( +base::Value::Dict NodeDataDescriberDefaultImpl::DescribeWorkerNodeData( const WorkerNode* node) const { - return base::Value(); + return base::Value::Dict(); } } // namespace performance_manager
diff --git a/components/performance_manager/graph/page_node_impl_describer.cc b/components/performance_manager/graph/page_node_impl_describer.cc index 828c676e..ba1593e 100644 --- a/components/performance_manager/graph/page_node_impl_describer.cc +++ b/components/performance_manager/graph/page_node_impl_describer.cc
@@ -39,7 +39,7 @@ graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this); } -base::Value PageNodeImplDescriber::DescribePageNodeData( +base::Value::Dict PageNodeImplDescriber::DescribePageNodeData( const PageNode* page_node) const { const PageNodeImpl* page_node_impl = PageNodeImpl::FromNode(page_node); DCHECK_CALLED_ON_VALID_SEQUENCE(page_node_impl->sequence_checker_); @@ -86,7 +86,7 @@ result.Set("freezing_vote", FreezingVoteToString(page_node_impl->freezing_vote())); - return base::Value(std::move(result)); + return result; } } // namespace performance_manager
diff --git a/components/performance_manager/graph/page_node_impl_describer.h b/components/performance_manager/graph/page_node_impl_describer.h index 56bf669d..5bc1d08 100644 --- a/components/performance_manager/graph/page_node_impl_describer.h +++ b/components/performance_manager/graph/page_node_impl_describer.h
@@ -25,7 +25,8 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* page_node) const override; + base::Value::Dict DescribePageNodeData( + const PageNode* page_node) const override; }; } // namespace performance_manager
diff --git a/components/performance_manager/graph/process_node_impl_describer.cc b/components/performance_manager/graph/process_node_impl_describer.cc index 31cd844..e90a4322 100644 --- a/components/performance_manager/graph/process_node_impl_describer.cc +++ b/components/performance_manager/graph/process_node_impl_describer.cc
@@ -132,7 +132,7 @@ graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this); } -base::Value ProcessNodeImplDescriber::DescribeProcessNodeData( +base::Value::Dict ProcessNodeImplDescriber::DescribeProcessNodeData( const ProcessNode* node) const { const ProcessNodeImpl* impl = ProcessNodeImpl::FromNode(node); @@ -191,7 +191,7 @@ .value()); } - return base::Value(std::move(ret)); + return ret; } } // namespace performance_manager
diff --git a/components/performance_manager/graph/process_node_impl_describer.h b/components/performance_manager/graph/process_node_impl_describer.h index 401214c..e0f1d3f 100644 --- a/components/performance_manager/graph/process_node_impl_describer.h +++ b/components/performance_manager/graph/process_node_impl_describer.h
@@ -26,7 +26,8 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: - base::Value DescribeProcessNodeData(const ProcessNode* node) const override; + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const override; }; } // namespace performance_manager
diff --git a/components/performance_manager/graph/worker_node_impl_describer.cc b/components/performance_manager/graph/worker_node_impl_describer.cc index 72db192b..9ebc9b1 100644 --- a/components/performance_manager/graph/worker_node_impl_describer.cc +++ b/components/performance_manager/graph/worker_node_impl_describer.cc
@@ -36,11 +36,11 @@ graph->GetNodeDataDescriberRegistry()->UnregisterDescriber(this); } -base::Value WorkerNodeImplDescriber::DescribeWorkerNodeData( +base::Value::Dict WorkerNodeImplDescriber::DescribeWorkerNodeData( const WorkerNode* node) const { const WorkerNodeImpl* impl = WorkerNodeImpl::FromNode(node); if (!impl) - return base::Value(); + return base::Value::Dict(); base::Value::Dict ret; ret.Set("browser_context_id", impl->browser_context_id()); @@ -49,7 +49,7 @@ ret.Set("worker_type", WorkerTypeToString(impl->worker_type())); ret.Set("priority", PriorityAndReasonToValue(impl->priority_and_reason())); - return base::Value(std::move(ret)); + return ret; } } // namespace performance_manager
diff --git a/components/performance_manager/graph/worker_node_impl_describer.h b/components/performance_manager/graph/worker_node_impl_describer.h index 91504437..2626148 100644 --- a/components/performance_manager/graph/worker_node_impl_describer.h +++ b/components/performance_manager/graph/worker_node_impl_describer.h
@@ -26,7 +26,8 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: - base::Value DescribeWorkerNodeData(const WorkerNode* node) const override; + base::Value::Dict DescribeWorkerNodeData( + const WorkerNode* node) const override; }; } // namespace performance_manager
diff --git a/components/performance_manager/public/decorators/page_live_state_decorator.h b/components/performance_manager/public/decorators/page_live_state_decorator.h index efc0b54..d4303c9d 100644 --- a/components/performance_manager/public/decorators/page_live_state_decorator.h +++ b/components/performance_manager/public/decorators/page_live_state_decorator.h
@@ -107,7 +107,7 @@ void OnTakenFromGraph(Graph* graph) override; // NodeDataDescriber implementation: - base::Value DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; // PageNode::ObserverDefaultImpl implementation: void OnMainFrameUrlChanged(const PageNode* page_node) override;
diff --git a/components/performance_manager/public/graph/node_data_describer.h b/components/performance_manager/public/graph/node_data_describer.h index 67dbb9e..3d52703 100644 --- a/components/performance_manager/public/graph/node_data_describer.h +++ b/components/performance_manager/public/graph/node_data_describer.h
@@ -39,23 +39,30 @@ public: virtual ~NodeDataDescriber() = default; - virtual base::Value DescribeFrameNodeData(const FrameNode* node) const = 0; - virtual base::Value DescribePageNodeData(const PageNode* node) const = 0; - virtual base::Value DescribeProcessNodeData( + virtual base::Value::Dict DescribeFrameNodeData( + const FrameNode* node) const = 0; + virtual base::Value::Dict DescribePageNodeData( + const PageNode* node) const = 0; + virtual base::Value::Dict DescribeProcessNodeData( const ProcessNode* node) const = 0; - virtual base::Value DescribeSystemNodeData(const SystemNode* node) const = 0; - virtual base::Value DescribeWorkerNodeData(const WorkerNode* node) const = 0; + virtual base::Value::Dict DescribeSystemNodeData( + const SystemNode* node) const = 0; + virtual base::Value::Dict DescribeWorkerNodeData( + const WorkerNode* node) const = 0; }; // A convenience do-nothing implementation of the interface above. Returns // an is_none() value for all nodes. class NodeDataDescriberDefaultImpl : public NodeDataDescriber { public: - base::Value DescribeFrameNodeData(const FrameNode* node) const override; - base::Value DescribePageNodeData(const PageNode* node) const override; - base::Value DescribeProcessNodeData(const ProcessNode* node) const override; - base::Value DescribeSystemNodeData(const SystemNode* node) const override; - base::Value DescribeWorkerNodeData(const WorkerNode* node) const override; + base::Value::Dict DescribeFrameNodeData(const FrameNode* node) const override; + base::Value::Dict DescribePageNodeData(const PageNode* node) const override; + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const override; + base::Value::Dict DescribeSystemNodeData( + const SystemNode* node) const override; + base::Value::Dict DescribeWorkerNodeData( + const WorkerNode* node) const override; }; } // namespace performance_manager
diff --git a/components/performance_manager/public/graph/node_data_describer_registry.h b/components/performance_manager/public/graph/node_data_describer_registry.h index e3e83e6..c75ba8b 100644 --- a/components/performance_manager/public/graph/node_data_describer_registry.h +++ b/components/performance_manager/public/graph/node_data_describer_registry.h
@@ -28,7 +28,7 @@ // Invoke all registered describers for |node| and return a dictionary from // their name to their description - if any. - virtual base::Value DescribeNodeData(const Node* node) const = 0; + virtual base::Value::Dict DescribeNodeData(const Node* node) const = 0; }; } // namespace performance_manager
diff --git a/components/performance_manager/v8_memory/v8_context_tracker.cc b/components/performance_manager/v8_memory/v8_context_tracker.cc index 69d07b2..f37e75f 100644 --- a/components/performance_manager/v8_memory/v8_context_tracker.cc +++ b/components/performance_manager/v8_memory/v8_context_tracker.cc
@@ -407,7 +407,7 @@ graph->RemoveGraphObserver(this); } -base::Value V8ContextTracker::DescribeFrameNodeData( +base::Value::Dict V8ContextTracker::DescribeFrameNodeData( const FrameNode* node) const { DCHECK_ON_GRAPH_SEQUENCE(node->GetGraph()); @@ -419,10 +419,10 @@ base::Value::Dict dict; dict.Set("v8_context_count", static_cast<int>(v8_context_count)); - return base::Value(std::move(dict)); + return dict; } -base::Value V8ContextTracker::DescribeProcessNodeData( +base::Value::Dict V8ContextTracker::DescribeProcessNodeData( const ProcessNode* node) const { DCHECK_ON_GRAPH_SEQUENCE(node->GetGraph()); @@ -447,10 +447,10 @@ static_cast<int>(execution_context_count)); dict.Set("destroyed_execution_context_count", static_cast<int>(destroyed_execution_context_count)); - return base::Value(std::move(dict)); + return dict; } -base::Value V8ContextTracker::DescribeWorkerNodeData( +base::Value::Dict V8ContextTracker::DescribeWorkerNodeData( const WorkerNode* node) const { DCHECK_ON_GRAPH_SEQUENCE(node->GetGraph()); size_t v8_context_count = 0; @@ -461,7 +461,7 @@ base::Value::Dict dict; dict.Set("v8_context_count", static_cast<int>(v8_context_count)); - return base::Value(std::move(dict)); + return dict; } void V8ContextTracker::OnBeforeProcessNodeRemoved(const ProcessNode* node) {
diff --git a/components/performance_manager/v8_memory/v8_context_tracker.h b/components/performance_manager/v8_memory/v8_context_tracker.h index 8c3b677e..af6e69d 100644 --- a/components/performance_manager/v8_memory/v8_context_tracker.h +++ b/components/performance_manager/v8_memory/v8_context_tracker.h
@@ -218,9 +218,10 @@ // Implementation of NodeDataDescriber. We have things to say about // execution contexts (frames and workers), as well as processes. - base::Value DescribeFrameNodeData(const FrameNode* node) const final; - base::Value DescribeProcessNodeData(const ProcessNode* node) const final; - base::Value DescribeWorkerNodeData(const WorkerNode* node) const final; + base::Value::Dict DescribeFrameNodeData(const FrameNode* node) const final; + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const final; + base::Value::Dict DescribeWorkerNodeData(const WorkerNode* node) const final; // Implementation of ProcessNode::ObserverDefaultImpl. void OnBeforeProcessNodeRemoved(const ProcessNode* node) final;
diff --git a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc index c811a2d..f74cde8 100644 --- a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc +++ b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.cc
@@ -753,26 +753,26 @@ process_data->process_measurement_requests().OnOwnerUnregistered(); } -base::Value V8DetailedMemoryDecorator::DescribeFrameNodeData( +base::Value::Dict V8DetailedMemoryDecorator::DescribeFrameNodeData( const FrameNode* frame_node) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const auto* const frame_data = V8DetailedMemoryExecutionContextData::ForFrameNode(frame_node); if (!frame_data) - return base::Value(); + return base::Value::Dict(); base::Value::Dict dict; dict.Set("v8_bytes_used", static_cast<int>(frame_data->v8_bytes_used())); - return base::Value(std::move(dict)); + return dict; } -base::Value V8DetailedMemoryDecorator::DescribeProcessNodeData( +base::Value::Dict V8DetailedMemoryDecorator::DescribeProcessNodeData( const ProcessNode* process_node) const { DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); const auto* const process_data = V8DetailedMemoryProcessData::ForProcessNode(process_node); if (!process_data) - return base::Value(); + return base::Value::Dict(); DCHECK_EQ(content::PROCESS_TYPE_RENDERER, process_node->GetProcessType()); @@ -781,7 +781,7 @@ static_cast<int>(process_data->detached_v8_bytes_used())); dict.Set("shared_v8_bytes_used", static_cast<int>(process_data->shared_v8_bytes_used())); - return base::Value(std::move(dict)); + return dict; } const V8DetailedMemoryRequest* V8DetailedMemoryDecorator::GetNextRequest()
diff --git a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h index 90f1c6a0..50e96ae4 100644 --- a/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h +++ b/components/performance_manager/v8_memory/v8_detailed_memory_decorator.h
@@ -53,8 +53,9 @@ void OnBeforeProcessNodeRemoved(const ProcessNode* process_node) override; // NodeDataDescriber overrides. - base::Value DescribeFrameNodeData(const FrameNode* node) const override; - base::Value DescribeProcessNodeData(const ProcessNode* node) const override; + base::Value::Dict DescribeFrameNodeData(const FrameNode* node) const override; + base::Value::Dict DescribeProcessNodeData( + const ProcessNode* node) const override; // Returns the next measurement request that should be scheduled. const V8DetailedMemoryRequest* GetNextRequest() const;
diff --git a/components/policy/BUILD.gn b/components/policy/BUILD.gn index 0dd4bcd..8b478f9 100644 --- a/components/policy/BUILD.gn +++ b/components/policy/BUILD.gn
@@ -72,30 +72,10 @@ # and compiled. cloud_policy_proto_path = "$target_gen_dir/proto/cloud_policy.proto" -# This file is used by chrome/browser/privacy/traffic_annotation.proto as it -# needs a version without LITE_RUNTIME optimization. -cloud_policy_full_runtime_proto_path = - "$target_gen_dir/proto/cloud_policy_full_runtime.proto" - -# This protobuf contains the common definitions of the shared messages -# between user and device policies -policy_common_definitions_proto_abspath = - "//components/policy/proto/policy_common_definitions.proto" - -# This file is used by chrome/browser/privacy/traffic_annotation.proto as it -# needs a version without LITE_RUNTIME optimization. -policy_common_definitions_full_runtime_proto_path = - "$target_gen_dir/proto/policy_common_definitions_full_runtime.proto" - # This is the "full" protobuf, which defines one protobuf message per # policy. It is also the format currently used by the server. chrome_settings_proto_path = "$target_gen_dir/proto/chrome_settings.proto" -# This file is used by chrome/browser/privacy/traffic_annotation.proto as it -# needs a version without LITE_RUNTIME optimization. -chrome_settings_full_runtime_proto_path = - "$target_gen_dir/proto/chrome_settings_full_runtime.proto" - constants_header_path = "$target_gen_dir/policy_constants.h" constants_source_path = "$target_gen_dir/policy_constants.cc" app_restrictions_path = "$target_gen_dir/app_restrictions.xml" @@ -150,43 +130,6 @@ ] } -action("full_runtime_code_generate") { - script = "tools/generate_policy_source.py" - chrome_version_abspath = "//chrome/VERSION" - chrome_version_path = rebase_path(chrome_version_abspath, root_build_dir) - - deps = [ ":generate_policy_templates" ] - inputs = [ - chrome_version_abspath, - policy_templates_generated_json_path, - ] - outputs = [ - cloud_policy_full_runtime_proto_path, - chrome_settings_full_runtime_proto_path, - policy_common_definitions_full_runtime_proto_path, - ] - - args = [ - # Input information - "--chrome-version-file=" + chrome_version_path, - "--target-platform=" + target_os, - "--policy-templates-file=" + - rebase_path(policy_templates_generated_json_path, root_build_dir), - "--target-platform=" + target_os, - - # Output files to be generated - "--cloud-policy-full-runtime-protobuf=" + - rebase_path(cloud_policy_full_runtime_proto_path, root_build_dir), - "--chrome-settings-full-runtime-protobuf=" + - rebase_path(chrome_settings_full_runtime_proto_path, root_build_dir), - "--policy-common-definitions-protobuf=" + - rebase_path(policy_common_definitions_proto_abspath, root_build_dir), - "--policy-common-definitions-full-runtime-protobuf=" + - rebase_path(policy_common_definitions_full_runtime_proto_path, - root_build_dir), - ] -} - policy_templates_grd_file = "resources/policy_templates.build.grd" # Generates a single policy_templates.json with a real JSON format. @@ -385,7 +328,6 @@ defines = [ "POLICY_COMPONENT_IMPLEMENTATION" ] public_deps = [ ":cloud_policy_proto_generated_compile", - ":full_runtime_code_generate", ":policy_code_generate", "//base", "//components/policy/core/common:common_constants",
diff --git a/components/policy/core/common/async_policy_loader.cc b/components/policy/core/common/async_policy_loader.cc index f4ba4910..f22b9ada 100644 --- a/components/policy/core/common/async_policy_loader.cc +++ b/components/policy/core/common/async_policy_loader.cc
@@ -34,9 +34,9 @@ AsyncPolicyLoader::AsyncPolicyLoader( const scoped_refptr<base::SequencedTaskRunner>& task_runner, bool periodic_updates) - : task_runner_(task_runner), - management_service_(nullptr), - periodic_updates_(periodic_updates) {} + : AsyncPolicyLoader(task_runner, + /*management_service=*/nullptr, + periodic_updates) {} AsyncPolicyLoader::AsyncPolicyLoader( const scoped_refptr<base::SequencedTaskRunner>& task_runner, @@ -44,7 +44,8 @@ bool periodic_updates) : task_runner_(task_runner), management_service_(management_service), - periodic_updates_(periodic_updates) {} + periodic_updates_(periodic_updates), + reload_interval_(kReloadInterval) {} AsyncPolicyLoader::~AsyncPolicyLoader() {} @@ -98,7 +99,11 @@ update_callback_.Run(std::move(bundle)); if (periodic_updates_) { - ScheduleNextReload(kReloadInterval); + // Note: it is important to schedule the next reload after calling Load() + // to make sure that anything done in Load() that may change the state of + // the loader (e.g. changing the `reload_interval_`) is effective before + // scheduling the next reload. + ScheduleNextReload(get_reload_interval()); } } @@ -158,7 +163,7 @@ // Start periodic refreshes. if (periodic_updates_) { - ScheduleNextReload(kReloadInterval); + ScheduleNextReload(get_reload_interval()); } }
diff --git a/components/policy/core/common/async_policy_loader.h b/components/policy/core/common/async_policy_loader.h index 38a8dfa..7ee411f 100644 --- a/components/policy/core/common/async_policy_loader.h +++ b/components/policy/core/common/async_policy_loader.h
@@ -91,6 +91,12 @@ const scoped_refptr<SchemaMap>& schema_map() const { return schema_map_; } + base::TimeDelta get_reload_interval() const { return reload_interval_; } + + void set_reload_interval(base::TimeDelta reload_interval) { + reload_interval_ = reload_interval; + } + private: // Allow AsyncPolicyProvider to call Init(). friend class AsyncPolicyProvider; @@ -143,6 +149,10 @@ // The current policy schemas that this provider should load. scoped_refptr<SchemaMap> schema_map_; + // The interval of time between periodic updates. Only relevant when + // `periodic_updates_` is true to enable periodic updates. + base::TimeDelta reload_interval_; + // Used to get WeakPtrs for the periodic reload task. base::WeakPtrFactory<AsyncPolicyLoader> weak_factory_{this}; };
diff --git a/components/policy/core/common/policy_loader_ios.mm b/components/policy/core/common/policy_loader_ios.mm index 71fa0510..8e76f39 100644 --- a/components/policy/core/common/policy_loader_ios.mm +++ b/components/policy/core/common/policy_loader_ios.mm
@@ -2,34 +2,49 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "components/policy/core/common/policy_loader_ios.h" +#import "components/policy/core/common/policy_loader_ios.h" #import <Foundation/Foundation.h> -#include <stddef.h> #import <UIKit/UIKit.h> +#import <stddef.h> -#include "base/check.h" -#include "base/functional/bind.h" -#include "base/json/json_reader.h" -#include "base/location.h" +#import "base/check.h" +#import "base/functional/bind.h" +#import "base/json/json_reader.h" +#import "base/location.h" #import "base/mac/foundation_util.h" -#include "base/metrics/histogram_macros.h" -#include "base/strings/sys_string_conversions.h" +#import "base/metrics/histogram_macros.h" +#import "base/strings/sys_string_conversions.h" #import "base/task/sequenced_task_runner.h" -#include "base/task/sequenced_task_runner.h" -#include "components/policy/core/common/mac_util.h" -#include "components/policy/core/common/policy_bundle.h" +#import "base/time/time.h" +#import "components/policy/core/common/mac_util.h" +#import "components/policy/core/common/policy_bundle.h" #import "components/policy/core/common/policy_loader_ios_constants.h" -#include "components/policy/core/common/policy_map.h" -#include "components/policy/core/common/policy_namespace.h" -#include "components/policy/core/common/schema.h" -#include "components/policy/core/common/schema_registry.h" -#include "components/policy/policy_constants.h" +#import "components/policy/core/common/policy_map.h" +#import "components/policy/core/common/policy_namespace.h" +#import "components/policy/core/common/schema.h" +#import "components/policy/core/common/schema_registry.h" +#import "components/policy/policy_constants.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "This file requires ARC support." #endif +namespace { + +// Policy reload interval when the browser has platform policy key. +constexpr base::TimeDelta kManagedByPlatformReloadInterval = base::Seconds(30); + +// Returns YES if the browser has platform policy key by looking at the +// presence of the App Config key. Even if the value of the key is an empty +// dictionary, the browser will be considered as managed. +BOOL HasPlatformPolicyKey() { + return [[NSUserDefaults standardUserDefaults] + dictionaryForKey:kPolicyLoaderIOSConfigurationKey] != nil; +} + +} // namespace + namespace policy { PolicyLoaderIOS::PolicyLoaderIOS( @@ -57,6 +72,12 @@ size_t count = bundle.Get(chrome_ns).size(); UMA_HISTOGRAM_COUNTS_100("Enterprise.IOSPolicies", count); + if (HasPlatformPolicyKey()) { + // Set a shorter reload interval when the browser is managed by the + // platform. This is to take the dynamic policy updates quickly. + set_reload_interval(kManagedByPlatformReloadInterval); + } + return bundle; }
diff --git a/components/policy/core/common/policy_loader_ios_unittest.mm b/components/policy/core/common/policy_loader_ios_unittest.mm index a4e87c2..6b94309 100644 --- a/components/policy/core/common/policy_loader_ios_unittest.mm +++ b/components/policy/core/common/policy_loader_ios_unittest.mm
@@ -16,14 +16,18 @@ #import "base/task/sequenced_task_runner.h" #include "base/task/sequenced_task_runner.h" #include "base/test/test_simple_task_runner.h" +#import "base/time/time.h" #include "base/values.h" #include "components/policy/core/common/async_policy_provider.h" #include "components/policy/core/common/configuration_policy_provider_test.h" #include "components/policy/core/common/policy_bundle.h" #import "components/policy/core/common/policy_loader_ios_constants.h" #include "components/policy/core/common/policy_map.h" +#import "components/policy/core/common/policy_namespace.h" #include "components/policy/core/common/policy_test_utils.h" #include "components/policy/core/common/policy_types.h" +#include "components/policy/core/common/schema.h" +#include "components/policy/core/common/schema_registry.h" #include "testing/gtest/include/gtest/gtest.h" #include "testing/platform_test.h" @@ -202,4 +206,129 @@ ConfigurationPolicyProviderTest, testing::Values(TestHarness::CreateWithJSONEncoding)); +const char kTestChromeSchema[] = + "{" + " \"type\": \"object\"," + " \"properties\": {" + " \"StringPolicy\": { \"type\": \"string\" }," + " }" + "}"; + +PolicyNamespace GetPolicyNamespace() { + return PolicyNamespace(POLICY_DOMAIN_CHROME, ""); +} + +// Tests cases not covered by the test harnest. +class PolicyLoaderIosTest : public PlatformTest { + protected: + PolicyLoaderIosTest() + : task_environment_(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {} + + void SetUp() override { + std::string error = RegisterSchema(GetPolicyNamespace(), kTestChromeSchema); + ASSERT_TRUE(error.empty()) + << "Registration of schema failed with error: " << error; + } + + void TearDown() override { + task_environment_.RunUntilIdle(); + provider_->Shutdown(); + // Clear App Config. + [[NSUserDefaults standardUserDefaults] + removeObjectForKey:kPolicyLoaderIOSConfigurationKey]; + } + + void InitProvider() { + std::unique_ptr<PolicyLoaderIOS> loader = std::make_unique<PolicyLoaderIOS>( + &schema_registry_, task_environment_.GetMainThreadTaskRunner()); + provider_ = std::make_unique<AsyncPolicyProvider>(&schema_registry_, + std::move(loader)); + provider_->Init(&schema_registry_); + task_environment_.RunUntilIdle(); + } + + base::test::TaskEnvironment task_environment_; + SchemaRegistry schema_registry_; + std::unique_ptr<AsyncPolicyProvider> provider_; + + private: + std::string RegisterSchema(const PolicyNamespace& ns, + const std::string& schema_string) { + std::string error; + Schema schema = Schema::Parse(schema_string, &error); + if (schema.valid()) { + schema_registry_.RegisterComponent(ns, schema); + return std::string(); + } + return error; + } +}; + +TEST_F(PolicyLoaderIosTest, ReloadIntervalWhenBrowserManagedPostStartup) { + InitProvider(); + + // Verify that there are no policies loaded at startup. + EXPECT_TRUE(provider_->policies().Equals(PolicyBundle())); + + // Set a policy in the App Config at runtime to replicate the situation where + // the browser is put under management after startup. + NSDictionary* policies = @{@"StringPolicy" : @"string_value"}; + [[NSUserDefaults standardUserDefaults] + setObject:policies + forKey:kPolicyLoaderIOSConfigurationKey]; + + // Verify that the new policy changes aren't picked up after 10 minutes + // when the browser wasn't managed at startup. This is to make sure that the + // first reload was scheduled with an interval of 15 minutes. + task_environment_.FastForwardBy(base::Minutes(10)); + EXPECT_TRUE(provider_->policies().Equals(PolicyBundle())); + + // Verify that the new policy changes are picked up after 15 minutes + + // epsilon. + task_environment_.FastForwardBy(base::Minutes(5) + base::Seconds(1)); + ASSERT_TRUE(task_environment_.MainThreadIsIdle()); + PolicyBundle bundle; + bundle.Get(GetPolicyNamespace()) + .Set("StringPolicy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PLATFORM, base::Value("string_value"), nullptr); + EXPECT_TRUE(provider_->policies().Equals(bundle)); + + // Simulate the situation where the App Config is updated with new values + // before the next reload. + NSDictionary* new_policies = @{@"StringPolicy" : @"string_value_new"}; + [[NSUserDefaults standardUserDefaults] + setObject:new_policies + forKey:kPolicyLoaderIOSConfigurationKey]; + + // Verify that the interval was adjusted to 30 seconds after first reload. + task_environment_.FastForwardBy(base::Seconds(31)); + ASSERT_TRUE(task_environment_.MainThreadIsIdle()); + PolicyBundle new_bundle; + new_bundle.Get(GetPolicyNamespace()) + .Set("StringPolicy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PLATFORM, base::Value("string_value_new"), nullptr); + EXPECT_TRUE(provider_->policies().Equals(new_bundle)); +} + +TEST_F(PolicyLoaderIosTest, ReloadIntervalWhenManagedByPlatformBeforeStartup) { + // Set a policy in the App Config to replicate the situation where the browser + // is put under management before startup. + NSDictionary* policies = @{@"StringPolicy" : @"string_value"}; + [[NSUserDefaults standardUserDefaults] + setObject:policies + forKey:kPolicyLoaderIOSConfigurationKey]; + + InitProvider(); + + // Verify that the new policy changes are picked up after 30 seconds + + // epsilon. + task_environment_.FastForwardBy(base::Seconds(31)); + ASSERT_TRUE(task_environment_.MainThreadIsIdle()); + PolicyBundle bundle; + bundle.Get(GetPolicyNamespace()) + .Set("StringPolicy", POLICY_LEVEL_MANDATORY, POLICY_SCOPE_MACHINE, + POLICY_SOURCE_PLATFORM, base::Value("string_value"), nullptr); + EXPECT_TRUE(provider_->policies().Equals(bundle)); +} + } // namespace policy
diff --git a/components/policy/tools/generate_policy_source.py b/components/policy/tools/generate_policy_source.py index 2b0fac5f1..6535cc3 100755 --- a/components/policy/tools/generate_policy_source.py +++ b/components/policy/tools/generate_policy_source.py
@@ -261,34 +261,12 @@ help='generate cloud policy protobuf file', metavar='FILE') parser.add_argument( - '--cpfrp', - '--cloud-policy-full-runtime-protobuf', - dest='cloud_policy_full_runtime_proto_path', - help='generate cloud policy full runtime protobuf', - metavar='FILE') - parser.add_argument( '--csp', '--chrome-settings-protobuf', dest='chrome_settings_proto_path', help='generate chrome settings protobuf file', metavar='FILE') parser.add_argument( - '--policy-common-definitions-protobuf', - dest='policy_common_definitions_proto_path', - help='policy common definitions protobuf file path', - metavar='FILE') - parser.add_argument( - '--policy-common-definitions-full-runtime-protobuf', - dest='policy_common_definitions_full_runtime_proto_path', - help='generate policy common definitions full runtime protobuf file', - metavar='FILE') - parser.add_argument( - '--csfrp', - '--chrome-settings-full-runtime-protobuf', - dest='chrome_settings_full_runtime_proto_path', - help='generate chrome settings full runtime protobuf', - metavar='FILE') - parser.add_argument( '--ard', '--app-restrictions-definition', dest='app_restrictions_path', @@ -420,20 +398,8 @@ GenerateFile(args.risk_header_path, _WritePolicyRiskTagHeader) if args.cloud_policy_proto_path: GenerateFile(args.cloud_policy_proto_path, _WriteCloudPolicyProtobuf) - if (args.policy_common_definitions_full_runtime_proto_path and - args.policy_common_definitions_proto_path): - GenerateFile( - args.policy_common_definitions_full_runtime_proto_path, - partial(_WritePolicyCommonDefinitionsFullRuntimeProtobuf, - args.policy_common_definitions_proto_path)) - if args.cloud_policy_full_runtime_proto_path: - GenerateFile(args.cloud_policy_full_runtime_proto_path, - partial(_WriteCloudPolicyProtobuf, is_full_runtime=True)) if args.chrome_settings_proto_path: GenerateFile(args.chrome_settings_proto_path, _WriteChromeSettingsProtobuf) - if args.chrome_settings_full_runtime_proto_path: - GenerateFile(args.chrome_settings_full_runtime_proto_path, - partial(_WriteChromeSettingsProtobuf, is_full_runtime=True)) if target_platform == 'android' and args.app_restrictions_path: GenerateFile(args.app_restrictions_path, _WriteAppRestrictions, xml=True) @@ -1515,27 +1481,27 @@ CHROME_SETTINGS_PROTO_HEAD = ''' syntax = "proto2"; -{full_runtime_comment}option optimize_for = LITE_RUNTIME; +option optimize_for = LITE_RUNTIME; package enterprise_management; option go_package="chromium/policy/enterprise_management_proto"; // For StringList and PolicyOptions. -import "policy_common_definitions{full_runtime_suffix}.proto"; +import "policy_common_definitions.proto"; ''' CLOUD_POLICY_PROTO_HEAD = ''' syntax = "proto2"; -{full_runtime_comment}option optimize_for = LITE_RUNTIME; +option optimize_for = LITE_RUNTIME; package enterprise_management; option go_package="chromium/policy/enterprise_management_proto"; -import "policy_common_definitions{full_runtime_suffix}.proto"; +import "policy_common_definitions.proto"; ''' @@ -1598,20 +1564,9 @@ return (policy_id - _LAST_TOP_LEVEL_POLICY_ID - 1) % _CHUNK_SIZE + 1 -def _WriteChromeSettingsProtobuf(policies, - policy_atomic_groups, - target_platform, - f, - risk_tags, - is_full_runtime=False): - # For full runtime, disable LITE_RUNTIME switch and import full runtime - # version of policy_common_definitions.proto. - full_runtime_comment = '//' if is_full_runtime else '' - full_runtime_suffix = '_full_runtime' if is_full_runtime else '' - f.write( - CHROME_SETTINGS_PROTO_HEAD.format( - full_runtime_comment=full_runtime_comment, - full_runtime_suffix=full_runtime_suffix)) +def _WriteChromeSettingsProtobuf(policies, policy_atomic_groups, + target_platform, f, risk_tags): + f.write(CHROME_SETTINGS_PROTO_HEAD) fields = defaultdict(list) f.write('// PBs for individual settings.\n\n') for policy in policies: @@ -1656,19 +1611,9 @@ f.write('}\n') -def _WriteCloudPolicyProtobuf(policies, - policy_atomic_groups, - target_platform, - f, - risk_tags, - is_full_runtime=False): - # For full runtime, disable LITE_RUNTIME switch and import full runtime - # version of policy_common_definitions.proto. - full_runtime_comment = '//' if is_full_runtime else '' - full_runtime_suffix = '_full_runtime' if is_full_runtime else '' - f.write( - CLOUD_POLICY_PROTO_HEAD.format(full_runtime_comment=full_runtime_comment, - full_runtime_suffix=full_runtime_suffix)) +def _WriteCloudPolicyProtobuf(policies, policy_atomic_groups, target_platform, + f, risk_tags): + f.write(CLOUD_POLICY_PROTO_HEAD) fields = defaultdict(list) @@ -1707,18 +1652,6 @@ f.write('}\n') -def _WritePolicyCommonDefinitionsFullRuntimeProtobuf( - policy_common_definitions_proto_path, policies, policy_atomic_groups, - target_platform, f, risk_tags): - # For full runtime, disable LITE_RUNTIME switch - with open(policy_common_definitions_proto_path, 'r') as proto_file: - policy_common_definitions_proto_code = proto_file.read() - f.write( - policy_common_definitions_proto_code.replace( - "option optimize_for = LITE_RUNTIME;", - "//option optimize_for = LITE_RUNTIME;")) - - #------------------ Chrome OS policy constants header --------------# # This code applies to Active Directory management only.
diff --git a/components/policy/tools/generate_policy_source_test.py b/components/policy/tools/generate_policy_source_test.py index 9d5c1e1..eaf483e 100755 --- a/components/policy/tools/generate_policy_source_test.py +++ b/components/policy/tools/generate_policy_source_test.py
@@ -304,62 +304,32 @@ self.assertEqual(expected_output.strip(), actual_output.strip()) def testWriteCloudPolicyProtobuf(self): - is_full_runtime_values = [False, True] output_path = 'mock_cloud_policy_proto' - for is_full_runtime in is_full_runtime_values: - with patch('codecs.open', mock_open()) as mocked_file: - with codecs.open(output_path, 'w', encoding='utf-8') as f: - generate_policy_source._WriteCloudPolicyProtobuf( - self.policies, - self.policy_atomic_groups, - self.target_platform, - f, - self.risk_tags, - is_full_runtime=is_full_runtime) + with patch('codecs.open', mock_open()) as mocked_file: + with codecs.open(output_path, 'w', encoding='utf-8') as f: + generate_policy_source._WriteCloudPolicyProtobuf( + self.policies, self.policy_atomic_groups, self.target_platform, f, + self.risk_tags) - full_runtime_comment = '//' if is_full_runtime else '' - full_runtime_suffix = '_full_runtime' if is_full_runtime else '' + mocked_file.assert_called_once_with(output_path, 'w', encoding='utf-8') - with self.subTest(is_full_runtime=is_full_runtime): - mocked_file.assert_called_once_with(output_path, 'w', encoding='utf-8') - - expected_formatted = test_data.EXPECTED_CLOUD_POLICY_PROTOBUF % { - "full_runtime_comment": full_runtime_comment, - "full_runtime_suffix": full_runtime_suffix, - } - - self._assertCallsEqual(expected_formatted, - mocked_file().write.call_args_list) + self._assertCallsEqual(test_data.EXPECTED_CLOUD_POLICY_PROTOBUF, + mocked_file().write.call_args_list) def testWriteChromeSettingsProtobuf(self): - is_full_runtime_values = [False, True] output_path = 'mock_chrome_settings_proto' - for is_full_runtime in is_full_runtime_values: - with patch('codecs.open', mock_open()) as mocked_file: - with codecs.open(output_path, 'w', encoding='utf-8') as f: - generate_policy_source._WriteChromeSettingsProtobuf( - self.policies, - self.policy_atomic_groups, - self.target_platform, - f, - self.risk_tags, - is_full_runtime=is_full_runtime) + with patch('codecs.open', mock_open()) as mocked_file: + with codecs.open(output_path, 'w', encoding='utf-8') as f: + generate_policy_source._WriteChromeSettingsProtobuf( + self.policies, self.policy_atomic_groups, self.target_platform, f, + self.risk_tags) - full_runtime_comment = '//' if is_full_runtime else '' - full_runtime_suffix = '_full_runtime' if is_full_runtime else '' + mocked_file.assert_called_once_with(output_path, 'w', encoding='utf-8') - with self.subTest(is_full_runtime=is_full_runtime): - mocked_file.assert_called_once_with(output_path, 'w', encoding='utf-8') - - expected_formatted = test_data.EXPECTED_CHROME_SETTINGS_PROTOBUF % { - "full_runtime_comment": full_runtime_comment, - "full_runtime_suffix": full_runtime_suffix, - } - - self._assertCallsEqual(expected_formatted, - mocked_file().write.call_args_list) + self._assertCallsEqual(test_data.EXPECTED_CHROME_SETTINGS_PROTOBUF, + mocked_file().write.call_args_list) def testWritePolicyProto(self): output_path = 'mock_write_policy_proto'
diff --git a/components/policy/tools/generate_policy_source_test_data.py b/components/policy/tools/generate_policy_source_test_data.py index 4ffb6b5..430dd7e 100644 --- a/components/policy/tools/generate_policy_source_test_data.py +++ b/components/policy/tools/generate_policy_source_test_data.py
@@ -10,13 +10,13 @@ EXPECTED_CLOUD_POLICY_PROTOBUF = ''' syntax = "proto2"; -%(full_runtime_comment)soption optimize_for = LITE_RUNTIME; +option optimize_for = LITE_RUNTIME; package enterprise_management; option go_package="chromium/policy/enterprise_management_proto"; -import "policy_common_definitions%(full_runtime_suffix)s.proto"; +import "policy_common_definitions.proto"; message CloudPolicySubProto1 { optional BooleanPolicyProto ChunkOneFirstFieldBooleanPolicy = 1; @@ -45,14 +45,14 @@ EXPECTED_CHROME_SETTINGS_PROTOBUF = """ syntax = "proto2"; -%(full_runtime_comment)soption optimize_for = LITE_RUNTIME; +option optimize_for = LITE_RUNTIME; package enterprise_management; option go_package="chromium/policy/enterprise_management_proto"; // For StringList and PolicyOptions. -import "policy_common_definitions%(full_runtime_suffix)s.proto"; +import "policy_common_definitions.proto"; // PBs for individual settings.
diff --git a/components/viz/common/quads/render_pass_io.cc b/components/viz/common/quads/render_pass_io.cc index 7ea951a..74d574da 100644 --- a/components/viz/common/quads/render_pass_io.cc +++ b/components/viz/common/quads/render_pass_io.cc
@@ -496,8 +496,7 @@ std::string PaintFilterToString(const sk_sp<cc::PaintFilter>& filter) { // TODO(zmo): Expand to readable fields. Such recorded data becomes invalid // when we update any data structure. - std::vector<uint8_t> buffer(cc::PaintOpWriter::HeaderBytes() + - cc::PaintFilter::GetFilterSize(filter.get())); + std::vector<uint8_t> buffer(cc::PaintOpWriter::SerializedSize(filter.get())); // No need to populate the SerializeOptions here since the security // constraints explicitly disable serializing images using the transfer cache // and serialization of PaintRecords.
diff --git a/components/viz/service/display/dc_layer_overlay.cc b/components/viz/service/display/dc_layer_overlay.cc index ec3cd8a..35de646 100644 --- a/components/viz/service/display/dc_layer_overlay.cc +++ b/components/viz/service/display/dc_layer_overlay.cc
@@ -131,15 +131,20 @@ void FromYUVQuad(const YUVVideoDrawQuad* quad, const gfx::Transform& transform_to_root_target, - DCLayerOverlayCandidate* dc_layer) { + OverlayCandidate* dc_layer) { // Direct composition path only supports a single NV12 buffer. DCHECK(quad->y_plane_resource_id() && quad->u_plane_resource_id()); DCHECK_EQ(quad->u_plane_resource_id(), quad->v_plane_resource_id()); dc_layer->resource_id = quad->y_plane_resource_id(); - dc_layer->z_order = 1; - dc_layer->content_rect = gfx::ToNearestRect(quad->ya_tex_coord_rect()); - dc_layer->quad_rect = quad->rect; + dc_layer->plane_z_order = 1; + dc_layer->display_rect = gfx::RectF(quad->rect); + dc_layer->resource_size_in_pixels = quad->ya_tex_size(); + dc_layer->uv_rect = + gfx::ScaleRect(quad->ya_tex_coord_rect(), + 1.f / dc_layer->resource_size_in_pixels.width(), + 1.f / dc_layer->resource_size_in_pixels.height()); + // Quad rect is in quad content space so both quad to target, and target to // root transforms must be applied to it. gfx::Transform quad_to_root_transform( @@ -191,17 +196,20 @@ void FromTextureQuad(const TextureDrawQuad* quad, const gfx::Transform& transform_to_root_target, - DCLayerOverlayCandidate* dc_layer) { + OverlayCandidate* dc_layer) { dc_layer->resource_id = quad->resource_id(); - dc_layer->z_order = 1; - dc_layer->content_rect = gfx::Rect(quad->resource_size_in_pixels()); - dc_layer->quad_rect = quad->rect; + dc_layer->plane_z_order = 1; + dc_layer->resource_size_in_pixels = quad->resource_size_in_pixels(); + dc_layer->uv_rect = + gfx::BoundingRect(quad->uv_top_left, quad->uv_bottom_right); + dc_layer->display_rect = gfx::RectF(quad->rect); // Quad rect is in quad content space so both quad to target, and target to // root transforms must be applied to it. gfx::Transform quad_to_root_transform; if (quad->y_flipped) { quad_to_root_transform.Scale(1.0, -1.0); - quad_to_root_transform.PostTranslate(0.0, dc_layer->content_rect.height()); + quad_to_root_transform.PostTranslate( + 0.0, dc_layer->resource_size_in_pixels.height()); } quad_to_root_transform.PostConcat( quad->shared_quad_state->quad_to_target_transform); @@ -413,15 +421,14 @@ } // This function records the damage rect rect of the current frame. -void RecordOverlayHistograms( - std::vector<DCLayerOverlayCandidate>* dc_layer_overlays, - bool has_occluding_surface_damage, - const gfx::Rect* damage_rect) { +void RecordOverlayHistograms(OverlayCandidateList* dc_layer_overlays, + bool has_occluding_surface_damage, + const gfx::Rect* damage_rect) { // If an underlay is found, we record the damage rect of this frame as an // underlay. bool is_overlay = true; for (const auto& dc_layer : *dc_layer_overlays) { - if (dc_layer.z_order != 1) { + if (dc_layer.plane_z_order != 1) { is_overlay = false; break; } @@ -464,13 +471,6 @@ } // namespace -DCLayerOverlayCandidate::DCLayerOverlayCandidate() = default; -DCLayerOverlayCandidate::DCLayerOverlayCandidate( - const DCLayerOverlayCandidate& other) = default; -DCLayerOverlayCandidate& DCLayerOverlayCandidate::operator=( - const DCLayerOverlayCandidate& other) = default; -DCLayerOverlayCandidate::~DCLayerOverlayCandidate() = default; - DCLayerOverlayProcessor::DCLayerOverlayProcessor( const DebugRendererSettings* debug_settings, int allowed_yuv_overlay_count, @@ -604,7 +604,7 @@ } void DCLayerOverlayProcessor::InsertDebugBorderDrawQuad( - const std::vector<DCLayerOverlayCandidate>* dc_layer_overlays, + const OverlayCandidateList* dc_layer_overlays, AggregatedRenderPass* render_pass, const gfx::RectF& display_rect, gfx::Rect* damage_rect) { @@ -627,13 +627,14 @@ // Add debug borders for overlays/underlays for (const auto& dc_layer : *dc_layer_overlays) { - gfx::Rect overlay_rect = dc_layer.transform.MapRect(dc_layer.quad_rect); + gfx::Rect overlay_rect = gfx::ToEnclosingRect( + OverlayCandidate::DisplayRectInTargetSpace(dc_layer)); if (dc_layer.clip_rect) overlay_rect.Intersect(*dc_layer.clip_rect); // Overlay:red, Underlay:blue. SkColor4f border_color = - dc_layer.z_order > 0 ? SkColors::kRed : SkColors::kBlue; + dc_layer.plane_z_order > 0 ? SkColors::kRed : SkColors::kBlue; auto it = quad_list.InsertBeforeAndInvalidateAllPointers<DebugBorderDrawQuad>( quad_list.begin(), 1u); @@ -722,7 +723,7 @@ AggregatedRenderPass* render_pass, gfx::Rect* damage_rect, SurfaceDamageRectList surface_damage_rect_list, - std::vector<DCLayerOverlayCandidate>* dc_layer_overlays, + OverlayCandidateList* dc_layer_overlays, bool is_video_capture_enabled, bool is_page_fullscreen_mode) { bool this_frame_has_occluding_damage_rect = false; @@ -1043,12 +1044,12 @@ QuadList::Iterator* new_it, size_t* new_index, gfx::Rect* damage_rect, - std::vector<DCLayerOverlayCandidate>* dc_layer_overlays, + OverlayCandidateList* dc_layer_overlays, bool is_page_fullscreen_mode) { // Record the result first before ProcessForOverlay(). RecordDCLayerResult(DC_LAYER_SUCCESS, it); - DCLayerOverlayCandidate dc_layer; + OverlayCandidate dc_layer; dc_layer.is_video_fullscreen_letterboxing = is_page_fullscreen_mode ? IsFullScreenLetterboxing(it, render_pass->quad_list.end(), @@ -1112,11 +1113,11 @@ const QuadList::Iterator& it, size_t processed_overlay_count, gfx::Rect* damage_rect, - DCLayerOverlayCandidate* dc_layer) { + OverlayCandidate* dc_layer) { // Assign decreasing z-order so that underlays processed earlier, and hence // which are above the subsequent underlays, are placed above in the direct // composition visual tree. - dc_layer->z_order = -1 - processed_overlay_count; + dc_layer->plane_z_order = -1 - processed_overlay_count; // If the video is translucent and uses SrcOver blend mode, we can achieve the // same result as compositing with video on top if we replace video quad with
diff --git a/components/viz/service/display/dc_layer_overlay.h b/components/viz/service/display/dc_layer_overlay.h index c05e0dd5..5e74d7f 100644 --- a/components/viz/service/display/dc_layer_overlay.h +++ b/components/viz/service/display/dc_layer_overlay.h
@@ -12,6 +12,7 @@ #include "base/threading/thread_checker.h" #include "components/viz/common/quads/aggregated_render_pass.h" #include "components/viz/service/display/aggregated_frame.h" +#include "components/viz/service/display/overlay_candidate.h" #include "components/viz/service/viz_service_export.h" #include "gpu/command_buffer/common/mailbox.h" #include "third_party/skia/include/core/SkColor.h" @@ -24,54 +25,6 @@ struct DebugRendererSettings; class DisplayResourceProvider; -// TODO(weiliangc): Eventually fold this into OverlayProcessorWin and -// OverlayCandidate class. -// Holds all information necessary to construct a direct composition overlay -// from a DrawQuad. -class VIZ_SERVICE_EXPORT DCLayerOverlayCandidate { - public: - DCLayerOverlayCandidate(); - DCLayerOverlayCandidate(const DCLayerOverlayCandidate& other); - DCLayerOverlayCandidate& operator=(const DCLayerOverlayCandidate& other); - ~DCLayerOverlayCandidate(); - - // Resource id for a single NV12 image or a swap chain image. See - // DCLayerOverlayImage for details. - ResourceId resource_id = kInvalidResourceId; - - // Mailbox corresponding to |resource_id|. This is populated in SkiaRenderer - // for accessing the textures on the GPU thread. - gpu::Mailbox mailbox; - - // Stacking order relative to backbuffer which has z-order 0. - int z_order = 1; - - // What part of the content to display in pixels. - gfx::Rect content_rect; - - // Bounds of the overlay in pre-transform space. - gfx::Rect quad_rect; - - // 2D flattened transform that maps |quad_rect| to root target space, - // after applying the |quad_rect.origin()| as an offset. - gfx::Transform transform; - - // If |clip_rect| is present, then clip to it in root target space. - absl::optional<gfx::Rect> clip_rect; - - // This is the color-space the texture should be displayed as. If invalid, - // then the default for the texture should be used. For YUV textures, that's - // normally BT.709. - gfx::ColorSpace color_space; - - gfx::ProtectedVideoType protected_video_type = - gfx::ProtectedVideoType::kClear; - - gfx::HDRMetadata hdr_metadata; - - bool is_video_fullscreen_letterboxing = false; -}; - class VIZ_SERVICE_EXPORT DCLayerOverlayProcessor final : public gl::DirectCompositionOverlayCapsObserver { public: @@ -97,7 +50,7 @@ AggregatedRenderPass* render_pass, gfx::Rect* damage_rect, SurfaceDamageRectList surface_damage_rect_list, - std::vector<DCLayerOverlayCandidate>* dc_layer_overlays, + OverlayCandidateList* dc_layer_overlays, bool is_video_capture_enabled, bool is_page_fullscreen_mode); void ClearOverlayState(); @@ -121,17 +74,16 @@ // UpdateDCLayerOverlays() adds the quad at |it| to the overlay list // |dc_layer_overlays|. - void UpdateDCLayerOverlays( - const gfx::RectF& display_rect, - AggregatedRenderPass* render_pass, - const QuadList::Iterator& it, - const gfx::Rect& quad_rectangle_in_root_space, - bool is_overlay, - QuadList::Iterator* new_it, - size_t* new_index, - gfx::Rect* damage_rect, - std::vector<DCLayerOverlayCandidate>* dc_layer_overlays, - bool is_page_fullscreen_mode); + void UpdateDCLayerOverlays(const gfx::RectF& display_rect, + AggregatedRenderPass* render_pass, + const QuadList::Iterator& it, + const gfx::Rect& quad_rectangle_in_root_space, + bool is_overlay, + QuadList::Iterator* new_it, + size_t* new_index, + gfx::Rect* damage_rect, + OverlayCandidateList* dc_layer_overlays, + bool is_page_fullscreen_mode); // Returns an iterator to the element after |it|. QuadList::Iterator ProcessForOverlay(const gfx::RectF& display_rect, @@ -143,18 +95,17 @@ const QuadList::Iterator& it, size_t processed_overlay_count, gfx::Rect* damage_rect, - DCLayerOverlayCandidate* dc_layer); + OverlayCandidate* dc_layer); void UpdateRootDamageRect(const gfx::RectF& display_rect, gfx::Rect* damage_rect); void RemoveOverlayDamageRect(const QuadList::Iterator& it); - void InsertDebugBorderDrawQuad( - const std::vector<DCLayerOverlayCandidate>* dc_layer_overlays, - AggregatedRenderPass* render_pass, - const gfx::RectF& display_rect, - gfx::Rect* damage_rect); + void InsertDebugBorderDrawQuad(const OverlayCandidateList* dc_layer_overlays, + AggregatedRenderPass* render_pass, + const gfx::RectF& display_rect, + gfx::Rect* damage_rect); bool IsPreviousFrameUnderlayRect(const gfx::Rect& quad_rectangle, size_t index);
diff --git a/components/viz/service/display/overlay_candidate.h b/components/viz/service/display/overlay_candidate.h index 8fd734b1..e55a000b 100644 --- a/components/viz/service/display/overlay_candidate.h +++ b/components/viz/service/display/overlay_candidate.h
@@ -26,6 +26,7 @@ #include "ui/gfx/hdr_metadata.h" #include "ui/gfx/overlay_priority_hint.h" #include "ui/gfx/overlay_transform.h" +#include "ui/gfx/video_types.h" namespace gfx { class Rect; @@ -131,6 +132,13 @@ // Mailbox from resource_id. It is used by SkiaRenderer. gpu::Mailbox mailbox; +#if BUILDFLAG(IS_WIN) + gfx::ProtectedVideoType protected_video_type = + gfx::ProtectedVideoType::kClear; + + bool is_video_fullscreen_letterboxing = false; +#endif + #if BUILDFLAG(IS_ANDROID) // For candidates from TextureDrawQuads with is_stream_video set to true, this // records whether the quad is marked as being backed by a SurfaceTexture or
diff --git a/components/viz/service/display/overlay_dc_unittest.cc b/components/viz/service/display/overlay_dc_unittest.cc index a3ff967..994a3a8 100644 --- a/components/viz/service/display/overlay_dc_unittest.cc +++ b/components/viz/service/display/overlay_dc_unittest.cc
@@ -29,6 +29,7 @@ #include "components/viz/service/display/output_surface.h" #include "components/viz/service/display/output_surface_client.h" #include "components/viz/service/display/output_surface_frame.h" +#include "components/viz/service/display/overlay_candidate.h" #include "components/viz/service/display/overlay_processor_win.h" #include "components/viz/test/fake_skia_output_surface.h" #include "components/viz/test/test_context_provider.h" @@ -262,7 +263,7 @@ video_quad->rect = gfx::Rect(0, 0, 10, 10) + video_rect_offset; video_quad->visible_rect = gfx::Rect(0, 0, 10, 10) + video_rect_offset; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; @@ -321,8 +322,7 @@ auto* first_video_quad = CreateFullscreenCandidateYUVVideoQuad( resource_provider_.get(), child_resource_provider_.get(), child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); - // Set the protected video flag will force DCLayerOverlayCandidate to use hw - // overlay + // Set the protected video flag will force the quad to use hw overlay first_video_quad->protected_video_type = gfx::ProtectedVideoType::kHardwareProtected; @@ -332,14 +332,13 @@ auto* second_video_quad = CreateFullscreenCandidateYUVVideoQuad( resource_provider_.get(), child_resource_provider_.get(), child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); - // Set the protected video flag will force DCLayerOverlayCandidate to use hw - // overlay + // Set the protected video flag will force the quad to use hw overlay second_video_quad->protected_video_type = gfx::ProtectedVideoType::kHardwareProtected; second_video_quad->rect.set_origin(gfx::Point(2, 2)); second_video_quad->visible_rect.set_origin(gfx::Point(2, 2)); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(1, 1, 10, 10); @@ -355,8 +354,8 @@ &damage_rect_, &content_bounds_); EXPECT_EQ(2U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.front().z_order); - EXPECT_EQ(-2, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.front().plane_z_order); + EXPECT_EQ(-2, dc_layer_list.back().plane_z_order); // Entire underlay rect must be redrawn. EXPECT_EQ(gfx::Rect(0, 0, 256, 256), damage_rect_); } @@ -374,8 +373,7 @@ auto* video_quad = CreateFullscreenCandidateYUVVideoQuad( resource_provider_.get(), child_resource_provider_.get(), child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); - // Set the protected video flag will force DCLayerOverlayCandidate to use hw - // overlay + // Set the protected video flag will force the quad to use hw overlay video_quad->protected_video_type = gfx::ProtectedVideoType::kHardwareProtected; @@ -390,7 +388,7 @@ second_video_quad->rect.set_origin(gfx::Point(2, 2)); second_video_quad->visible_rect.set_origin(gfx::Point(2, 2)); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(1, 1, 10, 10); @@ -406,8 +404,8 @@ &damage_rect_, &content_bounds_); EXPECT_EQ(2U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.front().z_order); - EXPECT_EQ(-2, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.front().plane_z_order); + EXPECT_EQ(-2, dc_layer_list.back().plane_z_order); // The underlay rectangle is the same, so the damage for first video quad is // contained within the combined occluding rects for this and the last @@ -440,7 +438,7 @@ video_quad->rect = gfx::Rect(0, 0, 200, 200); video_quad->visible_rect = video_quad->rect; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; // Damage rect fully outside video quad @@ -456,7 +454,7 @@ std::move(surface_damage_rect_list), nullptr, &dc_layer_list, &damage_rect_, &content_bounds_); EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.back().plane_z_order); // All rects must be redrawn at the first frame. EXPECT_EQ(gfx::Rect(0, 0, 230, 230), damage_rect_); } @@ -483,7 +481,7 @@ video_quad->rect = gfx::Rect(0, 0, 200, 200); video_quad->visible_rect = video_quad->rect; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; // Damage rect fully outside video quad @@ -499,7 +497,7 @@ std::move(surface_damage_rect_list), nullptr, &dc_layer_list, &damage_rect_, &content_bounds_); EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.back().plane_z_order); // Only the non-overlay damaged rect need to be drawn by the gl compositor EXPECT_EQ(gfx::Rect(210, 210, 20, 20), damage_rect_); } @@ -514,7 +512,7 @@ resource_provider_.get(), child_resource_provider_.get(), child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(1, 1, 10, 10); @@ -528,7 +526,7 @@ std::move(surface_damage_rect_list), nullptr, &dc_layer_list, &damage_rect_, &content_bounds_); EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(1, dc_layer_list.back().z_order); + EXPECT_EQ(1, dc_layer_list.back().plane_z_order); // Damage rect should be unchanged on initial frame because of resize, but // should be empty on the second frame because everything was put in a // layer. @@ -560,7 +558,7 @@ // Clipped rect shouldn't be overlapped by clipped opaque quad rect. shared_state->clip_rect = gfx::Rect(0, 0, 100, 3); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; AggregatedRenderPassList pass_list; @@ -577,7 +575,7 @@ EXPECT_EQ(1U, dc_layer_list.size()); // Because of clip rects the overlay isn't occluded and shouldn't be an // underlay. - EXPECT_EQ(1, dc_layer_list.back().z_order); + EXPECT_EQ(1, dc_layer_list.back().plane_z_order); EXPECT_EQ(gfx::Rect(0, 0, 100, 3), dc_layer_list.back().clip_rect); if (i == 1) { // The damage rect should only contain contents that aren't in the @@ -599,7 +597,7 @@ child_provider_.get(), pass->shared_quad_state_list.back(), pass.get()); pass->shared_quad_state_list.back()->opacity = 0.5f; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(1, 1, 10, 10); @@ -613,7 +611,7 @@ std::move(surface_damage_rect_list), nullptr, &dc_layer_list, &damage_rect_, &content_bounds_); EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(1, dc_layer_list.back().z_order); + EXPECT_EQ(1, dc_layer_list.back().plane_z_order); // Quad isn't opaque, so underlying damage must remain the same. EXPECT_EQ(gfx::Rect(1, 1, 10, 10), damage_rect_); } @@ -633,7 +631,7 @@ resource_provider_.get(), child_resource_provider_.get(), child_provider_.get(), shared_state, pass.get()); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; AggregatedRenderPassList pass_list; @@ -654,7 +652,7 @@ std::move(surface_damage_rect_list), nullptr, &dc_layer_list, &damage_rect_, &content_bounds_); EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.back().plane_z_order); // Damage rect should be unchanged on initial frame, but should be reduced // to the size of quad on top, and empty on the third frame. if (i == 0) @@ -684,7 +682,7 @@ pass->shared_quad_state_list.back()->mask_filter_info = gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(0.f, 0.f, 20.f, 30.f), 5.f)); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(0, 0, 256, 256); @@ -706,7 +704,7 @@ // The video should be forced to an underlay mode, even there is nothing on // top. EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.back().plane_z_order); // Check whether there is a replaced quad in the quad list. EXPECT_EQ(1U, root_pass->quad_list.size()); @@ -742,7 +740,7 @@ pass->shared_quad_state_list.back()->mask_filter_info = gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(0.f, 0.f, 20.f, 30.f), 5.f)); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(0, 0, 256, 256); @@ -763,7 +761,7 @@ // still in an underlay mode. EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.back().plane_z_order); // Check whether the red quad on top and the replacedment of the YUV quad // are still in the render pass. @@ -800,7 +798,7 @@ pass->shared_quad_state_list.back()->mask_filter_info = gfx::MaskFilterInfo(gfx::RRectF(gfx::RectF(0.f, 0.f, 20.f, 30.f), 5.f)); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(0, 0, 256, 256); @@ -821,7 +819,7 @@ // still in an underlay mode. EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(-1, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.back().plane_z_order); // Check whether the red quad on top and the replacedment of the YUV quad // are still in the render pass. @@ -867,7 +865,7 @@ second_video_quad->visible_rect = second_rect; pass->shared_quad_state_list.back()->overlay_damage_index = 2; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(0, 0, 220, 220); @@ -910,7 +908,7 @@ AggregatedRenderPassList pass_list; pass_list.push_back(std::move(pass)); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; SurfaceDamageRectList surface_damage_rect_list; @@ -933,7 +931,7 @@ &damage_rect_, &content_bounds_); EXPECT_EQ(1U, dc_layer_list.size()); - EXPECT_EQ(1, dc_layer_list.back().z_order); + EXPECT_EQ(1, dc_layer_list.back().plane_z_order); EXPECT_EQ(damage_rect_, expected_damage); Mock::VerifyAndClearExpectations(output_surface_.get()); @@ -948,7 +946,7 @@ quad->SetNew(pass->CreateAndAppendSharedQuadState(), damage_rect_, damage_rect_, SkColors::kRed, false); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; @@ -1029,7 +1027,7 @@ // 100, 100). pass->output_rect = gfx::Rect(0, 0, 512, 512); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; render_pass_filters[filter_render_pass_id] = &blur_filter; @@ -1050,7 +1048,7 @@ EXPECT_EQ(1U, dc_layer_list.size()); // Make sure the video is in an underlay mode if the overlay quad intersects // with (rpdq->rect + MaximumPixelMovement()). - EXPECT_EQ(-1, dc_layer_list.back().z_order); + EXPECT_EQ(-1, dc_layer_list.back().plane_z_order); EXPECT_EQ(gfx::Rect(0, 0, 360, 360), damage_rect_); } @@ -1099,7 +1097,7 @@ // 100, 100). pass->output_rect = gfx::Rect(0, 0, 512, 512); - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; render_pass_backdrop_filters[backdrop_filter_render_pass_id] = @@ -1145,7 +1143,7 @@ video_quad->visible_rect = rect; pass->shared_quad_state_list.back()->overlay_damage_index = 1; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(0, 0, 256, 256); @@ -1183,7 +1181,7 @@ video_quad->visible_rect = rect; pass->shared_quad_state_list.back()->overlay_damage_index = 0; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + OverlayCandidateList dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; damage_rect_ = gfx::Rect(0, 0, 256, 256); @@ -1252,7 +1250,7 @@ video_quad->rect = gfx::Rect(kVideoRect); video_quad->visible_rect = video_quad->rect; - std::vector<DCLayerOverlayCandidate> dc_layer_list; + std::vector<OverlayCandidate> dc_layer_list; OverlayProcessorInterface::FilterOperationsMap render_pass_filters; OverlayProcessorInterface::FilterOperationsMap render_pass_backdrop_filters; AggregatedRenderPassList pass_list; @@ -1268,11 +1266,14 @@ LOG(INFO) << damage_rect_.ToString(); EXPECT_EQ(dc_layer_list.size(), 1u); - EXPECT_EQ(dc_layer_list[0].transform, kRenderPassToRootTransform); + EXPECT_TRUE( + absl::holds_alternative<gfx::Transform>(dc_layer_list[0].transform)); + EXPECT_EQ(absl::get<gfx::Transform>(dc_layer_list[0].transform), + kRenderPassToRootTransform); if (is_overlay) { - EXPECT_GT(dc_layer_list[0].z_order, 0); + EXPECT_GT(dc_layer_list[0].plane_z_order, 0); } else { - EXPECT_LT(dc_layer_list[0].z_order, 0); + EXPECT_LT(dc_layer_list[0].plane_z_order, 0); } if (frame == 0) {
diff --git a/components/viz/service/display/overlay_processor_interface.h b/components/viz/service/display/overlay_processor_interface.h index 41ccab8..0c5b20a7 100644 --- a/components/viz/service/display/overlay_processor_interface.h +++ b/components/viz/service/display/overlay_processor_interface.h
@@ -52,9 +52,6 @@ #if BUILDFLAG(IS_APPLE) using PlatformOverlayCandidate = CALayerOverlay; using CandidateList = CALayerOverlayList; -#elif BUILDFLAG(IS_WIN) - using PlatformOverlayCandidate = DCLayerOverlayCandidate; - using CandidateList = std::vector<DCLayerOverlayCandidate>; #else // Default. using PlatformOverlayCandidate = OverlayCandidate; @@ -66,8 +63,7 @@ virtual bool DisableSplittingQuads() const; - // Used by Window's DCLayerOverlayCandidate system and - // OverlayProcessorUsingStrategy. + // Used by DCLayerOverlayProcessor and OverlayProcessorUsingStrategy. static void RecordOverlayDamageRectHistograms( bool is_overlay, bool has_occluding_surface_damage,
diff --git a/components/viz/service/display/overlay_processor_on_gpu.h b/components/viz/service/display/overlay_processor_on_gpu.h index 3be8131..2dd7527 100644 --- a/components/viz/service/display/overlay_processor_on_gpu.h +++ b/components/viz/service/display/overlay_processor_on_gpu.h
@@ -34,8 +34,6 @@ public: #if BUILDFLAG(IS_APPLE) using CandidateList = CALayerOverlayList; -#elif BUILDFLAG(IS_WIN) - using CandidateList = std::vector<DCLayerOverlayCandidate>; #else // Default. using CandidateList = OverlayCandidateList;
diff --git a/components/viz/service/display/overlay_processor_win.h b/components/viz/service/display/overlay_processor_win.h index bf6c971..65f4fd2 100644 --- a/components/viz/service/display/overlay_processor_win.h +++ b/components/viz/service/display/overlay_processor_win.h
@@ -26,8 +26,6 @@ class VIZ_SERVICE_EXPORT OverlayProcessorWin : public OverlayProcessorInterface { public: - using CandidateList = std::vector<DCLayerOverlayCandidate>; - OverlayProcessorWin( OutputSurface* output_surface, std::unique_ptr<DCLayerOverlayProcessor> dc_layer_overlay_processor); @@ -65,7 +63,7 @@ const FilterOperationsMap& render_pass_backdrop_filters, SurfaceDamageRectList surface_damage_rect_list, OutputSurfaceOverlayPlane* output_surface_plane, - CandidateList* overlay_candidates, + OverlayCandidateList* overlay_candidates, gfx::Rect* damage_rect, std::vector<gfx::Rect>* content_bounds) override;
diff --git a/components/viz/service/display/skia_output_surface.h b/components/viz/service/display/skia_output_surface.h index 880530a..a29f5710a 100644 --- a/components/viz/service/display/skia_output_surface.h +++ b/components/viz/service/display/skia_output_surface.h
@@ -55,8 +55,6 @@ using OverlayList = std::vector<OverlayCandidate>; #elif BUILDFLAG(IS_APPLE) using OverlayList = CALayerOverlayList; -#elif BUILDFLAG(IS_WIN) - using OverlayList = std::vector<DCLayerOverlayCandidate>; #elif BUILDFLAG(IS_OZONE) using OverlayList = std::vector<OverlayCandidate>; #else
diff --git a/components/viz/service/display/skia_renderer.cc b/components/viz/service/display/skia_renderer.cc index 3e954bc..875f183 100644 --- a/components/viz/service/display/skia_renderer.cc +++ b/components/viz/service/display/skia_renderer.cc
@@ -2662,11 +2662,8 @@ DCHECK(output_surface_->capabilities().supports_surfaceless); #endif -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) - // CrOS and Android SurfaceControl use this code path. Android classic has - // switched over to OverlayProcessor. - // TODO(weiliangc): Remove this when CrOS and Android SurfaceControl switch - // to OverlayProcessor as well. +#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_WIN) + // CrOS, Android SurfaceControl, and Windows use this code path. for (auto& overlay : current_frame()->overlay_list) { if (overlay.is_root_render_pass) { continue; @@ -2683,26 +2680,6 @@ overlay.mailbox = lock.mailbox(); DCHECK(!overlay.mailbox.IsZero()); } -#elif BUILDFLAG(IS_WIN) - for (auto& dc_layer_overlay : current_frame()->overlay_list) { - ResourceId resource_id = dc_layer_overlay.resource_id; - if (resource_id == kInvalidResourceId) { - continue; - } - - // Resources will be unlocked after the next SwapBuffers() is completed. - locks.emplace_back(resource_provider(), resource_id); - auto& lock = locks.back(); - - // Sync tokens ensure the texture to be overlaid is available before - // scheduling it for display. - if (lock.sync_token().HasData()) { - sync_tokens.push_back(lock.sync_token()); - } - - dc_layer_overlay.mailbox = lock.mailbox(); - DCHECK(!dc_layer_overlay.mailbox.IsZero()); - } #elif BUILDFLAG(IS_APPLE) for (CALayerOverlay& ca_layer_overlay : current_frame()->overlay_list) { if (ca_layer_overlay.rpdq) { @@ -2767,12 +2744,12 @@ overlay.mailbox = lock.mailbox(); DCHECK(!overlay.mailbox.IsZero()); } -#else // BUILDFLAG(IS_ANDROID) +#else // For platforms that don't support overlays, the // current_frame()->overlay_list should be empty, and this code should not be // reached. NOTREACHED(); -#endif // BUILDFLAG(IS_ANDROID) +#endif DCHECK(!current_gpu_commands_completed_fence_->was_set()); DCHECK(!current_release_fence_->was_set());
diff --git a/components/viz/service/display_embedder/output_presenter.h b/components/viz/service/display_embedder/output_presenter.h index 2191e3c..a19ec5e 100644 --- a/components/viz/service/display_embedder/output_presenter.h +++ b/components/viz/service/display_embedder/output_presenter.h
@@ -130,12 +130,8 @@ const OverlayProcessorInterface::OutputSurfaceOverlayPlane& plane, Image* image, bool is_submitted) = 0; -#if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_OZONE) - using OverlayPlaneCandidate = OverlayCandidate; -#elif BUILDFLAG(IS_APPLE) +#if BUILDFLAG(IS_APPLE) using OverlayPlaneCandidate = CALayerOverlay; -#elif BUILDFLAG(IS_WIN) - using OverlayPlaneCandidate = DCLayerOverlayCandidate; #else // Default. using OverlayPlaneCandidate = OverlayCandidate;
diff --git a/components/viz/service/display_embedder/output_presenter_gl.cc b/components/viz/service/display_embedder/output_presenter_gl.cc index 786ed061..e7c37b93 100644 --- a/components/viz/service/display_embedder/output_presenter_gl.cc +++ b/components/viz/service/display_embedder/output_presenter_gl.cc
@@ -312,8 +312,8 @@ ScopedOverlayAccess* access, std::unique_ptr<gfx::GpuFence> acquire_fence) { // Note that |overlay_plane_candidate| has different types on different - // platforms. On Android and Ozone it is an OverlayCandidate, on Windows it is - // a DCLayerOverlayCandidate, and on macOS it is a CALayeroverlay. + // platforms. On Android, Ozone, and Windows, it is an OverlayCandidate and on + // macOS it is a CALayeroverlay. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_OZONE) #if BUILDFLAG(IS_OZONE) // TODO(crbug.com/1366808): Add ScopedOverlayAccess::GetOverlayImage() that
diff --git a/components/viz/service/display_embedder/skia_output_device_dcomp.cc b/components/viz/service/display_embedder/skia_output_device_dcomp.cc index 444fed75..80407fbe 100644 --- a/components/viz/service/display_embedder/skia_output_device_dcomp.cc +++ b/components/viz/service/display_embedder/skia_output_device_dcomp.cc
@@ -35,6 +35,7 @@ #include "third_party/skia/include/gpu/GrDirectContext.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" #include "ui/gfx/buffer_format_util.h" +#include "ui/gfx/geometry/rect_conversions.h" #include "ui/gl/dc_layer_overlay_params.h" #include "ui/gl/gl_bindings.h" #include "ui/gl/gl_context.h" @@ -214,15 +215,22 @@ auto params = std::make_unique<gl::DCLayerOverlayParams>(); params->overlay_image = std::move(overlay_image); - params->z_order = dc_layer.z_order; - params->content_rect = dc_layer.content_rect; - params->quad_rect = dc_layer.quad_rect; - DCHECK(dc_layer.transform.IsFlat()); - params->transform = dc_layer.transform; + params->z_order = dc_layer.plane_z_order; + + // SwapChainPresenter uses the size of the overlay's resource in pixels to + // calculate its swap chain size. `uv_rect` maps the portion of + // `resource_size_in_pixels` that will be displayed. + params->content_rect = gfx::ToNearestRect(gfx::ScaleRect( + dc_layer.uv_rect, dc_layer.resource_size_in_pixels.width(), + dc_layer.resource_size_in_pixels.height())); + + params->quad_rect = gfx::ToEnclosingRect(dc_layer.display_rect); + DCHECK(absl::holds_alternative<gfx::Transform>(dc_layer.transform)); + params->transform = absl::get<gfx::Transform>(dc_layer.transform); params->clip_rect = dc_layer.clip_rect; params->protected_video_type = dc_layer.protected_video_type; params->color_space = dc_layer.color_space; - params->hdr_metadata = dc_layer.hdr_metadata; + params->hdr_metadata = dc_layer.hdr_metadata.value_or(gfx::HDRMetadata()); params->is_video_fullscreen_letterboxing = dc_layer.is_video_fullscreen_letterboxing;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc index ee13869..b2f0884cf 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.cc
@@ -16,6 +16,7 @@ #include "base/notreached.h" #include "base/task/bind_post_task.h" #include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "build/build_config.h" #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/blit_request.h" @@ -54,10 +55,12 @@ #include "skia/ext/rgba_to_yuva.h" #include "third_party/abseil-cpp/absl/types/optional.h" #include "third_party/libyuv/include/libyuv/planar_functions.h" +#include "third_party/skia/include/core/SkAlphaType.h" #include "third_party/skia/include/core/SkBlendMode.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkColorType.h" #include "third_party/skia/include/core/SkDeferredDisplayList.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkPromiseImageTexture.h" @@ -1140,25 +1143,19 @@ } // Create a destination for the scaled & clipped result: - auto intermediate_representation = CreateSharedImageRepresentationSkia( - ResourceFormat::RGBA_8888, intermediate_dst_size, color_space); - if (!intermediate_representation) { - DVLOG(1) << "failed to create shared image representation for the " - "intermediate surface"; + auto intermediate_surface = SkSurface::MakeRenderTarget( + gr_context(), skgpu::Budgeted::kYes, + SkImageInfo::Make(gfx::SizeToSkISize(intermediate_dst_size), + SkColorType::kRGBA_8888_SkColorType, + SkAlphaType::kPremul_SkAlphaType, + color_space.ToSkColorSpace())); + + if (!intermediate_surface) { + DVLOG(1) << "failed to create surface for the intermediate texture"; // Send empty result. return; } - SkSurfaceProps surface_props{0, kUnknown_SkPixelGeometry}; - std::vector<GrBackendSemaphore> begin_semaphores; - std::vector<GrBackendSemaphore> end_semaphores; - - auto intermediate_scoped_write = - intermediate_representation->BeginScopedWriteAccess( - /*final_msaa_count=*/1, surface_props, &begin_semaphores, - &end_semaphores, - gpu::SharedImageRepresentation::AllowUnclearedAccess::kYes); - absl::optional<SkVector> scaling; if (request->is_scaled()) { scaling = SkVector::Make(static_cast<SkScalar>(request->scale_to().x()) / @@ -1167,20 +1164,18 @@ request->scale_from().y()); } - intermediate_scoped_write->surface()->wait(begin_semaphores.size(), - begin_semaphores.data()); - RenderSurface(surface, src_rect, scaling, is_downscale_or_identity_in_both_dimensions, - intermediate_scoped_write->surface()); + intermediate_surface.get()); if (request->has_blit_request()) { - BlendBitmapOverlays(intermediate_scoped_write->surface()->getCanvas(), + BlendBitmapOverlays(intermediate_surface->getCanvas(), request->blit_request()); } - auto intermediate_image = - intermediate_scoped_write->surface()->makeImageSnapshot(); + intermediate_surface->flush(); + + auto intermediate_image = intermediate_surface->makeImageSnapshot(); if (!intermediate_image) { DLOG(ERROR) << "failed to retrieve `intermediate_image`."; return; @@ -1281,16 +1276,6 @@ } } - should_submit |= !end_semaphores.empty(); - - intermediate_representation->SetCleared(); - if (!FlushSurface(intermediate_scoped_write->surface(), end_semaphores, - intermediate_scoped_write->TakeEndState())) { - // TODO(penghuang): handle vulkan device lost. - FailedSkiaFlush("CopyOutputNV12 dest_surface->flush()"); - return; - } - if (should_submit && !gr_context()->submit()) { DLOG(ERROR) << "CopyOutputNV12 gr_context->submit() failed"; return;
diff --git a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h index 8f589a8..2300a4e 100644 --- a/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h +++ b/components/viz/service/display_embedder/skia_output_surface_impl_on_gpu.h
@@ -16,6 +16,7 @@ #include "base/memory/raw_ptr.h" #include "base/memory/scoped_refptr.h" #include "base/threading/thread_checker.h" +#include "base/time/time.h" #include "base/types/pass_key.h" #include "build/build_config.h" #include "components/viz/common/display/renderer_settings.h"
diff --git a/content/browser/accessibility/browser_accessibility_manager_win.cc b/content/browser/accessibility/browser_accessibility_manager_win.cc index 42846c3f..168ad44 100644 --- a/content/browser/accessibility/browser_accessibility_manager_win.cc +++ b/content/browser/accessibility/browser_accessibility_manager_win.cc
@@ -672,10 +672,13 @@ // static UiaRaiseActiveTextPositionChangedEventFunction BrowserAccessibilityManagerWin::GetUiaActiveTextPositionChangedEventFunction() { - // This API is only supported from Win8.1 onwards. On older platforms (such as - // Windows 7), we will return nullptr for the querying result for the address - // of the method "UiaRaiseActiveTextPositionChangedEvent" in - // uiautomationcore.dll. + // MSDN + // (https://learn.microsoft.com/en-us/windows/win32/api/uiautomationcoreapi/nf-uiautomationcoreapi-uiaraiseactivetextpositionchangedevent) + // claims this API is fully supported from Win8.1 ownwards, but older + // versions of this dll on Win10 (e.g., Windows-10-15063 aka. version 1703) + // don't seem to have the API, which makes chrome.dll fail to load, if + // ::UiaRaiseActiveTextPositionChangedEvent is called directly. On these older + // versions of Win10, we will return nullptr. return reinterpret_cast<UiaRaiseActiveTextPositionChangedEventFunction>( ::GetProcAddress(::GetModuleHandle(L"uiautomationcore.dll"), "UiaRaiseActiveTextPositionChangedEvent"));
diff --git a/content/browser/attribution_reporting/PRESUBMIT.py b/content/browser/attribution_reporting/PRESUBMIT.py deleted file mode 100644 index ff205c0..0000000 --- a/content/browser/attribution_reporting/PRESUBMIT.py +++ /dev/null
@@ -1,51 +0,0 @@ -# Copyright 2020 The Chromium Authors -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Presubmit script for the content/browser/attribution_reporting directory. - -See https://www.chromium.org/developers/how-tos/depottools/presubmit-scripts -for more details about the presubmit API built into depot_tools. -""" - -USE_PYTHON3 = True - -def CheckAttributionStorageSchemaModification(input_api, output_api): - """ Checks the kCurrentVersionNumber is modified when necessary. - - Whenever any of the following files is changed: - - attribution_storage_sql.cc - - attribution_storage_sql_migrations.cc - - rate_limit_table.cc - and kCurrentVersionNumber stays intact, this check returns a - presubmit warning to make sure the value is updated if necessary. - """ - - database_files_changed = False - database_version_changed = False - - for affected_file in input_api.AffectedFiles(): - basename = input_api.basename(affected_file.LocalPath()) - - if (basename == 'attribution_storage_sql_migrations.cc' or - basename == 'attribution_storage_sql.cc' or - basename == 'rate_limit_table.cc'): - database_files_changed = True - - if basename == 'attribution_storage_sql.cc': - for (_, line) in affected_file.ChangedContents(): - if 'const int AttributionStorageSql::kCurrentVersionNumber' in line: - database_version_changed = True - break - - out = [] - if database_files_changed and not database_version_changed: - out.append(output_api.PresubmitPromptWarning( - 'Please make sure that the conversions database is properly versioned ' - 'and migrated when making changes to schema or table contents. ' - 'kCurrentVersionNumber in attribution_storage_sql.cc ' - 'must be updated when doing a migration.')) - return out - -def CheckChangeOnUpload(input_api, output_api): - return CheckAttributionStorageSchemaModification(input_api, output_api)
diff --git a/content/browser/attribution_reporting/attribution_interop_parser.cc b/content/browser/attribution_reporting/attribution_interop_parser.cc index 59fed289..4d06351 100644 --- a/content/browser/attribution_reporting/attribution_interop_parser.cc +++ b/content/browser/attribution_reporting/attribution_interop_parser.cc
@@ -34,10 +34,6 @@ base::expected<base::Value::Dict, std::string> SimulatorInputFromInteropInput( base::Value::Dict) &&; - // Converts simulator output to interop test output format. - base::expected<base::Value::Dict, std::string> - InteropOutputFromSimulatorOutput(base::Value::Dict) &&; - [[nodiscard]] std::string ParseConfig(const base::Value::Dict&, AttributionConfig&, bool required) &&; @@ -76,12 +72,6 @@ base::Value::List ParseEvents(base::Value::Dict& dict, base::StringPiece key); - base::Value::List ParseEventLevelReports(base::Value::Dict& output); - - base::Value::List ParseAggregatableReports(base::Value::Dict& output); - - base::Value::List ParseVerboseDebugReports(base::Value::Dict& output); - // Returns true if `key` is present in `dict` and the integer is parsed // successfully. template <typename T> @@ -381,159 +371,6 @@ return result; } -base::Value::List AttributionInteropParser::ParseEventLevelReports( - base::Value::Dict& output) { - static constexpr char kKey[] = "event_level_reports"; - - base::Value::List event_level_results; - - base::Value* value = output.Find(kKey); - if (!value) { - return event_level_results; - } - - auto context = PushContext(kKey); - ParseList(output.Find(kKey), [&](base::Value value) { - if (!EnsureDictionary(&value)) { - return; - } - - base::Value::Dict result; - - base::Value::Dict& value_dict = value.GetDict(); - MoveValue(value_dict, "report", result, "payload"); - MoveValue(value_dict, "report_url", result); - MoveValue(value_dict, "intended_report_time", result, "report_time"); - - if (has_error()) { - return; - } - - event_level_results.Append(std::move(result)); - }); - - return event_level_results; -} - -base::Value::List AttributionInteropParser::ParseAggregatableReports( - base::Value::Dict& output) { - static constexpr char kKey[] = "aggregatable_reports"; - - base::Value::List aggregatable_results; - - base::Value* value = output.Find(kKey); - if (!value) { - return aggregatable_results; - } - - auto context = PushContext(kKey); - ParseList(output.Find(kKey), [&](base::Value value) { - if (!EnsureDictionary(&value)) { - return; - } - - base::Value::Dict result; - - base::Value::Dict& value_dict = value.GetDict(); - MoveValue(value_dict, "report_url", result); - MoveValue(value_dict, "intended_report_time", result, "report_time"); - - static constexpr char kKeyTestInfo[] = "test_info"; - base::Value* test_info; - { - auto test_info_context = PushContext(kKeyTestInfo); - test_info = value_dict.Find(kKeyTestInfo); - if (!EnsureDictionary(test_info)) { - return; - } - } - - static constexpr char kKeyReport[] = "report"; - { - auto report_context = PushContext(kKeyReport); - base::Value* report = value_dict.Find(kKeyReport); - if (!EnsureDictionary(report)) { - return; - } - - MoveDictValues(test_info->GetDict(), report->GetDict()); - } - - MoveValue(value_dict, "report", result, "payload"); - - if (has_error()) { - return; - } - - aggregatable_results.Append(std::move(result)); - }); - - return aggregatable_results; -} - -base::Value::List AttributionInteropParser::ParseVerboseDebugReports( - base::Value::Dict& output) { - static constexpr char kKey[] = "verbose_debug_reports"; - - base::Value::List reports; - - base::Value* value = output.Find(kKey); - if (!value) { - return reports; - } - - auto context = PushContext(kKey); - ParseList(output.Find(kKey), [&](base::Value value) { - if (!EnsureDictionary(&value)) { - return; - } - - base::Value::Dict report; - - base::Value::Dict& value_dict = value.GetDict(); - MoveValue(value_dict, "report", report, "payload"); - MoveValue(value_dict, "report_url", report); - MoveValue(value_dict, "report_time", report); - - if (has_error()) { - return; - } - - reports.Append(std::move(report)); - }); - - return reports; -} - -base::expected<base::Value::Dict, std::string> -AttributionInteropParser::InteropOutputFromSimulatorOutput( - base::Value::Dict output) && { - base::Value::List event_level_results = ParseEventLevelReports(output); - - base::Value::List aggregatable_results = ParseAggregatableReports(output); - - base::Value::List verbose_debug_reports = ParseVerboseDebugReports(output); - - if (has_error()) { - return base::unexpected(std::move(error_manager_).TakeError()); - } - - base::Value::Dict dict; - if (!event_level_results.empty()) { - dict.Set("event_level_results", std::move(event_level_results)); - } - - if (!aggregatable_results.empty()) { - dict.Set("aggregatable_results", std::move(aggregatable_results)); - } - - if (!verbose_debug_reports.empty()) { - dict.Set("verbose_debug_reports", std::move(verbose_debug_reports)); - } - - return dict; -} - void AttributionInteropParser::ParseRandomizedResponseRate( const base::Value::Dict& dict, base::StringPiece key, @@ -645,12 +482,6 @@ std::move(input)); } -base::expected<base::Value::Dict, std::string> -AttributionInteropOutputFromSimulatorOutput(base::Value::Dict output) { - return AttributionInteropParser().InteropOutputFromSimulatorOutput( - std::move(output)); -} - base::expected<AttributionConfig, std::string> ParseAttributionConfig( const base::Value::Dict& dict) { AttributionConfig config;
diff --git a/content/browser/attribution_reporting/attribution_interop_parser.h b/content/browser/attribution_reporting/attribution_interop_parser.h index c8dfe98..0315751 100644 --- a/content/browser/attribution_reporting/attribution_interop_parser.h +++ b/content/browser/attribution_reporting/attribution_interop_parser.h
@@ -21,9 +21,6 @@ base::expected<base::Value::Dict, std::string> AttributionSimulatorInputFromInteropInput(base::Value::Dict); -base::expected<base::Value::Dict, std::string> - AttributionInteropOutputFromSimulatorOutput(base::Value::Dict); - base::expected<AttributionConfig, std::string> ParseAttributionConfig( const base::Value::Dict&);
diff --git a/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc b/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc index 583a0cb..34f356f 100644 --- a/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc +++ b/content/browser/attribution_reporting/attribution_interop_parser_unittest.cc
@@ -128,93 +128,6 @@ EXPECT_THAT(*result, base::test::IsJson(base::test::ParseJson(kOutputJson))); } -TEST(AttributionInteropParserTest, ValidOutput) { - constexpr char kInputJson[] = R"json({ - "event_level_reports": [{ - "intended_report_time": "1643235573120", - "report_time": "1643235573123", - "report_url": "https://r.example/path", - "report": { - "attribution_destination": "https://d.test", - "randomized_trigger_rate": 0.0024, - "source_event_id": "123", - "source_type": "navigation", - "trigger_data": "7" - } - }], - "aggregatable_reports": [{ - "intended_report_time": "1643235573120", - "report_time": "1643235573123", - "report_url": "https://r.example/path", - "report": { - "attribution_destination": "https://d.test", - }, - "test_info": { - "histograms": [{ - "key": "key", - "value": "0x159" - }] - } - }], - "verbose_debug_reports": [{ - "report": [{ - "body": { - "attribution_destination": "https://destination2.test", - "limit": "1", - "source_event_id": "222", - "source_site": "https://source1.test" - }, - "type": "source-destination-limit" - }], - "report_time": "1643235575000", - "report_url": "https://reporter1.test/.well-known/attribution-reporting/debug/verbose" - }] - })json"; - - constexpr char kOutputJson[] = R"json({ - "event_level_results": [{ - "report_time": "1643235573120", - "report_url": "https://r.example/path", - "payload": { - "attribution_destination": "https://d.test", - "randomized_trigger_rate": 0.0024, - "source_event_id": "123", - "source_type": "navigation", - "trigger_data": "7" - } - }], - "aggregatable_results": [{ - "report_time": "1643235573120", - "report_url": "https://r.example/path", - "payload": { - "attribution_destination": "https://d.test", - "histograms": [{ - "key": "key", - "value": "0x159" - }] - } - }], - "verbose_debug_reports": [{ - "payload": [{ - "body": { - "attribution_destination": "https://destination2.test", - "limit": "1", - "source_event_id": "222", - "source_site": "https://source1.test" - }, - "type": "source-destination-limit" - }], - "report_time": "1643235575000", - "report_url": "https://reporter1.test/.well-known/attribution-reporting/debug/verbose" - }] - })json"; - - auto result = AttributionInteropOutputFromSimulatorOutput( - base::test::ParseJsonDict(kInputJson)); - ASSERT_TRUE(result.has_value()) << result.error(); - EXPECT_THAT(*result, base::test::IsJson(base::test::ParseJson(kOutputJson))); -} - TEST(AttributionInteropParserTest, ValidConfig) { const struct { const char* json; @@ -733,160 +646,5 @@ AttributionInteropParseInputErrorTest, ::testing::ValuesIn(kParseInputErrorTestCases)); -class AttributionInteropParseOutputErrorTest - : public testing::TestWithParam<ParseErrorTestCase> {}; - -TEST_P(AttributionInteropParseOutputErrorTest, InvalidOutputFails) { - const ParseErrorTestCase& test_case = GetParam(); - - auto result = AttributionInteropOutputFromSimulatorOutput( - base::test::ParseJsonDict(test_case.json)); - ASSERT_FALSE(result.has_value()); - EXPECT_THAT(result.error(), HasSubstr(test_case.expected_failure_substr)); -} - -const ParseErrorTestCase kParseOutputErrorTestCases[] = { - { - R"(["event_level_reports"]: must be a list)", - R"json({ - "event_level_reports": "" - })json", - }, - { - R"(["event_level_reports"][0]: must be a dictionary)", - R"json({ - "event_level_reports": [""] - })json", - }, - { - R"(["event_level_reports"][0]["report"]: must be present)", - R"json({ - "event_level_reports": [{}] - })json", - }, - { - R"(["event_level_reports"][0]["report_url"]: must be present)", - R"json({ - "event_level_reports": [{}] - })json", - }, - { - R"(["event_level_reports"][0]["intended_report_time"]: must be present)", - R"json({ - "event_level_reports": [{}] - })json", - }, - { - R"(["aggregatable_reports"]: must be a list)", - R"json({ - "aggregatable_reports": "" - })json", - }, - { - R"(["aggregatable_reports"][0]: must be a dictionary)", - R"json({ - "aggregatable_reports": [""] - })json", - }, - { - R"(["aggregatable_reports"][0]["report_url"]: must be present)", - R"json({ - "aggregatable_reports": [{}] - })json", - }, - { - R"(["aggregatable_reports"][0]["intended_report_time"]: must be present)", - R"json({ - "aggregatable_reports": [{}] - })json", - }, - { - R"(["aggregatable_reports"][0]["test_info"]: must be present)", - R"json({ - "aggregatable_reports": [{}] - })json", - }, - { - R"(["aggregatable_reports"][0]["test_info"]: must be a dictionary)", - R"json({ - "aggregatable_reports": [{ - "test_info": "" - }] - })json", - }, - { - R"(["aggregatable_reports"][0]["report"]: must be present)", - R"json({ - "aggregatable_reports": [{ - "test_info": {} - }] - })json", - }, - { - R"(["aggregatable_reports"][0]["report"]: must be a dictionary)", - R"json({ - "aggregatable_reports": [{ - "test_info": {}, - "report": "" - }] - })json", - }, - { - R"(["aggregatable_reports"][0]["report"]["histograms"]: must not be present)", - R"json({ - "aggregatable_reports": [{ - "report": { - "histograms": "" - }, - "test_info": { - "histograms": [] - } - }] - })json", - }, - { - R"(["verbose_debug_reports"]: must be a list)", - R"json({ - "verbose_debug_reports": {} - })json", - }, - { - R"(["verbose_debug_reports"][0]: must be a dictionary)", - R"json({ - "verbose_debug_reports": [""] - })json", - }, - { - R"(["verbose_debug_reports"][0]["report"]: must be present)", - R"json({ - "verbose_debug_reports": [{ - "report_time": "", - "report_url": "" - }] - })json", - }, - { - R"(["verbose_debug_reports"][0]["report_time"]: must be present)", - R"json({ - "verbose_debug_reports": [{ - "report": [], - "report_url": "" - }] - })json", - }, - { - R"(["verbose_debug_reports"][0]["report_url"]: must be present)", - R"json({ - "verbose_debug_reports": [{ - "report": [], - "report_time": "" - }] - })json", - }}; - -INSTANTIATE_TEST_SUITE_P(AttributionInteropParserInvalidOutputs, - AttributionInteropParseOutputErrorTest, - ::testing::ValuesIn(kParseOutputErrorTestCases)); - } // namespace } // namespace content
diff --git a/content/browser/attribution_reporting/attribution_interop_unittest.cc b/content/browser/attribution_reporting/attribution_interop_unittest.cc index 8c82b1c..6e27c4f 100644 --- a/content/browser/attribution_reporting/attribution_interop_unittest.cc +++ b/content/browser/attribution_reporting/attribution_interop_unittest.cc
@@ -96,12 +96,9 @@ auto input = AttributionSimulatorInputFromInteropInput(std::move(dict)); ASSERT_TRUE(input.has_value()) << input.error(); - auto simulator_output = RunAttributionSimulation(std::move(*input), config); - ASSERT_TRUE(simulator_output.has_value()) << simulator_output.error(); - - auto actual_output = - AttributionInteropOutputFromSimulatorOutput(std::move(*simulator_output)); + auto actual_output = RunAttributionSimulation(std::move(*input), config); ASSERT_TRUE(actual_output.has_value()) << actual_output.error(); + EXPECT_THAT(*actual_output, base::test::IsJson(*expected_output)); }
diff --git a/content/browser/attribution_reporting/attribution_simulator.cc b/content/browser/attribution_reporting/attribution_simulator.cc index c8f7ca06..7feb1e0 100644 --- a/content/browser/attribution_reporting/attribution_simulator.cc +++ b/content/browser/attribution_reporting/attribution_simulator.cc
@@ -108,6 +108,21 @@ report_body.Remove("aggregation_service_payloads"); report_body.Remove("source_registration_time"); + const auto& aggregatable_data = + absl::get<AttributionReport::AggregatableAttributionData>( + report.data()); + + base::Value::List list; + for (const auto& contribution : aggregatable_data.contributions) { + base::Value::Dict dict; + dict.Set("key", attribution_reporting::HexEncodeAggregationKey( + contribution.key())); + dict.Set("value", base::checked_cast<int>(contribution.value())); + + list.Append(std::move(dict)); + } + report_body.Set("histograms", std::move(list)); + break; } case AttributionReport::Type::kEventLevel: @@ -118,30 +133,13 @@ } base::Value::Dict value; - value.Set("report", std::move(report_body)); + value.Set("payload", std::move(report_body)); value.Set("report_url", report.ReportURL(is_debug_report).spec()); - value.Set("intended_report_time", + value.Set("report_time", FormatTime(is_debug_report ? report.attribution_info().time : report.report_time())); - if (const auto* aggregatable_data = - absl::get_if<AttributionReport::AggregatableAttributionData>( - &report.data())) { - base::Value::List list; - for (const auto& contribution : aggregatable_data->contributions) { - base::Value::Dict dict; - dict.Set("key", attribution_reporting::HexEncodeAggregationKey( - contribution.key())); - dict.Set("value", base::checked_cast<int>(contribution.value())); - - list.Append(std::move(dict)); - } - base::Value::Dict test_info; - test_info.Set("histograms", std::move(list)); - value.Set("test_info", std::move(test_info)); - } - return value; } @@ -163,7 +161,7 @@ } base::Value::Dict value; - value.Set("report", std::move(report_body)); + value.Set("payload", std::move(report_body)); value.Set("report_url", report.ReportURL().spec()); value.Set("report_time", FormatTime(time)); return value; @@ -282,22 +280,22 @@ base::Value::Dict output; if (!event_level_reports_.empty()) { - output.Set("event_level_reports", + output.Set("event_level_results", std::exchange(event_level_reports_, {})); } if (!debug_event_level_reports_.empty()) { - output.Set("debug_event_level_reports", + output.Set("debug_event_level_results", std::exchange(debug_event_level_reports_, {})); } if (!aggregatable_reports_.empty()) { - output.Set("aggregatable_reports", + output.Set("aggregatable_results", std::exchange(aggregatable_reports_, {})); } if (!debug_aggregatable_reports_.empty()) { - output.Set("debug_aggregatable_reports", + output.Set("debug_aggregatable_results", std::exchange(debug_aggregatable_reports_, {})); }
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.cc b/content/browser/attribution_reporting/attribution_storage_sql.cc index 4b5045e..1c6129e 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql.cc
@@ -66,22 +66,6 @@ namespace content { -// Version number of the database. -// TODO: remove the active_unattributed_sources_by_site_reporting_origin index -// during the next DB migration. -const int AttributionStorageSql::kCurrentVersionNumber = 46; - -// Earliest version which can use a |kCurrentVersionNumber| database -// without failing. -const int AttributionStorageSql::kCompatibleVersionNumber = 46; - -// Latest version of the database that cannot be upgraded to -// |kCurrentVersionNumber| without razing the database. -// -// Note that all versions >=15 were introduced during the transitional state of -// the Attribution Reporting API and can be removed when done. -const int AttributionStorageSql::kDeprecatedVersionNumber = 34; - namespace { using AggregatableResult = ::content::AttributionTrigger::AggregatableResult;
diff --git a/content/browser/attribution_reporting/attribution_storage_sql.h b/content/browser/attribution_reporting/attribution_storage_sql.h index d6eeccea..f93e09e8 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql.h +++ b/content/browser/attribution_reporting/attribution_storage_sql.h
@@ -50,10 +50,24 @@ // destroyed on the same sequence. The sequence must outlive |this|. class CONTENT_EXPORT AttributionStorageSql : public AttributionStorage { public: - // Exposed for testing. - static const int kCurrentVersionNumber; - static const int kCompatibleVersionNumber; - static const int kDeprecatedVersionNumber; + // Version number of the database. + // TODO: remove the active_unattributed_sources_by_site_reporting_origin index + // during the next DB migration. + static constexpr int kCurrentVersionNumber = 46; + + // Earliest version which can use a `kCurrentVersionNumber` database + // without failing. + static constexpr int kCompatibleVersionNumber = 46; + + // Latest version of the database that cannot be upgraded to + // `kCurrentVersionNumber` without razing the database. + // + // Note that all versions >=15 were introduced during the transitional state + // of the Attribution Reporting API and can be removed when done. + static constexpr int kDeprecatedVersionNumber = 34; + + static_assert(kCompatibleVersionNumber <= kCurrentVersionNumber); + static_assert(kDeprecatedVersionNumber < kCompatibleVersionNumber); [[nodiscard]] static bool DeleteStorageForTesting( const base::FilePath& user_data_directory);
diff --git a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc index c7f1a757..548a484 100644 --- a/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc +++ b/content/browser/attribution_reporting/attribution_storage_sql_migrations.cc
@@ -5,10 +5,12 @@ #include "content/browser/attribution_reporting/attribution_storage_sql_migrations.h" #include "base/check.h" +#include "base/functional/function_ref.h" #include "base/metrics/histogram_functions.h" #include "base/time/time.h" #include "components/aggregation_service/aggregation_service.mojom.h" #include "content/browser/attribution_reporting/attribution_report.h" +#include "content/browser/attribution_reporting/attribution_storage_sql.h" #include "content/browser/attribution_reporting/common_source_info.h" #include "content/browser/attribution_reporting/rate_limit_table.h" #include "sql/database.h" @@ -35,12 +37,27 @@ // transactions make it more likely that we'll make forward progress each time // Chrome stops. -bool MigrateToVersion36(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; +[[nodiscard]] bool MaybeMigrate( + sql::Database* db, + sql::MetaTable* meta_table, + int old_version, + base::FunctionRef<bool(sql::Database*)> migrate) { + DCHECK(db); + DCHECK(meta_table); + + if (meta_table->GetVersionNumber() != old_version) { + return true; } + sql::Transaction transaction(db); + + return transaction.Begin() && // + migrate(db) && // + SetVersionNumbers(meta_table, old_version + 1) && // + transaction.Commit(); +} + +bool To36(sql::Database* db) { static constexpr char kDropOldIndexSql[] = "DROP INDEX sources_by_origin"; if (!db->Execute(kDropOldIndexSql)) { return false; @@ -54,15 +71,10 @@ return false; } - return SetVersionNumbers(meta_table, 36) && transaction.Commit(); + return true; } -bool MigrateToVersion37(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To37(sql::Database* db) { static constexpr char kNewDedupKeyTableSql[] = "CREATE TABLE new_dedup_keys(" "source_id INTEGER NOT NULL," @@ -98,15 +110,10 @@ return false; } - return SetVersionNumbers(meta_table, 37) && transaction.Commit(); + return true; } -bool MigrateToVersion38(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To38(sql::Database* db) { static constexpr char kNewSourceTableSql[] = "CREATE TABLE new_sources(" "source_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," @@ -195,15 +202,10 @@ return false; } - return SetVersionNumbers(meta_table, 38) && transaction.Commit(); + return true; } -bool MigrateToVersion39(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To39(sql::Database* db) { // Create the new aggregatable_report_metadata table with // aggregation_coordinator. This follows the steps documented at // https://sqlite.org/lang_altertable.html#otheralter. Other approaches, like @@ -279,15 +281,10 @@ return false; } - return SetVersionNumbers(meta_table, 39) && transaction.Commit(); + return true; } -bool MigrateToVersion40(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To40(sql::Database* db) { // Create the new aggregatable_contributions table with desired primary-key // structure. static constexpr char kCreateNewTableSql[] = @@ -325,15 +322,10 @@ return false; } - return SetVersionNumbers(meta_table, 40) && transaction.Commit(); + return true; } -bool MigrateToVersion41(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To41(sql::Database* db) { static constexpr char kAddAttestationHeaderColumnSql[] = "ALTER TABLE aggregatable_report_metadata " "ADD COLUMN attestation_token TEXT"; @@ -341,15 +333,10 @@ return false; } - return SetVersionNumbers(meta_table, 41) && transaction.Commit(); + return true; } -bool MigrateToVersion42(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To42(sql::Database* db) { static constexpr char kRenameDestinationOriginSql[] = "ALTER TABLE rate_limits " "RENAME COLUMN destination_origin TO context_origin"; @@ -371,15 +358,10 @@ return false; } - return SetVersionNumbers(meta_table, 42) && transaction.Commit(); + return true; } -bool MigrateToVersion43(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To43(sql::Database* db) { static constexpr char kRenameExpiryTimeSql[] = "ALTER TABLE rate_limits " "RENAME COLUMN expiry_time TO source_expiry_or_attribution_time"; @@ -396,15 +378,10 @@ return false; } - return SetVersionNumbers(meta_table, 43) && transaction.Commit(); + return true; } -bool MigrateToVersion44(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To44(sql::Database* db) { { static constexpr char kConversionTableSql[] = "CREATE TABLE new_event_level_reports(" @@ -526,15 +503,10 @@ } } - return SetVersionNumbers(meta_table, 44) && transaction.Commit(); + return true; } -bool MigrateToVersion45(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To45(sql::Database* db) { static constexpr char kRenameSql[] = "ALTER TABLE event_level_reports " "RENAME COLUMN destination_origin TO context_origin"; @@ -542,20 +514,15 @@ return false; } - return SetVersionNumbers(meta_table, 45) && transaction.Commit(); + return true; } -bool MigrateToVersion46(sql::Database* db, sql::MetaTable* meta_table) { - sql::Transaction transaction(db); - if (!transaction.Begin()) { - return false; - } - +bool To46(sql::Database* db) { if (!db->Execute("ALTER TABLE sources DROP COLUMN destination_origin")) { return false; } - return SetVersionNumbers(meta_table, 46) && transaction.Commit(); + return true; } } // namespace @@ -570,62 +537,26 @@ start_timestamp = base::ThreadTicks::Now(); } - if (meta_table->GetVersionNumber() == 35) { - if (!MigrateToVersion36(db, meta_table)) { - return false; - } + static_assert(AttributionStorageSql::kDeprecatedVersionNumber + 1 == 35, + "Remove migration(s) below."); + + bool ok = MaybeMigrate(db, meta_table, 35, &To36) && + MaybeMigrate(db, meta_table, 36, &To37) && + MaybeMigrate(db, meta_table, 37, &To38) && + MaybeMigrate(db, meta_table, 38, &To39) && + MaybeMigrate(db, meta_table, 39, &To40) && + MaybeMigrate(db, meta_table, 40, &To41) && + MaybeMigrate(db, meta_table, 41, &To42) && + MaybeMigrate(db, meta_table, 42, &To43) && + MaybeMigrate(db, meta_table, 43, &To44) && + MaybeMigrate(db, meta_table, 44, &To45) && + MaybeMigrate(db, meta_table, 45, &To46); + if (!ok) { + return false; } - if (meta_table->GetVersionNumber() == 36) { - if (!MigrateToVersion37(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 37) { - if (!MigrateToVersion38(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 38) { - if (!MigrateToVersion39(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 39) { - if (!MigrateToVersion40(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 40) { - if (!MigrateToVersion41(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 41) { - if (!MigrateToVersion42(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 42) { - if (!MigrateToVersion43(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 43) { - if (!MigrateToVersion44(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 44) { - if (!MigrateToVersion45(db, meta_table)) { - return false; - } - } - if (meta_table->GetVersionNumber() == 45) { - if (!MigrateToVersion46(db, meta_table)) { - return false; - } - } - // Add similar if () blocks for new versions here. + + static_assert(AttributionStorageSql::kCurrentVersionNumber == 46, + "Add migration(s) above."); if (base::ThreadTicks::IsSupported()) { base::UmaHistogramMediumTimes("Conversions.Storage.MigrationTime",
diff --git a/content/browser/file_system_access/file_system_access_file_handle_move_browsertest.cc b/content/browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc similarity index 66% rename from content/browser/file_system_access/file_system_access_file_handle_move_browsertest.cc rename to content/browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc index cb4aca10..e60be1a 100644 --- a/content/browser/file_system_access/file_system_access_file_handle_move_browsertest.cc +++ b/content/browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc
@@ -12,11 +12,11 @@ #include "content/public/test/content_browser_test.h" #include "content/public/test/content_browser_test_utils.h" #include "net/test/embedded_test_server/embedded_test_server.h" +#include "testing/gtest/include/gtest/gtest.h" namespace content { -// TODO(crbug.com/1408211): Make this a WPT once crbug.com/1114920 is fixed. -class FileSystemAccessFileHandleMoveBrowserTest : public ContentBrowserTest { +class FileSystemAccessFileHandleImplBrowserTest : public ContentBrowserTest { public: void SetUp() override { ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); @@ -76,7 +76,8 @@ GURL test_url_; }; -IN_PROC_BROWSER_TEST_F(FileSystemAccessFileHandleMoveBrowserTest, +// TODO(crbug.com/1408211): Make this a WPT once crbug.com/1114920 is fixed. +IN_PROC_BROWSER_TEST_F(FileSystemAccessFileHandleImplBrowserTest, MoveLocalToSandboxed) { std::string file_contents = "move me to a sandboxed file system"; CreateTestFileInDirectory(temp_dir_.GetPath(), file_contents); @@ -91,7 +92,8 @@ << result.error; } -IN_PROC_BROWSER_TEST_F(FileSystemAccessFileHandleMoveBrowserTest, +// TODO(crbug.com/1408211): Make this a WPT once crbug.com/1114920 is fixed. +IN_PROC_BROWSER_TEST_F(FileSystemAccessFileHandleImplBrowserTest, MoveSandboxedToLocal) { CreateTestDirectoryInDirectory(temp_dir_.GetPath()); @@ -111,15 +113,13 @@ } class FileSystemAccessFileHandleMoveLocalBrowserTest - : public FileSystemAccessFileHandleMoveBrowserTest { + : public FileSystemAccessFileHandleImplBrowserTest { public: FileSystemAccessFileHandleMoveLocalBrowserTest() { scoped_feature_list_.InitAndDisableFeature( features::kFileSystemAccessMoveLocalFiles); } - void SetUp() override { FileSystemAccessFileHandleMoveBrowserTest::SetUp(); } - private: base::test::ScopedFeatureList scoped_feature_list_; }; @@ -136,4 +136,58 @@ << result.error; } +class FileSystemAccessFileHandleGetUniqueIdBrowserTest + : public FileSystemAccessFileHandleImplBrowserTest { + public: + void SetUpCommandLine(base::CommandLine* command_line) override { + FileSystemAccessFileHandleImplBrowserTest::SetUpCommandLine(command_line); + // Enable File System Access experimental features, which includes the + // getUniqueId() method. + command_line->AppendSwitch( + "--enable-blink-features=FileSystemAccessAPIExperimental"); + } +}; + +IN_PROC_BROWSER_TEST_F(FileSystemAccessFileHandleGetUniqueIdBrowserTest, + SameFileFromDifferentPickerInvocations) { + base::FilePath file_path; + std::string file_contents = "I am unique"; + { + base::ScopedAllowBlockingForTesting allow_blocking; + EXPECT_TRUE( + base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &file_path)); + EXPECT_TRUE(base::WriteFile(file_path, file_contents)); + } + + ui::SelectFileDialog::SetFactory( + new FakeSelectFileDialogFactory({file_path})); + EXPECT_TRUE(NavigateToURL(shell(), test_url_)); + EXPECT_EQ(file_path.BaseName().AsUTF8Unsafe(), + EvalJs(shell(), + "(async () => {" + " let [e] = await self.showOpenFilePicker();" + " self.file1 = e;" + " return e.name; })()")); + EXPECT_EQ(file_path.BaseName().AsUTF8Unsafe(), + EvalJs(shell(), + "(async () => {" + " let [e] = await self.showOpenFilePicker();" + " self.file2 = e;" + " return e.name; })()")); + + EXPECT_TRUE(EvalJs(shell(), + "(async () => {" + "return await self.file2.isSameEntry(self.file1); })()") + .ExtractBool()); + auto uniqueId1 = EvalJs(shell(), + "(async () => {" + "return await self.file1.getUniqueId(); })()") + .ExtractString(); + auto uniqueId2 = EvalJs(shell(), + "(async () => {" + "return await self.file2.getUniqueId(); })()") + .ExtractString(); + EXPECT_EQ(uniqueId1, uniqueId2); +} + } // namespace content
diff --git a/content/browser/gpu/gpu_process_host.cc b/content/browser/gpu/gpu_process_host.cc index 9f1efcd..28c9933 100644 --- a/content/browser/gpu/gpu_process_host.cc +++ b/content/browser/gpu/gpu_process_host.cc
@@ -446,17 +446,6 @@ // Block this DLL even if it is not loaded by the browser process. config->AddDllToUnload(L"cmsetac.dll"); - if (cmd_line_.HasSwitch(switches::kEnableLogging)) { - std::wstring log_file_path = logging::GetLogFileFullPath(); - if (!log_file_path.empty()) { - sandbox::ResultCode result = config->AddRule( - sandbox::SubSystem::kFiles, sandbox::Semantics::kFilesAllowAny, - log_file_path.c_str()); - if (result != sandbox::SBOX_ALL_OK) - return false; - } - } - return true; }
diff --git a/content/browser/renderer_host/input/touch_emulator.cc b/content/browser/renderer_host/input/touch_emulator.cc index 2b45a83..2c52f2bd 100644 --- a/content/browser/renderer_host/input/touch_emulator.cc +++ b/content/browser/renderer_host/input/touch_emulator.cc
@@ -5,6 +5,7 @@ #include "content/browser/renderer_host/input/touch_emulator.h" #include <memory> +#include <utility> #include "base/containers/queue.h" #include "base/time/time.h" @@ -24,6 +25,8 @@ #include "ui/events/base_event_utils.h" #include "ui/events/blink/blink_event_util.h" #include "ui/events/gesture_detection/gesture_provider_config_helper.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/skia_conversions.h" #include "ui/gfx/image/image.h" using blink::WebGestureEvent; @@ -72,7 +75,6 @@ gesture_provider_config_type_( ui::GestureProviderConfigType::CURRENT_PLATFORM), double_tap_enabled_(true), - use_2x_cursors_(false), pinch_gesture_mode_for_testing_(false), emulated_stream_active_sequence_count_(0), native_stream_active_sequence_count_(0), @@ -80,7 +82,7 @@ pending_taps_count_(0) { DCHECK(client_); ResetState(); - InitCursors(device_scale_factor, true); + SetDeviceScaleFactor(device_scale_factor); } TouchEmulator::~TouchEmulator() { @@ -102,7 +104,7 @@ void TouchEmulator::Enable(Mode mode, ui::GestureProviderConfigType config_type) { if (gesture_provider_ && mode_ != mode) - client_->SetCursor(pointer_cursor_); + client_->SetCursor(ui::mojom::CursorType::kPointer); if (!gesture_provider_ || gesture_provider_config_type_ != config_type || mode_ != mode) { @@ -128,13 +130,20 @@ gesture_provider_.reset(); base::queue<base::OnceClosure> empty; injected_touch_completion_callbacks_.swap(empty); - client_->SetCursor(pointer_cursor_); + client_->SetCursor(ui::mojom::CursorType::kPointer); ResetState(); } void TouchEmulator::SetDeviceScaleFactor(float device_scale_factor) { - if (!InitCursors(device_scale_factor, false)) + // Make sure the scale factor corresponds to the one of the available cursor + // images. + const float cursor_scale_factor = device_scale_factor < 1.5f ? 1.0f : 2.0f; + if (cursor_scale_factor == cursor_scale_factor_) { return; + } + + cursor_scale_factor_ = cursor_scale_factor; + InitCursors(); if (enabled()) UpdateCursor(); } @@ -145,38 +154,31 @@ gesture_provider_->SetDoubleTapSupportForPageEnabled(enabled); } -bool TouchEmulator::InitCursors(float device_scale_factor, bool force) { - bool use_2x = device_scale_factor > 1.5f; - if (use_2x == use_2x_cursors_ && !force) - return false; - use_2x_cursors_ = use_2x; - float cursor_scale_factor = use_2x ? 2.f : 1.f; - cursor_size_ = InitCursorFromResource(&touch_cursor_, - cursor_scale_factor, - use_2x ? IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X : - IDR_DEVTOOLS_TOUCH_CURSOR_ICON); - InitCursorFromResource(&pinch_cursor_, - cursor_scale_factor, - use_2x ? IDR_DEVTOOLS_PINCH_CURSOR_ICON_2X : - IDR_DEVTOOLS_PINCH_CURSOR_ICON); - - pointer_cursor_ = ui::Cursor(ui::mojom::CursorType::kPointer); - return true; +void TouchEmulator::InitCursors() { + touch_cursor_ = InitCursorFromResource( + cursor_scale_factor_ == 1.0f ? IDR_DEVTOOLS_TOUCH_CURSOR_ICON + : IDR_DEVTOOLS_TOUCH_CURSOR_ICON_2X); + pinch_cursor_ = InitCursorFromResource( + cursor_scale_factor_ == 1.0f ? IDR_DEVTOOLS_PINCH_CURSOR_ICON + : IDR_DEVTOOLS_PINCH_CURSOR_ICON_2X); + // The touch cursor is bigger. Use its size in DIPs for both cursors. + cursor_size_ = gfx::ScaleSize( + gfx::SizeF( + gfx::SkISizeToSize(touch_cursor_.custom_bitmap().dimensions())), + 1 / cursor_scale_factor_); } -gfx::SizeF TouchEmulator::InitCursorFromResource(ui::Cursor* cursor, - float scale, - int resource_id) { - gfx::Image& cursor_image = +ui::Cursor TouchEmulator::InitCursorFromResource(int resource_id) { + const gfx::Image& cursor_image = content::GetContentClient()->GetNativeImageNamed(resource_id); - ui::Cursor cursor_info(ui::mojom::CursorType::kCustom); - cursor_info.set_image_scale_factor(scale); - cursor_info.set_custom_bitmap(cursor_image.AsBitmap()); - cursor_info.set_custom_hotspot( - gfx::Point(cursor_image.Width() / 2, cursor_image.Height() / 2)); + SkBitmap bitmap = cursor_image.AsBitmap(); + gfx::Point hotspot(bitmap.width() / 2, bitmap.height() / 2); - *cursor = cursor_info; - return gfx::ScaleSize(gfx::SizeF(cursor_image.Size()), 1.f / scale); + ui::Cursor cursor(ui::mojom::CursorType::kCustom); + cursor.set_custom_bitmap(std::move(bitmap)); + cursor.set_custom_hotspot(std::move(hotspot)); + cursor.set_image_scale_factor(cursor_scale_factor_); + return cursor; } bool TouchEmulator::HandleMouseEvent(const WebMouseEvent& mouse_event,
diff --git a/content/browser/renderer_host/input/touch_emulator.h b/content/browser/renderer_host/input/touch_emulator.h index 267238c7..0cc3e13 100644 --- a/content/browser/renderer_host/input/touch_emulator.h +++ b/content/browser/renderer_host/input/touch_emulator.h
@@ -104,11 +104,8 @@ void OnGestureEvent(const ui::GestureEventData& gesture) override; bool RequiresDoubleTapGestureEvents() const override; - // Returns cursor size in DIP. - gfx::SizeF InitCursorFromResource(ui::Cursor* cursor, - float scale, - int resource_id); - bool InitCursors(float device_scale_factor, bool force); + ui::Cursor InitCursorFromResource(int resource_id); + void InitCursors(); void ResetState(); void UpdateCursor(); bool UpdateShiftPressed(bool shift_pressed); @@ -147,14 +144,14 @@ Mode mode_; bool double_tap_enabled_; - bool use_2x_cursors_; // While emulation is on, default cursor is touch. Pressing shift changes // cursor to the pinch one. - ui::Cursor pointer_cursor_; ui::Cursor touch_cursor_; ui::Cursor pinch_cursor_; gfx::SizeF cursor_size_; + float cursor_scale_factor_ = 0; + // These are used to drop extra mouse move events coming too quickly, so // we don't handle too much touches in gesture provider. bool last_mouse_event_was_move_;
diff --git a/content/browser/renderer_host/input/touch_emulator_unittest.cc b/content/browser/renderer_host/input/touch_emulator_unittest.cc index 2d364c9..1a3fdf96 100644 --- a/content/browser/renderer_host/input/touch_emulator_unittest.cc +++ b/content/browser/renderer_host/input/touch_emulator_unittest.cc
@@ -251,6 +251,8 @@ void DisableSynchronousTouchAck() { ack_touches_synchronously_ = false; } + const ui::Cursor& GetCursor() { return cursor_; } + float GetCursorScaleFactor() { return cursor_.image_scale_factor(); } private: @@ -595,9 +597,9 @@ emulator()->SetDeviceScaleFactor(1.33f); EXPECT_EQ(1.0f, GetCursorScaleFactor()); emulator()->Disable(); - EXPECT_EQ(1.0f, GetCursorScaleFactor()); + EXPECT_EQ(ui::mojom::CursorType::kPointer, GetCursor().type()); emulator()->SetDeviceScaleFactor(3.0f); - EXPECT_EQ(1.0f, GetCursorScaleFactor()); + EXPECT_EQ(ui::mojom::CursorType::kPointer, GetCursor().type()); emulator()->Enable(TouchEmulator::Mode::kEmulatingTouchFromMouse, ui::GestureProviderConfigType::GENERIC_MOBILE); EXPECT_EQ(2.0f, GetCursorScaleFactor());
diff --git a/content/browser/renderer_host/navigation_request.cc b/content/browser/renderer_host/navigation_request.cc index d66761d..b346c1c 100644 --- a/content/browser/renderer_host/navigation_request.cc +++ b/content/browser/renderer_host/navigation_request.cc
@@ -2501,11 +2501,7 @@ /*is_renderer_initiated_check=*/false)); } - // No throttles will actually run, but `CommitNavigation()` expects to be - // called only once the request has reached `WILL_PROCESS_RESPONSE`. - SetState(WILL_PROCESS_RESPONSE); - - CommitNavigation(); + WillCommitWithoutUrlLoader(); return; } @@ -3251,8 +3247,9 @@ } void NavigationRequest::DetermineOriginAgentClusterEndResult() { - DCHECK(state_ == WILL_PROCESS_RESPONSE || state_ == WILL_FAIL_REQUEST || - state_ == CANCELING); + DCHECK(state_ == WILL_PROCESS_RESPONSE || + state_ == WILL_COMMIT_WITHOUT_URL_LOADER || + state_ == WILL_FAIL_REQUEST || state_ == CANCELING); auto* policy = ChildProcessSecurityPolicyImpl::GetInstance(); url::Origin origin = GetOriginToCommit().value(); const IsolationContext& isolation_context = @@ -5068,6 +5065,23 @@ // NavigationRequest. } +void NavigationRequest::OnWillCommitWithoutUrlLoaderChecksComplete( + NavigationThrottle::ThrottleCheckResult result) { + DCHECK(result.action() == NavigationThrottle::CANCEL_AND_IGNORE || + result.action() == NavigationThrottle::PROCEED); + if (result.action() == NavigationThrottle::CANCEL_AND_IGNORE) { + OnRequestFailedInternal( + network::URLLoaderCompletionStatus(result.net_error_code()), + /*skip_throttles=*/true, result.error_page_content(), + /*collapse_frame=*/false); + + // DO NOT ADD CODE after this. The previous call to OnRequestFailedInternal + // has destroyed the NavigationRequest. + return; + } + CommitNavigation(); +} + void NavigationRequest::RunCommitDeferringConditions() { // TODO(nhiroki): Make RegisterDeferringConditions() private and have // ProcessChecks() call it for code cleanup. @@ -6193,6 +6207,9 @@ case NavigationThrottleRunner::Event::WillProcessResponse: OnWillProcessResponseProcessed(result); return; + case NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader: + OnWillCommitWithoutUrlLoaderProcessed(result); + return; default: NOTREACHED(); } @@ -6291,6 +6308,24 @@ // deleted by the previous calls. } +void NavigationRequest::OnWillCommitWithoutUrlLoaderProcessed( + NavigationThrottle::ThrottleCheckResult result) { + DCHECK_EQ(WILL_COMMIT_WITHOUT_URL_LOADER, state_); + DCHECK(result.action() == NavigationThrottle::CANCEL_AND_IGNORE || + result.action() == NavigationThrottle::PROCEED); + DCHECK(processing_navigation_throttle_); + processing_navigation_throttle_ = false; + if (complete_callback_for_testing_ && + std::move(complete_callback_for_testing_).Run(result)) { + return; + } + + OnWillCommitWithoutUrlLoaderChecksComplete(result); + + // DO NOT ADD CODE AFTER THIS, as the NavigationRequest might have been + // deleted by the previous calls. +} + NavigatorDelegate* NavigationRequest::GetDelegate() const { return frame_tree_node()->navigator().GetDelegate(); } @@ -6369,6 +6404,9 @@ case WILL_PROCESS_RESPONSE: OnWillProcessResponseChecksComplete(result); return; + case WILL_COMMIT_WITHOUT_URL_LOADER: + OnWillCommitWithoutUrlLoaderChecksComplete(result); + return; default: NOTREACHED(); } @@ -6471,6 +6509,22 @@ // by the previous call. } +void NavigationRequest::WillCommitWithoutUrlLoader() { + EnterChildTraceEvent("WillCommitWithoutUrlLoader", this); + + throttle_runner_->RegisterNavigationThrottlesForCommitWithoutUrlLoader(); + + // `CommitNavigation()` expects to be called once the request has reached + // at least `WILL_PROCESS_REPSONSE`. `WILL_COMMIT_WITHOUT_URL_LOADER` meets + // that requirement, and is useful to clarify which throttles we are waiting + // for. + SetState(WILL_COMMIT_WITHOUT_URL_LOADER); + processing_navigation_throttle_ = true; + + throttle_runner_->ProcessNavigationEvent( + NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader); +} + bool NavigationRequest::IsSelfReferentialURL() { // about: URLs should be exempted since they are reserved for other purposes // and cannot be the source of infinite recursion. @@ -8187,6 +8241,7 @@ {WILL_START_REQUEST, { WILL_REDIRECT_REQUEST, WILL_PROCESS_RESPONSE, + WILL_COMMIT_WITHOUT_URL_LOADER, READY_TO_COMMIT, DID_COMMIT, CANCELING, @@ -8204,6 +8259,11 @@ CANCELING, WILL_FAIL_REQUEST, }}, + {WILL_COMMIT_WITHOUT_URL_LOADER, { + READY_TO_COMMIT, + CANCELING, + WILL_FAIL_REQUEST, + }}, {READY_TO_COMMIT, { NOT_STARTED, DID_COMMIT,
diff --git a/content/browser/renderer_host/navigation_request.h b/content/browser/renderer_host/navigation_request.h index 64dc22d..d457923d 100644 --- a/content/browser/renderer_host/navigation_request.h +++ b/content/browser/renderer_host/navigation_request.h
@@ -159,6 +159,11 @@ // asynchronous. WILL_PROCESS_RESPONSE, + // The navigation does not require a request/response. Wait only for + // NavigationThrottles to finish before calling CommitNavigation(). This + // will only be asynchronous if a throttle defers the navigation. + WILL_COMMIT_WITHOUT_URL_LOADER, + // The browser process has asked the renderer to commit the response // and is waiting for acknowledgement that it has been committed. READY_TO_COMMIT, @@ -899,8 +904,9 @@ // Note #2: Even though "javascript:" URL and RendererDebugURL fit very well // in this category, they don't use the NavigationRequest. // - // Note #3: Navigations that do not use a URL loader also bypass - // NavigationThrottle. + // Note #3: Navigations that do not use a URL loader do not send the usual + // set of callbacks to NavigationThrottle. Instead, they send a single + // separate callback, WillCommitWithoutUrlLoader(). bool NeedsUrlLoader(); network::mojom::PrivateNetworkRequestPolicy private_network_request_policy() @@ -1234,6 +1240,8 @@ void OnFailureChecksComplete(NavigationThrottle::ThrottleCheckResult result); void OnWillProcessResponseChecksComplete( NavigationThrottle::ThrottleCheckResult result); + void OnWillCommitWithoutUrlLoaderChecksComplete( + NavigationThrottle::ThrottleCheckResult result); // Runs CommitDeferringConditions. // @@ -1424,6 +1432,8 @@ NavigationThrottle::ThrottleCheckResult result); void OnWillProcessResponseProcessed( NavigationThrottle::ThrottleCheckResult result); + void OnWillCommitWithoutUrlLoaderProcessed( + NavigationThrottle::ThrottleCheckResult result); void CancelDeferredNavigationInternal( NavigationThrottle::ThrottleCheckResult result); @@ -1455,6 +1465,10 @@ // just before calling |callback|. void WillProcessResponse(); + // Called when no URLRequest will be needed to perform this navigation, just + // before commit. + void WillCommitWithoutUrlLoader(); + // Checks for attempts to navigate to a page that is already referenced more // than once in the frame's ancestors. This is a helper function used by // WillStartRequest and WillRedirectRequest to prevent the navigation.
diff --git a/content/browser/renderer_host/navigation_request_browsertest.cc b/content/browser/renderer_host/navigation_request_browsertest.cc index d76ff817..931a901 100644 --- a/content/browser/renderer_host/navigation_request_browsertest.cc +++ b/content/browser/renderer_host/navigation_request_browsertest.cc
@@ -87,19 +87,26 @@ NavigationThrottle::ThrottleCheckResult will_redirect_result, NavigationThrottle::ThrottleCheckResult will_fail_result, NavigationThrottle::ThrottleCheckResult will_process_result, + NavigationThrottle::ThrottleCheckResult + will_commit_without_url_loader_result, base::OnceClosure did_call_will_start, base::OnceClosure did_call_will_redirect, base::OnceClosure did_call_will_fail, - base::OnceClosure did_call_will_process) + base::OnceClosure did_call_will_process, + base::OnceClosure did_call_will_commit_without_url_loader) : NavigationThrottle(handle), will_start_result_(will_start_result), will_redirect_result_(will_redirect_result), will_fail_result_(will_fail_result), will_process_result_(will_process_result), + will_commit_without_url_loader_result_( + will_commit_without_url_loader_result), did_call_will_start_(std::move(did_call_will_start)), did_call_will_redirect_(std::move(did_call_will_redirect)), did_call_will_fail_(std::move(did_call_will_fail)), - did_call_will_process_(std::move(did_call_will_process)) {} + did_call_will_process_(std::move(did_call_will_process)), + did_call_will_commit_without_url_loader_( + std::move(did_call_will_commit_without_url_loader)) {} ~TestNavigationThrottle() override = default; const char* GetNameForLogging() override { return "TestNavigationThrottle"; } @@ -159,14 +166,30 @@ return will_process_result_; } + NavigationThrottle::ThrottleCheckResult WillCommitWithoutUrlLoader() + override { + NavigationRequest* navigation_request = + NavigationRequest::From(navigation_handle()); + CHECK_NE(blink::mojom::RequestContextType::UNSPECIFIED, + navigation_request->request_context_type()); + request_context_type_ = navigation_request->request_context_type(); + + GetUIThreadTaskRunner({})->PostTask( + FROM_HERE, std::move(did_call_will_commit_without_url_loader_)); + return will_commit_without_url_loader_result_; + } + NavigationThrottle::ThrottleCheckResult will_start_result_; NavigationThrottle::ThrottleCheckResult will_redirect_result_; NavigationThrottle::ThrottleCheckResult will_fail_result_; NavigationThrottle::ThrottleCheckResult will_process_result_; + NavigationThrottle::ThrottleCheckResult + will_commit_without_url_loader_result_; base::OnceClosure did_call_will_start_; base::OnceClosure did_call_will_redirect_; base::OnceClosure did_call_will_fail_; base::OnceClosure did_call_will_process_; + base::OnceClosure did_call_will_commit_without_url_loader_; blink::mojom::RequestContextType request_context_type_ = blink::mojom::RequestContextType::UNSPECIFIED; }; @@ -182,6 +205,7 @@ WILL_REDIRECT_REQUEST, WILL_FAIL_REQUEST, WILL_PROCESS_RESPONSE, + WILL_COMMIT_WITHOUT_URL_LOADER, }; TestNavigationThrottleInstaller( @@ -190,12 +214,16 @@ NavigationThrottle::ThrottleCheckResult will_redirect_result, NavigationThrottle::ThrottleCheckResult will_fail_result, NavigationThrottle::ThrottleCheckResult will_process_result, + NavigationThrottle::ThrottleCheckResult + will_commit_without_url_loader_result, const GURL& expected_start_url = GURL()) : WebContentsObserver(web_contents), will_start_result_(will_start_result), will_redirect_result_(will_redirect_result), will_fail_result_(will_fail_result), will_process_result_(will_process_result), + will_commit_without_url_loader_result_( + will_commit_without_url_loader_result), expected_start_url_(expected_start_url) {} ~TestNavigationThrottleInstaller() override = default; @@ -210,6 +238,7 @@ auto will_redirect_result = will_start_result; auto will_fail_result = will_start_result; auto will_process_result = will_start_result; + auto will_commit_without_url_loader_result = will_start_result; switch (method) { case WILL_START_REQUEST: @@ -224,11 +253,14 @@ case WILL_PROCESS_RESPONSE: will_process_result = result; break; + case WILL_COMMIT_WITHOUT_URL_LOADER: + will_commit_without_url_loader_result = result; + break; } return std::make_unique<TestNavigationThrottleInstaller>( web_contents, will_start_result, will_redirect_result, will_fail_result, - will_process_result); + will_process_result, will_commit_without_url_loader_result); } TestNavigationThrottle* navigation_throttle() { return navigation_throttle_; } @@ -265,6 +297,15 @@ will_process_loop_runner_ = nullptr; } + void WaitForThrottleWillCommitWithoutUrlLoader() { + if (will_commit_without_url_loader_called_) { + return; + } + will_commit_without_url_loader_loop_runner_ = new MessageLoopRunner(); + will_commit_without_url_loader_loop_runner_->Run(); + will_commit_without_url_loader_loop_runner_ = nullptr; + } + void Continue(NavigationThrottle::ThrottleCheckResult result) { ASSERT_NE(NavigationThrottle::DEFER, result.action()); if (result.action() == NavigationThrottle::PROCEED) @@ -277,6 +318,9 @@ int will_redirect_called() { return will_redirect_called_; } int will_fail_called() { return will_fail_called_; } int will_process_called() { return will_process_called_; } + int will_commit_without_url_loader_called() { + return will_commit_without_url_loader_called_; + } int install_count() { return install_count_; } @@ -305,6 +349,13 @@ will_process_loop_runner_->Quit(); } + virtual void DidCallWillCommitWithoutUrlLoader() { + will_commit_without_url_loader_called_++; + if (will_commit_without_url_loader_loop_runner_) { + will_commit_without_url_loader_loop_runner_->Quit(); + } + } + private: void DidStartNavigation(NavigationHandle* handle) override { if (!expected_start_url_.is_empty() && @@ -313,7 +364,7 @@ std::unique_ptr<NavigationThrottle> throttle(new TestNavigationThrottle( handle, will_start_result_, will_redirect_result_, will_fail_result_, - will_process_result_, + will_process_result_, will_commit_without_url_loader_result_, base::BindOnce( &TestNavigationThrottleInstaller::DidCallWillStartRequest, weak_factory_.GetWeakPtr()), @@ -324,6 +375,9 @@ weak_factory_.GetWeakPtr()), base::BindOnce( &TestNavigationThrottleInstaller::DidCallWillProcessResponse, + weak_factory_.GetWeakPtr()), + base::BindOnce( + &TestNavigationThrottleInstaller::DidCallWillCommitWithoutUrlLoader, weak_factory_.GetWeakPtr()))); navigation_throttle_ = static_cast<TestNavigationThrottle*>(throttle.get()); handle->RegisterThrottleForTesting(std::move(throttle)); @@ -342,16 +396,20 @@ NavigationThrottle::ThrottleCheckResult will_redirect_result_; NavigationThrottle::ThrottleCheckResult will_fail_result_; NavigationThrottle::ThrottleCheckResult will_process_result_; + NavigationThrottle::ThrottleCheckResult + will_commit_without_url_loader_result_; int will_start_called_ = 0; int will_redirect_called_ = 0; int will_fail_called_ = 0; int will_process_called_ = 0; + int will_commit_without_url_loader_called_ = 0; raw_ptr<TestNavigationThrottle> navigation_throttle_ = nullptr; int install_count_ = 0; scoped_refptr<MessageLoopRunner> will_start_loop_runner_; scoped_refptr<MessageLoopRunner> will_redirect_loop_runner_; scoped_refptr<MessageLoopRunner> will_fail_loop_runner_; scoped_refptr<MessageLoopRunner> will_process_loop_runner_; + scoped_refptr<MessageLoopRunner> will_commit_without_url_loader_loop_runner_; GURL expected_start_url_; // The throttle installer can be deleted before all tasks posted by its @@ -371,17 +429,22 @@ NavigationThrottle::ThrottleCheckResult will_redirect_result, NavigationThrottle::ThrottleCheckResult will_fail_result, NavigationThrottle::ThrottleCheckResult will_process_result, + NavigationThrottle::ThrottleCheckResult + will_commit_without_url_loader_result, GURL expected_start_url = GURL()) : TestNavigationThrottleInstaller(web_contents, NavigationThrottle::DEFER, NavigationThrottle::DEFER, NavigationThrottle::DEFER, NavigationThrottle::DEFER, + NavigationThrottle::DEFER, expected_start_url), will_start_deferred_result_(will_start_result), will_redirect_deferred_result_(will_redirect_result), will_fail_deferred_result_(will_fail_result), - will_process_deferred_result_(will_process_result) {} + will_process_deferred_result_(will_process_result), + will_commit_without_url_loader_result_( + will_commit_without_url_loader_result) {} protected: void DidCallWillStartRequest() override { @@ -404,11 +467,18 @@ Continue(will_process_deferred_result_); } + void DidCallWillCommitWithoutUrlLoader() override { + TestNavigationThrottleInstaller::DidCallWillCommitWithoutUrlLoader(); + Continue(will_commit_without_url_loader_result_); + } + private: NavigationThrottle::ThrottleCheckResult will_start_deferred_result_; NavigationThrottle::ThrottleCheckResult will_redirect_deferred_result_; NavigationThrottle::ThrottleCheckResult will_fail_deferred_result_; NavigationThrottle::ThrottleCheckResult will_process_deferred_result_; + NavigationThrottle::ThrottleCheckResult + will_commit_without_url_loader_result_; }; // Records all navigation start URLs from the WebContents. @@ -937,7 +1007,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::CANCEL, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); EXPECT_FALSE(NavigateToURL(shell(), redirect_url)); @@ -963,7 +1033,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::CANCEL, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); EXPECT_FALSE(NavigateToURL(shell(), redirect_url)); @@ -980,7 +1050,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::CANCEL, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); EXPECT_TRUE(NavigateToURL(shell(), no_redirect_url)); @@ -1005,7 +1075,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::CANCEL, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), url); @@ -1028,7 +1098,7 @@ NavigationThrottle::PROCEED, NavigationThrottle::ThrottleCheckResult(NavigationThrottle::CANCEL, net::ERR_CERT_DATE_INVALID), - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), url); @@ -1052,7 +1122,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::CANCEL, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); EXPECT_TRUE(NavigateToURL(shell(), url)); @@ -1073,7 +1143,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::CANCEL); + NavigationThrottle::CANCEL, NavigationThrottle::PROCEED); EXPECT_FALSE(NavigateToURL(shell(), redirect_url)); @@ -1085,6 +1155,28 @@ EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), start_url); } +// Ensure that a NavigationThrottle can cancel the navigation when committing +// without a URLLoader. +IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest, + ThrottleCancelCommitWithoutUrlLoader) { + GURL start_url(embedded_test_server()->GetURL("/title1.html")); + EXPECT_TRUE(NavigateToURL(shell(), start_url)); + + GURL about_blank_url(url::kAboutBlankURL); + NavigationHandleObserver observer(shell()->web_contents(), about_blank_url); + TestNavigationThrottleInstaller installer( + shell()->web_contents(), NavigationThrottle::PROCEED, + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + NavigationThrottle::PROCEED, NavigationThrottle::CANCEL_AND_IGNORE); + + EXPECT_FALSE(NavigateToURL(shell(), about_blank_url)); + + EXPECT_FALSE(observer.has_committed()); + EXPECT_TRUE(observer.is_error()); + EXPECT_FALSE(observer.was_redirected()); + EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), start_url); +} + // Ensure that a NavigationThrottle can defer and resume the navigation at // navigation start, navigation redirect and response received. IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest, ThrottleDefer) { @@ -1098,7 +1190,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::DEFER, NavigationThrottle::DEFER, NavigationThrottle::DEFER, - NavigationThrottle::DEFER); + NavigationThrottle::DEFER, NavigationThrottle::DEFER); shell()->LoadURL(redirect_url); @@ -1108,6 +1200,7 @@ EXPECT_EQ(0, installer.will_redirect_called()); EXPECT_EQ(0, installer.will_fail_called()); EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); installer.navigation_throttle()->ResumeNavigation(); // Wait for WillRedirectRequest. @@ -1116,6 +1209,7 @@ EXPECT_EQ(1, installer.will_redirect_called()); EXPECT_EQ(0, installer.will_fail_called()); EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); installer.navigation_throttle()->ResumeNavigation(); // Wait for WillProcessResponse. @@ -1124,6 +1218,7 @@ EXPECT_EQ(1, installer.will_redirect_called()); EXPECT_EQ(0, installer.will_fail_called()); EXPECT_EQ(1, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); installer.navigation_throttle()->ResumeNavigation(); // Wait for the end of the navigation. @@ -1149,7 +1244,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::DEFER, NavigationThrottle::DEFER, NavigationThrottle::DEFER, - NavigationThrottle::DEFER); + NavigationThrottle::DEFER, NavigationThrottle::DEFER); shell()->LoadURL(failure_url); @@ -1159,6 +1254,7 @@ EXPECT_EQ(0, installer.will_redirect_called()); EXPECT_EQ(0, installer.will_fail_called()); EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); installer.navigation_throttle()->ResumeNavigation(); // Wait for WillFailRequest. @@ -1167,6 +1263,7 @@ EXPECT_EQ(0, installer.will_redirect_called()); EXPECT_EQ(1, installer.will_fail_called()); EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); installer.navigation_throttle()->ResumeNavigation(); // Wait for the end of the navigation. @@ -1177,6 +1274,180 @@ EXPECT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, observer.net_error_code()); } +// Ensure that a NavigationThrottle can defer and resume the navigation when +// navigating without a URLLoader. This test covers multiple types of +// navigations that do not require a URLLoader (same-document navigations and +// about:blank). +IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest, + ThrottleDeferCommitWithoutUrlLoader) { + GURL url(embedded_test_server()->GetURL("/title1.html")); + GURL url_fragment(embedded_test_server()->GetURL("/title1.html#id_1")); + GURL about_blank_url(url::kAboutBlankURL); + + // Perform a new-document navigation (setup). + { + TestNavigationThrottleInstaller installer( + shell()->web_contents(), NavigationThrottle::PROCEED, + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); + NavigationHandleObserver observer(shell()->web_contents(), url); + EXPECT_TRUE(NavigateToURL(shell(), url)); + EXPECT_EQ(1, installer.will_start_called()); + EXPECT_EQ(1, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); + EXPECT_FALSE(observer.is_same_document()); + } + + // Same-document navigation + { + TestNavigationObserver navigation_observer(shell()->web_contents(), 1); + NavigationHandleObserver observer(shell()->web_contents(), url_fragment); + TestNavigationThrottleInstaller installer( + shell()->web_contents(), NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER); + + shell()->LoadURL(url_fragment); + + // Wait for WillCommitWithoutUrlLoader. + installer.WaitForThrottleWillCommitWithoutUrlLoader(); + EXPECT_EQ(0, installer.will_start_called()); + EXPECT_EQ(0, installer.will_redirect_called()); + EXPECT_EQ(0, installer.will_fail_called()); + EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(1, installer.will_commit_without_url_loader_called()); + installer.navigation_throttle()->ResumeNavigation(); + + // Wait for the end of the navigation. + navigation_observer.Wait(); + + EXPECT_TRUE(observer.is_same_document()); + EXPECT_TRUE(observer.has_committed()); + EXPECT_FALSE(observer.was_redirected()); + EXPECT_FALSE(observer.is_error()); + EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), url_fragment); + } + + // about:blank + { + TestNavigationObserver navigation_observer(shell()->web_contents(), 1); + NavigationHandleObserver observer(shell()->web_contents(), about_blank_url); + TestNavigationThrottleInstaller installer( + shell()->web_contents(), NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER); + + shell()->LoadURL(about_blank_url); + + // Wait for WillCommitWithoutUrlLoader. + installer.WaitForThrottleWillCommitWithoutUrlLoader(); + EXPECT_EQ(0, installer.will_start_called()); + EXPECT_EQ(0, installer.will_redirect_called()); + EXPECT_EQ(0, installer.will_fail_called()); + EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(1, installer.will_commit_without_url_loader_called()); + installer.navigation_throttle()->ResumeNavigation(); + + // Wait for the end of the navigation. + navigation_observer.Wait(); + + EXPECT_FALSE(observer.is_same_document()); + EXPECT_TRUE(observer.has_committed()); + EXPECT_FALSE(observer.was_redirected()); + EXPECT_FALSE(observer.is_error()); + EXPECT_EQ(shell()->web_contents()->GetLastCommittedURL(), about_blank_url); + } +} + +// Ensure that a NavigationThrottle can defer and cancel the navigation when +// navigating without a URLLoader. This test covers multiple types of +// navigations that do not require a URLLoader (same-document navigations and +// about:blank). +IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest, + ThrottleDeferAndCancelCommitWithoutUrlLoader) { + GURL url(embedded_test_server()->GetURL("/title1.html")); + GURL url_fragment(embedded_test_server()->GetURL("/title1.html#id_1")); + GURL about_blank_url(url::kAboutBlankURL); + + // Perform a new-document navigation (setup). + { + TestNavigationThrottleInstaller installer( + shell()->web_contents(), NavigationThrottle::PROCEED, + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); + NavigationHandleObserver observer(shell()->web_contents(), url); + EXPECT_TRUE(NavigateToURL(shell(), url)); + EXPECT_EQ(1, installer.will_start_called()); + EXPECT_EQ(1, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); + EXPECT_FALSE(observer.is_same_document()); + } + + // Same-document navigation + { + TestNavigationObserver navigation_observer(shell()->web_contents(), 1); + NavigationHandleObserver observer(shell()->web_contents(), url_fragment); + TestNavigationThrottleInstaller installer( + shell()->web_contents(), NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER); + + shell()->LoadURL(url_fragment); + + // Wait for WillCommitWithoutUrlLoader. + installer.WaitForThrottleWillCommitWithoutUrlLoader(); + EXPECT_EQ(0, installer.will_start_called()); + EXPECT_EQ(0, installer.will_redirect_called()); + EXPECT_EQ(0, installer.will_fail_called()); + EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(1, installer.will_commit_without_url_loader_called()); + + // Cancel the deferred navigation. + installer.navigation_throttle()->CancelNavigation( + NavigationThrottle::CANCEL_AND_IGNORE); + + // Wait for the end of the navigation. + navigation_observer.Wait(); + + EXPECT_TRUE(observer.is_same_document()); + EXPECT_FALSE(observer.has_committed()); + EXPECT_FALSE(observer.was_redirected()); + EXPECT_TRUE(observer.is_error()); + } + + // about:blank + { + TestNavigationObserver navigation_observer(shell()->web_contents(), 1); + NavigationHandleObserver observer(shell()->web_contents(), about_blank_url); + TestNavigationThrottleInstaller installer( + shell()->web_contents(), NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER, + NavigationThrottle::DEFER, NavigationThrottle::DEFER); + + shell()->LoadURL(about_blank_url); + + // Wait for WillCommitWithoutUrlLoader. + installer.WaitForThrottleWillCommitWithoutUrlLoader(); + EXPECT_EQ(0, installer.will_start_called()); + EXPECT_EQ(0, installer.will_redirect_called()); + EXPECT_EQ(0, installer.will_fail_called()); + EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(1, installer.will_commit_without_url_loader_called()); + + // Cancel the deferred navigation. + installer.navigation_throttle()->CancelNavigation( + NavigationThrottle::CANCEL_AND_IGNORE); + + // Wait for the end of the navigation. + navigation_observer.Wait(); + + EXPECT_FALSE(observer.is_same_document()); + EXPECT_FALSE(observer.has_committed()); + EXPECT_FALSE(observer.was_redirected()); + EXPECT_TRUE(observer.is_error()); + } +} + // Ensure that a NavigationThrottle can block the navigation and collapse the // frame owner both on request start as well as after a redirect. Plus, ensure // that the frame is restored on the subsequent non-error-page navigation. @@ -1220,13 +1491,15 @@ std::make_unique<TestDeferringNavigationThrottleInstaller>( shell()->web_contents(), test_case.will_start_result, test_case.will_redirect_result, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED, blocked_subframe_url); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + blocked_subframe_url); } else { subframe_throttle_installer = std::make_unique<TestNavigationThrottleInstaller>( shell()->web_contents(), test_case.will_start_result, test_case.will_redirect_result, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED, blocked_subframe_url); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + blocked_subframe_url); } { @@ -1289,7 +1562,8 @@ TestNavigationThrottleInstaller subframe_throttle_installer( shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST_AND_COLLAPSE, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED, blocked_subframe_url); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + blocked_subframe_url); { SCOPED_TRACE("Initial navigation blocked on main frame load."); @@ -1333,7 +1607,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); TestNavigationManager main_manager(shell()->web_contents(), main_url); TestNavigationManager b_manager(shell()->web_contents(), b_url); TestNavigationManager c_manager(shell()->web_contents(), c_url); @@ -1385,7 +1659,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); TestNavigationManager link_manager(shell()->web_contents(), link_url); NavigationStartUrlRecorder url_recorder(shell()->web_contents()); @@ -1418,7 +1692,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); TestNavigationManager post_manager(shell()->web_contents(), post_url); NavigationStartUrlRecorder url_recorder(shell()->web_contents()); @@ -1456,7 +1730,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::CANCEL_AND_IGNORE, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), kUrl); // Try to navigate to the url. The navigation should be canceled and the @@ -1471,7 +1745,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::CANCEL_AND_IGNORE, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), kRedirectingUrl); // Try to navigate to the url. The navigation should be canceled and the @@ -1486,7 +1760,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::CANCEL_AND_IGNORE); + NavigationThrottle::CANCEL_AND_IGNORE, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), kUrl); // Try to navigate to the url. The navigation should be canceled and the @@ -1501,7 +1775,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), kUrl); // Try to navigate to the url. The navigation should be canceled and the @@ -1515,7 +1789,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), kRedirectingUrl); // Try to navigate to the url. The navigation should be canceled and the @@ -1545,7 +1819,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::CANCEL_AND_IGNORE, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); EXPECT_FALSE(NavigateToURL(shell(), kUrl2)); } @@ -1646,7 +1920,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); TestNavigationManager navigation_manager(shell()->web_contents(), iframe_secure_url); @@ -1757,6 +2031,9 @@ // Ensure that browser-initiated same-document navigations are detected and // don't issue network requests. See crbug.com/663777. +// Browser-initiated same-document navigations should trigger a +// WillCommitWithoutUrlLoader() callback, instead of the WillStartRequest() +// and WillProcessResponse() callbacks used when there is a network request. IN_PROC_BROWSER_TEST_F(NavigationRequestBrowserTest, SameDocumentBrowserInitiatedNoReload) { GURL url(embedded_test_server()->GetURL("/title1.html")); @@ -1768,11 +2045,12 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), url); EXPECT_TRUE(NavigateToURL(shell(), url)); EXPECT_EQ(1, installer.will_start_called()); EXPECT_EQ(1, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); EXPECT_FALSE(observer.is_same_document()); } @@ -1781,11 +2059,12 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), url_fragment_1); EXPECT_TRUE(NavigateToURL(shell(), url_fragment_1)); EXPECT_EQ(0, installer.will_start_called()); EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(1, installer.will_commit_without_url_loader_called()); EXPECT_TRUE(observer.is_same_document()); } @@ -1794,11 +2073,12 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2); EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); EXPECT_EQ(0, installer.will_start_called()); EXPECT_EQ(0, installer.will_process_called()); + EXPECT_EQ(1, installer.will_commit_without_url_loader_called()); EXPECT_TRUE(observer.is_same_document()); } @@ -1807,11 +2087,12 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), url_fragment_2); EXPECT_TRUE(NavigateToURL(shell(), url_fragment_2)); EXPECT_EQ(1, installer.will_start_called()); EXPECT_EQ(1, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); EXPECT_FALSE(observer.is_same_document()); } @@ -1820,11 +2101,12 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), url); EXPECT_TRUE(NavigateToURL(shell(), url)); EXPECT_EQ(1, installer.will_start_called()); EXPECT_EQ(1, installer.will_process_called()); + EXPECT_EQ(0, installer.will_commit_without_url_loader_called()); EXPECT_FALSE(observer.is_same_document()); } } @@ -1900,7 +2182,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver observer(shell()->web_contents(), kRedirectingUrl); NavigationLogger logger(shell()->web_contents()); @@ -1970,7 +2252,7 @@ auto installer = std::make_unique<TestNavigationThrottleInstaller>( shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); { // A blocked, renderer-initiated navigation in the main frame should commit @@ -2053,7 +2335,7 @@ installer = std::make_unique<TestNavigationThrottleInstaller>( shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); { // A blocked, browser-initiated navigation should commit an error page in a @@ -2094,7 +2376,7 @@ installer = std::make_unique<TestNavigationThrottleInstaller>( shell()->web_contents(), NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); content::RenderFrameHost* rfh = shell()->web_contents()->GetPrimaryMainFrame(); @@ -2312,8 +2594,9 @@ new TestNavigationThrottle( handle, NavigationThrottle::DEFER, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED, base::DoNothing(), - base::DoNothing(), base::DoNothing(), base::DoNothing())); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + base::DoNothing(), base::DoNothing(), base::DoNothing(), + base::DoNothing(), base::DoNothing())); client_throttle = throttle.get(); throttles.push_back(std::move(throttle)); return throttles; @@ -2324,7 +2607,8 @@ // before browser client throttles are registered. TestNavigationThrottleInstaller test_throttle_installer( web_contents, NavigationThrottle::DEFER, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, + NavigationThrottle::PROCEED); // Start navigating. TestNavigationManager manager(shell()->web_contents(), simple_url); @@ -2374,7 +2658,7 @@ TestNavigationThrottleInstaller installer( web_contents, NavigationThrottle::BLOCK_REQUEST, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigationHandleObserver commit_observer(web_contents, blocked_url); EXPECT_FALSE(NavigateToURL(shell(), blocked_url)); NavigationEntry* last_committed = @@ -2513,7 +2797,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); NavigateIframeToURL(shell()->web_contents(), "child0", iframe_url); @@ -2809,7 +3093,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::CANCEL, NavigationThrottle::PROCEED, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); EXPECT_TRUE(NavigateToURLAndExpectNoCommit(shell(), url)); EXPECT_FALSE(observer.has_committed()); @@ -2836,7 +3120,7 @@ TestNavigationThrottleInstaller installer( shell()->web_contents(), NavigationThrottle::PROCEED, NavigationThrottle::CANCEL, NavigationThrottle::PROCEED, - NavigationThrottle::PROCEED); + NavigationThrottle::PROCEED, NavigationThrottle::PROCEED); EXPECT_FALSE(NavigateToURL(shell(), redirect_url)); @@ -3555,7 +3839,8 @@ NavigationThrottle::PROCEED /* will_start_result */, NavigationThrottle::PROCEED /* will_redirect_result */, NavigationThrottle::DEFER /* will_fail_result */, - NavigationThrottle::PROCEED /* will_process_result */); + NavigationThrottle::PROCEED /* will_process_result */, + NavigationThrottle::PROCEED /* will_commit_without_url_loader_result */); // Start a navigation to foo.com that will result in an error. shell()->web_contents()->GetController().LoadURL(
diff --git a/content/browser/renderer_host/navigation_request_unittest.cc b/content/browser/renderer_host/navigation_request_unittest.cc index 379157f..01116fa 100644 --- a/content/browser/renderer_host/navigation_request_unittest.cc +++ b/content/browser/renderer_host/navigation_request_unittest.cc
@@ -144,6 +144,22 @@ GetNavigationRequest()->WillFailRequest(); } + // Helper function to call WillCommitWithoutUrlLoader on |handle|. If this + // function returns DEFER, |callback_result_| will be set to the actual result + // of the throttle checks when they are finished. + void SimulateWillCommitWithoutUrlLoader() { + was_callback_called_ = false; + callback_result_ = NavigationThrottle::DEFER; + + // It's safe to use base::Unretained since the NavigationRequest is owned by + // the NavigationRequestTest. + GetNavigationRequest()->set_complete_callback_for_testing( + base::BindOnce(&NavigationRequestTest::UpdateThrottleCheckResult, + base::Unretained(this))); + + GetNavigationRequest()->WillCommitWithoutUrlLoader(); + } + // Whether the callback was called. bool was_callback_called() const { return was_callback_called_; } @@ -160,7 +176,8 @@ int start, int redirect, int failure, - int process) { + int process, + int withoutUrlLoader) { return start == throttle->GetCallCount( TestNavigationThrottle::WILL_START_REQUEST) && redirect == throttle->GetCallCount( @@ -168,7 +185,10 @@ failure == throttle->GetCallCount( TestNavigationThrottle::WILL_FAIL_REQUEST) && process == throttle->GetCallCount( - TestNavigationThrottle::WILL_PROCESS_RESPONSE); + TestNavigationThrottle::WILL_PROCESS_RESPONSE) && + withoutUrlLoader == + throttle->GetCallCount( + TestNavigationThrottle::WILL_COMMIT_WITHOUT_URL_LOADER); } // Creates, register and returns a TestNavigationThrottle that will @@ -332,21 +352,21 @@ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(NavigationThrottle::DEFER); EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); - EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0)); // Simulate WillStartRequest. The request should be deferred. The callback // should not have been called. SimulateWillStartRequest(); EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); EXPECT_FALSE(was_callback_called()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0)); // Cancel the request. The callback should have been called. CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE); EXPECT_EQ(NavigationRequest::CANCELING, state()); EXPECT_TRUE(was_callback_called()); EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0)); } // Checks that a navigation deferred during WillRedirectRequest can be properly @@ -355,21 +375,21 @@ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(NavigationThrottle::DEFER); EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); - EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0)); // Simulate WillRedirectRequest. The request should be deferred. The callback // should not have been called. SimulateWillRedirectRequest(); EXPECT_EQ(NavigationRequest::WILL_REDIRECT_REQUEST, state()); EXPECT_FALSE(was_callback_called()); - EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0, 0)); // Cancel the request. The callback should have been called. CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE); EXPECT_EQ(NavigationRequest::CANCELING, state()); EXPECT_TRUE(was_callback_called()); EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result()); - EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 1, 0, 0, 0)); } // Checks that a navigation deferred during WillFailRequest can be properly @@ -378,25 +398,25 @@ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle( TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER); EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); - EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0)); // Simulate WillStartRequest. SimulateWillStartRequest(); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0)); // Simulate WillFailRequest. The request should be deferred. The callback // should not have been called. SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID); EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state()); EXPECT_FALSE(was_callback_called()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0)); // Cancel the request. The callback should have been called. CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE); EXPECT_EQ(NavigationRequest::CANCELING, state()); EXPECT_TRUE(was_callback_called()); EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0)); } // Checks that a navigation deferred can be canceled and not ignored. @@ -404,13 +424,13 @@ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle(NavigationThrottle::DEFER); EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); - EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0)); // Simulate WillStartRequest. The request should be deferred. The callback // should not have been called. SimulateWillStartRequest(); EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0)); // Cancel the request. The callback should have been called with CANCEL, and // not CANCEL_AND_IGNORE. @@ -418,7 +438,7 @@ EXPECT_EQ(NavigationRequest::CANCELING, state()); EXPECT_TRUE(was_callback_called()); EXPECT_EQ(NavigationThrottle::CANCEL, callback_result()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0)); } // Checks that a navigation deferred by WillFailRequest can be canceled and not @@ -427,18 +447,18 @@ TestNavigationThrottle* test_throttle = CreateTestNavigationThrottle( TestNavigationThrottle::WILL_FAIL_REQUEST, NavigationThrottle::DEFER); EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); - EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0)); // Simulate WillStartRequest. SimulateWillStartRequest(); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 0, 0, 0)); // Simulate WillFailRequest. The request should be deferred. The callback // should not have been called. SimulateWillFailRequest(net::ERR_CERT_DATE_INVALID); EXPECT_EQ(NavigationRequest::WILL_FAIL_REQUEST, state()); EXPECT_FALSE(was_callback_called()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0)); // Cancel the request. The callback should have been called with CANCEL, and // not CANCEL_AND_IGNORE. @@ -446,7 +466,30 @@ EXPECT_EQ(NavigationRequest::CANCELING, state()); EXPECT_TRUE(was_callback_called()); EXPECT_EQ(NavigationThrottle::CANCEL, callback_result()); - EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0)); + EXPECT_TRUE(call_counts_match(test_throttle, 1, 0, 1, 0, 0)); +} + +// Checks that a navigation deferred during WillCommitWithoutUrlLoader can be +// properly cancelled. +TEST_F(NavigationRequestTest, CancelDeferredWillCommitWithoutUrlLoader) { + TestNavigationThrottle* test_throttle = + CreateTestNavigationThrottle(NavigationThrottle::DEFER); + EXPECT_EQ(NavigationRequest::WILL_START_REQUEST, state()); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 0)); + + // Simulate WillCommitWithoutUrlLoader. The request should be deferred. The + // callback should not have been called. + SimulateWillCommitWithoutUrlLoader(); + EXPECT_EQ(NavigationRequest::WILL_COMMIT_WITHOUT_URL_LOADER, state()); + EXPECT_FALSE(was_callback_called()); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 1)); + + // Cancel the request. The callback should have been called. + CancelDeferredNavigation(NavigationThrottle::CANCEL_AND_IGNORE); + EXPECT_EQ(NavigationRequest::CANCELING, state()); + EXPECT_TRUE(was_callback_called()); + EXPECT_EQ(NavigationThrottle::CANCEL_AND_IGNORE, callback_result()); + EXPECT_TRUE(call_counts_match(test_throttle, 0, 0, 0, 0, 1)); } // Checks that data from the SSLInfo passed into SimulateWillStartRequest() is
diff --git a/content/browser/renderer_host/navigation_throttle_runner.cc b/content/browser/renderer_host/navigation_throttle_runner.cc index c93cbc9..bf471013 100644 --- a/content/browser/renderer_host/navigation_throttle_runner.cc +++ b/content/browser/renderer_host/navigation_throttle_runner.cc
@@ -39,6 +39,8 @@ return throttle->WillFailRequest(); case NavigationThrottleRunner::Event::WillProcessResponse: return throttle->WillProcessResponse(); + case NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader: + return throttle->WillCommitWithoutUrlLoader(); default: NOTREACHED(); } @@ -56,6 +58,8 @@ return "NavigationThrottle::WillFailRequest"; case NavigationThrottleRunner::Event::WillProcessResponse: return "NavigationThrottle::WillProcessResponse"; + case NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader: + return "NavigationThrottle::WillCommitWithoutUrlLoader"; default: NOTREACHED(); } @@ -72,6 +76,8 @@ return "WillFailRequest"; case NavigationThrottleRunner::Event::WillProcessResponse: return "WillProcessResponse"; + case NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader: + return "WillCommitWithoutUrlLoader"; default: NOTREACHED(); } @@ -197,6 +203,33 @@ std::make_move_iterator(testing_throttles.end())); } +void NavigationThrottleRunner:: + RegisterNavigationThrottlesForCommitWithoutUrlLoader() { + // Note: |throttle_| might not be empty. Some NavigationThrottles might have + // been registered with RegisterThrottleForTesting. These must reside at the + // end of |throttles_|. TestNavigationManagerThrottle expects that the + // NavigationThrottles added for test are the last NavigationThrottles to + // execute. Take them out while appending the rest of the + // NavigationThrottles. + std::vector<std::unique_ptr<NavigationThrottle>> testing_throttles = + std::move(throttles_); + + // The NavigationRequest associated with the NavigationThrottles this + // NavigationThrottleRunner manages. + // Unit tests that do not use NavigationRequest should never call + // RegisterNavigationThrottlesForCommitWithoutUrlLoader as this function + // expects |delegate_| to be a NavigationRequest. + // + // TODO(japhet): Uncomment this once there are throttles for commits without + // a URL loader. + // NavigationRequest* request = static_cast<NavigationRequest*>(delegate_); + + // Insert all testing NavigationThrottles last. + throttles_.insert(throttles_.end(), + std::make_move_iterator(testing_throttles.begin()), + std::make_move_iterator(testing_throttles.end())); +} + NavigationThrottle* NavigationThrottleRunner::GetDeferringThrottle() const { if (next_index_ == 0) return nullptr;
diff --git a/content/browser/renderer_host/navigation_throttle_runner.h b/content/browser/renderer_host/navigation_throttle_runner.h index ca43aba..c0460205 100644 --- a/content/browser/renderer_host/navigation_throttle_runner.h +++ b/content/browser/renderer_host/navigation_throttle_runner.h
@@ -28,6 +28,7 @@ WillRedirectRequest = 2, WillFailRequest = 3, WillProcessResponse = 4, + WillCommitWithoutUrlLoader = 5, }; class Delegate { @@ -64,8 +65,16 @@ // deferring NavigationThrottle do the resuming. void CallResumeForTesting(); + // Registers the appropriate NavigationThrottles are added for a "standard" + // navigation (i.e., one with a URLLoader that goes through the + // WillSendRequest/WillProcessResponse callback sequence). void RegisterNavigationThrottles(); + // Registers the appropriate NavigationThrottles for a navigation that can + // immediately commit because no URLLoader is required (about:blank, + // about:srcdoc, and most same-document navigations). + void RegisterNavigationThrottlesForCommitWithoutUrlLoader(); + // Returns the throttle that is currently deferring the navigation (i.e. the // throttle at index |next_index_ -1|). If the handle is not deferred, returns // nullptr;
diff --git a/content/browser/renderer_host/navigation_throttle_runner_unittest.cc b/content/browser/renderer_host/navigation_throttle_runner_unittest.cc index 91f14a5..c2eff8cb 100644 --- a/content/browser/renderer_host/navigation_throttle_runner_unittest.cc +++ b/content/browser/renderer_host/navigation_throttle_runner_unittest.cc
@@ -46,6 +46,12 @@ return NavigationThrottle::PROCEED; } + NavigationThrottle::ThrottleCheckResult WillCommitWithoutUrlLoader() + override { + deletion_callback_.Run(); + return NavigationThrottle::PROCEED; + } + const char* GetNameForLogging() override { return "DeletingNavigationThrottle"; } @@ -131,6 +137,13 @@ CHECK_EQ(0, throttle->GetCallCount( TestNavigationThrottle::WILL_PROCESS_RESPONSE)); } + if (event == NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader) { + CHECK_EQ(1, throttle->GetCallCount( + TestNavigationThrottle::WILL_COMMIT_WITHOUT_URL_LOADER)); + } else { + CHECK_EQ(0, throttle->GetCallCount( + TestNavigationThrottle::WILL_COMMIT_WITHOUT_URL_LOADER)); + } } // Creates, register and returns a TestNavigationThrottle that will @@ -264,10 +277,12 @@ INSTANTIATE_TEST_SUITE_P( AllEvents, NavigationThrottleRunnerTestWithEvent, - ::testing::Values(NavigationThrottleRunner::Event::WillStartRequest, - NavigationThrottleRunner::Event::WillRedirectRequest, - NavigationThrottleRunner::Event::WillFailRequest, - NavigationThrottleRunner::Event::WillProcessResponse)); + ::testing::Values( + NavigationThrottleRunner::Event::WillStartRequest, + NavigationThrottleRunner::Event::WillRedirectRequest, + NavigationThrottleRunner::Event::WillFailRequest, + NavigationThrottleRunner::Event::WillProcessResponse, + NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader)); class NavigationThrottleRunnerTestWithEventAndAction : public NavigationThrottleRunnerTest, @@ -411,10 +426,12 @@ AllEvents, NavigationThrottleRunnerTestWithEventAndAction, ::testing::Combine( - ::testing::Values(NavigationThrottleRunner::Event::WillStartRequest, - NavigationThrottleRunner::Event::WillRedirectRequest, - NavigationThrottleRunner::Event::WillFailRequest, - NavigationThrottleRunner::Event::WillProcessResponse), + ::testing::Values( + NavigationThrottleRunner::Event::WillStartRequest, + NavigationThrottleRunner::Event::WillRedirectRequest, + NavigationThrottleRunner::Event::WillFailRequest, + NavigationThrottleRunner::Event::WillProcessResponse, + NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader), ::testing::Values(NavigationThrottle::PROCEED, NavigationThrottle::CANCEL, NavigationThrottle::CANCEL_AND_IGNORE, @@ -490,10 +507,12 @@ AllEvents, NavigationThrottleRunnerTestWithEventAndError, ::testing::Combine( - ::testing::Values(NavigationThrottleRunner::Event::WillStartRequest, - NavigationThrottleRunner::Event::WillRedirectRequest, - NavigationThrottleRunner::Event::WillFailRequest, - NavigationThrottleRunner::Event::WillProcessResponse), + ::testing::Values( + NavigationThrottleRunner::Event::WillStartRequest, + NavigationThrottleRunner::Event::WillRedirectRequest, + NavigationThrottleRunner::Event::WillFailRequest, + NavigationThrottleRunner::Event::WillProcessResponse, + NavigationThrottleRunner::Event::WillCommitWithoutUrlLoader), ::testing::Values(net::ERR_BLOCKED_BY_ADMINISTRATOR, net::ERR_ABORTED), ::testing::Values(absl::nullopt, "<html><body>test</body></html>")));
diff --git a/content/browser/renderer_host/render_frame_host_impl.cc b/content/browser/renderer_host/render_frame_host_impl.cc index 7da6528..f8da6ee 100644 --- a/content/browser/renderer_host/render_frame_host_impl.cc +++ b/content/browser/renderer_host/render_frame_host_impl.cc
@@ -14448,12 +14448,6 @@ "security_origin", security_origin, "target_url", target_url); - // TODO(nick, estark): Should we call FilterURL using this frame's process on - // these parameters? |target_url| seems unused, except for a log message. And - // |security_origin| might be replaceable with the origin of the main frame. - - LOG(WARNING) << security_origin << " ran insecure content from " - << target_url.possibly_invalid_spec(); RecordAction(base::UserMetricsAction("SSL.RanInsecureContent")); if (base::EndsWith(security_origin.spec(), kDotGoogleDotCom, base::CompareCase::INSENSITIVE_ASCII)) {
diff --git a/content/browser/renderer_host/render_frame_host_impl.h b/content/browser/renderer_host/render_frame_host_impl.h index a03092f9..136a9007 100644 --- a/content/browser/renderer_host/render_frame_host_impl.h +++ b/content/browser/renderer_host/render_frame_host_impl.h
@@ -3788,8 +3788,10 @@ // SiteInstance::GetProcess()/GetOrCreateAgentSchedulingGroupHost() has the // side effect of creating the process again if it is gone. // - // TODO(https://crbug.com/1382971): Change back to `raw_ref` after the ad-hoc - // debugging is no longer needed to investigate the bug. + // It is a `SafeRef` so that the browser process crashes cleanly if `this` + // unintentionally outlives its associated `RenderFrameProcessHost` but tries + // to access it or its associated `AgentSchedulingGroupHost` (see + // crbug.com/1297030). const base::SafeRef<AgentSchedulingGroupHost> agent_scheduling_group_; // Reference to the whole frame tree that this RenderFrameHost belongs to.
diff --git a/content/browser/web_contents/aura/OWNERS b/content/browser/web_contents/aura/OWNERS index c65e542..90b3e80 100644 --- a/content/browser/web_contents/aura/OWNERS +++ b/content/browser/web_contents/aura/OWNERS
@@ -1 +1 @@ -mohsen@chromium.org +sky@chromium.org
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc index 705e3fa4..c71f65f 100644 --- a/content/browser/web_contents/web_contents_impl.cc +++ b/content/browser/web_contents/web_contents_impl.cc
@@ -4595,13 +4595,6 @@ std::vector<ui::AXPropertyFilter> property_filters) { OPTIONAL_TRACE_EVENT0("content", "WebContentsImpl::DumpAccessibilityTree"); auto* ax_mgr = GetOrCreateRootBrowserAccessibilityManager(); - DCHECK(ax_mgr); - - // Developer mode: crash immediately on any accessibility fatal error. - // This only runs during integration tests, or if a developer is - // using an inspection tool, e.g. chrome://accessibility. - BrowserAccessibilityManager::AlwaysFailFast(); - // Since for Web Content we get the AXTree updates through the renderer at a // point after the manager is created, there are cases where at this point in // the lifecycle the AXTree associated with `ax_mgr` does not have a valid @@ -4609,9 +4602,14 @@ // we don't have this check, there will be a scenario where we then try to get // the manager using the ID (which at this point is invalid) which leads to a // crash. See https://crbug.com/1405036. - if (!ax_mgr->HasValidTreeID()) + if (!ax_mgr || !ax_mgr->HasValidTreeID()) return "-"; + // Developer mode: crash immediately on any accessibility fatal error. + // This only runs during integration tests, or if a developer is + // using an inspection tool, e.g. chrome://accessibility. + BrowserAccessibilityManager::AlwaysFailFast(); + std::unique_ptr<ui::AXTreeFormatter> formatter = internal ? AXInspectFactory::CreateBlinkFormatter() : AXInspectFactory::CreatePlatformFormatter();
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc index a1fbaede..2433969 100644 --- a/content/browser/web_contents/web_contents_impl_browsertest.cc +++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -310,6 +310,26 @@ load_observer.controller_); } +// Regression test for https://crbug.com/1405036 +// Dumping the accessibility tree should not crash, even if it has not received +// an ID through a renderer tree yet. +IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest, + DumpAccessibilityTreeWithoutTreeID) { + ASSERT_TRUE(embedded_test_server()->Start()); + + LoadStopNotificationObserver load_observer( + &shell()->web_contents()->GetController()); + EXPECT_TRUE( + NavigateToURL(shell(), embedded_test_server()->GetURL("/title1.html"))); + load_observer.Wait(); + std::string expected = "-"; + + std::vector<ui::AXPropertyFilter> property_filters; + EXPECT_EQ( + shell()->web_contents()->DumpAccessibilityTree(false, property_filters), + expected); +} + // Test that DidStopLoading includes the correct URL in the details when a // pending entry is present. IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
diff --git a/content/public/browser/navigation_throttle.cc b/content/public/browser/navigation_throttle.cc index 0fdd474cb..1d47d841 100644 --- a/content/public/browser/navigation_throttle.cc +++ b/content/public/browser/navigation_throttle.cc
@@ -80,6 +80,11 @@ return NavigationThrottle::PROCEED; } +NavigationThrottle::ThrottleCheckResult +NavigationThrottle::WillCommitWithoutUrlLoader() { + return NavigationThrottle::PROCEED; +} + void NavigationThrottle::Resume() { if (resume_callback_) { resume_callback_.Run();
diff --git a/content/public/browser/navigation_throttle.h b/content/public/browser/navigation_throttle.h index fb335d4a..ea059b7 100644 --- a/content/public/browser/navigation_throttle.h +++ b/content/public/browser/navigation_throttle.h
@@ -169,6 +169,24 @@ // asynchronously. virtual ThrottleCheckResult WillProcessResponse(); + // Called when a navigation is about to immediately commit because there's no + // need for a url loader. This includes browser-initiated same-document + // navigations, same-document history navigations, about:blank, about:srcdoc, + // any other empty document scheme, and MHTML subframes. + // Renderer-initiated non-history same-document navigations do NOT go through + // this path, because they are handled synchronously in the renderer and the + // browser process is only notified after the fact. + // BFCache and prerender activation also do NOT go through this path, because + // they are considered already loaded when they are activated. + // In order to get this event, a NavigationThrottle must register itself with + // RegisterNavigationThrottlesForCommitWithoutUrlLoader(). + // This event is mutually exclusive with WillStartRequest, + // WillRedirectRequest, and WillProcessResponse. Only WillFailRequest can + // be called after WillCommitWithoutUrlLoader. + // Only PROCEED, DEFER, and CANCEL_AND_IGNORE results are supported at this + // time. + virtual ThrottleCheckResult WillCommitWithoutUrlLoader(); + // Returns the name of the throttle for logging purposes. It must not return // nullptr. virtual const char* GetNameForLogging() = 0;
diff --git a/content/public/test/test_navigation_throttle.cc b/content/public/test/test_navigation_throttle.cc index c5e7fc60..41c112ba 100644 --- a/content/public/test/test_navigation_throttle.cc +++ b/content/public/test/test_navigation_throttle.cc
@@ -37,6 +37,11 @@ return ProcessMethod(WILL_PROCESS_RESPONSE); } +NavigationThrottle::ThrottleCheckResult +TestNavigationThrottle::WillCommitWithoutUrlLoader() { + return ProcessMethod(WILL_COMMIT_WITHOUT_URL_LOADER); +} + const char* TestNavigationThrottle::GetNameForLogging() { return "TestNavigationThrottle"; }
diff --git a/content/public/test/test_navigation_throttle.h b/content/public/test/test_navigation_throttle.h index 7538fe6..886c504 100644 --- a/content/public/test/test_navigation_throttle.h +++ b/content/public/test/test_navigation_throttle.h
@@ -25,6 +25,7 @@ WILL_REDIRECT_REQUEST, WILL_FAIL_REQUEST, WILL_PROCESS_RESPONSE, + WILL_COMMIT_WITHOUT_URL_LOADER, NUM_THROTTLE_METHODS }; @@ -45,6 +46,7 @@ NavigationThrottle::ThrottleCheckResult WillRedirectRequest() override; NavigationThrottle::ThrottleCheckResult WillFailRequest() override; NavigationThrottle::ThrottleCheckResult WillProcessResponse() override; + NavigationThrottle::ThrottleCheckResult WillCommitWithoutUrlLoader() override; const char* GetNameForLogging() override; // Return how often the indicated |method| was called.
diff --git a/content/renderer/renderer_blink_platform_impl.cc b/content/renderer/renderer_blink_platform_impl.cc index a0811da..8bb04c9 100644 --- a/content/renderer/renderer_blink_platform_impl.cc +++ b/content/renderer/renderer_blink_platform_impl.cc
@@ -239,6 +239,15 @@ RendererBlinkPlatformImpl::WrapURLLoaderFactory( blink::CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase> url_loader_factory) { + return WrapURLLoaderFactory( + base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>( + mojo::PendingRemote<network::mojom::URLLoaderFactory>( + std::move(url_loader_factory)))); +} + +std::unique_ptr<blink::WebURLLoaderFactory> +RendererBlinkPlatformImpl::WrapURLLoaderFactory( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { // Check that there is always a main thread. It used to be possible to run // this code with a fuzzer without having a main thread, which is no longer // possible now. @@ -252,10 +261,7 @@ return blink::WebString::FromLatin1(h); }); return std::make_unique<blink::WebURLLoaderFactory>( - base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>( - mojo::PendingRemote<network::mojom::URLLoaderFactory>( - std::move(url_loader_factory))), - web_cors_exempt_header_list, + std::move(url_loader_factory), web_cors_exempt_header_list, /*terminate_sync_load_event=*/nullptr); }
diff --git a/content/renderer/renderer_blink_platform_impl.h b/content/renderer/renderer_blink_platform_impl.h index f9b61ff32..9678df0 100644 --- a/content/renderer/renderer_blink_platform_impl.h +++ b/content/renderer/renderer_blink_platform_impl.h
@@ -36,6 +36,10 @@ #include "third_party/skia/include/core/SkRefCnt.h" // nogncheck #endif +namespace network { +class SharedURLLoaderFactory; +} // namespace network + namespace blink { namespace scheduler { class WebThreadScheduler; @@ -208,6 +212,9 @@ blink::CrossVariantMojoRemote< network::mojom::URLLoaderFactoryInterfaceBase> url_loader_factory) override; + std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) + override; std::unique_ptr<media::MediaLog> GetMediaLog( blink::MediaInspectorContext* inspector_context, scoped_refptr<base::SingleThreadTaskRunner> owner_task_runner,
diff --git a/content/renderer/service_worker/service_worker_network_provider_for_frame.cc b/content/renderer/service_worker/service_worker_network_provider_for_frame.cc index 23467ba..a7c189b8 100644 --- a/content/renderer/service_worker/service_worker_network_provider_for_frame.cc +++ b/content/renderer/service_worker/service_worker_network_provider_for_frame.cc
@@ -15,7 +15,6 @@ #include "content/renderer/render_thread_impl.h" #include "content/renderer/service_worker/service_worker_provider_context.h" #include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h" -#include "third_party/blink/public/platform/web_back_forward_cache_loader_helper.h" #include "third_party/blink/public/platform/web_url_loader.h" #include "third_party/blink/public/web/web_local_frame.h" @@ -104,25 +103,13 @@ request.SetFetchWindowId(context()->fetch_request_window_id()); } -std::unique_ptr<blink::WebURLLoader> -ServiceWorkerNetworkProviderForFrame::CreateURLLoader( - const blink::WebURLRequest& request, - std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> - freezable_task_runner_handle, - std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> - unfreezable_task_runner_handle, - blink::CrossVariantMojoRemote<blink::mojom::KeepAliveHandleInterfaceBase> - keep_alive_handle, - blink::WebBackForwardCacheLoaderHelper back_forward_cache_loader_helper) { +scoped_refptr<network::SharedURLLoaderFactory> +ServiceWorkerNetworkProviderForFrame::GetSubresourceLoaderFactory( + const blink::WebURLRequest& request) { // RenderThreadImpl is nullptr in some tests. if (!RenderThreadImpl::current()) return nullptr; - // We need SubresourceLoaderFactory populated in order to create our own - // URLLoader for subresource loading. - if (!context() || !context()->GetSubresourceLoaderFactory()) - return nullptr; - // If the URL is not http(s) or otherwise allowed, do not intercept the // request. Schemes like 'blob' and 'file' are not eligible to be intercepted // by service workers. @@ -137,6 +124,11 @@ if (request.GetSkipServiceWorker()) return nullptr; + // We need SubresourceLoaderFactory populated. + if (!context() || !context()->GetSubresourceLoaderFactory()) { + return nullptr; + } + // Record use counter for intercepting requests from opaque stylesheets. // TODO(crbug.com/898497): Remove this feature usage once we have enough data. if (observer_ && request.IsFromOriginDirtyStyleSheet()) { @@ -145,24 +137,9 @@ kServiceWorkerInterceptedRequestFromOriginDirtyStyleSheet); } - std::vector<std::string> cors_exempt_header_list = - RenderThreadImpl::current()->cors_exempt_header_list(); - blink::WebVector<blink::WebString> web_cors_exempt_header_list( - cors_exempt_header_list.size()); - std::transform(cors_exempt_header_list.begin(), cors_exempt_header_list.end(), - web_cors_exempt_header_list.begin(), [](const std::string& h) { - return blink::WebString::FromLatin1(h); - }); - - // Create our own SubresourceLoader to route the request to the controller + // Returns our own SubresourceLoader to route the request to the controller // ServiceWorker. - return std::make_unique<blink::WebURLLoader>( - web_cors_exempt_header_list, - /*terminate_sync_load_event=*/nullptr, - std::move(freezable_task_runner_handle), - std::move(unfreezable_task_runner_handle), - context()->GetSubresourceLoaderFactory(), std::move(keep_alive_handle), - back_forward_cache_loader_helper); + return context()->GetSubresourceLoaderFactory(); } blink::mojom::ControllerServiceWorkerMode
diff --git a/content/renderer/service_worker/service_worker_network_provider_for_frame.h b/content/renderer/service_worker/service_worker_network_provider_for_frame.h index 348e794b..172707a 100644 --- a/content/renderer/service_worker/service_worker_network_provider_for_frame.h +++ b/content/renderer/service_worker/service_worker_network_provider_for_frame.h
@@ -43,16 +43,8 @@ // Implements WebServiceWorkerNetworkProvider. void WillSendRequest(blink::WebURLRequest& request) override; - std::unique_ptr<blink::WebURLLoader> CreateURLLoader( - const blink::WebURLRequest& request, - std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> - freezable_task_runner_handle, - std::unique_ptr<blink::scheduler::WebResourceLoadingTaskRunnerHandle> - unfreezable_task_runner_handle, - blink::CrossVariantMojoRemote<blink::mojom::KeepAliveHandleInterfaceBase> - keep_alive_handle, - blink::WebBackForwardCacheLoaderHelper back_forward_cache_loader_helper) - override; + scoped_refptr<network::SharedURLLoaderFactory> GetSubresourceLoaderFactory( + const blink::WebURLRequest& request) override; blink::mojom::ControllerServiceWorkerMode GetControllerServiceWorkerMode() override; blink::mojom::ServiceWorkerFetchHandlerType GetFetchHandlerType() override;
diff --git a/content/shell/BUILD.gn b/content/shell/BUILD.gn index a4d5f0a..af0eea2 100644 --- a/content/shell/BUILD.gn +++ b/content/shell/BUILD.gn
@@ -558,8 +558,12 @@ declare_args() { # The bundle identifier. Overriding this will affect the provisioning profile # used, and hence will affect the app's capabilities. - ios_content_shell_bundle_identifier = - "$ios_app_bundle_id_prefix.ios-content-shell" + if (ios_use_shared_bundle_id_for_test_apps) { + ios_content_shell_bundle_identifier = shared_bundle_id_for_test_apps + } else { + ios_content_shell_bundle_identifier = + "$ios_app_bundle_id_prefix.ios-content-shell" + } # Path to an entitlements file used in ios_content_shell. Can be overridden # to provide an alternative.
diff --git a/content/test/BUILD.gn b/content/test/BUILD.gn index f3ba504..c43e0003 100644 --- a/content/test/BUILD.gn +++ b/content/test/BUILD.gn
@@ -1899,7 +1899,7 @@ "../browser/direct_sockets/direct_sockets_udp_browsertest.cc", "../browser/file_system_access/file_system_access_clipboard_browsertest.cc", "../browser/file_system_access/file_system_access_drag_drop_browsertest.cc", - "../browser/file_system_access/file_system_access_file_handle_move_browsertest.cc", + "../browser/file_system_access/file_system_access_file_handle_impl_browsertest.cc", "../browser/file_system_access/file_system_access_file_writer_impl_browsertest.cc", "../browser/file_system_access/file_system_chooser_browsertest.cc", "../browser/font_preferences_browsertest.cc",
diff --git a/content/test/data/accessibility/html/selectmenu-expected-blink.txt b/content/test/data/accessibility/html/selectmenu-expected-blink.txt index 08d69fd..065b897e 100644 --- a/content/test/data/accessibility/html/selectmenu-expected-blink.txt +++ b/content/test/data/accessibility/html/selectmenu-expected-blink.txt
@@ -4,9 +4,10 @@ ++++++genericContainer ++++++++genericContainer ignored ++++++++++comboBoxMenuButton collapsed focusable value='Option 1' haspopup=listbox -++++++++++++genericContainer -++++++++++++++staticText name='Option 1' -++++++++++++++++inlineTextBox name='Option 1' +++++++++++++genericContainer ignored +++++++++++++++genericContainer +++++++++++++++++staticText name='Option 1' +++++++++++++++++++inlineTextBox name='Option 1' ++++++++++++genericContainer ignored ++++++++++++++genericContainer ignored ++++++++genericContainer ignored
diff --git a/content/test/data/accessibility/html/selectmenu-expected-fuchsia.txt b/content/test/data/accessibility/html/selectmenu-expected-fuchsia.txt index 9101076..802f8fa 100644 --- a/content/test/data/accessibility/html/selectmenu-expected-fuchsia.txt +++ b/content/test/data/accessibility/html/selectmenu-expected-fuchsia.txt
@@ -4,9 +4,10 @@ ++++++UNKNOWN ++++++++UNKNOWN hidden ++++++++++UNKNOWN focusable actions='{DEFAULT}' value='Option 1' -++++++++++++UNKNOWN actions='{DEFAULT}' -++++++++++++++STATIC_TEXT label='Option 1' actions='{DEFAULT}' -++++++++++++++++UNKNOWN label='Option 1' +++++++++++++UNKNOWN hidden +++++++++++++++UNKNOWN actions='{DEFAULT}' +++++++++++++++++STATIC_TEXT label='Option 1' actions='{DEFAULT}' +++++++++++++++++++UNKNOWN label='Option 1' ++++++++++++UNKNOWN hidden ++++++++++++++UNKNOWN hidden ++++++++UNKNOWN hidden
diff --git a/content/test/data/attribution_reporting/interop/success_debug_aggregatable.json b/content/test/data/attribution_reporting/interop/success_debug_aggregatable.json new file mode 100644 index 0000000..f94a82d --- /dev/null +++ b/content/test/data/attribution_reporting/interop/success_debug_aggregatable.json
@@ -0,0 +1,290 @@ +{ + "description": "Success debug aggregatable report sent when permitted and debug keys set", + "input": { + "sources": [ + { + "timestamp": "1643235573000", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "aggregation_keys": { + "a": "0x1" + }, + "debug_key": "111" + } + } + }] + }, + { + "timestamp": "1643235573000", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://another-reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://another-reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "aggregation_keys": { + "a": "0x2" + } + } + } + }] + }, + { + "timestamp": "1643235573000", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://reporter.test/register-source", + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://another-destination.test", + "aggregation_keys": { + "a": "0x3" + }, + "debug_key": "222" + } + } + }] + } + ], + "triggers": [ + // Will result in a debug report. + { + "timestamp": "1643235574000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x10" + } + ], + "aggregatable_values": { + "a": 111 + }, + "debug_key": "333" + } + } + }] + }, + // Will not result in a debug report as debug key is not set. + { + "timestamp": "1643235575000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x10" + } + ], + "aggregatable_values": { + "a": 222 + } + } + } + }] + }, + // Will not result in a debug report as debug permission is not set. + { + "timestamp": "1643235576000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "response": { + "Attribution-Reporting-Register-Trigger": { + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x10" + } + ], + "aggregatable_values": { + "a": 333 + }, + "debug_key": "444" + } + } + }] + }, + // Will not result in a debug report as source debug key is not set. + { + "timestamp": "1643235577000", + "registration_request": { + "attribution_src_url": "https://another-reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://another-reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x10" + } + ], + "aggregatable_values": { + "a": 444 + }, + "debug_key": "555" + } + } + }] + }, + // Will not result in a debug report as source debug permission is not set. + { + "timestamp": "1643235578000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://another-destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "aggregatable_trigger_data": [ + { + "source_keys": ["a"], + "key_piece": "0x10" + } + ], + "aggregatable_values": { + "a": 555 + }, + "debug_key": "666" + } + } + }] + } + ] + }, + "output": { + "aggregatable_results": [ + { + "payload": { + "attribution_destination": "https://destination.test", + "histograms": [ + { + "key": "0x11", + "value": 111 + } + ], + "source_debug_key": "111", + "trigger_debug_key": "333" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution", + "report_time": "1643239174000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "histograms": [ + { + "key": "0x11", + "value": 222 + } + ], + "source_debug_key": "111" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution", + "report_time": "1643239175000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "histograms": [ + { + "key": "0x11", + "value": 333 + } + ], + "source_debug_key": "111" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution", + "report_time": "1643239176000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "histograms": [ + { + "key": "0x12", + "value": 444 + } + ], + "trigger_debug_key": "555" + }, + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-aggregate-attribution", + "report_time": "1643239177000" + }, + { + "payload": { + "attribution_destination": "https://another-destination.test", + "histograms": [ + { + "key": "0x13", + "value": 555 + } + ], + "trigger_debug_key": "666" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-aggregate-attribution", + "report_time": "1643239178000" + } + ], + "debug_aggregatable_results": [ + { + "payload": { + "attribution_destination": "https://destination.test", + "histograms": [ + { + "key": "0x11", + "value": 111 + } + ], + "source_debug_key": "111", + "trigger_debug_key": "333" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/debug/report-aggregate-attribution", + "report_time": "1643235574000" + } + ] + } +}
diff --git a/content/test/data/attribution_reporting/interop/success_debug_event_level.json b/content/test/data/attribution_reporting/interop/success_debug_event_level.json new file mode 100644 index 0000000..e021172 --- /dev/null +++ b/content/test/data/attribution_reporting/interop/success_debug_event_level.json
@@ -0,0 +1,258 @@ +{ + "description": "Success debug event-level report sent when permitted and debug keys set", + "input": { + "sources": [ + { + "timestamp": "1643235573000", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "source_event_id": "123", + "debug_key": "111" + } + } + }] + }, + { + "timestamp": "1643235573000", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://another-reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://another-reporter.test/register-source", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://destination.test", + "source_event_id": "456" + } + } + }] + }, + { + "timestamp": "1643235573000", + "registration_request": { + "source_origin": "https://source.test", + "attribution_src_url": "https://reporter.test/register-source", + "source_type": "navigation" + }, + "responses": [{ + "url": "https://reporter.test/register-source", + "response": { + "Attribution-Reporting-Register-Source": { + "destination": "https://another-destination.test", + "source_event_id": "789", + "debug_key": "222" + } + } + }] + } + ], + "triggers": [ + // Will result in a debug report. + { + "timestamp": "1643235574000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "7" + } + ], + "debug_key": "333" + } + } + }] + }, + // Will not result in a debug report as debug key is not set. + { + "timestamp": "1643235575000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "6" + } + ] + } + } + }] + }, + // Will not result in a debug report as debug permission is not set. + { + "timestamp": "1643235576000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "5" + } + ], + "debug_key": "444" + } + } + }] + }, + // Will not result in a debug report as source debug key is not set. + { + "timestamp": "1643235577000", + "registration_request": { + "attribution_src_url": "https://another-reporter.test/register-trigger", + "destination_origin": "https://destination.test" + }, + "responses": [{ + "url": "https://another-reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "4" + } + ], + "debug_key": "555" + } + } + }] + }, + // Will not result in a debug report as source debug permission is not set. + { + "timestamp": "1643235578000", + "registration_request": { + "attribution_src_url": "https://reporter.test/register-trigger", + "destination_origin": "https://another-destination.test" + }, + "responses": [{ + "url": "https://reporter.test/register-trigger", + "debug_permission": true, + "response": { + "Attribution-Reporting-Register-Trigger": { + "event_trigger_data": [ + { + "trigger_data": "3" + } + ], + "debug_key": "666" + } + } + }] + } + ] + }, + "output": { + "event_level_results": [ + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024, + "scheduled_report_time": "1643411973", + "source_event_id": "123", + "source_type": "navigation", + "trigger_data": "7", + "source_debug_key": "111", + "trigger_debug_key": "333" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411973000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024, + "scheduled_report_time": "1643411973", + "source_event_id": "123", + "source_type": "navigation", + "trigger_data": "6", + "source_debug_key": "111" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411973000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024, + "scheduled_report_time": "1643411973", + "source_event_id": "123", + "source_type": "navigation", + "trigger_data": "5", + "source_debug_key": "111" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411973000" + }, + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024, + "scheduled_report_time": "1643411973", + "source_event_id": "456", + "source_type": "navigation", + "trigger_data": "4", + "trigger_debug_key": "555" + }, + "report_url": "https://another-reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411973000" + }, + { + "payload": { + "attribution_destination": "https://another-destination.test", + "randomized_trigger_rate": 0.0024, + "scheduled_report_time": "1643411973", + "source_event_id": "789", + "source_type": "navigation", + "trigger_data": "3", + "trigger_debug_key": "666" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/report-event-attribution", + "report_time": "1643411973000" + } + ], + "debug_event_level_results": [ + { + "payload": { + "attribution_destination": "https://destination.test", + "randomized_trigger_rate": 0.0024, + "scheduled_report_time": "1643411973", + "source_event_id": "123", + "source_type": "navigation", + "trigger_data": "7", + "source_debug_key": "111", + "trigger_debug_key": "333" + }, + "report_url": "https://reporter.test/.well-known/attribution-reporting/debug/report-event-attribution", + "report_time": "1643235574000" + } + ] + } +}
diff --git a/content/test/data/gpu/webcodecs/audio-encode-decode.html b/content/test/data/gpu/webcodecs/audio-encode-decode.html index 3ec01e5..816d889 100644 --- a/content/test/data/gpu/webcodecs/audio-encode-decode.html +++ b/content/test/data/gpu/webcodecs/audio-encode-decode.html
@@ -38,8 +38,14 @@ codec: args.codec, sampleRate: args.sample_rate, numberOfChannels: args.channels, - bitrate: 96000, + bitrate: 96000 }; + + if (args.aac_format) { + config.aac = { + format : args.aac_format + }; + } let decoder_config = null; let support = await AudioEncoder.isConfigSupported(config); @@ -92,6 +98,13 @@ timestamp_us += 2 * (2112 / config.sampleRate) * 1_000_000; TEST.assert(decoder_config != null, "No decoder config"); + if (args.aac_format == "adts") { + TEST.assert(decoder_config.description == null, "ADTS should carry desc"); + } else if (args.aac_format == "aac") { + TEST.assert(decoder_config.description != null, "AAC should carry desc"); + TEST.assert(decoder_config.description.byteLength > 1, + "AAC desc is too short"); + } TEST.assert(outputs.length > 0, "no outputs"); TEST.assert(outputs[0].timestamp == 0, "first chunk timestamp non zero"); @@ -102,6 +115,12 @@ `chunk timestamp is too small. ${timestamp_us} vs ${chunk.timestamp}`); TEST.assert(chunk.duration >= 0, "chunk duration is zero"); total_encoded_duration += chunk.duration; + let buf = new ArrayBuffer(chunk.byteLength); + chunk.copyTo(buf); + if (args.aac_format == "adts") { + let adts_header = new DataView(buf).getUint8(0); + TEST.assert(adts_header == 0xff, "Incorrect ADTS header"); + } } // The total duration might be padded with silence.
diff --git a/content/test/gpu/gpu_tests/webcodecs_integration_test.py b/content/test/gpu/gpu_tests/webcodecs_integration_test.py index 858623ec1..728a082 100644 --- a/content/test/gpu/gpu_tests/webcodecs_integration_test.py +++ b/content/test/gpu/gpu_tests/webcodecs_integration_test.py
@@ -88,7 +88,19 @@ 'sample_rate': 48000, 'channels': - 2 + 2, + 'aac_format': + 'aac' + }]) + yield ('WebCodecs_AudioEncoding_AAC_LC_ADTS', 'audio-encode-decode.html', [{ + 'codec': + 'mp4a.67', + 'sample_rate': + 48000, + 'channels': + 2, + 'aac_format': + 'adts' }]) @classmethod
diff --git a/docs/navigation-request-navigation-state.gv b/docs/navigation-request-navigation-state.gv index e8ceef28..984b0202 100644 --- a/docs/navigation-request-navigation-state.gv +++ b/docs/navigation-request-navigation-state.gv
@@ -6,12 +6,13 @@ NOT_STARTED -> {WAITING_FOR_RENDERER_RESPONSE, WILL_START_NAVIGATION, WILL_START_REQUEST}; WAITING_FOR_RENDERER_RESPONSE -> {WILL_START_NAVIGATION, WILL_START_REQUEST}; WILL_START_NAVIGATION -> {WILL_START_REQUEST, WILL_FAIL_REQUEST}; - WILL_START_REQUEST -> {WILL_REDIRECT_REQUEST, WILL_PROCESS_RESPONSE, READY_TO_COMMIT, DID_COMMIT, CANCELING, WILL_FAIL_REQUEST, DID_COMMIT_ERROR_PAGE}; + WILL_START_REQUEST -> {WILL_REDIRECT_REQUEST, WILL_PROCESS_RESPONSE, WILL_COMMIT_WITHOUT_URL_LOADER, READY_TO_COMMIT, DID_COMMIT, CANCELING, WILL_FAIL_REQUEST, DID_COMMIT_ERROR_PAGE}; WILL_REDIRECT_REQUEST -> {WILL_REDIRECT_REQUEST, WILL_PROCESS_RESPONSE, CANCELING, WILL_FAIL_REQUEST}; WILL_PROCESS_RESPONSE -> {READY_TO_COMMIT, CANCELING, WILL_FAIL_REQUEST}; + WILL_COMMIT_WITHOUT_URL_LOADER -> {READY_TO_COMMIT, CANCELING, WILL_FAIL_REQUEST}; READY_TO_COMMIT -> {NOT_STARTED, DID_COMMIT, DID_COMMIT_ERROR_PAGE}; - DID_COMMIT -> {}; CANCELING -> {READY_TO_COMMIT, WILL_FAIL_REQUEST}; WILL_FAIL_REQUEST -> {READY_TO_COMMIT, CANCELING, WILL_FAIL_REQUEST}; + DID_COMMIT -> {}; DID_COMMIT_ERROR_PAGE -> {}; }
diff --git a/docs/navigation-request-navigation-state.png b/docs/navigation-request-navigation-state.png index 572a0ce..aa2430d0 100644 --- a/docs/navigation-request-navigation-state.png +++ b/docs/navigation-request-navigation-state.png Binary files differ
diff --git a/docs/navigation.md b/docs/navigation.md index d481150..3e4a425 100644 --- a/docs/navigation.md +++ b/docs/navigation.md
@@ -160,10 +160,17 @@ `NavigationThrottleRunner::RegisterNavigationThrottles` or `ContentBrowserClient::CreateThrottlesForNavigation`. -NavigationThrottles are only invoked on navigations that require a URLLoader -(see NavigationRequest::NeedsUrlLoader). This means they don't typically run in -cases like same-document navigations, about:blank, etc. They are also not run in -page-activation navigations, such as activating a prerendered page or restoring -a page from the back-forward cache. +The most common NavigationThrottles events are `WillStartRequest`, +`WillRedirectRequest`, and `WillProcessResponse`, which allow intercepting a +navigation before sending the network request, during any redirects, and after +receiving the response. These events are only invoked on navigations that +require a URLLoader (see NavigationRequest::NeedsUrlLoader). +A NavigationThrottle that wishes to intercept a non-URLLoader navigation +(same-document navigations, about:blank, etc.) should register itself in +`NavigationThrottleRunner::RegisterNavigationThrottlesForCommitWithoutUrlLoader`, +and will get a single `WillCommitWithoutUrlLoader` event instead of the full +set of events centered on network requests. Page-activation navigations, such +as activating a prerendered page or restoring a page from the back-forward +cache, skip NavigationThrottles entirely. [WebContentsObserver]: https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/web_contents_observer.h
diff --git a/gpu/GRAPHICS_TEAM_OWNERS b/gpu/GRAPHICS_TEAM_OWNERS index 8080ca3..60e0ff7d 100644 --- a/gpu/GRAPHICS_TEAM_OWNERS +++ b/gpu/GRAPHICS_TEAM_OWNERS
@@ -5,15 +5,12 @@ vmiura@chromium.org geofflang@chromium.org fserb@chromium.org -sadrul@chromium.org rockot@google.com rjkroege@chromium.org zmo@chromium.org # ANGLE team -jmadill@chromium.org jonahr@chromium.org -srisser@chromium.org syoussefi@chromium.org ynovikov@chromium.org @@ -25,13 +22,10 @@ yiyix@chromium.org # Metrics team -behdadb@chromium.org jonross@chromium.org mjzhang@chromium.org -mohsen@chromium.org # Platforms Team -backer@chromium.org boliu@chromium.org ccameron@chromium.org fangzhoug@chromium.org @@ -41,7 +35,6 @@ magchen@chromium.org penghuang@chromium.org petermcneeley@chromium.org -rivr@chromium.org sunnyps@chromium.org vasilyt@chromium.org vikassoni@chromium.org
diff --git a/gpu/command_buffer/client/webgpu_implementation.cc b/gpu/command_buffer/client/webgpu_implementation.cc index 5cd7459e..8427ca3b 100644 --- a/gpu/command_buffer/client/webgpu_implementation.cc +++ b/gpu/command_buffer/client/webgpu_implementation.cc
@@ -128,11 +128,10 @@ std::unique_ptr<TransferBuffer> transfer_buffer = std::make_unique<TransferBuffer>(helper_); - if (!transfer_buffer->Initialize(limits.start_transfer_buffer_size, - /* start offset */ 0, - limits.min_transfer_buffer_size, - limits.max_transfer_buffer_size, - /* alignment */ 8)) { + if (!transfer_buffer->Initialize( + limits.start_transfer_buffer_size, + /* start offset */ 0, limits.min_transfer_buffer_size, + limits.max_transfer_buffer_size, kAlignment)) { return gpu::ContextResult::kFatalFailure; }
diff --git a/gpu/command_buffer/service/raster_decoder.cc b/gpu/command_buffer/service/raster_decoder.cc index 0dd275c..9dbc018 100644 --- a/gpu/command_buffer/service/raster_decoder.cc +++ b/gpu/command_buffer/service/raster_decoder.cc
@@ -2820,17 +2820,17 @@ return; } - alignas( - cc::PaintOpBuffer::kPaintOpAlign) char data[sizeof(cc::LargestPaintOp)]; + alignas(cc::PaintOpBuffer::kPaintOpAlign) char + data[cc::kLargestPaintOpAlignedSize]; size_t paint_buffer_size = raster_shm_size; gl::ScopedProgressReporter report_progress( shared_context_state_->progress_reporter()); while (paint_buffer_size > 0) { size_t skip = 0; - cc::PaintOp* deserialized_op = cc::PaintOp::Deserialize( - paint_buffer_memory, paint_buffer_size, &data[0], - sizeof(cc::LargestPaintOp), &skip, options); + cc::PaintOp* deserialized_op = + cc::PaintOp::Deserialize(paint_buffer_memory, paint_buffer_size, data, + std::size(data), &skip, options); if (!deserialized_op) { LOCAL_SET_GL_ERROR(GL_INVALID_OPERATION, "glRasterCHROMIUM", "RasterCHROMIUM: serialization failure");
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc index 1e70198..7a2ecea 100644 --- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc +++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.cc
@@ -201,6 +201,11 @@ passthrough_texture_.reset(); egl_image_.reset(); + + if (need_gl_finish_before_destroy_ && have_context()) { + gl::GLApi* api = gl::g_current_gl_context; + api->glFinishFn(); + } } if (vulkan_image_) { @@ -399,8 +404,9 @@ --gl_reads_in_process_; // For the last GL read access, release texture from ANGLE. - if (gl_reads_in_process_ == 0) + if (gl_reads_in_process_ == 0) { ReleaseTextureANGLE(); + } return; } @@ -427,6 +433,9 @@ GLuint texture = passthrough_texture_->service_id(); // Release the texture from ANGLE, so it can be used elsewhere. api->glReleaseTexturesANGLEFn(1, &texture, &layout_); + // Releasing the texture will submit all related works to queue, so to be + // safe, glFinish() should be called before releasing the VkImage. + need_gl_finish_before_destroy_ = true; } void AngleVulkanImageBacking::PrepareBackendTexture() { @@ -506,6 +515,11 @@ return; } + // The backing is used by skia, so skia should submit related work to the + // queue, and we can use vulkan fence helper to release the VkImage. + // glFinish() is not necessary anymore. + need_gl_finish_before_destroy_ = false; + SyncImageLayoutFromBackendTexture(); if (gl_reads_in_process_ > 0) {
diff --git a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h index daec0c06..8d28076 100644 --- a/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h +++ b/gpu/command_buffer/service/shared_image/angle_vulkan_image_backing.h
@@ -77,6 +77,7 @@ bool is_gl_write_in_process_ = false; int skia_reads_in_process_ = 0; int gl_reads_in_process_ = 0; + bool need_gl_finish_before_destroy_ = false; }; } // namespace gpu
diff --git a/headless/test/data/protocol/input/input-clipboard-ops-expected.txt b/headless/test/data/protocol/input/input-clipboard-ops-expected.txt index 79fdbfc..17f868e6 100644 --- a/headless/test/data/protocol/input/input-clipboard-ops-expected.txt +++ b/headless/test/data/protocol/input/input-clipboard-ops-expected.txt
@@ -1,4 +1,4 @@ Tests input field clipboard operations. input: input_value -input: abc -input: input_value \ No newline at end of file +input: 123 +input: 123input_value \ No newline at end of file
diff --git a/headless/test/data/protocol/input/input-clipboard-ops.js b/headless/test/data/protocol/input/input-clipboard-ops.js index 682d682..3363661b 100644 --- a/headless/test/data/protocol/input/input-clipboard-ops.js +++ b/headless/test/data/protocol/input/input-clipboard-ops.js
@@ -3,12 +3,14 @@ // found in the LICENSE file. (async function(testRunner) { - const {page, session, dp} = await testRunner.startBlank( - `Tests input field clipboard operations.`); + const html = `<!doctype html> + <html><body> + <input type="text" id="input" value="input_value" autofocus> + </body></html> + `; - await dp.Page.enable(); - dp.Page.navigate({url: testRunner.url('/resources/input.html')}); - await dp.Page.onceLoadEventFired(); + const {page, session, dp} = await testRunner.startHTML( + html, `Tests input field clipboard operations.`); async function logElementValue(id) { const value = await session.evaluate(` @@ -34,19 +36,23 @@ }); } - await logElementValue("input"); - await sendKey('a', 65, 2, ["selectAll"]); - await sendKey('c', 67, 2, ["copy"]); + const modControl = 2; + const modCommand = 4; + const mod = navigator.platform.includes('Mac') ? modCommand : modControl; - await sendKey('a', 65); - await sendKey('b', 66); - await sendKey('c', 67); + await logElementValue("input"); + await sendKey('a', 65, mod, ['selectAll']); + await sendKey('c', 67, mod, ['copy']); + + await sendKey('1', 61); + await sendKey('2', 62); + await sendKey('3', 63); await logElementValue("input"); - await sendKey('a', 65, 2, ["selectAll"]); - await sendKey('c', 67, 2, ["paste"]); + // Don't send Ctrl+A here because this would cause clipboard copy on + // systems that support selection clipboard, e.g. Linux. + await sendKey('v', 86, mod, ['paste']); await logElementValue("input"); testRunner.completeTest(); }) -
diff --git a/headless/test/data/protocol/input/resources/input.html b/headless/test/data/protocol/input/resources/input.html deleted file mode 100644 index a750341..0000000 --- a/headless/test/data/protocol/input/resources/input.html +++ /dev/null
@@ -1,3 +0,0 @@ -<html> <body> - <input type="text" id="input" value="input_value" autofocus> -</body></html>
diff --git a/headless/test/headless_protocol_browsertest.cc b/headless/test/headless_protocol_browsertest.cc index a8dae8c..c6e76ad2 100644 --- a/headless/test/headless_protocol_browsertest.cc +++ b/headless/test/headless_protocol_browsertest.cc
@@ -302,8 +302,8 @@ HEADLESS_PROTOCOL_TEST(DragStarted, "input/dragIntercepted.js") -// https://crbug.com/1204620 -#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_MAC) || BUILDFLAG(IS_WIN) +// https://crbug.com/1414190 +#if BUILDFLAG(IS_MAC) #define MAYBE_InputClipboardOps DISABLED_InputClipboardOps #else #define MAYBE_InputClipboardOps InputClipboardOps
diff --git a/infra/archive_config/linux-chromiumos-full.json b/infra/archive_config/linux-chromiumos-full.json index 4cf51096..0db71b1 100644 --- a/infra/archive_config/linux-chromiumos-full.json +++ b/infra/archive_config/linux-chromiumos-full.json
@@ -9,7 +9,12 @@ "chrome_crashpad_handler", "icudtl.dat", "keyboard_resources.pak", + "libEGL.so", + "libGLESv2.so", "libminigbm.so", + "libmojo_core.so", + "libmojo_core_arc32.so", + "libmojo_core_arc64.so", "MEIPreload/manifest.json", "MEIPreload/preloaded_data.pb", "nacl_helper", @@ -21,7 +26,7 @@ "xdg-mime", "xdg-settings" ], - "dirs": ["ClearKeyCdm", "locales", "resources"], + "dirs": ["ClearKeyCdm", "locales", "resources", "mojo_service_manager"], "rename_dirs": [ {"from_dir": ".", "to_dir": "chrome-chromeos"} ],
diff --git a/infra/config/generated/builders/ci/Mac Builder Next/properties.json b/infra/config/generated/builders/ci/Mac Builder Next/properties.json index 4fbdcc1..59401df 100644 --- a/infra/config/generated/builders/ci/Mac Builder Next/properties.json +++ b/infra/config/generated/builders/ci/Mac Builder Next/properties.json
@@ -17,7 +17,7 @@ "apply_configs": [ "mb" ], - "build_config": "Release", + "build_config": "Debug", "config": "chromium", "target_arch": "arm", "target_bits": 64
diff --git a/infra/config/generated/builders/ci/linux-js-code-coverage/properties.json b/infra/config/generated/builders/ci/linux-js-code-coverage/properties.json index 8cac476..5a2e7de 100644 --- a/infra/config/generated/builders/ci/linux-js-code-coverage/properties.json +++ b/infra/config/generated/builders/ci/linux-js-code-coverage/properties.json
@@ -45,6 +45,7 @@ } }, "$build/code_coverage": { + "export_coverage_to_zoss": true, "use_javascript_coverage": true }, "$build/reclient": {
diff --git a/infra/config/generated/builders/try/android-12-x64-rel/properties.json b/infra/config/generated/builders/try/android-12-x64-rel/properties.json index 2341f30c..f7e9fef 100644 --- a/infra/config/generated/builders/try/android-12-x64-rel/properties.json +++ b/infra/config/generated/builders/try/android-12-x64-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "android-12-x64-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/android-arm64-rel-inverse-fyi/properties.json b/infra/config/generated/builders/try/android-arm64-rel-inverse-fyi/properties.json index 8d211f28..547487f 100644 --- a/infra/config/generated/builders/try/android-arm64-rel-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/android-arm64-rel-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "android-arm64-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/android-arm64-rel/properties.json b/infra/config/generated/builders/try/android-arm64-rel/properties.json index 8d211f28..547487f 100644 --- a/infra/config/generated/builders/try/android-arm64-rel/properties.json +++ b/infra/config/generated/builders/try/android-arm64-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "android-arm64-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/android-nougat-x86-rel-inverse-fyi/properties.json b/infra/config/generated/builders/try/android-nougat-x86-rel-inverse-fyi/properties.json index 27cc6358..b37bead 100644 --- a/infra/config/generated/builders/try/android-nougat-x86-rel-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/android-nougat-x86-rel-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "android-nougat-x86-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/android-nougat-x86-rel/properties.json b/infra/config/generated/builders/try/android-nougat-x86-rel/properties.json index 27cc6358..b37bead 100644 --- a/infra/config/generated/builders/try/android-nougat-x86-rel/properties.json +++ b/infra/config/generated/builders/try/android-nougat-x86-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "android-nougat-x86-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json b/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json index a508abe..fbbb60e 100644 --- a/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json +++ b/infra/config/generated/builders/try/chromeos-amd64-generic-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "chromeos-amd64-generic-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json b/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json index a78a8e3..ad7bcfdf 100644 --- a/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json +++ b/infra/config/generated/builders/try/fuchsia-arm64-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "fuchsia-arm64-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/properties.json b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/properties.json index ee33e86..50e84fc 100644 --- a/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/properties.json +++ b/infra/config/generated/builders/try/fuchsia-x64-cast-receiver-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "fuchsia-x64-cast-receiver-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/ios-simulator/properties.json b/infra/config/generated/builders/try/ios-simulator/properties.json index 4bd8399..e47e00ae 100644 --- a/infra/config/generated/builders/try/ios-simulator/properties.json +++ b/infra/config/generated/builders/try/ios-simulator/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "ios-simulator-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/lacros-amd64-generic-rel-orchestrator/properties.json b/infra/config/generated/builders/try/lacros-amd64-generic-rel-orchestrator/properties.json index 8cb1356..fbef280a 100644 --- a/infra/config/generated/builders/try/lacros-amd64-generic-rel-orchestrator/properties.json +++ b/infra/config/generated/builders/try/lacros-amd64-generic-rel-orchestrator/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "lacros-amd64-generic-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux-chromeos-rel/properties.json b/infra/config/generated/builders/try/linux-chromeos-rel/properties.json index 15f9eb6..c3e15d6 100644 --- a/infra/config/generated/builders/try/linux-chromeos-rel/properties.json +++ b/infra/config/generated/builders/try/linux-chromeos-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux-chromeos-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux-lacros-rel/properties.json b/infra/config/generated/builders/try/linux-lacros-rel/properties.json index 52e3b47f7..0ba42f1 100644 --- a/infra/config/generated/builders/try/linux-lacros-rel/properties.json +++ b/infra/config/generated/builders/try/linux-lacros-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux-lacros-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux-rel-inverse-fyi/properties.json b/infra/config/generated/builders/try/linux-rel-inverse-fyi/properties.json index 03d03cb..591ea80 100644 --- a/infra/config/generated/builders/try/linux-rel-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/linux-rel-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux-rel/properties.json b/infra/config/generated/builders/try/linux-rel/properties.json index 03d03cb..591ea80 100644 --- a/infra/config/generated/builders/try/linux-rel/properties.json +++ b/infra/config/generated/builders/try/linux-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux-wayland-rel-inverse-fyi/properties.json b/infra/config/generated/builders/try/linux-wayland-rel-inverse-fyi/properties.json index 45eea6f..275ecf99 100644 --- a/infra/config/generated/builders/try/linux-wayland-rel-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/linux-wayland-rel-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux-wayland-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux-wayland-rel/properties.json b/infra/config/generated/builders/try/linux-wayland-rel/properties.json index 45eea6f..275ecf99 100644 --- a/infra/config/generated/builders/try/linux-wayland-rel/properties.json +++ b/infra/config/generated/builders/try/linux-wayland-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux-wayland-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng-inverse-fyi/properties.json b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng-inverse-fyi/properties.json index e65ed2a..ea99e46e 100644 --- a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux_chromium_asan_rel_ng-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/properties.json index e65ed2a..ea99e46e 100644 --- a/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_asan_rel_ng/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux_chromium_asan_rel_ng-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng-inverse-fyi/properties.json b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng-inverse-fyi/properties.json index e7490ef3..d1fe41a 100644 --- a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux_chromium_tsan_rel_ng-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/properties.json b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/properties.json index e7490ef3..d1fe41a 100644 --- a/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/properties.json +++ b/infra/config/generated/builders/try/linux_chromium_tsan_rel_ng/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "linux_chromium_tsan_rel_ng-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/mac-builder-next-rel/properties.json b/infra/config/generated/builders/try/mac-builder-next-rel/properties.json index dc0d327e..f39d9cb 100644 --- a/infra/config/generated/builders/try/mac-builder-next-rel/properties.json +++ b/infra/config/generated/builders/try/mac-builder-next-rel/properties.json
@@ -17,7 +17,7 @@ "apply_configs": [ "mb" ], - "build_config": "Release", + "build_config": "Debug", "config": "chromium", "target_arch": "arm", "target_bits": 64
diff --git a/infra/config/generated/builders/try/mac-rel-inverse-fyi/properties.json b/infra/config/generated/builders/try/mac-rel-inverse-fyi/properties.json index 760c6f5..4757703 100644 --- a/infra/config/generated/builders/try/mac-rel-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/mac-rel-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "mac-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/mac-rel/properties.json b/infra/config/generated/builders/try/mac-rel/properties.json index 760c6f5..4757703 100644 --- a/infra/config/generated/builders/try/mac-rel/properties.json +++ b/infra/config/generated/builders/try/mac-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "mac-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/mac12-arm64-rel/properties.json b/infra/config/generated/builders/try/mac12-arm64-rel/properties.json index 06a90182..c435c0a 100644 --- a/infra/config/generated/builders/try/mac12-arm64-rel/properties.json +++ b/infra/config/generated/builders/try/mac12-arm64-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "mac12-arm64-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/win-rel-inverse-fyi/properties.json b/infra/config/generated/builders/try/win-rel-inverse-fyi/properties.json index 14f1682..aa57c503 100644 --- a/infra/config/generated/builders/try/win-rel-inverse-fyi/properties.json +++ b/infra/config/generated/builders/try/win-rel-inverse-fyi/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "win-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/builders/try/win-rel/properties.json b/infra/config/generated/builders/try/win-rel/properties.json index 14f1682..aa57c503 100644 --- a/infra/config/generated/builders/try/win-rel/properties.json +++ b/infra/config/generated/builders/try/win-rel/properties.json
@@ -1,7 +1,7 @@ { "$build/chromium_orchestrator": { "compilator": "win-rel-compilator", - "compilator_watcher_git_revision": "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" + "compilator_watcher_git_revision": "e6d08be3fd589d4f222dae5d18dbc972e6117b23" }, "$build/chromium_tests_builder_config": { "builder_config": {
diff --git a/infra/config/generated/luci/project.cfg b/infra/config/generated/luci/project.cfg index 388833f8..bced30d 100644 --- a/infra/config/generated/luci/project.cfg +++ b/infra/config/generated/luci/project.cfg
@@ -7,7 +7,7 @@ name: "chromium" access: "group:all" lucicfg { - version: "1.37.2" + version: "1.38.1" package_dir: "../.." config_dir: "generated/luci" entry_point: "main.star"
diff --git a/infra/config/lib/orchestrator.star b/infra/config/lib/orchestrator.star index 314b429..03f0f22 100644 --- a/infra/config/lib/orchestrator.star +++ b/infra/config/lib/orchestrator.star
@@ -16,7 +16,7 @@ # infra/infra git revision to use for the compilator_watcher luciexe sub_build # Used by chromium orchestrators -_COMPILATOR_WATCHER_GIT_REVISION = "ed88e894b6a9f09ab3604fb3276c5810389cbcf4" +_COMPILATOR_WATCHER_GIT_REVISION = "e6d08be3fd589d4f222dae5d18dbc972e6117b23" # Nodes for the definition of an orchestrator builder _ORCHESTRATOR = nodes.create_bucket_scoped_node_type("orchestrator")
diff --git a/infra/config/subprojects/chromium/ci/chromium.coverage.star b/infra/config/subprojects/chromium/ci/chromium.coverage.star index b1b7160..b84a513 100644 --- a/infra/config/subprojects/chromium/ci/chromium.coverage.star +++ b/infra/config/subprojects/chromium/ci/chromium.coverage.star
@@ -251,6 +251,7 @@ ], reclient_jobs = reclient.jobs.HIGH_JOBS_FOR_CI, use_javascript_coverage = True, + export_coverage_to_zoss = True, ) coverage_builder(
diff --git a/infra/config/subprojects/chromium/ci/chromium.fyi.star b/infra/config/subprojects/chromium/ci/chromium.fyi.star index 306c83ab..eedc56d 100644 --- a/infra/config/subprojects/chromium/ci/chromium.fyi.star +++ b/infra/config/subprojects/chromium/ci/chromium.fyi.star
@@ -2278,7 +2278,7 @@ chromium_config = builder_config.chromium_config( config = "chromium", apply_configs = ["mb"], - build_config = builder_config.build_config.RELEASE, + build_config = builder_config.build_config.DEBUG, target_arch = builder_config.target_arch.ARM, target_bits = 64, ),
diff --git a/ios/chrome/browser/ntp/new_tab_page_tab_helper.h b/ios/chrome/browser/ntp/new_tab_page_tab_helper.h index 59a5dfc..82e03ac 100644 --- a/ios/chrome/browser/ntp/new_tab_page_tab_helper.h +++ b/ios/chrome/browser/ntp/new_tab_page_tab_helper.h
@@ -83,8 +83,9 @@ web::NavigationContext* navigation_context) override; void DidFinishNavigation(web::WebState* web_state, web::NavigationContext* navigation_context) override; - void DidStopLoading(web::WebState* web_state) override; - void DidStartLoading(web::WebState* web_state) override; + void PageLoaded( + web::WebState* web_state, + web::PageLoadCompletionStatus load_completion_status) override; // Enable or disable the tab helper. void SetActive(bool active); @@ -95,8 +96,8 @@ // The WebState with which this object is associated. web::WebState* web_state_ = nullptr; - // `YES` if the current tab helper is active. - BOOL active_ = NO; + // `true` if the current tab helper is active. + bool active_ = false; // `YES` if the NTP for this WebState should be configured to show the Start // Surface.
diff --git a/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm b/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm index adfa0fd..31ab0a7 100644 --- a/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm +++ b/ios/chrome/browser/ntp/new_tab_page_tab_helper.mm
@@ -152,32 +152,27 @@ } UpdateItem(web_state_->GetNavigationManager()->GetLastCommittedItem()); - SetActive(IsNTPURL(web_state->GetLastCommittedURL())); } -void NewTabPageTabHelper::DidStartLoading(web::WebState* web_state) { - // This is needed to avoid flashing the NTP when loading error pages. - if (!IsNTPURL(web_state->GetVisibleURL())) { - SetActive(false); - } -} - -void NewTabPageTabHelper::DidStopLoading(web::WebState* web_state) { - if (IsNTPURL(web_state->GetVisibleURL())) { - SetActive(true); +void NewTabPageTabHelper::PageLoaded( + web::WebState* web_state, + web::PageLoadCompletionStatus load_completion_status) { + if (load_completion_status == web::PageLoadCompletionStatus::SUCCESS) { + if (IsNTPURL(web_state->GetVisibleURL())) { + SetActive(true); + } } } #pragma mark - Private void NewTabPageTabHelper::SetActive(bool active) { - bool was_active = active_; + if (active_ == active) { + return; + } active_ = active; - // Tell `delegate_` to show or hide the NTP, if necessary. - if (active_ != was_active) { - [delegate_ newTabPageHelperDidChangeVisibility:this forWebState:web_state_]; - } + [delegate_ newTabPageHelperDidChangeVisibility:this forWebState:web_state_]; } WEB_STATE_USER_DATA_KEY_IMPL(NewTabPageTabHelper)
diff --git a/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm b/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm index 452d805..e6c2195 100644 --- a/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm +++ b/ios/chrome/browser/ntp/new_tab_page_tab_helper_unittest.mm
@@ -123,7 +123,7 @@ web::FakeNavigationContext context; context.SetUrl(url); fake_navigation_manager_->SetLastCommittedItem(pending_item_.get()); - fake_web_state_.OnNavigationFinished(&context); + fake_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS); EXPECT_TRUE(tab_helper()->IsActive()); GURL not_ntp_url(kTestURL); @@ -131,16 +131,17 @@ context.SetUrl(not_ntp_url); pending_item_->SetURL(not_ntp_url); fake_web_state_.OnNavigationStarted(&context); + fake_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS); EXPECT_FALSE(tab_helper()->IsActive()); fake_navigation_manager_->SetLastCommittedItem(pending_item_.get()); - fake_web_state_.OnNavigationFinished(&context); + fake_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS); EXPECT_FALSE(tab_helper()->IsActive()); context.SetUrl(url); pending_item_->SetURL(url); fake_web_state_.SetCurrentURL(url); fake_navigation_manager_->SetLastCommittedItem(pending_item_.get()); - fake_web_state_.OnNavigationFinished(&context); + fake_web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS); EXPECT_TRUE(tab_helper()->IsActive()); context.SetUrl(not_ntp_url); @@ -172,6 +173,5 @@ fake_web_state_.SetCurrentURL(not_ntp_url); fake_navigation_manager_->SetLastCommittedItem(pending_item_.get()); fake_web_state_.OnNavigationFinished(&context); - EXPECT_FALSE(tab_helper()->IsActive()); EXPECT_EQ(GURL(kTestURL), pending_item_->GetVirtualURL()); }
diff --git a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm index f9e6f0e..4eede526 100644 --- a/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/browser_view/browser_coordinator_unittest.mm
@@ -37,6 +37,7 @@ #import "ios/chrome/browser/web/web_state_delegate_browser_agent.h" #import "ios/chrome/browser/web_state_list/tab_insertion_browser_agent.h" #import "ios/chrome/common/ui/reauthentication/reauthentication_module.h" +#import "ios/web/public/test/fakes/fake_navigation_context.h" #import "ios/web/public/test/web_task_environment.h" #import "testing/gtest/include/gtest/gtest.h" #import "testing/gtest_mac.h" @@ -169,10 +170,14 @@ UrlLoadParams urlLoadParams = UrlLoadParams::InCurrentTab(url); urlLoadingBrowserAgent->Load(urlLoadParams); - // Force the DidStopLoading callback. + // Force the WebStateObserver callbacks that simulate a page load. web::WebStateObserver* ntpHelper = (web::WebStateObserver*)NewTabPageTabHelper::FromWebState(web_state); - ntpHelper->DidStopLoading(web_state); + web::FakeNavigationContext context; + context.SetUrl(url); + context.SetIsSameDocument(false); + ntpHelper->DidStartNavigation(web_state, &context); + ntpHelper->PageLoaded(web_state, web::PageLoadCompletionStatus::SUCCESS); } IOSChromeScopedTestingLocalState local_state_;
diff --git a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm index 015a3c2..2bc602d 100644 --- a/ios/chrome/browser/ui/browser_view/browser_view_controller.mm +++ b/ios/chrome/browser/ui/browser_view/browser_view_controller.mm
@@ -2644,19 +2644,6 @@ } } -- (void)tabDidLoadURL:(GURL)URL - transitionType:(ui::PageTransition)transitionType { - // Deactivate the NTP immediately on a load to hide the NTP quickly, but - // after calling UrlLoadingService::Load. Otherwise, if the - // webState has never been visible (such as during startup with an NTP), it's - // possible the webView can trigger a unnecessary load for chrome://newtab. - if (self.currentWebState->GetVisibleURL() != kChromeUINewTabURL) { - if (self.isNTPActiveForCurrentWebState) { - NewTabPageTabHelper::FromWebState(self.currentWebState)->Deactivate(); - } - } -} - - (void)newTabWillLoadURL:(GURL)URL isUserInitiated:(BOOL)isUserInitiated { if (isUserInitiated) { // Send either the "New Tab Opened" or "New Incognito Tab" opened to the
diff --git a/ios/chrome/browser/ui/lens/lens_coordinator.mm b/ios/chrome/browser/ui/lens/lens_coordinator.mm index 7a80e0ee..449c3d0e 100644 --- a/ios/chrome/browser/ui/lens/lens_coordinator.mm +++ b/ios/chrome/browser/ui/lens/lens_coordinator.mm
@@ -5,7 +5,6 @@ #import "ios/chrome/browser/ui/lens/lens_coordinator.h" #import "base/strings/sys_string_conversions.h" -#import "base/task/sequenced_task_runner.h" #import "ios/chrome/browser/application_context/application_context.h" #import "ios/chrome/browser/browser_state/chrome_browser_state.h" #import "ios/chrome/browser/main/browser.h" @@ -195,8 +194,8 @@ contentArea = [delegate webContentAreaForLensCoordinator:self]; } - UIViewController* viewController = [lensController - inputSelectionViewControllerWithWebContentFrame:contentArea]; + UIViewController* viewController = + [lensController inputSelectionViewController]; // TODO(crbug.com/1353430): the returned UIViewController // must not be nil, remove this check once the internal @@ -284,6 +283,15 @@ [self dismissViewController]; } +- (CGRect)webContentFrame { + id<LensPresentationDelegate> delegate = self.delegate; + if (delegate) { + return [delegate webContentAreaForLensCoordinator:self]; + } + + return [UIScreen mainScreen].bounds; +} + #pragma mark - WebStateListObserving methods - (void)webStateList:(WebStateList*)webStateList @@ -317,6 +325,13 @@ } } +- (void)webStateDidStartLoading:(web::WebState*)webState { + const id<ChromeLensController> lensController = self.lensController; + if (self.lensWebPageLoadTriggeredFromInputSelection && lensController) { + [lensController triggerSecondaryTransitionAnimation]; + } +} + - (void)webStateDestroyed:(web::WebState*)webState { DCHECK_EQ(webState, self.loadingWebState); self.loadingWebState = nil;
diff --git a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm index 1fdc17c..94591f04 100644 --- a/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm +++ b/ios/chrome/browser/ui/ntp/new_tab_page_coordinator_unittest.mm
@@ -29,6 +29,8 @@ #import "ios/chrome/browser/web_state_list/web_state_list.h" #import "ios/chrome/browser/web_state_list/web_state_opener.h" #import "ios/chrome/test/ios_chrome_scoped_testing_chrome_browser_state_manager.h" +#import "ios/web/public/test/fakes/fake_navigation_context.h" +#import "ios/web/public/test/fakes/fake_navigation_manager.h" #import "ios/web/public/test/fakes/fake_web_state.h" #import "ios/web/public/test/web_task_environment.h" #import "testing/gtest/include/gtest/gtest.h" @@ -99,9 +101,14 @@ std::make_unique<web::FakeWebState>(); NewTabPageTabHelper::CreateForWebState(web_state.get()); web_state->SetVisibleURL(url); - // Force the DidStopLoading callback. - web_state->SetLoading(true); - web_state->SetLoading(false); + auto navigation_manager = std::make_unique<web::FakeNavigationManager>(); + navigation_manager->AddItem(url, ui::PAGE_TRANSITION_LINK); + web_state->SetNavigationManager(std::move(navigation_manager)); + + // Force the URL load callbacks. + web::FakeNavigationContext navigation_context; + web_state->OnNavigationStarted(&navigation_context); + web_state->OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS); return std::move(web_state); }
diff --git a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 index 4d3f909f..73caff3c 100644 --- a/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -be03c64b44569baa3fb4bbe064975d06fa76ba36 \ No newline at end of file +670528dc9ab978f0dc68fad0b6fdd1ce8a1ab666 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 index bff45aa..6701690 100644 --- a/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1 +++ b/ios/google_internal/frameworks/ChromeSSOInternal.framework.dSYM.ios.zip.sha1
@@ -1 +1 @@ -569ff963ca1bfabe7a236de0c057a441e0e52b1f \ No newline at end of file +f547cce9256a37fd4ef8c47ddc434c0b0fe25f27 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 index c793a3c..26eb40b 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -e79514092cdfbc88a1652c4dc32635e4d8afb751 \ No newline at end of file +189887952b3931c6775033ac5fca80d36ae10e7d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 index 94947bd87..bcce62b 100644 --- a/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -6f79178cd83c34d9c4bbaf934c781291f28a67d7 \ No newline at end of file +d4087b1be923e5664a9cf90d794a8ea782e00b93 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 index 4ba2d1ce..b904ed2 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -e81db22aada10b50cacc7081e5a7d813bdb30472 \ No newline at end of file +afd248c2a332da19c893ddab96981e8c014c1f12 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 index a2409f3..75dfe4a9 100644 --- a/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_sso_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -8e87da09581e62c7f1c8b388570cad3bb909e21a \ No newline at end of file +73450b008f4d33dec59ac7da3e86e6bbf9d37821 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 index 33aaf72..6a8cb63e 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -bd8328d2ba2ad45101d98629285b2c5bfaf76418 \ No newline at end of file +deecc81491bcfc37cda31ee621ca4e1475d6eb7d \ No newline at end of file
diff --git a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 index 06c7974..759f70a 100644 --- a/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/chrome_test_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -f8645712304e4d2e00c864a3d656c16b1847ead3 \ No newline at end of file +f1209d487eedf56e3a73ce6410bbffa601beaf95 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 index 30b3d839..e4157ac 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -1d6bee1f7d6c43af22ef5e40297d696cc38db9d1 \ No newline at end of file +2e47ed454b0d78f159124e7655593cdb881d83c8 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 index fb35a144..e7070a7 100644 --- a/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/remoting_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -073bd03d62aba80f6e09d7c78c2a9068000b53af \ No newline at end of file +2f995d271eb8ca4b088090234ab10b7ca35e37a0 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 index 8eb2b69..6d61079 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.ios.zip.sha1
@@ -1 +1 @@ -dacd257107fa3d8aa7b6aecca454f5224661791f \ No newline at end of file +3136bc310c5ec219e4692b04b2d677edf5833d35 \ No newline at end of file
diff --git a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 index b873b71..6b2b343 100644 --- a/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1 +++ b/ios/google_internal/frameworks/web_view_shell_internal_dynamic_framework.iossimulator.zip.sha1
@@ -1 +1 @@ -057984130adb4015eaadb28fb5fb5e48d46873ef \ No newline at end of file +5b500e5196c9eb7bcdaeedaf04a7c84187b950ba \ No newline at end of file
diff --git a/ios/public/provider/chrome/browser/lens/lens_api.h b/ios/public/provider/chrome/browser/lens/lens_api.h index 11d17db..719101df 100644 --- a/ios/public/provider/chrome/browser/lens/lens_api.h +++ b/ios/public/provider/chrome/browser/lens/lens_api.h
@@ -31,6 +31,9 @@ - (void)lensControllerDidGenerateLoadParams: (const web::NavigationManager::WebLoadParams&)params; +// Returns the frame of the web content area of the browser. +- (CGRect)webContentFrame; + @end // A controller that can facilitate communication with the downstream Lens @@ -40,10 +43,11 @@ // A delegate that can receive Lens events forwarded by the controller. @property(nonatomic, weak) id<ChromeLensControllerDelegate> delegate; -// Returns an input selection UIViewController with the provided -// web content frame. -- (UIViewController*)inputSelectionViewControllerWithWebContentFrame: - (CGRect)webContentFrame; +// Returns an input selection UIViewController. +- (UIViewController*)inputSelectionViewController; + +// Triggers the secondary transition animation from native LVF to Lens Web. +- (void)triggerSecondaryTransitionAnimation; @end
diff --git a/ios/web/navigation/crw_wk_navigation_handler.mm b/ios/web/navigation/crw_wk_navigation_handler.mm index 7ed9889..71f4de9 100644 --- a/ios/web/navigation/crw_wk_navigation_handler.mm +++ b/ios/web/navigation/crw_wk_navigation_handler.mm
@@ -2084,6 +2084,9 @@ - (void)loadCancelled { // TODO(crbug.com/821995): Check if this function should be removed. if (self.navigationState != web::WKNavigationState::FINISHED) { + UMA_HISTOGRAM_BOOLEAN("IOS.NavigationStateNotFinishedInLoadCancelled", + self.beingDestroyed); + self.navigationState = web::WKNavigationState::FINISHED; if (!self.beingDestroyed) { self.webStateImpl->SetIsLoading(false);
diff --git a/media/gpu/windows/mf_audio_encoder.cc b/media/gpu/windows/mf_audio_encoder.cc index aa54a0a..5578040 100644 --- a/media/gpu/windows/mf_audio_encoder.cc +++ b/media/gpu/windows/mf_audio_encoder.cc
@@ -155,6 +155,7 @@ HRESULT CreateOutputMediaType(const int sample_rate, const int channels, const int bitrate, + media::AudioEncoder::AacOutputFormat format, ComPtr<IMFMediaType>* output_media_type) { // https://docs.microsoft.com/en-us/windows/win32/medfound/aac-encoder#output-types ComPtr<IMFMediaType> media_type; @@ -173,9 +174,14 @@ RETURN_IF_FAILED(media_type->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, adjusted_bitrate / 8)); - // The encoder can produce ADTS headers for us if we set the payload - // type to 1. - RETURN_IF_FAILED(media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 1)); + // Set payload format. + // https://learn.microsoft.com/en-us/windows/win32/medfound/mf-mt-aac-payload-type + // 0 - The stream contains raw_data_block elements only. (default) + // 1 - Audio Data Transport Stream (ADTS). + // The stream contains an adts_sequence, as defined by MPEG-2. + if (format == media::AudioEncoder::AacOutputFormat::ADTS) { + RETURN_IF_FAILED(media_type->SetUINT32(MF_MT_AAC_PAYLOAD_TYPE, 1)); + } *output_media_type = std::move(media_type); return S_OK; @@ -429,9 +435,10 @@ return; } + auto format = options_.aac.value_or(AacOptions()).format; ComPtr<IMFMediaType> output_media_type; hr = CreateOutputMediaType(options_.sample_rate, options_.channels, bitrate, - &output_media_type); + format, &output_media_type); if (FAILED(hr) || !output_media_type) { std::move(done_cb).Run(EncoderStatus::Codes::kEncoderInitializationError); return; @@ -457,6 +464,33 @@ hr = GetOutputBufferRequirements(mf_encoder_, output_media_type, options_.channels, &output_buffer_alignment_); + + /* + https://learn.microsoft.com/en-us/windows/win32/medfound/aac-encoder + + After the output type is set, the AAC encoder updates the type by adding + the MF_MT_USER_DATA attribute. This attribute contains the portion of + the HEAACWAVEINFO structure that appears after the WAVEFORMATEX structure + (that is, after the wfx member). + This is followed by the AudioSpecificConfig() data, + as defined by ISO/IEC 14496-3. + */ + UINT32 desc_size = 0; + if (output_media_type->GetBlobSize(MF_MT_USER_DATA, &desc_size) == S_OK && + desc_size > 0 && format == media::AudioEncoder::AacOutputFormat::AAC) { + codec_desc_.resize(desc_size); + size_t aac_config_offset = + sizeof(HEAACWAVEINFO) - offsetof(HEAACWAVEINFO, wPayloadType); + hr = output_media_type->GetBlob(MF_MT_USER_DATA, codec_desc_.data(), + desc_size, nullptr); + if (FAILED(hr) || aac_config_offset > codec_desc_.size()) { + std::move(done_cb).Run(EncoderStatus::Codes::kEncoderInitializationError); + return; + } + codec_desc_.erase(codec_desc_.begin(), + codec_desc_.begin() + aac_config_offset); + } + if (FAILED(hr)) { std::move(done_cb).Run(EncoderStatus::Codes::kEncoderInitializationError); return; @@ -728,7 +762,13 @@ return; } - output_cb_.Run(std::move(encoded_audio), absl::nullopt); + absl::optional<CodecDescription> desc; + if (!codec_desc_.empty()) { + desc = codec_desc_; + codec_desc_.clear(); + } + + output_cb_.Run(std::move(encoded_audio), desc); samples_in_encoder_ -= kSamplesPerFrame; hr = mf_encoder_->GetOutputStatus(&status); }
diff --git a/media/gpu/windows/mf_audio_encoder.h b/media/gpu/windows/mf_audio_encoder.h index 1f721eb8..078a89b 100644 --- a/media/gpu/windows/mf_audio_encoder.h +++ b/media/gpu/windows/mf_audio_encoder.h
@@ -186,6 +186,7 @@ int input_buffer_alignment_; int output_buffer_alignment_; bool initialized_ = false; + std::vector<uint8_t> codec_desc_; // We can't produce output until at least `kMinSamplesForOutput` have been // provided. Until then, `output_cb_` will not be run.
diff --git a/media/mojo/mojom/audio_encoder.mojom b/media/mojo/mojom/audio_encoder.mojom index 9283796..3bd42d43 100644 --- a/media/mojo/mojom/audio_encoder.mojom +++ b/media/mojo/mojom/audio_encoder.mojom
@@ -8,6 +8,11 @@ import "media/mojo/mojom/audio_parameters.mojom"; import "mojo/public/mojom/base/time.mojom"; +enum AacOutputFormat { kAAC, kADTS }; +struct AacAudioEncoderConfig { + AacOutputFormat format; +}; + // This defines a mojo transport format for media::AudioEncoderConfig. // See media/base/audio_encoder.h for descriptions. struct AudioEncoderConfig { @@ -23,6 +28,9 @@ // Target encoded bitrate - bits per second of playback // 0 - if client has no bitrate preference. uint32 bitrate; + + // AAC specific parts of the config + AacAudioEncoderConfig aac; }; // This defines a mojo transport format for media::EncodedAudioBuffer.
diff --git a/media/mojo/mojom/audio_encoder_config_mojom_traits.cc b/media/mojo/mojom/audio_encoder_config_mojom_traits.cc index 263929e6..529246ad 100644 --- a/media/mojo/mojom/audio_encoder_config_mojom_traits.cc +++ b/media/mojo/mojom/audio_encoder_config_mojom_traits.cc
@@ -12,6 +12,51 @@ namespace mojo { // static +media::mojom::AacOutputFormat EnumTraits<media::mojom::AacOutputFormat, + media::AudioEncoder::AacOutputFormat>:: + ToMojom(media::AudioEncoder::AacOutputFormat input) { + switch (input) { + case media::AudioEncoder::AacOutputFormat::ADTS: + return media::mojom::AacOutputFormat::kADTS; + case media::AudioEncoder::AacOutputFormat::AAC: + return media::mojom::AacOutputFormat::kAAC; + } + NOTREACHED(); + return media::mojom::AacOutputFormat::kAAC; +} + +// static +bool EnumTraits<media::mojom::AacOutputFormat, + media::AudioEncoder::AacOutputFormat>:: + FromMojom(media::mojom::AacOutputFormat format, + media::AudioEncoder::AacOutputFormat* output) { + switch (format) { + case media::mojom::AacOutputFormat::kADTS: + *output = media::AudioEncoder::AacOutputFormat::ADTS; + return true; + case media::mojom::AacOutputFormat::kAAC: + *output = media::AudioEncoder::AacOutputFormat::AAC; + return true; + } + NOTREACHED(); + return false; +} + +// static +bool StructTraits<media::mojom::AacAudioEncoderConfigDataView, + media::AudioEncoder::AacOptions>:: + Read(media::mojom::AacAudioEncoderConfigDataView input, + media::AudioEncoder::AacOptions* output) { + media::AudioEncoder::AacOutputFormat format; + if (!input.ReadFormat(&format)) { + return false; + } + + output->format = format; + return true; +} + +// static bool StructTraits<media::mojom::AudioEncoderConfigDataView, media::AudioEncoderConfig>:: Read(media::mojom::AudioEncoderConfigDataView input, @@ -33,6 +78,12 @@ return false; output->channels = input.channel_count(); + media::AudioEncoder::AacOptions aac; + if (!input.ReadAac(&aac)) { + return false; + } + output->aac = aac; + return true; }
diff --git a/media/mojo/mojom/audio_encoder_config_mojom_traits.h b/media/mojo/mojom/audio_encoder_config_mojom_traits.h index d99908a1..b97f391 100644 --- a/media/mojo/mojom/audio_encoder_config_mojom_traits.h +++ b/media/mojo/mojom/audio_encoder_config_mojom_traits.h
@@ -13,6 +13,28 @@ namespace mojo { template <> +struct EnumTraits<media::mojom::AacOutputFormat, + media::AudioEncoder::AacOutputFormat> { + static media::mojom::AacOutputFormat ToMojom( + media::AudioEncoder::AacOutputFormat input); + + static bool FromMojom(media::mojom::AacOutputFormat, + media::AudioEncoder::AacOutputFormat* output); +}; + +template <> +struct StructTraits<media::mojom::AacAudioEncoderConfigDataView, + media::AudioEncoder::AacOptions> { + static media::AudioEncoder::AacOutputFormat format( + media::AudioEncoder::AacOptions& input) { + return input.format; + } + + static bool Read(media::mojom::AacAudioEncoderConfigDataView input, + media::AudioEncoder::AacOptions* output); +}; + +template <> struct StructTraits<media::mojom::AudioEncoderConfigDataView, media::AudioEncoderConfig> { static media::AudioCodec codec(const media::AudioEncoderConfig& input) { @@ -31,6 +53,11 @@ return input.bitrate.value_or(0); } + static media::AudioEncoder::AacOptions aac( + const media::AudioEncoderConfig& input) { + return input.aac.value_or(media::AudioEncoder::AacOptions()); + } + static bool Read(media::mojom::AudioEncoderConfigDataView input, media::AudioEncoderConfig* output); };
diff --git a/media/renderers/video_resource_updater.cc b/media/renderers/video_resource_updater.cc index b97612a..2d15a5c 100644 --- a/media/renderers/video_resource_updater.cc +++ b/media/renderers/video_resource_updater.cc
@@ -669,44 +669,18 @@ overlay_plane_id_); break; } - case VideoFrameResourceType::YUV: { - DCHECK_EQ(frame_resources_.size(), - VideoFrame::NumPlanes(frame->format())); - if (frame->HasTextures()) { - DCHECK(frame->format() == PIXEL_FORMAT_NV12 || - frame->format() == PIXEL_FORMAT_P016LE || - frame->format() == PIXEL_FORMAT_I420); - } - - // Get the scaling factor of the YA texture relative to the UV texture. - const gfx::Size uv_sample_size = - VideoFrame::SampleSize(frame->format(), VideoFrame::kUPlane); - - auto* yuv_video_quad = - render_pass->CreateAndAppendDrawQuad<viz::YUVVideoDrawQuad>(); - yuv_video_quad->SetNew( - shared_quad_state, quad_rect, visible_quad_rect, needs_blending, - coded_size, visible_rect, uv_sample_size, frame_resources_[0].id, - frame_resources_[1].id, - frame_resources_.size() > 2 ? frame_resources_[2].id - : frame_resources_[1].id, - frame_resources_.size() > 3 ? frame_resources_[3].id - : viz::kInvalidResourceId, - frame->ColorSpace(), frame_resource_offset_, - frame_resource_multiplier_, frame_bits_per_channel_, - ProtectedVideoTypeFromMetadata(frame->metadata()), - frame->hdr_metadata()); - - for (viz::ResourceId resource_id : yuv_video_quad->resources) { - resource_provider_->ValidateResource(resource_id); - } - break; - } + case VideoFrameResourceType::YUV: case VideoFrameResourceType::YUVA: { DCHECK_EQ(frame_resources_.size(), VideoFrame::NumPlanes(frame->format())); if (frame->HasTextures()) { - DCHECK_EQ(frame->format(), PIXEL_FORMAT_NV12A); + if (frame_resource_type_ == VideoFrameResourceType::YUV) { + DCHECK(frame->format() == PIXEL_FORMAT_NV12 || + frame->format() == PIXEL_FORMAT_P016LE || + frame->format() == PIXEL_FORMAT_I420); + } else { + DCHECK_EQ(frame->format(), PIXEL_FORMAT_NV12A); + } } // Get the scaling factor of the YA texture relative to the UV texture. @@ -715,16 +689,25 @@ auto* yuv_video_quad = render_pass->CreateAndAppendDrawQuad<viz::YUVVideoDrawQuad>(); + viz::ResourceId v_plane_id; + viz::ResourceId a_plane_id; + if (frame_resource_type_ == VideoFrameResourceType::YUV) { + v_plane_id = frame_resources_.size() > 2 ? frame_resources_[2].id + : frame_resources_[1].id; + a_plane_id = frame_resources_.size() > 3 ? frame_resources_[3].id + : viz::kInvalidResourceId; + } else { + v_plane_id = frame_resources_.size() > 3 ? frame_resources_[2].id + : frame_resources_[1].id; + a_plane_id = frame_resources_.size() > 3 ? frame_resources_[3].id + : frame_resources_[2].id; + } yuv_video_quad->SetNew( shared_quad_state, quad_rect, visible_quad_rect, needs_blending, coded_size, visible_rect, uv_sample_size, frame_resources_[0].id, - frame_resources_[1].id, - frame_resources_.size() > 3 ? frame_resources_[2].id - : frame_resources_[1].id, - frame_resources_.size() > 3 ? frame_resources_[3].id - : frame_resources_[2].id, - frame->ColorSpace(), frame_resource_offset_, - frame_resource_multiplier_, frame_bits_per_channel_, + frame_resources_[1].id, v_plane_id, a_plane_id, frame->ColorSpace(), + frame_resource_offset_, frame_resource_multiplier_, + frame_bits_per_channel_, ProtectedVideoTypeFromMetadata(frame->metadata()), frame->hdr_metadata());
diff --git a/pdf/loader/url_loader_unittest.cc b/pdf/loader/url_loader_unittest.cc index 1d23935..ea1d4bc 100644 --- a/pdf/loader/url_loader_unittest.cc +++ b/pdf/loader/url_loader_unittest.cc
@@ -168,8 +168,8 @@ std::unique_ptr<UrlLoader> loader_; // Becomes invalid if `loader_` is closed or destructed. - raw_ptr<MockWebAssociatedURLLoader> mock_url_loader_ = - fake_client_.mock_url_loader(); + raw_ptr<MockWebAssociatedURLLoader, DisableDanglingPtrDetection> + mock_url_loader_ = fake_client_.mock_url_loader(); blink::WebURLRequest saved_request_; };
diff --git a/sandbox/policy/win/sandbox_win.cc b/sandbox/policy/win/sandbox_win.cc index 38601d0..86a96e44 100644 --- a/sandbox/policy/win/sandbox_win.cc +++ b/sandbox/policy/win/sandbox_win.cc
@@ -718,11 +718,13 @@ process_type == switches::kGpuProcess || process_type == switches::kUtilityProcess) { if (logging::IsLoggingToFileEnabled()) { - DCHECK(base::FilePath(logging::GetLogFileFullPath()).IsAbsolute()); + auto log_path = logging::GetLogFileFullPath(); + DCHECK(base::FilePath(log_path).IsAbsolute()); result = config->AddRule(SubSystem::kFiles, Semantics::kFilesAllowAny, - logging::GetLogFileFullPath().c_str()); - if (result != SBOX_ALL_OK) + log_path.c_str()); + if (result != SBOX_ALL_OK) { return result; + } } }
diff --git a/services/data_decoder/public/cpp/BUILD.gn b/services/data_decoder/public/cpp/BUILD.gn index 373e9007..bc4e847 100644 --- a/services/data_decoder/public/cpp/BUILD.gn +++ b/services/data_decoder/public/cpp/BUILD.gn
@@ -42,7 +42,7 @@ "//net", "//services/data_decoder/public/mojom", ] - deps = [] + deps = [ "//build:blink_buildflags" ] if (is_android) { sources += [ "json_sanitizer_android.cc" ] @@ -57,7 +57,7 @@ # NOTE: We depend on this target here for iOS only, to support in-process # use of the service. Non-test targets in this directory should otherwise # NEVER depend on this target. - deps = [ "//services/data_decoder:lib" ] + deps += [ "//services/data_decoder:lib" ] } else { public += [ "decode_image.h",
diff --git a/services/data_decoder/public/cpp/data_decoder.cc b/services/data_decoder/public/cpp/data_decoder.cc index 358bdac..185915f4 100644 --- a/services/data_decoder/public/cpp/data_decoder.cc +++ b/services/data_decoder/public/cpp/data_decoder.cc
@@ -12,6 +12,7 @@ #include "base/task/sequenced_task_runner.h" #include "base/task/thread_pool.h" #include "base/time/time.h" +#include "build/blink_buildflags.h" #include "build/build_config.h" #include "net/http/structured_headers.h" #include "services/data_decoder/public/mojom/gzipper.mojom.h" @@ -23,7 +24,7 @@ #include "services/data_decoder/public/cpp/json_sanitizer.h" #endif -#if BUILDFLAG(IS_IOS) +#if !BUILDFLAG(USE_BLINK) #include "services/data_decoder/data_decoder_service.h" // nogncheck #endif @@ -114,7 +115,7 @@ scoped_refptr<DataDecoder::CancellationFlag> is_cancelled_; }; -#if BUILDFLAG(IS_IOS) +#if !BUILDFLAG(USE_BLINK) void BindInProcessService( mojo::PendingReceiver<mojom::DataDecoderService> receiver) { static base::NoDestructor<scoped_refptr<base::SequencedTaskRunner>> @@ -167,7 +168,7 @@ if (provider) { provider->BindDataDecoderService(service_.BindNewPipeAndPassReceiver()); } else { -#if BUILDFLAG(IS_IOS) +#if !BUILDFLAG(USE_BLINK) BindInProcessService(service_.BindNewPipeAndPassReceiver()); #else LOG(FATAL) << "data_decoder::ServiceProvider::Set() must be called "
diff --git a/services/viz/public/cpp/compositing/paint_filter_mojom_traits.cc b/services/viz/public/cpp/compositing/paint_filter_mojom_traits.cc index 9ddb806..04309021 100644 --- a/services/viz/public/cpp/compositing/paint_filter_mojom_traits.cc +++ b/services/viz/public/cpp/compositing/paint_filter_mojom_traits.cc
@@ -4,6 +4,8 @@ #include "services/viz/public/cpp/compositing/paint_filter_mojom_traits.h" +#include <utility> + #include "cc/paint/paint_filter.h" namespace mojo { @@ -13,8 +15,7 @@ StructTraits<viz::mojom::PaintFilterDataView, sk_sp<cc::PaintFilter>>::data( const sk_sp<cc::PaintFilter>& filter) { std::vector<uint8_t> memory; - memory.resize(cc::PaintOpWriter::HeaderBytes() + - cc::PaintFilter::GetFilterSize(filter.get())); + memory.resize(cc::PaintOpWriter::SerializedSize(filter.get())); // No need to populate the SerializeOptions here since the security // constraints explicitly disable serializing images using the transfer cache // and serialization of PaintRecords.
diff --git a/services/viz/public/cpp/gpu/gpu.cc b/services/viz/public/cpp/gpu/gpu.cc index f05b721..506d9b6 100644 --- a/services/viz/public/cpp/gpu/gpu.cc +++ b/services/viz/public/cpp/gpu/gpu.cc
@@ -127,7 +127,9 @@ // request. This must be called from main thread. void SetWaitableEvent(base::WaitableEvent* establish_event) { DCHECK(main_task_runner_->BelongsToCurrentThread()); + DCHECK(establish_event); base::AutoLock mutex(lock_); + DCHECK(!establish_event_); // If we've already received a response then don't reset |establish_event|. // The caller won't block and will immediately process the response. @@ -323,7 +325,7 @@ } establish_callbacks_.push_back(std::move(callback)); - SendEstablishGpuChannelRequest(); + SendEstablishGpuChannelRequest(/*waitable_event=*/nullptr); } scoped_refptr<gpu::GpuChannelHost> Gpu::EstablishGpuChannelSync() { @@ -335,10 +337,9 @@ return channel; SCOPED_UMA_HISTOGRAM_TIMER("GPU.EstablishGpuChannelSyncTime"); - SendEstablishGpuChannelRequest(); base::WaitableEvent event(base::WaitableEvent::ResetPolicy::MANUAL, base::WaitableEvent::InitialState::SIGNALED); - pending_request_->SetWaitableEvent(&event); + SendEstablishGpuChannelRequest(&event); event.Wait(); // Running FinishOnMain() will create |gpu_channel_| and run any callbacks @@ -367,12 +368,19 @@ return gpu_channel_; } -void Gpu::SendEstablishGpuChannelRequest() { - if (pending_request_) +void Gpu::SendEstablishGpuChannelRequest(base::WaitableEvent* waitable_event) { + if (pending_request_) { + if (waitable_event) { + pending_request_->SetWaitableEvent(waitable_event); + } return; + } pending_request_ = base::MakeRefCounted<EstablishRequest>(this, main_task_runner_); + if (waitable_event) { + pending_request_->SetWaitableEvent(waitable_event); + } io_task_runner_->PostTask( FROM_HERE, base::BindOnce(&EstablishRequest::SendRequest, pending_request_,
diff --git a/services/viz/public/cpp/gpu/gpu.h b/services/viz/public/cpp/gpu/gpu.h index 85fb350b..a13e9679 100644 --- a/services/viz/public/cpp/gpu/gpu.h +++ b/services/viz/public/cpp/gpu/gpu.h
@@ -74,7 +74,7 @@ // Sends a request to establish a gpu channel. If a request is currently // pending this will do nothing. - void SendEstablishGpuChannelRequest(); + void SendEstablishGpuChannelRequest(base::WaitableEvent* waitable_event); // Handles results of request to establish a gpu channel in // |pending_request_|.
diff --git a/sql/database_unittest.cc b/sql/database_unittest.cc index 3ee7f5a5..13be18fa 100644 --- a/sql/database_unittest.cc +++ b/sql/database_unittest.cc
@@ -1746,7 +1746,7 @@ ASSERT_TRUE(!db_->DoesTableExist("meta")); // When the meta table is first created, it sets up to map everything. - MetaTable().Init(db_.get(), 1, 1); + ASSERT_TRUE(MetaTable().Init(db_.get(), 1, 1)); ASSERT_TRUE(db_->DoesTableExist("meta")); ASSERT_GT(db_->ComputeMmapSizeForOpen(), kMmapAlot); ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status)); @@ -1765,7 +1765,7 @@ // Re-initializing the meta table does not re-create the key if the table // already exists. ASSERT_TRUE(db_->Execute("DELETE FROM meta WHERE key = 'mmap_status'")); - MetaTable().Init(db_.get(), 1, 1); + ASSERT_TRUE(MetaTable().Init(db_.get(), 1, 1)); ASSERT_EQ(MetaTable::kMmapSuccess, mmap_status); ASSERT_TRUE(MetaTable::GetMmapStatus(db_.get(), &mmap_status)); ASSERT_EQ(0, mmap_status);
diff --git a/sql/meta_table.h b/sql/meta_table.h index a1cc1fa..ce552a9 100644 --- a/sql/meta_table.h +++ b/sql/meta_table.h
@@ -77,9 +77,7 @@ // Versions must be greater than 0 to distinguish missing versions (see // GetVersionNumber()). If there was no meta table (proxy for a fresh // database), mmap status is set to `kMmapSuccess`. - // TODO(apaseltiner): Mark this [[nodiscard]] once all callers have been - // updated. - bool Init(Database* db, int version, int compatible_version); + [[nodiscard]] bool Init(Database* db, int version, int compatible_version); // Resets this MetaTable object, making another call to Init() possible. void Reset();
diff --git a/storage/browser/file_system/file_system_url.cc b/storage/browser/file_system/file_system_url.cc index 9d83fbd..91651be9 100644 --- a/storage/browser/file_system/file_system_url.cc +++ b/storage/browser/file_system/file_system_url.cc
@@ -22,7 +22,7 @@ namespace { -bool areSameStorageKey(const FileSystemURL& a, const FileSystemURL& b) { +bool AreSameStorageKey(const FileSystemURL& a, const FileSystemURL& b) { // TODO(https://crbug.com/1396116): Make the `storage_key_` member optional. // This class improperly uses a StorageKey with an opaque origin to indicate a // lack of origin for FileSystemURLs corresponding to non-sandboxed file @@ -211,7 +211,7 @@ !base::FeatureList::IsEnabled( features::kFileSystemURLComparatorsTreatOpaqueOriginAsNoOrigin) || (is_valid() && other.is_valid()); - return areSameStorageKey(*this, other) && is_maybe_valid && + return AreSameStorageKey(*this, other) && is_maybe_valid && type() == other.type() && filesystem_id() == other.filesystem_id() && bucket() == other.bucket(); } @@ -221,7 +221,7 @@ return true; } - return areSameStorageKey(*this, that) && type_ == that.type_ && + return AreSameStorageKey(*this, that) && type_ == that.type_ && path_ == that.path_ && filesystem_id_ == that.filesystem_id_ && is_valid_ == that.is_valid_ && bucket_ == that.bucket_; } @@ -229,14 +229,18 @@ bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs, const FileSystemURL& rhs) const { DCHECK(lhs.is_valid_ && rhs.is_valid_); - if (lhs.storage_key() != rhs.storage_key()) + if (!AreSameStorageKey(lhs, rhs)) { return lhs.storage_key() < rhs.storage_key(); - if (lhs.type_ != rhs.type_) + } + if (lhs.type_ != rhs.type_) { return lhs.type_ < rhs.type_; - if (lhs.filesystem_id_ != rhs.filesystem_id_) + } + if (lhs.filesystem_id_ != rhs.filesystem_id_) { return lhs.filesystem_id_ < rhs.filesystem_id_; - if (lhs.bucket_ != rhs.bucket_) + } + if (lhs.bucket_ != rhs.bucket_) { return lhs.bucket_ < rhs.bucket_; + } return lhs.path_ < rhs.path_; }
diff --git a/testing/buildbot/chromium.android.json b/testing/buildbot/chromium.android.json index 7c20f7b..7b5e58a 100644 --- a/testing/buildbot/chromium.android.json +++ b/testing/buildbot/chromium.android.json
@@ -3907,7 +3907,7 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android30.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_11.crashpad_tests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter" ], "merge": { "args": [ @@ -4914,7 +4914,7 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android30.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_11_12.media_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter" ], "merge": { "args": [ @@ -6707,7 +6707,7 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android31.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_12.base_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.base_unittests.filter" ], "merge": { "args": [ @@ -7872,7 +7872,7 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android31.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_12.crashpad_tests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter" ], "merge": { "args": [ @@ -8881,7 +8881,7 @@ "--gs-results-bucket=chromium-result-details", "--recover-devices", "--avd-config=../../tools/android/avd/proto/generic_android31.textpb", - "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_11_12.media_unittests.filter" + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter" ], "merge": { "args": [ @@ -10790,7 +10790,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.base_unittests.filter" ], "merge": { "args": [ @@ -11941,7 +11942,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter" ], "merge": { "args": [ @@ -12946,7 +12948,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter" ], "merge": { "args": [ @@ -13360,7 +13363,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android32_foldable.textpb", + "--gtest_filter=-ScopedDirTest.CloseOutOfScope" ], "merge": { "args": [ @@ -14710,7 +14714,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android33.textpb", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.base_unittests.filter" ], "merge": { "args": [ @@ -15861,7 +15866,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android33.textpb", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter" ], "merge": { "args": [ @@ -16866,7 +16872,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android33.textpb", + "--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter" ], "merge": { "args": [ @@ -17280,7 +17287,8 @@ "args": [ "--gs-results-bucket=chromium-result-details", "--recover-devices", - "--avd-config=../../tools/android/avd/proto/generic_android33.textpb" + "--avd-config=../../tools/android/avd/proto/generic_android33.textpb", + "--gtest_filter=-ScopedDirTest.CloseOutOfScope" ], "merge": { "args": [
diff --git a/testing/buildbot/filters/BUILD.gn b/testing/buildbot/filters/BUILD.gn index 890874a..02ad0d9d 100644 --- a/testing/buildbot/filters/BUILD.gn +++ b/testing/buildbot/filters/BUILD.gn
@@ -31,7 +31,7 @@ testonly = true data = [ - "//testing/buildbot/filters/android.emulator_12.base_unittests.filter", + "//testing/buildbot/filters/android.emulator.base_unittests.filter", "//testing/buildbot/filters/android.pie_tot.base_unittests.filter", "//testing/buildbot/filters/fuchsia.lsan.base_unittests.filter", ] @@ -169,8 +169,7 @@ testonly = true data = [ - "//testing/buildbot/filters/android.emulator_11.crashpad_tests.filter", - "//testing/buildbot/filters/android.emulator_12.crashpad_tests.filter", + "//testing/buildbot/filters/android.emulator.crashpad_tests.filter", "//testing/buildbot/filters/android.pie_tot.crashpad_tests.filter", ] } @@ -315,7 +314,7 @@ source_set("media_unittests_filters") { data = [ - "//testing/buildbot/filters/android.emulator_11_12.media_unittests.filter", + "//testing/buildbot/filters/android.emulator.media_unittests.filter", "//testing/buildbot/filters/fuchsia.debug.media_unittests.filter", ] }
diff --git a/testing/buildbot/filters/android.emulator_12.base_unittests.filter b/testing/buildbot/filters/android.emulator.base_unittests.filter similarity index 100% rename from testing/buildbot/filters/android.emulator_12.base_unittests.filter rename to testing/buildbot/filters/android.emulator.base_unittests.filter
diff --git a/testing/buildbot/filters/android.emulator_12.crashpad_tests.filter b/testing/buildbot/filters/android.emulator.crashpad_tests.filter similarity index 100% rename from testing/buildbot/filters/android.emulator_12.crashpad_tests.filter rename to testing/buildbot/filters/android.emulator.crashpad_tests.filter
diff --git a/testing/buildbot/filters/android.emulator_11_12.media_unittests.filter b/testing/buildbot/filters/android.emulator.media_unittests.filter similarity index 84% rename from testing/buildbot/filters/android.emulator_11_12.media_unittests.filter rename to testing/buildbot/filters/android.emulator.media_unittests.filter index 33612d2..a644e4a4 100644 --- a/testing/buildbot/filters/android.emulator_11_12.media_unittests.filter +++ b/testing/buildbot/filters/android.emulator.media_unittests.filter
@@ -2,4 +2,3 @@ # Not applicable to emulator due to not supporting fence sync -PaintCanvasVideoRendererWithGLTest.CopyVideoFrameTexturesToGLTexture* -PaintCanvasVideoRendererWithGLTest.CopyVideoFrameYUVDataToGLTexture* --PaintCanvasVideoRendererWithGLTest.Paint*
diff --git a/testing/buildbot/filters/android.emulator_11.crashpad_tests.filter b/testing/buildbot/filters/android.emulator_11.crashpad_tests.filter deleted file mode 100644 index 4f48442..0000000 --- a/testing/buildbot/filters/android.emulator_11.crashpad_tests.filter +++ /dev/null
@@ -1,3 +0,0 @@ -# crbug.com/1188310 --CrashReportDatabaseTest.CleanBrokenDatabase --ProcessReaderLinux.ChildThreadsWithSmallUserStacks
diff --git a/testing/buildbot/test_suite_exceptions.pyl b/testing/buildbot/test_suite_exceptions.pyl index 91c3a38..a7fee25 100644 --- a/testing/buildbot/test_suite_exceptions.pyl +++ b/testing/buildbot/test_suite_exceptions.pyl
@@ -150,7 +150,17 @@ }, 'android-12-x64-rel': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_12.base_unittests.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.base_unittests.filter', + ], + }, + 'android-12l-x64-dbg-tests': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.base_unittests.filter', + ], + }, + 'android-13-x64-rel': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.base_unittests.filter', ], }, 'fuchsia-code-coverage': { @@ -2028,12 +2038,22 @@ }, 'android-11-x86-rel': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_11.crashpad_tests.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter', ], }, 'android-12-x64-rel': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_12.crashpad_tests.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter', + ], + }, + 'android-12l-x64-dbg-tests': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter', + ], + }, + 'android-13-x64-rel': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.crashpad_tests.filter', ], }, # TODO(crbug.com/1254975): dyld was rebuilt for macOS 12, which breaks @@ -2726,12 +2746,22 @@ 'modifications': { 'android-11-x86-rel': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_11_12.media_unittests.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter', ], }, 'android-12-x64-rel': { 'args': [ - '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator_11_12.media_unittests.filter', + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter', + ], + }, + 'android-12l-x64-dbg-tests': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter', + ], + }, + 'android-13-x64-rel': { + 'args': [ + '--test-launcher-filter-file=../../testing/buildbot/filters/android.emulator.media_unittests.filter', ], }, 'android-pie-arm64-rel': { @@ -3043,6 +3073,18 @@ '--gtest_filter=-ScopedDirTest.CloseOutOfScope', ], }, + 'android-12l-x64-dbg-tests': { + 'args': [ + # TODO(crbug.com/1260440): Fix the failed test + '--gtest_filter=-ScopedDirTest.CloseOutOfScope', + ], + }, + 'android-13-x64-rel': { + 'args': [ + # TODO(crbug.com/1260440): Fix the failed test + '--gtest_filter=-ScopedDirTest.CloseOutOfScope', + ], + }, 'android-nougat-x86-rel': { 'args': [ # TODO(crbug.com/1260440): Fix the failed test
diff --git a/testing/variations/fieldtrial_testing_config.json b/testing/variations/fieldtrial_testing_config.json index eea7ac0..8e23284a 100644 --- a/testing/variations/fieldtrial_testing_config.json +++ b/testing/variations/fieldtrial_testing_config.json
@@ -438,6 +438,7 @@ { "name": "Enabled", "params": { + "enable_bookmarks": "true", "enable_longpress_entry": "true", "enable_share": "true" }, @@ -1344,47 +1345,6 @@ ] } ], - "AutofillSaveCardUiExperiment": [ - { - "platforms": [ - "chromeos", - "chromeos_lacros", - "fuchsia", - "linux", - "mac", - "windows" - ], - "experiments": [ - { - "name": "EnabledEncryptedAndSecure", - "params": { - "autofill_save_card_ui_experiment_selector_in_number": "2" - }, - "enable_features": [ - "AutofillSaveCardUiExperiment" - ] - }, - { - "name": "EnabledFasterAndProtected", - "params": { - "autofill_save_card_ui_experiment_selector_in_number": "1" - }, - "enable_features": [ - "AutofillSaveCardUiExperiment" - ] - }, - { - "name": "EnabledCurrentWithUserAvatarAndEmail", - "params": { - "autofill_save_card_ui_experiment_selector_in_number": "3" - }, - "enable_features": [ - "AutofillSaveCardUiExperiment" - ] - } - ] - } - ], "AutofillServerCommunication": [ { "platforms": [ @@ -5690,6 +5650,27 @@ ] } ], + "HighlightManagedPrefDisclaimerAndroid": [ + { + "platforms": [ + "android" + ], + "experiments": [ + { + "name": "Enabled", + "enable_features": [ + "HighlightManagedPrefDisclaimerAndroid" + ] + }, + { + "name": "Control", + "disable_features": [ + "HighlightManagedPrefDisclaimerAndroid" + ] + } + ] + } + ], "HoldbackRemoveMobileViewportDoubleTap": [ { "platforms": [
diff --git a/third_party/blink/common/features.cc b/third_party/blink/common/features.cc index 253de9a..7687280f 100644 --- a/third_party/blink/common/features.cc +++ b/third_party/blink/common/features.cc
@@ -1507,11 +1507,11 @@ // TODO(mahesh.ma): Enable for supported Android versions once feature is ready. BASE_FEATURE(kStylusWritingToInput, "StylusWritingToInput", - base::FEATURE_DISABLED_BY_DEFAULT); + base::FEATURE_ENABLED_BY_DEFAULT); BASE_FEATURE(kAndroidExtendedEditingCommands, "AndroidExtendedEditingCommands", - base::FEATURE_ENABLED_BY_DEFAULT); + base::FEATURE_DISABLED_BY_DEFAULT); BASE_FEATURE(kStylusPointerAdjustment, "StylusPointerAdjustment",
diff --git a/third_party/blink/perf_tests/view_transitions/OWNERS b/third_party/blink/perf_tests/view_transitions/OWNERS new file mode 100644 index 0000000..1fbd23f --- /dev/null +++ b/third_party/blink/perf_tests/view_transitions/OWNERS
@@ -0,0 +1,3 @@ +bokan@chromium.org +khushalsagar@chromium.org +vmpstr@chromium.org
diff --git a/third_party/blink/perf_tests/view_transitions/huge_element_capture.html b/third_party/blink/perf_tests/view_transitions/huge_element_capture.html new file mode 100644 index 0000000..9adb40e --- /dev/null +++ b/third_party/blink/perf_tests/view_transitions/huge_element_capture.html
@@ -0,0 +1,45 @@ +<!DOCTYPE html> +<html> +<head> +<style> +html { view-transition-name: unset } +#target { + height: 100000px; + width: 1000px; + position: absolute; + background: lightblue; + contain: layout; + view-transition-name: target; +} +.left { + left: 8px; +} +.right { + right: 8px; +} +::view-transition-group(*) { + animation-duration: 0s; +} +</style> +<script src="../resources/runner.js"></script> +<script> +function startTest() { + var transition; + PerfTestRunner.measureFrameTime({ + description: "Measures performance starting/finishing a transition with a large element", + setup: () => { + transition = document.startViewTransition(() => { + target.classList.toggle("left"); + target.classList.toggle("right"); + }); + }, + run: async () => { await transition.finished }, + done: () => {} + }); +} +</script> +</head> +<body onload="startTest()"> +<div id=target class=left>This is a div!</div> +<div id="log"></div> +</body></html>
diff --git a/third_party/blink/perf_tests/view_transitions/many_small_elements_capture.html b/third_party/blink/perf_tests/view_transitions/many_small_elements_capture.html new file mode 100644 index 0000000..09f7d17 --- /dev/null +++ b/third_party/blink/perf_tests/view_transitions/many_small_elements_capture.html
@@ -0,0 +1,52 @@ +<!DOCTYPE html> +<html> +<head> +<style> +html { view-transition-name: unset } +#container > * { + contain: layout; + display: inline-block; + border: 1px solid black; + width: 20px; + height: 20px; +} +.green > * { + background: green; +} +.blue > * { + background: blue; +} +::view-transition-group(*) { + animation-duration: 0s; +} +</style> +<script src="../resources/runner.js"></script> + +<script> +const kCount = 1500; + +function startTest() { + var transition; + for (let i = 0; i < kCount; i++) { + let e = document.createElement("div"); + e.viewTransitionName = "e" + i; + container.appendChild(e); + } + PerfTestRunner.measureFrameTime({ + description: "Measures performance starting/finishing a transition with many small elements", + setup: () => { + transition = document.startViewTransition(() => { + container.classList.toggle("green"); + container.classList.toggle("blue"); + }); + }, + run: async () => { await transition.finished }, + done: () => {} + }); +} +</script> +</head> +<body onload="startTest()"> +<div id=container class=green></div> +<div id="log"></div> +</body></html>
diff --git a/third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h b/third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h index a214b9c4..a9592b2 100644 --- a/third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h +++ b/third_party/blink/public/platform/modules/service_worker/web_service_worker_network_provider.h
@@ -31,19 +31,15 @@ #ifndef THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_SERVICE_WORKER_WEB_SERVICE_WORKER_NETWORK_PROVIDER_H_ #define THIRD_PARTY_BLINK_PUBLIC_PLATFORM_MODULES_SERVICE_WORKER_WEB_SERVICE_WORKER_NETWORK_PROVIDER_H_ -#include <memory> - #include "base/memory/scoped_refptr.h" #include "third_party/blink/public/mojom/frame/frame.mojom-shared.h" #include "third_party/blink/public/mojom/service_worker/controller_service_worker_mode.mojom-shared.h" #include "third_party/blink/public/mojom/service_worker/service_worker_fetch_handler_type.mojom-shared.h" #include "third_party/blink/public/platform/cross_variant_mojo_util.h" -#include "third_party/blink/public/platform/scheduler/web_resource_loading_task_runner_handle.h" #include "third_party/blink/public/platform/web_url_loader.h" namespace blink { -class WebBackForwardCacheLoaderHelper; class WebURLRequest; // This interface allows the Blink embedder to implement loading functionality @@ -63,14 +59,10 @@ // request made. virtual void WillSendRequest(WebURLRequest&) = 0; - // Returns a URLLoader for loading |request|. May return nullptr to fall back - // to the default loading behavior. - virtual std::unique_ptr<WebURLLoader> CreateURLLoader( - const WebURLRequest& request, - std::unique_ptr<scheduler::WebResourceLoadingTaskRunnerHandle>, - std::unique_ptr<scheduler::WebResourceLoadingTaskRunnerHandle>, - CrossVariantMojoRemote<blink::mojom::KeepAliveHandleInterfaceBase>, - WebBackForwardCacheLoaderHelper) = 0; + // Returns a SharedURLLoaderFactory for loading |request|. May return nullptr + // to fall back to the default loading behavior. + virtual scoped_refptr<network::SharedURLLoaderFactory> + GetSubresourceLoaderFactory(const WebURLRequest& request) = 0; // For service worker clients. virtual blink::mojom::ControllerServiceWorkerMode
diff --git a/third_party/blink/public/platform/platform.h b/third_party/blink/public/platform/platform.h index b2de9ae2..1bd8703 100644 --- a/third_party/blink/public/platform/platform.h +++ b/third_party/blink/public/platform/platform.h
@@ -99,6 +99,7 @@ class URLLoaderFactoryInterfaceBase; } class PendingSharedURLLoaderFactory; +class SharedURLLoaderFactory; } namespace url { @@ -263,6 +264,8 @@ virtual std::unique_ptr<WebURLLoaderFactory> WrapURLLoaderFactory( CrossVariantMojoRemote<network::mojom::URLLoaderFactoryInterfaceBase> url_loader_factory); + virtual std::unique_ptr<blink::WebURLLoaderFactory> WrapURLLoaderFactory( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory); // Returns the default User-Agent string, it can either full User-Agent string // or reduced User-Agent string based on policy setting.
diff --git a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc index 7d406160..0453c00 100644 --- a/third_party/blink/renderer/core/css/properties/computed_style_utils.cc +++ b/third_party/blink/renderer/core/css/properties/computed_style_utils.cc
@@ -2614,15 +2614,12 @@ } gfx::RectF reference_box = ReferenceBoxForTransform(*layout_object); - const auto* layout_box = layout_object->IsSVGChild() - ? nullptr - : DynamicTo<LayoutBox>(*layout_object); + gfx::Transform transform; - style.ApplyTransform(transform, layout_box, reference_box, - ComputedStyle::kIncludeTransformOperations, - ComputedStyle::kExcludeTransformOrigin, - ComputedStyle::kExcludeMotionPath, - ComputedStyle::kExcludeIndependentTransformProperties); + style.ApplyTransform( + transform, reference_box, ComputedStyle::kIncludeTransformOperations, + ComputedStyle::kExcludeTransformOrigin, ComputedStyle::kExcludeMotionPath, + ComputedStyle::kExcludeIndependentTransformProperties); // FIXME: Need to print out individual functions // (https://bugs.webkit.org/show_bug.cgi?id=23924)
diff --git a/third_party/blink/renderer/core/dom/node.cc b/third_party/blink/renderer/core/dom/node.cc index 98731f742..e4a87eb 100644 --- a/third_party/blink/renderer/core/dom/node.cc +++ b/third_party/blink/renderer/core/dom/node.cc
@@ -1042,11 +1042,6 @@ // We don't set computed style for text nodes. DCHECK(IsElementNode()); - if (auto* element = DynamicTo<Element>(this)) { - ViewTransitionSupplement::From(GetDocument()) - ->UpdateViewTransitionNames(*element, computed_style.get()); - } - // Already pointing to a non empty NodeData so just set the pointer // to the new LayoutObject. if (!data_->IsSharedEmptyData()) {
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc index 4d0e11d..2fb8f9bc 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc +++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.cc
@@ -242,6 +242,10 @@ button_part_->addEventListener(event_type_names::kKeydown, button_part_listener_, /*use_capture=*/false); + selected_value_slot_ = MakeGarbageCollected<HTMLSlotElement>(document); + selected_value_slot_->setAttribute(html_names::kNameAttr, + kSelectedValuePartName); + selected_value_part_ = MakeGarbageCollected<HTMLDivElement>(document); selected_value_part_->setAttribute(html_names::kPartAttr, kSelectedValuePartName); @@ -269,9 +273,11 @@ auto* options_slot = MakeGarbageCollected<HTMLSlotElement>(document); - button_part_->AppendChild(selected_value_part_); + button_part_->AppendChild(selected_value_slot_); button_part_->AppendChild(marker_slot_); + selected_value_slot_->AppendChild(selected_value_part_); + marker_slot_->AppendChild(marker_icon); button_slot_->AppendChild(button_part_); @@ -1048,6 +1054,7 @@ visitor->Trace(button_slot_); visitor->Trace(listbox_slot_); visitor->Trace(marker_slot_); + visitor->Trace(selected_value_slot_); visitor->Trace(selected_option_); visitor->Trace(selected_option_when_listbox_opened_); HTMLFormControlElementWithState::Trace(visitor);
diff --git a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h index 7b873e2..39fc3a2b 100644 --- a/third_party/blink/renderer/core/html/forms/html_select_menu_element.h +++ b/third_party/blink/renderer/core/html/forms/html_select_menu_element.h
@@ -173,6 +173,7 @@ Member<HTMLSlotElement> button_slot_; Member<HTMLSlotElement> listbox_slot_; Member<HTMLSlotElement> marker_slot_; + Member<HTMLSlotElement> selected_value_slot_; Member<HTMLOptionElement> selected_option_; Member<HTMLOptionElement> selected_option_when_listbox_opened_; bool queued_check_for_missing_parts_{false};
diff --git a/third_party/blink/renderer/core/layout/svg/transform_helper.cc b/third_party/blink/renderer/core/layout/svg/transform_helper.cc index d016bb1..54fed35 100644 --- a/third_party/blink/renderer/core/layout/svg/transform_helper.cc +++ b/third_party/blink/renderer/core/layout/svg/transform_helper.cc
@@ -80,11 +80,10 @@ // https://svgwg.org/svg2-draft/coords.html#ObjectBoundingBoxUnits gfx::Transform transform; gfx::RectF reference_box = ComputeReferenceBox(layout_object); - style.ApplyTransform(transform, nullptr, reference_box, - ComputedStyle::kIncludeTransformOperations, - apply_transform_origin, - ComputedStyle::kIncludeMotionPath, - ComputedStyle::kIncludeIndependentTransformProperties); + style.ApplyTransform( + transform, reference_box, ComputedStyle::kIncludeTransformOperations, + apply_transform_origin, ComputedStyle::kIncludeMotionPath, + ComputedStyle::kIncludeIndependentTransformProperties); const float zoom = style.EffectiveZoom(); if (zoom != 1) transform.Zoom(1 / zoom);
diff --git a/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc b/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc index c0e817f..41bb077 100644 --- a/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc +++ b/third_party/blink/renderer/core/loader/loader_factory_for_frame.cc
@@ -109,15 +109,17 @@ mojo::PendingRemote<mojom::blink::KeepAliveHandle> pending_remote; mojo::PendingReceiver<mojom::blink::KeepAliveHandle> pending_receiver = pending_remote.InitWithNewPipeAndPassReceiver(); - auto loader = - document_loader_->GetServiceWorkerNetworkProvider()->CreateURLLoader( - webreq, CreateTaskRunnerHandle(freezable_task_runner), - CreateTaskRunnerHandle(unfreezable_task_runner), - std::move(pending_remote), back_forward_cache_loader_helper); - if (loader) { + auto loader_factory = document_loader_->GetServiceWorkerNetworkProvider() + ->GetSubresourceLoaderFactory(webreq); + if (loader_factory) { IssueKeepAliveHandleIfRequested(request, frame->GetLocalFrameHostRemote(), std::move(pending_receiver)); - return loader; + return Platform::Current() + ->WrapURLLoaderFactory(std::move(loader_factory)) + ->CreateURLLoader( + webreq, CreateTaskRunnerHandle(freezable_task_runner), + CreateTaskRunnerHandle(unfreezable_task_runner), + std::move(pending_remote), back_forward_cache_loader_helper); } }
diff --git a/third_party/blink/renderer/core/loader/resource/image_resource_test.cc b/third_party/blink/renderer/core/loader/resource/image_resource_test.cc index 5c073ca..97e02a5 100644 --- a/third_party/blink/renderer/core/loader/resource/image_resource_test.cc +++ b/third_party/blink/renderer/core/loader/resource/image_resource_test.cc
@@ -461,9 +461,7 @@ image_resource->ResponseReceived(resource_response); image_resource->AppendData(reinterpret_cast<const char*>(kJpegImage), sizeof(kJpegImage)); - EXPECT_NE(0u, image_resource->EncodedSizeMemoryUsageForTesting()); image_resource->FinishForTest(); - EXPECT_EQ(0u, image_resource->EncodedSizeMemoryUsageForTesting()); EXPECT_FALSE(image_resource->ErrorOccurred()); ASSERT_TRUE(image_resource->GetContent()->HasImage()); EXPECT_FALSE(image_resource->GetContent()->GetImage()->IsNull());
diff --git a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc index 03b634c1..b0dcdff9 100644 --- a/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc +++ b/third_party/blink/renderer/core/paint/compositing/compositing_reason_finder.cc
@@ -108,7 +108,7 @@ // is probably good enough for a use counter. auto& box = To<LayoutBox>(layout_object); gfx::Transform matrix; - style.ApplyTransform(matrix, &box, box.Size(), + style.ApplyTransform(matrix, box.Size(), ComputedStyle::kIncludeTransformOperations, ComputedStyle::kExcludeTransformOrigin, ComputedStyle::kExcludeMotionPath,
diff --git a/third_party/blink/renderer/core/paint/paint_layer.cc b/third_party/blink/renderer/core/paint/paint_layer.cc index 6fbccc2..e76c2cfd 100644 --- a/third_party/blink/renderer/core/paint/paint_layer.cc +++ b/third_party/blink/renderer/core/paint/paint_layer.cc
@@ -331,8 +331,7 @@ DCHECK(box); transform->MakeIdentity(); box->StyleRef().ApplyTransform( - *transform, box, box->Size(), - ComputedStyle::kIncludeTransformOperations, + *transform, box->Size(), ComputedStyle::kIncludeTransformOperations, ComputedStyle::kIncludeTransformOrigin, ComputedStyle::kIncludeMotionPath, ComputedStyle::kIncludeIndependentTransformProperties); @@ -2105,8 +2104,17 @@ PhysicalRect result = LocalBoundingBox(); ExpandRectForSelfPaintingDescendants(result); gfx::RectF reference_box(result); - if (!ResourceInfo() || ResourceInfo()->FilterReferenceBox() != reference_box) - GetLayoutObject().SetNeedsPaintPropertyUpdate(); + if (!ResourceInfo() || + ResourceInfo()->FilterReferenceBox() != reference_box) { + if (GetLayoutObject().GetDocument().Lifecycle().GetState() == + DocumentLifecycle::kInPrePaint) { + GetLayoutObject() + .GetMutableForPainting() + .SetOnlyThisNeedsPaintPropertyUpdate(); + } else { + GetLayoutObject().SetNeedsPaintPropertyUpdate(); + } + } EnsureResourceInfo().SetFilterReferenceBox(reference_box); }
diff --git a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc index 9707f30..a1b7e4ff 100644 --- a/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc +++ b/third_party/blink/renderer/core/paint/paint_property_tree_builder.cc
@@ -250,7 +250,7 @@ void UpdateIndividualTransform( bool (*needs_property)(const LayoutObject&, CompositingReasons), - void (*compute_matrix)(const LayoutBox* box, + void (*compute_matrix)(const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix), CompositingReasons compositing_reasons_for_property, @@ -1082,11 +1082,11 @@ static TransformPaintPropertyNode::TransformAndOrigin TransformAndOriginState( const LayoutBox& box, const PhysicalSize& size, - void (*compute_matrix)(const LayoutBox* box, + void (*compute_matrix)(const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix)) { gfx::Transform matrix; - compute_matrix(&box, size, matrix); + compute_matrix(box.StyleRef(), size, matrix); return {matrix, GetTransformOrigin(box, size)}; } @@ -1099,7 +1099,7 @@ void FragmentPaintPropertyTreeBuilder::UpdateIndividualTransform( bool (*needs_property)(const LayoutObject&, CompositingReasons), - void (*compute_matrix)(const LayoutBox* box, + void (*compute_matrix)(const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix), CompositingReasons compositing_reasons_for_property, @@ -1222,9 +1222,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateTranslate() { UpdateIndividualTransform( &NeedsTranslate, - [](const LayoutBox* box, const PhysicalSize& size, + [](const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix) { - const auto& style = box->StyleRef(); if (style.Translate()) style.Translate()->Apply(matrix, gfx::SizeF(size)); }, @@ -1239,9 +1238,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateRotate() { UpdateIndividualTransform( &NeedsRotate, - [](const LayoutBox* box, const PhysicalSize& size, + [](const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix) { - const auto& style = box->StyleRef(); if (style.Rotate()) style.Rotate()->Apply(matrix, gfx::SizeF(size)); }, @@ -1255,9 +1253,8 @@ void FragmentPaintPropertyTreeBuilder::UpdateScale() { UpdateIndividualTransform( &NeedsScale, - [](const LayoutBox* box, const PhysicalSize& size, + [](const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix) { - const auto& style = box->StyleRef(); if (style.Scale()) style.Scale()->Apply(matrix, gfx::SizeF(size)); }, @@ -1271,11 +1268,10 @@ void FragmentPaintPropertyTreeBuilder::UpdateOffset() { UpdateIndividualTransform( &NeedsOffset, - [](const LayoutBox* box, const PhysicalSize& size, + [](const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix) { - const auto& style = box->StyleRef(); style.ApplyTransform( - matrix, box, size.ToLayoutSize(), + matrix, size.ToLayoutSize(), ComputedStyle::kExcludeTransformOperations, ComputedStyle::kExcludeTransformOrigin, ComputedStyle::kIncludeMotionPath, @@ -1293,11 +1289,10 @@ void FragmentPaintPropertyTreeBuilder::UpdateTransform() { UpdateIndividualTransform( &NeedsTransform, - [](const LayoutBox* box, const PhysicalSize& size, + [](const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix) { - const auto& style = box->StyleRef(); style.ApplyTransform( - matrix, box, size.ToLayoutSize(), + matrix, size.ToLayoutSize(), ComputedStyle::kIncludeTransformOperations, ComputedStyle::kExcludeTransformOrigin, ComputedStyle::kExcludeMotionPath, @@ -4235,11 +4230,10 @@ auto* transform = properties->Transform(); auto transform_and_origin = TransformAndOriginState( box, size, - [](const LayoutBox* box, const PhysicalSize& size, + [](const ComputedStyle& style, const PhysicalSize& size, gfx::Transform& matrix) { - const auto& style = box->StyleRef(); style.ApplyTransform( - matrix, box, size.ToLayoutSize(), + matrix, size.ToLayoutSize(), ComputedStyle::kIncludeTransformOperations, ComputedStyle::kExcludeTransformOrigin, ComputedStyle::kExcludeMotionPath,
diff --git a/third_party/blink/renderer/core/style/computed_style.cc b/third_party/blink/renderer/core/style/computed_style.cc index 4a27d2e..4f410dd 100644 --- a/third_party/blink/renderer/core/style/computed_style.cc +++ b/third_party/blink/renderer/core/style/computed_style.cc
@@ -51,7 +51,6 @@ #include "third_party/blink/renderer/core/html/html_body_element.h" #include "third_party/blink/renderer/core/html/html_html_element.h" #include "third_party/blink/renderer/core/html/html_progress_element.h" -#include "third_party/blink/renderer/core/layout/layout_box.h" #include "third_party/blink/renderer/core/layout/layout_theme.h" #include "third_party/blink/renderer/core/layout/ng/custom/layout_worklet.h" #include "third_party/blink/renderer/core/layout/text_autosizer.h" @@ -1341,21 +1340,19 @@ void ComputedStyle::ApplyTransform( gfx::Transform& result, - const LayoutBox* box, const LayoutSize& border_box_size, ApplyTransformOperations apply_operations, ApplyTransformOrigin apply_origin, ApplyMotionPath apply_motion_path, ApplyIndependentTransformProperties apply_independent_transform_properties) const { - ApplyTransform(result, box, gfx::RectF(gfx::SizeF(border_box_size)), + ApplyTransform(result, gfx::RectF(gfx::SizeF(border_box_size)), apply_operations, apply_origin, apply_motion_path, apply_independent_transform_properties); } void ComputedStyle::ApplyTransform( gfx::Transform& result, - const LayoutBox* box, const gfx::RectF& bounding_box, ApplyTransformOperations apply_operations, ApplyTransformOrigin apply_origin, @@ -1403,7 +1400,7 @@ } if (apply_motion_path == kIncludeMotionPath) { - ApplyMotionPathTransform(origin_x, origin_y, box, bounding_box, result); + ApplyMotionPathTransform(origin_x, origin_y, bounding_box, result); } if (apply_operations == kIncludeTransformOperations) { @@ -1421,111 +1418,56 @@ return FilterInternal().Get() && !FilterInternal()->operations_.IsEmpty(); } -static const LayoutBox* GetContainingBox(const LayoutBox* box, - const EPosition& position) { - if (!box) { - return nullptr; - } - if (position == EPosition::kStatic || position == EPosition::kRelative) { - return box->ParentBox(); - } - if (position == EPosition::kSticky) { - return box->ContainingScrollContainer(); - } - LayoutObject* container = nullptr; - if (position == EPosition::kAbsolute) { - container = box->ContainerForAbsolutePosition(); - } - if (position == EPosition::kFixed) { - container = box->ContainerForFixedPosition(); - } - if (container) { - return container->EnclosingBox(); - } - return nullptr; -} - -static gfx::SizeF GetContainingBoxSize(const LayoutBox* box, - const EPosition& position, - const gfx::RectF& bounding_box) { - const auto* containing_box = GetContainingBox(box, position); - if (containing_box) { - // FIXME(sakhapov): return based <coord-box> once the spec is clarified. - return gfx::SizeF(containing_box->ContentSize()); - } - return bounding_box.size(); -} - -static gfx::PointF GetOffsetFromContainingBox(const LayoutBox* box) { - if (box && box->ParentBox()) { - if (Element* element = DynamicTo<Element>(box->ParentBox()->GetNode())) { - const auto& offset = box->OffsetPoint(element); - return {offset.left, offset.top}; - } - } - return {0, 0}; -} - -static gfx::PointF GetInitialPositionForMotionPath( - const LayoutBox* box, - const LengthPoint& offset_position, - const gfx::SizeF& containing_box_size) { - if (offset_position.X().IsAuto()) { - return GetOffsetFromContainingBox(box); - } - return PointForLengthPoint(offset_position, containing_box_size); -} - -PointAndTangent ComputedStyle::CalculatePointAndTangentOnRay( - const LayoutBox* box, - const gfx::RectF& bounding_box, - const gfx::PointF& anchor_point) const { - const auto& ray = To<StyleRay>(*OffsetPath()); - const gfx::SizeF containing_box_size = - GetContainingBoxSize(box, PositionInternal(), bounding_box); - const gfx::PointF initial_position = GetInitialPositionForMotionPath( - box, OffsetPosition(), containing_box_size); - const float path_length = - ray.CalculateLength(anchor_point, OffsetDistance(), OffsetRotate(), - initial_position, bounding_box, containing_box_size); - return ray.PointAndNormalAtLength(path_length); -} - -PointAndTangent ComputedStyle::CalculatePointAndTangentOnPath() const { - float zoom = EffectiveZoom(); - const StylePath& path = To<StylePath>(*OffsetPath()); - float path_length = path.length(); - float float_distance = - FloatValueForLength(OffsetDistance(), path_length * zoom) / zoom; - float computed_distance; - if (path.IsClosed() && path_length > 0) { - computed_distance = fmod(float_distance, path_length); - if (computed_distance < 0) { - computed_distance += path_length; - } - } else { - computed_distance = ClampTo<float>(float_distance, 0, path_length); - } - PointAndTangent path_position = - path.GetPath().PointAndNormalAtLength(computed_distance); - path_position.point.Scale(zoom, zoom); - return path_position; -} - void ComputedStyle::ApplyMotionPathTransform(float origin_x, float origin_y, - const LayoutBox* box, const gfx::RectF& bounding_box, gfx::Transform& transform) const { // TODO(ericwilligers): crbug.com/638055 Apply offset-position. - const BasicShape* path = OffsetPath(); - if (!path) { + if (!OffsetPath()) { return; } const LengthPoint& position = OffsetPosition(); const LengthPoint& anchor = OffsetAnchor(); + const Length& distance = OffsetDistance(); + const BasicShape* path = OffsetPath(); const StyleOffsetRotation& rotate = OffsetRotate(); + PointAndTangent path_position; + if (path->GetType() == BasicShape::kStyleRayType) { + // TODO(ericwilligers): crbug.com/641245 Support <size> for ray paths. + float float_distance = FloatValueForLength(distance, 0); + + // Use ClampTo() to convert infinite values to min/max finite ones. + path_position.tangent_in_degrees = + ClampTo<float, float>(To<StyleRay>(*path).Angle() - 90); + float tangent_in_radians = Deg2rad(path_position.tangent_in_degrees); + path_position.point.set_x(float_distance * cos(tangent_in_radians)); + path_position.point.set_y(float_distance * sin(tangent_in_radians)); + } else { + float zoom = EffectiveZoom(); + const StylePath& motion_path = To<StylePath>(*path); + float path_length = motion_path.length(); + float float_distance = + FloatValueForLength(distance, path_length * zoom) / zoom; + float computed_distance; + if (motion_path.IsClosed() && path_length > 0) { + computed_distance = fmod(float_distance, path_length); + if (computed_distance < 0) { + computed_distance += path_length; + } + } else { + computed_distance = ClampTo<float>(float_distance, 0, path_length); + } + + path_position = + motion_path.GetPath().PointAndNormalAtLength(computed_distance); + path_position.point.Scale(zoom, zoom); + } + + if (rotate.type == OffsetRotationType::kFixed) { + path_position.tangent_in_degrees = 0; + } + float origin_shift_x = 0; float origin_shift_y = 0; // If the offset-position and offset-anchor properties are not yet enabled, @@ -1540,18 +1482,6 @@ origin_shift_y = anchor_point.y() - origin_y; } - PointAndTangent path_position; - if (path->GetType() == BasicShape::kStyleRayType) { - path_position = - CalculatePointAndTangentOnRay(box, bounding_box, anchor_point); - } else { - path_position = CalculatePointAndTangentOnPath(); - } - - if (rotate.type == OffsetRotationType::kFixed) { - path_position.tangent_in_degrees = 0; - } - transform.Translate( path_position.point.x() - anchor_point.x() + origin_shift_x, path_position.point.y() - anchor_point.y() + origin_shift_y);
diff --git a/third_party/blink/renderer/core/style/computed_style.h b/third_party/blink/renderer/core/style/computed_style.h index 9944a16..f140b973 100644 --- a/third_party/blink/renderer/core/style/computed_style.h +++ b/third_party/blink/renderer/core/style/computed_style.h
@@ -63,7 +63,6 @@ #include "third_party/blink/renderer/platform/geometry/length_point.h" #include "third_party/blink/renderer/platform/geometry/length_size.h" #include "third_party/blink/renderer/platform/graphics/color.h" -#include "third_party/blink/renderer/platform/graphics/path.h" #include "third_party/blink/renderer/platform/graphics/touch_action.h" #include "third_party/blink/renderer/platform/runtime_enabled_features.h" #include "third_party/blink/renderer/platform/text/text_direction.h" @@ -2035,14 +2034,12 @@ kExcludeTransformOperations }; void ApplyTransform(gfx::Transform&, - const LayoutBox* box, const LayoutSize& border_box_data_size, ApplyTransformOperations, ApplyTransformOrigin, ApplyMotionPath, ApplyIndependentTransformProperties) const; void ApplyTransform(gfx::Transform&, - const LayoutBox* box, const gfx::RectF& bounding_box, ApplyTransformOperations, ApplyTransformOrigin, @@ -2528,14 +2525,8 @@ void ApplyMotionPathTransform(float origin_x, float origin_y, - const LayoutBox* box, const gfx::RectF& bounding_box, gfx::Transform&) const; - PointAndTangent CalculatePointAndTangentOnRay( - const LayoutBox* box, - const gfx::RectF& bounding_box, - const gfx::PointF& anchor_point) const; - PointAndTangent CalculatePointAndTangentOnPath() const; bool ScrollAnchorDisablingPropertyChanged(const ComputedStyle& other, const StyleDifference&) const; @@ -3440,8 +3431,6 @@ void AddAppliedTextDecoration(const AppliedTextDecoration&); void OverrideTextDecorationColors(blink::Color propagated_color); - ComputedStyleBuilder() = default; - scoped_refptr<ComputedStyle> style_; };
diff --git a/third_party/blink/renderer/core/style/style_ray.cc b/third_party/blink/renderer/core/style/style_ray.cc index cc6f664..f8f6b2e 100644 --- a/third_party/blink/renderer/core/style/style_ray.cc +++ b/third_party/blink/renderer/core/style/style_ray.cc
@@ -3,12 +3,6 @@ // found in the LICENSE file. #include "third_party/blink/renderer/core/style/style_ray.h" -#include "third_party/blink/renderer/core/style/style_offset_rotation.h" -#include "third_party/blink/renderer/platform/geometry/length_functions.h" -#include "third_party/blink/renderer/platform/graphics/path.h" -#include "ui/gfx/geometry/point_f.h" -#include "ui/gfx/geometry/rect_f.h" -#include "ui/gfx/geometry/size_f.h" #include "base/notreached.h" @@ -35,197 +29,4 @@ NOTREACHED(); } -static float CalculatePerpendicularDistanceToBoundingBoxSide( - const gfx::PointF& point, - const gfx::SizeF& box_size, - float (*comp)(std::initializer_list<float>)) { - return comp({std::abs(point.x()), std::abs(point.x() - box_size.width()), - std::abs(point.y()), std::abs(point.y() - box_size.height())}); -} - -static float CalculateDistance(const gfx::PointF& a, const gfx::PointF& b) { - return (a - b).Length(); -} - -float CalculateDistanceToBoundingBoxCorner( - const gfx::PointF& point, - const gfx::SizeF& box_size, - float (*comp)(std::initializer_list<float>)) { - return comp({CalculateDistance(point, {0, 0}), - CalculateDistance(point, {box_size.width(), 0}), - CalculateDistance(point, {box_size.width(), box_size.height()}), - CalculateDistance(point, {0, box_size.height()})}); -} - -static float CalculateDistanceToBoundingBoxSide(const gfx::PointF& point, - const float angle, - const gfx::SizeF& box_size) { - if (!gfx::RectF(box_size).InclusiveContains(point)) { - return 0; - } - const float theta = Deg2rad(angle); - float cos_t = cos(theta); - float sin_t = sin(theta); - // We are looking for % point, let's swap signs and lines - // so that we end up in situation like this: - // (0, 0) #--------------%--# (box.width, 0) - // | | / | - // | v / | - // | | / | - // | |t/ | - // | |/ | - // (point) *---h----* (box.width, point.y) - // | | | - // | | | - // (0, box.height)#-----------------# (box.width, box.height) - - // cos_t and sin_t swapped due to the 0 angle is pointing up. - const float vertical = cos_t >= 0 ? point.y() : box_size.height() - point.y(); - const float horizontal = - sin_t >= 0 ? box_size.width() - point.x() : point.x(); - cos_t = abs(cos_t); - sin_t = abs(sin_t); - // Check what side we hit. - if (vertical * sin_t > horizontal * cos_t) { - return horizontal / sin_t; - } - return vertical / cos_t; -} - -float StyleRay::CalculateRayPathLength( - const gfx::PointF& initial_position, - const gfx::SizeF& containing_box_size) const { - switch (Size()) { - case StyleRay::RaySize::kClosestSide: - return CalculatePerpendicularDistanceToBoundingBoxSide( - initial_position, containing_box_size, std::min); - case StyleRay::RaySize::kFarthestSide: - return CalculatePerpendicularDistanceToBoundingBoxSide( - initial_position, containing_box_size, std::max); - case StyleRay::RaySize::kClosestCorner: - return CalculateDistanceToBoundingBoxCorner( - initial_position, containing_box_size, std::min); - case StyleRay::RaySize::kFarthestCorner: - return CalculateDistanceToBoundingBoxCorner( - initial_position, containing_box_size, std::max); - case StyleRay::RaySize::kSides: - return CalculateDistanceToBoundingBoxSide(initial_position, Angle(), - containing_box_size); - } -} - -static void RotateVertices(std::array<gfx::PointF, 4>& vertices, - const float ray_angle, - const StyleOffsetRotation& rotate) { - // https://drafts.fxtf.org/motion/#offset-rotate-property - // For ray paths, the rotation implied by auto is 90 degrees less - // than the ray’s bearing <angle>. - float angle = rotate.angle; - // NOTE: rotation type 'reverse' is handled during parsing and translated to - // auto, 180deg. - if (rotate.type == OffsetRotationType::kAuto) { - angle += ray_angle - 90; - } - // Rotate ray to x-axis + rotate object by its rotate angle. - const float angle_to_x_axis = Deg2rad(angle + 90 - ray_angle); - const float cos_t = cos(angle_to_x_axis); - const float sin_t = sin(angle_to_x_axis); - for (auto& v : vertices) { - const float vx = v.x(); - const float vy = v.y(); - v.set_x(cos_t * vx - sin_t * vy); - v.set_y(cos_t * vy + sin_t * vx); - } -} - -float StyleRay::CalculateLength(const gfx::PointF& anchor, - const Length& offset_distance, - const StyleOffsetRotation& offset_rotate, - const gfx::PointF& initial_position, - const gfx::RectF& bounding_box, - const gfx::SizeF& containing_box_size) const { - const float ray_length = - CalculateRayPathLength(initial_position, containing_box_size); - float float_length = FloatValueForLength(offset_distance, ray_length); - if (!Contain()) { - return float_length; - } - const float width = bounding_box.width(); - const float height = bounding_box.height(); - std::array<gfx::PointF, 4> vertices{{ - {-anchor.x(), -anchor.y()}, - {width - anchor.x(), -anchor.y()}, - {width - anchor.x(), height - anchor.y()}, - {-anchor.x(), height - anchor.y()}, - }}; - // Rotate ray to x axis; - RotateVertices(vertices, Angle(), offset_rotate); - float upper = std::numeric_limits<float>::max(); - float lower = std::numeric_limits<float>::lowest(); - bool should_increase = false; - // Find path intervals that enclose the box. - for (const auto& v : vertices) { - const float d = ray_length * ray_length - v.y() * v.y(); - if (d < 0) { - should_increase = true; - break; - } - const float sqrt_d = sqrt(d); - upper = std::min(upper, -v.x() + sqrt_d); - lower = std::max(lower, -v.x() - sqrt_d); - } - if (!should_increase) { - return std::max(lower, std::min(upper, float_length)); - } - - // Path length should be increased. - // We find the smallest path length such that an offset exists - // for all vertices to lie within the path. - const auto comp = [](const auto& a, const auto& b) { - return std::abs(a.y()) >= std::abs(b.y()); - }; - std::sort(vertices.begin(), vertices.end(), comp); - float radius = std::abs(vertices[0].y()); - float_length = -vertices[0].x(); - const float eps = 1e-5; - - // Find the path length such that, for some offset, - // vertices[i] and vertices[j] both lie within the path. - for (size_t i = 0; i < 3; ++i) { - for (size_t j = i + 1; j < 4; ++j) { - const float xi = vertices[i].x(); - const float yi = vertices[i].y(); - const float xj = vertices[j].x(); - const float yj = vertices[j].y(); - const float dx = xi - xj; - - // Any path that encloses vertices[i] would also enclose vertices[j]. - if (dx * dx + yj * yj <= yi * yi + eps) { - continue; - } - - // If both lie on the path, - // (offset + xi)**2 + yi**2 = (offset + xj)**2 + yj**2 = (path length)**2 - // 2 * xi * offset + xi**2 + yi**2 = 2 * xj * offset + xj**2 + yj**2 - const float new_length = - (xj * xj + yj * yj - xi * xi - yi * yi) / dx / 2.0; - const float x0 = xi + new_length; - const float new_radius = sqrt(x0 * x0 + yi * yi); - if (new_radius > radius) { - radius = new_radius; - float_length = new_length; - } - } - } - return float_length; -} - -PointAndTangent StyleRay::PointAndNormalAtLength(float length) const { - const float angle = Angle() - 90; - const float rad = Deg2rad(angle); - const float x = length * cos(rad); - const float y = length * sin(rad); - return {{x, y}, angle}; -} - } // namespace blink
diff --git a/third_party/blink/renderer/core/style/style_ray.h b/third_party/blink/renderer/core/style/style_ray.h index cc3d335..a1bf4ee 100644 --- a/third_party/blink/renderer/core/style/style_ray.h +++ b/third_party/blink/renderer/core/style/style_ray.h
@@ -6,16 +6,10 @@ #define THIRD_PARTY_BLINK_RENDERER_CORE_STYLE_STYLE_RAY_H_ #include "third_party/blink/renderer/core/style/basic_shapes.h" - -namespace gfx { -class PointF; -} +#include "third_party/blink/renderer/platform/wtf/casting.h" namespace blink { -struct PointAndTangent; -struct StyleOffsetRotation; - class StyleRay : public BasicShape { public: enum class RaySize { @@ -29,17 +23,7 @@ static scoped_refptr<StyleRay> Create(float angle, RaySize, bool contain); ~StyleRay() override = default; - float CalculateRayPathLength(const gfx::PointF& initial_position, - const gfx::SizeF& containing_box_size) const; - float CalculateLength(const gfx::PointF& anchor, - const Length& offset_distance, - const StyleOffsetRotation& offset_rotate, - const gfx::PointF& initial_position, - const gfx::RectF& bounding_box, - const gfx::SizeF& containing_box_size) const; - PointAndTangent PointAndNormalAtLength(float length) const; - - float Angle() const { return ClampTo<float, float>(angle_); } + float Angle() const { return angle_; } RaySize Size() const { return size_; } bool Contain() const { return contain_; }
diff --git a/third_party/blink/renderer/core/testing/internals.cc b/third_party/blink/renderer/core/testing/internals.cc index 2828818..2025225 100644 --- a/third_party/blink/renderer/core/testing/internals.cc +++ b/third_party/blink/renderer/core/testing/internals.cc
@@ -2272,6 +2272,9 @@ document->View()->UpdateAllLifecyclePhasesForTest(); auto* hit_test_rects = MakeGarbageCollected<HitTestLayerRectList>(); + if (!document->View()->RootCcLayer()) { + return hit_test_rects; + } for (const auto& layer : document->View()->RootCcLayer()->children()) { const cc::TouchActionRegion& touch_action_region = layer->touch_action_region();
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc index bf7c4bb..7406dad 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc +++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.cc
@@ -185,15 +185,6 @@ return transition_; } -void ViewTransitionSupplement::UpdateViewTransitionNames( - const Element& element, - const ComputedStyle* style) { - if (style && style->ViewTransitionName()) - elements_with_view_transition_name_.insert(&element); - else - elements_with_view_transition_name_.erase(&element); -} - ViewTransitionSupplement::ViewTransitionSupplement(Document& document) : Supplement<Document>(document) {} @@ -201,7 +192,6 @@ void ViewTransitionSupplement::Trace(Visitor* visitor) const { visitor->Trace(transition_); - visitor->Trace(elements_with_view_transition_name_); Supplement<Document>::Trace(visitor); }
diff --git a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h index 0068aee..53d97661 100644 --- a/third_party/blink/renderer/core/view_transition/view_transition_supplement.h +++ b/third_party/blink/renderer/core/view_transition/view_transition_supplement.h
@@ -51,14 +51,6 @@ ViewTransition* GetActiveTransition(); - // Tracks the set of elements with a valid |view-transition-name|. - void UpdateViewTransitionNames(const Element& element, - const ComputedStyle* style); - const HeapHashSet<Member<const Element>>& ElementsWithViewTransitionName() - const { - return elements_with_view_transition_name_; - } - explicit ViewTransitionSupplement(Document&); ~ViewTransitionSupplement() override; @@ -92,8 +84,6 @@ VectorOf<std::unique_ptr<ViewTransitionRequest>> pending_requests_; - HeapHashSet<Member<const Element>> elements_with_view_transition_name_; - mojom::ViewTransitionSameOriginOptIn same_origin_opt_in_ = mojom::ViewTransitionSameOriginOptIn::kDisabled; };
diff --git a/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc b/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc index 5547a7f..4b9eb5f5 100644 --- a/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc +++ b/third_party/blink/renderer/modules/webcodecs/audio_encoder.cc
@@ -281,6 +281,18 @@ {44100, 48000})) { return false; } +#if BUILDFLAG(IS_MAC) + if (config->options.aac.has_value() && + config->options.aac->format == + media::AudioEncoder::AacOutputFormat::ADTS) { + if (exception_state) { + exception_state->ThrowDOMException( + DOMExceptionCode::kNotSupportedError, + "ADTS is not supported on Mac yet"); + } + return false; + } +#endif // BUILDFLAG(IS_MAC) return true; }
diff --git a/third_party/blink/renderer/platform/exported/platform.cc b/third_party/blink/renderer/platform/exported/platform.cc index c8d72af..4af008c 100644 --- a/third_party/blink/renderer/platform/exported/platform.cc +++ b/third_party/blink/renderer/platform/exported/platform.cc
@@ -305,6 +305,11 @@ return nullptr; } +std::unique_ptr<WebURLLoaderFactory> Platform::WrapURLLoaderFactory( + scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory) { + return nullptr; +} + std::unique_ptr<WebDedicatedWorkerHostFactoryClient> Platform::CreateDedicatedWorkerHostFactoryClient( WebDedicatedWorker*,
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.cc b/third_party/blink/renderer/platform/loader/fetch/resource.cc index 286dbba6..b72f0f5 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.cc +++ b/third_party/blink/renderer/platform/loader/fetch/resource.cc
@@ -144,7 +144,6 @@ : type_(type), status_(ResourceStatus::kNotStarted), encoded_size_(0), - encoded_size_memory_usage_(0), decoded_size_(0), cache_identifier_(MemoryCache::DefaultCacheIdentifier()), link_preload_(false), @@ -278,7 +277,6 @@ void Resource::ClearData() { data_ = nullptr; - encoded_size_memory_usage_ = 0; } void Resource::TriggerNotificationForFinishObservers( @@ -684,12 +682,11 @@ } void Resource::SetEncodedSize(size_t encoded_size) { - if (encoded_size == encoded_size_ && - encoded_size == encoded_size_memory_usage_) + if (encoded_size == encoded_size_) { return; + } size_t old_size = size(); encoded_size_ = encoded_size; - encoded_size_memory_usage_ = encoded_size; if (IsMainThread()) MemoryCache::Get()->Update(this, old_size, size()); } @@ -852,11 +849,6 @@ const String dump_name = GetMemoryDumpName(); WebMemoryAllocatorDump* dump = memory_dump->CreateMemoryAllocatorDump(dump_name); - dump->AddScalar("encoded_size", "bytes", encoded_size_memory_usage_); - if (HasClientsOrObservers()) - dump->AddScalar("live_size", "bytes", encoded_size_memory_usage_); - else - dump->AddScalar("dead_size", "bytes", encoded_size_memory_usage_); if (data_) GetSharedBufferMemoryDump(Data(), dump_name, memory_dump);
diff --git a/third_party/blink/renderer/platform/loader/fetch/resource.h b/third_party/blink/renderer/platform/loader/fetch/resource.h index 5d99c79..eb7b8a5 100644 --- a/third_party/blink/renderer/platform/loader/fetch/resource.h +++ b/third_party/blink/renderer/platform/loader/fetch/resource.h
@@ -226,16 +226,6 @@ // need to be refactored (crbug/643135). size_t EncodedSize() const { return encoded_size_; } - // Returns the current memory usage for the encoded data. Adding a new usage - // of this function is not recommended as the same reason as |EncodedSize()|. - // - // |EncodedSize()| and |EncodedSizeMemoryUsageForTesting()| can return - // different values, e.g., when ImageResource purges encoded image data after - // finishing loading. - size_t EncodedSizeMemoryUsageForTesting() const { - return encoded_size_memory_usage_; - } - size_t DecodedSize() const { return decoded_size_; } size_t OverheadSize() const { return overhead_size_; } virtual size_t CodeCacheSize() const { return 0; } @@ -532,7 +522,6 @@ base::TimeTicks load_response_end_; size_t encoded_size_; - size_t encoded_size_memory_usage_; size_t decoded_size_; String cache_identifier_;
diff --git a/third_party/blink/web_tests/TestExpectations b/third_party/blink/web_tests/TestExpectations index be0ba1d3..f40bf9e 100644 --- a/third_party/blink/web_tests/TestExpectations +++ b/third_party/blink/web_tests/TestExpectations
@@ -2759,6 +2759,18 @@ crbug.com/798257 external/wpt/css/css-pseudo/first-line-line-height-002.html [ Failure ] # motion-1 issues +crbug.com/641245 external/wpt/css/motion/offset-path-ray-002.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-003.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-004.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-005.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-006.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-007.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-009.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-contain-001.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-contain-002.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-contain-003.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-contain-004.html [ Failure ] +crbug.com/641245 external/wpt/css/motion/offset-path-ray-contain-005.html [ Failure ] crbug.com/654669 external/wpt/css/motion/offset-path-shape.html [ Failure ] crbug.com/654666 external/wpt/css/motion/offset-path-url.html [ Failure ] @@ -6352,7 +6364,6 @@ crbug.com/1395840 [ Mac12 ] http/tests/accessibility/slow-document-load.html [ Failure ] crbug.com/1395840 [ Mac12-arm64 Release ] http/tests/accessibility/slow-document-load.html [ Failure ] crbug.com/1395840 [ Mac13-arm64 Release ] http/tests/accessibility/slow-document-load.html [ Failure ] -crbug.com/1404767 [ Debug Linux ] external/wpt/css/css-cascade/all-prop-revert-layer-noop.html [ Failure Timeout ] crbug.com/1406027 [ Win ] virtual/media-foundation-for-clear-dcomp/media/controls/overflow-menu-hide-on-resize.html [ Failure ] crbug.com/1289607 [ Linux ] external/wpt/cookie-store/cookieStore_subscribe_arguments.https.any.html [ Failure ] crbug.com/1408294 [ Debug Linux ] virtual/gpu/external/wpt/mediacapture-record/MediaRecorder-canvas-media-source.https.html [ Failure ]
diff --git a/third_party/blink/web_tests/VirtualTestSuites b/third_party/blink/web_tests/VirtualTestSuites index 1a5f490..49723825 100644 --- a/third_party/blink/web_tests/VirtualTestSuites +++ b/third_party/blink/web_tests/VirtualTestSuites
@@ -896,13 +896,6 @@ "expires": "Jul 1, 2023" }, { - "prefix": "top-level-storage-access-api", - "platforms": ["Linux", "Mac", "Win"], - "bases": [ "external/wpt/top-level-storage-access-api" ], - "args": [ "--enable-features=StorageAccessAPI,StorageAccessAPIForOriginExtension" ], - "expires": "Jul 1, 2023" - }, - { "prefix": "web-bluetooth-new-permissions-backend", "platforms": ["Linux", "Mac", "Win"], "bases": ["wpt_internal/bluetooth", "external/wpt/bluetooth"],
diff --git a/third_party/blink/web_tests/WebDriverExpectations b/third_party/blink/web_tests/WebDriverExpectations index 7662d2c..982b8f0 100644 --- a/third_party/blink/web_tests/WebDriverExpectations +++ b/third_party/blink/web_tests/WebDriverExpectations
@@ -641,3 +641,7 @@ crbug.com/1325690 [ Linux ] external/wpt/webdriver/tests/take_screenshot/user_prompts.py>>test_dismiss[capabilities0-prompt-None] [ Failure Pass ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_touch.py>>test_touch_pointer_properties [ Failure ] crbug.com/626703 [ Linux ] external/wpt/webdriver/tests/perform_actions/pointer_touch.py>>test_touch_pointer_properties_tilt_twist [ Failure ] +crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/forward/forward.py>>test_dismissed_beforeunload [ Failure ] +crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_dismissed_beforeunload [ Failure ] +crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_history_pushstate [ Failure ] +crbug.com/1414111 [ Linux ] external/wpt/webdriver/tests/refresh/refresh.py>>test_refresh_switches_to_parent_browsing_context [ Failure ]
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer-noop.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer-noop.html index 66aa2b9..5c31c58 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer-noop.html +++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-layer-noop.html
@@ -4,6 +4,18 @@ <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> <link rel="help" href="https://www.w3.org/TR/css-cascade-5/#revert-layer"> <meta name="assert" content="Checks that adding 'all: revert-layer' inside @layer has no effect on elements with no other author rules."> +<!-- Split into chunks to avoid timeouts. --> +<meta name="variant" content="?include=0"> +<meta name="variant" content="?include=1"> +<meta name="variant" content="?include=2"> +<meta name="variant" content="?include=3"> +<meta name="variant" content="?include=4"> +<meta name="variant" content="?include=5"> +<meta name="variant" content="?include=6"> +<meta name="variant" content="?include=7"> +<script> + const CHUNKS = 8; +</script> <style> @layer { @@ -16,6 +28,7 @@ <div id="log"></div> <div id="wrapper"></div> +<script src="/common/subset-tests-by-key.js"></script> <script src="/html/resources/common.js"></script> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -41,8 +54,10 @@ const wrapper = document.getElementById("wrapper"); const elementNames = [...HTML5_ELEMENTS, "math", "svg", "z-custom"].sort(); -for (let elementName of elementNames) { - test(function() { +for (let i = 0; i < elementNames.length; ++i) { + let elementName = elementNames[i]; + let chunk = i % CHUNKS; + subsetTestByKey(chunk.toString(), test, function() { const element = document.createElement(elementName); wrapper.appendChild(element); const style = getComputedStyle(element);
diff --git a/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-noop.html b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-noop.html index d70fa530..e8f560d 100644 --- a/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-noop.html +++ b/third_party/blink/web_tests/external/wpt/css/css-cascade/all-prop-revert-noop.html
@@ -4,7 +4,18 @@ <link rel="author" title="Oriol Brufau" href="mailto:obrufau@igalia.com"> <link rel="help" href="https://www.w3.org/TR/css-cascade-4/#default"> <meta name="assert" content="Checks that adding 'all: revert' has no effect on elements with no other author rules."> -<meta name="timeout" content="long"> +<!-- Split into chunks to avoid timeouts. --> +<meta name="variant" content="?include=0"> +<meta name="variant" content="?include=1"> +<meta name="variant" content="?include=2"> +<meta name="variant" content="?include=3"> +<meta name="variant" content="?include=4"> +<meta name="variant" content="?include=5"> +<meta name="variant" content="?include=6"> +<meta name="variant" content="?include=7"> +<script> + const CHUNKS = 8; +</script> <style> .revert-all { @@ -15,6 +26,7 @@ <div id="log"></div> <div id="wrapper"></div> +<script src="/common/subset-tests-by-key.js"></script> <script src="/html/resources/common.js"></script> <script src="/resources/testharness.js"></script> <script src="/resources/testharnessreport.js"></script> @@ -40,8 +52,10 @@ const wrapper = document.getElementById("wrapper"); const elementNames = [...HTML5_ELEMENTS, "math", "svg", "z-custom"].sort(); -for (let elementName of elementNames) { - test(function() { +for (let i = 0; i < elementNames.length; ++i) { + let elementName = elementNames[i]; + let chunk = i % CHUNKS; + subsetTestByKey(chunk.toString(), test, function() { const element = document.createElement(elementName); wrapper.appendChild(element); const style = getComputedStyle(element);
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-002.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-002.html.ini new file mode 100644 index 0000000..0dc1929 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-002.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-002.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-003.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-003.html.ini new file mode 100644 index 0000000..6e6b6c0 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-003.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-003.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-004.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-004.html.ini new file mode 100644 index 0000000..c5c4730 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-004.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-004.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-005.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-005.html.ini new file mode 100644 index 0000000..576f2b6 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-005.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-005.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-006.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-006.html.ini new file mode 100644 index 0000000..8cd4502 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-006.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-006.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-007.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-007.html.ini new file mode 100644 index 0000000..4b79075 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-007.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-007.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-009.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-009.html.ini new file mode 100644 index 0000000..91127da --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-009.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-009.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-001.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-001.html.ini new file mode 100644 index 0000000..f15f5cc --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-001.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-contain-001.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-002.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-002.html.ini new file mode 100644 index 0000000..0362210 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-002.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-contain-002.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-003.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-003.html.ini new file mode 100644 index 0000000..01290e50 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-003.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-contain-003.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-004-ref.html b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-004-ref.html index 2d62445..38b0d44 100644 --- a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-004-ref.html +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-004-ref.html
@@ -15,7 +15,7 @@ height: 100px; background-color: lime; /* The movement is about sqrt(150^2 - 50^2) - 50 */ - transform: rotate(-45deg) translate(91.4214px); + transform: rotate(-45deg) translate(91.42px); } </style> </head>
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-004.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-004.html.ini new file mode 100644 index 0000000..eca174c1 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-004.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-contain-004.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-005.html.ini b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-005.html.ini new file mode 100644 index 0000000..7fdbe8d --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/css/motion/offset-path-ray-contain-005.html.ini
@@ -0,0 +1,2 @@ +[offset-path-ray-contain-005.html] + expected: FAIL
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-behavior-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-behavior-ref.html new file mode 100644 index 0000000..bf468c5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-behavior-ref.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<script src="support/fake-selectmenu.js"></script> +<body> +<script> + const selectmenu = createFakeSelectmenu('hello world'); + document.body.appendChild(selectmenu); + selectmenu.querySelector('.fake-selectmenu-selected-value') + .style.color = 'blue'; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-behavior.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-behavior.tentative.html new file mode 100644 index 0000000..799b445 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-behavior.tentative.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=match href="selectmenu-selected-value-behavior-ref.html"> + +<selectmenu> + <div style="color:blue" slot=selected-value behavior=selected-value></div> + <option>hello world</option> +</selectmenu>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-part-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-part-ref.html new file mode 100644 index 0000000..744846b5 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-part-ref.html
@@ -0,0 +1,9 @@ +<!DOCTYPE html> +<script src="support/fake-selectmenu.js"></script> +<body> +<script> + const selectmenu = createFakeSelectmenu('hello world'); + document.body.appendChild(selectmenu); + selectmenu.querySelector('.fake-selectmenu-selected-value') + .style.backgroundColor = 'red'; +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-part.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-part.tentative.html new file mode 100644 index 0000000..e41d2dd --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-part.tentative.html
@@ -0,0 +1,12 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=match href="selectmenu-selected-value-part-ref.html"> + +<style> +selectmenu::part(selected-value) { + background-color: red; +} +</style> +<selectmenu> + <option>hello world</option> +</selectmenu>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-slot-ref.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-slot-ref.html new file mode 100644 index 0000000..1320583 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-slot-ref.html
@@ -0,0 +1,14 @@ +<!DOCTYPE html> +<script src="support/fake-selectmenu.js"></script> +<body> +<script> + const selectmenu = createFakeSelectmenu('hello world'); + document.body.appendChild(selectmenu); + + const oldSelectedValue = selectmenu.querySelector('.fake-selectmenu-selected-value'); + const newSelectedValue = document.createElement('div'); + newSelectedValue.textContent = 'new selected value'; + + const button = selectmenu.querySelector('.fake-selectmenu-internal-selectmenu-button'); + button.replaceChild(newSelectedValue, oldSelectedValue); +</script>
diff --git a/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-slot.tentative.html b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-slot.tentative.html new file mode 100644 index 0000000..9bbf2df --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/html/semantics/forms/the-selectmenu-element/selectmenu-selected-value-slot.tentative.html
@@ -0,0 +1,8 @@ +<!DOCTYPE html> +<link rel=author href="mailto:jarhar@chromium.org"> +<link rel=match href="selectmenu-selected-value-slot-ref.html"> + +<selectmenu> + <div slot=selected-value>new selected value</div> + <option>hello world</option> +</selectmenu>
diff --git a/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/set-metadata.https.html.ini b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/set-metadata.https.html.ini index d7ee1367..2c62b325 100644 --- a/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/set-metadata.https.html.ini +++ b/third_party/blink/web_tests/external/wpt/webrtc-encoded-transform/set-metadata.https.html.ini
@@ -1,3 +1,3 @@ [set-metadata.https.html] - [[VP8] setMetadata() carries over codec-specific properties] + [[VP8\] setMetadata() carries over codec-specific properties] expected: [PASS, FAIL] # Temporarily disable to allow WebRTC roll before required Chrome changes land in crrev.com/c/4224473
diff --git a/third_party/blink/web_tests/fast/events/touch/empty-iframe-touch-hit-rects-crash.html b/third_party/blink/web_tests/fast/events/touch/empty-iframe-touch-hit-rects-crash.html new file mode 100644 index 0000000..164ae26d --- /dev/null +++ b/third_party/blink/web_tests/fast/events/touch/empty-iframe-touch-hit-rects-crash.html
@@ -0,0 +1,10 @@ +<!DOCTYPE html> +<iframe src="#empty"></iframe> +<script src="../../../resources/testharness.js"></script> +<script src="../../../resources/testharnessreport.js"></script> +<script> +test(()=> { + if (window.internals) + internals.touchEventTargetLayerRects(document); +}); +</script>
diff --git a/third_party/blink/web_tests/virtual/top-level-storage-access-api/README.md b/third_party/blink/web_tests/virtual/top-level-storage-access-api/README.md deleted file mode 100644 index 68a1bd9..0000000 --- a/third_party/blink/web_tests/virtual/top-level-storage-access-api/README.md +++ /dev/null
@@ -1 +0,0 @@ -See third_party/blink/web_tests/external/wpt/top-level-storage-access-api/README.md
diff --git a/third_party/blink/web_tests/wpt_internal/css/css-multicol/box-reflect-quirk-crash.html b/third_party/blink/web_tests/wpt_internal/css/css-multicol/box-reflect-quirk-crash.html new file mode 100644 index 0000000..24e7b0d --- /dev/null +++ b/third_party/blink/web_tests/wpt_internal/css/css-multicol/box-reflect-quirk-crash.html
@@ -0,0 +1,32 @@ +<link rel="help" href="https://crbug.com/1403599"> +<style> +#foo { + -webkit-box-reflect: right 1px; + border-inline-start-style: dashed; + content: url(); + transition-duration: 6s; + height: 1; +} +</style> +<script> + function runTest(){ + document.elementFromPoint(0, 0); + + let node = foo.removeChild(bar); + target.appendChild(node); + + document.fgColor = "1"; + } +</script> +<body onload="runTest();")> + <div style="columns: 1px;"> + <span id="target"> + <ul style="float: left;"> + <div id="foo"> + <div id="bar"> + </div> + </div> + </ul> + </span> + </div> +</body>
diff --git a/third_party/freetype/README.chromium b/third_party/freetype/README.chromium index 742ea25..e8433170 100644 --- a/third_party/freetype/README.chromium +++ b/third_party/freetype/README.chromium
@@ -1,7 +1,7 @@ Name: FreeType URL: http://www.freetype.org/ -Version: VER-2-12-1-180-g27b2cd410 -Revision: 27b2cd4101dfcf7d03904204e078b2de84cce8c4 +Version: VER-2-12-1-181-g4c3916e90 +Revision: 4c3916e901ac88243321b7518c023dc8c51a7586 CPEPrefix: cpe:/a:freetype:freetype:2.12.1 License: Custom license "inspired by the BSD, Artistic, and IJG (Independent JPEG Group) licenses"
diff --git a/tools/gn/bootstrap/bootstrap.py b/tools/gn/bootstrap/bootstrap.py index 8baa4e4..09091499 100755 --- a/tools/gn/bootstrap/bootstrap.py +++ b/tools/gn/bootstrap/bootstrap.py
@@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright 2014 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file.
diff --git a/tools/grit/grit_rule.gni b/tools/grit/grit_rule.gni index a7e8485..8dd0cef 100644 --- a/tools/grit/grit_rule.gni +++ b/tools/grit/grit_rule.gni
@@ -94,7 +94,7 @@ import("//build/toolchain/gcc_toolchain.gni") import("//tools/grit/grit_args.gni") _strip_resource_files = is_android && is_official_build -_js_minifier = "//tools/grit/minify_with_uglify.py" +_js_minifier = "//tools/grit/minify_js.py" _css_minifier = "//tools/grit/minimize_css.py" grit_resource_id_target = "//tools/gritsettings:default_resource_ids"
diff --git a/tools/grit/minify_with_uglify.py b/tools/grit/minify_js.py similarity index 93% rename from tools/grit/minify_with_uglify.py rename to tools/grit/minify_js.py index 69d4e0f..cbf2fbac 100755 --- a/tools/grit/minify_with_uglify.py +++ b/tools/grit/minify_js.py
@@ -3,7 +3,6 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. - import os import sys import tempfile @@ -15,8 +14,9 @@ import node import node_modules + def Minify(source): - # Open two temporary files, so that uglify can read the input from one and + # Open two temporary files, so that terser can read the input from one and # write its output to the other. with tempfile.NamedTemporaryFile(mode="w+", suffix='.js') as infile, \ tempfile.NamedTemporaryFile(mode="r+", suffix='.js') as outfile:
diff --git a/tools/grit/minify_with_uglify_unittest.py b/tools/grit/minify_js_unittest.py similarity index 75% rename from tools/grit/minify_with_uglify_unittest.py rename to tools/grit/minify_js_unittest.py index 8bbf65f..4a34e0b 100755 --- a/tools/grit/minify_with_uglify_unittest.py +++ b/tools/grit/minify_js_unittest.py
@@ -5,7 +5,7 @@ import unittest -import minify_with_uglify +import minify_js class MinifyWithUglifyTest(unittest.TestCase): @@ -13,7 +13,7 @@ source = """ var foo = 0; """ - minimized = minify_with_uglify.Minify(source) + minimized = minify_js.Minify(source) self.assertEqual(minimized, "var foo=0;") def test_complex(self): @@ -25,6 +25,6 @@ }; var qux = foo.bar + foo.baz; """ - minimized = minify_with_uglify.Minify(source) + minimized = minify_js.Minify(source) self.assertEqual(minimized, - "var foo={bar:0,baz:5};var qux=foo.bar+foo.baz;") + "var foo={bar:0,baz:5};var qux=foo.bar+foo.baz;")
diff --git a/tools/gritsettings/resource_ids.spec b/tools/gritsettings/resource_ids.spec index 9b7d421..7e50c2b7 100644 --- a/tools/gritsettings/resource_ids.spec +++ b/tools/gritsettings/resource_ids.spec
@@ -162,7 +162,7 @@ "chrome/browser/resources/chromeos/app_icon/app_icon_resources.grd": { "structures": [1395], }, - "chrome/browser/resources/chromeos/login/oobe_conditional_resources.grd": { + "<(SHARED_INTERMEDIATE_DIR)/chrome/browser/resources/chromeos/login/oobe_conditional_resources.grd": { "META": {"sizes": {"includes": [150], "structures": [300]}}, "includes": [1400], "structures": [1420],
diff --git a/tools/mb/mb_config.pyl b/tools/mb/mb_config.pyl index e36403c..88ead4bf 100644 --- a/tools/mb/mb_config.pyl +++ b/tools/mb/mb_config.pyl
@@ -453,7 +453,7 @@ 'mac-upload-perfetto': 'release_bot_perfetto_zlib_reclient', 'mac10.15-wpt-content-shell-fyi-rel': 'release_trybot_minimal_symbols_reclient', 'mac11-wpt-content-shell-fyi-rel': 'release_trybot_minimal_symbols_reclient', - 'mac12-arm64-wpt-content-shell-fyi-rel': 'release_trybot_minimal_symbols_reclient', + 'mac12-arm64-wpt-content-shell-fyi-rel': 'mac_arm64_release_bot_reclient', 'mac12-wpt-content-shell-fyi-rel': 'release_trybot_minimal_symbols_reclient', 'win-annotator-rel': 'release_bot_reclient', 'win-backuprefptr-x64-fyi-rel': 'release_trybot_backuprefptr_x64_reclient',
diff --git a/tools/mb/mb_config_expectations/chromium.fyi.json b/tools/mb/mb_config_expectations/chromium.fyi.json index 18b2c3b..903e32b 100644 --- a/tools/mb/mb_config_expectations/chromium.fyi.json +++ b/tools/mb/mb_config_expectations/chromium.fyi.json
@@ -1068,10 +1068,10 @@ }, "mac12-arm64-wpt-content-shell-fyi-rel": { "gn_args": { - "dcheck_always_on": true, + "dcheck_always_on": false, "is_component_build": false, "is_debug": false, - "symbol_level": 1, + "target_cpu": "arm64", "use_remoteexec": true } },
diff --git a/tools/metrics/actions/actions.xml b/tools/metrics/actions/actions.xml index 7b42d05..ae2bead 100644 --- a/tools/metrics/actions/actions.xml +++ b/tools/metrics/actions/actions.xml
@@ -25493,7 +25493,7 @@ </action> <action name="Overscroll_Cancelled.Reload"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <description> When vertical overscroll corresponding to the RELOAD navigation is cancelled - either because the user performed an interfering action such as pressing a @@ -25517,7 +25517,7 @@ </action> <action name="Overscroll_Navigated.Reload"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <description> When vertical overscroll initiates a RELOAD navigation in the browser. </description>
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 4ddc1f7..304e323 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -9249,12 +9249,12 @@ <int value="14" label="Omnibox icon shown, but not bubble (max strikes)"/> </enum> -<enum name="AutofillSaveCreditCardPromptOfferEnum"> +<enum name="AutofillSavePaymentMethodPromptOfferEnum"> <int value="0" label="Shown"/> <int value="1" label="Not shown, max strikes reached"/> </enum> -<enum name="AutofillSaveCreditCardPromptResultEnum"> +<enum name="AutofillSavePaymentMethodPromptResultEnum"> <int value="0" label="Accepted"/> <int value="1" label="Cancelled"/> <int value="2" label="Closed"/> @@ -57977,6 +57977,7 @@ <int value="-2007377632" label="DiscoverFeedMultiColumn:enabled"/> <int value="-2006505465" label="AutofillRemoveCardExpirationAndTypeTitles:disabled"/> + <int value="-2005716090" label="ShareSheetMigrationAndroid:disabled"/> <int value="-2005089558" label="BackgroundVideoTrackOptimization:disabled"/> <int value="-2004882388" label="AutofillPruneSuggestions:enabled"/> <int value="-2004862295" label="FedCmUserInfo:disabled"/> @@ -60480,6 +60481,7 @@ <int value="-617452890" label="media-router"/> <int value="-616818899" label="SameSiteByDefaultCookies:enabled"/> <int value="-616508634" label="DisableCryptAuthV1DeviceSync:enabled"/> + <int value="-616414905" label="ThumbnailCacheRefactor:disabled"/> <int value="-615974325" label="ArcMouseWheelSmoothScroll:disabled"/> <int value="-615254902" label="SystemJapanesePhysicalTyping:enabled"/> <int value="-614223913" @@ -63652,6 +63654,7 @@ <int value="1220274247" label="AllowReaderForAccessibility:disabled"/> <int value="1220464509" label="enable-first-run-ui-transitions"/> <int value="1220655015" label="kScrollableTabStripOverflow:enabled"/> + <int value="1221104166" label="ThumbnailCacheRefactor:enabled"/> <int value="1221394044" label="SharingUseDeviceInfo:enabled"/> <int value="1221559505" label="enable-spelling-feedback-field-trial"/> <int value="1222017136" label="WebRtcUseEchoCanceller3:disabled"/> @@ -63734,6 +63737,7 @@ <int value="1266525177" label="AutofillUpstreamUseGooglePayOnAndroidBranding:disabled"/> <int value="1266886673" label="delay-reload-stop-button-change"/> + <int value="1267585140" label="ShareSheetMigrationAndroid:enabled"/> <int value="1268470658" label="disable-android-password-link"/> <int value="1268678442" label="KerberosSettingsSection:disabled"/> <int value="1269216922" label="MediaAppPhotosIntegrationVideo:enabled"/>
diff --git a/tools/metrics/histograms/extract_histograms.py b/tools/metrics/histograms/extract_histograms.py index ca8797e4..c3f3e48 100644 --- a/tools/metrics/histograms/extract_histograms.py +++ b/tools/metrics/histograms/extract_histograms.py
@@ -69,6 +69,8 @@ import re import xml.dom.minidom +import histogram_configuration_model + BASIC_EMAIL_REGEXP = r'^[\w\-\+\%\.]+\@[\w\-\+\%\.]+$' OWNER_PLACEHOLDER = ( @@ -375,6 +377,39 @@ return owners, has_owner +def _ExtractImprovementDirection(histogram_node): + """Extracts improvement direction from the given histogram element, if any. + + Args: + histogram_node: A DOM Element corresponding to a histogram. + + Returns: + A tuple, where the first element is the improvement direction, if any; + the second element is an error message if the given direction is invalid. + """ + direction = None + error = None + improvement_nodes = histogram_node.getElementsByTagName('improvement') + if not improvement_nodes: + return None, None + if len(improvement_nodes) > 1: + histogram_name = histogram_node.getAttribute('name') + error = f'Histogram "{histogram_name}" has multiple <improvement> tags.' + return None, error + + improvement_node = improvement_nodes[0] + direction = improvement_node.getAttribute('direction') + if (direction not in + histogram_configuration_model.IMPROVEMENT_DIRECTION_VALID_VALUES): + histogram_name = histogram_node.getAttribute('name') + error = ( + f'Histogram "{histogram_name}" has an invalid direction "{direction}" ' + f'in its <improvement> tag.') + return None, error + + return direction, None + + def _ExtractComponents(histogram): """Extracts component information from the given histogram element. @@ -583,6 +618,15 @@ if owners: histogram_entry['owners'] = owners + # Find the <improvement> tag, if any. + improvement_direction, improvement_error = _ExtractImprovementDirection( + histogram) + if improvement_direction: + histogram_entry['improvement'] = improvement_direction + if improvement_error: + logging.error(improvement_error) + have_errors = True + # Find <component> tag. components = _ExtractComponents(histogram) if components:
diff --git a/tools/metrics/histograms/extract_histograms_test.py b/tools/metrics/histograms/extract_histograms_test.py index d6be485..d3474a7 100644 --- a/tools/metrics/histograms/extract_histograms_test.py +++ b/tools/metrics/histograms/extract_histograms_test.py
@@ -8,6 +8,7 @@ import xml.dom.minidom import extract_histograms +import histogram_configuration_model TEST_SUFFIX_OBSOLETION_XML_CONTENT = """ <histogram-configuration> @@ -938,6 +939,46 @@ self.assertIn('Test.First.Found', histograms_dict) self.assertIn('Test.Last.Found', histograms_dict) + def testExtractImprovementDirection(self): + histogram_name = 'Histogram.With.InterpretationTag' + config = """ +<histogram-configuration> + +<histograms> + +<histogram name="{histogram_name}" expires_after="M100" units="units"> + <owner>owner@chromium.org</owner> + {improvement_tag} + <summary>The improvement tag says a higher value is good!</summary> +</histogram> + +</histograms> + +</histogram-configuration>""" + + improvement_tag_good = '<improvement direction="HIGHER_IS_BETTER"/>' + improvement_tag_bad = '<improvement>HIGHER_IS_BETTER</improvement>' + + config_good = config.format(histogram_name=histogram_name, + improvement_tag=improvement_tag_good) + config_bad = config.format(histogram_name=histogram_name, + improvement_tag=improvement_tag_bad) + + histograms_dict, had_errors = extract_histograms.ExtractHistogramsFromDom( + xml.dom.minidom.parseString(config_good)) + self.assertFalse(had_errors) + self.assertIn(histogram_name, histograms_dict) + self.assertIn('improvement', histograms_dict[histogram_name]) + self.assertEqual( + histogram_configuration_model.IMPROVEMENT_DIRECTION_HIGHER_IS_BETTER, + histograms_dict[histogram_name]['improvement']) + + histograms_dict, had_errors = extract_histograms.ExtractHistogramsFromDom( + xml.dom.minidom.parseString(config_bad)) + self.assertTrue(had_errors) + self.assertNotIn('improvement', histograms_dict[histogram_name]) + + if __name__ == "__main__": logging.basicConfig(level=logging.ERROR + 1) unittest.main()
diff --git a/tools/metrics/histograms/histogram_configuration_model.py b/tools/metrics/histograms/histogram_configuration_model.py index b88c176..278f51b 100644 --- a/tools/metrics/histograms/histogram_configuration_model.py +++ b/tools/metrics/histograms/histogram_configuration_model.py
@@ -81,6 +81,26 @@ ]) # The following types are used for histograms.xml. +IMPROVEMENT_DIRECTION_VALID_VALUES = ( + IMPROVEMENT_DIRECTION_HIGHER_IS_BETTER := 'HIGHER_IS_BETTER', + IMPROVEMENT_DIRECTION_LOWER_IS_BETTER := 'LOWER_IS_BETTER', + IMPROVEMENT_DIRECTION_NEITHER_IS_BETTER := 'NEITHER_IS_BETTER', +) + +_IMPROVEMENT_TYPE = models.ObjectNodeType( + 'improvement', + attributes=[ + ( + 'direction', + str, + r'^(' + '|'.join(IMPROVEMENT_DIRECTION_VALID_VALUES) + ')$', + ), + ], + required_attributes=['direction'], + text_attribute=False, + single_line=True, +) + _VARIANT_TYPE = models.ObjectNodeType( 'variant', attributes=[ @@ -145,6 +165,7 @@ (_OBSOLETE_TYPE.tag, _KEEP_ORDER), (_OWNER_TYPE.tag, _KEEP_ORDER), (_COMPONENT_TYPE.tag, _KEEP_ORDER), + (_IMPROVEMENT_TYPE.tag, _KEEP_ORDER), (_SUMMARY_TYPE.tag, _KEEP_ORDER), (_TOKEN_TYPE.tag, _KEEP_ORDER), ], @@ -158,6 +179,9 @@ models.ChildType(_COMPONENT_TYPE.tag, _COMPONENT_TYPE, multiple=True), models.ChildType(_SUMMARY_TYPE.tag, _SUMMARY_TYPE, multiple=False), models.ChildType(_TOKEN_TYPE.tag, _TOKEN_TYPE, multiple=True), + models.ChildType(_IMPROVEMENT_TYPE.tag, + _IMPROVEMENT_TYPE, + multiple=False), ]) _HISTOGRAMS_TYPE = models.ObjectNodeType(
diff --git a/tools/metrics/histograms/histogram_configuration_model_test_histograms.py b/tools/metrics/histograms/histogram_configuration_model_test_histograms.py index 9f119172..43d7961 100644 --- a/tools/metrics/histograms/histogram_configuration_model_test_histograms.py +++ b/tools/metrics/histograms/histogram_configuration_model_test_histograms.py
@@ -636,6 +636,38 @@ etree_util.ParseXMLString(input_xml)) self.assertMultiLineEqual(result.strip(), expected_xml) + def testIndividualTagParsing_improvement(self): + """Tests that <improvement> has the right format and can be parsed.""" + + improvement_tag_good = '<improvement direction="HIGHER_IS_BETTER"/>' + improvement_tag_bad = ' <improvement>HIGHER_IS_BETTER</improvement>' + config = """ +<histogram-configuration> + +<histograms> + +<histogram name="Histogram.With.ImprovementTag" expires_after="M100"> + <owner>owner1@chromium.org</owner> + {improvement_tag} + <summary>The improvement tag says higher value is good!</summary> +</histogram> + +</histograms> + +</histogram-configuration>""" + + config_good = config.format(improvement_tag=improvement_tag_good) + config_bad = config.format(improvement_tag=improvement_tag_bad) + + result = histogram_configuration_model.PrettifyTree( + etree_util.ParseXMLString(config_good)) + self.assertMultiLineEqual(result.strip(), config_good.strip()) + + with self.assertRaisesRegex(ValueError, + 'direction "" does not match regex'): + histogram_configuration_model.PrettifyTree( + etree_util.ParseXMLString(config_bad)) + if __name__ == '__main__': unittest.main()
diff --git a/tools/metrics/histograms/metadata/apps/OWNERS b/tools/metrics/histograms/metadata/apps/OWNERS index b6b66f2..03bcea3f 100644 --- a/tools/metrics/histograms/metadata/apps/OWNERS +++ b/tools/metrics/histograms/metadata/apps/OWNERS
@@ -4,4 +4,5 @@ # Use chromium-metrics-reviews@google.com as a backup. nancylingwang@chromium.org tby@chromium.org +tsergeant@chromium.org yulunwu@chromium.org
diff --git a/tools/metrics/histograms/metadata/apps/histograms.xml b/tools/metrics/histograms/metadata/apps/histograms.xml index 62a36c9..a4a3976b 100644 --- a/tools/metrics/histograms/metadata/apps/histograms.xml +++ b/tools/metrics/histograms/metadata/apps/histograms.xml
@@ -187,6 +187,23 @@ <summary>The ways the user opens up the App Management interface.</summary> </histogram> +<histogram name="AppPreloadService.FirstLoginFlowTime.{Status}" units="ms" + expires_after="2023-08-01"> + <owner>jshikaram@chromium.org</owner> + <owner>chromeos-apps-foundation-team@google.com</owner> + <summary> + The time it takes for the first login flow of the App Preload service to + complete with the final status of {Status}. + + This metric is recorded when the user logs in for the first time on a device + and the App Preload service kicks off the first login flow. + </summary> + <token key="Status"> + <variant name="Failure" summary="First login flow completed in failure"/> + <variant name="Success" summary="First login flow completed successfully"/> + </token> +</histogram> + <histogram name="AppPreloadService.ServerResponseCodes" enum="CombinedHttpResponseAndNetErrorCode" expires_after="2023-08-01"> <owner>jshikaram@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/ash/histograms.xml b/tools/metrics/histograms/metadata/ash/histograms.xml index e3cc180..4e15dcf 100644 --- a/tools/metrics/histograms/metadata/ash/histograms.xml +++ b/tools/metrics/histograms/metadata/ash/histograms.xml
@@ -143,8 +143,8 @@ <histogram name="Ash.Accelerators.WindowSnap" enum="WindowSnapAcceleratorAction" expires_after="2023-11-20"> - <owner>amusbach@chromium.org</owner> <owner>xdai@chromium.org</owner> + <owner>chromeos-wmp@google.com</owner> <summary>Captures usage of Alt+[ and Alt+].</summary> </histogram> @@ -1499,9 +1499,9 @@ <histogram name="Ash.Desks.AnimationLatency.DeskActivation" units="ms" expires_after="2023-06-25"> - <owner>amusbach@chromium.org</owner> <owner>afakhry@chromium.org</owner> <owner>tclaiborne@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Emitted when the virtual desks activation animation begins, to report the latency of starting this animation. In a continuous desk animation, this @@ -1511,9 +1511,9 @@ <histogram name="Ash.Desks.AnimationLatency.DeskRemoval" units="ms" expires_after="2023-06-25"> - <owner>amusbach@chromium.org</owner> <owner>afakhry@chromium.org</owner> <owner>tclaiborne@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Emitted when the virtual desks removal animation begins, to report the latency of starting this animation. In a continuous desk animation, this @@ -3734,9 +3734,10 @@ </histogram> <histogram name="Ash.Overview.AnimationSmoothness.Enter{OverviewAnimationMode}" - units="%" expires_after="2022-10-15"> + units="%" expires_after="2024-02-07"> <owner>omrilio@chromium.org</owner> <owner>oshima@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Relative smoothness of animations when entering overview mode, recorded when the animation completes. 100% represents ideally smooth 60 frames per @@ -3746,9 +3747,10 @@ </histogram> <histogram name="Ash.Overview.AnimationSmoothness.Exit{OverviewAnimationMode}" - units="%" expires_after="2022-10-15"> + units="%" expires_after="2024-02-07"> <owner>omrilio@chromium.org</owner> <owner>oshima@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Relative smoothness of animations when exiting overview mode, recorded when the animation completes. 100% represents ideally smooth 60 frames per @@ -3914,8 +3916,8 @@ <histogram name="Ash.Overview.WindowDrag.Workflow" enum="OverviewDragAction" expires_after="2023-07-16"> - <owner>amusbach@chromium.org</owner> <owner>xdai@chromium.org</owner> + <owner>chromeos-wmp@google.com</owner> <summary> Recorded when a drag from overview (not from the top or shelf) is completed, and when an overview item is closed by vertically swiping or flinging (even @@ -4504,7 +4506,7 @@ </histogram> <histogram name="Ash.Shelf.Menu.SelectedMenuItemIndex" units="Index" - expires_after="2023-02-01"> + expires_after="2024-02-08"> <owner>anasalazar@chromium.org</owner> <owner>mmourgos@google.com</owner> <summary> @@ -4876,8 +4878,38 @@ </token> </histogram> +<histogram name="Ash.Smoothness.PercentDroppedFrames_1sWindow2{Stage}" + units="%" expires_after="2024-01-29"> + <owner>xiyuan@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> + <summary> + Tracks the percent of dropped frames in a 1 second sliding window. + + PercentDroppedFrames is measured by tracking the number of frames which were + not displayed on screen out of the total number of frames expected to be + produced and displayed. In other words, the lower this number is, the + smoother experience. + + The ".InSession" covers the time of 1 minute beyond into user + sessions. The 1 minute timeline is picked based on + "Ash.Login.TimeUntilGoodADF" histogram, where about 93-94% user + sessions fall under the 1 minute bar. + + The metric is reported {Stage}. + </summary> + <token key="Stage"> + <variant name="" summary="on every frame"/> + <variant name=".InSession" + summary="on every frame after 1 min into session"/> + </token> +</histogram> + <histogram name="Ash.Smoothness.PercentDroppedFrames_1sWindow{Stage}" units="%" expires_after="2023-10-30"> + <obsolete> + This metric is reported on every dropped frame instead of every frame. It is + deprecated in favor of Ash.Smoothness.PercentDroppedFrames_1sWindow2. + </obsolete> <owner>xiyuan@chromium.org</owner> <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> @@ -4987,8 +5019,8 @@ <histogram name="Ash.SplitView.TimeInMultiDisplaySplitView" units="ms" expires_after="2023-07-02"> - <owner>amusbach@chromium.org</owner> <owner>xdai@chromium.org</owner> + <owner>chromeos-wmp@google.com</owner> <summary> The amount of time that the user spent in multi-display split view mode, meaning that split view is active on more than one display. The time is @@ -5044,11 +5076,11 @@ <histogram name="Ash.SplitViewResize.PresentationTime.MaxLatency{SplitViewResizeModes}" - units="ms" expires_after="2023-01-10"> - <owner>amusbach@chromium.org</owner> + units="ms" expires_after="2024-02-07"> <owner>xdai@chromium.org</owner> <owner>omrilio@chromium.org</owner> <owner>oshima@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Maximum latency of the presentation time while resizing one or two split view windows. {SplitViewResizeModes} @@ -5058,10 +5090,10 @@ <histogram name="Ash.SplitViewResize.PresentationTime{SplitViewResizeModes}" units="ms" expires_after="2023-11-18"> - <owner>amusbach@chromium.org</owner> <owner>xdai@chromium.org</owner> <owner>omrilio@chromium.org</owner> <owner>oshima@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Presentation time while resizing one or two split view windows. {SplitViewResizeModes} @@ -5790,9 +5822,9 @@ <histogram name="Ash.Window.AnimationSmoothness.Minimize" units="%" expires_after="2023-06-25"> - <owner>amusbach@chromium.org</owner> <owner>oshima@chromium.org</owner> <owner>sammiequon@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Relative smoothness of minimizing window animation. 100% represents ideally smooth 60 frames per second. 50% represents when only 30 frames per second @@ -5818,9 +5850,9 @@ <histogram name="Ash.Window.AnimationSmoothness.Unminimize" units="%" expires_after="2023-06-25"> - <owner>amusbach@chromium.org</owner> <owner>oshima@chromium.org</owner> <owner>sammiequon@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> Relative smoothness of unminimizing window animation. 100% represents ideally smooth 60 frames per second. 50% represents when only 30 frames per
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index 28b2b87d2..d3f096e 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -219,11 +219,6 @@ <variant name=".Unknown" summary="Unknown form type"/> </variants> -<variants name="AutofillLocalCardMigrationBubbleShow"> - <variant name=".FirstShow" summary="First time bubble is shown"/> - <variant name=".Reshows" summary="Bubble was reopened after being closed"/> -</variants> - <variants name="AutofillProfileCategory"> <variant name="AccountChrome" summary="kAccount profiles originating from Chrome"/> @@ -2420,34 +2415,26 @@ </summary> </histogram> -<histogram - name="Autofill.LocalCardMigrationBubbleOffer{AutofillLocalCardMigrationBubbleShow}" +<histogram name="Autofill.LocalCardMigrationBubbleOffer.{ShowType}" enum="AutofillLocalCardMigrationBubbleOffer" expires_after="2023-09-01"> <owner>siyua@chromium.org</owner> <owner>jsaul@google.com</owner> <summary> Record events related to bubble showing. Logged when bubble is requested or - is actually shown to users. {AutofillLocalCardMigrationBubbleShow} + is actually shown to users. </summary> - <token key="AutofillLocalCardMigrationBubbleShow" - variants="AutofillLocalCardMigrationBubbleShow"> - <variant name=""/> - </token> + <token key="ShowType" variants="Autofill.PaymentBubble.Show"/> </histogram> -<histogram - name="Autofill.LocalCardMigrationBubbleResult{AutofillLocalCardMigrationBubbleShow}" +<histogram name="Autofill.LocalCardMigrationBubbleResult.{ShowType}" enum="AutofillLocalCardMigrationBubbleResult" expires_after="2023-09-01"> <owner>siyua@chromium.org</owner> <owner>jsaul@google.com</owner> <summary> Records whether and how the local card migration bubble was accepted or - closed. {AutofillLocalCardMigrationBubbleShow} + closed. </summary> - <token key="AutofillLocalCardMigrationBubbleShow" - variants="AutofillLocalCardMigrationBubbleShow"> - <variant name=""/> - </token> + <token key="ShowType" variants="Autofill.PaymentBubble.Show"/> </histogram> <histogram name="Autofill.LocalCardMigrationBubbleUserInteraction" @@ -3566,7 +3553,7 @@ <histogram name="Autofill.SaveCreditCardPromptOffer{AutofillSaveCreditCardPromptDestination}" - enum="AutofillSaveCreditCardPromptOfferEnum" expires_after="2023-11-01"> + enum="AutofillSavePaymentMethodPromptOfferEnum" expires_after="2023-11-01"> <owner>jsaul@google.com</owner> <owner>siyua@chromium.org</owner> <owner>payments-autofill-team@google.com</owner> @@ -3583,7 +3570,7 @@ <histogram name="Autofill.SaveCreditCardPromptResult{AutofillSaveCreditCardPromptDestination}" - enum="AutofillSaveCreditCardPromptResultEnum" expires_after="2023-11-01"> + enum="AutofillSavePaymentMethodPromptOfferEnum" expires_after="2023-11-01"> <owner>jsaul@google.com</owner> <owner>siyua@chromium.org</owner> <owner>payments-autofill-team@google.com</owner> @@ -3598,6 +3585,44 @@ </token> </histogram> +<histogram name="Autofill.SaveIbanPromptOffer{IbanTypeToBeSaved}.{ShowType}" + enum="AutofillSavePaymentMethodPromptResultEnum" expires_after="2023-09-01"> + <owner>qihuizhao@google.com</owner> + <owner>jsaul@google.com</owner> + <owner>payments-autofill-team@google.com</owner> + <summary> + Records every time the save IBAN bubble or omnibox icon (due to maxstrike + reached) is offered to the user, broken down by destination and show type. + </summary> + <token key="IbanTypeToBeSaved" variants="IbanTypeToBeSaved"/> + <token key="ShowType" variants="Autofill.PaymentBubble.Show"/> +</histogram> + +<histogram + name="Autofill.SaveIbanPromptResult{IbanTypeToBeSaved}.SavedWithNickname" + enum="Boolean" expires_after="2023-09-01"> + <owner>jsaul@google.com</owner> + <owner>payments-autofill-team@google.com</owner> + <summary> + Records when the user accepts the bubble to save an IBAN, with or without + nickname. + </summary> + <token key="IbanTypeToBeSaved" variants="IbanTypeToBeSaved"/> +</histogram> + +<histogram name="Autofill.SaveIbanPromptResult{IbanTypeToBeSaved}.{ShowType}" + enum="AutofillSavePaymentMethodPromptOfferEnum" expires_after="2023-09-01"> + <owner>qihuizhao@google.com</owner> + <owner>jsaul@google.com</owner> + <owner>payments-autofill-team@google.com</owner> + <summary> + Records when the user makes a decision on the save IBAN bubble, broken down + by destinations. + </summary> + <token key="IbanTypeToBeSaved" variants="IbanTypeToBeSaved"/> + <token key="ShowType" variants="Autofill.PaymentBubble.Show"/> +</histogram> + <histogram name="Autofill.ScanCreditCard.Completed" enum="BooleanCompleted" expires_after="2023-06-18"> <owner>battre@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/chrome/histograms.xml b/tools/metrics/histograms/metadata/chrome/histograms.xml index 114e205..9d41db5 100644 --- a/tools/metrics/histograms/metadata/chrome/histograms.xml +++ b/tools/metrics/histograms/metadata/chrome/histograms.xml
@@ -106,6 +106,11 @@ <histogram name="Chrome.Lacros.Smoothness.PercentDroppedFrames_1sWindow" units="%" expires_after="2023-07-25"> + <obsolete> + This metric is reported on every dropped frame instead of every frame. It is + deprecated in favor of + Chrome.Lacros.Smoothness.PercentDroppedFrames_1sWindow2 + </obsolete> <owner>xiyuan@chromium.org</owner> <owner>chromeos-perfmetrics-eng@google.com</owner> <summary> @@ -114,6 +119,16 @@ </summary> </histogram> +<histogram name="Chrome.Lacros.Smoothness.PercentDroppedFrames_1sWindow2" + units="%" expires_after="2024-01-29"> + <owner>xiyuan@chromium.org</owner> + <owner>chromeos-perfmetrics-eng@google.com</owner> + <summary> + Similar to Ash.Smoothness.PercentDroppedFrames_1sWindow2 but emitted for the + browser UI of lacros-chrome. + </summary> +</histogram> + <histogram name="Chrome.ProcessSingleton.NotifyResult" enum="NotifyResult" expires_after="2023-07-30"> <owner>gab@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/compositing/histograms.xml b/tools/metrics/histograms/metadata/compositing/histograms.xml index 1a1a891c..fd2f85e 100644 --- a/tools/metrics/histograms/metadata/compositing/histograms.xml +++ b/tools/metrics/histograms/metadata/compositing/histograms.xml
@@ -1246,6 +1246,7 @@ <variant name="SETMainThreadAnimation" summary="main thread animations during a view transition"/> <variant name="TouchScroll" summary="touch scrolling"/> + <variant name="Video" summary="video playback"/> <variant name="WheelScroll" summary="wheel scrolling"/> </token> </histogram>
diff --git a/tools/metrics/histograms/metadata/event/histograms.xml b/tools/metrics/histograms/metadata/event/histograms.xml index 5192cb3..2430a5db 100644 --- a/tools/metrics/histograms/metadata/event/histograms.xml +++ b/tools/metrics/histograms/metadata/event/histograms.xml
@@ -1887,7 +1887,7 @@ units="microseconds" expires_after="never"> <!-- expires-never: guiding metric (internal: go/chrome-browser-guiding-metrics) --> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <owner>chrome-analysis-team@google.com</owner> <summary> @@ -1908,7 +1908,7 @@ <histogram name="EventLatency.GestureScrollUpdate.Touchscreen.TotalLatency2" units="microseconds" expires_after="2024-01-16"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> When a user performs a scroll using touchscreen, a sequence of touch-move @@ -1930,7 +1930,7 @@ <histogram name="EventLatency.GestureScrollUpdate.{NonTouchscreenScrollInputType}.TotalLatency{Version}" units="microseconds" expires_after="2024-01-16"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> Tracks total latency of {NonTouchscreenScrollInputType} @@ -1954,7 +1954,7 @@ <histogram name="EventLatency.TotalLatency" units="microseconds" expires_after="2024-01-16"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> Tracks total latency of all event types, from when the user input causing @@ -1968,7 +1968,7 @@ <histogram name="EventLatency.{NonGsuScrollEventType}.{ScrollInputType}.TotalLatency{Version}" units="microseconds" expires_after="2024-01-16"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> Tracks total latency of {ScrollInputType} {NonGsuScrollEventType}, from when @@ -2001,7 +2001,7 @@ <histogram name="EventLatency.{NonScrollPinchEventType}.TotalLatency" units="microseconds" expires_after="2024-01-16"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> Tracks total latency of {NonScrollPinchEventType}, from when the user input @@ -2036,7 +2036,7 @@ <histogram name="EventLatency.{PinchEventType}.{PinchInputType}.TotalLatency" units="microseconds" expires_after="2024-01-16"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> Tracks total latency of {PinchInputType} {PinchEventType}, from when the @@ -2060,7 +2060,7 @@ <histogram name="EventLatency.{ScrollEventType}.TotalLatency{Version}" units="microseconds" expires_after="2024-01-16"> - <owner>mohsen@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>graphics-dev@chromium.org</owner> <summary> Tracks total latency of {ScrollEventType}, from when the user input causing
diff --git a/tools/metrics/histograms/metadata/ios/histograms.xml b/tools/metrics/histograms/metadata/ios/histograms.xml index a64df8fd..2e77bdc 100644 --- a/tools/metrics/histograms/metadata/ios/histograms.xml +++ b/tools/metrics/histograms/metadata/ios/histograms.xml
@@ -1233,6 +1233,21 @@ </summary> </histogram> +<histogram name="IOS.NavigationStateNotFinishedInLoadCancelled" enum="Boolean" + expires_after="2023-09-24"> + <owner>ajuma@chromium.org</owner> + <owner>michaeldo@chromium.org</owner> + <summary> + The method -[CRWWKNavigationHandler loadCancelled] updates the navigation + state to finished if it is any other state. Additionally, if + `beingDestroyed` is false, the webstate's loading state is set to false. + There is a long standing TODO in this method with the comment: "Check + if this function should be removed." This metric is logged when the + logic in this method is triggered. The results will be reviewed to see if + this logic is still ever called or if it can now be removed. + </summary> +</histogram> + <histogram name="IOS.NSString.stringByReplacingCharactersInRange.NilArgument" enum="Boolean" expires_after="2022-12-11"> <owner>rohitrao@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/platform/histograms.xml b/tools/metrics/histograms/metadata/platform/histograms.xml index d0fe517..a3eb765 100644 --- a/tools/metrics/histograms/metadata/platform/histograms.xml +++ b/tools/metrics/histograms/metadata/platform/histograms.xml
@@ -2224,7 +2224,7 @@ </histogram> <histogram name="Platform.{GSC}.ARVStatus" enum="GscArvStatus" - expires_after="2023-11-09"> + expires_after="2024-02-05"> <owner>vbendeb@chromium.org</owner> <owner>ti50-core+uma@chromium.org</owner> <summary> @@ -2243,7 +2243,7 @@ </histogram> <histogram name="Platform.{GSC}.BoardIdFlags" enum="Cr50BoardIdFlags" - expires_after="2023-02-10"> + expires_after="2024-02-05"> <owner>apronin@chromium.org</owner> <owner>vbendeb@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner> @@ -2259,7 +2259,7 @@ </histogram> <histogram name="Platform.{GSC}.BoardIdOfRlzMismatch" enum="Cr50CrosRlzCodes" - expires_after="2023-02-10"> + expires_after="2024-02-05"> <owner>vbendeb@chromium.org</owner> <owner>apronin@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner> @@ -2275,7 +2275,7 @@ </histogram> <histogram name="Platform.{GSC}.FlashLog" enum="Cr50FlashLogs" - expires_after="2023-02-10"> + expires_after="2024-02-05"> <owner>apronin@chromium.org</owner> <owner>vbendeb@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner> @@ -2293,7 +2293,7 @@ </histogram> <histogram name="Platform.{GSC}.MatchingBoardId" enum="Cr50CrosRlzCodes" - expires_after="2023-02-10"> + expires_after="2024-02-05"> <owner>vbendeb@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner> <summary> @@ -2308,7 +2308,7 @@ </histogram> <histogram name="Platform.{GSC}.RlzOfBoardIdMismatch" enum="Cr50CrosRlzCodes" - expires_after="2023-02-10"> + expires_after="2024-02-05"> <owner>vbendeb@chromium.org</owner> <owner>apronin@chromium.org</owner> <owner>cros-hwsec+uma@chromium.org</owner>
diff --git a/tools/metrics/histograms/metadata/signin/histograms.xml b/tools/metrics/histograms/metadata/signin/histograms.xml index 6852af3..09988fa 100644 --- a/tools/metrics/histograms/metadata/signin/histograms.xml +++ b/tools/metrics/histograms/metadata/signin/histograms.xml
@@ -385,7 +385,7 @@ </histogram> <histogram name="Signin.Enterprise.WorkProfile.ProfileCreatedWithPolicySet" - enum="BooleanCreated" expires_after="2023-03-15"> + enum="BooleanCreated" expires_after="2023-09-15"> <owner>pastarmovj@chromium.org</owner> <owner>ydago@chromium.org</owner> <summary> @@ -397,7 +397,7 @@ </histogram> <histogram name="Signin.Enterprise.WorkProfile.ProfileCreatedwithPolicyUnset" - enum="BooleanCreated" expires_after="2023-03-15"> + enum="BooleanCreated" expires_after="2023-09-15"> <owner>pastarmovj@chromium.org</owner> <owner>ydago@chromium.org</owner> <summary>
diff --git a/tools/metrics/ukm/ukm.xml b/tools/metrics/ukm/ukm.xml index afbc6614..eca5860 100644 --- a/tools/metrics/ukm/ukm.xml +++ b/tools/metrics/ukm/ukm.xml
@@ -7519,8 +7519,7 @@ </event> <event name="Graphics.Smoothness.EventLatency"> - <owner>mohsen@chromium.org</owner> - <owner>sadrul@chromium.org</owner> + <owner>jonross@chromium.org</owner> <summary> Tracks the duration of stages in the rendering pipeline when processing a single frame in response to an input event. To meet UKM goals for data @@ -8347,7 +8346,7 @@ <event name="Graphics.Smoothness.Latency"> <owner>animations-dev@chromium.org</owner> - <owner>sadrul@chromium.org</owner> + <owner>jonross@chromium.org</owner> <owner>schenney@chromium.org</owner> <summary> Tracks the duration of stages in the rendering pipeline while processing a @@ -8871,7 +8870,7 @@ <event name="Graphics.Smoothness.NormalizedPercentDroppedFrames" singular="True"> <owner>animations-dev@chromium.org</owner> - <owner>sadrul@chromium.org</owner> + <owner>jonross@chromium.org</owner> <summary> Measures various normalizations for the smoothness metric. The metric is measured by counting dropped frames, and various normalization strategies @@ -9327,7 +9326,7 @@ <event name="Graphics.Smoothness.PercentDroppedFrames"> <owner>animations-dev@chromium.org</owner> - <owner>sadrul@chromium.org</owner> + <owner>jonross@chromium.org</owner> <summary> Tracks the percent of dropped frames for a particular sequence of frames such as during scroll or animation. PercentDroppedFrames is measured by @@ -9656,7 +9655,7 @@ Deprecated 02/2020. </obsolete> <owner>animations-dev@chromium.org</owner> - <owner>sadrul@chromium.org</owner> + <owner>jonross@chromium.org</owner> <summary> As of 2020-02-12, this is deprecated in favor of Graphics.Smoothness.PercentDroppedFrames.
diff --git a/tools/perf/benchmark.csv b/tools/perf/benchmark.csv index dffbf79..1e19649 100644 --- a/tools/perf/benchmark.csv +++ b/tools/perf/benchmark.csv
@@ -6,6 +6,7 @@ UNSCHEDULED_blink_perf.base64,csharrison@chromium.org,Blink>Internals>WTF,https://bit.ly/blink-perf-benchmarks,all UNSCHEDULED_blink_perf.performance_apis,yoavweiss@chromium.org,Blink>PerformanceAPIs,https://bit.ly/blink-perf-benchmarks,all UNSCHEDULED_blink_perf.service_worker,"shimazu@chromium.org, falken@chromium.org, ting.shao@intel.com",Blink>ServiceWorker,https://bit.ly/blink-perf-benchmarks, +UNSCHEDULED_blink_perf.view_transitions,"bokan@chromium.org, khushalsagar@chromium.org, vmpstr@chromium.org",Blink>ViewTransitions,https://bit.ly/blink-perf-benchmarks,all UNSCHEDULED_loading.mbi,blink-isolation-dev@chromium.org,Blink>Internals>Modularization,https://bit.ly/loading-benchmarks,many_agents UNSCHEDULED_v8.loading_desktop,"cbruni@chromium.org, tmrts@chromium.org, almuthanna@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,emerging_market,health_check,international,javascript_heavy" UNSCHEDULED_v8.loading_mobile,"cbruni@chromium.org, leszeks@chromium.org, tmrts@chromium.org",Blink>JavaScript,https://bit.ly/system-health-v8-benchmarks,"2016,2018,2019,2020,emerging_market,health_check,international,javascript_heavy"
diff --git a/tools/perf/benchmarks/blink_perf.py b/tools/perf/benchmarks/blink_perf.py index 81d50d5..7a55c96d 100644 --- a/tools/perf/benchmarks/blink_perf.py +++ b/tools/perf/benchmarks/blink_perf.py
@@ -794,3 +794,17 @@ def SetExtraBrowserOptions(self, options): options.AppendExtraBrowserArgs( ['--enable-unsafe-webgpu', '--enable-features=V8TurboFastApiCalls']) + + +@benchmark.Info(emails=[ + 'bokan@chromium.org', 'khushalsagar@chromium.org', 'vmpstr@chromium.org' +], + component='Blink>ViewTransitions', + documentation_url='https://bit.ly/blink-perf-benchmarks') +class BlinkPerfViewTransitions(_BlinkPerfBenchmark): + SUBDIR = 'view_transitions' + TAGS = _BlinkPerfBenchmark.TAGS + ['all'] + + @classmethod + def Name(cls): + return 'UNSCHEDULED_blink_perf.view_transitions'
diff --git a/tools/perf/core/perfetto_binary_roller/binary_deps.json b/tools/perf/core/perfetto_binary_roller/binary_deps.json index 4e4aeb7..868db5b 100644 --- a/tools/perf/core/perfetto_binary_roller/binary_deps.json +++ b/tools/perf/core/perfetto_binary_roller/binary_deps.json
@@ -6,15 +6,15 @@ }, "win": { "hash": "3bc30c6747aa0fefd2dad9c006415bbc322e7065", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/656582b37c3b7214e3b20aba8fd74d41b35a7160/trace_processor_shell.exe" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/win/0374f0872ca2a125943edd23e8d27bb606fe47de/trace_processor_shell.exe" }, "linux_arm": { "hash": "e945a99da7a66211f847b8049627bbec846d2d1d", "full_remote_path": "perfetto-luci-artifacts/3b59f000c939bfe4d05267fd68d282ef0b541334/linux-arm/trace_processor_shell" }, "mac": { - "hash": "db9551018053d43c61c96765708a25ca01e0bb19", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/656582b37c3b7214e3b20aba8fd74d41b35a7160/trace_processor_shell" + "hash": "8a1fc8c9e19df500c3bc81df066a3e9467ed925d", + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/mac/0374f0872ca2a125943edd23e8d27bb606fe47de/trace_processor_shell" }, "mac_arm64": { "hash": "f9caa6dfbdc44573d32a21a9aeeed2058ffc3d68", @@ -22,7 +22,7 @@ }, "linux": { "hash": "4a5fe0dbde2818c8752df7a36cd8f60c052e8f56", - "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/a352070f45024ce07dfec791a89ed2af785ce46c/trace_processor_shell" + "full_remote_path": "chromium-telemetry/perfetto_binaries/trace_processor_shell/linux/0374f0872ca2a125943edd23e8d27bb606fe47de/trace_processor_shell" } }, "power_profile.sql": {
diff --git a/tools/perf/expectations.config b/tools/perf/expectations.config index d4ed7d34..f348f7a 100644 --- a/tools/perf/expectations.config +++ b/tools/perf/expectations.config
@@ -303,7 +303,6 @@ crbug.com/1269978 [ fuchsia ] rendering.mobile/svg_icon_raster [ Skip ] crbug.com/1271258 [ fuchsia ] rendering.mobile/motionmark* [ Skip ] crbug.com/1316726 [ fuchsia ] rendering.mobile/microgame_fps [ Skip ] -crbug.com/1316721 [ fuchsia ] rendering.mobile/reddit_mobile_2018 [ Skip ] crbug.com/1316725 [ fuchsia ] rendering.mobile/mix_10k [ Skip ] # Fuchsia does not support the pinch tests. crbug.com/1316732 [ fuchsia ] rendering.mobile/accu_weather_mobile_pinch_2018 [ Skip ] @@ -469,7 +468,6 @@ crbug.com/1147969 [ fuchsia-board-astro ] system_health.memory_desktop/browse:media:youtubetv_watch:2020 [ Skip ] crbug.com/1147969 [ fuchsia-board-astro ] system_health.memory_desktop/browse:media:youtubetv:2019 [ Skip ] crbug.com/1147969 [ fuchsia-board-astro ] system_health.memory_desktop/browse:news:cnn:2021 [ Skip ] -crbug.com/1147969 [ fuchsia-board-astro ] system_health.memory_desktop/browse:news:reddit:2020 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse_accessibility:tech:codesearch:2018 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:media:googleplaystore:2021 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:media:imgur [ Skip ] @@ -477,7 +475,6 @@ crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:media:youtubetv_watch:2020 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:media:youtubetv:2019 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:news:cnn:2021 [ Skip ] -crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:news:reddit:2020 [ Skip ] crbug.com/1147969 [ linux ] system_health.memory_desktop/browse:news:reddit:2020 [ Skip ] crbug.com/1147969 [ fuchsia-board-astro ] system_health.memory_desktop/browse:search:google_india:2021 [ Skip ] crbug.com/1147969 [ fuchsia-board-astro ] system_health.memory_desktop/browse:social:facebook_infinite_scroll:2018 [ Skip ] @@ -502,7 +499,6 @@ crbug.com/1192170 [ fuchsia-board-astro ] system_health.memory_desktop/browse:news:nytimes:2020 [ Skip ] crbug.com/1192176 [ fuchsia-board-astro ] system_health.memory_desktop/browse:media:tumblr:2018 [ Skip ] crbug.com/1232202 [ fuchsia-board-astro ] system_health.memory_desktop/browse:search:google:2020 [ Skip ] -crbug.com/1316721 [ fuchsia-board-astro ] system_health.memory_desktop/load:news:reddit:2018 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:search:google_india:2021 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:social:facebook_infinite_scroll:2018 [ Skip ] crbug.com/1147969 [ fuchsia-board-sherlock ] system_health.memory_desktop/browse:social:twitter:2018 [ Skip ]
diff --git a/tools/visual_debugger/filter-ui.js b/tools/visual_debugger/filter-ui.js index ea4347c..5542d336 100644 --- a/tools/visual_debugger/filter-ui.js +++ b/tools/visual_debugger/filter-ui.js
@@ -42,7 +42,8 @@ <div class='label' title='Filter annotation to match. For example frame.root.damage' >Annotation </div> <div class='input'> - <input placeholder='Substring to match' id='annotation' size=40> + <input list="knownAnnotations" placeholder='Substring to match' + id='annotation' size=40> <!-- TODO: A fancy drop-down here would be nice. --> </div> </div> @@ -133,6 +134,26 @@ window.customElements.define('filter-ui', FilterUI); +// A <datalist> element containing values of previously seen filter annotations. +let dataListElement = undefined; +let knownAnnotations = new Set(); +// Called when processing new sources from a frame. +function notifyUiOfNewSource(source) { + if (dataListElement === undefined) { + dataListElement = document.createElement("datalist"); + dataListElement.id = "knownAnnotations"; + document.body.appendChild(dataListElement); + } + + if (!knownAnnotations.has(source.anno)) { + let option = document.createElement("option"); + option.value = source.anno; + dataListElement.appendChild(option); + + knownAnnotations.add(source.anno); + } +} + function createFilterChip(filter) { const chip = document.createElement('div'); chip.className = "mdc-chip";
diff --git a/tools/visual_debugger/frame.js b/tools/visual_debugger/frame.js index d9de672..b2d3d92 100644 --- a/tools/visual_debugger/frame.js +++ b/tools/visual_debugger/frame.js
@@ -80,6 +80,7 @@ if (json.new_sources) { for (const s of json.new_sources) { new Source(s); + notifyUiOfNewSource(s); } } @@ -217,16 +218,16 @@ const transformMatrix = context.getTransform(); context.resetTransform(); - context.fillStyle = 'black'; - context.font = "16px Courier bold"; + context.font = "16px 'Courier bold', monospace"; - const frameNumberPosX = 3; - const frameNumberPosY = 15; - this.drawText(context, - this.num_, - frameNumberPosX, - frameNumberPosY, - transformMatrix); + // Draw the frame number + { + context.textBaseline = "bottom"; + context.fillStyle = "black"; + var newTextPos = transformMatrix.transformPoint(new DOMPoint(0, 0)); + context.fillText(this.num_, newTextPos.x, newTextPos.y); + } + for (const text of this.drawTexts_) { // If thread not enabled, then skip text calls from this thread. @@ -263,6 +264,35 @@ drawText(context, text, posX, posY, transformMatrix) { // TODO: Set the text alignment based on the transform. var newTextPos = transformMatrix.transformPoint(new DOMPoint(posX, posY)); + + // Make the origin of text the top-left, similar to rectangles. + context.textBaseline = "top"; + + // Fill a background rectangle behind the text with the current fill color. + const measure = context.measureText(text); + context.fillRect( + newTextPos.x, + newTextPos.y, + measure.width, + measure.actualBoundingBoxDescent - measure.actualBoundingBoxAscent + ); + + function perceptualBrightness(hexColor) { + const r = parseInt(hexColor.substr(1, 2), 16) / 255; + const g = parseInt(hexColor.substr(3, 2), 16) / 255; + const b = parseInt(hexColor.substr(5, 2), 16) / 255; + return Math.sqrt( + 0.299 * Math.pow(r, 2) + 0.587 * Math.pow(g, 2) + 0.114 * Math.pow(b, 2) + ); + } + + // Attempt to make the text contrast better against the background. + if (perceptualBrightness(context.fillStyle) > 0.65) { + context.fillStyle = "black"; + } else { + context.fillStyle = "white"; + } + context.fillText(text, newTextPos.x, newTextPos.y); }
diff --git a/ui/accessibility/ax_tree.cc b/ui/accessibility/ax_tree.cc index 1f0bd1e7..fecee724 100644 --- a/ui/accessibility/ax_tree.cc +++ b/ui/accessibility/ax_tree.cc
@@ -2725,7 +2725,10 @@ return has_pagination_support_; } -void AXTree::NotifyTreeManagerWillBeRemoved() { +void AXTree::NotifyTreeManagerWillBeRemoved(AXTreeID previous_tree_id) { + if (previous_tree_id == AXTreeIDUnknown()) + return; + for (AXTreeObserver& observer : observers_) observer.OnTreeManagerWillBeRemoved(this); }
diff --git a/ui/accessibility/ax_tree.h b/ui/accessibility/ax_tree.h index 9023da5..085bf7e1 100644 --- a/ui/accessibility/ax_tree.h +++ b/ui/accessibility/ax_tree.h
@@ -250,9 +250,12 @@ // Event metadata while applying a tree update during unserialization. AXEvent* event_data() const { return event_data_.get(); } - // Notify the delegate that the tree manager for this AXTree will be removed - // from the AXTreeManagerMap. - void NotifyTreeManagerWillBeRemoved(); + // Notify the delegate that the tree manager for |previous_tree_id| will be + // removed from the AXTreeManagerMap. Because we sometimes remove the tree + // manager after the tree's id has been modified, we need to pass the (old) + // tree id associated with the manager we are removing even though it is the + // same tree. + void NotifyTreeManagerWillBeRemoved(AXTreeID previous_tree_id); private: friend class ScopedTreeUpdateInProgressStateSetter;
diff --git a/ui/accessibility/ax_tree_manager.cc b/ui/accessibility/ax_tree_manager.cc index e66437b..1c5bb8df 100644 --- a/ui/accessibility/ax_tree_manager.cc +++ b/ui/accessibility/ax_tree_manager.cc
@@ -149,7 +149,7 @@ void AXTreeManager::WillBeRemovedFromMap() { if (HasValidTreeID()) { - ax_tree_->NotifyTreeManagerWillBeRemoved(); + ax_tree_->NotifyTreeManagerWillBeRemoved(GetTreeID()); } }
diff --git a/ui/accessibility/ax_tree_manager_base.cc b/ui/accessibility/ax_tree_manager_base.cc index f0289f7..8b56fa2 100644 --- a/ui/accessibility/ax_tree_manager_base.cc +++ b/ui/accessibility/ax_tree_manager_base.cc
@@ -57,7 +57,7 @@ return; DCHECK_NE(GetTreeID().type(), ax::mojom::AXTreeIDType::kUnknown); - tree_->NotifyTreeManagerWillBeRemoved(); + tree_->NotifyTreeManagerWillBeRemoved(GetTreeID()); GetTreeManagerMapInstance().erase(GetTreeID()); } @@ -67,7 +67,7 @@ return; } - manager.tree_->NotifyTreeManagerWillBeRemoved(); + manager.tree_->NotifyTreeManagerWillBeRemoved(manager.GetTreeID()); GetTreeManagerMapInstance().erase(manager.GetTreeID()); SetTree(std::move(manager.tree_)); } @@ -77,7 +77,7 @@ return *this; if (manager.tree_) { - manager.tree_->NotifyTreeManagerWillBeRemoved(); + manager.tree_->NotifyTreeManagerWillBeRemoved(manager.GetTreeID()); GetTreeManagerMapInstance().erase(manager.GetTreeID()); SetTree(std::move(manager.tree_)); } else { @@ -105,7 +105,7 @@ } if (tree_) { - tree_->NotifyTreeManagerWillBeRemoved(); + tree_->NotifyTreeManagerWillBeRemoved(GetTreeID()); GetTreeManagerMapInstance().erase(GetTreeID()); } @@ -123,7 +123,7 @@ if (!tree_) return {}; - tree_->NotifyTreeManagerWillBeRemoved(); + tree_->NotifyTreeManagerWillBeRemoved(GetTreeID()); GetTreeManagerMapInstance().erase(GetTreeID()); return std::move(tree_); }
diff --git a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java index 05b7ffa5..4a7143c 100644 --- a/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java +++ b/ui/android/javatests/src/org/chromium/ui/base/ClipboardAndroidTest.java
@@ -24,6 +24,7 @@ import org.chromium.base.test.util.CallbackHelper; import org.chromium.base.test.util.Criteria; import org.chromium.base.test.util.CriteriaHelper; +import org.chromium.base.test.util.DisabledTest; import org.chromium.base.test.util.MinAndroidSdkLevel; import org.chromium.content_public.browser.test.NativeLibraryTestUtils; import org.chromium.content_public.browser.test.util.TestThreadUtils; @@ -71,6 +72,7 @@ */ @Test @SmallTest + @DisabledTest(message = "https://crbug.com/1413839") public void internalClipboardInvalidation() throws TimeoutException { // Write to the clipboard in native and ensure that is propagated to the platform clipboard. final String originalText = "foo";
diff --git a/ui/color/ui_color_mixer.cc b/ui/color/ui_color_mixer.cc index 96f5280..c8f49bd 100644 --- a/ui/color/ui_color_mixer.cc +++ b/ui/color/ui_color_mixer.cc
@@ -40,10 +40,7 @@ kColorSubtleEmphasisBackground}; mixer[kColorButtonBackgroundProminentFocused] = { kColorButtonBackgroundProminent}; - // TODO(crbug.com/1406633): Finalize button colors. - mixer[kColorButtonBackgroundTonal] = {dark_mode - ? SkColorSetRGB(0x00, 0x4A, 0x77) - : SkColorSetRGB(0xC2, 0xE7, 0xFF)}; + mixer[kColorButtonBackgroundTonal] = {kColorSysPrimaryContainer}; mixer[kColorButtonBackgroundTonalDisabled] = {kColorSubtleEmphasisBackground}; mixer[kColorButtonBackgroundTonalFocused] = {kColorButtonBackgroundTonal}; mixer[kColorButtonBorder] = {kColorMidground}; @@ -55,10 +52,7 @@ mixer[kColorButtonForegroundDisabled] = {kColorDisabledForeground}; mixer[kColorButtonForegroundProminent] = GetColorWithMaxContrast(kColorButtonBackgroundProminent); - // TODO(crbug.com/1406633): Finalize button colors. - mixer[kColorButtonForegroundTonal] = {dark_mode - ? SkColorSetRGB(0xC2, 0xE7, 0xFF) - : SkColorSetRGB(0x00, 0x1D, 0x35)}; + mixer[kColorButtonForegroundTonal] = {kColorSysOnPrimaryContainer}; mixer[kColorButtonForegroundUnchecked] = {kColorSecondaryForeground}; mixer[kColorCustomFrameCaptionForeground] = {SK_ColorWHITE}; mixer[kColorDebugBoundsOutline] = SetAlpha(SK_ColorRED, 0x30);
diff --git a/ui/file_manager/file_manager/foreground/js/actions_model.js b/ui/file_manager/file_manager/foreground/js/actions_model.js index 0f18adc..37fcacce 100644 --- a/ui/file_manager/file_manager/foreground/js/actions_model.js +++ b/ui/file_manager/file_manager/foreground/js/actions_model.js
@@ -820,7 +820,7 @@ // URLs. // TODO(b/237216270): Restrict to the ODFS extension ID. if (action.id === - constants.FSP_ACTION_HIDDEN_ODFS_URL) { + constants.FSP_ACTION_HIDDEN_ONEDRIVE_URL) { return; } actions[action.id] = new CustomAction(
diff --git a/ui/file_manager/file_manager/foreground/js/constants.js b/ui/file_manager/file_manager/foreground/js/constants.js index fa20f61..a02850d 100644 --- a/ui/file_manager/file_manager/foreground/js/constants.js +++ b/ui/file_manager/file_manager/foreground/js/constants.js
@@ -114,4 +114,4 @@ * URLs. * @const {string} */ -constants.FSP_ACTION_HIDDEN_ODFS_URL = 'HIDDEN_ODFS_URL'; +constants.FSP_ACTION_HIDDEN_ONEDRIVE_URL = 'HIDDEN_ONEDRIVE_URL';
diff --git a/ui/touch_selection/OWNERS b/ui/touch_selection/OWNERS deleted file mode 100644 index c65e542..0000000 --- a/ui/touch_selection/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -mohsen@chromium.org
diff --git a/ui/views/accessibility/ax_tree_source_views.cc b/ui/views/accessibility/ax_tree_source_views.cc index 31ef16bb..4b0d74f 100644 --- a/ui/views/accessibility/ax_tree_source_views.cc +++ b/ui/views/accessibility/ax_tree_source_views.cc
@@ -35,10 +35,7 @@ // In Views, we only support setting the selection within a single node, // not across multiple nodes like on the web. if (action.action == ax::mojom::Action::kSetSelection) { - if (action.anchor_node_id != action.focus_node_id) { - NOTREACHED(); - return; - } + CHECK_EQ(action.anchor_node_id, action.focus_node_id); id = action.anchor_node_id; }
diff --git a/ui/views/accessibility/ax_virtual_view.cc b/ui/views/accessibility/ax_virtual_view.cc index b18c0ec..41dfc00 100644 --- a/ui/views/accessibility/ax_virtual_view.cc +++ b/ui/views/accessibility/ax_virtual_view.cc
@@ -130,12 +130,10 @@ if (parent_view_) return parent_view_->RemoveVirtualChildView(this); - if (virtual_parent_view_) - return virtual_parent_view_->RemoveChildView(this); - // This virtual view hasn't been added to a parent view yet. - NOTREACHED() << "Cannot remove from parent view if there is no parent."; - return {}; + CHECK(virtual_parent_view_) + << "Cannot remove from parent view if there is no parent."; + return virtual_parent_view_->RemoveChildView(this); } std::unique_ptr<AXVirtualView> AXVirtualView::RemoveChildView( @@ -296,14 +294,12 @@ } } - NOTREACHED() << "|index| should be less than the child count."; - return nullptr; + NOTREACHED_NORETURN() << "|index| should be less than the child count."; } #if !BUILDFLAG(IS_MAC) gfx::NativeViewAccessible AXVirtualView::GetNSWindow() { - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } #endif
diff --git a/ui/views/accessibility/view_ax_platform_node_delegate.cc b/ui/views/accessibility/view_ax_platform_node_delegate.cc index 57349dfd..6719a3d 100644 --- a/ui/views/accessibility/view_ax_platform_node_delegate.cc +++ b/ui/views/accessibility/view_ax_platform_node_delegate.cc
@@ -385,8 +385,8 @@ } } - NOTREACHED() << "|index| should be less than the unignored child count."; - return nullptr; + NOTREACHED_NORETURN() + << "|index| should be less than the unignored child count."; } // Our widget might have child widgets. If this is a root view, include those @@ -424,11 +424,9 @@ } } - if (index < child_widgets_result.child_widgets.size()) - return child_widgets[index]->GetRootView()->GetNativeViewAccessible(); - - NOTREACHED() << "|index| should be less than the unignored child count."; - return nullptr; + CHECK_LT(index, child_widgets_result.child_widgets.size()) + << "|index| should be less than the unignored child count."; + return child_widgets[index]->GetRootView()->GetNativeViewAccessible(); } bool ViewAXPlatformNodeDelegate::HasModalDialog() const {
diff --git a/ui/views/accessibility/views_ax_tree_manager.cc b/ui/views/accessibility/views_ax_tree_manager.cc index 1c77f618..078d982 100644 --- a/ui/views/accessibility/views_ax_tree_manager.cc +++ b/ui/views/accessibility/views_ax_tree_manager.cc
@@ -130,12 +130,13 @@ continue; ui::AXTreeUpdate update; + // TODO(pbos): Consider rewriting this as a CHECK now that this is fatally + // aborting. if (!tree_serializer_.SerializeChanges(wrapper, &update)) { std::string error; ui::AXTreeSourceChecker<AXAuraObjWrapper*> checker(&tree_source_); checker.CheckAndGetErrorString(&error); - NOTREACHED() << error << '\n' << update.ToString(); - return; + NOTREACHED_NORETURN() << error << '\n' << update.ToString(); } updates.push_back(update); @@ -150,10 +151,7 @@ return; for (const ui::AXTreeUpdate& update : updates) { - if (!ax_tree_->Unserialize(update)) { - NOTREACHED() << ax_tree_->error(); - return; - } + CHECK(ax_tree_->Unserialize(update)) << ax_tree_->error(); } // Unserializing the updates into our AXTree should have prompted our
diff --git a/ui/views/animation/animation_sequence_block.cc b/ui/views/animation/animation_sequence_block.cc index 2ea113c..15eba44 100644 --- a/ui/views/animation/animation_sequence_block.cc +++ b/ui/views/animation/animation_sequence_block.cc
@@ -294,7 +294,7 @@ duration); break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } element->set_tween_type(pair.second.tween_type_); owner_->AddLayerAnimationElement(PassKey(), pair.first, start_, duration,
diff --git a/ui/views/animation/ink_drop_animation_ended_reason.cc b/ui/views/animation/ink_drop_animation_ended_reason.cc index d2bac5d..7a8219f8 100644 --- a/ui/views/animation/ink_drop_animation_ended_reason.cc +++ b/ui/views/animation/ink_drop_animation_ended_reason.cc
@@ -17,9 +17,7 @@ case InkDropAnimationEndedReason::PRE_EMPTED: return "PRE_EMPTED"; } - NOTREACHED() - << "Should never be reached but is necessary for some compilers."; - return std::string(); + NOTREACHED_NORETURN(); } } // namespace views
diff --git a/ui/views/animation/ink_drop_host_unittest.cc b/ui/views/animation/ink_drop_host_unittest.cc index 6b3db42..82e0e75 100644 --- a/ui/views/animation/ink_drop_host_unittest.cc +++ b/ui/views/animation/ink_drop_host_unittest.cc
@@ -286,8 +286,7 @@ public: BasicTestViewWithInkDrop() { InkDrop::Install(this, std::make_unique<InkDropHost>(this)); - // Call SetBaseColor to avoid hitting a NOTREACHED() for fetching an - // undefined color. + // Call SetBaseColor to avoid fetching an undefined color. InkDrop::Get(this)->SetBaseColor(gfx::kPlaceholderColor); } BasicTestViewWithInkDrop(const BasicTestViewWithInkDrop&) = delete;
diff --git a/ui/views/animation/ink_drop_impl.cc b/ui/views/animation/ink_drop_impl.cc index dc4eb28..1c290a2 100644 --- a/ui/views/animation/ink_drop_impl.cc +++ b/ui/views/animation/ink_drop_impl.cc
@@ -528,9 +528,7 @@ return std::make_unique<ShowHighlightOnRippleHiddenState>( this, base::TimeDelta()); } - // Required for some compilers. - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } std::unique_ptr<InkDropImpl::HighlightState> @@ -548,8 +546,7 @@ this, animation_duration); } // Required for some compilers. - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } std::unique_ptr<InkDropImpl::HighlightState> @@ -567,8 +564,7 @@ this, animation_duration); } // Required for some compilers. - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } InkDropImpl::InkDropImpl(InkDropHost* ink_drop_host,
diff --git a/ui/views/animation/ink_drop_state.cc b/ui/views/animation/ink_drop_state.cc index 903e1ee..36bba93 100644 --- a/ui/views/animation/ink_drop_state.cc +++ b/ui/views/animation/ink_drop_state.cc
@@ -28,9 +28,7 @@ case InkDropState::DEACTIVATED: return std::string("DEACTIVATED"); } - NOTREACHED() - << "Should never be reached but is necessary for some compilers."; - return std::string("UNKNOWN"); + NOTREACHED_NORETURN(); } } // namespace views
diff --git a/ui/views/animation/slide_out_controller.cc b/ui/views/animation/slide_out_controller.cc index dd8e539d..c4045ab 100644 --- a/ui/views/animation/slide_out_controller.cc +++ b/ui/views/animation/slide_out_controller.cc
@@ -84,7 +84,7 @@ gesture_amount_ = swipe_control_width_; break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } delegate_->OnSlideStarted(); } else if (event->type() == ui::ET_GESTURE_SCROLL_UPDATE) {
diff --git a/ui/views/animation/square_ink_drop_ripple.cc b/ui/views/animation/square_ink_drop_ripple.cc index b0afa28..227685f 100644 --- a/ui/views/animation/square_ink_drop_ripple.cc +++ b/ui/views/animation/square_ink_drop_ripple.cc
@@ -222,8 +222,8 @@ case VERTICAL_RECT: return "VERTICAL_RECT"; case PAINTED_SHAPE_COUNT: - NOTREACHED() << "The PAINTED_SHAPE_COUNT value should never be used."; - return "PAINTED_SHAPE_COUNT"; + NOTREACHED_NORETURN() + << "The PAINTED_SHAPE_COUNT value should never be used."; } return "UNKNOWN"; } @@ -563,8 +563,8 @@ delegate = rect_layer_delegate_.get(); break; case PAINTED_SHAPE_COUNT: - NOTREACHED() << "PAINTED_SHAPE_COUNT is not an actual shape type."; - break; + NOTREACHED_NORETURN() + << "PAINTED_SHAPE_COUNT is not an actual shape type."; } ui::Layer* layer = new ui::Layer();
diff --git a/ui/views/bubble/bubble_border_arrow_utils.cc b/ui/views/bubble/bubble_border_arrow_utils.cc index 7848d82..0638df9a 100644 --- a/ui/views/bubble/bubble_border_arrow_utils.cc +++ b/ui/views/bubble/bubble_border_arrow_utils.cc
@@ -46,8 +46,7 @@ return anchor_rect.left_center(); default: - NOTREACHED(); - return gfx::Point(); + NOTREACHED_NORETURN(); } } @@ -93,8 +92,7 @@ return anchor_point - contents_bounds.right_center(); default: - NOTREACHED(); - return gfx::Vector2d(); + NOTREACHED_NORETURN(); } }
diff --git a/ui/views/bubble/bubble_dialog_model_host.cc b/ui/views/bubble/bubble_dialog_model_host.cc index 9f1b9b7..8616a2f 100644 --- a/ui/views/bubble/bubble_dialog_model_host.cc +++ b/ui/views/bubble/bubble_dialog_model_host.cc
@@ -567,8 +567,7 @@ switch (field->type(GetPassKey())) { case ui::DialogModelField::kButton: // TODO(pbos): Add support for buttons that are part of content area. - NOTREACHED(); - return; + NOTREACHED_NORETURN(); case ui::DialogModelField::kParagraph: AddOrUpdateParagraph(field->AsParagraph(GetPassKey())); break; @@ -906,8 +905,7 @@ if (info.field_view == view) return info; } - NOTREACHED(); - return {}; + NOTREACHED_NORETURN(); } View* BubbleDialogModelHost::GetTargetView(
diff --git a/ui/views/controls/button/button.cc b/ui/views/controls/button/button.cc index 92f676c2..d17b95a 100644 --- a/ui/views/controls/button/button.cc +++ b/ui/views/controls/button/button.cc
@@ -151,7 +151,7 @@ case ui::NativeTheme::kPressed: return Button::STATE_PRESSED; case ui::NativeTheme::kNumStates: - NOTREACHED(); + NOTREACHED_NORETURN(); } return Button::STATE_NORMAL; }
diff --git a/ui/views/controls/button/button_controller.cc b/ui/views/controls/button/button_controller.cc index 18f21a0..b27d698 100644 --- a/ui/views/controls/button/button_controller.cc +++ b/ui/views/controls/button/button_controller.cc
@@ -100,8 +100,7 @@ return false; } - NOTREACHED(); - return false; + NOTREACHED_NORETURN(); } bool ButtonController::OnKeyReleased(const ui::KeyEvent& event) {
diff --git a/ui/views/controls/button/label_button.cc b/ui/views/controls/button/label_button.cc index 98b0f831..749cb84bd 100644 --- a/ui/views/controls/button/label_button.cc +++ b/ui/views/controls/button/label_button.cc
@@ -428,7 +428,7 @@ case STATE_DISABLED: return ui::NativeTheme::kDisabled; case STATE_COUNT: - NOTREACHED(); + NOTREACHED_NORETURN(); } return ui::NativeTheme::kNormal; }
diff --git a/ui/views/controls/combobox/combobox_unittest.cc b/ui/views/controls/combobox/combobox_unittest.cc index 34c0220..83db162 100644 --- a/ui/views/controls/combobox/combobox_unittest.cc +++ b/ui/views/controls/combobox/combobox_unittest.cc
@@ -78,8 +78,7 @@ if (separators_.find(index) == separators_.end()) return index; } - NOTREACHED(); - return 0; + NOTREACHED_NORETURN(); } void SetSeparators(const std::set<size_t>& separators) {
diff --git a/ui/views/controls/combobox/empty_combobox_model.cc b/ui/views/controls/combobox/empty_combobox_model.cc index 5597bb4..f34bd125 100644 --- a/ui/views/controls/combobox/empty_combobox_model.cc +++ b/ui/views/controls/combobox/empty_combobox_model.cc
@@ -18,8 +18,7 @@ } std::u16string EmptyComboboxModel::GetItemAt(size_t index) const { - NOTREACHED(); - return std::u16string(); + NOTREACHED_NORETURN(); } absl::optional<size_t> EmptyComboboxModel::GetDefaultIndex() const {
diff --git a/ui/views/controls/focus_ring.cc b/ui/views/controls/focus_ring.cc index cc8d096f..d3cfc17 100644 --- a/ui/views/controls/focus_ring.cc +++ b/ui/views/controls/focus_ring.cc
@@ -274,11 +274,8 @@ return SkRRect::MakeOval(gfx::RectFToSkRect(rect)); } - if (path.isRRect(&rbounds)) - return RingRectFromPathRect(rbounds); - - NOTREACHED(); - return SkRRect(); + CHECK(path.isRRect(&rbounds)); + return RingRectFromPathRect(rbounds); } void FocusRing::GetAccessibleNodeData(ui::AXNodeData* node_data) {
diff --git a/ui/views/controls/label.cc b/ui/views/controls/label.cc index 7f8df43..cc97944 100644 --- a/ui/views/controls/label.cc +++ b/ui/views/controls/label.cc
@@ -1034,7 +1034,7 @@ } void Label::SetTextBeingDragged(bool value) { - NOTREACHED(); + NOTREACHED_NORETURN(); } int Label::GetViewHeight() const { @@ -1062,8 +1062,7 @@ } bool Label::PasteSelectionClipboard() { - NOTREACHED(); - return false; + NOTREACHED_NORETURN(); } void Label::UpdateSelectionClipboard() { @@ -1101,7 +1100,7 @@ UpdateSelectionClipboard(); break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } }
diff --git a/ui/views/controls/menu/menu_closure_animation_mac.mm b/ui/views/controls/menu/menu_closure_animation_mac.mm index 0e33b00..7326c15 100644 --- a/ui/views/controls/menu/menu_closure_animation_mac.mm +++ b/ui/views/controls/menu/menu_closure_animation_mac.mm
@@ -105,7 +105,7 @@ void MenuClosureAnimationMac::AnimationCanceled( const gfx::Animation* animation) { - NOTREACHED(); + NOTREACHED_NORETURN(); } } // namespace views
diff --git a/ui/views/controls/menu/menu_controller.cc b/ui/views/controls/menu/menu_controller.cc index 64229eee..2309794 100644 --- a/ui/views/controls/menu/menu_controller.cc +++ b/ui/views/controls/menu/menu_controller.cc
@@ -1846,11 +1846,8 @@ delegate_->SiblingMenuCreated(alt_menu); - if (!button) { - // If the delegate returns a menu, they must also return a button. - NOTREACHED(); - return false; - } + // If the delegate returns a menu, they must also return a button. + CHECK(button); // There is a sibling menu, update the button state, hide the current menu // and show the new one.
diff --git a/ui/views/controls/menu/menu_delegate.cc b/ui/views/controls/menu/menu_delegate.cc index 5ddb15a..1526ce13 100644 --- a/ui/views/controls/menu/menu_delegate.cc +++ b/ui/views/controls/menu/menu_delegate.cc
@@ -103,16 +103,16 @@ MenuItemView* item, const ui::DropTargetEvent& event, DropPosition* position) { - NOTREACHED() << "If you override CanDrop, you need to override this too"; - return ui::mojom::DragOperation::kNone; + NOTREACHED_NORETURN() + << "If you override CanDrop, you must override this too"; } views::View::DropCallback MenuDelegate::GetDropCallback( MenuItemView* menu, DropPosition position, const ui::DropTargetEvent& event) { - NOTREACHED() << "If you override CanDrop, you need to override this too"; - return base::NullCallback(); + NOTREACHED_NORETURN() + << "If you override CanDrop, you must override this too"; } bool MenuDelegate::CanDrag(MenuItemView* menu) { @@ -120,12 +120,13 @@ } void MenuDelegate::WriteDragData(MenuItemView* sender, OSExchangeData* data) { - NOTREACHED() << "If you override CanDrag, you must override this too."; + NOTREACHED_NORETURN() + << "If you override CanDrag, you must override this too."; } int MenuDelegate::GetDragOperations(MenuItemView* sender) { - NOTREACHED() << "If you override CanDrag, you must override this too."; - return 0; + NOTREACHED_NORETURN() + << "If you override CanDrag, you must override this too."; } bool MenuDelegate::ShouldCloseOnDragComplete() {
diff --git a/ui/views/controls/menu/menu_model_adapter.cc b/ui/views/controls/menu/menu_model_adapter.cc index 944a82d..daf9fff 100644 --- a/ui/views/controls/menu/menu_model_adapter.cc +++ b/ui/views/controls/menu/menu_model_adapter.cc
@@ -153,23 +153,15 @@ void MenuModelAdapter::ExecuteCommand(int id) { ui::MenuModel* model = menu_model_; size_t index = 0; - if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) { - model->ActivatedAt(index); - return; - } - - NOTREACHED(); + CHECK(ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)); + model->ActivatedAt(index); } void MenuModelAdapter::ExecuteCommand(int id, int mouse_event_flags) { ui::MenuModel* model = menu_model_; size_t index = 0; - if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) { - model->ActivatedAt(index, mouse_event_flags); - return; - } - - NOTREACHED(); + CHECK(ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)); + model->ActivatedAt(index, mouse_event_flags); } bool MenuModelAdapter::IsTriggerableEvent(MenuItemView* source, @@ -183,21 +175,15 @@ ui::Accelerator* accelerator) const { ui::MenuModel* model = menu_model_; size_t index = 0; - if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) - return model->GetAcceleratorAt(index, accelerator); - - NOTREACHED(); - return false; + CHECK(ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)); + return model->GetAcceleratorAt(index, accelerator); } std::u16string MenuModelAdapter::GetLabel(int id) const { ui::MenuModel* model = menu_model_; size_t index = 0; - if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) - return model->GetLabelAt(index); - - NOTREACHED(); - return std::u16string(); + CHECK(ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)); + return model->GetLabelAt(index); } const gfx::FontList* MenuModelAdapter::GetLabelFontList(int id) const { @@ -216,55 +202,38 @@ bool MenuModelAdapter::IsCommandEnabled(int id) const { ui::MenuModel* model = menu_model_; size_t index = 0; - if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) - return model->IsEnabledAt(index); - - NOTREACHED(); - return false; + CHECK(ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)); + return model->IsEnabledAt(index); } bool MenuModelAdapter::IsCommandVisible(int id) const { ui::MenuModel* model = menu_model_; size_t index = 0; - if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) - return model->IsVisibleAt(index); - - NOTREACHED(); - return false; + CHECK(ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)); + return model->IsVisibleAt(index); } bool MenuModelAdapter::IsItemChecked(int id) const { ui::MenuModel* model = menu_model_; size_t index = 0; - if (ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)) - return model->IsItemCheckedAt(index); - - NOTREACHED(); - return false; + CHECK(ui::MenuModel::GetModelAndIndexForCommandId(id, &model, &index)); + return model->IsItemCheckedAt(index); } void MenuModelAdapter::WillShowMenu(MenuItemView* menu) { // Look up the menu model for this menu. const std::map<MenuItemView*, ui::MenuModel*>::const_iterator map_iterator = menu_map_.find(menu); - if (map_iterator != menu_map_.end()) { - map_iterator->second->MenuWillShow(); - return; - } - - NOTREACHED(); + CHECK(map_iterator != menu_map_.end()); + map_iterator->second->MenuWillShow(); } void MenuModelAdapter::WillHideMenu(MenuItemView* menu) { // Look up the menu model for this menu. const std::map<MenuItemView*, ui::MenuModel*>::const_iterator map_iterator = menu_map_.find(menu); - if (map_iterator != menu_map_.end()) { - map_iterator->second->MenuWillClose(); - return; - } - - NOTREACHED(); + CHECK(map_iterator != menu_map_.end()); + map_iterator->second->MenuWillClose(); } void MenuModelAdapter::OnMenuClosed(MenuItemView* menu) {
diff --git a/ui/views/controls/menu/menu_runner_impl_cocoa.mm b/ui/views/controls/menu/menu_runner_impl_cocoa.mm index 1319c56..5f8fdc6 100644 --- a/ui/views/controls/menu/menu_runner_impl_cocoa.mm +++ b/ui/views/controls/menu/menu_runner_impl_cocoa.mm
@@ -218,8 +218,9 @@ ui::ElementTrackerMac::GetInstance()->NotifyMenuDoneShowing(menu); - } else if (run_types & MenuRunner::COMBOBOX) { - NSMenuItem* checked_item = FirstCheckedItem(menu_controller_); + } else { + CHECK(run_types & MenuRunner::COMBOBOX); + NSMenuItem* const checked_item = FirstCheckedItem(menu_controller_); base::scoped_nsobject<NSView> anchor_view(CreateMenuAnchorView( window, bounds, checked_item, menu.size.width, anchor)); [menu setMinimumWidth:bounds.width() + kNativeCheckmarkWidth]; @@ -228,8 +229,6 @@ inView:anchor_view]; [anchor_view removeFromSuperview]; - } else { - NOTREACHED(); } closing_event_time_ = ui::EventTimeForNow();
diff --git a/ui/views/controls/scroll_view.cc b/ui/views/controls/scroll_view.cc index 844a9ed..72df09a 100644 --- a/ui/views/controls/scroll_view.cc +++ b/ui/views/controls/scroll_view.cc
@@ -515,8 +515,7 @@ more_content_bottom_thickness_ = thickness; break; default: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } UpdateOverflowIndicatorVisibility(CurrentOffset());
diff --git a/ui/views/controls/scroll_view_unittest.cc b/ui/views/controls/scroll_view_unittest.cc index 51c8b75..318ef77 100644 --- a/ui/views/controls/scroll_view_unittest.cc +++ b/ui/views/controls/scroll_view_unittest.cc
@@ -497,8 +497,7 @@ case UiConfig::kRtlWithLayers: return "RTL_LAYERS"; } - NOTREACHED(); - return std::string(); + NOTREACHED_NORETURN(); } // Verifies the viewport is sized to fit the available space.
diff --git a/ui/views/controls/scrollbar/scroll_bar_button.cc b/ui/views/controls/scrollbar/scroll_bar_button.cc index 7fd39c3..68d4d77 100644 --- a/ui/views/controls/scrollbar/scroll_bar_button.cc +++ b/ui/views/controls/scrollbar/scroll_bar_button.cc
@@ -83,8 +83,7 @@ return ui::NativeTheme::kScrollbarRightArrow; } - NOTREACHED(); - return ui::NativeTheme::kScrollbarUpArrow; + NOTREACHED_NORETURN(); } ui::NativeTheme::State ScrollBarButton::GetNativeThemeState() const { @@ -101,8 +100,7 @@ break; } - NOTREACHED(); - return ui::NativeTheme::kNormal; + NOTREACHED_NORETURN(); } void ScrollBarButton::RepeaterNotifyClick() {
diff --git a/ui/views/controls/scrollbar/scroll_bar_views.cc b/ui/views/controls/scrollbar/scroll_bar_views.cc index 9693fcf..862122a 100644 --- a/ui/views/controls/scrollbar/scroll_bar_views.cc +++ b/ui/views/controls/scrollbar/scroll_bar_views.cc
@@ -101,11 +101,8 @@ case Button::STATE_NORMAL: return ui::NativeTheme::kNormal; case Button::STATE_COUNT: - break; + NOTREACHED_NORETURN(); } - - NOTREACHED(); - return ui::NativeTheme::kNormal; } } // namespace
diff --git a/ui/views/controls/slider_unittest.cc b/ui/views/controls/slider_unittest.cc index 677e986..8375a29e 100644 --- a/ui/views/controls/slider_unittest.cc +++ b/ui/views/controls/slider_unittest.cc
@@ -202,7 +202,7 @@ slider->SetAllowedValues(&values_); break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } gfx::Size size = slider->GetPreferredSize(); slider->SetSize(size);
diff --git a/ui/views/controls/table/table_utils.cc b/ui/views/controls/table/table_utils.cc index 126b9c1..673494b 100644 --- a/ui/views/controls/table/table_utils.cc +++ b/ui/views/controls/table/table_utils.cc
@@ -107,8 +107,7 @@ case ui::TableColumn::RIGHT: return gfx::Canvas::TEXT_ALIGN_RIGHT; } - NOTREACHED(); - return gfx::Canvas::TEXT_ALIGN_LEFT; + NOTREACHED_NORETURN(); } absl::optional<size_t> GetClosestVisibleColumnIndex(const TableView* table,
diff --git a/ui/views/controls/table/table_view.cc b/ui/views/controls/table/table_view.cc index bacd5f35..2bd3615 100644 --- a/ui/views/controls/table/table_view.cc +++ b/ui/views/controls/table/table_view.cc
@@ -1845,23 +1845,19 @@ DCHECK_LT(row, GetRowCount()); if (header_) ++row; - if (row < GetViewAccessibility().virtual_children().size()) { - const auto& ax_row = GetViewAccessibility().virtual_children()[row]; - DCHECK(ax_row); - DCHECK_EQ(ax_row->GetData().role, ax::mojom::Role::kRow); - return ax_row.get(); - } - NOTREACHED() << "|row| not found. Did you forget to call " - "RebuildVirtualAccessibilityChildren()?"; - return nullptr; + CHECK_LT(row, GetViewAccessibility().virtual_children().size()) + << "|row| not found. Did you forget to call " + "RebuildVirtualAccessibilityChildren()?"; + + const auto& ax_row = GetViewAccessibility().virtual_children()[row]; + DCHECK(ax_row); + DCHECK_EQ(ax_row->GetData().role, ax::mojom::Role::kRow); + return ax_row.get(); } AXVirtualView* TableView::GetVirtualAccessibilityHeaderRow() { - if (!header_) { - NOTREACHED() << "|row| not found. Did you forget to call " + CHECK(header_) << "|row| not found. Did you forget to call " "RebuildVirtualAccessibilityChildren()?"; - return nullptr; - } // The header row is always the first virtual child. const auto& ax_row = GetViewAccessibility().virtual_children()[size_t{0}]; DCHECK(ax_row);
diff --git a/ui/views/controls/textfield/textfield.cc b/ui/views/controls/textfield/textfield.cc index 98753af10..691fd6f8 100644 --- a/ui/views/controls/textfield/textfield.cc +++ b/ui/views/controls/textfield/textfield.cc
@@ -1770,8 +1770,7 @@ case ui::TextEditCommand::INVALID_COMMAND: return false; } - NOTREACHED(); - return false; + NOTREACHED_NORETURN(); } void Textfield::SetTextEditCommandForNextKeyEvent(ui::TextEditCommand command) { @@ -2135,8 +2134,7 @@ case ui::TextEditCommand::SET_MARK: case ui::TextEditCommand::UNSELECT: case ui::TextEditCommand::INVALID_COMMAND: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } return {changed, cursor_changed};
diff --git a/ui/views/controls/webview/unhandled_keyboard_event_handler.cc b/ui/views/controls/webview/unhandled_keyboard_event_handler.cc index 3645af6..e520615 100644 --- a/ui/views/controls/webview/unhandled_keyboard_event_handler.cc +++ b/ui/views/controls/webview/unhandled_keyboard_event_handler.cc
@@ -17,10 +17,8 @@ bool UnhandledKeyboardEventHandler::HandleKeyboardEvent( const content::NativeWebKeyboardEvent& event, FocusManager* focus_manager) { - if (!focus_manager) { - NOTREACHED(); - return false; - } + CHECK(focus_manager); + // Previous calls to TranslateMessage can generate Char events as well as // RawKeyDown events, even if the latter triggered an accelerator. In these // cases, we discard the Char events.
diff --git a/ui/views/controls/webview/web_dialog_view.cc b/ui/views/controls/webview/web_dialog_view.cc index a4e4703..af075e8 100644 --- a/ui/views/controls/webview/web_dialog_view.cc +++ b/ui/views/controls/webview/web_dialog_view.cc
@@ -230,8 +230,7 @@ case WebDialogDelegate::FrameKind::kDialog: return DialogDelegate::CreateDialogFrameView(widget); default: - NOTREACHED() << "Unknown frame kind type enum specified."; - return std::unique_ptr<NonClientFrameView>{}; + NOTREACHED_NORETURN() << "Unknown frame kind type enum specified."; } }
diff --git a/ui/views/corewm/tooltip_controller.cc b/ui/views/corewm/tooltip_controller.cc index 3ed8c373..b414937 100644 --- a/ui/views/corewm/tooltip_controller.cc +++ b/ui/views/corewm/tooltip_controller.cc
@@ -124,10 +124,8 @@ return screen_target; } default: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } - return nullptr; } } // namespace
diff --git a/ui/views/examples/examples_with_content_main.cc b/ui/views/examples/examples_with_content_main.cc index 7d4edc7..5a77472 100644 --- a/ui/views/examples/examples_with_content_main.cc +++ b/ui/views/examples/examples_with_content_main.cc
@@ -52,7 +52,7 @@ // sandbox::InitLibcUrandomOverrides(). See http://crbug.com/374712. if (!browser_context) { browser_context->SaveSessionState(); - NOTREACHED(); + NOTREACHED_NORETURN(); } }
diff --git a/ui/views/examples/tree_view_example.cc b/ui/views/examples/tree_view_example.cc index 9d64a83..ea27079 100644 --- a/ui/views/examples/tree_view_example.cc +++ b/ui/views/examples/tree_view_example.cc
@@ -218,7 +218,7 @@ AddNewNode(); break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } }
diff --git a/ui/views/interaction/element_tracker_views.cc b/ui/views/interaction/element_tracker_views.cc index b475bff7..5d4ab359 100644 --- a/ui/views/interaction/element_tracker_views.cc +++ b/ui/views/interaction/element_tracker_views.cc
@@ -208,19 +208,16 @@ data.element.get()); data.element.reset(); } else if (visible && old_context != data.context) { - if (update_reason == UpdateReason::kVisbilityFromRoot) { - // This can happen in some tests where a widget is closed before it - // actually becomes visible, or a parent widget is closed underneath us. - if (!view->GetWidget()->IsVisible()) { - ui::ElementTracker::GetFrameworkDelegate()->NotifyElementHidden( - data.element.get()); - data.element.reset(); - } - } else { - NOTREACHED() - << "We should always get a removed-from-widget notification before " - "an added-to-widget notification, the context should never " - "change while a view is visible."; + CHECK(update_reason == UpdateReason::kVisbilityFromRoot) + << "We should always get a removed-from-widget notification before " + "an added-to-widget notification, the context should never " + "change while a view is visible."; + // This can happen in some tests where a widget is closed before it + // actually becomes visible, or a parent widget is closed underneath us. + if (!view->GetWidget()->IsVisible()) { + ui::ElementTracker::GetFrameworkDelegate()->NotifyElementHidden( + data.element.get()); + data.element.reset(); } } }
diff --git a/ui/views/interaction/interaction_test_util_views.cc b/ui/views/interaction/interaction_test_util_views.cc index 6edffea1..fcf1393 100644 --- a/ui/views/interaction/interaction_test_util_views.cc +++ b/ui/views/interaction/interaction_test_util_views.cc
@@ -99,9 +99,7 @@ private: // WidgetObserver: void OnWidgetDestroyed(Widget* widget) override { - widget_observation_.Reset(); - run_loop_.Quit(); - NOTREACHED() << "Widget destroyed before observation."; + NOTREACHED_NORETURN() << "Widget destroyed before observation."; } void OnWidgetActivationChanged(Widget* widget, bool active) override { if (!active) { @@ -209,8 +207,7 @@ LOG(ERROR) << "Unable to select dropdown menu item."; break; case ui::test::ActionResult::kNotAttempted: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); case ui::test::ActionResult::kKnownIncompatible: LOG(WARNING) << "Select dropdown item not available on this platform with "
diff --git a/ui/views/layout/animating_layout_manager.cc b/ui/views/layout/animating_layout_manager.cc index 32c5b365..1e2a309 100644 --- a/ui/views/layout/animating_layout_manager.cc +++ b/ui/views/layout/animating_layout_manager.cc
@@ -500,8 +500,7 @@ const SizeBounds& size_bounds) const { // This class directly overrides Layout() so GetProposedLayout() and // CalculateProposedLayout() are not called. - NOTREACHED(); - return ProposedLayout(); + NOTREACHED_NORETURN(); } void AnimatingLayoutManager::OnInstalled(View* host) { @@ -757,8 +756,7 @@ child_layout.visible = false; break; case LayoutFadeType::kContinuingFade: - NOTREACHED(); - continue; + NOTREACHED_NORETURN(); } } else if (default_fade_mode_ == FadeInOutMode::kHide) { child_layout.child_view = fade_info.child_view; @@ -770,8 +768,7 @@ switch (default_fade_mode_) { case FadeInOutMode::kHide: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); case FadeInOutMode::kScaleFromMinimum: child_layout = CalculateScaleFade(fade_info, scale_percent, /* scale_from_zero */ false); @@ -1007,8 +1004,7 @@ new_bounds.set_origin_main(trailing_reference_point - new_size); break; case LayoutFadeType::kContinuingFade: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } new_bounds.set_size_main(new_size); child_layout.bounds = Denormalize(orientation(), new_bounds); @@ -1043,8 +1039,7 @@ fully_faded_layout = &target_layout_; break; case LayoutFadeType::kContinuingFade: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } if (slide_from_leading) {
diff --git a/ui/views/layout/box_layout.cc b/ui/views/layout/box_layout.cc index ddab6c0..1d0c1c7 100644 --- a/ui/views/layout/box_layout.cc +++ b/ui/views/layout/box_layout.cc
@@ -198,8 +198,7 @@ size = total_main_axis_size; break; default: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } } gfx::Rect new_child_area(child_area);
diff --git a/ui/views/layout/layout_provider.cc b/ui/views/layout/layout_provider.cc index 349bce94..8b958eb 100644 --- a/ui/views/layout/layout_provider.cc +++ b/ui/views/layout/layout_provider.cc
@@ -68,8 +68,7 @@ case InsetsMetric::INSETS_LABEL_BUTTON: return gfx::Insets::VH(5, 6); } - NOTREACHED(); - return gfx::Insets(); + NOTREACHED_NORETURN(); } int LayoutProvider::GetDistanceMetric(int metric) const { @@ -122,11 +121,9 @@ return 16; case VIEWS_DISTANCE_END: case VIEWS_DISTANCE_MAX: - NOTREACHED(); - return 0; + NOTREACHED_NORETURN(); } - NOTREACHED(); - return 0; + NOTREACHED_NORETURN(); } const TypographyProvider& LayoutProvider::GetTypographyProvider() const {
diff --git a/ui/views/layout/table_layout.cc b/ui/views/layout/table_layout.cc index ae6dda41..cf147c6 100644 --- a/ui/views/layout/table_layout.cc +++ b/ui/views/layout/table_layout.cc
@@ -144,7 +144,7 @@ *location = *location + available_size - *size; break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } } } @@ -449,11 +449,9 @@ break; col = 0; } - if (row == rows_.size()) { - NOTREACHED() << "There're not enough cells for layout. Did you forget to " - "call AddRows()?"; - break; - } + CHECK_LT(row, rows_.size()) + << "There're not enough cells for layout. Did you forget to " + "call AddRows()?"; // Construct a ViewState for this `child`. const gfx::Size* span = child->GetProperty(kTableColAndRowSpanKey);
diff --git a/ui/views/mouse_watcher.cc b/ui/views/mouse_watcher.cc index a074b53..1c255cefa 100644 --- a/ui/views/mouse_watcher.cc +++ b/ui/views/mouse_watcher.cc
@@ -53,8 +53,7 @@ HandleMouseEvent(EventType::kPress); break; default: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } }
diff --git a/ui/views/selection_controller.cc b/ui/views/selection_controller.cc index a36cbd5..61ba0ce 100644 --- a/ui/views/selection_controller.cc +++ b/ui/views/selection_controller.cc
@@ -70,7 +70,7 @@ SelectAll(); break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } }
diff --git a/ui/views/test/event_generator_delegate_mac.mm b/ui/views/test/event_generator_delegate_mac.mm index e7be1cc2..c9b9903 100644 --- a/ui/views/test/event_generator_delegate_mac.mm +++ b/ui/views/test/event_generator_delegate_mac.mm
@@ -114,8 +114,7 @@ case ui::ET_SCROLL_FLING_START: return NSEventTypeSwipe; default: - NOTREACHED(); - return NSEventTypeApplicationDefined; + NOTREACHED_NORETURN(); } } @@ -183,15 +182,13 @@ // for the generator to handle entered/exited separately. It's the // responsibility of views::internal::RootView to convert the moved events // into entered and exited events for the individual views. - NOTREACHED(); - break; + NOTREACHED_NORETURN(); case NSEventTypeSwipe: // NSEventTypeSwipe events can't be generated using public interfaces on // NSEvent, so this will need to be handled at a higher level. - NOTREACHED(); - break; + NOTREACHED_NORETURN(); default: - NOTREACHED(); + NOTREACHED_NORETURN(); } } @@ -479,7 +476,7 @@ } void EventGeneratorDelegateMac::OnTouchEvent(ui::TouchEvent* event) { - NOTREACHED() << "Touchscreen events not supported on Chrome Mac."; + NOTREACHED_NORETURN() << "Touchscreen events not supported on Chrome Mac."; } void EventGeneratorDelegateMac::OnScrollEvent(ui::ScrollEvent* event) {
diff --git a/ui/views/test/views_test_base.cc b/ui/views/test/views_test_base.cc index 6884f500..7929750 100644 --- a/ui/views/test/views_test_base.cc +++ b/ui/views/test/views_test_base.cc
@@ -186,8 +186,7 @@ return new test::TestPlatformNativeWidget<NativeWidgetAura>(delegate, true, nullptr); #else - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); #endif }
diff --git a/ui/views/test/widget_test_aura.cc b/ui/views/test/widget_test_aura.cc index 10ad006..4fec98408 100644 --- a/ui/views/test/widget_test_aura.cc +++ b/ui/views/test/widget_test_aura.cc
@@ -125,9 +125,9 @@ // of lacros-chrome is complete. #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS) return widget->GetNativeWindow()->delegate()->GetMinimumSize(); +#else + NOTREACHED_NORETURN(); #endif - NOTREACHED(); - return gfx::Size(); } // static
diff --git a/ui/views/touchui/OWNERS b/ui/views/touchui/OWNERS deleted file mode 100644 index c65e542..0000000 --- a/ui/views/touchui/OWNERS +++ /dev/null
@@ -1 +0,0 @@ -mohsen@chromium.org
diff --git a/ui/views/touchui/touch_selection_controller_impl.cc b/ui/views/touchui/touch_selection_controller_impl.cc index 7281f69..6df3c8a 100644 --- a/ui/views/touchui/touch_selection_controller_impl.cc +++ b/ui/views/touchui/touch_selection_controller_impl.cc
@@ -111,8 +111,8 @@ case gfx::SelectionBound::RIGHT: return GetRightHandleImage(); default: - NOTREACHED() << "Invalid touch handle bound type: " << bound_type; - return nullptr; + NOTREACHED_NORETURN() + << "Invalid touch handle bound type: " << bound_type; } } @@ -141,8 +141,7 @@ widget_left = bound.edge_start_rounded().x() - widget_width / 2; break; default: - NOTREACHED() << "Undefined bound type."; - break; + NOTREACHED_NORETURN() << "Undefined bound type."; } return gfx::Rect(widget_left, bound.edge_start_rounded().y(), widget_width, widget_height);
diff --git a/ui/views/touchui/touch_selection_controller_impl_unittest.cc b/ui/views/touchui/touch_selection_controller_impl_unittest.cc index 77d3b78..cf570121 100644 --- a/ui/views/touchui/touch_selection_controller_impl_unittest.cc +++ b/ui/views/touchui/touch_selection_controller_impl_unittest.cc
@@ -668,13 +668,13 @@ private: // Overridden from ui::TouchEditable. - void MoveCaret(const gfx::Point& position) override { NOTREACHED(); } + void MoveCaret(const gfx::Point& position) override { NOTREACHED_NORETURN(); } void MoveRangeSelectionExtent(const gfx::Point& extent) override { - NOTREACHED(); + NOTREACHED_NORETURN(); } void SelectBetweenCoordinates(const gfx::Point& base, const gfx::Point& extent) override { - NOTREACHED(); + NOTREACHED_NORETURN(); } void GetSelectionEndPoints(gfx::SelectionBound* anchor, gfx::SelectionBound* focus) override { @@ -695,20 +695,20 @@ screen_position_client->ConvertPointFromScreen(window_, point); } bool DrawsHandles() override { return false; } - void OpenContextMenu(const gfx::Point& anchor) override { NOTREACHED(); } - void DestroyTouchSelection() override { NOTREACHED(); } + void OpenContextMenu(const gfx::Point& anchor) override { + NOTREACHED_NORETURN(); + } + void DestroyTouchSelection() override { NOTREACHED_NORETURN(); } // Overridden from ui::SimpleMenuModel::Delegate. bool IsCommandIdChecked(int command_id) const override { - NOTREACHED(); - return false; + NOTREACHED_NORETURN(); } bool IsCommandIdEnabled(int command_id) const override { - NOTREACHED(); - return false; + NOTREACHED_NORETURN(); } void ExecuteCommand(int command_id, int event_flags) override { - NOTREACHED(); + NOTREACHED_NORETURN(); } raw_ptr<aura::Window> window_;
diff --git a/ui/views/view.cc b/ui/views/view.cc index fa4bcc83c..332e15a 100644 --- a/ui/views/view.cc +++ b/ui/views/view.cc
@@ -1532,7 +1532,7 @@ void View::OnScrollEvent(ui::ScrollEvent* event) {} void View::OnTouchEvent(ui::TouchEvent* event) { - NOTREACHED() << "Views should not receive touch events."; + NOTREACHED_NORETURN() << "Views should not receive touch events."; } void View::OnGestureEvent(ui::GestureEvent* event) {} @@ -1616,16 +1616,10 @@ } void View::RemoveAccelerator(const ui::Accelerator& accelerator) { - if (!accelerators_) { - NOTREACHED() << "Removing non-existing accelerator"; - return; - } + CHECK(accelerators_) << "Removing non-existent accelerator"; auto i(base::ranges::find(*accelerators_, accelerator)); - if (i == accelerators_->end()) { - NOTREACHED() << "Removing non-existing accelerator"; - return; - } + CHECK(i != accelerators_->end()) << "Removing non-existent accelerator"; auto index = static_cast<size_t>(i - accelerators_->begin()); accelerators_->erase(i); @@ -3204,13 +3198,7 @@ } accelerator_focus_manager_ = GetFocusManager(); - if (!accelerator_focus_manager_) { - // Some crash reports seem to show that we may get cases where we have no - // focus manager (see bug #1291225). This should never be the case, just - // making sure we don't crash. - NOTREACHED(); - return; - } + CHECK(accelerator_focus_manager_); for (std::vector<ui::Accelerator>::const_iterator i = accelerators_->begin() + static_cast<ptrdiff_t>(registered_accelerator_count_);
diff --git a/ui/views/view_targeter.cc b/ui/views/view_targeter.cc index 6f0589a..f92a1bb 100644 --- a/ui/views/view_targeter.cc +++ b/ui/views/view_targeter.cc
@@ -29,7 +29,7 @@ ui::EventTarget* ViewTargeter::FindTargetForEvent(ui::EventTarget* root, ui::Event* event) { - View* view = static_cast<View*>(root); + View* const view = static_cast<View*>(root); if (event->IsKeyEvent()) return FindTargetForKeyEvent(view, *event->AsKeyEvent()); @@ -37,15 +37,13 @@ if (event->IsScrollEvent()) return FindTargetForScrollEvent(view, *event->AsScrollEvent()); - if (event->IsGestureEvent()) { - ui::GestureEvent* gesture = event->AsGestureEvent(); - View* gesture_target = FindTargetForGestureEvent(view, *gesture); - root->ConvertEventToTarget(gesture_target, gesture); - return gesture_target; - } + CHECK(event->IsGestureEvent()) + << "ViewTargeter does not yet support this event type."; - NOTREACHED() << "ViewTargeter does not yet support this event type."; - return nullptr; + ui::GestureEvent* gesture = event->AsGestureEvent(); + View* gesture_target = FindTargetForGestureEvent(view, *gesture); + root->ConvertEventToTarget(gesture_target, gesture); + return gesture_target; } ui::EventTarget* ViewTargeter::FindNextBestTarget( @@ -84,15 +82,13 @@ // a RootViewTargeter). Provide a default implementation // here if we need to be able to perform gesture targeting // starting at an arbitrary node in a Views tree. - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } ui::EventTarget* ViewTargeter::FindNextBestTargetForGestureEvent( ui::EventTarget* previous_target, const ui::GestureEvent& gesture) { - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } } // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc index f875d90..612299b4 100644 --- a/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc +++ b/ui/views/widget/desktop_aura/desktop_native_cursor_manager.cc
@@ -94,7 +94,7 @@ void DesktopNativeCursorManager::InitCursorSizeObserver( wm::NativeCursorManagerDelegate* delegate) { - NOTREACHED(); + NOTREACHED_NORETURN(); } } // namespace views
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc index 113fcb9..1b890d3b 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform.cc
@@ -105,8 +105,7 @@ default: return ui::PlatformWindowType::kPopup; } - NOTREACHED(); - return ui::PlatformWindowType::kPopup; + NOTREACHED_NORETURN(); } ui::PlatformWindowShadowType GetPlatformWindowShadowType( @@ -119,8 +118,7 @@ case Widget::InitParams::ShadowType::kDrop: return ui::PlatformWindowShadowType::kDrop; } - NOTREACHED(); - return ui::PlatformWindowShadowType::kNone; + NOTREACHED_NORETURN(); } ui::PlatformWindowInitProperties ConvertWidgetInitParamsToInitProperties( @@ -473,8 +471,7 @@ bool DesktopWindowTreeHostPlatform::IsStackedAbove(aura::Window* window) { // TODO(https://crbug.com/1363218) Implement Window layer check - NOTREACHED(); - return false; + NOTREACHED_NORETURN(); } void DesktopWindowTreeHostPlatform::CenterWindow(const gfx::Size& size) { @@ -956,13 +953,14 @@ const gfx::Point& screen_in_pixels) const { #if BUILDFLAG(IS_CHROMEOS_LACROS) // lacros should not use this. - NOTREACHED(); -#endif + NOTREACHED_NORETURN(); +#else // TODO(crbug.com/1318279): DIP should use gfx::PointF. Fix this as // a part of cleanup work(crbug.com/1318279). gfx::Point local_dip(screen_in_pixels); ConvertScreenInPixelsToDIP(&local_dip); return gfx::PointF(local_dip); +#endif } void DesktopWindowTreeHostPlatform::OnWorkspaceChanged() {
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_impl_interactive_uitest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_impl_interactive_uitest.cc index 3699d8b..719438a 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_impl_interactive_uitest.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_impl_interactive_uitest.cc
@@ -296,14 +296,12 @@ const gfx::Point& click_location, int flags) { int flag = 0; - if (flags & ui::EF_LEFT_MOUSE_BUTTON) + if (flags & ui::EF_LEFT_MOUSE_BUTTON) { flag = ui::EF_LEFT_MOUSE_BUTTON; - else if (flags & ui::EF_RIGHT_MOUSE_BUTTON) - flag = ui::EF_RIGHT_MOUSE_BUTTON; - - if (!flag) { - NOTREACHED() + } else { + CHECK(flags & ui::EF_RIGHT_MOUSE_BUTTON) << "Other mouse clicks are not supported yet. Add the new one."; + flag = ui::EF_RIGHT_MOUSE_BUTTON; } return new ui::MouseEvent(event_type, click_location, click_location, base::TimeTicks::Now(), flags, flag);
diff --git a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc index 6491f6b..3c51cfee 100644 --- a/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc +++ b/ui/views/widget/desktop_aura/desktop_window_tree_host_platform_unittest.cc
@@ -65,8 +65,7 @@ Wait(); break; default: - NOTREACHED() << "unknown value"; - break; + NOTREACHED_NORETURN() << "unknown value"; } }
diff --git a/ui/views/widget/native_widget_mac.mm b/ui/views/widget/native_widget_mac.mm index 964f1c3..d1a934d2 100644 --- a/ui/views/widget/native_widget_mac.mm +++ b/ui/views/widget/native_widget_mac.mm
@@ -536,15 +536,14 @@ return; } - if (ns_window_host_->application_host() == sibling_host->application_host()) { - // Check if |native_view|'s NativeWidgetMacNSWindowHost corresponds to the - // same process as |this|. - GetNSWindowMojo()->StackAbove(sibling_host->bridged_native_widget_id()); - return; - } - - NOTREACHED() << "|native_view|'s NativeWidgetMacNSWindowHost isn't same " - "process |this|"; + CHECK_EQ(ns_window_host_->application_host(), + sibling_host->application_host()) + << "|native_view|'s NativeWidgetMacNSWindowHost isn't same " + "process |this|"; + // Check if |native_view|'s NativeWidgetMacNSWindowHost corresponds to the + // same process as |this|. + GetNSWindowMojo()->StackAbove(sibling_host->bridged_native_widget_id()); + return; } void NativeWidgetMac::StackAtTop() { @@ -603,8 +602,7 @@ NOTIMPLEMENTED(); break; case ui::SHOW_STATE_END: - NOTREACHED(); - break; + NOTREACHED_NORETURN(); } auto window_state = WindowVisibilityState::kShowAndActivateWindow; if (show_state == ui::SHOW_STATE_INACTIVE) { @@ -1126,11 +1124,8 @@ gfx::NativeView new_parent) { DCHECK_NE(child, new_parent); DCHECK([new_parent.GetNativeNSView() window]); - if (!new_parent || - [child.GetNativeNSView() superview] == new_parent.GetNativeNSView()) { - NOTREACHED(); - return; - } + CHECK(new_parent); + CHECK_NE([child.GetNativeNSView() superview], new_parent.GetNativeNSView()); NativeWidgetMacNSWindowHost* child_window_host = NativeWidgetMacNSWindowHost::GetFromNativeView(child);
diff --git a/ui/views/widget/sublevel_manager_mac_unittest.mm b/ui/views/widget/sublevel_manager_mac_unittest.mm index 2e34c2f..1734d2a4 100644 --- a/ui/views/widget/sublevel_manager_mac_unittest.mm +++ b/ui/views/widget/sublevel_manager_mac_unittest.mm
@@ -75,7 +75,7 @@ test_name += "Activatable"; break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } return test_name; }
diff --git a/ui/views/widget/sublevel_manager_unittest.cc b/ui/views/widget/sublevel_manager_unittest.cc index 41e1c5d..bff3d20e 100644 --- a/ui/views/widget/sublevel_manager_unittest.cc +++ b/ui/views/widget/sublevel_manager_unittest.cc
@@ -97,7 +97,7 @@ test_name += "Activatable"; break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } return test_name; }
diff --git a/ui/views/widget/widget.cc b/ui/views/widget/widget.cc index 13d32438..1e80a2a 100644 --- a/ui/views/widget/widget.cc +++ b/ui/views/widget/widget.cc
@@ -1926,15 +1926,13 @@ FocusTraversable* Widget::GetFocusTraversableParent() { // We are a proxy to the root view, so we should be bypassed when traversing // up and as a result this should not be called. - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } View* Widget::GetFocusTraversableParentView() { // We are a proxy to the root view, so we should be bypassed when traversing // up and as a result this should not be called. - NOTREACHED(); - return nullptr; + NOTREACHED_NORETURN(); } ////////////////////////////////////////////////////////////////////////////////
diff --git a/ui/views/widget/widget_aura_utils.cc b/ui/views/widget/widget_aura_utils.cc index 365c8ef..dfeee980 100644 --- a/ui/views/widget/widget_aura_utils.cc +++ b/ui/views/widget/widget_aura_utils.cc
@@ -25,8 +25,7 @@ case Widget::InitParams::TYPE_TOOLTIP: return aura::client::WINDOW_TYPE_TOOLTIP; default: - NOTREACHED() << "Unhandled widget type " << type; - return aura::client::WINDOW_TYPE_UNKNOWN; + NOTREACHED_NORETURN() << "Unhandled widget type " << type; } }
diff --git a/ui/views/widget/widget_hwnd_utils.cc b/ui/views/widget/widget_hwnd_utils.cc index b162f426..3b9b00b7 100644 --- a/ui/views/widget/widget_hwnd_utils.cc +++ b/ui/views/widget/widget_hwnd_utils.cc
@@ -114,7 +114,7 @@ *style |= WS_POPUP; break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } }
diff --git a/ui/views/win/hwnd_message_handler.cc b/ui/views/win/hwnd_message_handler.cc index 24cc2ff3..f25b11d 100644 --- a/ui/views/win/hwnd_message_handler.cc +++ b/ui/views/win/hwnd_message_handler.cc
@@ -278,8 +278,7 @@ case WMSZ_BOTTOMRIGHT: return gfx::ResizeEdge::kBottomRight; default: - NOTREACHED(); - return gfx::ResizeEdge::kBottomRight; + NOTREACHED_NORETURN(); } } @@ -3437,12 +3436,12 @@ // window, so use the weak ptr to check if destruction occurred or not. base::WeakPtr<HWNDMessageHandler> ref(msg_handler_weak_factory_.GetWeakPtr()); if (event) { - if (event->IsTouchEvent()) + if (event->IsTouchEvent()) { delegate_->HandleTouchEvent(event->AsTouchEvent()); - else if (event->IsMouseEvent()) + } else { + CHECK(event->IsMouseEvent()); delegate_->HandleMouseEvent(event->AsMouseEvent()); - else - NOTREACHED(); + } last_touch_or_pen_message_time_ = ::GetMessageTime(); is_pen_active_in_client_area_ = true;
diff --git a/ui/views/win/pen_event_processor.cc b/ui/views/win/pen_event_processor.cc index 7d6ec155..dd0fa6b 100644 --- a/ui/views/win/pen_event_processor.cc +++ b/ui/views/win/pen_event_processor.cc
@@ -158,7 +158,7 @@ id_generator_->ReleaseNumber(pointer_id); break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } std::unique_ptr<ui::Event> event = std::make_unique<ui::MouseEvent>( event_type, point, point, ui::EventTimeForNow(), @@ -196,7 +196,7 @@ event_type = ui::ET_TOUCH_MOVED; break; default: - NOTREACHED(); + NOTREACHED_NORETURN(); } const base::TimeTicks event_time = ui::EventTimeForNow();
diff --git a/ui/views/window/dialog_delegate.cc b/ui/views/window/dialog_delegate.cc index fca150024..dfd41ce 100644 --- a/ui/views/window/dialog_delegate.cc +++ b/ui/views/window/dialog_delegate.cc
@@ -135,13 +135,10 @@ if (button == ui::DIALOG_BUTTON_OK) return l10n_util::GetStringUTF16(IDS_APP_OK); - if (button == ui::DIALOG_BUTTON_CANCEL) { - if (GetDialogButtons() & ui::DIALOG_BUTTON_OK) - return l10n_util::GetStringUTF16(IDS_APP_CANCEL); - return l10n_util::GetStringUTF16(IDS_APP_CLOSE); - } - NOTREACHED(); - return std::u16string(); + CHECK_EQ(button, ui::DIALOG_BUTTON_CANCEL); + return GetDialogButtons() & ui::DIALOG_BUTTON_OK + ? l10n_util::GetStringUTF16(IDS_APP_CANCEL) + : l10n_util::GetStringUTF16(IDS_APP_CLOSE); } bool DialogDelegate::IsDialogButtonEnabled(ui::DialogButton button) const { @@ -180,11 +177,8 @@ if (default_button == ui::DIALOG_BUTTON_NONE) return nullptr; - if ((default_button & GetDialogButtons()) == 0) { - // The default button is a button we don't have. - NOTREACHED(); - return nullptr; - } + // The default button should be a button we have. + CHECK(default_button & GetDialogButtons()); if (default_button & ui::DIALOG_BUTTON_OK) return dcv->ok_button();
diff --git a/ui/views/window/non_client_view.cc b/ui/views/window/non_client_view.cc index ac55b96..5f39961 100644 --- a/ui/views/window/non_client_view.cc +++ b/ui/views/window/non_client_view.cc
@@ -52,25 +52,26 @@ int component; if (point_in_top) { - if (point_in_left) + if (point_in_left) { component = HTTOPLEFT; - else if (point_in_right) + } else if (point_in_right) { component = HTTOPRIGHT; - else + } else { component = HTTOP; + } } else if (point_in_bottom) { - if (point_in_left) + if (point_in_left) { component = HTBOTTOMLEFT; - else if (point_in_right) + } else if (point_in_right) { component = HTBOTTOMRIGHT; - else + } else { component = HTBOTTOM; + } } else if (point_in_left) { component = HTLEFT; - } else if (point_in_right) { - component = HTRIGHT; } else { - NOTREACHED(); + CHECK(point_in_right); + component = HTRIGHT; } // If the window can't be resized, there are no resize boundaries, just